[PATCH 7/8] xephyr: Pass incoming XCB events to the Xlib event filter.

Eric Anholt eric at anholt.net
Mon Feb 3 10:36:48 PST 2014


This is the same thing that Qt ended up doing to get DRI2's event
mangling to happen despite using an XCB event loop.

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 hw/kdrive/ephyr/ephyr.c            |  3 +++
 hw/kdrive/ephyr/ephyr_glamor_glx.c | 39 ++++++++++++++++++++++++++++++++++++++
 hw/kdrive/ephyr/ephyr_glamor_glx.h | 15 +++++++++++++--
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index e799b6e..aaa9bb9 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -1217,6 +1217,9 @@ ephyrPoll(void)
             break;
         }
 
+        if (ephyr_glamor)
+            ephyr_glamor_process_event(xev);
+
         free(xev);
     }
 }
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.c b/hw/kdrive/ephyr/ephyr_glamor_glx.c
index a937c1a..d56907f 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.c
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c
@@ -29,12 +29,17 @@
 
 #include <stdlib.h>
 #include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
 #include <X11/Xlib-xcb.h>
 #include <xcb/xcb_aux.h>
 #include <pixman.h>
 #include <epoxy/glx.h>
 #include "ephyr_glamor_glx.h"
 #include "os.h"
+#include <X11/Xproto.h>
 
 /** @{
  *
@@ -218,6 +223,40 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
     glXSwapBuffers(dpy, glamor->glx_win);
 }
 
+/**
+ * Xlib-based handling of xcb events for glamor.
+ *
+ * We need to let the Xlib event filtering run on the event so that
+ * Mesa's dri2_glx.c userspace event mangling gets run, and we
+ * correctly get our invalidate events propagated into the driver.
+ */
+void
+ephyr_glamor_process_event(xcb_generic_event_t *xev)
+{
+
+    uint32_t response_type = xev->response_type & 0x7f;
+    /* Note the types on wire_to_event: there's an Xlib XEvent (with
+     * the broken types) that it returns, and a protocol xEvent that
+     * it inspects.
+     */
+    Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event);
+
+    XLockDisplay(dpy);
+    /* Set the event handler to NULL to get access to the current one. */
+    wire_to_event = XESetWireToEvent(dpy, response_type, NULL);
+    if (wire_to_event) {
+        XEvent processed_event;
+
+        /* OK they had an event handler.  Plug it back in, and call
+         * through to it.
+         */
+        XESetWireToEvent(dpy, response_type, wire_to_event);
+        xev->sequence = LastKnownRequestProcessed(dpy);
+        wire_to_event(dpy, &processed_event, (xEvent *)xev);
+    }
+    XUnlockDisplay(dpy);
+}
+
 struct ephyr_glamor *
 ephyr_glamor_glx_screen_init(xcb_window_t win)
 {
diff --git a/hw/kdrive/ephyr/ephyr_glamor_glx.h b/hw/kdrive/ephyr/ephyr_glamor_glx.h
index 950beff..8995e1e 100644
--- a/hw/kdrive/ephyr/ephyr_glamor_glx.h
+++ b/hw/kdrive/ephyr/ephyr_glamor_glx.h
@@ -53,10 +53,21 @@ ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor);
 void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage);
-#else
+
+void
+ephyr_glamor_process_event(xcb_generic_event_t *xev);
+
+#else /* !GLAMOR */
+
 static inline void
 ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
                               struct pixman_region16 *damage)
 {
 }
-#endif
+
+static inline void
+ephyr_glamor_process_event(xcb_generic_event_t *xev)
+{
+}
+
+#endif /* !GLAMOR */
-- 
1.9.rc1



More information about the xorg-devel mailing list