/* * RootlessValidateTree * ValidateTree is modified in two ways: * - top-level windows don't clip each other * - windows aren't clipped against root. * These only matter when validating from the root. */ static int RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind) { int result; RegionRec saveRoot; ScreenPtr pScreen = pParent->drawable.pScreen; SCREEN_UNWRAP(pScreen, ValidateTree); RL_DEBUG_MSG("VALIDATETREE start "); // Use our custom version to validate from root if (IsRoot(pParent)) { RL_DEBUG_MSG("custom "); result = RootlessMiValidateTree(pParent, pChild, kind); } else { HUGE_ROOT(pParent); result = pScreen->ValidateTree(pParent, pChild, kind); NORMAL_ROOT(pParent); } SCREEN_WRAP(pScreen, ValidateTree); RL_DEBUG_MSG("VALIDATETREE end\n"); return result; }
static void RootlessPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what) { int oldBackgroundState = 0; PixUnion oldBackground; ScreenPtr pScreen = pWin->drawable.pScreen; SCREEN_UNWRAP(pScreen, PaintWindowBackground); RL_DEBUG_MSG("paintwindowbackground start (win 0x%x) ", pWin); if (IsFramedWindow(pWin)) { if (IsRoot(pWin)) { // set root background to magic transparent color oldBackgroundState = pWin->backgroundState; oldBackground = pWin->background; pWin->backgroundState = BackgroundPixel; pWin->background.pixel = 0x00fffffe; } } pScreen->PaintWindowBackground(pWin, pRegion, what); if (IsFramedWindow(pWin)) { RootlessDamageRegion(pWin, pRegion); if (IsRoot(pWin)) { pWin->backgroundState = oldBackgroundState; pWin->background = oldBackground; } } SCREEN_WRAP(pScreen, PaintWindowBackground); RL_DEBUG_MSG("paintwindowbackground end\n"); }
static void RootlessPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what) { SCREEN_UNWRAP(pWin->drawable.pScreen, PaintWindowBorder); RL_DEBUG_MSG("paintwindowborder start (win 0x%x) ", pWin); pWin->drawable.pScreen->PaintWindowBorder(pWin, pRegion, what); if (IsFramedWindow(pWin)) { RootlessDamageRegion(pWin, pRegion); } SCREEN_WRAP(pWin->drawable.pScreen, PaintWindowBorder); RL_DEBUG_MSG("paintwindowborder end\n"); }
static void RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planeMask, char *pdstLine) { ScreenPtr pScreen = pDrawable->pScreen; SCREEN_UNWRAP(pScreen, GetImage); if (pDrawable->type == DRAWABLE_WINDOW) { int x0, y0, x1, y1; RootlessWindowRec *winRec; // Many apps use GetImage to sync with the visible frame buffer // FIXME: entire screen or just window or all screens? RootlessRedisplayScreen(pScreen); // RedisplayScreen stops drawing, so we need to start it again RootlessStartDrawing((WindowPtr)pDrawable); /* Check that we have some place to read from. */ winRec = WINREC(TopLevelParent((WindowPtr) pDrawable)); if (winRec == NULL) goto out; /* Clip to top-level window bounds. */ /* FIXME: fbGetImage uses the width parameter to calculate the stride of the destination pixmap. If w is clipped, the data returned will be garbage, although we will not crash. */ x0 = pDrawable->x + sx; y0 = pDrawable->y + sy; x1 = x0 + w; y1 = y0 + h; x0 = max (x0, winRec->x); y0 = max (y0, winRec->y); x1 = min (x1, winRec->x + winRec->width); y1 = min (y1, winRec->y + winRec->height); sx = x0 - pDrawable->x; sy = y0 - pDrawable->y; w = x1 - x0; h = y1 - y0; if (w <= 0 || h <= 0) goto out; } pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); out: SCREEN_WRAP(pScreen, GetImage); }
/* * RootlessSourceValidate * CopyArea and CopyPlane use a GC tied to the destination drawable. * StartDrawing/StopDrawing wrappers won't be called if source is * a visible window but the destination isn't. So, we call StartDrawing * here and leave StopDrawing for the block handler. */ static void RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int subWindowMode) { SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate); if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDrawable; RootlessStartDrawing(pWin); } if (pDrawable->pScreen->SourceValidate) { pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h, subWindowMode); } SCREEN_WRAP(pDrawable->pScreen, SourceValidate); }
static void RootlessUninstallColormap (ColormapPtr pMap) { ScreenPtr pScreen = pMap->pScreen; RootlessScreenRec *s = SCREENREC (pScreen); SCREEN_UNWRAP(pScreen, UninstallColormap); if (s->colormap == pMap) s->colormap = NULL; pScreen->UninstallColormap (pMap); SCREEN_WRAP(pScreen, UninstallColormap); }
static void RootlessStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef) { ScreenPtr pScreen = pMap->pScreen; RootlessScreenRec *s = SCREENREC (pScreen); SCREEN_UNWRAP(pScreen, StoreColors); if (s->colormap == pMap && ndef > 0) { s->colormap_changed = TRUE; RootlessQueueRedisplay (pScreen); } pScreen->StoreColors (pMap, ndef, pdef); SCREEN_WRAP(pScreen, StoreColors); }
static void RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, unsigned int format, unsigned long planeMask, char *pdstLine) { ScreenPtr pScreen = pDrawable->pScreen; SCREEN_UNWRAP(pScreen, GetImage); if (pDrawable->type == DRAWABLE_WINDOW) { /* Many apps use GetImage to sync with the visible frame buffer */ // fixme entire screen or just window or all screens? RootlessRedisplayScreen(pScreen); } pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); SCREEN_WRAP(pScreen, GetImage); }
static void RootlessInstallColormap (ColormapPtr pMap) { ScreenPtr pScreen = pMap->pScreen; RootlessScreenRec *s = SCREENREC (pScreen); SCREEN_UNWRAP(pScreen, InstallColormap); if (s->colormap != pMap) { s->colormap = pMap; s->colormap_changed = TRUE; RootlessQueueRedisplay (pScreen); } pScreen->InstallColormap (pMap); SCREEN_WRAP (pScreen, InstallColormap); }
/* * Screen function to create a graphics context */ Bool RootlessCreateGC(GCPtr pGC) { RootlessGCRec *gcrec; RootlessScreenRec *s; Bool result; SCREEN_UNWRAP(pGC->pScreen, CreateGC); s = SCREENREC(pGC->pScreen); result = s->CreateGC(pGC); gcrec = (RootlessGCRec *) dixLookupPrivate(&pGC->devPrivates, rootlessGCPrivateKey); gcrec->originalOps = NULL; // don't wrap ops yet gcrec->originalFuncs = pGC->funcs; pGC->funcs = &rootlessGCFuncs; SCREEN_WRAP(pGC->pScreen, CreateGC); return result; }
/* * RootlessCreateScreenResources * Rootless implementations typically set a null framebuffer pointer, which * causes problems with miCreateScreenResources. We fix things up here. */ static Bool RootlessCreateScreenResources(ScreenPtr pScreen) { Bool ret = TRUE; SCREEN_UNWRAP(pScreen, CreateScreenResources); if (pScreen->CreateScreenResources != NULL) ret = (*pScreen->CreateScreenResources)(pScreen); SCREEN_WRAP(pScreen, CreateScreenResources); if (!ret) return ret; /* Make sure we have a valid screen pixmap. */ RootlessUpdateScreenPixmap(pScreen); return ret; }
/* * RootlessMarkOverlappedWindows * MarkOverlappedWindows is modified to ignore overlapping * top-level windows. */ static Bool RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst, WindowPtr *ppLayerWin) { RegionRec saveRoot; Bool result; ScreenPtr pScreen = pWin->drawable.pScreen; SCREEN_UNWRAP(pScreen, MarkOverlappedWindows); RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start "); HUGE_ROOT(pWin); if (IsRoot(pWin)) { // root - mark nothing RL_DEBUG_MSG("is root not marking "); result = FALSE; } else if (! IsTopLevel(pWin)) { // not top-level window - mark normally result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin); } else { //top-level window - mark children ONLY - NO overlaps with sibs (?) // This code copied from miMarkOverlappedWindows() register WindowPtr pChild; Bool anyMarked = FALSE; MarkWindowProcPtr MarkWindow = pScreen->MarkWindow; RL_DEBUG_MSG("is top level! "); /* single layered systems are easy */ if (ppLayerWin) *ppLayerWin = pWin; if (pWin == pFirst) { /* Blindly mark pWin and all of its inferiors. This is a slight * overkill if there are mapped windows that outside pWin's border, * but it's better than wasting time on RectIn checks. */ pChild = pWin; while (1) { if (pChild->viewable) { if (RegionBroken(&pChild->winSize)) SetWinSize (pChild); if (RegionBroken(&pChild->borderSize)) SetBorderSize (pChild); (* MarkWindow)(pChild); if (pChild->firstChild) { pChild = pChild->firstChild; continue; } } while (!pChild->nextSib && (pChild != pWin)) pChild = pChild->parent; if (pChild == pWin) break; pChild = pChild->nextSib; } anyMarked = TRUE; pFirst = pFirst->nextSib; } if (anyMarked) (* MarkWindow)(pWin->parent); result = anyMarked; } NORMAL_ROOT(pWin); SCREEN_WRAP(pScreen, MarkOverlappedWindows); RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n"); return result; }