From fa2e78788327c41bfd45b3de3c71bf9c26dcc85e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 20 Dec 2013 10:41:43 -0800 Subject: [PATCH] xephyr: Pass incoming XCB events to the Xlib event filter. 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 Reviewed-by: Keith Packard Reviewed-by: Adam Jackson --- 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 75a6fcb77..def50d8d8 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -1223,6 +1223,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 a937c1ac5..d56907fe7 100644 --- a/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -29,12 +29,17 @@ #include #include +#include +#undef Xcalloc +#undef Xrealloc +#undef Xfree #include #include #include #include #include "ephyr_glamor_glx.h" #include "os.h" +#include /** @{ * @@ -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 950beff3e..8995e1eca 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 */