Add support for event processing via XInput 2
* configure.ac: Add an option to use XInput 2 if available. * src/Makefile.in (XINPUT_LIBS, XINPUT_CFLAGS): New variables. (EMACS_CFLAGS): Add Xinput CFLAGS. (LIBES): Add XInput libs. * src/xmenu.c (popup_activated_flag): Expose flag if XInput 2 is available. * src/xfns.c (x_window): Set XInput 2 event mask. (setup_xi_event_mask): New function. (syms_of_xfns): Provide XInput 2 feature. * src/xterm.c (x_detect_focus_change): Handle XInput 2 GenericEvents. (handle_one_xevent): Handle XInput 2 events. (x_term_init): Ask the server for XInput 2 support and set xkb_desc if available. (x_delete_terminal): Free XKB kb desc if it exists, and free XI2 devices if they exist. (xi_grab_or_ungrab_device) (xi_reset_scroll_valuators_for_device_id) (x_free_xi_devices, x_init_master_valuators): New functions. (x_get_scroll_valuator_delta): New function. (init_xterm): Don't tell GTK to only use Core Input when built with XInput 2 support. * src/xterm.h (struct x_display_info): Add fields for XKB and XI2 support. * src/gtkutil.c (xg_event_is_for_menubar): Handle XIDeviceEvents. (xg_is_menu_window): New function. (xg_event_is_for_scrollbar): Handle XIDeviceEvents. * etc/NEWS: Document changes. * lisp/mwheel.el (mouse-wheel-down-alternate-event) (mouse-wheel-up-alternate-event) (mouse-wheel-left-alternate-event) (mouse-wheel-right-alternate-event): New user options. (mouse-wheel-text-scale) (mwheel-scroll): Test for alternate events. (mouse-wheel--setup-bindings): Set up bindings for alternate buttons.
This commit is contained in:
parent
fbf361f593
commit
487ec3cf2a
10 changed files with 1372 additions and 21 deletions
22
configure.ac
22
configure.ac
|
@ -487,6 +487,7 @@ OPTION_DEFAULT_ON([modules],[don't compile with dynamic modules support])
|
|||
OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support])
|
||||
OPTION_DEFAULT_OFF([native-compilation],[compile with Emacs Lisp native compiler support])
|
||||
OPTION_DEFAULT_OFF([cygwin32-native-compilation],[use native compilation on 32-bit Cygwin])
|
||||
OPTION_DEFAULT_OFF([xinput2],[use version 2.0 the X Input Extension for input])
|
||||
|
||||
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
|
||||
[use a file notification library (LIB one of: yes, inotify, kqueue, gfile, w32, no)])],
|
||||
|
@ -4237,6 +4238,26 @@ fi
|
|||
AC_SUBST(XFIXES_CFLAGS)
|
||||
AC_SUBST(XFIXES_LIBS)
|
||||
|
||||
## Use XInput 2.0 if available
|
||||
HAVE_XINPUT2=no
|
||||
if test "${HAVE_X11}" = "yes" && test "${with_xinput2}" != "no"; then
|
||||
EMACS_CHECK_MODULES([XINPUT], [xi])
|
||||
if test $HAVE_XINPUT = yes; then
|
||||
# Now check for XInput2.h
|
||||
AC_CHECK_HEADER(X11/extensions/XInput2.h,
|
||||
[AC_CHECK_LIB(Xi, XIGrabButton, HAVE_XINPUT2=yes)])
|
||||
fi
|
||||
if test $HAVE_XINPUT2 = yes; then
|
||||
AC_DEFINE(HAVE_XINPUT2, 1, [Define to 1 if the X Input Extension version 2.0 is present.])
|
||||
if test "$USE_GTK_TOOLKIT" = "GTK2"; then
|
||||
AC_MSG_WARN([You are building Emacs with GTK+ 2 and the X Input Extension version 2.
|
||||
This might lead to problems if your version of GTK+ is not built with support for XInput 2.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(XINPUT_CFLAGS)
|
||||
AC_SUBST(XINPUT_LIBS)
|
||||
|
||||
### Use Xdbe (-lXdbe) if available
|
||||
HAVE_XDBE=no
|
||||
if test "${HAVE_X11}" = "yes"; then
|
||||
|
@ -6011,6 +6032,7 @@ AS_ECHO([" Does Emacs use -lXaw3d? ${HAVE_XAW3D
|
|||
Does Emacs support legacy unexec dumping? ${with_unexec}
|
||||
Which dumping strategy does Emacs use? ${with_dumping}
|
||||
Does Emacs have native lisp compiler? ${HAVE_NATIVE_COMP}
|
||||
Does Emacs use version 2 of the the X Input Extension? ${HAVE_XINPUT2}
|
||||
"])
|
||||
|
||||
if test -n "${EMACSDATA}"; then
|
||||
|
|
17
etc/NEWS
17
etc/NEWS
|
@ -30,6 +30,14 @@ The file is typically installed using a file name akin to
|
|||
If a constant file name is required, the file can be renamed to
|
||||
"emacs.pdmp", and Emacs will find it during startup anyway.
|
||||
|
||||
** Emacs now supports use of XInput 2 for input events.
|
||||
If your X server has support and you have the XInput 2 development headers
|
||||
installed, you can configure Emacs with the option '--with-xinput2' to enable
|
||||
this support.
|
||||
|
||||
The named feature `xinput2' can be used to test for the presence of
|
||||
XInput 2 support from Lisp programs.
|
||||
|
||||
|
||||
* Startup Changes in Emacs 29.1
|
||||
|
||||
|
@ -224,6 +232,15 @@ The user option 'comint-terminfo-terminal' and variable
|
|||
'system-uses-terminfo' can now be set as connection-local variables to
|
||||
change the terminal used on a remote host.
|
||||
|
||||
** Mwheel
|
||||
|
||||
---
|
||||
*** New user options for alternate wheel events.
|
||||
The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event',
|
||||
'mouse-wheel-left-alternate-event', and 'mouse-wheel-right-alternate-event' have
|
||||
been added to better support systems where two kinds of wheel events can be
|
||||
received.
|
||||
|
||||
|
||||
* Changes in Specialized Modes and Packages in Emacs 29.1
|
||||
|
||||
|
|
|
@ -63,6 +63,13 @@
|
|||
:type 'symbol
|
||||
:set 'mouse-wheel-change-button)
|
||||
|
||||
(defcustom mouse-wheel-down-alternate-event
|
||||
(when (featurep 'xinput2) 'wheel-up)
|
||||
"Alternative wheel down event to consider."
|
||||
:group 'mouse
|
||||
:type 'symbol
|
||||
:set 'mouse-wheel-change-button)
|
||||
|
||||
(defcustom mouse-wheel-up-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
'wheel-down
|
||||
|
@ -72,6 +79,13 @@
|
|||
:type 'symbol
|
||||
:set 'mouse-wheel-change-button)
|
||||
|
||||
(defcustom mouse-wheel-up-alternate-event
|
||||
(when (featurep 'xinput2) 'wheel-down)
|
||||
"Alternative wheel up event to consider."
|
||||
:group 'mouse
|
||||
:type 'symbol
|
||||
:set 'mouse-wheel-change-button)
|
||||
|
||||
(defcustom mouse-wheel-click-event 'mouse-2
|
||||
"Event that should be temporarily inhibited after mouse scrolling.
|
||||
The mouse wheel is typically on the mouse-2 button, so it may easily
|
||||
|
@ -226,12 +240,20 @@ Also see `mouse-wheel-tilt-scroll'."
|
|||
'mouse-6)
|
||||
"Event used for scrolling left.")
|
||||
|
||||
(defvar mouse-wheel-left-alternate-event
|
||||
(when (featurep 'xinput2) 'wheel-left)
|
||||
"Alternative wheel left event to consider.")
|
||||
|
||||
(defvar mouse-wheel-right-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
'wheel-right
|
||||
'mouse-7)
|
||||
"Event used for scrolling right.")
|
||||
|
||||
(defvar mouse-wheel-right-alternate-event
|
||||
(when (featurep 'xinput2) 'wheel-right)
|
||||
"Alternative wheel right event to consider.")
|
||||
|
||||
(defun mouse-wheel--get-scroll-window (event)
|
||||
"Return window for mouse wheel event EVENT.
|
||||
If `mouse-wheel-follow-mouse' is non-nil, return the window that
|
||||
|
@ -296,14 +318,16 @@ value of ARG, and the command uses it in subsequent scrolls."
|
|||
(condition-case nil
|
||||
(unwind-protect
|
||||
(let ((button (mwheel-event-button event)))
|
||||
(cond ((and (eq amt 'hscroll) (eq button mouse-wheel-down-event))
|
||||
(cond ((and (eq amt 'hscroll) (memq button (list mouse-wheel-down-event
|
||||
mouse-wheel-down-alternate-event)))
|
||||
(when (and (natnump arg) (> arg 0))
|
||||
(setq mouse-wheel-scroll-amount-horizontal arg))
|
||||
(funcall (if mouse-wheel-flip-direction
|
||||
mwheel-scroll-left-function
|
||||
mwheel-scroll-right-function)
|
||||
mouse-wheel-scroll-amount-horizontal))
|
||||
((eq button mouse-wheel-down-event)
|
||||
((memq button (list mouse-wheel-down-event
|
||||
mouse-wheel-down-alternate-event))
|
||||
(condition-case nil (funcall mwheel-scroll-down-function amt)
|
||||
;; Make sure we do indeed scroll to the beginning of
|
||||
;; the buffer.
|
||||
|
@ -318,23 +342,27 @@ value of ARG, and the command uses it in subsequent scrolls."
|
|||
;; for a reason that escapes me. This problem seems
|
||||
;; to only affect scroll-down. --Stef
|
||||
(set-window-start (selected-window) (point-min))))))
|
||||
((and (eq amt 'hscroll) (eq button mouse-wheel-up-event))
|
||||
((and (eq amt 'hscroll) (memq button (list mouse-wheel-up-event
|
||||
mouse-wheel-up-alternate-event)))
|
||||
(when (and (natnump arg) (> arg 0))
|
||||
(setq mouse-wheel-scroll-amount-horizontal arg))
|
||||
(funcall (if mouse-wheel-flip-direction
|
||||
mwheel-scroll-right-function
|
||||
mwheel-scroll-left-function)
|
||||
mouse-wheel-scroll-amount-horizontal))
|
||||
((eq button mouse-wheel-up-event)
|
||||
((memq button (list mouse-wheel-up-event
|
||||
mouse-wheel-up-alternate-event))
|
||||
(condition-case nil (funcall mwheel-scroll-up-function amt)
|
||||
;; Make sure we do indeed scroll to the end of the buffer.
|
||||
(end-of-buffer (while t (funcall mwheel-scroll-up-function)))))
|
||||
((eq button mouse-wheel-left-event) ; for tilt scroll
|
||||
((memq button (list mouse-wheel-left-event
|
||||
mouse-wheel-left-alternate-event)) ; for tilt scroll
|
||||
(when mouse-wheel-tilt-scroll
|
||||
(funcall (if mouse-wheel-flip-direction
|
||||
mwheel-scroll-right-function
|
||||
mwheel-scroll-left-function) amt)))
|
||||
((eq button mouse-wheel-right-event) ; for tilt scroll
|
||||
((memq button (list mouse-wheel-right-event
|
||||
mouse-wheel-right-alternate-event)) ; for tilt scroll
|
||||
(when mouse-wheel-tilt-scroll
|
||||
(funcall (if mouse-wheel-flip-direction
|
||||
mwheel-scroll-left-function
|
||||
|
@ -378,9 +406,11 @@ value of ARG, and the command uses it in subsequent scrolls."
|
|||
(button (mwheel-event-button event)))
|
||||
(select-window scroll-window 'mark-for-redisplay)
|
||||
(unwind-protect
|
||||
(cond ((eq button mouse-wheel-down-event)
|
||||
(cond ((memq button (list mouse-wheel-down-event
|
||||
mouse-wheel-down-alternate-event))
|
||||
(text-scale-increase 1))
|
||||
((eq button mouse-wheel-up-event)
|
||||
((eq button (list mouse-wheel-up-event
|
||||
mouse-wheel-up-alternate-event))
|
||||
(text-scale-decrease 1)))
|
||||
(select-window selected-window))))
|
||||
|
||||
|
@ -432,15 +462,23 @@ an event used for scrolling, such as `mouse-wheel-down-event'."
|
|||
(cond
|
||||
;; Bindings for changing font size.
|
||||
((and (consp binding) (eq (cdr binding) 'text-scale))
|
||||
(dolist (event (list mouse-wheel-down-event mouse-wheel-up-event))
|
||||
(mouse-wheel--add-binding `[,(list (caar binding) event)]
|
||||
'mouse-wheel-text-scale)))
|
||||
(dolist (event (list mouse-wheel-down-event mouse-wheel-up-event
|
||||
mouse-wheel-down-alternate-event
|
||||
mouse-wheel-up-alternate-event))
|
||||
(when event
|
||||
(mouse-wheel--add-binding `[,(list (caar binding) event)]
|
||||
'mouse-wheel-text-scale))))
|
||||
;; Bindings for scrolling.
|
||||
(t
|
||||
(dolist (event (list mouse-wheel-down-event mouse-wheel-up-event
|
||||
mouse-wheel-left-event mouse-wheel-right-event))
|
||||
(dolist (key (mouse-wheel--create-scroll-keys binding event))
|
||||
(mouse-wheel--add-binding key 'mwheel-scroll)))))))
|
||||
mouse-wheel-left-event mouse-wheel-right-event
|
||||
mouse-wheel-down-alternate-event
|
||||
mouse-wheel-up-alternate-event
|
||||
mouse-wheel-left-alternate-event
|
||||
mouse-wheel-right-alternate-event))
|
||||
(when event
|
||||
(dolist (key (mouse-wheel--create-scroll-keys binding event))
|
||||
(mouse-wheel--add-binding key 'mwheel-scroll))))))))
|
||||
|
||||
(when mouse-wheel-mode
|
||||
(mouse-wheel--setup-bindings))
|
||||
|
|
|
@ -258,6 +258,9 @@ XINERAMA_CFLAGS = @XINERAMA_CFLAGS@
|
|||
XFIXES_LIBS = @XFIXES_LIBS@
|
||||
XFIXES_CFLAGS = @XFIXES_CFLAGS@
|
||||
|
||||
XINPUT_LIBS = @XINPUT_LIBS@
|
||||
XINPUT_CFLAGS = @XINPUT_CFLAGS@
|
||||
|
||||
XDBE_LIBS = @XDBE_LIBS@
|
||||
XDBE_CFLAGS = @XDBE_CFLAGS@
|
||||
|
||||
|
@ -374,7 +377,7 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
|
|||
$(GNUSTEP_CFLAGS) $(CFLAGS_SOUND) $(RSVG_CFLAGS) $(IMAGEMAGICK_CFLAGS) \
|
||||
$(PNG_CFLAGS) $(LIBXML2_CFLAGS) $(LIBGCCJIT_CFLAGS) $(DBUS_CFLAGS) \
|
||||
$(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(XFIXES_CFLAGS) $(XDBE_CFLAGS) \
|
||||
$(WEBKIT_CFLAGS) $(WEBP_CFLAGS) $(LCMS2_CFLAGS) \
|
||||
$(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
|
||||
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
|
||||
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
|
||||
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
|
||||
|
@ -524,7 +527,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
|
|||
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
|
||||
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
|
||||
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
|
||||
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS)
|
||||
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS)
|
||||
|
||||
## FORCE it so that admin/unidata can decide whether this file is
|
||||
## up-to-date. Although since charprop depends on bootstrap-emacs,
|
||||
|
|
|
@ -47,6 +47,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XFT
|
||||
#include <X11/Xft/Xft.h>
|
||||
#endif
|
||||
|
@ -839,6 +843,23 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined HAVE_GTK3 && defined HAVE_XINPUT2
|
||||
bool
|
||||
xg_is_menu_window (Display *dpy, Window wdesc)
|
||||
{
|
||||
GtkWidget *gwdesc = xg_win_to_widget (dpy, wdesc);
|
||||
|
||||
if (GTK_IS_WINDOW (gwdesc))
|
||||
{
|
||||
GtkWidget *fw = gtk_bin_get_child (GTK_BIN (gwdesc));
|
||||
if (GTK_IS_MENU (fw))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make a geometry string and pass that to GTK. It seems this is the
|
||||
only way to get geometry position right if the user explicitly
|
||||
asked for a position when starting Emacs.
|
||||
|
@ -3589,6 +3610,18 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
|
|||
|
||||
if (! x->menubar_widget) return 0;
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data;
|
||||
if (event->type == GenericEvent) /* XI_ButtonPress or XI_ButtonRelease */
|
||||
{
|
||||
if (! (xev->event_x >= 0
|
||||
&& xev->event_x < FRAME_PIXEL_WIDTH (f)
|
||||
&& xev->event_y >= 0
|
||||
&& xev->event_y < FRAME_MENUBAR_HEIGHT (f)))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (! (event->xbutton.x >= 0
|
||||
&& event->xbutton.x < FRAME_PIXEL_WIDTH (f)
|
||||
&& event->xbutton.y >= 0
|
||||
|
@ -3597,7 +3630,12 @@ xg_event_is_for_menubar (struct frame *f, const XEvent *event)
|
|||
return 0;
|
||||
|
||||
gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
|
||||
gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window);
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (event->type == GenericEvent)
|
||||
gw = gdk_x11_window_lookup_for_display (gdpy, xev->event);
|
||||
else
|
||||
#endif
|
||||
gw = gdk_x11_window_lookup_for_display (gdpy, event->xbutton.window);
|
||||
if (! gw) return 0;
|
||||
gevent.any.window = gw;
|
||||
gevent.any.type = GDK_NOTHING;
|
||||
|
@ -4244,7 +4282,20 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
|
|||
{
|
||||
bool retval = 0;
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
XIDeviceEvent *xev = (XIDeviceEvent *) event->xcookie.data;
|
||||
if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
|
||||
&& event->type == GenericEvent
|
||||
&& (event->xgeneric.extension
|
||||
== FRAME_DISPLAY_INFO (f)->xi2_opcode)
|
||||
&& ((event->xgeneric.evtype == XI_ButtonPress
|
||||
&& xev->detail < 4)
|
||||
|| (event->xgeneric.evtype == XI_Motion)))
|
||||
|| (event->type == ButtonPress
|
||||
&& event->xbutton.button < 4)))
|
||||
#else
|
||||
if (f && event->type == ButtonPress && event->xbutton.button < 4)
|
||||
#endif /* HAVE_XINPUT2 */
|
||||
{
|
||||
/* Check if press occurred outside the edit widget. */
|
||||
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
|
||||
|
@ -4262,10 +4313,29 @@ xg_event_is_for_scrollbar (struct frame *f, const XEvent *event)
|
|||
gwin = gdk_display_get_window_at_pointer (gdpy, NULL, NULL);
|
||||
#endif
|
||||
retval = gwin != gtk_widget_get_window (f->output_data.x->edit_widget);
|
||||
#ifdef HAVE_XINPUT2
|
||||
GtkWidget *grab = gtk_grab_get_current ();
|
||||
if (event->type == GenericEvent
|
||||
&& event->xgeneric.evtype == XI_Motion)
|
||||
retval = retval || (grab && GTK_IS_SCROLLBAR (grab));
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_XINPUT2
|
||||
else if (f && ((FRAME_DISPLAY_INFO (f)->supports_xi2
|
||||
&& event->type == GenericEvent
|
||||
&& (event->xgeneric.extension
|
||||
== FRAME_DISPLAY_INFO (f)->xi2_opcode)
|
||||
&& ((event->xgeneric.evtype == XI_ButtonRelease
|
||||
&& xev->detail < 4)
|
||||
|| (event->xgeneric.evtype == XI_Motion)))
|
||||
|| ((event->type == ButtonRelease
|
||||
&& event->xbutton.button < 4)
|
||||
|| event->type == MotionNotify)))
|
||||
#else
|
||||
else if (f
|
||||
&& ((event->type == ButtonRelease && event->xbutton.button < 4)
|
||||
|| event->type == MotionNotify))
|
||||
#endif /* HAVE_XINPUT2 */
|
||||
{
|
||||
/* If we are releasing or moving the scroll bar, it has the grab. */
|
||||
GtkWidget *w = gtk_grab_get_current ();
|
||||
|
|
|
@ -192,6 +192,10 @@ extern Lisp_Object xg_get_page_setup (void);
|
|||
extern void xg_print_frames_dialog (Lisp_Object);
|
||||
#endif
|
||||
|
||||
#if defined HAVE_GTK3 && defined HAVE_XINPUT2
|
||||
extern bool xg_is_menu_window (Display *dpy, Window);
|
||||
#endif
|
||||
|
||||
/* Mark all callback data that are Lisp_object:s during GC. */
|
||||
extern void xg_mark_data (void);
|
||||
|
||||
|
|
50
src/xfns.c
50
src/xfns.c
|
@ -57,6 +57,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <X11/extensions/Xdbe.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
#include <X11/Shell.h>
|
||||
|
||||
|
@ -2912,6 +2916,37 @@ initial_set_up_x_back_buffer (struct frame *f)
|
|||
unblock_input ();
|
||||
}
|
||||
|
||||
#if defined HAVE_XINPUT2 && !defined USE_GTK
|
||||
static void
|
||||
setup_xi_event_mask (struct frame *f)
|
||||
{
|
||||
XIEventMask mask;
|
||||
ptrdiff_t l = XIMaskLen (XI_LASTEVENT);
|
||||
unsigned char *m;
|
||||
|
||||
mask.mask = m = alloca (l);
|
||||
memset (m, 0, l);
|
||||
mask.mask_len = l;
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
|
||||
XISetMask (m, XI_ButtonPress);
|
||||
XISetMask (m, XI_ButtonRelease);
|
||||
XISetMask (m, XI_KeyPress);
|
||||
XISetMask (m, XI_KeyRelease);
|
||||
XISetMask (m, XI_Motion);
|
||||
XISetMask (m, XI_Enter);
|
||||
XISetMask (m, XI_Leave);
|
||||
XISetMask (m, XI_FocusIn);
|
||||
XISetMask (m, XI_FocusOut);
|
||||
XISetMask (m, XI_PropertyEvent);
|
||||
XISetMask (m, XI_HierarchyChanged);
|
||||
XISetMask (m, XI_DeviceChanged);
|
||||
XISelectEvents (FRAME_X_DISPLAY (f),
|
||||
FRAME_X_WINDOW (f),
|
||||
&mask, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
|
||||
/* Create and set up the X widget for frame F. */
|
||||
|
@ -3074,6 +3109,11 @@ x_window (struct frame *f, long window_prompting)
|
|||
class_hints.res_class = SSDATA (Vx_resource_class);
|
||||
XSetClassHint (FRAME_X_DISPLAY (f), XtWindow (shell_widget), &class_hints);
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (FRAME_DISPLAY_INFO (f)->supports_xi2)
|
||||
setup_xi_event_mask (f);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_X_I18N
|
||||
FRAME_XIC (f) = NULL;
|
||||
if (use_xim)
|
||||
|
@ -3254,6 +3294,11 @@ x_window (struct frame *f)
|
|||
}
|
||||
#endif /* HAVE_X_I18N */
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (FRAME_DISPLAY_INFO (f)->supports_xi2)
|
||||
setup_xi_event_mask (f);
|
||||
#endif
|
||||
|
||||
validate_x_resource_name ();
|
||||
|
||||
class_hints.res_name = SSDATA (Vx_resource_name);
|
||||
|
@ -8038,6 +8083,11 @@ eliminated in future versions of Emacs. */);
|
|||
/* Tell Emacs about this window system. */
|
||||
Fprovide (Qx, Qnil);
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
DEFSYM (Qxinput2, "xinput2");
|
||||
Fprovide (Qxinput2, Qnil);
|
||||
#endif
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
Fprovide (intern_c_string ("x-toolkit"), Qnil);
|
||||
#ifdef USE_MOTIF
|
||||
|
|
|
@ -105,7 +105,11 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
|
||||
/* Flag which when set indicates a dialog or menu has been posted by
|
||||
Xt on behalf of one of the widget sets. */
|
||||
#ifndef HAVE_XINPUT2
|
||||
static int popup_activated_flag;
|
||||
#else
|
||||
int popup_activated_flag;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_X_TOOLKIT
|
||||
|
|
1107
src/xterm.c
1107
src/xterm.c
File diff suppressed because it is too large
Load diff
44
src/xterm.h
44
src/xterm.h
|
@ -88,6 +88,10 @@ typedef GtkWidget *xt_or_gtk_widget;
|
|||
#include <X11/Xlib-xcb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#include "dispextern.h"
|
||||
#include "termhooks.h"
|
||||
|
||||
|
@ -163,6 +167,28 @@ struct color_name_cache_entry
|
|||
char *name;
|
||||
};
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
struct xi_scroll_valuator_t
|
||||
{
|
||||
bool invalid_p;
|
||||
double current_value;
|
||||
double emacs_value;
|
||||
double increment;
|
||||
|
||||
int number;
|
||||
int horizontal;
|
||||
};
|
||||
|
||||
struct xi_device_t
|
||||
{
|
||||
int device_id;
|
||||
int scroll_valuator_count;
|
||||
int grab;
|
||||
|
||||
struct xi_scroll_valuator_t *valuators;
|
||||
};
|
||||
#endif
|
||||
|
||||
Status x_parse_color (struct frame *f, const char *color_name,
|
||||
XColor *color);
|
||||
|
||||
|
@ -474,6 +500,19 @@ struct x_display_info
|
|||
#ifdef HAVE_XDBE
|
||||
bool supports_xdbe;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
bool supports_xi2;
|
||||
int xi2_version;
|
||||
int xi2_opcode;
|
||||
|
||||
int num_devices;
|
||||
struct xi_device_t *devices;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
XkbDescPtr xkb_desc;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef HAVE_X_I18N
|
||||
|
@ -481,6 +520,11 @@ struct x_display_info
|
|||
extern bool use_xim;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
/* Defined in xmenu.c. */
|
||||
extern int popup_activated_flag;
|
||||
#endif
|
||||
|
||||
/* This is a chain of structures for all the X displays currently in use. */
|
||||
extern struct x_display_info *x_display_list;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue