diff options
author | Keith Packard <keithp@keithp.com> | 2016-06-04 19:55:07 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-06-04 20:21:16 -0700 |
commit | da7b95a398ba6b368334d234c97c37cba015e209 (patch) | |
tree | f9f6a79c4cd0a8af71af4c93344d645def8e6926 | |
parent | 846523786826af6a0f65367517a22be943a2b20d (diff) |
ephyr: Process queued X events before blockingfix-ephyr
If we end up reading all pending X events in the course of other server
execution, then our notify FD callback won't get invoked and we won't
process them. Fix this by clearing the pending event queue before
blocking in the server.
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | hw/kdrive/ephyr/ephyr.c | 118 |
1 files changed, 62 insertions, 56 deletions
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index 2114c1c32..9f1c80391 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -337,29 +337,28 @@ ephyrInternalDamageRedisplay(ScreenPtr pScreen) } static void +ephyrXcbHandleEvent(xcb_generic_event_t *xev); + +static void ephyrScreenBlockHandler(ScreenPtr pScreen, void *timeout, void *pRead) { KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; EphyrScrPriv *scrpriv = screen->driver; + xcb_connection_t *conn = hostx_get_xcbconn(); + xcb_generic_event_t *xev; pScreen->BlockHandler = scrpriv->BlockHandler; (*pScreen->BlockHandler)(pScreen, timeout, pRead); + scrpriv->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = ephyrScreenBlockHandler; - if (scrpriv->pDamage) { - - /* Re-wrap if we're still tracking damage - */ - scrpriv->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = ephyrScreenBlockHandler; + if (scrpriv->pDamage) ephyrInternalDamageRedisplay(pScreen); - } else { - /* Done tracking damage, note that we've left - * the block handler unwrapped - */ - scrpriv->BlockHandler = NULL; - } + while ((xev = xcb_poll_for_queued_event(conn)) != NULL) + ephyrXcbHandleEvent(xev); + } Bool @@ -374,12 +373,6 @@ ephyrSetInternalDamage(ScreenPtr pScreen) (DamageDestroyFunc) 0, DamageReportNone, TRUE, pScreen, pScreen); - /* Wrap only once */ - if (scrpriv->BlockHandler == NULL) { - scrpriv->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = ephyrScreenBlockHandler; - } - pPixmap = (*pScreen->GetScreenPixmap) (pScreen); DamageRegister(&pPixmap->drawable, scrpriv->pDamage); @@ -668,6 +661,10 @@ ephyrInitScreen(ScreenPtr pScreen) Bool ephyrFinishInitScreen(ScreenPtr pScreen) { + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + EphyrScrPriv *scrpriv = screen->driver; + /* FIXME: Calling this even if not using shadow. * Seems harmless enough. But may be safer elsewhere. */ @@ -679,6 +676,9 @@ ephyrFinishInitScreen(ScreenPtr pScreen) return FALSE; #endif + scrpriv->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = ephyrScreenBlockHandler; + return TRUE; } @@ -1117,6 +1117,49 @@ ephyrProcessConfigureNotify(xcb_generic_event_t *xev) } static void +ephyrXcbHandleEvent(xcb_generic_event_t *xev) +{ + switch (xev->response_type & 0x7f) { + case 0: + ephyrProcessErrorEvent(xev); + break; + + case XCB_EXPOSE: + ephyrProcessExpose(xev); + break; + + case XCB_MOTION_NOTIFY: + ephyrProcessMouseMotion(xev); + break; + + case XCB_KEY_PRESS: + ephyrProcessKeyPress(xev); + break; + + case XCB_KEY_RELEASE: + ephyrProcessKeyRelease(xev); + break; + + case XCB_BUTTON_PRESS: + ephyrProcessButtonPress(xev); + break; + + case XCB_BUTTON_RELEASE: + ephyrProcessButtonRelease(xev); + break; + + case XCB_CONFIGURE_NOTIFY: + ephyrProcessConfigureNotify(xev); + break; + } + + if (ephyr_glamor) + ephyr_glamor_process_event(xev); + + free(xev); +} + +static void ephyrXcbNotify(int fd, int ready, void *data) { xcb_connection_t *conn = hostx_get_xcbconn(); @@ -1136,44 +1179,7 @@ ephyrXcbNotify(int fd, int ready, void *data) break; } - switch (xev->response_type & 0x7f) { - case 0: - ephyrProcessErrorEvent(xev); - break; - - case XCB_EXPOSE: - ephyrProcessExpose(xev); - break; - - case XCB_MOTION_NOTIFY: - ephyrProcessMouseMotion(xev); - break; - - case XCB_KEY_PRESS: - ephyrProcessKeyPress(xev); - break; - - case XCB_KEY_RELEASE: - ephyrProcessKeyRelease(xev); - break; - - case XCB_BUTTON_PRESS: - ephyrProcessButtonPress(xev); - break; - - case XCB_BUTTON_RELEASE: - ephyrProcessButtonRelease(xev); - break; - - case XCB_CONFIGURE_NOTIFY: - ephyrProcessConfigureNotify(xev); - break; - } - - if (ephyr_glamor) - ephyr_glamor_process_event(xev); - - free(xev); + ephyrXcbHandleEvent(xev); } } |