diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 604 |
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) | |||
| 353 | static void | 353 | static void |
| 354 | x_free_xi_devices (struct x_display_info *dpyinfo) | 354 | x_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 | |||
| 567 | static void | ||
| 568 | xi_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 | |||
| 582 | static void | ||
| 583 | xi_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 | |||
| 604 | static struct xi_touch_point_t * | ||
| 605 | xi_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 | |||
| 537 | static void | 620 | static void |
| 538 | xi_grab_or_ungrab_device (struct xi_device_t *device, | 621 | xi_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 | } |