1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Screen routines for generic rootless X server
3*4882a593Smuzhiyun */
4*4882a593Smuzhiyun /*
5*4882a593Smuzhiyun * Copyright (c) 2001 Greg Parker. All Rights Reserved.
6*4882a593Smuzhiyun * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
7*4882a593Smuzhiyun * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
10*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
11*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
12*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
14*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
17*4882a593Smuzhiyun * all copies or substantial portions of the Software.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22*4882a593Smuzhiyun * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * Except as contained in this notice, the name(s) of the above copyright
28*4882a593Smuzhiyun * holders shall not be used in advertising or otherwise to promote the sale,
29*4882a593Smuzhiyun * use or other dealings in this Software without prior written authorization.
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
33*4882a593Smuzhiyun #include <dix-config.h>
34*4882a593Smuzhiyun #endif
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include "mi.h"
37*4882a593Smuzhiyun #include "scrnintstr.h"
38*4882a593Smuzhiyun #include "gcstruct.h"
39*4882a593Smuzhiyun #include "pixmapstr.h"
40*4882a593Smuzhiyun #include "windowstr.h"
41*4882a593Smuzhiyun #include "propertyst.h"
42*4882a593Smuzhiyun #include "mivalidate.h"
43*4882a593Smuzhiyun #include "picturestr.h"
44*4882a593Smuzhiyun #include "colormapst.h"
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #include <sys/types.h>
47*4882a593Smuzhiyun #include <sys/stat.h>
48*4882a593Smuzhiyun #include <fcntl.h>
49*4882a593Smuzhiyun #include <string.h>
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #include "rootlessCommon.h"
52*4882a593Smuzhiyun #include "rootlessWindow.h"
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun /* In milliseconds */
55*4882a593Smuzhiyun #ifndef ROOTLESS_REDISPLAY_DELAY
56*4882a593Smuzhiyun #define ROOTLESS_REDISPLAY_DELAY 10
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun extern int RootlessMiValidateTree(WindowPtr pRoot, WindowPtr pChild,
60*4882a593Smuzhiyun VTKind kind);
61*4882a593Smuzhiyun extern Bool RootlessCreateGC(GCPtr pGC);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun // Initialize globals
64*4882a593Smuzhiyun DevPrivateKeyRec rootlessGCPrivateKeyRec;
65*4882a593Smuzhiyun DevPrivateKeyRec rootlessScreenPrivateKeyRec;
66*4882a593Smuzhiyun DevPrivateKeyRec rootlessWindowPrivateKeyRec;
67*4882a593Smuzhiyun DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec;
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun * RootlessUpdateScreenPixmap
71*4882a593Smuzhiyun * miCreateScreenResources does not like a null framebuffer pointer,
72*4882a593Smuzhiyun * it leaves the screen pixmap with an uninitialized data pointer.
73*4882a593Smuzhiyun * Thus, rootless implementations typically set the framebuffer width
74*4882a593Smuzhiyun * to zero so that miCreateScreenResources does not allocate a screen
75*4882a593Smuzhiyun * pixmap for us. We allocate our own screen pixmap here since we need
76*4882a593Smuzhiyun * the screen pixmap to be valid (e.g. CopyArea from the root window).
77*4882a593Smuzhiyun */
78*4882a593Smuzhiyun void
RootlessUpdateScreenPixmap(ScreenPtr pScreen)79*4882a593Smuzhiyun RootlessUpdateScreenPixmap(ScreenPtr pScreen)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
82*4882a593Smuzhiyun PixmapPtr pPix;
83*4882a593Smuzhiyun unsigned int rowbytes;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun pPix = (*pScreen->GetScreenPixmap) (pScreen);
86*4882a593Smuzhiyun if (pPix == NULL) {
87*4882a593Smuzhiyun pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
88*4882a593Smuzhiyun (*pScreen->SetScreenPixmap) (pPix);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun rowbytes = PixmapBytePad(pScreen->width, pScreen->rootDepth);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun if (s->pixmap_data_size < rowbytes) {
94*4882a593Smuzhiyun free(s->pixmap_data);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun s->pixmap_data_size = rowbytes;
97*4882a593Smuzhiyun s->pixmap_data = malloc(s->pixmap_data_size);
98*4882a593Smuzhiyun if (s->pixmap_data == NULL)
99*4882a593Smuzhiyun return;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun memset(s->pixmap_data, 0xFF, s->pixmap_data_size);
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun pScreen->ModifyPixmapHeader(pPix, pScreen->width, pScreen->height,
104*4882a593Smuzhiyun pScreen->rootDepth,
105*4882a593Smuzhiyun BitsPerPixel(pScreen->rootDepth),
106*4882a593Smuzhiyun 0, s->pixmap_data);
107*4882a593Smuzhiyun /* ModifyPixmapHeader ignores zero arguments, so install rowbytes
108*4882a593Smuzhiyun by hand. */
109*4882a593Smuzhiyun pPix->devKind = 0;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun * RootlessCreateScreenResources
115*4882a593Smuzhiyun * Rootless implementations typically set a null framebuffer pointer, which
116*4882a593Smuzhiyun * causes problems with miCreateScreenResources. We fix things up here.
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun static Bool
RootlessCreateScreenResources(ScreenPtr pScreen)119*4882a593Smuzhiyun RootlessCreateScreenResources(ScreenPtr pScreen)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun Bool ret = TRUE;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, CreateScreenResources);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun if (pScreen->CreateScreenResources != NULL)
126*4882a593Smuzhiyun ret = (*pScreen->CreateScreenResources) (pScreen);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun SCREEN_WRAP(pScreen, CreateScreenResources);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun if (!ret)
131*4882a593Smuzhiyun return ret;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /* Make sure we have a valid screen pixmap. */
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun RootlessUpdateScreenPixmap(pScreen);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun return ret;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun static Bool
RootlessCloseScreen(ScreenPtr pScreen)141*4882a593Smuzhiyun RootlessCloseScreen(ScreenPtr pScreen)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun RootlessScreenRec *s;
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun s = SCREENREC(pScreen);
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun // fixme unwrap everything that was wrapped?
148*4882a593Smuzhiyun pScreen->CloseScreen = s->CloseScreen;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (s->pixmap_data != NULL) {
151*4882a593Smuzhiyun free(s->pixmap_data);
152*4882a593Smuzhiyun s->pixmap_data = NULL;
153*4882a593Smuzhiyun s->pixmap_data_size = 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun free(s);
157*4882a593Smuzhiyun return pScreen->CloseScreen(pScreen);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun static void
RootlessGetImage(DrawablePtr pDrawable,int sx,int sy,int w,int h,unsigned int format,unsigned long planeMask,char * pdstLine)161*4882a593Smuzhiyun RootlessGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
162*4882a593Smuzhiyun unsigned int format, unsigned long planeMask, char *pdstLine)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun ScreenPtr pScreen = pDrawable->pScreen;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, GetImage);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if (pDrawable->type == DRAWABLE_WINDOW) {
169*4882a593Smuzhiyun int x0, y0, x1, y1;
170*4882a593Smuzhiyun RootlessWindowRec *winRec;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun // Many apps use GetImage to sync with the visible frame buffer
173*4882a593Smuzhiyun // FIXME: entire screen or just window or all screens?
174*4882a593Smuzhiyun RootlessRedisplayScreen(pScreen);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun // RedisplayScreen stops drawing, so we need to start it again
177*4882a593Smuzhiyun RootlessStartDrawing((WindowPtr) pDrawable);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* Check that we have some place to read from. */
180*4882a593Smuzhiyun winRec = WINREC(TopLevelParent((WindowPtr) pDrawable));
181*4882a593Smuzhiyun if (winRec == NULL)
182*4882a593Smuzhiyun goto out;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* Clip to top-level window bounds. */
185*4882a593Smuzhiyun /* FIXME: fbGetImage uses the width parameter to calculate the
186*4882a593Smuzhiyun stride of the destination pixmap. If w is clipped, the data
187*4882a593Smuzhiyun returned will be garbage, although we will not crash. */
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun x0 = pDrawable->x + sx;
190*4882a593Smuzhiyun y0 = pDrawable->y + sy;
191*4882a593Smuzhiyun x1 = x0 + w;
192*4882a593Smuzhiyun y1 = y0 + h;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun x0 = max(x0, winRec->x);
195*4882a593Smuzhiyun y0 = max(y0, winRec->y);
196*4882a593Smuzhiyun x1 = min(x1, winRec->x + winRec->width);
197*4882a593Smuzhiyun y1 = min(y1, winRec->y + winRec->height);
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun sx = x0 - pDrawable->x;
200*4882a593Smuzhiyun sy = y0 - pDrawable->y;
201*4882a593Smuzhiyun w = x1 - x0;
202*4882a593Smuzhiyun h = y1 - y0;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun if (w <= 0 || h <= 0)
205*4882a593Smuzhiyun goto out;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun out:
211*4882a593Smuzhiyun SCREEN_WRAP(pScreen, GetImage);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun /*
215*4882a593Smuzhiyun * RootlessSourceValidate
216*4882a593Smuzhiyun * CopyArea and CopyPlane use a GC tied to the destination drawable.
217*4882a593Smuzhiyun * StartDrawing/StopDrawing wrappers won't be called if source is
218*4882a593Smuzhiyun * a visible window but the destination isn't. So, we call StartDrawing
219*4882a593Smuzhiyun * here and leave StopDrawing for the block handler.
220*4882a593Smuzhiyun */
221*4882a593Smuzhiyun static void
RootlessSourceValidate(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int subWindowMode)222*4882a593Smuzhiyun RootlessSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
223*4882a593Smuzhiyun unsigned int subWindowMode)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun SCREEN_UNWRAP(pDrawable->pScreen, SourceValidate);
226*4882a593Smuzhiyun if (pDrawable->type == DRAWABLE_WINDOW) {
227*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDrawable;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun RootlessStartDrawing(pWin);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun if (pDrawable->pScreen->SourceValidate) {
232*4882a593Smuzhiyun pDrawable->pScreen->SourceValidate(pDrawable, x, y, w, h,
233*4882a593Smuzhiyun subWindowMode);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun SCREEN_WRAP(pDrawable->pScreen, SourceValidate);
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun 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)239*4882a593Smuzhiyun RootlessComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
240*4882a593Smuzhiyun INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
241*4882a593Smuzhiyun INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun ScreenPtr pScreen = pDst->pDrawable->pScreen;
244*4882a593Smuzhiyun PictureScreenPtr ps = GetPictureScreen(pScreen);
245*4882a593Smuzhiyun WindowPtr srcWin, dstWin, maskWin = NULL;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (pMask) { // pMask can be NULL
248*4882a593Smuzhiyun maskWin = (pMask->pDrawable &&
249*4882a593Smuzhiyun pMask->pDrawable->type ==
250*4882a593Smuzhiyun DRAWABLE_WINDOW) ? (WindowPtr) pMask->pDrawable : NULL;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
253*4882a593Smuzhiyun (WindowPtr) pSrc->pDrawable : NULL;
254*4882a593Smuzhiyun dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
255*4882a593Smuzhiyun (WindowPtr) pDst->pDrawable : NULL;
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun // SCREEN_UNWRAP(ps, Composite);
258*4882a593Smuzhiyun ps->Composite = SCREENREC(pScreen)->Composite;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun if (srcWin && IsFramedWindow(srcWin))
261*4882a593Smuzhiyun RootlessStartDrawing(srcWin);
262*4882a593Smuzhiyun if (maskWin && IsFramedWindow(maskWin))
263*4882a593Smuzhiyun RootlessStartDrawing(maskWin);
264*4882a593Smuzhiyun if (dstWin && IsFramedWindow(dstWin))
265*4882a593Smuzhiyun RootlessStartDrawing(dstWin);
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun ps->Composite(op, pSrc, pMask, pDst,
268*4882a593Smuzhiyun xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun if (dstWin && IsFramedWindow(dstWin)) {
271*4882a593Smuzhiyun RootlessDamageRect(dstWin, xDst, yDst, width, height);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun ps->Composite = RootlessComposite;
275*4882a593Smuzhiyun // SCREEN_WRAP(ps, Composite);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun static void
RootlessGlyphs(CARD8 op,PicturePtr pSrc,PicturePtr pDst,PictFormatPtr maskFormat,INT16 xSrc,INT16 ySrc,int nlist,GlyphListPtr list,GlyphPtr * glyphs)279*4882a593Smuzhiyun RootlessGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
280*4882a593Smuzhiyun PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
281*4882a593Smuzhiyun int nlist, GlyphListPtr list, GlyphPtr * glyphs)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun ScreenPtr pScreen = pDst->pDrawable->pScreen;
284*4882a593Smuzhiyun PictureScreenPtr ps = GetPictureScreen(pScreen);
285*4882a593Smuzhiyun int x, y;
286*4882a593Smuzhiyun int n;
287*4882a593Smuzhiyun GlyphPtr glyph;
288*4882a593Smuzhiyun WindowPtr srcWin, dstWin;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun srcWin = (pSrc->pDrawable && pSrc->pDrawable->type == DRAWABLE_WINDOW) ?
291*4882a593Smuzhiyun (WindowPtr) pSrc->pDrawable : NULL;
292*4882a593Smuzhiyun dstWin = (pDst->pDrawable->type == DRAWABLE_WINDOW) ?
293*4882a593Smuzhiyun (WindowPtr) pDst->pDrawable : NULL;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun if (srcWin && IsFramedWindow(srcWin))
296*4882a593Smuzhiyun RootlessStartDrawing(srcWin);
297*4882a593Smuzhiyun if (dstWin && IsFramedWindow(dstWin))
298*4882a593Smuzhiyun RootlessStartDrawing(dstWin);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun //SCREEN_UNWRAP(ps, Glyphs);
301*4882a593Smuzhiyun ps->Glyphs = SCREENREC(pScreen)->Glyphs;
302*4882a593Smuzhiyun ps->Glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
303*4882a593Smuzhiyun ps->Glyphs = RootlessGlyphs;
304*4882a593Smuzhiyun //SCREEN_WRAP(ps, Glyphs);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun if (dstWin && IsFramedWindow(dstWin)) {
307*4882a593Smuzhiyun x = xSrc;
308*4882a593Smuzhiyun y = ySrc;
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun while (nlist--) {
311*4882a593Smuzhiyun x += list->xOff;
312*4882a593Smuzhiyun y += list->yOff;
313*4882a593Smuzhiyun n = list->len;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /* Calling DamageRect for the bounding box of each glyph is
316*4882a593Smuzhiyun inefficient. So compute the union of all glyphs in a list
317*4882a593Smuzhiyun and damage that. */
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun if (n > 0) {
320*4882a593Smuzhiyun BoxRec box;
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun glyph = *glyphs++;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun box.x1 = x - glyph->info.x;
325*4882a593Smuzhiyun box.y1 = y - glyph->info.y;
326*4882a593Smuzhiyun box.x2 = box.x1 + glyph->info.width;
327*4882a593Smuzhiyun box.y2 = box.y1 + glyph->info.height;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun x += glyph->info.xOff;
330*4882a593Smuzhiyun y += glyph->info.yOff;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun while (--n > 0) {
333*4882a593Smuzhiyun short x1, y1, x2, y2;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun glyph = *glyphs++;
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun x1 = x - glyph->info.x;
338*4882a593Smuzhiyun y1 = y - glyph->info.y;
339*4882a593Smuzhiyun x2 = x1 + glyph->info.width;
340*4882a593Smuzhiyun y2 = y1 + glyph->info.height;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun box.x1 = max(box.x1, x1);
343*4882a593Smuzhiyun box.y1 = max(box.y1, y1);
344*4882a593Smuzhiyun box.x2 = max(box.x2, x2);
345*4882a593Smuzhiyun box.y2 = max(box.y2, y2);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun x += glyph->info.xOff;
348*4882a593Smuzhiyun y += glyph->info.yOff;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun RootlessDamageBox(dstWin, &box);
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun list++;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun /*
359*4882a593Smuzhiyun * RootlessValidateTree
360*4882a593Smuzhiyun * ValidateTree is modified in two ways:
361*4882a593Smuzhiyun * - top-level windows don't clip each other
362*4882a593Smuzhiyun * - windows aren't clipped against root.
363*4882a593Smuzhiyun * These only matter when validating from the root.
364*4882a593Smuzhiyun */
365*4882a593Smuzhiyun static int
RootlessValidateTree(WindowPtr pParent,WindowPtr pChild,VTKind kind)366*4882a593Smuzhiyun RootlessValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun int result;
369*4882a593Smuzhiyun RegionRec saveRoot;
370*4882a593Smuzhiyun ScreenPtr pScreen = pParent->drawable.pScreen;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, ValidateTree);
373*4882a593Smuzhiyun RL_DEBUG_MSG("VALIDATETREE start ");
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun // Use our custom version to validate from root
376*4882a593Smuzhiyun if (IsRoot(pParent)) {
377*4882a593Smuzhiyun RL_DEBUG_MSG("custom ");
378*4882a593Smuzhiyun result = RootlessMiValidateTree(pParent, pChild, kind);
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun else {
381*4882a593Smuzhiyun HUGE_ROOT(pParent);
382*4882a593Smuzhiyun result = pScreen->ValidateTree(pParent, pChild, kind);
383*4882a593Smuzhiyun NORMAL_ROOT(pParent);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun SCREEN_WRAP(pScreen, ValidateTree);
387*4882a593Smuzhiyun RL_DEBUG_MSG("VALIDATETREE end\n");
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun return result;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /*
393*4882a593Smuzhiyun * RootlessMarkOverlappedWindows
394*4882a593Smuzhiyun * MarkOverlappedWindows is modified to ignore overlapping
395*4882a593Smuzhiyun * top-level windows.
396*4882a593Smuzhiyun */
397*4882a593Smuzhiyun static Bool
RootlessMarkOverlappedWindows(WindowPtr pWin,WindowPtr pFirst,WindowPtr * ppLayerWin)398*4882a593Smuzhiyun RootlessMarkOverlappedWindows(WindowPtr pWin, WindowPtr pFirst,
399*4882a593Smuzhiyun WindowPtr *ppLayerWin)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun RegionRec saveRoot;
402*4882a593Smuzhiyun Bool result;
403*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, MarkOverlappedWindows);
406*4882a593Smuzhiyun RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS start ");
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun HUGE_ROOT(pWin);
409*4882a593Smuzhiyun if (IsRoot(pWin)) {
410*4882a593Smuzhiyun // root - mark nothing
411*4882a593Smuzhiyun RL_DEBUG_MSG("is root not marking ");
412*4882a593Smuzhiyun result = FALSE;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun else if (!IsTopLevel(pWin)) {
415*4882a593Smuzhiyun // not top-level window - mark normally
416*4882a593Smuzhiyun result = pScreen->MarkOverlappedWindows(pWin, pFirst, ppLayerWin);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun else {
419*4882a593Smuzhiyun //top-level window - mark children ONLY - NO overlaps with sibs (?)
420*4882a593Smuzhiyun // This code copied from miMarkOverlappedWindows()
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun register WindowPtr pChild;
423*4882a593Smuzhiyun Bool anyMarked = FALSE;
424*4882a593Smuzhiyun MarkWindowProcPtr MarkWindow = pScreen->MarkWindow;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun RL_DEBUG_MSG("is top level! ");
427*4882a593Smuzhiyun /* single layered systems are easy */
428*4882a593Smuzhiyun if (ppLayerWin)
429*4882a593Smuzhiyun *ppLayerWin = pWin;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (pWin == pFirst) {
432*4882a593Smuzhiyun /* Blindly mark pWin and all of its inferiors. This is a slight
433*4882a593Smuzhiyun * overkill if there are mapped windows that outside pWin's border,
434*4882a593Smuzhiyun * but it's better than wasting time on RectIn checks.
435*4882a593Smuzhiyun */
436*4882a593Smuzhiyun pChild = pWin;
437*4882a593Smuzhiyun while (1) {
438*4882a593Smuzhiyun if (pChild->viewable) {
439*4882a593Smuzhiyun if (RegionBroken(&pChild->winSize))
440*4882a593Smuzhiyun SetWinSize(pChild);
441*4882a593Smuzhiyun if (RegionBroken(&pChild->borderSize))
442*4882a593Smuzhiyun SetBorderSize(pChild);
443*4882a593Smuzhiyun (*MarkWindow) (pChild);
444*4882a593Smuzhiyun if (pChild->firstChild) {
445*4882a593Smuzhiyun pChild = pChild->firstChild;
446*4882a593Smuzhiyun continue;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun while (!pChild->nextSib && (pChild != pWin))
450*4882a593Smuzhiyun pChild = pChild->parent;
451*4882a593Smuzhiyun if (pChild == pWin)
452*4882a593Smuzhiyun break;
453*4882a593Smuzhiyun pChild = pChild->nextSib;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun anyMarked = TRUE;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun if (anyMarked)
458*4882a593Smuzhiyun (*MarkWindow) (pWin->parent);
459*4882a593Smuzhiyun result = anyMarked;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun NORMAL_ROOT(pWin);
462*4882a593Smuzhiyun SCREEN_WRAP(pScreen, MarkOverlappedWindows);
463*4882a593Smuzhiyun RL_DEBUG_MSG("MARKOVERLAPPEDWINDOWS end\n");
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun return result;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun static void
expose_1(WindowPtr pWin)469*4882a593Smuzhiyun expose_1(WindowPtr pWin)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun WindowPtr pChild;
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun if (!pWin->realized)
474*4882a593Smuzhiyun return;
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun pWin->drawable.pScreen->PaintWindow(pWin, &pWin->borderClip, PW_BACKGROUND);
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun /* FIXME: comments in windowstr.h indicate that borderClip doesn't
479*4882a593Smuzhiyun include subwindow visibility. But I'm not so sure.. so we may
480*4882a593Smuzhiyun be exposing too much.. */
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun miSendExposures(pWin, &pWin->borderClip,
483*4882a593Smuzhiyun pWin->drawable.x, pWin->drawable.y);
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun for (pChild = pWin->firstChild; pChild != NULL; pChild = pChild->nextSib)
486*4882a593Smuzhiyun expose_1(pChild);
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun void
RootlessScreenExpose(ScreenPtr pScreen)490*4882a593Smuzhiyun RootlessScreenExpose(ScreenPtr pScreen)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun expose_1(pScreen->root);
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun ColormapPtr
RootlessGetColormap(ScreenPtr pScreen)496*4882a593Smuzhiyun RootlessGetColormap(ScreenPtr pScreen)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun return s->colormap;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun static void
RootlessInstallColormap(ColormapPtr pMap)504*4882a593Smuzhiyun RootlessInstallColormap(ColormapPtr pMap)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun ScreenPtr pScreen = pMap->pScreen;
507*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, InstallColormap);
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (s->colormap != pMap) {
512*4882a593Smuzhiyun s->colormap = pMap;
513*4882a593Smuzhiyun s->colormap_changed = TRUE;
514*4882a593Smuzhiyun RootlessQueueRedisplay(pScreen);
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun pScreen->InstallColormap(pMap);
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun SCREEN_WRAP(pScreen, InstallColormap);
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun static void
RootlessUninstallColormap(ColormapPtr pMap)523*4882a593Smuzhiyun RootlessUninstallColormap(ColormapPtr pMap)
524*4882a593Smuzhiyun {
525*4882a593Smuzhiyun ScreenPtr pScreen = pMap->pScreen;
526*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, UninstallColormap);
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun if (s->colormap == pMap)
531*4882a593Smuzhiyun s->colormap = NULL;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun pScreen->UninstallColormap(pMap);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun SCREEN_WRAP(pScreen, UninstallColormap);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun static void
RootlessStoreColors(ColormapPtr pMap,int ndef,xColorItem * pdef)539*4882a593Smuzhiyun RootlessStoreColors(ColormapPtr pMap, int ndef, xColorItem * pdef)
540*4882a593Smuzhiyun {
541*4882a593Smuzhiyun ScreenPtr pScreen = pMap->pScreen;
542*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun SCREEN_UNWRAP(pScreen, StoreColors);
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun if (s->colormap == pMap && ndef > 0) {
547*4882a593Smuzhiyun s->colormap_changed = TRUE;
548*4882a593Smuzhiyun RootlessQueueRedisplay(pScreen);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun pScreen->StoreColors(pMap, ndef, pdef);
552*4882a593Smuzhiyun
553*4882a593Smuzhiyun SCREEN_WRAP(pScreen, StoreColors);
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun static CARD32
RootlessRedisplayCallback(OsTimerPtr timer,CARD32 time,void * arg)557*4882a593Smuzhiyun RootlessRedisplayCallback(OsTimerPtr timer, CARD32 time, void *arg)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun RootlessScreenRec *screenRec = arg;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun if (!screenRec->redisplay_queued) {
562*4882a593Smuzhiyun /* No update needed. Stop the timer. */
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun screenRec->redisplay_timer_set = FALSE;
565*4882a593Smuzhiyun return 0;
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun screenRec->redisplay_queued = FALSE;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun /* Mark that we should redisplay before waiting for I/O next time */
571*4882a593Smuzhiyun screenRec->redisplay_expired = TRUE;
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun /* Reinstall the timer immediately, so we get as close to our
574*4882a593Smuzhiyun redisplay interval as possible. */
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun return ROOTLESS_REDISPLAY_DELAY;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun /*
580*4882a593Smuzhiyun * RootlessQueueRedisplay
581*4882a593Smuzhiyun * Queue a redisplay after a timer delay to ensure we do not redisplay
582*4882a593Smuzhiyun * too frequently.
583*4882a593Smuzhiyun */
584*4882a593Smuzhiyun void
RootlessQueueRedisplay(ScreenPtr pScreen)585*4882a593Smuzhiyun RootlessQueueRedisplay(ScreenPtr pScreen)
586*4882a593Smuzhiyun {
587*4882a593Smuzhiyun RootlessScreenRec *screenRec = SCREENREC(pScreen);
588*4882a593Smuzhiyun
589*4882a593Smuzhiyun screenRec->redisplay_queued = TRUE;
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun if (screenRec->redisplay_timer_set)
592*4882a593Smuzhiyun return;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun screenRec->redisplay_timer = TimerSet(screenRec->redisplay_timer,
595*4882a593Smuzhiyun 0, ROOTLESS_REDISPLAY_DELAY,
596*4882a593Smuzhiyun RootlessRedisplayCallback, screenRec);
597*4882a593Smuzhiyun screenRec->redisplay_timer_set = TRUE;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun /*
601*4882a593Smuzhiyun * RootlessBlockHandler
602*4882a593Smuzhiyun * If the redisplay timer has expired, flush drawing before blocking
603*4882a593Smuzhiyun * on select().
604*4882a593Smuzhiyun */
605*4882a593Smuzhiyun static void
RootlessBlockHandler(void * pbdata,void * ptimeout)606*4882a593Smuzhiyun RootlessBlockHandler(void *pbdata, void *ptimeout)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun ScreenPtr pScreen = pbdata;
609*4882a593Smuzhiyun RootlessScreenRec *screenRec = SCREENREC(pScreen);
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun if (screenRec->redisplay_expired) {
612*4882a593Smuzhiyun screenRec->redisplay_expired = FALSE;
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun RootlessRedisplayScreen(pScreen);
615*4882a593Smuzhiyun }
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun static void
RootlessWakeupHandler(void * data,int result)619*4882a593Smuzhiyun RootlessWakeupHandler(void *data, int result)
620*4882a593Smuzhiyun {
621*4882a593Smuzhiyun // nothing here
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun static Bool
RootlessAllocatePrivates(ScreenPtr pScreen)625*4882a593Smuzhiyun RootlessAllocatePrivates(ScreenPtr pScreen)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun RootlessScreenRec *s;
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun if (!dixRegisterPrivateKey
630*4882a593Smuzhiyun (&rootlessGCPrivateKeyRec, PRIVATE_GC, sizeof(RootlessGCRec)))
631*4882a593Smuzhiyun return FALSE;
632*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&rootlessScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
633*4882a593Smuzhiyun return FALSE;
634*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&rootlessWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
635*4882a593Smuzhiyun return FALSE;
636*4882a593Smuzhiyun if (!dixRegisterPrivateKey
637*4882a593Smuzhiyun (&rootlessWindowOldPixmapPrivateKeyRec, PRIVATE_WINDOW, 0))
638*4882a593Smuzhiyun return FALSE;
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun s = malloc(sizeof(RootlessScreenRec));
641*4882a593Smuzhiyun if (!s)
642*4882a593Smuzhiyun return FALSE;
643*4882a593Smuzhiyun SETSCREENREC(pScreen, s);
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun s->pixmap_data = NULL;
646*4882a593Smuzhiyun s->pixmap_data_size = 0;
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun s->redisplay_timer = NULL;
649*4882a593Smuzhiyun s->redisplay_timer_set = FALSE;
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun return TRUE;
652*4882a593Smuzhiyun }
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun static void
RootlessWrap(ScreenPtr pScreen)655*4882a593Smuzhiyun RootlessWrap(ScreenPtr pScreen)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun RootlessScreenRec *s = SCREENREC(pScreen);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun #define WRAP(a) \
660*4882a593Smuzhiyun if (pScreen->a) { \
661*4882a593Smuzhiyun s->a = pScreen->a; \
662*4882a593Smuzhiyun } else { \
663*4882a593Smuzhiyun RL_DEBUG_MSG("null screen fn " #a "\n"); \
664*4882a593Smuzhiyun s->a = NULL; \
665*4882a593Smuzhiyun } \
666*4882a593Smuzhiyun pScreen->a = Rootless##a
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun WRAP(CreateScreenResources);
669*4882a593Smuzhiyun WRAP(CloseScreen);
670*4882a593Smuzhiyun WRAP(CreateGC);
671*4882a593Smuzhiyun WRAP(CopyWindow);
672*4882a593Smuzhiyun WRAP(PaintWindow);
673*4882a593Smuzhiyun WRAP(GetImage);
674*4882a593Smuzhiyun WRAP(SourceValidate);
675*4882a593Smuzhiyun WRAP(CreateWindow);
676*4882a593Smuzhiyun WRAP(DestroyWindow);
677*4882a593Smuzhiyun WRAP(RealizeWindow);
678*4882a593Smuzhiyun WRAP(UnrealizeWindow);
679*4882a593Smuzhiyun WRAP(MoveWindow);
680*4882a593Smuzhiyun WRAP(PositionWindow);
681*4882a593Smuzhiyun WRAP(ResizeWindow);
682*4882a593Smuzhiyun WRAP(RestackWindow);
683*4882a593Smuzhiyun WRAP(ReparentWindow);
684*4882a593Smuzhiyun WRAP(ChangeBorderWidth);
685*4882a593Smuzhiyun WRAP(MarkOverlappedWindows);
686*4882a593Smuzhiyun WRAP(ValidateTree);
687*4882a593Smuzhiyun WRAP(ChangeWindowAttributes);
688*4882a593Smuzhiyun WRAP(InstallColormap);
689*4882a593Smuzhiyun WRAP(UninstallColormap);
690*4882a593Smuzhiyun WRAP(StoreColors);
691*4882a593Smuzhiyun
692*4882a593Smuzhiyun WRAP(SetShape);
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun // Composite and Glyphs don't use normal screen wrapping
696*4882a593Smuzhiyun PictureScreenPtr ps = GetPictureScreen(pScreen);
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun s->Composite = ps->Composite;
699*4882a593Smuzhiyun ps->Composite = RootlessComposite;
700*4882a593Smuzhiyun s->Glyphs = ps->Glyphs;
701*4882a593Smuzhiyun ps->Glyphs = RootlessGlyphs;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun // WRAP(ClearToBackground); fixme put this back? useful for shaped wins?
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun #undef WRAP
707*4882a593Smuzhiyun }
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun /*
710*4882a593Smuzhiyun * RootlessInit
711*4882a593Smuzhiyun * Called by the rootless implementation to initialize the rootless layer.
712*4882a593Smuzhiyun * Rootless wraps lots of stuff and needs a bunch of devPrivates.
713*4882a593Smuzhiyun */
714*4882a593Smuzhiyun Bool
RootlessInit(ScreenPtr pScreen,RootlessFrameProcsPtr procs)715*4882a593Smuzhiyun RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs)
716*4882a593Smuzhiyun {
717*4882a593Smuzhiyun RootlessScreenRec *s;
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun if (!RootlessAllocatePrivates(pScreen))
720*4882a593Smuzhiyun return FALSE;
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun s = SCREENREC(pScreen);
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun s->imp = procs;
725*4882a593Smuzhiyun s->colormap = NULL;
726*4882a593Smuzhiyun s->redisplay_expired = FALSE;
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun RootlessWrap(pScreen);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun if (!RegisterBlockAndWakeupHandlers(RootlessBlockHandler,
731*4882a593Smuzhiyun RootlessWakeupHandler,
732*4882a593Smuzhiyun (void *) pScreen)) {
733*4882a593Smuzhiyun return FALSE;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun return TRUE;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun void
RootlessUpdateRooted(Bool state)740*4882a593Smuzhiyun RootlessUpdateRooted(Bool state)
741*4882a593Smuzhiyun {
742*4882a593Smuzhiyun int i;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun if (!state) {
745*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++)
746*4882a593Smuzhiyun RootlessDisableRoot(screenInfo.screens[i]);
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun else {
749*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++)
750*4882a593Smuzhiyun RootlessEnableRoot(screenInfo.screens[i]);
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun }
753