]> git.eshelyaron.com Git - emacs.git/commitdiff
Simplify XI scroll class reporting code
authorPo Lu <luangruo@yahoo.com>
Sat, 5 Nov 2022 11:09:42 +0000 (19:09 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 5 Nov 2022 11:11:29 +0000 (19:11 +0800)
* src/xterm.c (xi_populate_device_from_info): Use xnmalloc.
Avoid reading classes at all when the XI library only supports
2.0.
(xi_handle_new_classes): New function.
(xi_handle_device_changed): Move class parsing logic there to
avoid duplicating code.

src/xterm.c

index 4178526c3180a44d4e4639ae04b472e8b3a0c88d..545a95f7b24b79e27d7723f33e88bf400eb51498 100644 (file)
@@ -5301,6 +5301,7 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
 }
 
 #ifdef HAVE_XINPUT2_1
+
 struct xi_known_valuator
 {
   /* The current value of this valuator.  */
@@ -5312,6 +5313,7 @@ struct xi_known_valuator
   /* The next valuator whose value we already know.  */
   struct xi_known_valuator *next;
 };
+
 #endif
 
 static void
@@ -5321,11 +5323,10 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
 #ifdef HAVE_XINPUT2_1
   struct xi_scroll_valuator_t *valuator;
   struct xi_known_valuator *values, *tem;
-  int actual_valuator_count;
+  int actual_valuator_count, c;
   XIScrollClassInfo *info;
   XIValuatorClassInfo *val_info;
 #endif
-  int c;
 #ifdef HAVE_XINPUT2_2
   XITouchClassInfo *touch_info;
 #endif
@@ -5339,8 +5340,8 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
 
 #ifdef HAVE_XINPUT2_1
   actual_valuator_count = 0;
-  xi_device->valuators = xmalloc (sizeof *xi_device->valuators
-                                 * device->num_classes);
+  xi_device->valuators = xnmalloc (device->num_classes,
+                                  sizeof *xi_device->valuators);
   values = NULL;
 #endif
 
@@ -5353,11 +5354,11 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
   xi_device->direct_p = false;
 #endif
 
