1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-22 07:09:54 +00:00

On X, avoid reporting unrepresentable touch IDs to Lisp

* src/xterm.c (xi_link_touch_point): Assign a Lisp-representable
identifier to the new touch point and return the same.
(xi_unlink_touch_point): New arg LOCAL_DETAIL.  Return such an
identifier if there is a matching touch point record.
(handle_one_xevent): Adjust as is proper.

* src/xterm.h (struct xi_touch_point_t) <local_detail>:
New field.  Reorder fields for alignment.
This commit is contained in:
Po Lu 2024-06-01 13:53:37 +08:00
parent 0cb511b33b
commit b1692e23ed
2 changed files with 40 additions and 19 deletions

View File

@ -5820,37 +5820,50 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
#ifdef HAVE_XINPUT2_2 #ifdef HAVE_XINPUT2_2
/* Record a touch sequence with the identifier DETAIL from the given /* Record a touch sequence with the identifier DETAIL from the given
FRAME on the specified DEVICE. Round X and Y and record them as FRAME on the specified DEVICE. Round X and Y and record them as its
its current position. */ 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, xi_link_touch_point (struct xi_device_t *device,
int detail, double x, double y, int detail, double x, double y,
struct frame *frame) struct frame *frame)
{ {
struct xi_touch_point_t *touchpoint; 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 = xmalloc (sizeof *touchpoint);
touchpoint->next = device->touchpoints; touchpoint->next = device->touchpoints;
touchpoint->x = lrint (x); touchpoint->x = lrint (x);
touchpoint->y = lrint (y); touchpoint->y = lrint (y);
touchpoint->number = detail; touchpoint->number = detail;
touchpoint->local_detail = local_detail++;
touchpoint->frame = frame; touchpoint->frame = frame;
touchpoint->ownership = TOUCH_OWNERSHIP_NONE; touchpoint->ownership = TOUCH_OWNERSHIP_NONE;
device->touchpoints = touchpoint; device->touchpoints = touchpoint;
return touchpoint->local_detail;
} }
/* Free and remove the touch sequence with the identifier DETAIL. /* Free and remove the touch sequence with the identifier DETAIL.
DEVICE is the device in which the touch sequence should be 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 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 DEVICE, 1 if a touch sequence has been found but is not owned by
Emacs, and 2 otherwise. */ Emacs, and 2 otherwise. */
static int 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; struct xi_touch_point_t *last, *tem;
enum xi_touch_ownership ownership; enum xi_touch_ownership ownership;
@ -5866,6 +5879,7 @@ xi_unlink_touch_point (int detail, struct xi_device_t *device)
last->next = tem->next; last->next = tem->next;
ownership = tem->ownership; ownership = tem->ownership;
*local_detail = tem->local_detail;
xfree (tem); xfree (tem);
if (ownership == TOUCH_OWNERSHIP_SELF) if (ownership == TOUCH_OWNERSHIP_SELF)
@ -24781,6 +24795,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
#ifdef HAVE_GTK3 #ifdef HAVE_GTK3
GdkRectangle test_rect; GdkRectangle test_rect;
#endif #endif
EMACS_INT local_detail;
device = xi_device_from_id (dpyinfo, xev->deviceid); device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid); source = xi_device_from_id (dpyinfo, xev->sourceid);
x_display_set_last_user_time (dpyinfo, xev->time, 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)) if (!x_had_errors_p (dpyinfo->display))
{ {
xi_link_touch_point (device, xev->detail, local_detail
xev->event_x, = xi_link_touch_point (device, xev->detail,
xev->event_y, f); xev->event_x,
xev->event_y, f);
inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT; inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
inev.ie.timestamp = xev->time; inev.ie.timestamp = xev->time;
XSETFRAME (inev.ie.frame_or_window, f); XSETFRAME (inev.ie.frame_or_window, f);
XSETINT (inev.ie.x, lrint (xev->event_x)); XSETINT (inev.ie.x, lrint (xev->event_x));
XSETINT (inev.ie.y, lrint (xev->event_y)); XSETINT (inev.ie.y, lrint (xev->event_y));
XSETINT (inev.ie.arg, xev->detail); XSETINT (inev.ie.arg, local_detail);
if (source) if (source)
inev.ie.device = source->name; inev.ie.device = source->name;
@ -25032,7 +25048,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{ {
if (touchpoint->frame == f) if (touchpoint->frame == f)
arg = Fcons (list3i (touchpoint->x, touchpoint->y, arg = Fcons (list3i (touchpoint->x, touchpoint->y,
lrint (touchpoint->number)), touchpoint->local_detail),
arg); arg);
} }
@ -25049,6 +25065,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{ {
struct xi_device_t *device, *source; struct xi_device_t *device, *source;
int state; int state;
EMACS_INT local_detail;
device = xi_device_from_id (dpyinfo, xev->deviceid); device = xi_device_from_id (dpyinfo, xev->deviceid);
source = xi_device_from_id (dpyinfo, xev->sourceid); 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) if (!device || device->use == XIMasterPointer)
goto XI_OTHER; goto XI_OTHER;
state = xi_unlink_touch_point (xev->detail, device); state = xi_unlink_touch_point (xev->detail, device,
&local_detail);
if (state) if (state)
{ {
@ -25079,7 +25097,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
XSETFRAME (inev.ie.frame_or_window, f); XSETFRAME (inev.ie.frame_or_window, f);
XSETINT (inev.ie.x, lrint (xev->event_x)); XSETINT (inev.ie.x, lrint (xev->event_x));
XSETINT (inev.ie.y, lrint (xev->event_y)); XSETINT (inev.ie.y, lrint (xev->event_y));
XSETINT (inev.ie.arg, xev->detail); XSETINT (inev.ie.arg, local_detail);
if (source) if (source)
inev.ie.device = source->name; inev.ie.device = source->name;

View File

@ -305,6 +305,15 @@ enum xi_touch_ownership
struct xi_touch_point_t 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. */ /* The touchpoint detail. */
int number; int number;
@ -314,12 +323,6 @@ struct xi_touch_point_t
/* The last known rounded X and Y positions of the touchpoint. */ /* The last known rounded X and Y positions of the touchpoint. */
int x, y; 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 #endif