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 <e...@anholt.net> Reviewed-by: Keith Packard <kei...@keithp.com> --- 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 75a6fcb..def50d8 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 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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel