emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master f3f20a37fb: Handle hierarchy events for updating scroll valuators


From: Po Lu
Subject: master f3f20a37fb: Handle hierarchy events for updating scroll valuators correctly
Date: Sat, 9 Apr 2022 01:31:04 -0400 (EDT)

branch: master
commit f3f20a37fb3b7e02fc52b3787968e2a332f52119
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Handle hierarchy events for updating scroll valuators correctly
    
    * src/keyboard.c (gen_help_event, kbd_buffer_store_help_event):
    Make sure to initialize the event buffer correctly.
    
    * src/xterm.c (xi_populate_device_from_info): New function.
    (x_init_master_valuators): Factor out most of the valuator
    tracking code to that function.
    (handle_one_xevent): Handle device enable and disable events in
    a more detailed fashion.
---
 src/keyboard.c |   2 +
 src/xterm.c    | 225 +++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 155 insertions(+), 72 deletions(-)

diff --git a/src/keyboard.c b/src/keyboard.c
index 98eebaf7f5..e569f8f34c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3766,6 +3766,7 @@ gen_help_event (Lisp_Object help, Lisp_Object frame, 
Lisp_Object window,
                Lisp_Object object, ptrdiff_t pos)
 {
   struct input_event event;
+  EVENT_INIT (event);
 
   event.kind = HELP_EVENT;
   event.frame_or_window = frame;
@@ -3783,6 +3784,7 @@ void
 kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help)
 {
   struct input_event event;
+  EVENT_INIT (event);
 
   event.kind = HELP_EVENT;
   event.frame_or_window = frame;
diff --git a/src/xterm.c b/src/xterm.c
index 509403fbf2..f6138d5214 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -3842,6 +3842,77 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
   unblock_input ();
 }
 
