]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix old X menu on builds with XI2
authorPo Lu <luangruo@yahoo.com>
Tue, 1 Mar 2022 06:44:02 +0000 (14:44 +0800)
committerPo Lu <luangruo@yahoo.com>
Tue, 1 Mar 2022 06:44:02 +0000 (14:44 +0800)
* oldXMenu/Activate.c (XMenuActivateSetTranslateFunction): New
function.
(XMenuActivate): Handle generic events.
* oldXMenu/XMenu.h: New prototypes.
(Translate_func): New type.
* src/xmenu.c (x_menu_wait_translate_generic_event): New
function.
(x_menu_show): Set translate function.

oldXMenu/Activate.c
oldXMenu/XMenu.h
src/xmenu.c

index 646631df84b0b018e98eccbdce6d111ddadcfb6e..447b7398ca28109ebf44045d307d07a82dbf354d 100644 (file)
@@ -121,6 +121,7 @@ int x_menu_grab_keyboard = 1;
 
 static Wait_func wait_func;
 static void* wait_data;
+static Translate_func translate_func = NULL;
 
 void
 XMenuActivateSetWaitFunction (Wait_func func, void *data)
@@ -129,6 +130,12 @@ XMenuActivateSetWaitFunction (Wait_func func, void *data)
   wait_data = data;
 }
 
+void
+XMenuActivateSetTranslateFunction (Translate_func func)
+{
+  translate_func = func;
+}
+
 int
 XMenuActivate(
     register Display *display,         /* Display to put menu on. */
@@ -515,6 +522,12 @@ XMenuActivate(
                    feq = feq_tmp;
                }
                else if (_XMEventHandler) (*_XMEventHandler)(&event);
+               break;
+#ifdef HAVE_XINPUT2
+        case GenericEvent:
+           if (translate_func)
+             translate_func (&event);
+#endif
        }
        /*
         * If a selection has been made, break out of the event loop.
index 50ea683409073f21e72338a97e4f58e5626d1334..2eee18a3844f03571230bdb13466ea2ea55f0c48 100644 (file)
@@ -255,6 +255,11 @@ typedef struct _xmenu {
 
 typedef void (*Wait_func)(void*);
 
+/* Function for translating GenericEvents.  It is should call
+   XPutBackEvent on an equivalent artificial core event on any
+   function it wants to translate.  */
+typedef void (*Translate_func)(XEvent *);
+
 /*
  * XMenu library routine declarations.
  */
@@ -274,6 +279,7 @@ void XMenuEventHandler(int (*handler) (XEvent *));
 int XMenuLocate(Display *display, XMenu *menu, int p_num, int s_num, int x_pos, int y_pos, int *ul_x, int *ul_y, int *width, int *height);
 void XMenuSetFreeze(XMenu *menu, int freeze);
 void XMenuActivateSetWaitFunction(Wait_func func, void *data);
+void XMenuActivateSetTranslateFunction(Translate_func func);
 int XMenuActivate(Display *display, XMenu *menu, int *p_num, int *s_num, int x_pos, int y_pos, unsigned int event_mask, char **data, void (*help_callback) (char const *, int, int));
 char *XMenuPost(Display *display, XMenu *menu, int *p_num, int *s_num, int x_pos, int y_pos, int event_mask);
 int XMenuDeletePane(Display *display, XMenu *menu, int p_num);
index e483c8f73b04ea5b722d083e739fb78729dd5428..fb80221e15b568c0bcddf514d7b3f494e97e2e64 100644 (file)
@@ -222,6 +222,64 @@ x_menu_wait_for_event (void *data)
 #endif
     }
 }
+
+#if !defined USE_GTK && !defined USE_X_TOOLKIT && defined HAVE_XINPUT2
+static void
+x_menu_translate_generic_event (XEvent *event)
+{
+  struct x_display_info *dpyinfo;
+  XEvent copy;
+  XIDeviceEvent *xev;
+
+  dpyinfo = x_display_info_for_display (event->xgeneric.display);
+
+  if (event->xgeneric.extension == dpyinfo->xi2_opcode)
+    {
+      eassert (!event->xcookie.data);
+
+      if (XGetEventData (dpyinfo->display, &event->xcookie))
+       {
+         switch (event->xcookie.evtype)
+           {
+           case XI_ButtonPress:
+           case XI_ButtonRelease:
+             xev = (XIDeviceEvent *) event->xcookie.data;
+             copy.xbutton.type = (event->xcookie.evtype == XI_ButtonPress
+                                  ? ButtonPress : ButtonRelease);
+             copy.xbutton.serial = xev->serial;
+             copy.xbutton.send_event = xev->send_event;
+             copy.xbutton.display = dpyinfo->display;
+             copy.xbutton.window = xev->event;
+             copy.xbutton.root = xev->root;
+             copy.xbutton.subwindow = xev->child;
+             copy.xbutton.time = xev->time;
+             copy.xbutton.x = lrint (xev->event_x);
+             copy.xbutton.y = lrint (xev->event_y);
+             copy.xbutton.x_root = lrint (xev->root_x);
+             copy.xbutton.y_root = lrint (xev->root_y);
+             copy.xbutton.state = xev->mods.effective;
+             copy.xbutton.button = xev->detail;
+             copy.xbutton.same_screen = True;
+
+             if (xev->buttons.mask_len)
+               {
+                 if (XIMaskIsSet (xev->buttons.mask, 1))
+                   copy.xbutton.state |= Button1Mask;
+                 if (XIMaskIsSet (xev->buttons.mask, 2))
+                   copy.xbutton.state |= Button2Mask;
+                 if (XIMaskIsSet (xev->buttons.mask, 3))
+                   copy.xbutton.state |= Button3Mask;
+               }
+
+             XPutBackEvent (dpyinfo->display, &copy);
+
+             break;
+           }
+         XFreeEventData (dpyinfo->display, &event->xcookie);
+       }
+    }
+}
+#endif
 #endif /* ! MSDOS */
 
 \f
@@ -2568,6 +2626,9 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
 
 #ifndef MSDOS
   XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f));
+#ifdef HAVE_XINPUT2
+  XMenuActivateSetTranslateFunction (x_menu_translate_generic_event);
+#endif
 #endif
 
   record_unwind_protect_ptr (pop_down_menu,