X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-osx%2Ftrunk%2Flauncher%2Frootless-screen.c;fp=synfig-osx%2Ftrunk%2Flauncher%2Frootless-screen.c;h=46fb91608def782956580bdc06b4f894d84520d0;hb=4f638c4f8e5dc642a92d62da31233654eca397b2;hp=0000000000000000000000000000000000000000;hpb=7bf63b38a939d592d8a7c0c1f52aadfda2229427;p=synfig.git diff --git a/synfig-osx/trunk/launcher/rootless-screen.c b/synfig-osx/trunk/launcher/rootless-screen.c new file mode 100644 index 0000000..46fb916 --- /dev/null +++ b/synfig-osx/trunk/launcher/rootless-screen.c @@ -0,0 +1,794 @@ +/* + * Screen routines for Mac OS X rootless X server + * + * Greg Parker gparker@cs.stanford.edu + * + * February 2001 Created + * March 3, 2001 Restructured as generic rootless mode + */ + +/* Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. */ + +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/rootlessScreen.c,v 1.2 2002/04/03 00:06:32 torrey Exp $ */ + + +#include "mi.h" +#include "scrnintstr.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "propertyst.h" +#include "mivalidate.h" +#include "picturestr.h" +#include "os.h" +#include "servermd.h" +#include "colormapst.h" + +#include +#include +#include + +#include "rootless-common.h" +#include "rootless-window.h" + +/* In milcroseconds */ +#define REDISPLAY_DELAY 10 +#define REDISPLAY_MAX_DELAY 60 + +extern int RootlessMiValidateTree(WindowPtr pRoot, + WindowPtr pChild, VTKind kind); +extern Bool RootlessCreateGC(GCPtr pGC); + +int rootlessGCPrivateIndex = -1; +int rootlessScreenPrivateIndex = -1; +int rootlessWindowPrivateIndex = -1; + +void +RootlessUpdateScreenPixmap (ScreenPtr pScreen) +{ + RootlessScreenRec *s = SCREENREC(pScreen); + PixmapPtr pPix; + unsigned int rowbytes; + + pPix = (*pScreen->GetScreenPixmap) (pScreen); + if (pPix == NULL) + { + pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth); + (*pScreen->SetScreenPixmap) (pPix); + } + + rowbytes = PixmapBytePad (pScreen->width, pScreen->rootDepth); + + if (s->pixmap_data_size < rowbytes) + { + if (s->pixmap_data != NULL) + xfree (s->pixmap_data); + + s->pixmap_data_size = rowbytes; + s->pixmap_data = xalloc (s->pixmap_data_size); + if (s->pixmap_data == NULL) + return; + + xp_fill_bytes (s->pixmap_data_size, 1, ~0, + s->pixmap_data, s->pixmap_data_size); + + pScreen->ModifyPixmapHeader (pPix, pScreen->width, pScreen->height, + pScreen->rootDepth, + BitsPerPixel (pScreen->rootDepth), + 0, s->pixmap_data); + /* ModifyPixmapHeader ignores zero arguments, so install rowbytes + by hand. */ + pPix->devKind = 0; + } +} + +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; + + /* miCreateScreenResources doesn't like our null framebuffer pointer, + it leaves the screen pixmap with an uninitialized data pointer. So + we gave it depth=0,bits=0, which says, leave it the fsck alone. + So we have some work to do since we need the screen pixmap to be + valid (e.g. CopyArea from the root window) */ + + RootlessUpdateScreenPixmap (pScreen); + + return ret; +} + +static Bool +RootlessCloseScreen(int i, ScreenPtr pScreen) +{ + RootlessScreenRec *s; + + s = SCREENREC(pScreen); + + /* FIXME: unwrap everything that was wrapped? */ + pScreen->CloseScreen = s->CloseScreen; + + if (s->pixmap_data != NULL) + { + xfree (s->pixmap_data); + s->pixmap_data = NULL; + s->pixmap_data_size = 0; + } + + xfree(s); + return pScreen->CloseScreen(i, pScreen); +} + +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. */ + + 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 + (int) winRec->width); + y1 = MIN (y1, winRec->y + (int) winRec->height); + + /* FIXME: if clipped we need to adjust the data returned from + fbGetImage (), since it calculates the destination stride + from the passed in width.. */ + + 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) +{ + 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); + } + SCREEN_WRAP(pDrawable->pScreen, SourceValidate); +} + +#ifdef RENDER + +static void +rootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, + INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + WindowPtr srcWin, dstWin, maskWin = NULL; + + if (pMask) { + maskWin = (pMask->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr)pMask->pDrawable : NULL; + } + srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr)pSrc->pDrawable : NULL; + dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr)pDst->pDrawable : NULL; + + ps->Composite = SCREENREC(pScreen)->Composite; + + if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); + if (maskWin && IsFramedWindow(maskWin)) RootlessStartDrawing(maskWin); + if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); + + ps->Composite(op, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, + xDst, yDst, width, height); + + if (dstWin && IsFramedWindow(dstWin)) { + RootlessDamageRect(dstWin, xDst, yDst, width, height); + } + + ps->Composite = RootlessComposite; +} + +static void +RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int nlist, GlyphListPtr list, GlyphPtr *glyphs) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + int x, y; + int n; + GlyphPtr glyph; + WindowPtr srcWin, dstWin; + + srcWin = (pSrc->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr)pSrc->pDrawable : NULL; + dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ? + (WindowPtr)pDst->pDrawable : NULL; + + if (srcWin && IsFramedWindow(srcWin)) RootlessStartDrawing(srcWin); + if (dstWin && IsFramedWindow(dstWin)) RootlessStartDrawing(dstWin); + + ps->Glyphs = SCREENREC(pScreen)->Glyphs; + ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); + ps->Glyphs = RootlessGlyphs; + + if (dstWin && IsFramedWindow(dstWin)) + { + x = xSrc; + y = ySrc; + + while (nlist--) + { + /* Originally this code called DamageRect for the bounding + box of each glyph. But that was causing way too much + time to be spent in CGSBoundingRegionAddRect. So compute + the union of all glyphs in a list and damage that. It + shouldn't be very different. */ + + x += list->xOff; + y += list->yOff; + n = list->len; + + if (n > 0) + { + BoxRec box; + + glyph = *glyphs++; + + box.x1 = x - glyph->info.x; + box.y1 = y - glyph->info.y; + box.x2 = box.x1 + glyph->info.width; + box.y2 = box.y2 + glyph->info.height; + + x += glyph->info.xOff; + y += glyph->info.yOff; + + while (--n > 0) + { + short x1, y1, x2, y2; + + glyph = *glyphs++; + + x1 = x - glyph->info.x; + y1 = y - glyph->info.y; + x2 = x1 + glyph->info.width; + y2 = y1 + glyph->info.height; + + box.x1 = MAX (box.x1, x1); + box.y1 = MAX (box.y1, y1); + box.x2 = MAX (box.x2, x2); + box.y2 = MAX (box.y2, y2); + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + + RootlessDamageBox (dstWin, &box); + } + + list++; + } + } +} + +#endif /* RENDER */ + +/* 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; +} + +/* 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; + void (* 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 (REGION_BROKEN (pScreen, &pChild->winSize)) + SetWinSize (pChild); + if (REGION_BROKEN (pScreen, &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; +} + +static void +expose_1 (WindowPtr pWin) +{ + WindowPtr pChild; + + if (!pWin->realized) + return; + + (*pWin->drawable.pScreen->PaintWindowBackground) (pWin, &pWin->borderClip, + PW_BACKGROUND); + + /* FIXME: comments in windowstr.h indicate that borderClip doesn't + include subwindow visibility. But I'm not so sure.. so we may + be exposing too much.. */ + + miSendExposures (pWin, &pWin->borderClip, + pWin->drawable.x, pWin->drawable.y); + + for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib) + expose_1 (pChild); +} + +void +RootlessScreenExpose (ScreenPtr pScreen) +{ + expose_1 (WindowTable[pScreen->myNum]); +} + +ColormapPtr +RootlessGetColormap (ScreenPtr pScreen) +{ + RootlessScreenRec *s = SCREENREC (pScreen); + + return s->colormap; +} + +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); +} + +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 CARD32 +redisplay_callback (OsTimerPtr timer, CARD32 time, void *arg) +{ + RootlessScreenRec *screenRec = arg; + + if (!screenRec->redisplay_queued) + { + /* No update needed. Stop the timer. */ + + screenRec->redisplay_timer_set = FALSE; + return 0; + } + + screenRec->redisplay_queued = FALSE; + + /* Mark that we should redisplay before waiting for I/O next time */ + screenRec->redisplay_expired = TRUE; + + /* Reinstall the timer immediately, so we get as close to our + redisplay interval as possible. */ + + return REDISPLAY_DELAY; +} + +void +RootlessQueueRedisplay (ScreenPtr pScreen) +{ + RootlessScreenRec *screenRec = SCREENREC (pScreen); + + screenRec->redisplay_queued = TRUE; + + if (screenRec->redisplay_timer_set) + return; + + screenRec->redisplay_timer = TimerSet (screenRec->redisplay_timer, + 0, REDISPLAY_DELAY, + redisplay_callback, screenRec); + screenRec->redisplay_timer_set = TRUE; +} + +/* Call this function when it might be a good idea to flush updates. + Note that it will unlock window buffers! */ +Bool +RootlessMayRedisplay (ScreenPtr pScreen) +{ + RootlessScreenRec *screenRec = SCREENREC (pScreen); + + if (!screenRec->redisplay_queued) + return FALSE; + + /* If the timer has fired, or it's been long enough since the last + update, redisplay everything now. */ + + if (!screenRec->redisplay_expired) + { + CARD32 now = GetTimeInMillis (); + + if (screenRec->last_redisplay + REDISPLAY_MAX_DELAY >= now) + return FALSE; + } + + if (screenRec->redisplay_timer_set) + { + TimerCancel (screenRec->redisplay_timer); + screenRec->redisplay_timer_set = FALSE; + } + + RootlessRedisplayScreen (screenRec->pScreen); + screenRec->redisplay_expired = FALSE; + + return TRUE; +} + +/* Flush drawing before blocking on select(). */ +static void +RootlessBlockHandler(pointer pbdata, OSTimePtr pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = pbdata; + RootlessScreenRec *screenRec = SCREENREC (pScreen); + + if (screenRec->redisplay_expired) + { + screenRec->redisplay_expired = FALSE; + + if (screenRec->colormap_changed) + { + RootlessFlushScreenColormaps (screenRec->pScreen); + screenRec->colormap_changed = FALSE; + } + + RootlessRedisplayScreen (screenRec->pScreen); + } +} + +static void +RootlessWakeupHandler(pointer data, int i, pointer LastSelectMask) +{ +} + +static Bool +RootlessAllocatePrivates(ScreenPtr pScreen) +{ + RootlessScreenRec *s; + static unsigned int rootlessGeneration = -1; + + if (rootlessGeneration != serverGeneration) { + rootlessScreenPrivateIndex = AllocateScreenPrivateIndex(); + if (rootlessScreenPrivateIndex == -1) return FALSE; + rootlessGCPrivateIndex = AllocateGCPrivateIndex(); + if (rootlessGCPrivateIndex == -1) return FALSE; + rootlessWindowPrivateIndex = AllocateWindowPrivateIndex(); + if (rootlessWindowPrivateIndex == -1) return FALSE; + rootlessGeneration = serverGeneration; + } + + /* no allocation needed for screen privates */ + if (!AllocateGCPrivate(pScreen, rootlessGCPrivateIndex, + sizeof(RootlessGCRec))) + return FALSE; + if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0)) + return FALSE; + + s = xalloc(sizeof(RootlessScreenRec)); + if (! s) return FALSE; + SCREENREC(pScreen) = s; + + s->pixmap_data = NULL; + s->pixmap_data_size = 0; + + s->redisplay_timer = NULL; + s->redisplay_timer_set = FALSE; + + return TRUE; +} + +static void +RootlessWrap(ScreenPtr pScreen) +{ + RootlessScreenRec *s = (RootlessScreenRec*) + pScreen->devPrivates[rootlessScreenPrivateIndex].ptr; + +#define WRAP(a) \ + if (pScreen->a) { \ + s->a = pScreen->a; \ + } else { \ + RL_DEBUG_MSG("null screen fn " #a "\n"); \ + s->a = NULL; \ + } \ + pScreen->a = Rootless##a + + WRAP(CreateScreenResources); + WRAP(CloseScreen); + WRAP(CreateGC); + WRAP(PaintWindowBackground); + WRAP(PaintWindowBorder); + WRAP(CopyWindow); + WRAP(GetImage); + WRAP(SourceValidate); + WRAP(CreateWindow); + WRAP(DestroyWindow); + WRAP(RealizeWindow); + WRAP(UnrealizeWindow); + WRAP(ReparentWindow); + WRAP(MoveWindow); + WRAP(PositionWindow); + WRAP(ResizeWindow); + WRAP(RestackWindow); + WRAP(ChangeBorderWidth); + WRAP(MarkOverlappedWindows); + WRAP(ValidateTree); + WRAP(ChangeWindowAttributes); + WRAP(InstallColormap); + WRAP(UninstallColormap); + WRAP(StoreColors); + +#ifdef SHAPE + WRAP(SetShape); +#endif + +#ifdef RENDER + { + /* Composite and Glyphs don't use normal screen wrapping */ + PictureScreenPtr ps = GetPictureScreen(pScreen); + s->Composite = ps->Composite; + ps->Composite = rootlessComposite; + s->Glyphs = ps->Glyphs; + ps->Glyphs = RootlessGlyphs; + } +#endif + + // WRAP(ClearToBackground); fixme put this back? useful for shaped wins? + // WRAP(RestoreAreas); fixme put this back? + +#undef WRAP +} + +Bool +RootlessSetupScreen(int index, ScreenPtr pScreen) +{ + RootlessScreenRec *s; + + /* Add replacements for fb screen functions */ + pScreen->PaintWindowBackground = RootlessPaintWindow; + pScreen->PaintWindowBorder = RootlessPaintWindow; + +#ifdef RENDER + { + PictureScreenPtr ps = GetPictureScreen(pScreen); + ps->Composite = RootlessComposite; + } +#endif + + if (!RootlessAllocatePrivates(pScreen)) + return FALSE; + + s = ((RootlessScreenRec*) + pScreen->devPrivates[rootlessScreenPrivateIndex].ptr); + + s->pScreen = pScreen; + RootlessWrap(pScreen); + + if (!RegisterBlockAndWakeupHandlers (RootlessBlockHandler, + RootlessWakeupHandler, + (pointer) pScreen)) + { + return FALSE; + } + + return TRUE; +} + +void +RootlessUpdateRooted (Bool state) +{ + int i; + + if (!state) + { + for (i = 0; i < screenInfo.numScreens; i++) + RootlessDisableRoot (screenInfo.screens[i]); + } + else + { + for (i = 0; i < screenInfo.numScreens; i++) + RootlessEnableRoot (screenInfo.screens[i]); + } +}