diff options
| author | Po Lu | 2021-11-10 14:04:24 +0800 |
|---|---|---|
| committer | Po Lu | 2021-11-10 14:04:24 +0800 |
| commit | b21f1cabd833aaa370fb0572cfaac2af83856ad5 (patch) | |
| tree | 89c0e64e9c4f4f534efd90904bf15624f70acad1 /src | |
| parent | 12beb77ec83fdda5caf793d724f991b068979006 (diff) | |
| download | emacs-b21f1cabd833aaa370fb0572cfaac2af83856ad5.tar.gz emacs-b21f1cabd833aaa370fb0572cfaac2af83856ad5.zip | |
Revert "Add support for event processing via XInput 2"
This reverts commit 346cfc81247e6bf8e727a27b42f44f2389bd1269.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.in | 7 | ||||
| -rw-r--r-- | src/gtkutil.c | 72 | ||||
| -rw-r--r-- | src/gtkutil.h | 4 | ||||
| -rw-r--r-- | src/xfns.c | 78 | ||||
| -rw-r--r-- | src/xmenu.c | 4 | ||||
| -rw-r--r-- | src/xterm.c | 1086 | ||||
| -rw-r--r-- | src/xterm.h | 42 |
7 files changed, 7 insertions, 1286 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index 4795ade3eaa..4c5535f8ad9 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -258,9 +258,6 @@ XINERAMA_CFLAGS = @XINERAMA_CFLAGS@ | |||
| 258 | XFIXES_LIBS = @XFIXES_LIBS@ | 258 | XFIXES_LIBS = @XFIXES_LIBS@ |
| 259 | XFIXES_CFLAGS = @XFIXES_CFLAGS@ | 259 | XFIXES_CFLAGS = @XFIXES_CFLAGS@ |
| 260 | 260 | ||
| 261 | XINPUT_LIBS = @XINPUT_LIBS@ | ||
| 262 | XINPUT_CFLAGS = @XINPUT_CFLAGS@ | ||
| 263 | |||
| 264 | XDBE_LIBS = @XDBE_LIBS@ | 261 | XDBE_LIBS = @XDBE_LIBS@ |
| 265 | XDBE_CFLAGS = @XDBE_CFLAGS@ | 262 | XDBE_CFLAGS = @XDBE_CFLAGS@ |
| 266 | 263 | ||
| @@ -377,7 +374,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \ | |||
| 377 | $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ | 374 | $(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \ |
| 378 | $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \ | 375 | $(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \ |
| 379 | $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ | 376 | $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \ |
| 380 | $(WEBKIT_CFLAGS) $(WEBP_CFLAGS) $(LCMS2_CFLAGS) $(XINPUT_CFLAGS) \ | 377 | $(WEBKIT_CFLAGS) $(WEBP_CFLAGS) $(LCMS2_CFLAGS) \ |
| 381 | $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ | 378 | $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \ |
| 382 | $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ | 379 | $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \ |
| 383 | $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \ | 380 | $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \ |
| @@ -527,7 +524,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ | |||
| 527 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ | 524 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ |
| 528 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ | 525 | $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \ |
| 529 | $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ | 526 | $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \ |
| 530 | $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) | 527 | $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) |
| 531 | 528 | ||
| 532 | ## FORCE it so that admin/unidata can decide whether this file is | 529 | ## FORCE it so that admin/unidata can decide whether this file is |
| 533 | ## up-to-date. Although since charprop depends on bootstrap-emacs, | 530 | ## up-to-date. Although since charprop depends on bootstrap-emacs, |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 9e676cd025b..a9eabf47d8f 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -47,10 +47,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 47 | 47 | ||
| 48 | #include <gdk/gdkkeysyms.h> | 48 | #include <gdk/gdkkeysyms.h> |
| 49 | 49 | ||
| 50 | #ifdef HAVE_XINPUT2 | ||
| 51 | #include <X11/extensions/XInput2.h> | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #ifdef HAVE_XFT | 50 | #ifdef HAVE_XFT |
| 55 | #include <X11/Xft/Xft.h> | 51 | #include <X11/Xft/Xft.h> |
| 56 | #endif | 52 | #endif |
| @@ -843,23 +839,6 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, | |||
| 843 | } | 839 | } |
| 844 | #endif | 840 | #endif |
| 845 | 841 | ||
| 846 | #if defined HAVE_GTK3 && defined HAVE_XINPUT2 | ||
| 847 | bool | ||
| 848 | xg_is_menu_window (Display *dpy, Window wdesc) | ||
| 849 | { | ||
| 850 | GtkWidget *gwdesc = xg_win_to_widget (dpy, wdesc); | ||
| 851 | |||
| 852 | if (GTK_IS_WINDOW (gwdesc)) | ||
| 853 | { | ||
| 854 | GtkWidget *fw = gtk_bin_get_child (GTK_BIN (gwdesc)); | ||
| 855 | if (GTK_IS_MENU (fw)) | ||
| 856 | return true; | ||
| 857 | } | ||
| 858 | |||
| 859 | return false; | ||
| 860 | } | ||
| 861 | #endif | ||
| 862 | |||
| 863 | /* Make a geometry string and pass that to GTK. It seems this is the | 842 | /* Make a geometry string and pass that to GTK. It seems this is the |
| 864 | only way to get geometry position right if the user explicitly | 843 | only way to get geometry position right if the user explicitly |
| 865 | asked for a position when starting Emacs. | 844 | asked for a position when starting Emacs. |
| @@ -3610,18 +3589,6 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) | |||
| 3610 | 3589 | ||
| 3611 | if (! x->menubar_widget) return 0; | 3590 | if (! x->menubar_widget) return 0; |
| 3612 | 3591 | ||
| 3613 | #ifdef HAVE_XINPUT2 | ||
| 3614 | XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; | ||
| 3615 | if (event->type == GenericEvent) /* XI_ButtonPress or XI_ButtonRelease */ | ||
| 3616 | { | ||
| 3617 | if (! (xev->event_x >= 0 | ||
| 3618 | && xev->event_x < FRAME_PIXEL_WIDTH (f) | ||
| 3619 | && xev->event_y >= 0 | ||
| 3620 | && xev->event_y < FRAME_MENUBAR_HEIGHT (f))) | ||
| 3621 | return 0; | ||
| 3622 | } | ||
| 3623 | else | ||
| 3624 | #endif | ||
| 3625 | if (! (event->xbutton.x >= 0 | 3592 | if (! (event->xbutton.x >= 0 |
| 3626 | && event->xbutton.x < FRAME_PIXEL_WIDTH (f) | 3593 | && event->xbutton.x < FRAME_PIXEL_WIDTH (f) |
| 3627 | && event->xbutton.y >= 0 | 3594 | && event->xbutton.y >= 0 |
| @@ -3630,12 +3597,7 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event) | |||
| 3630 | return 0; | 3597 | return 0; |
| 3631 | 3598 | ||
| 3632 | gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | 3599 | gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); |
| 3633 | #ifdef HAVE_XINPUT2 | 3600 | gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); |
| 3634 | if (event->type == GenericEvent) | ||
| 3635 | gw = gdk_x11_window_lookup_for_display (gdpy, xev->event); | ||
| 3636 | else | ||
| 3637 | #endif | ||
| 3638 | gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window); | ||
| 3639 | if (! gw) return 0; | 3601 | if (! gw) return 0; |
| 3640 | gevent.any.window = gw; | 3602 | gevent.any.window = gw; |
| 3641 | gevent.any.type = GDK_NOTHING; | 3603 | gevent.any.type = GDK_NOTHING; |
| @@ -4282,20 +4244,7 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) | |||
| 4282 | { | 4244 | { |
| 4283 | bool retval = 0; | 4245 | bool retval = 0; |
| 4284 | 4246 | ||
| 4285 | #ifdef HAVE_XINPUT2 | ||
| 4286 | XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data; | ||
| 4287 | if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 4288 | && event->type == GenericEvent | ||
| 4289 | && (event->xgeneric.extension | ||
| 4290 | == FRAME_DISPLAY_INFO (f)->xi2_opcode) | ||
| 4291 | && ((event->xgeneric.evtype == XI_ButtonPress | ||
| 4292 | && xev->detail < 4) | ||
| 4293 | || (event->xgeneric.evtype == XI_Motion))) | ||
| 4294 | || (event->type == ButtonPress | ||
| 4295 | && event->xbutton.button < 4))) | ||
| 4296 | #else | ||
| 4297 | if (f && event->type == ButtonPress && event->xbutton.button < 4) | 4247 | if (f && event->type == ButtonPress && event->xbutton.button < 4) |
| 4298 | #endif /* HAVE_XINPUT2 */ | ||
| 4299 | { | 4248 | { |
| 4300 | /* Check if press occurred outside the edit widget. */ | 4249 | /* Check if press occurred outside the edit widget. */ |
| 4301 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); | 4250 | GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); |
| @@ -4313,29 +4262,10 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event) | |||
| 4313 | gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL); | 4262 | gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL); |
| 4314 | #endif | 4263 | #endif |
| 4315 | retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget); | 4264 | retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget); |
| 4316 | #ifdef HAVE_XINPUT2 | ||
| 4317 | GtkWidget *grab = gtk_grab_get_current (); | ||
| 4318 | if (event->type == GenericEvent | ||
| 4319 | && event->xgeneric.evtype == XI_Motion) | ||
| 4320 | retval = retval || (grab && GTK_IS_SCROLLBAR (grab)); | ||
| 4321 | #endif | ||
| 4322 | } | 4265 | } |
| 4323 | #ifdef HAVE_XINPUT2 | ||
| 4324 | else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2 | ||
| 4325 | && event->type == GenericEvent | ||
| 4326 | && (event->xgeneric.extension | ||
| 4327 | == FRAME_DISPLAY_INFO (f)->xi2_opcode) | ||
| 4328 | && ((event->xgeneric.evtype == XI_ButtonRelease | ||
| 4329 | && xev->detail < 4) | ||
| 4330 | || (event->xgeneric.evtype == XI_Motion))) | ||
| 4331 | || ((event->type == ButtonRelease | ||
| 4332 | && event->xbutton.button < 4) | ||
| 4333 | || event->type == MotionNotify))) | ||
| 4334 | #else | ||
| 4335 | else if (f | 4266 | else if (f |
| 4336 | && ((event->type == ButtonRelease && event->xbutton.button < 4) | 4267 | && ((event->type == ButtonRelease && event->xbutton.button < 4) |
| 4337 | || event->type == MotionNotify)) | 4268 | || event->type == MotionNotify)) |
| 4338 | #endif /* HAVE_XINPUT2 */ | ||
| 4339 | { | 4269 | { |
| 4340 | /* If we are releasing or moving the scroll bar, it has the grab. */ | 4270 | /* If we are releasing or moving the scroll bar, it has the grab. */ |
| 4341 | GtkWidget *w = gtk_grab_get_current (); | 4271 | GtkWidget *w = gtk_grab_get_current (); |
diff --git a/src/gtkutil.h b/src/gtkutil.h index 95dd75b7fad..31a12cd5d3c 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -192,10 +192,6 @@ extern Lisp_Object xg_get_page_setup (void); | |||
| 192 | extern void xg_print_frames_dialog (Lisp_Object); | 192 | extern void xg_print_frames_dialog (Lisp_Object); |
| 193 | #endif | 193 | #endif |
| 194 | 194 | ||
| 195 | #if defined HAVE_GTK3 && defined HAVE_XINPUT2 | ||
| 196 | extern bool xg_is_menu_window (Display *dpy, Window); | ||
| 197 | #endif | ||
| 198 | |||
| 199 | /* Mark all callback data that are Lisp_object:s during GC. */ | 195 | /* Mark all callback data that are Lisp_object:s during GC. */ |
| 200 | extern void xg_mark_data (void); | 196 | extern void xg_mark_data (void); |
| 201 | 197 | ||
diff --git a/src/xfns.c b/src/xfns.c index c792826e6be..785ae3baca5 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -57,10 +57,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 57 | #include <X11/extensions/Xdbe.h> | 57 | #include <X11/extensions/Xdbe.h> |
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | #ifdef HAVE_XINPUT2 | ||
| 61 | #include <X11/extensions/XInput2.h> | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifdef USE_X_TOOLKIT | 60 | #ifdef USE_X_TOOLKIT |
| 65 | #include <X11/Shell.h> | 61 | #include <X11/Shell.h> |
| 66 | 62 | ||
| @@ -3078,43 +3074,6 @@ x_window (struct frame *f, long window_prompting) | |||
| 3078 | class_hints.res_class = SSDATA (Vx_resource_class); | 3074 | class_hints.res_class = SSDATA (Vx_resource_class); |
| 3079 | XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); | 3075 | XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints); |
| 3080 | 3076 | ||
| 3081 | #ifdef HAVE_XINPUT2 | ||
| 3082 | if (FRAME_DISPLAY_INFO (f)->supports_xi2) | ||
| 3083 | { | ||
| 3084 | XIEventMask mask; | ||
| 3085 | ptrdiff_t l = XIMaskLen (XI_LASTEVENT); | ||
| 3086 | unsigned char *m; | ||
| 3087 | mask.mask = m = alloca (l); | ||
| 3088 | memset (m, 0, l); | ||
| 3089 | mask.mask_len = l; | ||
| 3090 | mask.deviceid = XIAllMasterDevices; | ||
| 3091 | |||
| 3092 | XISetMask (m, XI_ButtonPress); | ||
| 3093 | XISetMask (m, XI_ButtonRelease); | ||
| 3094 | XISetMask (m, XI_KeyPress); | ||
| 3095 | XISetMask (m, XI_KeyRelease); | ||
| 3096 | XISetMask (m, XI_Motion); | ||
| 3097 | XISetMask (m, XI_Enter); | ||
| 3098 | XISetMask (m, XI_Leave); | ||
| 3099 | XISetMask (m, XI_FocusIn); | ||
| 3100 | XISetMask (m, XI_FocusOut); | ||
| 3101 | XISetMask (m, XI_DeviceChanged); | ||
| 3102 | |||
| 3103 | XISelectEvents (FRAME_X_DISPLAY (f), | ||
| 3104 | FRAME_X_WINDOW (f), | ||
| 3105 | &mask, 1); | ||
| 3106 | |||
| 3107 | mask.deviceid = XIAllDevices; | ||
| 3108 | memset (m, 0, l); | ||
| 3109 | XISetMask (m, XI_PropertyEvent); | ||
| 3110 | XISetMask (m, XI_HierarchyChanged); | ||
| 3111 | |||
| 3112 | XISelectEvents (FRAME_X_DISPLAY (f), | ||
| 3113 | FRAME_X_WINDOW (f), | ||
| 3114 | &mask, 1); | ||
| 3115 | } | ||
| 3116 | #endif | ||
| 3117 | |||
| 3118 | #ifdef HAVE_X_I18N | 3077 | #ifdef HAVE_X_I18N |
| 3119 | FRAME_XIC (f) = NULL; | 3078 | FRAME_XIC (f) = NULL; |
| 3120 | if (use_xim) | 3079 | if (use_xim) |
| @@ -3295,43 +3254,6 @@ x_window (struct frame *f) | |||
| 3295 | } | 3254 | } |
| 3296 | #endif /* HAVE_X_I18N */ | 3255 | #endif /* HAVE_X_I18N */ |
| 3297 | 3256 | ||
| 3298 | #ifdef HAVE_XINPUT2 | ||
| 3299 | if (FRAME_DISPLAY_INFO (f)->supports_xi2) | ||
| 3300 | { | ||
| 3301 | XIEventMask mask; | ||
| 3302 | ptrdiff_t l = XIMaskLen (XI_LASTEVENT); | ||
| 3303 | unsigned char *m; | ||
| 3304 | mask.mask = m = alloca (l); | ||
| 3305 | memset (m, 0, l); | ||
| 3306 | mask.mask_len = l; | ||
| 3307 | mask.deviceid = XIAllMasterDevices; | ||
| 3308 | |||
| 3309 | XISetMask (m, XI_ButtonPress); | ||
| 3310 | XISetMask (m, XI_ButtonRelease); | ||
| 3311 | XISetMask (m, XI_KeyPress); | ||
| 3312 | XISetMask (m, XI_KeyRelease); | ||
| 3313 | XISetMask (m, XI_Motion); | ||
| 3314 | XISetMask (m, XI_Enter); | ||
| 3315 | XISetMask (m, XI_Leave); | ||
| 3316 | XISetMask (m, XI_FocusIn); | ||
| 3317 | XISetMask (m, XI_FocusOut); | ||
| 3318 | XISetMask (m, XI_DeviceChanged); | ||
| 3319 | |||
| 3320 | XISelectEvents (FRAME_X_DISPLAY (f), | ||
| 3321 | FRAME_X_WINDOW (f), | ||
| 3322 | &mask, 1); | ||
| 3323 | |||
| 3324 | mask.deviceid = XIAllDevices; | ||
| 3325 | memset (m, 0, l); | ||
| 3326 | XISetMask (m, XI_PropertyEvent); | ||
| 3327 | XISetMask (m, XI_HierarchyChanged); | ||
| 3328 | |||
| 3329 | XISelectEvents (FRAME_X_DISPLAY (f), | ||
| 3330 | FRAME_X_WINDOW (f), | ||
| 3331 | &mask, 1); | ||
| 3332 | } | ||
| 3333 | #endif | ||
| 3334 | |||
| 3335 | validate_x_resource_name (); | 3257 | validate_x_resource_name (); |
| 3336 | 3258 | ||
| 3337 | class_hints.res_name = SSDATA (Vx_resource_name); | 3259 | class_hints.res_name = SSDATA (Vx_resource_name); |
diff --git a/src/xmenu.c b/src/xmenu.c index 07255911f97..ea2cbab2030 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -105,11 +105,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 105 | 105 | ||
| 106 | /* Flag which when set indicates a dialog or menu has been posted by | 106 | /* Flag which when set indicates a dialog or menu has been posted by |
| 107 | Xt on behalf of one of the widget sets. */ | 107 | Xt on behalf of one of the widget sets. */ |
| 108 | #ifndef HAVE_XINPUT2 | ||
| 109 | static int popup_activated_flag; | 108 | static int popup_activated_flag; |
| 110 | #else | ||
| 111 | int popup_activated_flag; | ||
| 112 | #endif | ||
| 113 | 109 | ||
| 114 | 110 | ||
| 115 | #ifdef USE_X_TOOLKIT | 111 | #ifdef USE_X_TOOLKIT |
diff --git a/src/xterm.c b/src/xterm.c index d0da6ad6a6d..172abe919dd 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -42,10 +42,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 42 | #include <X11/extensions/Xdbe.h> | 42 | #include <X11/extensions/Xdbe.h> |
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #ifdef HAVE_XINPUT2 | ||
| 46 | #include <X11/extensions/XInput2.h> | ||
| 47 | #endif | ||
| 48 | |||
| 49 | /* Load sys/types.h if not already loaded. | 45 | /* Load sys/types.h if not already loaded. |
| 50 | In some systems loading it twice is suicidal. */ | 46 | In some systems loading it twice is suicidal. */ |
| 51 | #ifndef makedev | 47 | #ifndef makedev |
| @@ -227,15 +223,9 @@ static bool x_handle_net_wm_state (struct frame *, const XPropertyEvent *); | |||
| 227 | static void x_check_fullscreen (struct frame *); | 223 | static void x_check_fullscreen (struct frame *); |
| 228 | static void x_check_expected_move (struct frame *, int, int); | 224 | static void x_check_expected_move (struct frame *, int, int); |
| 229 | static void x_sync_with_move (struct frame *, int, int, bool); | 225 | static void x_sync_with_move (struct frame *, int, int, bool); |
| 230 | #ifndef HAVE_XINPUT2 | ||
| 231 | static int handle_one_xevent (struct x_display_info *, | 226 | static int handle_one_xevent (struct x_display_info *, |
| 232 | const XEvent *, int *, | 227 | const XEvent *, int *, |
| 233 | struct input_event *); | 228 | struct input_event *); |
| 234 | #else | ||
| 235 | static int handle_one_xevent (struct x_display_info *, | ||
| 236 | XEvent *, int *, | ||
| 237 | struct input_event *); | ||
| 238 | #endif | ||
| 239 | #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK | 229 | #if ! (defined USE_X_TOOLKIT || defined USE_MOTIF) && defined USE_GTK |
| 240 | static int x_dispatch_event (XEvent *, Display *); | 230 | static int x_dispatch_event (XEvent *, Display *); |
| 241 | #endif | 231 | #endif |
| @@ -345,156 +335,6 @@ x_extension_initialize (struct x_display_info *dpyinfo) | |||
| 345 | dpyinfo->ext_codes = ext_codes; | 335 | dpyinfo->ext_codes = ext_codes; |
| 346 | } | 336 | } |
| 347 | 337 | ||
| 348 | |||
| 349 | #ifdef HAVE_XINPUT2 | ||
| 350 | |||
| 351 | /* Free all XI2 devices on dpyinfo. */ | ||
| 352 | static void | ||
| 353 | x_free_xi_devices (struct x_display_info *dpyinfo) | ||
| 354 | { | ||
| 355 | block_input (); | ||
| 356 | |||
| 357 | if (dpyinfo->num_devices) | ||
| 358 | { | ||
| 359 | for (int i = 0; i < dpyinfo->num_devices; ++i) | ||
| 360 | xfree (dpyinfo->devices[i].valuators); | ||
| 361 | |||
| 362 | xfree (dpyinfo->devices); | ||
| 363 | dpyinfo->devices = NULL; | ||
| 364 | dpyinfo->num_devices = 0; | ||
| 365 | } | ||
| 366 | |||
| 367 | unblock_input (); | ||
| 368 | } | ||
| 369 | |||
| 370 | /* Setup valuator tracking for XI2 master devices on | ||
| 371 | DPYINFO->display. */ | ||
| 372 | |||
| 373 | static void | ||
| 374 | x_init_master_valuators (struct x_display_info *dpyinfo) | ||
| 375 | { | ||
| 376 | int ndevices; | ||
| 377 | XIDeviceInfo *infos; | ||
| 378 | |||
| 379 | block_input (); | ||
| 380 | x_free_xi_devices (dpyinfo); | ||
| 381 | infos = XIQueryDevice (dpyinfo->display, | ||
| 382 | XIAllMasterDevices, | ||
| 383 | &ndevices); | ||
| 384 | |||
| 385 | if (!ndevices) | ||
| 386 | { | ||
| 387 | XIFreeDeviceInfo (infos); | ||
| 388 | unblock_input (); | ||
| 389 | return; | ||
| 390 | } | ||
| 391 | |||
| 392 | int actual_devices = 0; | ||
| 393 | dpyinfo->devices = xmalloc (sizeof *dpyinfo->devices * ndevices); | ||
| 394 | |||
| 395 | for (int i = 0; i < ndevices; ++i) | ||
| 396 | { | ||
| 397 | XIDeviceInfo *device = &infos[i]; | ||
| 398 | |||
| 399 | if (device->enabled) | ||
| 400 | { | ||
| 401 | int actual_valuator_count = 0; | ||
| 402 | struct xi_device_t *xi_device = | ||
| 403 | &dpyinfo->devices[actual_devices++]; | ||
| 404 | xi_device->device_id = device->deviceid; | ||
| 405 | xi_device->valuators = | ||
| 406 | xmalloc (sizeof *xi_device->valuators * device->num_classes); | ||
| 407 | |||
| 408 | for (int c = 0; c < device->num_classes; ++c) | ||
| 409 | { | ||
| 410 | switch (device->classes[c]->type) | ||
| 411 | { | ||
| 412 | #ifdef XIScrollClass /* XInput 2.1 */ | ||
| 413 | case XIScrollClass: | ||
| 414 | { | ||
| 415 | XIScrollClassInfo *info = | ||
| 416 | (XIScrollClassInfo *) device->classes[c]; | ||
| 417 | struct xi_scroll_valuator_t *valuator = | ||
| 418 | &xi_device->valuators[actual_valuator_count++]; | ||
| 419 | |||
| 420 | valuator->horizontal = (info->scroll_type == XIScrollTypeHorizontal); | ||
| 421 | valuator->invalid_p = true; | ||
| 422 | valuator->emacs_value = DBL_MIN; | ||
| 423 | valuator->increment = info->increment; | ||
| 424 | valuator->number = info->number; | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | #endif | ||
| 428 | default: | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | xi_device->scroll_valuator_count = actual_valuator_count; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | dpyinfo->num_devices = actual_devices; | ||
| 437 | XIFreeDeviceInfo (infos); | ||
| 438 | unblock_input (); | ||
| 439 | } | ||
| 440 | |||
| 441 | /* Return the delta of the scroll valuator VALUATOR_NUMBER under | ||
| 442 | DEVICE_ID in the display DPYINFO with VALUE. The valuator's | ||
| 443 | valuator will be set to VALUE afterwards. In case no scroll | ||
| 444 | valuator is found, or if device_id is not known to Emacs, DBL_MAX | ||
| 445 | is returned. Otherwise, the valuator is returned in | ||
| 446 | VALUATOR_RETURN. */ | ||
| 447 | static double | ||
| 448 | x_get_scroll_valuator_delta (struct x_display_info *dpyinfo, int device_id, | ||
| 449 | int valuator_number, double value, | ||
| 450 | struct xi_scroll_valuator_t **valuator_return) | ||
| 451 | { | ||
| 452 | block_input (); | ||
| 453 | |||
| 454 | for (int i = 0; i < dpyinfo->num_devices; ++i) | ||
| 455 | { | ||
| 456 | struct xi_device_t *device = &dpyinfo->devices[i]; | ||
| 457 | |||
| 458 | if (device->device_id == device_id) | ||
| 459 | { | ||
| 460 | for (int j = 0; j < device->scroll_valuator_count; ++j) | ||
| 461 | { | ||
| 462 | struct xi_scroll_valuator_t *sv = &device->valuators[j]; | ||
| 463 | |||
| 464 | if (sv->number == valuator_number) | ||
| 465 | { | ||
| 466 | if (sv->invalid_p) | ||
| 467 | { | ||
| 468 | sv->current_value = value; | ||
| 469 | sv->invalid_p = false; | ||
| 470 | *valuator_return = sv; | ||
| 471 | |||
| 472 | unblock_input (); | ||
| 473 | return 0.0; | ||
| 474 | } | ||
| 475 | else | ||
| 476 | { | ||
| 477 | double delta = sv->current_value - value; | ||
| 478 | sv->current_value = value; | ||
| 479 | *valuator_return = sv; | ||
| 480 | |||
| 481 | unblock_input (); | ||
| 482 | return delta / sv->increment; | ||
| 483 | } | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | unblock_input (); | ||
| 488 | return DBL_MAX; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | unblock_input (); | ||
| 493 | return DBL_MAX; | ||
| 494 | } | ||
| 495 | |||
| 496 | #endif | ||
| 497 | |||
| 498 | void | 338 | void |
| 499 | x_cr_destroy_frame_context (struct frame *f) | 339 | x_cr_destroy_frame_context (struct frame *f) |
| 500 | { | 340 | { |
| @@ -4928,16 +4768,7 @@ static struct frame * | |||
| 4928 | x_menubar_window_to_frame (struct x_display_info *dpyinfo, | 4768 | x_menubar_window_to_frame (struct x_display_info *dpyinfo, |
| 4929 | const XEvent *event) | 4769 | const XEvent *event) |
| 4930 | { | 4770 | { |
| 4931 | Window wdesc; | 4771 | Window wdesc = event->xany.window; |
| 4932 | #ifdef HAVE_XINPUT2 | ||
| 4933 | if (event->type == GenericEvent | ||
| 4934 | && dpyinfo->supports_xi2 | ||
| 4935 | && (event->xcookie.evtype == XI_ButtonPress | ||
| 4936 | || event->xcookie.evtype == XI_ButtonRelease)) | ||
| 4937 | wdesc = ((XIDeviceEvent *) event->xcookie.data)->event; | ||
| 4938 | else | ||
| 4939 | #endif | ||
| 4940 | wdesc = event->xany.window; | ||
| 4941 | Lisp_Object tail, frame; | 4772 | Lisp_Object tail, frame; |
| 4942 | struct frame *f; | 4773 | struct frame *f; |
| 4943 | struct x_output *x; | 4774 | struct x_output *x; |
| @@ -5040,29 +4871,6 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame, | |||
| 5040 | } | 4871 | } |
| 5041 | break; | 4872 | break; |
| 5042 | 4873 | ||
| 5043 | #ifdef HAVE_XINPUT2 | ||
| 5044 | case GenericEvent: | ||
| 5045 | { | ||
| 5046 | XIEvent *xi_event = (XIEvent *) event; | ||
| 5047 | |||
| 5048 | struct frame *focus_frame = dpyinfo->x_focus_event_frame; | ||
| 5049 | int focus_state | ||
| 5050 | = focus_frame ? focus_frame->output_data.x->focus_state : 0; | ||
| 5051 | |||
| 5052 | if (!((xi_event->evtype == XI_Enter | ||
| 5053 | || xi_event->evtype == XI_Leave) | ||
| 5054 | && (focus_state & FOCUS_EXPLICIT))) | ||
| 5055 | x_focus_changed ((xi_event->evtype == XI_Enter | ||
| 5056 | || xi_event->evtype == XI_FocusIn | ||
| 5057 | ? FocusIn : FocusOut), | ||
| 5058 | (xi_event->evtype == XI_Enter | ||
| 5059 | || xi_event->evtype == XI_Leave | ||
| 5060 | ? FOCUS_IMPLICIT : FOCUS_EXPLICIT), | ||
| 5061 | dpyinfo, frame, bufp); | ||
| 5062 | break; | ||
| 5063 | } | ||
| 5064 | #endif | ||
| 5065 | |||
| 5066 | case FocusIn: | 4874 | case FocusIn: |
| 5067 | case FocusOut: | 4875 | case FocusOut: |
| 5068 | /* Ignore transient focus events from hotkeys, window manager | 4876 | /* Ignore transient focus events from hotkeys, window manager |
| @@ -8167,11 +7975,7 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc) | |||
| 8167 | 7975 | ||
| 8168 | static int | 7976 | static int |
| 8169 | handle_one_xevent (struct x_display_info *dpyinfo, | 7977 | handle_one_xevent (struct x_display_info *dpyinfo, |
| 8170 | #ifndef HAVE_XINPUT2 | ||
| 8171 | const XEvent *event, | 7978 | const XEvent *event, |
| 8172 | #else | ||
| 8173 | XEvent *event, | ||
| 8174 | #endif | ||
| 8175 | int *finish, struct input_event *hold_quit) | 7979 | int *finish, struct input_event *hold_quit) |
| 8176 | { | 7980 | { |
| 8177 | union buffered_input_event inev; | 7981 | union buffered_input_event inev; |
| @@ -8197,14 +8001,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8197 | inev.ie.kind = NO_EVENT; | 8001 | inev.ie.kind = NO_EVENT; |
| 8198 | inev.ie.arg = Qnil; | 8002 | inev.ie.arg = Qnil; |
| 8199 | 8003 | ||
| 8200 | #ifdef HAVE_XINPUT2 | 8004 | any = x_any_window_to_frame (dpyinfo, event->xany.window); |
| 8201 | if (event->type != GenericEvent) | ||
| 8202 | #endif | ||
| 8203 | any = x_any_window_to_frame (dpyinfo, event->xany.window); | ||
| 8204 | #ifdef HAVE_XINPUT2 | ||
| 8205 | else | ||
| 8206 | any = NULL; | ||
| 8207 | #endif | ||
| 8208 | 8005 | ||
| 8209 | if (any && any->wait_event_type == event->type) | 8006 | if (any && any->wait_event_type == event->type) |
| 8210 | any->wait_event_type = 0; /* Indicates we got it. */ | 8007 | any->wait_event_type = 0; /* Indicates we got it. */ |
| @@ -8683,10 +8480,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 8683 | goto OTHER; | 8480 | goto OTHER; |
| 8684 | 8481 | ||
| 8685 | case MapNotify: | 8482 | case MapNotify: |
| 8686 | #if defined HAVE_XINPUT2 && defined HAVE_GTK3 | ||
| 8687 | if (xg_is_menu_window (dpyinfo->display, event->xmap.window)) | ||
| 8688 | popup_activated_flag = 1; | ||
| 8689 | #endif | ||
| 8690 | /* We use x_top_window_to_frame because map events can | 8483 | /* We use x_top_window_to_frame because map events can |
| 8691 | come for sub-windows and they don't mean that the | 8484 | come for sub-windows and they don't mean that the |
| 8692 | frame is visible. */ | 8485 | frame is visible. */ |
| @@ -9725,832 +9518,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 9725 | case DestroyNotify: | 9518 | case DestroyNotify: |
| 9726 | xft_settings_event (dpyinfo, event); | 9519 | xft_settings_event (dpyinfo, event); |
| 9727 | break; | 9520 | break; |
| 9728 | #ifdef HAVE_XINPUT2 | ||
| 9729 | case GenericEvent: | ||
| 9730 | { | ||
| 9731 | if (!dpyinfo->supports_xi2) | ||
| 9732 | goto OTHER; | ||
| 9733 | if (event->xgeneric.extension != dpyinfo->xi2_opcode) | ||
| 9734 | /* Not an XI2 event. */ | ||
| 9735 | goto OTHER; | ||
| 9736 | bool must_free_data = false; | ||
| 9737 | XIEvent *xi_event = (XIEvent *) event->xcookie.data; | ||
| 9738 | /* Sometimes the event is already claimed by GTK, which | ||
| 9739 | will free its data in due course. */ | ||
| 9740 | if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie)) | ||
| 9741 | { | ||
| 9742 | must_free_data = true; | ||
| 9743 | xi_event = (XIEvent *) event->xcookie.data; | ||
| 9744 | } | ||
| 9745 | |||
| 9746 | XIDeviceEvent *xev = (XIDeviceEvent *) xi_event; | ||
| 9747 | XILeaveEvent *leave = (XILeaveEvent *) xi_event; | ||
| 9748 | XIEnterEvent *enter = (XIEnterEvent *) xi_event; | ||
| 9749 | XIFocusInEvent *focusin = (XIFocusInEvent *) xi_event; | ||
| 9750 | XIFocusOutEvent *focusout = (XIFocusOutEvent *) xi_event; | ||
| 9751 | XIValuatorState *states; | ||
| 9752 | double *values; | ||
| 9753 | bool found_valuator = false; | ||
| 9754 | |||
| 9755 | /* A fake XMotionEvent for x_note_mouse_movement. */ | ||
| 9756 | XMotionEvent ev; | ||
| 9757 | /* A fake XButtonEvent for x_construct_mouse_click. */ | ||
| 9758 | XButtonEvent bv; | ||
| 9759 | |||
| 9760 | if (!xi_event) | ||
| 9761 | { | ||
| 9762 | eassert (!must_free_data); | ||
| 9763 | goto OTHER; | ||
| 9764 | } | ||
| 9765 | |||
| 9766 | switch (event->xcookie.evtype) | ||
| 9767 | { | ||
| 9768 | case XI_FocusIn: | ||
| 9769 | any = x_any_window_to_frame (dpyinfo, focusin->event); | ||
| 9770 | #ifndef USE_GTK | ||
| 9771 | /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap | ||
| 9772 | minimized/iconified windows; thus, for those WMs we won't get | ||
| 9773 | a MapNotify when unminimizing/deconifying. Check here if we | ||
| 9774 | are deiconizing a window (Bug42655). | ||
| 9775 | |||
| 9776 | But don't do that on GTK since it may cause a plain invisible | ||
| 9777 | frame get reported as iconified, compare | ||
| 9778 | https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. | ||
| 9779 | That is fixed above but bites us here again. */ | ||
| 9780 | f = any; | ||
| 9781 | if (f && FRAME_ICONIFIED_P (f)) | ||
| 9782 | { | ||
| 9783 | SET_FRAME_VISIBLE (f, 1); | ||
| 9784 | SET_FRAME_ICONIFIED (f, false); | ||
| 9785 | f->output_data.x->has_been_visible = true; | ||
| 9786 | inev.ie.kind = DEICONIFY_EVENT; | ||
| 9787 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 9788 | } | ||
| 9789 | #endif /* USE_GTK */ | ||
| 9790 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | ||
| 9791 | goto XI_OTHER; | ||
| 9792 | case XI_FocusOut: | ||
| 9793 | any = x_any_window_to_frame (dpyinfo, focusout->event); | ||
| 9794 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | ||
| 9795 | goto XI_OTHER; | ||
| 9796 | case XI_Enter: | ||
| 9797 | any = x_any_window_to_frame (dpyinfo, enter->event); | ||
| 9798 | ev.x = lrint (enter->event_x); | ||
| 9799 | ev.y = lrint (enter->event_y); | ||
| 9800 | ev.window = leave->event; | ||
| 9801 | |||
| 9802 | x_display_set_last_user_time (dpyinfo, xi_event->time); | ||
| 9803 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | ||
| 9804 | f = any; | ||
| 9805 | |||
| 9806 | if (f && x_mouse_click_focus_ignore_position) | ||
| 9807 | ignore_next_mouse_click_timeout = xi_event->time + 200; | ||
| 9808 | |||
| 9809 | /* EnterNotify counts as mouse movement, | ||
| 9810 | so update things that depend on mouse position. */ | ||
| 9811 | if (f && !f->output_data.x->hourglass_p) | ||
| 9812 | x_note_mouse_movement (f, &ev); | ||
| 9813 | #ifdef USE_GTK | ||
| 9814 | /* We may get an EnterNotify on the buttons in the toolbar. In that | ||
| 9815 | case we moved out of any highlighted area and need to note this. */ | ||
| 9816 | if (!f && dpyinfo->last_mouse_glyph_frame) | ||
| 9817 | x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); | ||
| 9818 | #endif | ||
| 9819 | goto XI_OTHER; | ||
| 9820 | case XI_Leave: | ||
| 9821 | ev.x = lrint (leave->event_x); | ||
| 9822 | ev.y = lrint (leave->event_y); | ||
| 9823 | ev.window = leave->event; | ||
| 9824 | any = x_any_window_to_frame (dpyinfo, leave->event); | ||
| 9825 | |||
| 9826 | x_display_set_last_user_time (dpyinfo, xi_event->time); | ||
| 9827 | x_detect_focus_change (dpyinfo, any, event, &inev.ie); | ||
| 9828 | |||
| 9829 | f = x_top_window_to_frame (dpyinfo, leave->event); | ||
| 9830 | if (f) | ||
| 9831 | { | ||
| 9832 | if (f == hlinfo->mouse_face_mouse_frame) | ||
| 9833 | { | ||
| 9834 | /* If we move outside the frame, then we're | ||
| 9835 | certainly no longer on any text in the frame. */ | ||
| 9836 | clear_mouse_face (hlinfo); | ||
| 9837 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 9838 | } | ||
| 9839 | |||
| 9840 | /* Generate a nil HELP_EVENT to cancel a help-echo. | ||
| 9841 | Do it only if there's something to cancel. | ||
| 9842 | Otherwise, the startup message is cleared when | ||
| 9843 | the mouse leaves the frame. */ | ||
| 9844 | if (any_help_event_p) | ||
| 9845 | do_help = -1; | ||
| 9846 | } | ||
| 9847 | #ifdef USE_GTK | ||
| 9848 | /* See comment in EnterNotify above */ | ||
| 9849 | else if (dpyinfo->last_mouse_glyph_frame) | ||
| 9850 | x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &ev); | ||
| 9851 | #endif | ||
| 9852 | goto XI_OTHER; | ||
| 9853 | case XI_Motion: | ||
| 9854 | /* First test if there is some kind of scroll event | ||
| 9855 | here! */ | ||
| 9856 | states = &xev->valuators; | ||
| 9857 | values = states->values; | ||
| 9858 | |||
| 9859 | x_display_set_last_user_time (dpyinfo, xi_event->time); | ||
| 9860 | |||
| 9861 | for (int i = 0; i < states->mask_len * 8; i++) | ||
| 9862 | { | ||
| 9863 | if (XIMaskIsSet (states->mask, i)) | ||
| 9864 | { | ||
| 9865 | block_input (); | ||
| 9866 | |||
| 9867 | struct xi_scroll_valuator_t *val; | ||
| 9868 | double delta = | ||
| 9869 | x_get_scroll_valuator_delta (dpyinfo, xev->deviceid, | ||
| 9870 | i, *values, &val); | ||
| 9871 | |||
| 9872 | if (delta != DBL_MAX) | ||
| 9873 | { | ||
| 9874 | /* TODO: Figure out how pixelwise scrolling should work. | ||
| 9875 | Until that happens, this will have to do. */ | ||
| 9876 | delta *= 10; | ||
| 9877 | |||
| 9878 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); | ||
| 9879 | found_valuator = true; | ||
| 9880 | if (signbit (delta) != signbit (val->emacs_value)) | ||
| 9881 | val->emacs_value = DBL_MIN; | ||
| 9882 | |||
| 9883 | val->emacs_value += delta; | ||
| 9884 | |||
| 9885 | if (!f) | ||
| 9886 | { | ||
| 9887 | f = x_any_window_to_frame (dpyinfo, xev->event); | ||
| 9888 | |||
| 9889 | if (!f) | ||
| 9890 | { | ||
| 9891 | unblock_input (); | ||
| 9892 | goto XI_OTHER; | ||
| 9893 | } | ||
| 9894 | } | ||
| 9895 | |||
| 9896 | if ((val->horizontal | ||
| 9897 | && fabs (val->emacs_value) >= FRAME_COLUMN_WIDTH (f)) | ||
| 9898 | || (!val->horizontal | ||
| 9899 | && fabs (val->emacs_value) >= FRAME_LINE_HEIGHT (f))) | ||
| 9900 | { | ||
| 9901 | Lisp_Object tab_bar_arg = Qnil; | ||
| 9902 | bool tab_bar_p = false; | ||
| 9903 | bool tool_bar_p = false; | ||
| 9904 | bool s = signbit (val->emacs_value); | ||
| 9905 | |||
| 9906 | bv.button = !val->horizontal ? (s ? 5 : 4) : (s ? 7 : 6); | ||
| 9907 | bv.type = ButtonPress; | ||
| 9908 | |||
| 9909 | bv.x = lrint (xev->event_x); | ||
| 9910 | bv.y = lrint (xev->event_y); | ||
| 9911 | bv.window = xev->event; | ||
| 9912 | bv.state = xev->mods.base | ||
| 9913 | | xev->mods.effective | ||
| 9914 | | xev->mods.latched | ||
| 9915 | | xev->mods.locked; | ||
| 9916 | |||
| 9917 | /* Is this in the tab-bar? */ | ||
| 9918 | if (WINDOWP (f->tab_bar_window) | ||
| 9919 | && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window))) | ||
| 9920 | { | ||
| 9921 | Lisp_Object window; | ||
| 9922 | int x = bv.x; | ||
| 9923 | int y = bv.y; | ||
| 9924 | |||
| 9925 | window = window_from_coordinates (f, x, y, 0, true, true); | ||
| 9926 | tab_bar_p = EQ (window, f->tab_bar_window); | ||
| 9927 | |||
| 9928 | if (tab_bar_p) | ||
| 9929 | { | ||
| 9930 | tab_bar_arg = handle_tab_bar_click | ||
| 9931 | (f, x, y, true, x_x_to_emacs_modifiers (dpyinfo, bv.state)); | ||
| 9932 | tab_bar_arg = handle_tab_bar_click | ||
| 9933 | (f, x, y, false, x_x_to_emacs_modifiers (dpyinfo, bv.state)); | ||
| 9934 | } | ||
| 9935 | } | ||
| 9936 | |||
| 9937 | if (!NILP (tab_bar_arg)) | ||
| 9938 | inev.ie.arg = tab_bar_arg; | ||
| 9939 | |||
| 9940 | if (!tool_bar_p && !(NILP (tab_bar_arg) && tab_bar_p)) | ||
| 9941 | { | ||
| 9942 | if (ignore_next_mouse_click_timeout) | ||
| 9943 | { | ||
| 9944 | if (xev->time > ignore_next_mouse_click_timeout) | ||
| 9945 | { | ||
| 9946 | /* XXX: Wouldn't it be better | ||
| 9947 | to just use wheel events | ||
| 9948 | instead of pretending to be | ||
| 9949 | X here? */ | ||
| 9950 | x_construct_mouse_click (&inev.ie, &bv, f); | ||
| 9951 | if (!NILP (tab_bar_arg)) | ||
| 9952 | inev.ie.arg = tab_bar_arg; | ||
| 9953 | kbd_buffer_store_event (&inev.ie); | ||
| 9954 | inev.ie.modifiers &= ~down_modifier; | ||
| 9955 | inev.ie.modifiers |= up_modifier; | ||
| 9956 | kbd_buffer_store_event (&inev.ie); | ||
| 9957 | } | ||
| 9958 | ignore_next_mouse_click_timeout = 0; | ||
| 9959 | } | ||
| 9960 | else | ||
| 9961 | { | ||
| 9962 | x_construct_mouse_click (&inev.ie, &bv, f); | ||
| 9963 | kbd_buffer_store_event (&inev.ie); | ||
| 9964 | inev.ie.modifiers &= ~down_modifier; | ||
| 9965 | inev.ie.modifiers |= up_modifier; | ||
| 9966 | kbd_buffer_store_event (&inev.ie); | ||
| 9967 | } | ||
| 9968 | } | ||
| 9969 | |||
| 9970 | val->emacs_value = DBL_MIN; | ||
| 9971 | } | ||
| 9972 | } | ||
| 9973 | unblock_input (); | ||
| 9974 | values++; | ||
| 9975 | } | ||
| 9976 | |||
| 9977 | inev.ie.kind = NO_EVENT; | ||
| 9978 | } | ||
| 9979 | |||
| 9980 | if (found_valuator) | ||
| 9981 | goto XI_OTHER; | ||
| 9982 | |||
| 9983 | ev.x = lrint (xev->event_x); | ||
| 9984 | ev.y = lrint (xev->event_y); | ||
| 9985 | ev.window = xev->event; | ||
| 9986 | |||
| 9987 | previous_help_echo_string = help_echo_string; | ||
| 9988 | help_echo_string = Qnil; | ||
| 9989 | |||
| 9990 | if (hlinfo->mouse_face_hidden) | ||
| 9991 | { | ||
| 9992 | hlinfo->mouse_face_hidden = false; | ||
| 9993 | clear_mouse_face (hlinfo); | ||
| 9994 | } | ||
| 9995 | |||
| 9996 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); | ||
| 9997 | |||
| 9998 | #ifdef USE_GTK | ||
| 9999 | if (f && xg_event_is_for_scrollbar (f, event)) | ||
| 10000 | f = 0; | ||
| 10001 | #endif | ||
| 10002 | if (f) | ||
| 10003 | { | ||
| 10004 | /* Maybe generate a SELECT_WINDOW_EVENT for | ||
| 10005 | `mouse-autoselect-window' but don't let popup menus | ||
| 10006 | interfere with this (Bug#1261). */ | ||
| 10007 | if (!NILP (Vmouse_autoselect_window) | ||
| 10008 | && !popup_activated () | ||
| 10009 | /* Don't switch if we're currently in the minibuffer. | ||
| 10010 | This tries to work around problems where the | ||
| 10011 | minibuffer gets unselected unexpectedly, and where | ||
| 10012 | you then have to move your mouse all the way down to | ||
| 10013 | the minibuffer to select it. */ | ||
| 10014 | && !MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 10015 | /* With `focus-follows-mouse' non-nil create an event | ||
| 10016 | also when the target window is on another frame. */ | ||
| 10017 | && (f == XFRAME (selected_frame) | ||
| 10018 | || !NILP (focus_follows_mouse))) | ||
| 10019 | { | ||
| 10020 | static Lisp_Object last_mouse_window; | ||
| 10021 | Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false); | ||
| 10022 | |||
| 10023 | /* A window will be autoselected only when it is not | ||
| 10024 | selected now and the last mouse movement event was | ||
| 10025 | not in it. The remainder of the code is a bit vague | ||
| 10026 | wrt what a "window" is. For immediate autoselection, | ||
| 10027 | the window is usually the entire window but for GTK | ||
| 10028 | where the scroll bars don't count. For delayed | ||
| 10029 | autoselection the window is usually the window's text | ||
| 10030 | area including the margins. */ | ||
| 10031 | if (WINDOWP (window) | ||
| 10032 | && !EQ (window, last_mouse_window) | ||
| 10033 | && !EQ (window, selected_window)) | ||
| 10034 | { | ||
| 10035 | inev.ie.kind = SELECT_WINDOW_EVENT; | ||
| 10036 | inev.ie.frame_or_window = window; | ||
| 10037 | } | ||
| 10038 | |||
| 10039 | /* Remember the last window where we saw the mouse. */ | ||
| 10040 | last_mouse_window = window; | ||
| 10041 | } | ||
| 10042 | |||
| 10043 | if (!x_note_mouse_movement (f, &ev)) | ||
| 10044 | help_echo_string = previous_help_echo_string; | ||
| 10045 | } | ||
| 10046 | else | ||
| 10047 | { | ||
| 10048 | #ifndef USE_TOOLKIT_SCROLL_BARS | ||
| 10049 | struct scroll_bar *bar | ||
| 10050 | = x_window_to_scroll_bar (xi_event->display, xev->event, 2); | ||
| 10051 | |||
| 10052 | if (bar) | ||
| 10053 | x_scroll_bar_note_movement (bar, &ev); | ||
| 10054 | #endif /* USE_TOOLKIT_SCROLL_BARS */ | ||
| 10055 | |||
| 10056 | /* If we move outside the frame, then we're | ||
| 10057 | certainly no longer on any text in the frame. */ | ||
| 10058 | clear_mouse_face (hlinfo); | ||
| 10059 | } | ||
| 10060 | |||
| 10061 | /* If the contents of the global variable help_echo_string | ||
| 10062 | has changed, generate a HELP_EVENT. */ | ||
| 10063 | if (!NILP (help_echo_string) | ||
| 10064 | || !NILP (previous_help_echo_string)) | ||
| 10065 | do_help = 1; | ||
| 10066 | goto XI_OTHER; | ||
| 10067 | case XI_ButtonRelease: | ||
| 10068 | case XI_ButtonPress: | ||
| 10069 | { | ||
| 10070 | /* If we decide we want to generate an event to be seen | ||
| 10071 | by the rest of Emacs, we put it here. */ | ||
| 10072 | Lisp_Object tab_bar_arg = Qnil; | ||
| 10073 | bool tab_bar_p = false; | ||
| 10074 | bool tool_bar_p = false; | ||
| 10075 | |||
| 10076 | /* Ignore emulated scroll events when XI2 native | ||
| 10077 | scroll events are present. */ | ||
| 10078 | if (dpyinfo->xi2_version >= 1 && xev->detail >= 4 | ||
| 10079 | && xev->detail <= 8) | ||
| 10080 | goto XI_OTHER; | ||
| 10081 | |||
| 10082 | bv.button = xev->detail; | ||
| 10083 | bv.type = xev->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; | ||
| 10084 | bv.x = lrint (xev->event_x); | ||
| 10085 | bv.y = lrint (xev->event_y); | ||
| 10086 | bv.window = xev->event; | ||
| 10087 | bv.state = xev->mods.base | ||
| 10088 | | xev->mods.effective | ||
| 10089 | | xev->mods.latched | ||
| 10090 | | xev->mods.locked; | ||
| 10091 | |||
| 10092 | memset (&compose_status, 0, sizeof (compose_status)); | ||
| 10093 | dpyinfo->last_mouse_glyph_frame = NULL; | ||
| 10094 | x_display_set_last_user_time (dpyinfo, xev->time); | ||
| 10095 | |||
| 10096 | f = mouse_or_wdesc_frame (dpyinfo, xev->event); | ||
| 10097 | |||
| 10098 | if (f && xev->evtype == XI_ButtonPress | ||
| 10099 | && !popup_activated () | ||
| 10100 | && !x_window_to_scroll_bar (xev->display, xev->event, 2) | ||
| 10101 | && !FRAME_NO_ACCEPT_FOCUS (f)) | ||
| 10102 | { | ||
| 10103 | /* When clicking into a child frame or when clicking | ||
| 10104 | into a parent frame with the child frame selected and | ||
| 10105 | `no-accept-focus' is not set, select the clicked | ||
| 10106 | frame. */ | ||
| 10107 | struct frame *hf = dpyinfo->highlight_frame; | ||
| 10108 | |||
| 10109 | if (FRAME_PARENT_FRAME (f) || (hf && frame_ancestor_p (f, hf))) | ||
| 10110 | { | ||
| 10111 | block_input (); | ||
| 10112 | XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 10113 | RevertToParent, CurrentTime); | ||
| 10114 | if (FRAME_PARENT_FRAME (f)) | ||
| 10115 | XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f)); | ||
| 10116 | unblock_input (); | ||
| 10117 | } | ||
| 10118 | } | ||
| 10119 | |||
| 10120 | #ifdef USE_GTK | ||
| 10121 | if (f && xg_event_is_for_scrollbar (f, event)) | ||
| 10122 | f = 0; | ||
| 10123 | #endif | ||
| 10124 | |||
| 10125 | if (f) | ||
| 10126 | { | ||
| 10127 | /* Is this in the tab-bar? */ | ||
| 10128 | if (WINDOWP (f->tab_bar_window) | ||
| 10129 | && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window))) | ||
| 10130 | { | ||
| 10131 | Lisp_Object window; | ||
| 10132 | int x = bv.x; | ||
| 10133 | int y = bv.y; | ||
| 10134 | |||
| 10135 | window = window_from_coordinates (f, x, y, 0, true, true); | ||
| 10136 | tab_bar_p = EQ (window, f->tab_bar_window); | ||
| 10137 | |||
| 10138 | if (tab_bar_p) | ||
| 10139 | tab_bar_arg = handle_tab_bar_click | ||
| 10140 | (f, x, y, xev->evtype == XI_ButtonPress, | ||
| 10141 | x_x_to_emacs_modifiers (dpyinfo, bv.state)); | ||
| 10142 | } | ||
| 10143 | |||
| 10144 | #if ! defined (USE_GTK) | ||
| 10145 | /* Is this in the tool-bar? */ | ||
| 10146 | if (WINDOWP (f->tool_bar_window) | ||
| 10147 | && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window))) | ||
| 10148 | { | ||
| 10149 | Lisp_Object window; | ||
| 10150 | int x = bv.x; | ||
| 10151 | int y = bv.y; | ||
| 10152 | |||
| 10153 | window = window_from_coordinates (f, x, y, 0, true, true); | ||
| 10154 | tool_bar_p = EQ (window, f->tool_bar_window); | ||
| 10155 | |||
| 10156 | if (tool_bar_p && xev->detail < 4) | ||
| 10157 | handle_tool_bar_click | ||
| 10158 | (f, x, y, xev->evtype == XI_ButtonPress, | ||
| 10159 | x_x_to_emacs_modifiers (dpyinfo, bv.state)); | ||
| 10160 | } | ||
| 10161 | #endif /* !USE_GTK */ | ||
| 10162 | |||
| 10163 | if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) | ||
| 10164 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | ||
| 10165 | if (! popup_activated ()) | ||
| 10166 | #endif | ||
| 10167 | { | ||
| 10168 | if (ignore_next_mouse_click_timeout) | ||
| 10169 | { | ||
| 10170 | if (xev->evtype == XI_ButtonPress | ||
| 10171 | && xev->time > ignore_next_mouse_click_timeout) | ||
| 10172 | { | ||
| 10173 | ignore_next_mouse_click_timeout = 0; | ||
| 10174 | x_construct_mouse_click (&inev.ie, &bv, f); | ||
| 10175 | } | ||
| 10176 | if (xev->evtype == XI_ButtonRelease) | ||
| 10177 | ignore_next_mouse_click_timeout = 0; | ||
| 10178 | } | ||
| 10179 | else | ||
| 10180 | x_construct_mouse_click (&inev.ie, &bv, f); | ||
| 10181 | |||
| 10182 | if (!NILP (tab_bar_arg)) | ||
| 10183 | inev.ie.arg = tab_bar_arg; | ||
| 10184 | } | ||
| 10185 | if (FRAME_X_EMBEDDED_P (f)) | ||
| 10186 | xembed_send_message (f, xev->time, | ||
| 10187 | XEMBED_REQUEST_FOCUS, 0, 0, 0); | ||
| 10188 | } | ||
| 10189 | |||
| 10190 | if (xev->evtype == XI_ButtonPress) | ||
| 10191 | { | ||
| 10192 | dpyinfo->grabbed |= (1 << xev->detail); | ||
| 10193 | dpyinfo->last_mouse_frame = f; | ||
| 10194 | if (f && !tab_bar_p) | ||
| 10195 | f->last_tab_bar_item = -1; | ||
| 10196 | #if ! defined (USE_GTK) | ||
| 10197 | if (f && !tool_bar_p) | ||
| 10198 | f->last_tool_bar_item = -1; | ||
| 10199 | #endif /* not USE_GTK */ | ||
| 10200 | |||
| 10201 | } | ||
| 10202 | else | ||
| 10203 | dpyinfo->grabbed &= ~(1 << xev->detail); | ||
| 10204 | |||
| 10205 | if (f) | ||
| 10206 | f->mouse_moved = false; | ||
| 10207 | |||
| 10208 | #if defined (USE_GTK) | ||
| 10209 | /* No Xt toolkit currently available has support for XI2. | ||
| 10210 | So the code here assumes use of GTK. */ | ||
| 10211 | f = x_menubar_window_to_frame (dpyinfo, event); | ||
| 10212 | if (f /* Gtk+ menus only react to the first three buttons. */ | ||
| 10213 | && xev->detail < 3) | ||
| 10214 | { | ||
| 10215 | /* What is done with Core Input ButtonPressed is not | ||
| 10216 | possible here, because GenericEvents cannot be saved. */ | ||
| 10217 | bool was_waiting_for_input = waiting_for_input; | ||
| 10218 | /* This hack was adopted from the NS port. Whether | ||
| 10219 | or not it is actually safe is a different story | ||
| 10220 | altogether. */ | ||
| 10221 | if (waiting_for_input) | ||
| 10222 | waiting_for_input = 0; | ||
| 10223 | set_frame_menubar (f, true); | ||
| 10224 | waiting_for_input = was_waiting_for_input; | ||
| 10225 | } | ||
| 10226 | #endif | ||
| 10227 | goto XI_OTHER; | ||
| 10228 | } | ||
| 10229 | case XI_KeyPress: | ||
| 10230 | { | ||
| 10231 | int state = xev->mods.base | ||
| 10232 | | xev->mods.effective | ||
| 10233 | | xev->mods.latched | ||
| 10234 | | xev->mods.locked; | ||
| 10235 | Lisp_Object c; | ||
| 10236 | #ifdef HAVE_XKB | ||
| 10237 | unsigned int mods_rtrn; | ||
| 10238 | #endif | ||
| 10239 | int keycode = xev->detail; | ||
| 10240 | KeySym keysym; | ||
| 10241 | char copy_buffer[81]; | ||
| 10242 | char *copy_bufptr = copy_buffer; | ||
| 10243 | unsigned char *copy_ubufptr; | ||
| 10244 | #ifdef HAVE_XKB | ||
| 10245 | int copy_bufsiz = sizeof (copy_buffer); | ||
| 10246 | #endif | ||
| 10247 | ptrdiff_t i; | ||
| 10248 | int nchars, len; | ||
| 10249 | |||
| 10250 | #ifdef HAVE_XKB | ||
| 10251 | if (dpyinfo->xkb_desc) | ||
| 10252 | { | ||
| 10253 | if (!XkbTranslateKeyCode (dpyinfo->xkb_desc, keycode, | ||
| 10254 | state, &mods_rtrn, &keysym)) | ||
| 10255 | goto XI_OTHER; | ||
| 10256 | } | ||
| 10257 | else | ||
| 10258 | { | ||
| 10259 | #endif | ||
| 10260 | int keysyms_per_keycode_return; | ||
| 10261 | KeySym *ksms = XGetKeyboardMapping (dpyinfo->display, keycode, 1, | ||
| 10262 | &keysyms_per_keycode_return); | ||
| 10263 | if (!(keysym = ksms[0])) | ||
| 10264 | { | ||
| 10265 | XFree (ksms); | ||
| 10266 | goto XI_OTHER; | ||
| 10267 | } | ||
| 10268 | XFree (ksms); | ||
| 10269 | #ifdef HAVE_XKB | ||
| 10270 | } | ||
| 10271 | #endif | ||
| 10272 | |||
| 10273 | if (keysym == NoSymbol) | ||
| 10274 | goto XI_OTHER; | ||
| 10275 | |||
| 10276 | x_display_set_last_user_time (dpyinfo, xev->time); | ||
| 10277 | ignore_next_mouse_click_timeout = 0; | ||
| 10278 | |||
| 10279 | #if defined (USE_X_TOOLKIT) || defined (USE_GTK) | ||
| 10280 | /* Dispatch XI_KeyPress events when in menu. */ | ||
| 10281 | if (popup_activated ()) | ||
| 10282 | goto XI_OTHER; | ||
| 10283 | #endif | ||
| 10284 | |||
| 10285 | f = x_any_window_to_frame (dpyinfo, xev->event); | ||
| 10286 | |||
| 10287 | /* If mouse-highlight is an integer, input clears out | ||
| 10288 | mouse highlighting. */ | ||
| 10289 | if (!hlinfo->mouse_face_hidden && FIXNUMP (Vmouse_highlight) | ||
| 10290 | && (f == 0 | ||
| 10291 | #if ! defined (USE_GTK) | ||
| 10292 | || !EQ (f->tool_bar_window, hlinfo->mouse_face_window) | ||
| 10293 | #endif | ||
| 10294 | || !EQ (f->tab_bar_window, hlinfo->mouse_face_window)) | ||
| 10295 | ) | ||
| 10296 | { | ||
| 10297 | clear_mouse_face (hlinfo); | ||
| 10298 | hlinfo->mouse_face_hidden = true; | ||
| 10299 | } | ||
| 10300 | |||
| 10301 | if (f != 0) | ||
| 10302 | { | ||
| 10303 | #ifdef USE_GTK | ||
| 10304 | /* Don't pass keys to GTK. A Tab will shift focus to the | ||
| 10305 | tool bar in GTK 2.4. Keys will still go to menus and | ||
| 10306 | dialogs because in that case popup_activated is nonzero | ||
| 10307 | (see above). */ | ||
| 10308 | *finish = X_EVENT_DROP; | ||
| 10309 | #endif | ||
| 10310 | /* If not using XIM/XIC, and a compose sequence is in progress, | ||
| 10311 | we break here. Otherwise, chars_matched is always 0. */ | ||
| 10312 | if (compose_status.chars_matched > 0 && nbytes == 0) | ||
| 10313 | goto XI_OTHER; | ||
| 10314 | |||
| 10315 | memset (&compose_status, 0, sizeof (compose_status)); | ||
| 10316 | |||
| 10317 | XSETFRAME (inev.ie.frame_or_window, f); | ||
| 10318 | inev.ie.modifiers | ||
| 10319 | = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state); | ||
| 10320 | inev.ie.timestamp = xev->time; | ||
| 10321 | |||
| 10322 | /* First deal with keysyms which have defined | ||
| 10323 | translations to characters. */ | ||
| 10324 | if (keysym >= 32 && keysym < 128) | ||
| 10325 | /* Avoid explicitly decoding each ASCII character. */ | ||
| 10326 | { | ||
| 10327 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; | ||
| 10328 | inev.ie.code = keysym; | ||
| 10329 | |||
| 10330 | goto xi_done_keysym; | ||
| 10331 | } | ||
| 10332 | |||
| 10333 | /* Keysyms directly mapped to Unicode characters. */ | ||
| 10334 | if (keysym >= 0x01000000 && keysym <= 0x0110FFFF) | ||
| 10335 | { | ||
| 10336 | if (keysym < 0x01000080) | ||
| 10337 | inev.ie.kind = ASCII_KEYSTROKE_EVENT; | ||
| 10338 | else | ||
| 10339 | inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; | ||
| 10340 | inev.ie.code = keysym & 0xFFFFFF; | ||
| 10341 | goto xi_done_keysym; | ||
| 10342 | } | ||
| 10343 | |||
| 10344 | /* Now non-ASCII. */ | ||
| 10345 | if (HASH_TABLE_P (Vx_keysym_table) | ||
| 10346 | && (c = Fgethash (make_fixnum (keysym), | ||
| 10347 | Vx_keysym_table, | ||
| 10348 | Qnil), | ||
| 10349 | FIXNATP (c))) | ||
| 10350 | { | ||
| 10351 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFIXNAT (c)) | ||
| 10352 | ? ASCII_KEYSTROKE_EVENT | ||
| 10353 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | ||
| 10354 | inev.ie.code = XFIXNAT (c); | ||
| 10355 | goto xi_done_keysym; | ||
| 10356 | } | ||
| 10357 | |||
| 10358 | /* Random non-modifier sorts of keysyms. */ | ||
| 10359 | if (((keysym >= XK_BackSpace && keysym <= XK_Escape) | ||
| 10360 | || keysym == XK_Delete | ||
| 10361 | #ifdef XK_ISO_Left_Tab | ||
| 10362 | || (keysym >= XK_ISO_Left_Tab | ||
| 10363 | && keysym <= XK_ISO_Enter) | ||
| 10364 | #endif | ||
| 10365 | || IsCursorKey (keysym) /* 0xff50 <= x < 0xff60 */ | ||
| 10366 | || IsMiscFunctionKey (keysym) /* 0xff60 <= x < VARIES */ | ||
| 10367 | #ifdef HPUX | ||
| 10368 | /* This recognizes the "extended function | ||
| 10369 | keys". It seems there's no cleaner way. | ||
| 10370 | Test IsModifierKey to avoid handling | ||
| 10371 | mode_switch incorrectly. */ | ||
| 10372 | || (XK_Select <= keysym && keysym < XK_KP_Space) | ||
| 10373 | #endif | ||
| 10374 | #ifdef XK_dead_circumflex | ||
| 10375 | || keysym == XK_dead_circumflex | ||
| 10376 | #endif | ||
| 10377 | #ifdef XK_dead_grave | ||
| 10378 | || keysym == XK_dead_grave | ||
| 10379 | #endif | ||
| 10380 | #ifdef XK_dead_tilde | ||
| 10381 | || keysym == XK_dead_tilde | ||
| 10382 | #endif | ||
| 10383 | #ifdef XK_dead_diaeresis | ||
| 10384 | || keysym == XK_dead_diaeresis | ||
| 10385 | #endif | ||
| 10386 | #ifdef XK_dead_macron | ||
| 10387 | || keysym == XK_dead_macron | ||
| 10388 | #endif | ||
| 10389 | #ifdef XK_dead_degree | ||
| 10390 | || keysym == XK_dead_degree | ||
| 10391 | #endif | ||
| 10392 | #ifdef XK_dead_acute | ||
| 10393 | || keysym == XK_dead_acute | ||
| 10394 | #endif | ||
| 10395 | #ifdef XK_dead_cedilla | ||
| 10396 | || keysym == XK_dead_cedilla | ||
| 10397 | #endif | ||
| 10398 | #ifdef XK_dead_breve | ||
| 10399 | || keysym == XK_dead_breve | ||
| 10400 | #endif | ||
| 10401 | #ifdef XK_dead_ogonek | ||
| 10402 | || keysym == XK_dead_ogonek | ||
| 10403 | #endif | ||
| 10404 | #ifdef XK_dead_caron | ||
| 10405 | || keysym == XK_dead_caron | ||
| 10406 | #endif | ||
| 10407 | #ifdef XK_dead_doubleacute | ||
| 10408 | || keysym == XK_dead_doubleacute | ||
| 10409 | #endif | ||
| 10410 | #ifdef XK_dead_abovedot | ||
| 10411 | || keysym == XK_dead_abovedot | ||
| 10412 | #endif | ||
| 10413 | || IsKeypadKey (keysym) /* 0xff80 <= x < 0xffbe */ | ||
| 10414 | || IsFunctionKey (keysym) /* 0xffbe <= x < 0xffe1 */ | ||
| 10415 | /* Any "vendor-specific" key is ok. */ | ||
| 10416 | || (keysym & (1 << 28)) | ||
| 10417 | || (keysym != NoSymbol && nbytes == 0)) | ||
| 10418 | && ! (IsModifierKey (keysym) | ||
| 10419 | /* The symbols from XK_ISO_Lock | ||
| 10420 | to XK_ISO_Last_Group_Lock | ||
| 10421 | don't have real modifiers but | ||
| 10422 | should be treated similarly to | ||
| 10423 | Mode_switch by Emacs. */ | ||
| 10424 | #if defined XK_ISO_Lock && defined XK_ISO_Last_Group_Lock | ||
| 10425 | || (XK_ISO_Lock <= keysym | ||
| 10426 | && keysym <= XK_ISO_Last_Group_Lock) | ||
| 10427 | #endif | ||
| 10428 | )) | ||
| 10429 | { | ||
| 10430 | STORE_KEYSYM_FOR_DEBUG (keysym); | ||
| 10431 | /* make_lispy_event will convert this to a symbolic | ||
| 10432 | key. */ | ||
| 10433 | inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT; | ||
| 10434 | inev.ie.code = keysym; | ||
| 10435 | goto xi_done_keysym; | ||
| 10436 | } | ||
| 10437 | |||
| 10438 | #ifdef HAVE_XKB | ||
| 10439 | int overflow = 0; | ||
| 10440 | KeySym sym = keysym; | ||
| 10441 | |||
| 10442 | if (dpyinfo->xkb_desc) | ||
| 10443 | { | ||
| 10444 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10445 | state & ~mods_rtrn, copy_bufptr, | ||
| 10446 | copy_bufsiz, &overflow))) | ||
| 10447 | goto XI_OTHER; | ||
| 10448 | } | ||
| 10449 | else | ||
| 10450 | #else | ||
| 10451 | { | ||
| 10452 | block_input (); | ||
| 10453 | char *str = XKeysymToString (keysym); | ||
| 10454 | if (!str) | ||
| 10455 | { | ||
| 10456 | unblock_input (); | ||
| 10457 | goto XI_OTHER; | ||
| 10458 | } | ||
| 10459 | nbytes = strlen (str) + 1; | ||
| 10460 | copy_bufptr = alloca (nbytes); | ||
| 10461 | strcpy (copy_bufptr, str); | ||
| 10462 | unblock_input (); | ||
| 10463 | } | ||
| 10464 | #endif | ||
| 10465 | #ifdef HAVE_XKB | ||
| 10466 | if (overflow) | ||
| 10467 | { | ||
| 10468 | overflow = 0; | ||
| 10469 | copy_bufptr = alloca (copy_bufsiz + overflow); | ||
| 10470 | keysym = sym; | ||
| 10471 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10472 | state & ~mods_rtrn, copy_bufptr, | ||
| 10473 | copy_bufsiz + overflow, &overflow))) | ||
| 10474 | goto XI_OTHER; | ||
| 10475 | |||
| 10476 | if (overflow) | ||
| 10477 | goto XI_OTHER; | ||
| 10478 | } | ||
| 10479 | #endif | ||
| 10480 | |||
| 10481 | for (i = 0, nchars = 0; i < nbytes; i++) | ||
| 10482 | { | ||
| 10483 | if (ASCII_CHAR_P (copy_bufptr[i])) | ||
| 10484 | nchars++; | ||
| 10485 | STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]); | ||
| 10486 | } | ||
| 10487 | |||
| 10488 | if (nchars < nbytes) | ||
| 10489 | { | ||
| 10490 | /* Decode the input data. */ | ||
| 10491 | |||
| 10492 | setup_coding_system (Vlocale_coding_system, &coding); | ||
| 10493 | coding.src_multibyte = false; | ||
| 10494 | coding.dst_multibyte = true; | ||
| 10495 | /* The input is converted to events, thus we can't | ||
| 10496 | handle composition. Anyway, there's no XIM that | ||
| 10497 | gives us composition information. */ | ||
| 10498 | coding.common_flags &= ~CODING_ANNOTATION_MASK; | ||
| 10499 | |||
| 10500 | SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH, | ||
| 10501 | nbytes); | ||
| 10502 | coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes; | ||
| 10503 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 10504 | decode_coding_c_string (&coding, (unsigned char *) copy_bufptr, nbytes, Qnil); | ||
| 10505 | nbytes = coding.produced; | ||
| 10506 | nchars = coding.produced_char; | ||
| 10507 | copy_bufptr = (char *) coding.destination; | ||
| 10508 | } | ||
| 10509 | |||
| 10510 | copy_ubufptr = (unsigned char *) copy_bufptr; | ||
| 10511 | |||
| 10512 | /* Convert the input data to a sequence of | ||
| 10513 | character events. */ | ||
| 10514 | for (i = 0; i < nbytes; i += len) | ||
| 10515 | { | ||
| 10516 | int ch; | ||
| 10517 | if (nchars == nbytes) | ||
| 10518 | ch = copy_ubufptr[i], len = 1; | ||
| 10519 | else | ||
| 10520 | ch = string_char_and_length (copy_ubufptr + i, &len); | ||
| 10521 | inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch) | ||
| 10522 | ? ASCII_KEYSTROKE_EVENT | ||
| 10523 | : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | ||
| 10524 | inev.ie.code = ch; | ||
| 10525 | kbd_buffer_store_buffered_event (&inev, hold_quit); | ||
| 10526 | } | ||
| 10527 | |||
| 10528 | inev.ie.kind = NO_EVENT; | ||
| 10529 | goto xi_done_keysym; | ||
| 10530 | } | ||
| 10531 | goto XI_OTHER; | ||
| 10532 | } | ||
| 10533 | case XI_KeyRelease: | ||
| 10534 | x_display_set_last_user_time (dpyinfo, xev->time); | ||
| 10535 | goto XI_OTHER; | ||
| 10536 | case XI_PropertyEvent: | ||
| 10537 | case XI_HierarchyChanged: | ||
| 10538 | case XI_DeviceChanged: | ||
| 10539 | x_init_master_valuators (dpyinfo); | ||
| 10540 | goto XI_OTHER; | ||
| 10541 | default: | ||
| 10542 | goto XI_OTHER; | ||
| 10543 | } | ||
| 10544 | xi_done_keysym: | ||
| 10545 | if (must_free_data) | ||
| 10546 | XFreeEventData (dpyinfo->display, &event->xcookie); | ||
| 10547 | goto done_keysym; | ||
| 10548 | XI_OTHER: | ||
| 10549 | if (must_free_data) | ||
| 10550 | XFreeEventData (dpyinfo->display, &event->xcookie); | ||
| 10551 | goto OTHER; | ||
| 10552 | } | ||
| 10553 | #endif | ||
| 10554 | 9521 | ||
| 10555 | default: | 9522 | default: |
| 10556 | OTHER: | 9523 | OTHER: |
| @@ -14225,40 +13192,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 14225 | dpyinfo->supports_xdbe = true; | 13192 | dpyinfo->supports_xdbe = true; |
| 14226 | #endif | 13193 | #endif |
| 14227 | 13194 | ||
| 14228 | #ifdef HAVE_XINPUT2 | ||
| 14229 | dpyinfo->supports_xi2 = false; | ||
| 14230 | int rc; | ||
| 14231 | int major = 2; | ||
| 14232 | #ifdef XI_BarrierHit /* XInput 2.3 */ | ||
| 14233 | int minor = 3; | ||
| 14234 | #elif defined XI_TouchBegin /* XInput 2.2 */ | ||
| 14235 | int minor = 2; | ||
| 14236 | #elif defined XIScrollClass /* XInput 1.1 */ | ||
| 14237 | int minor = 1; | ||
| 14238 | #else /* Some old version of XI2 we're not interested in. */ | ||
| 14239 | int minor = 0; | ||
| 14240 | #endif | ||
| 14241 | int fer, fee; | ||
| 14242 | |||
| 14243 | if (XQueryExtension (dpyinfo->display, "XInputExtension", | ||
| 14244 | &dpyinfo->xi2_opcode, &fer, &fee)) | ||
| 14245 | { | ||
| 14246 | rc = XIQueryVersion (dpyinfo->display, &major, &minor); | ||
| 14247 | if (rc == Success) | ||
| 14248 | { | ||
| 14249 | dpyinfo->supports_xi2 = true; | ||
| 14250 | x_init_master_valuators (dpyinfo); | ||
| 14251 | } | ||
| 14252 | } | ||
| 14253 | dpyinfo->xi2_version = minor; | ||
| 14254 | #endif | ||
| 14255 | |||
| 14256 | #ifdef HAVE_XKB | ||
| 14257 | dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display, | ||
| 14258 | XkbAllComponentsMask, | ||
| 14259 | XkbUseCoreKbd); | ||
| 14260 | #endif | ||
| 14261 | |||
| 14262 | #if defined USE_CAIRO || defined HAVE_XFT | 13195 | #if defined USE_CAIRO || defined HAVE_XFT |
| 14263 | { | 13196 | { |
| 14264 | /* If we are using Xft, the following precautions should be made: | 13197 | /* If we are using Xft, the following precautions should be made: |
| @@ -14691,14 +13624,6 @@ x_delete_terminal (struct terminal *terminal) | |||
| 14691 | XrmDestroyDatabase (dpyinfo->rdb); | 13624 | XrmDestroyDatabase (dpyinfo->rdb); |
| 14692 | #endif | 13625 | #endif |
| 14693 | 13626 | ||
| 14694 | #ifdef HAVE_XKB | ||
| 14695 | if (dpyinfo->xkb_desc) | ||
| 14696 | XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); | ||
| 14697 | #endif | ||
| 14698 | #ifdef HAVE_XINPUT2 | ||
| 14699 | if (dpyinfo->supports_xi2) | ||
| 14700 | x_free_xi_devices (dpyinfo); | ||
| 14701 | #endif | ||
| 14702 | #ifdef USE_GTK | 13627 | #ifdef USE_GTK |
| 14703 | xg_display_close (dpyinfo->display); | 13628 | xg_display_close (dpyinfo->display); |
| 14704 | #else | 13629 | #else |
| @@ -14858,12 +13783,9 @@ x_initialize (void) | |||
| 14858 | void | 13783 | void |
| 14859 | init_xterm (void) | 13784 | init_xterm (void) |
| 14860 | { | 13785 | { |
| 14861 | #ifndef HAVE_XINPUT2 | 13786 | /* Emacs can handle only core input events, so make sure |
| 14862 | /* Emacs can handle only core input events when built without XI2 | 13787 | Gtk doesn't use Xinput or Xinput2 extensions. */ |
| 14863 | support, so make sure Gtk doesn't use Xinput or Xinput2 | ||
| 14864 | extensions. */ | ||
| 14865 | xputenv ("GDK_CORE_DEVICE_EVENTS=1"); | 13788 | xputenv ("GDK_CORE_DEVICE_EVENTS=1"); |
| 14866 | #endif | ||
| 14867 | } | 13789 | } |
| 14868 | #endif | 13790 | #endif |
| 14869 | 13791 | ||
diff --git a/src/xterm.h b/src/xterm.h index 25eddf8bf28..9d9534dd629 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -88,10 +88,6 @@ typedef GtkWidget *xt_or_gtk_widget; | |||
| 88 | #include <X11/Xlib-xcb.h> | 88 | #include <X11/Xlib-xcb.h> |
| 89 | #endif | 89 | #endif |
| 90 | 90 | ||
| 91 | #ifdef HAVE_XKB | ||
| 92 | #include <X11/XKBlib.h> | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #include "dispextern.h" | 91 | #include "dispextern.h" |
| 96 | #include "termhooks.h" | 92 | #include "termhooks.h" |
| 97 | 93 | ||
| @@ -167,26 +163,6 @@ struct color_name_cache_entry | |||
| 167 | char *name; | 163 | char *name; |
| 168 | }; | 164 | }; |
| 169 | 165 | ||
| 170 | #ifdef HAVE_XINPUT2 | ||
| 171 | struct xi_scroll_valuator_t | ||
| 172 | { | ||
| 173 | bool invalid_p; | ||
| 174 | double current_value; | ||
| 175 | double emacs_value; | ||
| 176 | double increment; | ||
| 177 | |||
| 178 | int number; | ||
| 179 | int horizontal; | ||
| 180 | }; | ||
| 181 | |||
| 182 | struct xi_device_t | ||
| 183 | { | ||
| 184 | int device_id; | ||
| 185 | int scroll_valuator_count; | ||
| 186 | struct xi_scroll_valuator_t *valuators; | ||
| 187 | }; | ||
| 188 | #endif | ||
| 189 | |||
| 190 | Status x_parse_color (struct frame *f, const char *color_name, | 166 | Status x_parse_color (struct frame *f, const char *color_name, |
| 191 | XColor *color); | 167 | XColor *color); |
| 192 | 168 | ||
| @@ -498,19 +474,6 @@ struct x_display_info | |||
| 498 | #ifdef HAVE_XDBE | 474 | #ifdef HAVE_XDBE |
| 499 | bool supports_xdbe; | 475 | bool supports_xdbe; |
| 500 | #endif | 476 | #endif |
| 501 | |||
| 502 | #ifdef HAVE_XINPUT2 | ||
| 503 | bool supports_xi2; | ||
| 504 | int xi2_version; | ||
| 505 | int xi2_opcode; | ||
| 506 | |||
| 507 | int num_devices; | ||
| 508 | struct xi_device_t *devices; | ||
| 509 | #endif | ||
| 510 | |||
| 511 | #ifdef HAVE_XKB | ||
| 512 | XkbDescPtr xkb_desc; | ||
| 513 | #endif | ||
| 514 | }; | 477 | }; |
| 515 | 478 | ||
| 516 | #ifdef HAVE_X_I18N | 479 | #ifdef HAVE_X_I18N |
| @@ -518,11 +481,6 @@ struct x_display_info | |||
| 518 | extern bool use_xim; | 481 | extern bool use_xim; |
| 519 | #endif | 482 | #endif |
| 520 | 483 | ||
| 521 | #ifdef HAVE_XINPUT2 | ||
| 522 | /* Defined in xmenu.c. */ | ||
| 523 | extern int popup_activated_flag; | ||
| 524 | #endif | ||
| 525 | |||
| 526 | /* This is a chain of structures for all the X displays currently in use. */ | 484 | /* This is a chain of structures for all the X displays currently in use. */ |
| 527 | extern struct x_display_info *x_display_list; | 485 | extern struct x_display_info *x_display_list; |
| 528 | 486 | ||