[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:
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master f3f20a37fb: Handle hierarchy events for updating scroll valuators correctly,
Po Lu <=