xref: /OK3568_Linux_fs/external/xserver/miext/rootless/rootlessScreen.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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