[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