+#ifdef HAVE_XINPUT2_1
   for (c = 0; c < device->num_classes; ++c)
     {
       switch (device->classes[c]->type)
        {
-#ifdef HAVE_XINPUT2_1
        case XIScrollClass:
          {
            info = (XIScrollClassInfo *) device->classes[c];
@@ -5385,7 +5386,6 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
            values = tem;
            break;
          }
-#endif
 
 #ifdef HAVE_XINPUT2_2
        case XITouchClass:
@@ -5399,7 +5399,6 @@ xi_populate_device_from_info (struct xi_device_t *xi_device,
        }
     }
 
-#ifdef HAVE_XINPUT2_1
   xi_device->scroll_valuator_count = actual_valuator_count;
 
   /* Now look through all the valuators whose values are already known
@@ -13043,97 +13042,117 @@ xi_has_scroll_valuators (XIDeviceChangedEvent *event)
   return false;
 }
 
-#endif
+/* Repopulate the information (touchpoint tracking information, scroll
+   valuators, etc) in DEVICE with the device classes provided in
+   CLASSES.  This is called upon receiving a DeviceChanged event.
 
-/* Handle EVENT, a DeviceChanged event.  Look up the device that
-   changed, and update its information with the data in EVENT.  */
+   This function is not present on XI 2.0 as there are no worthwhile
+   classes there.  */
 
 static void
-xi_handle_device_changed (struct x_display_info *dpyinfo,
-                         struct xi_device_t *device,
-                         XIDeviceChangedEvent *event)
+xi_handle_new_classes (struct x_display_info *dpyinfo, struct xi_device_t *device,
+                      XIAnyClassInfo **classes, int num_classes)
 {
-#ifdef HAVE_XINPUT2_1
-  XIDeviceInfo *info;
   XIScrollClassInfo *scroll;
-  int i, ndevices;
   struct xi_scroll_valuator_t *valuator;
   XIValuatorClassInfo *valuator_info;
-#endif
+  int i;
 #ifdef HAVE_XINPUT2_2
-  struct xi_touch_point_t *tem, *last;
   XITouchClassInfo *touch;
 #endif
 
-#ifdef HAVE_XINPUT2_1
-  if (xi_has_scroll_valuators (event))
-    {
-      /* Scroll valuators are provided by this event.  Use the values
-        provided in this event to populate the device's new scroll
-        valuator list, as if this event's is a SlaveSwitch event
-        caused by wheel movement, querying for the device info will
-        probably return newer values, leading to a delta of 0 being
-        computed when handling the subsequent XI_Motion event.
-        (bug#58980) */
-
-      device->valuators = xrealloc (device->valuators,
-                                   (event->num_classes
-                                    * sizeof *device->valuators));
-      device->scroll_valuator_count = 0;
+  if (dpyinfo->xi2_version < 1)
+    /* Emacs is connected to an XI 2.0 server, which reports no
+       classes of interest.  */
+    return;
+
+  device->valuators = xnmalloc (num_classes,
+                               sizeof *device->valuators);
+  device->scroll_valuator_count = 0;
 #ifdef HAVE_XINPUT2_2
-      device->direct_p = false;
+  device->direct_p = false;
 #endif
 
-      for (i = 0; i < event->num_classes; ++i)
+  for (i = 0; i < num_classes; ++i)
+    {
+      switch (classes[i]->type)
        {
-         switch (event->classes[i]->type)
-           {
-           case XIScrollClass:
-             scroll = (XIScrollClassInfo *) event->classes[i];
-
-             valuator = &device->valuators[device->scroll_valuator_count++];
-             valuator->horizontal = (scroll->scroll_type
-                                     == XIScrollTypeHorizontal);
-             valuator->invalid_p = true;
-             valuator->emacs_value = 0;
-             valuator->increment = scroll->increment;
-             valuator->number = scroll->number;
-             break;
+       case XIScrollClass:
+         scroll = (XIScrollClassInfo *) classes[i];
+
+         valuator = &device->valuators[device->scroll_valuator_count++];
+         valuator->horizontal = (scroll->scroll_type
+                                 == XIScrollTypeHorizontal);
+         valuator->invalid_p = true;
+         valuator->emacs_value = 0;
+         valuator->increment = scroll->increment;
+         valuator->number = scroll->number;
+         break;
 
 #ifdef HAVE_XINPUT2_2
-           case XITouchClass:
-             touch = (XITouchClassInfo *) event->classes[i];
+       case XITouchClass:
+         touch = (XITouchClassInfo *) classes[i];
 
-             if (touch->mode == XIDirectTouch)
-               device->direct_p = true;
-             break;
+         if (touch->mode == XIDirectTouch)
+           device->direct_p = true;
+         break;
 #endif
-           }
        }
+    }
 
-      /* Restore the values of any scroll valuators that we already
-        know about.  */
+  /* Restore the values of any scroll valuators that we already
+     know about.  */
 
-      for (i = 0; i < event->num_classes; ++i)
+  for (i = 0; i < num_classes; ++i)
+    {
+      switch (classes[i]->type)
        {
-         switch (event->classes[i]->type)
-           {
-           case XIValuatorClass:
-             valuator_info = (XIValuatorClassInfo *) event->classes[i];
-
-             valuator = xi_get_scroll_valuator (device,
-                                                valuator_info->number);
-             if (valuator)
-               {
-                 valuator->invalid_p = false;
-                 valuator->current_value = valuator_info->value;
-                 valuator->emacs_value = 0;
-               }
+       case XIValuatorClass:
+         valuator_info = (XIValuatorClassInfo *) classes[i];
 
-             break;
+         valuator = xi_get_scroll_valuator (device,
+                                            valuator_info->number);
+         if (valuator)
+           {
+             valuator->invalid_p = false;
+             valuator->current_value = valuator_info->value;
+             valuator->emacs_value = 0;
            }
+
+         break;
        }
     }
+}
+
+#endif
+
+/* Handle EVENT, a DeviceChanged event.  Look up the device that
+   changed, and update its information with the data in EVENT.  */
+
+static void
+xi_handle_device_changed (struct x_display_info *dpyinfo,
+                         struct xi_device_t *device,
+                         XIDeviceChangedEvent *event)
+{
+#ifdef HAVE_XINPUT2_1
+  int ndevices;
+  XIDeviceInfo *info;
+#endif
+#ifdef HAVE_XINPUT2_2
+  struct xi_touch_point_t *tem, *last;
+#endif
+
+#ifdef HAVE_XINPUT2_1
+  if (xi_has_scroll_valuators (event))
+    /* Scroll valuators are provided by this event.  Use the values
+       provided in this event to populate the device's new scroll
+       valuator list: if this event is a SlaveSwitch event caused by
+       wheel movement, then querying for the device info will probably
+       return the value after the wheel movement, leading to a delta
+       of 0 being computed upon handling the subsequent XI_Motion
+       event.  (bug#58980) */
+    xi_handle_new_classes (dpyinfo, device, event->classes,
+                          event->num_classes);
   else
     {
       /* When a DeviceChange event is received for a master device,
@@ -13153,65 +13172,10 @@ xi_handle_device_changed (struct x_display_info *dpyinfo,
       if (!info)
        return;
 
-      device->valuators = xrealloc (device->valuators,
-                                   (info->num_classes
-                                    * sizeof *device->valuators));
-      device->scroll_valuator_count = 0;
-#ifdef HAVE_XINPUT2_2
-      device->direct_p = false;
-#endif
-
-      for (i = 0; i < info->num_classes; ++i)
-       {
-         switch (info->classes[i]->type)
-           {
-           case XIScrollClass:
-             scroll = (XIScrollClassInfo *) info->classes[i];
-
-             valuator = &device->valuators[device->scroll_valuator_count++];
-             valuator->horizontal = (scroll->scroll_type
-                                     == XIScrollTypeHorizontal);
-             valuator->invalid_p = true;
-             valuator->emacs_value = 0;
-             valuator->increment = scroll->increment;
-             valuator->number = scroll->number;
-             break;
-
-#ifdef HAVE_XINPUT2_2
-           case XITouchClass:
-             touch = (XITouchClassInfo *) info->classes[i];
-
-             if (touch->mode == XIDirectTouch)
-               device->direct_p = true;
-             break;
-#endif
-           }
-       }
-
-      /* Restore the values of any scroll valuators that we already
-        know about.  */
-
-      for (i = 0; i < info->num_classes; ++i)
-       {
-         switch (info->classes[i]->type)
-           {
-           case XIValuatorClass:
-             valuator_info = (XIValuatorClassInfo *) info->classes[i];
-
-             valuator = xi_get_scroll_valuator (device,
-                                                valuator_info->number);
-             if (valuator)
-               {
-                 valuator->invalid_p = false;
-                 valuator->current_value = valuator_info->value;
-                 valuator->emacs_value = 0;
-               }
-
-             break;
-           }
-       }
-
-      XIFreeDeviceInfo (info);
+      /* info contains the classes currently associated with the
+        event.  Apply them.  */
+      xi_handle_new_classes (dpyinfo, device, info->classes,
+                            info->num_classes);
     }
 #endif