mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-02-14 22:40:29 +01:00
Handle back-end server expose events properly.
This commit is contained in:
parent
f8454fe814
commit
f14ec79b25
3 changed files with 117 additions and 95 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue