diff --git a/src/xterm.c b/src/xterm.c index 11ef9a4bd94..2f5e54f63d5 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -5820,37 +5820,50 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid) #ifdef HAVE_XINPUT2_2 /* Record a touch sequence with the identifier DETAIL from the given - FRAME on the specified DEVICE. Round X and Y and record them as - its current position. */ + FRAME on the specified DEVICE. Round X and Y and record them as its + current position, assign an identifier to the touch sequence suitable + for reporting to Lisp, and return the same. */ -static void +static EMACS_INT xi_link_touch_point (struct xi_device_t *device, int detail, double x, double y, struct frame *frame) { struct xi_touch_point_t *touchpoint; + static EMACS_INT local_detail; + + /* Assign an identifier suitable for reporting to Lisp. On builds + with 64-bit Lisp_Object, this is largely a theoretical problem, but + CARD32s easily overflow 32-bit systems, as they are not specific to + X clients (e.g. Emacs) but grow uniformly across all of them. */ + + if (FIXNUM_OVERFLOW_P (local_detail)) + local_detail = 0; touchpoint = xmalloc (sizeof *touchpoint); touchpoint->next = device->touchpoints; touchpoint->x = lrint (x); touchpoint->y = lrint (y); touchpoint->number = detail; + touchpoint->local_detail = local_detail++; touchpoint->frame = frame; touchpoint->ownership = TOUCH_OWNERSHIP_NONE; - device->touchpoints = touchpoint; + return touchpoint->local_detail; } /* Free and remove the touch sequence with the identifier DETAIL. DEVICE is the device in which the touch sequence should be - recorded. + recorded. If such a touch sequence exists, return its local + identifier in *LOCAL_DETAIL. Value is 0 if no touch sequence by that identifier exists inside DEVICE, 1 if a touch sequence has been found but is not owned by Emacs, and 2 otherwise. */ static int -xi_unlink_touch_point (int detail, struct xi_device_t *device) +xi_unlink_touch_point (int detail, struct xi_device_t *device, + EMACS_INT *local_detail) { struct xi_touch_point_t *last, *tem; enum xi_touch_ownership ownership; @@ -5866,6 +5879,7 @@ xi_unlink_touch_point (int detail, struct xi_device_t *device) last->next = tem->next; ownership = tem->ownership; + *local_detail = tem->local_detail; xfree (tem); if (ownership == TOUCH_OWNERSHIP_SELF) @@ -24781,6 +24795,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, #ifdef HAVE_GTK3 GdkRectangle test_rect; #endif + EMACS_INT local_detail; device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); x_display_set_last_user_time (dpyinfo, xev->time, @@ -24905,16 +24920,17 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!x_had_errors_p (dpyinfo->display)) { - xi_link_touch_point (device, xev->detail, - xev->event_x, - xev->event_y, f); + local_detail + = xi_link_touch_point (device, xev->detail, + xev->event_x, + xev->event_y, f); inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT; inev.ie.timestamp = xev->time; XSETFRAME (inev.ie.frame_or_window, f); XSETINT (inev.ie.x, lrint (xev->event_x)); XSETINT (inev.ie.y, lrint (xev->event_y)); - XSETINT (inev.ie.arg, xev->detail); + XSETINT (inev.ie.arg, local_detail); if (source) inev.ie.device = source->name; @@ -25032,7 +25048,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { if (touchpoint->frame == f) arg = Fcons (list3i (touchpoint->x, touchpoint->y, - lrint (touchpoint->number)), + touchpoint->local_detail), arg); } @@ -25049,6 +25065,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, { struct xi_device_t *device, *source; int state; + EMACS_INT local_detail; device = xi_device_from_id (dpyinfo, xev->deviceid); source = xi_device_from_id (dpyinfo, xev->sourceid); @@ -25064,7 +25081,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!device || device->use == XIMasterPointer) goto XI_OTHER; - state = xi_unlink_touch_point (xev->detail, device); + state = xi_unlink_touch_point (xev->detail, device, + &local_detail); if (state) { @@ -25079,7 +25097,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XSETFRAME (inev.ie.frame_or_window, f); XSETINT (inev.ie.x, lrint (xev->event_x)); XSETINT (inev.ie.y, lrint (xev->event_y)); - XSETINT (inev.ie.arg, xev->detail); + XSETINT (inev.ie.arg, local_detail); if (source) inev.ie.device = source->name; diff --git a/src/xterm.h b/src/xterm.h index bf402de326b..8d5c9917749 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -305,6 +305,15 @@ enum xi_touch_ownership struct xi_touch_point_t { + /* The detail code reported to Lisp. */ + EMACS_INT local_detail; + + /* The frame associated with this touch point. */ + struct frame *frame; + + /* The next touch point in this list. */ + struct xi_touch_point_t *next; + /* The touchpoint detail. */ int number; @@ -314,12 +323,6 @@ struct xi_touch_point_t /* The last known rounded X and Y positions of the touchpoint. */ int x, y; - - /* The frame associated with this touch point. */ - struct frame *frame; - - /* The next touch point in this list. */ - struct xi_touch_point_t *next; }; #endif