+static void
+xi_populate_device_from_info (struct xi_device_t *xi_device,
+                             XIDeviceInfo *device)
+{
+#ifdef HAVE_XINPUT2_1
+  struct xi_scroll_valuator_t *valuator;
+  int actual_valuator_count;
+  XIScrollClassInfo *info;
+#endif
+#ifdef HAVE_XINPUT2_2
+  XITouchClassInfo *touch_info;
+#endif
+  int c;
+
+  xi_device->device_id = device->deviceid;
+  xi_device->grab = 0;
+
+#ifdef HAVE_XINPUT2_1
+  actual_valuator_count = 0;
+  xi_device->valuators =
+    xmalloc (sizeof *xi_device->valuators * device->num_classes);
+#endif
+#ifdef HAVE_XINPUT2_2
+  xi_device->touchpoints = NULL;
+#endif
+
+  xi_device->master_p = (device->use == XIMasterKeyboard
+                        || device->use == XIMasterPointer);
+#ifdef HAVE_XINPUT2_2
+  xi_device->direct_p = false;
+#endif
+  xi_device->name = build_string (device->name);
+
+  for (c = 0; c < device->num_classes; ++c)
+    {
+      switch (device->classes[c]->type)
+       {
+#ifdef HAVE_XINPUT2_1
+       case XIScrollClass:
+         {
+           info = (XIScrollClassInfo *) device->classes[c];
+
+           valuator = &xi_device->valuators[actual_valuator_count++];
+           valuator->horizontal
+             = (info->scroll_type == XIScrollTypeHorizontal);
+           valuator->invalid_p = true;
+           valuator->emacs_value = DBL_MIN;
+           valuator->increment = info->increment;
+           valuator->number = info->number;
+           valuator->pending_enter_reset = false;
+
+           break;
+         }
+#endif
+#ifdef HAVE_XINPUT2_2
+       case XITouchClass:
+         {
+           touch_info = (XITouchClassInfo *) device->classes[c];
+           xi_device->direct_p = touch_info->mode == XIDirectTouch;
+         }
+#endif
+       default:
+         break;
+       }
+    }
+
+#ifdef HAVE_XINPUT2_1
+  xi_device->scroll_valuator_count = actual_valuator_count;
+#endif
+}
+
 /* The code below handles the tracking of scroll valuators on XInput
    2, in order to support scroll wheels that report information more
    granular than a screen line.
@@ -3876,9 +3947,10 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
 static void
 x_init_master_valuators (struct x_display_info *dpyinfo)
 {
-  int ndevices;
+  int ndevices, actual_devices;
   XIDeviceInfo *infos;
 
+  actual_devices = 0;
   block_input ();
   x_free_xi_devices (dpyinfo);
   infos = XIQueryDevice (dpyinfo->display,
@@ -3892,79 +3964,13 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
       return;
     }
 
-  int actual_devices = 0;
   dpyinfo->devices = xmalloc (sizeof *dpyinfo->devices * ndevices);
 
   for (int i = 0; i < ndevices; ++i)
     {
-      XIDeviceInfo *device = &infos[i];
-
-      if (device->enabled)
-       {
-#ifdef HAVE_XINPUT2_1
-         int actual_valuator_count = 0;
-#endif
-
-         struct xi_device_t *xi_device = &dpyinfo->devices[actual_devices++];
-         xi_device->device_id = device->deviceid;
-         xi_device->grab = 0;
-
-#ifdef HAVE_XINPUT2_1
-         xi_device->valuators =
-           xmalloc (sizeof *xi_device->valuators * device->num_classes);
-#endif
-#ifdef HAVE_XINPUT2_2
-         xi_device->touchpoints = NULL;
-#endif
-
-         xi_device->master_p = (device->use == XIMasterKeyboard
-                                || device->use == XIMasterPointer);
-#ifdef HAVE_XINPUT2_2
-         xi_device->direct_p = false;
-#endif
-         xi_device->name = build_string (device->name);
-
-         for (int c = 0; c < device->num_classes; ++c)
-           {
-             switch (device->classes[c]->type)
-               {
-#ifdef HAVE_XINPUT2_1
-               case XIScrollClass:
-                 {
-                   XIScrollClassInfo *info =
-                     (XIScrollClassInfo *) device->classes[c];
-                   struct xi_scroll_valuator_t *valuator;
-
-                   valuator = &xi_device->valuators[actual_valuator_count++];
-                   valuator->horizontal
-                     = (info->scroll_type == XIScrollTypeHorizontal);
-                   valuator->invalid_p = true;
-                   valuator->emacs_value = DBL_MIN;
-                   valuator->increment = info->increment;
-                   valuator->number = info->number;
-                   valuator->pending_enter_reset = false;
-
-                   break;
-                 }
-#endif
-#ifdef HAVE_XINPUT2_2
-               case XITouchClass:
-                 {
-                   XITouchClassInfo *info;
-
-                   info = (XITouchClassInfo *) device->classes[c];
-                   xi_device->direct_p = info->mode == XIDirectTouch;
-                 }
-#endif
-               default:
-                 break;
-               }
-           }
-
-#ifdef HAVE_XINPUT2_1
-         xi_device->scroll_valuator_count = actual_valuator_count;
-#endif
-       }
+      if (infos[i].enabled)
+       xi_populate_device_from_info (&dpyinfo->devices[actual_devices++],
+                                     &infos[i]);
     }
 
   dpyinfo->num_devices = actual_devices;
@@ -17692,8 +17698,83 @@ handle_one_xevent (struct x_display_info *dpyinfo,
            goto XI_OTHER;
 
          case XI_HierarchyChanged:
-           x_init_master_valuators (dpyinfo);
-           goto XI_OTHER;
+           {
+             XIHierarchyEvent *hev = (XIHierarchyEvent *) xi_event;
+             XIDeviceInfo *info;
+             int i, j, ndevices, n_disabled, *disabled;
+             struct xi_device_t *device, *devices;
+#ifdef HAVE_XINPUT2_2
+             struct xi_touch_point_t *tem, *last;
+#endif
+
+             disabled = alloca (sizeof *disabled * hev->num_info);
+             n_disabled = 0;
+
+             for (i = 0; i < hev->num_info; ++i)
+               {
+                 if (hev->info[i].flags & XIDeviceEnabled)
+                   {
+                     x_catch_errors (dpyinfo->display);
+                     info = XIQueryDevice (dpyinfo->display, 
hev->info[i].deviceid,
+                                           &ndevices);
+                     x_uncatch_errors ();
+
+                     if (info && info->enabled)
+                       {
+                         dpyinfo->devices
+                           = xrealloc (dpyinfo->devices, (sizeof 
*dpyinfo->devices
+                                                          * 
++dpyinfo->num_devices));
+                         device = &dpyinfo->devices[dpyinfo->num_devices - 1];
+                         xi_populate_device_from_info (device, info);
+                       }
+
+                     if (info)
+                       XIFreeDeviceInfo (info);
+                   }
+                 else if (hev->info[i].flags & XIDeviceDisabled)
+                   disabled[n_disabled++] = hev->info[i].deviceid;
+               }
+
+             if (n_disabled)
+               {
+                 ndevices = 0;
+                 devices = xmalloc (sizeof *devices * dpyinfo->num_devices);
+
+                 for (i = 0; i < dpyinfo->num_devices; ++i)
+                   {
+                     for (j = 0; j < n_disabled; ++j)
+                       {
+                         if (disabled[j] == dpyinfo->devices[i].device_id)
+                           {
+#ifdef HAVE_XINPUT2_1
+                             xfree (dpyinfo->devices[i].valuators);
+#endif
+#ifdef HAVE_XINPUT2_2
+                             tem = dpyinfo->devices[i].touchpoints;
+                             while (tem)
+                               {
+                                 last = tem;
+                                 tem = tem->next;
+                                 xfree (last);
+                               }
+#endif
+                             goto continue_detachment;
+                           }
+                       }
+
+                     devices[ndevices++] = dpyinfo->devices[i];
+
+                   continue_detachment:
+                     continue;
+                   }
+
+                 xfree (dpyinfo->devices);
+                 dpyinfo->devices = devices;
+                 dpyinfo->num_devices = ndevices;
+               }
+
+             goto XI_OTHER;
+           }
 
          case XI_DeviceChanged:
            {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]