summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-06-04 19:55:07 -0700
committerKeith Packard <keithp@keithp.com>2016-06-04 20:21:16 -0700
commitda7b95a398ba6b368334d234c97c37cba015e209 (patch)
treef9f6a79c4cd0a8af71af4c93344d645def8e6926
parent846523786826af6a0f65367517a22be943a2b20d (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.c118
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);
}
}