diff options
author | Eric Anholt <eric@anholt.net> | 2013-12-20 10:41:43 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2014-03-05 13:10:15 -0800 |
commit | fa2e78788327c41bfd45b3de3c71bf9c26dcc85e (patch) | |
tree | ff642012c52749d40ea72556ee1e1c2ea6e6f082 /hw | |
parent | 9fe052d90cca90fdf750d3a45b151be2ac7f0ebd (diff) |
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 <eric@anholt.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/kdrive/ephyr/ephyr.c | 3 | ||||
-rw-r--r-- | hw/kdrive/ephyr/ephyr_glamor_glx.c | 39 | ||||
-rw-r--r-- | 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 <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 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 */ |