From f14ec79b25728b963b0d4e4ec4993829d87238f4 Mon Sep 17 00:00:00 2001 From: David Reveman Date: Tue, 3 Jun 2008 18:51:51 -0400 Subject: [PATCH] Handle back-end server expose events properly. --- hw/dmx/dmxscrinit.c | 164 +++++++++++++++++++++++++++++++------------- hw/dmx/dmxwindow.c | 46 +------------ hw/dmx/dmxwindow.h | 2 - 3 files changed, 117 insertions(+), 95 deletions(-) diff --git a/hw/dmx/dmxscrinit.c b/hw/dmx/dmxscrinit.c index d1b602a2a..63c57f3ec 100644 --- a/hw/dmx/dmxscrinit.c +++ b/hw/dmx/dmxscrinit.c @@ -1146,55 +1146,28 @@ dmxRRModeDestroy (ScreenPtr pScreen, } static void -dmxRRCheckScreens (void) +dmxRRCheckScreen (ScreenPtr pScreen) { - int i; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - for (i = 0; i < dmxNumScreens; i++) + if (dmxScreen->beDisplay && dmxScreen->beRandr) { - DMXScreenInfo *dmxScreen = &dmxScreens[i]; + XEvent event; - if (dmxScreen->beDisplay && dmxScreen->beRandr) - { - XEvent event; - - XLIB_PROLOGUE (dmxScreen); - while (XCheckTypedEvent (dmxScreen->beDisplay, - dmxScreen->beRandrEventBase + - RRScreenChangeNotify, - &event)) - { - dmxScreen->beRandrPending = TRUE; - RRTellChanged (screenInfo.screens[0]); - } - while (XCheckTypedEvent (dmxScreen->beDisplay, - dmxScreen->beRandrEventBase + RRNotify, - &event)) - { - dmxScreen->beRandrPending = TRUE; - RRTellChanged (screenInfo.screens[0]); - } - XLIB_EPILOGUE (dmxScreen); - } + XLIB_PROLOGUE (dmxScreen); + while (XCheckTypedEvent (dmxScreen->beDisplay, + dmxScreen->beRandrEventBase + + RRScreenChangeNotify, + &event)) + RRTellChanged (screenInfo.screens[0]); + while (XCheckTypedEvent (dmxScreen->beDisplay, + dmxScreen->beRandrEventBase + RRNotify, + &event)) + RRTellChanged (screenInfo.screens[0]); + XLIB_EPILOGUE (dmxScreen); } } -static void -dmxRRBlockHandler (pointer blockData, - OSTimePtr pTimeout, - pointer pReadMask) -{ - dmxRRCheckScreens (); -} - -static void -dmxRRWakeupHandler (pointer blockData, - int result, - pointer pReadMask) -{ - dmxRRCheckScreens (); -} - static Bool dmxRRInit (ScreenPtr pScreen) { @@ -1285,10 +1258,6 @@ dmxRRInit (ScreenPtr pScreen) } } - RegisterBlockAndWakeupHandlers (dmxRRBlockHandler, - dmxRRWakeupHandler, - NULL); - return TRUE; } @@ -1482,6 +1451,103 @@ dmxSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap) DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen); } +static void +dmxScreenExpose (ScreenPtr pScreen) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + + if (dmxScreen->beDisplay) + { + WindowPtr pChild0, pChildN; + XEvent X; + + for (;;) + { + Bool status = FALSE; + + XLIB_PROLOGUE (dmxScreen); + + status = XCheckTypedEvent (dmxScreen->beDisplay, Expose, &X); + + XLIB_EPILOGUE (dmxScreen); + + if (!status) + break; + + pChild0 = WindowTable[0]; + pChildN = WindowTable[pScreen->myNum]; + + for (;;) + { + dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pChildN); + + if (pWinPriv->window == X.xexpose.window) + break; + + if (pChild0->firstChild) + { + pChild0 = pChild0->firstChild; + pChildN = pChildN->firstChild; + continue; + } + + while (!pChild0->nextSib && (pChild0 != WindowTable[0])) + { + pChild0 = pChild0->parent; + pChildN = pChildN->parent; + } + + if (pChild0 == WindowTable[0]) + break; + + pChild0 = pChild0->nextSib; + pChildN = pChildN->nextSib; + } + + if (pChild0) + { + RegionRec region; + BoxRec box; + + box.x1 = pChild0->drawable.x + X.xexpose.x; + box.y1 = pChild0->drawable.y + X.xexpose.y; + box.x2 = box.x1 + X.xexpose.width; + box.y2 = box.y1 + X.xexpose.height; + + ErrorF ("EXPOSE: %d %d %dx%d\n", box.x1, box.y1, + X.xexpose.width, X.xexpose.height); + + REGION_INIT (screenInfo.screens[0], ®ion, &box, 1); + (*pScreen->WindowExposures) (pChild0, ®ion, NullRegion); + REGION_UNINIT (screenInfo.screens[0], ®ion); + } + } + } +} + +static void +dmxScreenBlockHandler (pointer blockData, + OSTimePtr pTimeout, + pointer pReadMask) +{ + ScreenPtr pScreen = (ScreenPtr) blockData; + + dmxScreenExpose (pScreen); +} + +static void +dmxScreenWakeupHandler (pointer blockData, + int result, + pointer pReadMask) +{ + ScreenPtr pScreen = (ScreenPtr) blockData; + +#ifdef RANDR + dmxRRCheckScreen (pScreen); +#endif + +} + /** Initialize screen number \a idx. */ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) { @@ -1642,7 +1708,6 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen); DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen); DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen); - DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen); DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen); DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen); @@ -1678,6 +1743,10 @@ Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[]) if (!dmxCreateDefColormap(pScreen)) return FALSE; + RegisterBlockAndWakeupHandlers (dmxScreenBlockHandler, + dmxScreenWakeupHandler, + pScreen); + return TRUE; } @@ -1790,7 +1859,6 @@ Bool dmxCloseScreen(int idx, ScreenPtr pScreen) DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen); DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen); DMX_UNWRAP(RestackWindow, dmxScreen, pScreen); - DMX_UNWRAP(WindowExposures, dmxScreen, pScreen); DMX_UNWRAP(CopyWindow, dmxScreen, pScreen); DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen); diff --git a/hw/dmx/dmxwindow.c b/hw/dmx/dmxwindow.c index 89d163577..efa95457a 100644 --- a/hw/dmx/dmxwindow.c +++ b/hw/dmx/dmxwindow.c @@ -247,7 +247,7 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow) } mask |= CWEventMask; - attribs.event_mask = FocusChangeMask; + attribs.event_mask = ExposureMask | FocusChangeMask; /* Incorporate new attributes, if needed */ if (pWinPriv->attribMask) { @@ -826,50 +826,6 @@ void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib) dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow); } -static Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr) -{ - return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr); -} - -/** Handle exposures on \a pWindow. Since window exposures are handled - * in DMX, the events that are generated by the back-end server are - * redundant, so we eat them here. */ -void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn, - RegionPtr other_exposed) -{ - ScreenPtr pScreen = pWindow->drawable.pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow); - XEvent ev; - - DMX_UNWRAP(WindowExposures, dmxScreen, pScreen); - - dmxSync(dmxScreen, False); - - if (pWinPriv->window && dmxScreen->beDisplay) { - - XLIB_PROLOGUE (dmxScreen); - while (XCheckIfEvent(dmxScreen->beDisplay, &ev, - dmxWindowExposurePredicate, - (XPointer)&pWinPriv->window)) { - /* Handle expose events -- this should not be necessary - since the base window in which the root window was - created is guaranteed to be on top (override_redirect), - so we should just swallow these events. If for some - reason the window is not on top, then we'd need to - collect these events and send them to the client later - (e.g., during the block handler as Xnest does). */ - } - XLIB_EPILOGUE (dmxScreen); - } - -#if 1 - if (pScreen->WindowExposures) - pScreen->WindowExposures(pWindow, prgn, other_exposed); -#endif - DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen); -} - /** Move \a pWindow on the back-end server. Determine whether or not it * is on or offscreen, and realize it if it is newly on screen and the * lazy window creation optimization is enabled. */ diff --git a/hw/dmx/dmxwindow.h b/hw/dmx/dmxwindow.h index 5e4a3c0c4..7a864d6ed 100644 --- a/hw/dmx/dmxwindow.h +++ b/hw/dmx/dmxwindow.h @@ -78,8 +78,6 @@ extern Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask); extern Bool dmxRealizeWindow(WindowPtr pWindow); extern Bool dmxUnrealizeWindow(WindowPtr pWindow); extern void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib); -extern void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn, - RegionPtr other_exposed); extern void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc);