aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-07-18 09:29:16 +0800
committerPo Lu2023-07-18 09:29:16 +0800
commit46fd03a49617066fca87000378771caedfd150f3 (patch)
treeffa3b4d930878d329257185821e0bd2bb63baaa3 /src
parent324d66e3901665f1efa82650ee03b13c9b9bcfe4 (diff)
parent9ad601e7d762f47d3469692b8135cc72b8301365 (diff)
downloademacs-46fd03a49617066fca87000378771caedfd150f3.tar.gz
emacs-46fd03a49617066fca87000378771caedfd150f3.zip
Merge remote-tracking branch 'origin/master' into feature/android
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c20
-rw-r--r--src/termhooks.h6
-rw-r--r--src/xfns.c1
-rw-r--r--src/xterm.c92
-rw-r--r--src/xterm.h62
5 files changed, 157 insertions, 24 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 78105fa9e05..bd7433e584a 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6557,7 +6557,6 @@ make_lispy_event (struct input_event *event)
6557 } 6557 }
6558 6558
6559 case TOUCHSCREEN_BEGIN_EVENT: 6559 case TOUCHSCREEN_BEGIN_EVENT:
6560 case TOUCHSCREEN_END_EVENT:
6561 { 6560 {
6562 Lisp_Object x, y, id, position; 6561 Lisp_Object x, y, id, position;
6563 struct frame *f; 6562 struct frame *f;
@@ -6684,6 +6683,25 @@ make_lispy_event (struct input_event *event)
6684 Fcons (id, position)); 6683 Fcons (id, position));
6685 } 6684 }
6686 6685
6686 case TOUCHSCREEN_END_EVENT:
6687 {
6688 Lisp_Object x, y, id, position;
6689 struct frame *f = XFRAME (event->frame_or_window);
6690
6691 id = event->arg;
6692 x = event->x;
6693 y = event->y;
6694
6695 position = make_lispy_position (f, x, y, event->timestamp);
6696
6697 return list3 (((event->kind
6698 == TOUCHSCREEN_BEGIN_EVENT)
6699 ? Qtouchscreen_begin
6700 : Qtouchscreen_end),
6701 Fcons (id, position),
6702 event->modifiers ? Qt : Qnil);
6703 }
6704
6687 case PINCH_EVENT: 6705 case PINCH_EVENT:
6688 { 6706 {
6689 Lisp_Object x, y, position; 6707 Lisp_Object x, y, position;
diff --git a/src/termhooks.h b/src/termhooks.h
index 99f27cd668e..d978819aeca 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -308,7 +308,11 @@ enum event_kind
308 308
309 In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the 309 In TOUCHSCREEN_BEGIN_EVENT and TOUCHSCREEN_END_EVENT, ARG is the
310 unique ID of the touchpoint, and X and Y are the frame-relative 310 unique ID of the touchpoint, and X and Y are the frame-relative
311 positions of the touchpoint. */ 311 positions of the touchpoint.
312
313 In TOUCHSCREEN_END_EVENT, non-0 modifiers means that the
314 touchpoint has been canceled. (See (elisp)Touchscreen
315 Events.) */
312 316
313 , TOUCHSCREEN_UPDATE_EVENT 317 , TOUCHSCREEN_UPDATE_EVENT
314 , TOUCHSCREEN_BEGIN_EVENT 318 , TOUCHSCREEN_BEGIN_EVENT
diff --git a/src/xfns.c b/src/xfns.c
index 704f7a3f892..854a85f5306 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4107,6 +4107,7 @@ setup_xi_event_mask (struct frame *f)
4107 XISetMask (m, XI_TouchBegin); 4107 XISetMask (m, XI_TouchBegin);
4108 XISetMask (m, XI_TouchUpdate); 4108 XISetMask (m, XI_TouchUpdate);
4109 XISetMask (m, XI_TouchEnd); 4109 XISetMask (m, XI_TouchEnd);
4110 XISetMask (m, XI_TouchOwnership);
4110 4111
4111#if defined HAVE_XINPUT2_4 && defined USE_GTK3 4112#if defined HAVE_XINPUT2_4 && defined USE_GTK3
4112 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4) 4113 if (FRAME_DISPLAY_INFO (f)->xi2_version >= 4)
diff --git a/src/xterm.c b/src/xterm.c
index 75e5b07f2c0..b818609d4b5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -5742,6 +5742,10 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
5742 5742
5743#ifdef HAVE_XINPUT2_2 5743#ifdef HAVE_XINPUT2_2
5744 5744
5745/* Record a touch sequence with the identifier DETAIL from the given
5746 FRAME on the specified DEVICE. Round X and Y and record them as
5747 its current position. */
5748
5745static void 5749static void
5746xi_link_touch_point (struct xi_device_t *device, 5750xi_link_touch_point (struct xi_device_t *device,
5747 int detail, double x, double y, 5751 int detail, double x, double y,
@@ -5751,19 +5755,28 @@ xi_link_touch_point (struct xi_device_t *device,
5751 5755
5752 touchpoint = xmalloc (sizeof *touchpoint); 5756 touchpoint = xmalloc (sizeof *touchpoint);
5753 touchpoint->next = device->touchpoints; 5757 touchpoint->next = device->touchpoints;
5754 touchpoint->x = x; 5758 touchpoint->x = lrint (x);
5755 touchpoint->y = y; 5759 touchpoint->y = lrint (y);
5756 touchpoint->number = detail; 5760 touchpoint->number = detail;
5757 touchpoint->frame = frame; 5761 touchpoint->frame = frame;
5762 touchpoint->ownership = TOUCH_OWNERSHIP_NONE;
5758 5763
5759 device->touchpoints = touchpoint; 5764 device->touchpoints = touchpoint;
5760} 5765}
5761 5766
5762static bool 5767/* Free and remove the touch sequence with the identifier DETAIL.
5763xi_unlink_touch_point (int detail, 5768 DEVICE is the device in which the touch sequence should be
5764 struct xi_device_t *device) 5769 recorded.
5770
5771 Value is 0 if no touch sequence by that identifier exists inside
5772 DEVICE, 1 if a touch sequence has been found but is not owned by
5773 Emacs, and 2 otherwise. */
5774
5775static int
5776xi_unlink_touch_point (int detail, struct xi_device_t *device)
5765{ 5777{
5766 struct xi_touch_point_t *last, *tem; 5778 struct xi_touch_point_t *last, *tem;
5779 enum xi_touch_ownership ownership;
5767 5780
5768 for (last = NULL, tem = device->touchpoints; tem; 5781 for (last = NULL, tem = device->touchpoints; tem;
5769 last = tem, tem = tem->next) 5782 last = tem, tem = tem->next)
@@ -5775,12 +5788,17 @@ xi_unlink_touch_point (int detail,
5775 else 5788 else
5776 last->next = tem->next; 5789 last->next = tem->next;
5777 5790
5791 ownership = tem->ownership;
5778 xfree (tem); 5792 xfree (tem);
5779 return true; 5793
5794 if (ownership == TOUCH_OWNERSHIP_SELF)
5795 return 2;
5796
5797 return 1;
5780 } 5798 }
5781 } 5799 }
5782 5800
5783 return false; 5801 return 0;
5784} 5802}
5785 5803
5786/* Unlink all touch points associated with the frame F. 5804/* Unlink all touch points associated with the frame F.
@@ -5813,6 +5831,10 @@ xi_unlink_touch_points (struct frame *f)
5813 } 5831 }
5814} 5832}
5815 5833
5834/* Return the data associated with a touch sequence DETAIL recorded by
5835 `xi_link_touch_point' from DEVICE, or NULL if it can't be
5836 found. */
5837
5816static struct xi_touch_point_t * 5838static struct xi_touch_point_t *
5817xi_find_touch_point (struct xi_device_t *device, int detail) 5839xi_find_touch_point (struct xi_device_t *device, int detail)
5818{ 5840{
@@ -24458,12 +24480,48 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24458 goto XI_OTHER; 24480 goto XI_OTHER;
24459 } 24481 }
24460 24482
24483 case XI_TouchOwnership:
24484 {
24485 struct xi_device_t *device;
24486 struct xi_touch_point_t *touchpoint;
24487 XITouchOwnershipEvent *event;
24488
24489 /* All grabbing clients have decided to reject ownership
24490 of this touch sequence. */
24491
24492 event = (XITouchOwnershipEvent *) xi_event;
24493 device = xi_device_from_id (dpyinfo, event->deviceid);
24494
24495 if (!device || device->use == XIMasterPointer)
24496 goto XI_OTHER;
24497
24498 touchpoint = xi_find_touch_point (device, event->touchid);
24499
24500 if (!touchpoint)
24501 goto XI_OTHER;
24502
24503 /* As a result, Emacs should complete whatever editing
24504 operations result from this touch sequence. */
24505 touchpoint->ownership = TOUCH_OWNERSHIP_SELF;
24506 }
24507
24461 case XI_TouchUpdate: 24508 case XI_TouchUpdate:
24462 { 24509 {
24463 struct xi_device_t *device, *source; 24510 struct xi_device_t *device, *source;
24464 struct xi_touch_point_t *touchpoint; 24511 struct xi_touch_point_t *touchpoint;
24465 Lisp_Object arg = Qnil; 24512 Lisp_Object arg = Qnil;
24466 24513
24514 /* If flags & TouchPendingEnd, the touch sequence has
24515 already ended, but some grabbing clients remain
24516 undecided as to whether they will obtain ownership of
24517 the touch sequence.
24518
24519 Wait for them to make their decision, resulting in
24520 TouchOwnership and TouchEnd events being sent. */
24521
24522 if (xev->flags & XITouchPendingEnd)
24523 goto XI_OTHER;
24524
24467 device = xi_device_from_id (dpyinfo, xev->deviceid); 24525 device = xi_device_from_id (dpyinfo, xev->deviceid);
24468 source = xi_device_from_id (dpyinfo, xev->sourceid); 24526 source = xi_device_from_id (dpyinfo, xev->sourceid);
24469 x_display_set_last_user_time (dpyinfo, xev->time, 24527 x_display_set_last_user_time (dpyinfo, xev->time,
@@ -24475,7 +24533,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24475 detached, and master pointers may also represent 24533 detached, and master pointers may also represent
24476 dependent touch devices. */ 24534 dependent touch devices. */
24477 24535
24478 if (!device) 24536 if (!device || device->use == XIMasterPointer)
24479 goto XI_OTHER; 24537 goto XI_OTHER;
24480 24538
24481 touchpoint = xi_find_touch_point (device, xev->detail); 24539 touchpoint = xi_find_touch_point (device, xev->detail);
@@ -24483,12 +24541,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24483 if (!touchpoint 24541 if (!touchpoint
24484 /* Don't send this event if nothing has changed 24542 /* Don't send this event if nothing has changed
24485 either. */ 24543 either. */
24486 || (touchpoint->x == (int) xev->event_x 24544 || (touchpoint->x == lrint (xev->event_x)
24487 && touchpoint->y == (int) xev->event_y)) 24545 && touchpoint->y == lrint (xev->event_y)))
24488 goto XI_OTHER; 24546 goto XI_OTHER;
24489 24547
24490 touchpoint->x = xev->event_x; 24548 touchpoint->x = lrint (xev->event_x);
24491 touchpoint->y = xev->event_y; 24549 touchpoint->y = lrint (xev->event_y);
24492 24550
24493 f = x_window_to_frame (dpyinfo, xev->event); 24551 f = x_window_to_frame (dpyinfo, xev->event);
24494 24552
@@ -24502,8 +24560,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24502 touchpoint; touchpoint = touchpoint->next) 24560 touchpoint; touchpoint = touchpoint->next)
24503 { 24561 {
24504 if (touchpoint->frame == f) 24562 if (touchpoint->frame == f)
24505 arg = Fcons (list3i (lrint (touchpoint->x), 24563 arg = Fcons (list3i (touchpoint->x, touchpoint->y,
24506 lrint (touchpoint->y),
24507 lrint (touchpoint->number)), 24564 lrint (touchpoint->number)),
24508 arg); 24565 arg);
24509 } 24566 }
@@ -24520,7 +24577,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24520 case XI_TouchEnd: 24577 case XI_TouchEnd:
24521 { 24578 {
24522 struct xi_device_t *device, *source; 24579 struct xi_device_t *device, *source;
24523 bool unlinked_p; 24580 int state;
24524 24581
24525 device = xi_device_from_id (dpyinfo, xev->deviceid); 24582 device = xi_device_from_id (dpyinfo, xev->deviceid);
24526 source = xi_device_from_id (dpyinfo, xev->sourceid); 24583 source = xi_device_from_id (dpyinfo, xev->sourceid);
@@ -24536,9 +24593,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24536 if (!device || device->use == XIMasterPointer) 24593 if (!device || device->use == XIMasterPointer)
24537 goto XI_OTHER; 24594 goto XI_OTHER;
24538 24595
24539 unlinked_p = xi_unlink_touch_point (xev->detail, device); 24596 state = xi_unlink_touch_point (xev->detail, device);
24540 24597
24541 if (unlinked_p) 24598 if (state)
24542 { 24599 {
24543 f = x_window_to_frame (dpyinfo, xev->event); 24600 f = x_window_to_frame (dpyinfo, xev->event);
24544 24601
@@ -24546,6 +24603,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
24546 { 24603 {
24547 inev.ie.kind = TOUCHSCREEN_END_EVENT; 24604 inev.ie.kind = TOUCHSCREEN_END_EVENT;
24548 inev.ie.timestamp = xev->time; 24605 inev.ie.timestamp = xev->time;
24606 inev.ie.modifiers = state != 2;
24549 24607
24550 XSETFRAME (inev.ie.frame_or_window, f); 24608 XSETFRAME (inev.ie.frame_or_window, f);
24551 XSETINT (inev.ie.x, lrint (xev->event_x)); 24609 XSETINT (inev.ie.x, lrint (xev->event_x));
diff --git a/src/xterm.h b/src/xterm.h
index e7171ba072f..cb477645bfa 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -255,19 +255,71 @@ struct xi_scroll_valuator_t
255 255
256#ifdef HAVE_XINPUT2_2 256#ifdef HAVE_XINPUT2_2
257 257
258/* Enum describing the ownership of a touch point.
259
260 The input extension allows other clients to intercept touch
261 sequences destined for a client window through passively grabbing
262 for touch events on a parent window.
263
264 When a passive touch grab for an XI_TouchBegin event activates, one
265 grabbing client is designated the ``owner'' of the touch sequence
266 started by the grabbed event. Touch events are then delivered to
267 both the grabbing client and other clients that have selected for
268 touch events on the subwindow.
269
270 The X server will not deliver TouchEnd events to clients other than
271 the owner until one grabbing client decides to take over processing
272 the touch event sequence, or no more grabbing clients remain.
273 Instead, a TouchUpdate event with the TouchPendingEnd flag is sent,
274 and the TouchEnd event is postponed until the decision is made and
275 all XI_TouchOwnership events are sent.
276
277 If the owner decides to take over processing the touch sequence, an
278 XI_TouchEnd event is delivered to all other clients receiving
279 events for the current touch sequence, who are then expected to
280 cancel or undo any actions which have taken place in reaction to
281 events from that sequence.
282
283 If the owner decides to relinquish ownership over the touch
284 sequence, the X server looks for another grabbing client, and
285 transfers touch ownership to that client instead. Nothing changes
286 from the perspective of clients who have merely selected for events
287 from the subwindow, while an XI_TouchEnd event is delivered to the
288 old owner, and an XI_TouchOwnership event is delivered to the new
289 owner.
290
291 If all grabbing clients reject ownership over the touch sequence,
292 the X server delivers an XI_TouchOwnership event to the client that
293 has selected for touch events on the subwindow, the only client
294 that will receive events for this touch sequence from this time
295 forward. */
296
297enum xi_touch_ownership
298 {
299 /* Emacs doesn't own this touch sequence. */
300 TOUCH_OWNERSHIP_NONE,
301
302 /* Emacs owns this touch sequence. */
303 TOUCH_OWNERSHIP_SELF,
304 };
305
258struct xi_touch_point_t 306struct xi_touch_point_t
259{ 307{
260 /* The next touch point in this list. */
261 struct xi_touch_point_t *next;
262
263 /* The touchpoint detail. */ 308 /* The touchpoint detail. */
264 int number; 309 int number;
265 310
266 /* The last known X and Y position of the touchpoint. */ 311 /* Whether or not Emacs has ``exclusive'' access to this touch
267 double x, y; 312 point. */
313 enum xi_touch_ownership ownership;
314
315 /* The last known rounded X and Y positions of the touchpoint. */
316 int x, y;
268 317
269 /* The frame associated with this touch point. */ 318 /* The frame associated with this touch point. */
270 struct frame *frame; 319 struct frame *frame;
320
321 /* The next touch point in this list. */
322 struct xi_touch_point_t *next;
271}; 323};
272 324
273#endif 325#endif