]> git.eshelyaron.com Git - emacs.git/commitdiff
Amend last change
authorPo Lu <luangruo@yahoo.com>
Sun, 9 Jun 2024 12:40:17 +0000 (20:40 +0800)
committerEshel Yaron <me@eshelyaron.com>
Mon, 10 Jun 2024 07:26:08 +0000 (09:26 +0200)
* lisp/loadup.el: Load touch-screen.el on MS-Windows.

* src/w32fns.c (Emacs_GESTURECONFIG): New structure.
(SetGestureConfig_fn): New variable.
(w32_createwindow): Disable emulated mouse and gesture events
for the frame's window.
(w32_wnd_proc) <WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_LBUTTONUP>
<WM_RBUTTONUP>: Ignore mouse events which are marked as emulated
pointer events.
(globals_of_w32fns): Load SetGestureConfig from user32.dll.

* src/w32term.c (w32_read_socket): Correct utilization of
GetTouchInputInfo, coordinate spaces, &c.

(cherry picked from commit 588a8439e0919b0b9fede908a55200bb790e6de3)

lisp/loadup.el
src/w32fns.c
src/w32term.c

index eea87d4b940677a33d140c05f455dbbcb545c518..229956571fe708ba3559de0721d38ef522f67c5b 100644 (file)
       (when (eq system-type 'windows-nt)
         (load "w32-fns")
         (load "ls-lisp")
-        (load "dos-w32"))))
+        (load "dos-w32"))
+      (load "touch-screen")))
 (if (eq system-type 'ms-dos)
     (progn
       (load "dos-w32")
index 4437c1fb2b524e914ce8d783b85f335505d78a28..062ed0f5ef25783ef32326c3029699e43edda196 100644 (file)
@@ -218,6 +218,19 @@ typedef BOOL (WINAPI * WTSUnRegisterSessionNotification_Proc) (HWND hwnd);
 
 typedef BOOL (WINAPI * RegisterTouchWindow_proc) (HWND, ULONG);
 
+/* Types for gesture recognition are documented by Microsoft but appear
+   not to be defined anywhere in MinGW's includes.  */
+
+typedef struct Emacs_GESTURECONFIG
+{
+  DWORD dwID;
+  DWORD dwWant;
+  DWORD dwBlock;
+} Emacs_GESTURECONFIG, *Emacs_PGESTURECONFIG;
+
+typedef BOOL (WINAPI * SetGestureConfig_proc) (HWND, DWORD, UINT,
+                                              Emacs_PGESTURECONFIG, UINT);
+
 TrackMouseEvent_Proc track_mouse_event_fn = NULL;
 ImmGetCompositionString_Proc get_composition_string_fn = NULL;
 ImmGetContext_Proc get_ime_context_fn = NULL;
@@ -237,6 +250,7 @@ DwmSetWindowAttribute_Proc DwmSetWindowAttribute_fn = NULL;
 WTSUnRegisterSessionNotification_Proc WTSUnRegisterSessionNotification_fn = NULL;
 WTSRegisterSessionNotification_Proc WTSRegisterSessionNotification_fn = NULL;
 RegisterTouchWindow_proc RegisterTouchWindow_fn = NULL;
+SetGestureConfig_proc SetGestureConfig_fn = NULL;
 
 extern AppendMenuW_Proc unicode_append_menu;
 
@@ -2553,7 +2567,20 @@ w32_createwindow (struct frame *f, int *coords)
 
       /* Enable touch-screen input.  */
       if (RegisterTouchWindow_fn)
-       (*RegisterTouchWindow_fn) (hwnd, 0);
+       {
+         Emacs_GESTURECONFIG cfg;
+
+         (*RegisterTouchWindow_fn) (hwnd, 0);
+
+         /* Disable Window's emulation of mouse events.  */
+         cfg.dwID = 0;
+         cfg.dwWant = 0;
+#ifndef GC_ALLGESTURES
+#define GC_ALLGESTURES 0x00000001
+#endif /* GC_ALLGESTURES */
+         cfg.dwBlock = GC_ALLGESTURES;
+         (*SetGestureConfig_fn) (hwnd, 0, 1, &cfg, sizeof cfg);
+       }
 
       /* Reset F's touch point array.  */
       for (i = 0; i < ARRAYELTS (f->output_data.w32->touch_ids); ++i)
@@ -4803,6 +4830,14 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
         are used together, but only if user has two button mouse. */
     case WM_LBUTTONDOWN:
     case WM_RBUTTONDOWN:
+
+      /* Ignore mouse events produced by a touch screen.  */
+#ifndef MOUSEEVENTF_FROMTOUCH
+#define MOUSEEVENTF_FROMTOUCH 0xFF515700
+#endif /* MOUSEEVENTF_FROMTOUCH */
+      if (GetMessageExtraInfo () & MOUSEEVENTF_FROMTOUCH)
+       goto dflt;
+
       if (w32_num_mouse_buttons > 2)
        goto handle_plain_button;
 
@@ -4868,6 +4903,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
     case WM_LBUTTONUP:
     case WM_RBUTTONUP:
+      /* Ignore mouse events produced by a touch screen.  */
+#ifndef MOUSEEVENTF_FROMTOUCH
+#define MOUSEEVENTF_FROMTOUCH 0xFF515700
+#endif /* MOUSEEVENTF_FROMTOUCH */
+      if (GetMessageExtraInfo () & MOUSEEVENTF_FROMTOUCH)
+       goto dflt;
+
       if (w32_num_mouse_buttons > 2)
        goto handle_plain_button;
 
@@ -11441,6 +11483,9 @@ globals_of_w32fns (void)
   RegisterTouchWindow_fn
     = (RegisterTouchWindow_proc) get_proc_addr (user32_lib,
                                                "RegisterTouchWindow");
+  SetGestureConfig_fn
+    = (SetGestureConfig_proc) get_proc_addr (user32_lib,
+                                            "SetGestureConfig");
 
   {
     HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
index 45f94ab76bdf5257027f0f5f5a36ba6cfa83bd1b..74d73af727a4ee45b531ba295f84ea6914b8f6ea 100644 (file)
@@ -6114,11 +6114,13 @@ w32_read_socket (struct terminal *terminal,
 
          if (f)
            {
-             TOUCHINPUT points[MAX_TOUCH_POINTS];
-             int i, x;
+             TOUCHINPUT *points;
+             int i, x, px, py;
+             POINT pt;
 
+             points = alloca (sizeof *points * LOWORD (msg.msg.wParam));
              if ((*pfnGetTouchInputInfo) ((HANDLE) msg.msg.lParam,
-                                          MAX_TOUCH_POINTS,
+                                          LOWORD (msg.msg.wParam),
                                           points, sizeof (TOUCHINPUT)))
                {
                  bool movement_p = false;
@@ -6128,7 +6130,7 @@ w32_read_socket (struct terminal *terminal,
                     structure, and for each, enter or remove
                     information into and from F->touch_ids, and
                     generate events correspondingly.  */
-                 for (i = 0; i < MAX_TOUCH_POINTS; ++i)
+                 for (i = 0; i < LOWORD (msg.msg.wParam); ++i)
                    {
                      if (!points[i].dwID)
                        continue;
@@ -6137,14 +6139,34 @@ w32_read_socket (struct terminal *terminal,
                         empty or matches dwID.  */
                      for (x = 0; x < MAX_TOUCH_POINTS; x++)
                        {
-                         if (FRAME_OUTPUT_DATA (f)->touch_ids[x] == -1
-                             || (FRAME_OUTPUT_DATA (f)->touch_ids[x]
-                                 == points[i].dwID))
+                         if (FRAME_OUTPUT_DATA (f)->touch_ids[x]
+                             == points[i].dwID)
                            break;
                        }
+
+                     if (x < MAX_TOUCH_POINTS)
+                       goto touch_located;
+
+                     for (x = 0; x < MAX_TOUCH_POINTS; x++)
+                       {
+                         if (FRAME_OUTPUT_DATA (f)->touch_ids[x] == -1)
+                           break;
+                       }
+
                      if (x == MAX_TOUCH_POINTS)
                        continue;
 
+                   touch_located:
+                     /* X and Y are fractional values.  */
+                     pt.x = points[i].x / 100;
+                     pt.y = points[i].y / 100;
+
+                     /* Convert them from screen values to client
+                        values.  */
+                     ScreenToClient (msg.msg.hwnd, &pt);
+                     px = pt.x;
+                     py = pt.y;
+
                      if (points[i].dwFlags & TOUCHEVENTF_UP)
                        {
                          /* Clear the entry in touch_ids and report the
@@ -6157,22 +6179,25 @@ w32_read_socket (struct terminal *terminal,
                          inev.kind = TOUCHSCREEN_END_EVENT;
                          inev.timestamp = msg.msg.time;
                          XSETFRAME (inev.frame_or_window, f);
-                         XSETINT (inev.x, points[i].x);
-                         XSETINT (inev.y, points[i].y);
+                         XSETINT (inev.x, px);
+                         XSETINT (inev.y, py);
                          XSETINT (inev.arg, x + base);
                          kbd_buffer_store_event (&inev);
                          EVENT_INIT (inev);
                        }
                      else if (points[i].dwFlags & TOUCHEVENTF_DOWN)
                        {
-                         bool recorded_p
+                         bool recorded_p;
+
+                       touchscreen_down:
+                         recorded_p
                            = FRAME_OUTPUT_DATA (f)->touch_ids[x] != -1;
 
                          /* Report and record (if not already recorded)
                             the addition.  */
                          FRAME_OUTPUT_DATA (f)->touch_ids[x] = points[i].dwID;
-                         FRAME_OUTPUT_DATA (f)->touch_x[x] = points[i].x;
-                         FRAME_OUTPUT_DATA (f)->touch_y[x] = points[i].y;
+                         FRAME_OUTPUT_DATA (f)->touch_x[x] = px;
+                         FRAME_OUTPUT_DATA (f)->touch_y[x] = py;
 
                          if (recorded_p)
                            movement_p = true;
@@ -6181,8 +6206,8 @@ w32_read_socket (struct terminal *terminal,
                              inev.kind = TOUCHSCREEN_BEGIN_EVENT;
                              inev.timestamp = msg.msg.time;
                              XSETFRAME (inev.frame_or_window, f);
-                             XSETINT (inev.x, points[i].x);
-                             XSETINT (inev.y, points[i].y);
+                             XSETINT (inev.x, px);
+                             XSETINT (inev.y, py);
                              XSETINT (inev.arg, x + base);
                              kbd_buffer_store_event (&inev);
                              EVENT_INIT (inev);
@@ -6190,10 +6215,20 @@ w32_read_socket (struct terminal *terminal,
                        }
                      else
                        {
-                         FRAME_OUTPUT_DATA (f)->touch_ids[x] = points[i].dwID;
-                         FRAME_OUTPUT_DATA (f)->touch_x[x] = points[i].x;
-                         FRAME_OUTPUT_DATA (f)->touch_y[x] = points[i].y;
-                         movement_p = true;
+                         bool recorded_p
+                           = FRAME_OUTPUT_DATA (f)->touch_ids[x] != -1;
+                         if (!recorded_p)
+                           goto touchscreen_down;
+
+                         if (FRAME_OUTPUT_DATA (f)->touch_x[x] != px
+                             || FRAME_OUTPUT_DATA (f)->touch_y[x] != py)
+                           {
+                             movement_p = true;
+                             FRAME_OUTPUT_DATA (f)->touch_ids[x]
+                               = points[i].dwID;
+                             FRAME_OUTPUT_DATA (f)->touch_x[x] = px;
+                             FRAME_OUTPUT_DATA (f)->touch_y[x] = py;
+                           }
                        }
                    }
 
@@ -6209,13 +6244,22 @@ w32_read_socket (struct terminal *terminal,
                      arg = Qnil;
 
                      for (i = 0; i < MAX_TOUCH_POINTS; ++i)
-                       arg
-                         = Fcons (list3i (FRAME_OUTPUT_DATA (f)->touch_x[i],
-                                          FRAME_OUTPUT_DATA (f)->touch_y[i],
-                                          i + base),
-                                  arg);
+                       {
+                         if (FRAME_OUTPUT_DATA (f)->touch_ids[i] == -1)
+                           continue;
+
+                         arg
+                           = Fcons (list3i (FRAME_OUTPUT_DATA (f)->touch_x[i],
+                                            FRAME_OUTPUT_DATA (f)->touch_y[i],
+                                            i + base),
+                                    arg);
+                       }
 
                      inev.arg = arg;
+
+                     /* Don't generate events if they would be empty.  */
+                     if (NILP (arg))
+                       EVENT_INIT (inev);
                    }
                }
            }