From 154ecf61972fa7277bf9412f2bf34b496338b57d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 5 Nov 2022 19:09:42 +0800 Subject: [PATCH] Simplify XI scroll class reporting code * 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 | 224 ++++++++++++++++++++++------------------------------ 1 file changed, 94 insertions(+), 130 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 4178526c318..545a95f7b24 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -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 -- 2.39.2