aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c604
1 files changed, 403 insertions, 201 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 646985bdc20..fa60a4e8745 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -353,6 +353,8 @@ x_extension_initialize (struct x_display_info *dpyinfo)
353static void 353static void
354x_free_xi_devices (struct x_display_info *dpyinfo) 354x_free_xi_devices (struct x_display_info *dpyinfo)
355{ 355{
356 struct xi_touch_point_t *tem, *last;
357
356 block_input (); 358 block_input ();
357 359
358 if (dpyinfo->num_devices) 360 if (dpyinfo->num_devices)
@@ -362,6 +364,14 @@ x_free_xi_devices (struct x_display_info *dpyinfo)
362 XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id, 364 XIUngrabDevice (dpyinfo->display, dpyinfo->devices[i].device_id,
363 CurrentTime); 365 CurrentTime);
364 xfree (dpyinfo->devices[i].valuators); 366 xfree (dpyinfo->devices[i].valuators);
367
368 tem = dpyinfo->devices[i].touchpoints;
369 while (tem)
370 {
371 last = tem;
372 tem = tem->next;
373 xfree (last);
374 }
365 } 375 }
366 376
367 xfree (dpyinfo->devices); 377 xfree (dpyinfo->devices);
@@ -407,7 +417,7 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
407 block_input (); 417 block_input ();
408 x_free_xi_devices (dpyinfo); 418 x_free_xi_devices (dpyinfo);
409 infos = XIQueryDevice (dpyinfo->display, 419 infos = XIQueryDevice (dpyinfo->display,
410 XIAllMasterDevices, 420 XIAllDevices,
411 &ndevices); 421 &ndevices);
412 422
413 if (!ndevices) 423 if (!ndevices)
@@ -432,6 +442,10 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
432 xi_device->grab = 0; 442 xi_device->grab = 0;
433 xi_device->valuators = 443 xi_device->valuators =
434 xmalloc (sizeof *xi_device->valuators * device->num_classes); 444 xmalloc (sizeof *xi_device->valuators * device->num_classes);
445 xi_device->touchpoints = NULL;
446 xi_device->master_p = (device->use == XIMasterKeyboard
447 || device->use == XIMasterPointer);
448 xi_device->direct_p = false;
435 449
436 for (int c = 0; c < device->num_classes; ++c) 450 for (int c = 0; c < device->num_classes; ++c)
437 { 451 {
@@ -442,22 +456,36 @@ x_init_master_valuators (struct x_display_info *dpyinfo)
442 { 456 {
443 XIScrollClassInfo *info = 457 XIScrollClassInfo *info =
444 (XIScrollClassInfo *) device->classes[c]; 458 (XIScrollClassInfo *) device->classes[c];
445 struct xi_scroll_valuator_t *valuator = 459 struct xi_scroll_valuator_t *valuator;
446 &xi_device->valuators[actual_valuator_count++]; 460
447 461 if (xi_device->master_p)
448 valuator->horizontal 462 {
449 = (info->scroll_type == XIScrollTypeHorizontal); 463 valuator = &xi_device->valuators[actual_valuator_count++];
450 valuator->invalid_p = true; 464 valuator->horizontal
451 valuator->emacs_value = DBL_MIN; 465 = (info->scroll_type == XIScrollTypeHorizontal);
452 valuator->increment = info->increment; 466 valuator->invalid_p = true;
453 valuator->number = info->number; 467 valuator->emacs_value = DBL_MIN;
468 valuator->increment = info->increment;
469 valuator->number = info->number;
470 }
471
454 break; 472 break;
455 } 473 }
456#endif 474#endif
475#ifdef XITouchClass /* XInput 2.2 */
476 case XITouchClass:
477 {
478 XITouchClassInfo *info;
479
480 info = (XITouchClassInfo *) device->classes[c];
481 xi_device->direct_p = info->mode == XIDirectTouch;
482 }
483#endif
457 default: 484 default:
458 break; 485 break;
459 } 486 }
460 } 487 }
488
461 xi_device->scroll_valuator_count = actual_valuator_count; 489 xi_device->scroll_valuator_count = actual_valuator_count;
462 } 490 }
463 } 491 }
@@ -484,7 +512,7 @@ x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id,
484 { 512 {
485 struct xi_device_t *device = &dpyinfo->devices[i]; 513 struct xi_device_t *device = &dpyinfo->devices[i];
486 514
487 if (device->device_id == device_id) 515 if (device->device_id == device_id && device->master_p)
488 { 516 {
489 for (int j = 0; j < device->scroll_valuator_count; ++j) 517 for (int j = 0; j < device->scroll_valuator_count; ++j)
490 { 518 {
@@ -534,6 +562,61 @@ xi_device_from_id (struct x_display_info *dpyinfo, int deviceid)
534 return NULL; 562 return NULL;
535} 563}
536 564
565#ifdef XI_TouchBegin
566
567static void
568xi_link_touch_point (struct xi_device_t *device,
569 int detail, double x, double y)
570{
571 struct xi_touch_point_t *touchpoint;
572
573 touchpoint = xmalloc (sizeof *touchpoint);
574 touchpoint->next = device->touchpoints;
575 touchpoint->x = x;
576 touchpoint->y = y;
577 touchpoint->number = detail;
578
579 device->touchpoints = touchpoint;
580}
581
582static void
583xi_unlink_touch_point (int detail,
584 struct xi_device_t *device)
585{
586 struct xi_touch_point_t *last, *tem;
587
588 for (last = NULL, tem = device->touchpoints; tem;
589 last = tem, tem = tem->next)
590 {
591 if (tem->number == detail)
592 {
593 if (!last)
594 device->touchpoints = tem->next;
595 else
596 last->next = tem->next;
597
598 xfree (tem);
599 return;
600 }
601 }
602}
603
604static struct xi_touch_point_t *
605xi_find_touch_point (struct xi_device_t *device, int detail)
606{
607 struct xi_touch_point_t *point;
608
609 for (point = device->touchpoints; point; point = point->next)
610 {
611 if (point->number == detail)
612 return point;
613 }
614
615 return NULL;
616}
617
618#endif /* XI_TouchBegin */
619
537static void 620static void
538xi_grab_or_ungrab_device (struct xi_device_t *device, 621xi_grab_or_ungrab_device (struct xi_device_t *device,
539 struct x_display_info *dpyinfo, 622 struct x_display_info *dpyinfo,
@@ -570,7 +653,7 @@ xi_reset_scroll_valuators_for_device_id (struct x_display_info *dpyinfo, int id)
570 struct xi_device_t *device = xi_device_from_id (dpyinfo, id); 653 struct xi_device_t *device = xi_device_from_id (dpyinfo, id);
571 struct xi_scroll_valuator_t *valuator; 654 struct xi_scroll_valuator_t *valuator;
572 655
573 if (!device) 656 if (!device || !device->master_p)
574 return; 657 return;
575 658
576 if (!device->scroll_valuator_count) 659 if (!device->scroll_valuator_count)
@@ -9981,242 +10064,250 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9981#endif 10064#endif
9982 goto XI_OTHER; 10065 goto XI_OTHER;
9983 case XI_Motion: 10066 case XI_Motion:
9984 states = &xev->valuators; 10067 {
9985 values = states->values; 10068 struct xi_device_t *device;
9986 10069
9987 x_display_set_last_user_time (dpyinfo, xi_event->time); 10070 states = &xev->valuators;
10071 values = states->values;
10072 device = xi_device_from_id (dpyinfo, xev->deviceid);
10073
10074 if (!device || !device->master_p)
10075 goto XI_OTHER;
10076
10077 x_display_set_last_user_time (dpyinfo, xi_event->time);
9988 10078
9989#ifdef HAVE_XWIDGETS 10079#ifdef HAVE_XWIDGETS
9990 struct xwidget_view *xv = xwidget_view_from_window (xev->event); 10080 struct xwidget_view *xv = xwidget_view_from_window (xev->event);
9991 double xv_total_x = 0.0; 10081 double xv_total_x = 0.0;
9992 double xv_total_y = 0.0; 10082 double xv_total_y = 0.0;
9993#endif 10083#endif
9994 10084
9995 for (int i = 0; i < states->mask_len * 8; i++) 10085 for (int i = 0; i < states->mask_len * 8; i++)
9996 { 10086 {
9997 if (XIMaskIsSet (states->mask, i)) 10087 if (XIMaskIsSet (states->mask, i))
9998 { 10088 {
9999 struct xi_scroll_valuator_t *val; 10089 struct xi_scroll_valuator_t *val;
10000 double delta, scroll_unit; 10090 double delta, scroll_unit;
10001 int scroll_height; 10091 int scroll_height;
10002 Lisp_Object window; 10092 Lisp_Object window;
10003 10093
10004 10094
10005 /* See the comment on top of 10095 /* See the comment on top of
10006 x_init_master_valuators for more details on how 10096 x_init_master_valuators for more details on how
10007 scroll wheel movement is reported on XInput 2. */ 10097 scroll wheel movement is reported on XInput 2. */
10008 delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, 10098 delta = x_get_scroll_valuator_delta (dpyinfo, xev->deviceid,
10009 i, *values, &val); 10099 i, *values, &val);
10010 10100
10011 if (delta != DBL_MAX) 10101 if (delta != DBL_MAX)
10012 { 10102 {
10013#ifdef HAVE_XWIDGETS 10103#ifdef HAVE_XWIDGETS
10014 if (xv) 10104 if (xv)
10015 { 10105 {
10016 if (val->horizontal) 10106 if (val->horizontal)
10017 xv_total_x += delta; 10107 xv_total_x += delta;
10018 else 10108 else
10019 xv_total_y += delta; 10109 xv_total_y += delta;
10020 10110
10021 found_valuator = true; 10111 found_valuator = true;
10022 10112
10023 if (delta == 0.0) 10113 if (delta == 0.0)
10024 any_stop_p = true; 10114 any_stop_p = true;
10025 10115
10026 continue; 10116 continue;
10027 } 10117 }
10028#endif 10118#endif
10029 if (!f) 10119 if (!f)
10030 { 10120 {
10031 f = x_any_window_to_frame (dpyinfo, xev->event); 10121 f = x_any_window_to_frame (dpyinfo, xev->event);
10032 10122
10033 if (!f) 10123 if (!f)
10034 goto XI_OTHER; 10124 goto XI_OTHER;
10035 } 10125 }
10036 10126
10037 found_valuator = true; 10127 found_valuator = true;
10038 10128
10039 if (signbit (delta) != signbit (val->emacs_value)) 10129 if (signbit (delta) != signbit (val->emacs_value))
10040 val->emacs_value = 0; 10130 val->emacs_value = 0;
10041 10131
10042 val->emacs_value += delta; 10132 val->emacs_value += delta;
10043 10133
10044 if (mwheel_coalesce_scroll_events 10134 if (mwheel_coalesce_scroll_events
10045 && (fabs (val->emacs_value) < 1) 10135 && (fabs (val->emacs_value) < 1)
10046 && (fabs (delta) > 0)) 10136 && (fabs (delta) > 0))
10047 continue; 10137 continue;
10048 10138
10049 bool s = signbit (val->emacs_value); 10139 bool s = signbit (val->emacs_value);
10050 inev.ie.kind = (fabs (delta) > 0 10140 inev.ie.kind = (fabs (delta) > 0
10051 ? (val->horizontal 10141 ? (val->horizontal
10052 ? HORIZ_WHEEL_EVENT 10142 ? HORIZ_WHEEL_EVENT
10053 : WHEEL_EVENT) 10143 : WHEEL_EVENT)
10054 : TOUCH_END_EVENT); 10144 : TOUCH_END_EVENT);
10055 inev.ie.timestamp = xev->time; 10145 inev.ie.timestamp = xev->time;
10056 10146
10057 XSETINT (inev.ie.x, lrint (xev->event_x)); 10147 XSETINT (inev.ie.x, lrint (xev->event_x));
10058 XSETINT (inev.ie.y, lrint (xev->event_y)); 10148 XSETINT (inev.ie.y, lrint (xev->event_y));
10059 XSETFRAME (inev.ie.frame_or_window, f); 10149 XSETFRAME (inev.ie.frame_or_window, f);
10060 10150
10061 if (fabs (delta) > 0) 10151 if (fabs (delta) > 0)
10062 { 10152 {
10063 inev.ie.modifiers = !s ? up_modifier : down_modifier; 10153 inev.ie.modifiers = !s ? up_modifier : down_modifier;
10064 inev.ie.modifiers 10154 inev.ie.modifiers
10065 |= x_x_to_emacs_modifiers (dpyinfo, 10155 |= x_x_to_emacs_modifiers (dpyinfo,
10066 xev->mods.effective); 10156 xev->mods.effective);
10067 } 10157 }
10068 10158
10069 window = window_from_coordinates (f, xev->event_x, 10159 window = window_from_coordinates (f, xev->event_x,
10070 xev->event_y, NULL, 10160 xev->event_y, NULL,
10071 false, false); 10161 false, false);
10072 10162
10073 if (WINDOWP (window)) 10163 if (WINDOWP (window))
10074 scroll_height = XWINDOW (window)->pixel_height; 10164 scroll_height = XWINDOW (window)->pixel_height;
10075 else 10165 else
10076 /* EVENT_X and EVENT_Y can be outside the 10166 /* EVENT_X and EVENT_Y can be outside the
10077 frame if F holds the input grab, so fall 10167 frame if F holds the input grab, so fall
10078 back to the height of the frame instead. */ 10168 back to the height of the frame instead. */
10079 scroll_height = FRAME_PIXEL_HEIGHT (f); 10169 scroll_height = FRAME_PIXEL_HEIGHT (f);
10080 10170
10081 scroll_unit = pow (scroll_height, 2.0 / 3.0); 10171 scroll_unit = pow (scroll_height, 2.0 / 3.0);
10082 10172
10083 if (NUMBERP (Vx_scroll_event_delta_factor)) 10173 if (NUMBERP (Vx_scroll_event_delta_factor))
10084 scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor); 10174 scroll_unit *= XFLOATINT (Vx_scroll_event_delta_factor);
10085 10175
10086 if (fabs (delta) > 0) 10176 if (fabs (delta) > 0)
10087 { 10177 {
10088 if (val->horizontal) 10178 if (val->horizontal)
10089 { 10179 {
10090 inev.ie.arg 10180 inev.ie.arg
10091 = list3 (Qnil, 10181 = list3 (Qnil,
10092 make_float (val->emacs_value 10182 make_float (val->emacs_value
10093 * scroll_unit), 10183 * scroll_unit),
10094 make_float (0)); 10184 make_float (0));
10095 } 10185 }
10096 else 10186 else
10097 { 10187 {
10098 inev.ie.arg = list3 (Qnil, make_float (0), 10188 inev.ie.arg = list3 (Qnil, make_float (0),
10099 make_float (val->emacs_value 10189 make_float (val->emacs_value
10100 * scroll_unit)); 10190 * scroll_unit));
10101 } 10191 }
10102 } 10192 }
10103 else 10193 else
10104 { 10194 {
10105 inev.ie.arg = Qnil; 10195 inev.ie.arg = Qnil;
10106 } 10196 }
10107 10197
10108 kbd_buffer_store_event_hold (&inev.ie, hold_quit); 10198 kbd_buffer_store_event_hold (&inev.ie, hold_quit);
10109 10199
10110 val->emacs_value = 0; 10200 val->emacs_value = 0;
10111 } 10201 }
10112 values++; 10202 values++;
10113 } 10203 }
10114 10204
10115 inev.ie.kind = NO_EVENT; 10205 inev.ie.kind = NO_EVENT;
10116 } 10206 }
10117 10207
10118#ifdef HAVE_XWIDGETS 10208#ifdef HAVE_XWIDGETS
10119 if (xv) 10209 if (xv)
10120 { 10210 {
10121 if (found_valuator) 10211 if (found_valuator)
10122 xwidget_scroll (xv, xev->event_x, xev->event_y, 10212 xwidget_scroll (xv, xev->event_x, xev->event_y,
10123 xv_total_x, xv_total_y, xev->mods.effective, 10213 xv_total_x, xv_total_y, xev->mods.effective,
10124 xev->time, any_stop_p); 10214 xev->time, any_stop_p);
10125 else 10215 else
10126 xwidget_motion_notify (xv, xev->event_x, xev->event_y, 10216 xwidget_motion_notify (xv, xev->event_x, xev->event_y,
10127 xev->mods.effective, xev->time); 10217 xev->mods.effective, xev->time);
10128 10218
10129 goto XI_OTHER; 10219 goto XI_OTHER;
10130 } 10220 }
10131#endif 10221#endif
10132 if (found_valuator) 10222 if (found_valuator)
10133 goto XI_OTHER; 10223 goto XI_OTHER;
10134 10224
10135 ev.x = lrint (xev->event_x); 10225 ev.x = lrint (xev->event_x);
10136 ev.y = lrint (xev->event_y); 10226 ev.y = lrint (xev->event_y);
10137 ev.window = xev->event; 10227 ev.window = xev->event;
10138 ev.time = xev->time; 10228 ev.time = xev->time;
10139 10229
10140 previous_help_echo_string = help_echo_string; 10230 previous_help_echo_string = help_echo_string;
10141 help_echo_string = Qnil; 10231 help_echo_string = Qnil;
10142 10232
10143 if (hlinfo->mouse_face_hidden) 10233 if (hlinfo->mouse_face_hidden)
10144 { 10234 {
10145 hlinfo->mouse_face_hidden = false; 10235 hlinfo->mouse_face_hidden = false;
10146 clear_mouse_face (hlinfo); 10236 clear_mouse_face (hlinfo);
10147 } 10237 }
10148 10238
10149 f = mouse_or_wdesc_frame (dpyinfo, xev->event); 10239 f = mouse_or_wdesc_frame (dpyinfo, xev->event);
10150 10240
10151#ifdef USE_GTK 10241#ifdef USE_GTK
10152 if (f && xg_event_is_for_scrollbar (f, event)) 10242 if (f && xg_event_is_for_scrollbar (f, event))
10153 f = 0; 10243 f = 0;
10154#endif 10244#endif
10155 if (f) 10245 if (f)
10156 { 10246 {
10157 /* Maybe generate a SELECT_WINDOW_EVENT for 10247 /* Maybe generate a SELECT_WINDOW_EVENT for
10158 `mouse-autoselect-window' but don't let popup menus 10248 `mouse-autoselect-window' but don't let popup menus
10159 interfere with this (Bug#1261). */ 10249 interfere with this (Bug#1261). */
10160 if (!NILP (Vmouse_autoselect_window) 10250 if (!NILP (Vmouse_autoselect_window)
10161 && !popup_activated () 10251 && !popup_activated ()
10162 /* Don't switch if we're currently in the minibuffer. 10252 /* Don't switch if we're currently in the minibuffer.
10163 This tries to work around problems where the 10253 This tries to work around problems where the
10164 minibuffer gets unselected unexpectedly, and where 10254 minibuffer gets unselected unexpectedly, and where
10165 you then have to move your mouse all the way down to 10255 you then have to move your mouse all the way down to
10166 the minibuffer to select it. */ 10256 the minibuffer to select it. */
10167 && !MINI_WINDOW_P (XWINDOW (selected_window)) 10257 && !MINI_WINDOW_P (XWINDOW (selected_window))
10168 /* With `focus-follows-mouse' non-nil create an event 10258 /* With `focus-follows-mouse' non-nil create an event
10169 also when the target window is on another frame. */ 10259 also when the target window is on another frame. */
10170 && (f == XFRAME (selected_frame) 10260 && (f == XFRAME (selected_frame)
10171 || !NILP (focus_follows_mouse))) 10261 || !NILP (focus_follows_mouse)))
10172 { 10262 {
10173 static Lisp_Object last_mouse_window; 10263 static Lisp_Object last_mouse_window;
10174 Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); 10264 Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
10175 10265
10176 /* A window will be autoselected only when it is not 10266 /* A window will be autoselected only when it is not
10177 selected now and the last mouse movement event was 10267 selected now and the last mouse movement event was
10178 not in it. The remainder of the code is a bit vague 10268 not in it. The remainder of the code is a bit vague
10179 wrt what a "window" is. For immediate autoselection, 10269 wrt what a "window" is. For immediate autoselection,
10180 the window is usually the entire window but for GTK 10270 the window is usually the entire window but for GTK
10181 where the scroll bars don't count. For delayed 10271 where the scroll bars don't count. For delayed
10182 autoselection the window is usually the window's text 10272 autoselection the window is usually the window's text
10183 area including the margins. */ 10273 area including the margins. */
10184 if (WINDOWP (window) 10274 if (WINDOWP (window)
10185 && !EQ (window, last_mouse_window) 10275 && !EQ (window, last_mouse_window)
10186 && !EQ (window, selected_window)) 10276 && !EQ (window, selected_window))
10187 { 10277 {
10188 inev.ie.kind = SELECT_WINDOW_EVENT; 10278 inev.ie.kind = SELECT_WINDOW_EVENT;
10189 inev.ie.frame_or_window = window; 10279 inev.ie.frame_or_window = window;
10190 } 10280 }
10191 10281
10192 /* Remember the last window where we saw the mouse. */ 10282 /* Remember the last window where we saw the mouse. */
10193 last_mouse_window = window; 10283 last_mouse_window = window;
10194 } 10284 }
10195 10285
10196 if (!x_note_mouse_movement (f, &ev)) 10286 if (!x_note_mouse_movement (f, &ev))
10197 help_echo_string = previous_help_echo_string; 10287 help_echo_string = previous_help_echo_string;
10198 } 10288 }
10199 else 10289 else
10200 { 10290 {
10201#ifndef USE_TOOLKIT_SCROLL_BARS 10291#ifndef USE_TOOLKIT_SCROLL_BARS
10202 struct scroll_bar *bar 10292 struct scroll_bar *bar
10203 = x_window_to_scroll_bar (xi_event->display, xev->event, 2); 10293 = x_window_to_scroll_bar (xi_event->display, xev->event, 2);
10204 10294
10205 if (bar) 10295 if (bar)
10206 x_scroll_bar_note_movement (bar, &ev); 10296 x_scroll_bar_note_movement (bar, &ev);
10207#endif /* USE_TOOLKIT_SCROLL_BARS */ 10297#endif /* USE_TOOLKIT_SCROLL_BARS */
10208 10298
10209 /* If we move outside the frame, then we're 10299 /* If we move outside the frame, then we're
10210 certainly no longer on any text in the frame. */ 10300 certainly no longer on any text in the frame. */
10211 clear_mouse_face (hlinfo); 10301 clear_mouse_face (hlinfo);
10212 } 10302 }
10213 10303
10214 /* If the contents of the global variable help_echo_string 10304 /* If the contents of the global variable help_echo_string
10215 has changed, generate a HELP_EVENT. */ 10305 has changed, generate a HELP_EVENT. */
10216 if (!NILP (help_echo_string) 10306 if (!NILP (help_echo_string)
10217 || !NILP (previous_help_echo_string)) 10307 || !NILP (previous_help_echo_string))
10218 do_help = 1; 10308 do_help = 1;
10219 goto XI_OTHER; 10309 goto XI_OTHER;
10310 }
10220 case XI_ButtonRelease: 10311 case XI_ButtonRelease:
10221 case XI_ButtonPress: 10312 case XI_ButtonPress:
10222 { 10313 {
@@ -10242,6 +10333,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10242 10333
10243 device = xi_device_from_id (dpyinfo, xev->deviceid); 10334 device = xi_device_from_id (dpyinfo, xev->deviceid);
10244 10335
10336 if (!device || !device->master_p)
10337 goto XI_OTHER;
10338
10245 bv.button = xev->detail; 10339 bv.button = xev->detail;
10246 bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; 10340 bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
10247 bv.x = lrint (xev->event_x); 10341 bv.x = lrint (xev->event_x);
@@ -10408,6 +10502,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10408 int copy_bufsiz = sizeof (copy_buffer); 10502 int copy_bufsiz = sizeof (copy_buffer);
10409 ptrdiff_t i; 10503 ptrdiff_t i;
10410 int nchars, len; 10504 int nchars, len;
10505 struct xi_device_t *device;
10506
10507 device = xi_device_from_id (dpyinfo, xev->deviceid);
10508
10509 if (!device || !device->master_p)
10510 goto XI_OTHER;
10411 10511
10412#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 10512#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10413 /* Dispatch XI_KeyPress events when in menu. */ 10513 /* Dispatch XI_KeyPress events when in menu. */
@@ -10765,6 +10865,108 @@ handle_one_xevent (struct x_display_info *dpyinfo,
10765 case XI_DeviceChanged: 10865 case XI_DeviceChanged:
10766 x_init_master_valuators (dpyinfo); 10866 x_init_master_valuators (dpyinfo);
10767 goto XI_OTHER; 10867 goto XI_OTHER;
10868#ifdef XI_TouchBegin
10869 case XI_TouchBegin:
10870 {
10871 struct xi_device_t *device;
10872 device = xi_device_from_id (dpyinfo, xev->deviceid);
10873
10874 if (!device)
10875 goto XI_OTHER;
10876
10877 if (xi_find_touch_point (device, xev->detail))
10878 emacs_abort ();
10879
10880 f = x_any_window_to_frame (dpyinfo, xev->event);
10881
10882 if (f && device->direct_p)
10883 {
10884 xi_link_touch_point (device, xev->detail, xev->event_x,
10885 xev->event_y);
10886
10887 inev.ie.kind = TOUCHSCREEN_BEGIN_EVENT;
10888 inev.ie.timestamp = xev->time;
10889 XSETFRAME (inev.ie.frame_or_window, f);
10890 XSETINT (inev.ie.x, lrint (xev->event_x));
10891 XSETINT (inev.ie.y, lrint (xev->event_y));
10892 XSETINT (inev.ie.arg, xev->detail);
10893
10894 XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
10895 xev->detail, xev->event, XIAcceptTouch);
10896 }
10897 else
10898 XIAllowTouchEvents (dpyinfo->display, xev->deviceid,
10899 xev->detail, xev->event, XIRejectTouch);
10900
10901 goto XI_OTHER;
10902 }
10903 case XI_TouchUpdate:
10904 {
10905 struct xi_device_t *device;
10906 struct xi_touch_point_t *touchpoint;
10907 Lisp_Object arg = Qnil;
10908
10909 device = xi_device_from_id (dpyinfo, xev->deviceid);
10910
10911 if (!device)
10912 goto XI_OTHER;
10913
10914 touchpoint = xi_find_touch_point (device, xev->detail);
10915
10916 if (!touchpoint)
10917 emacs_abort ();
10918
10919 touchpoint->x = xev->event_x;
10920 touchpoint->y = xev->event_y;
10921
10922 f = x_any_window_to_frame (dpyinfo, xev->event);
10923
10924 if (f && device->direct_p)
10925 {
10926 inev.ie.kind = TOUCHSCREEN_UPDATE_EVENT;
10927 inev.ie.timestamp = xev->time;
10928 XSETFRAME (inev.ie.frame_or_window, f);
10929
10930 for (touchpoint = device->touchpoints;
10931 touchpoint; touchpoint = touchpoint->next)
10932 {
10933 arg = Fcons (list3i (lrint (touchpoint->x),
10934 lrint (touchpoint->y),
10935 lrint (touchpoint->number)),
10936 arg);
10937 }
10938
10939 inev.ie.arg = arg;
10940 }
10941
10942 goto XI_OTHER;
10943 }
10944 case XI_TouchEnd:
10945 {
10946 struct xi_device_t *device;
10947
10948 device = xi_device_from_id (dpyinfo, xev->deviceid);
10949
10950 if (!device)
10951 goto XI_OTHER;
10952
10953 xi_unlink_touch_point (xev->detail, device);
10954
10955 f = x_any_window_to_frame (dpyinfo, xev->event);
10956
10957 if (f && device->direct_p)
10958 {
10959 inev.ie.kind = TOUCHSCREEN_END_EVENT;
10960 inev.ie.timestamp = xev->time;
10961 XSETFRAME (inev.ie.frame_or_window, f);
10962 XSETINT (inev.ie.x, lrint (xev->event_x));
10963 XSETINT (inev.ie.y, lrint (xev->event_y));
10964 XSETINT (inev.ie.arg, xev->detail);
10965 }
10966
10967 goto XI_OTHER;
10968 }
10969#endif
10768 default: 10970 default:
10769 goto XI_OTHER; 10971 goto XI_OTHER;
10770 } 10972 }