xref: /OK3568_Linux_fs/external/xserver/miext/rootless/rootlessCommon.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Common rootless definitions and code
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 <stddef.h>             /* For NULL */
37*4882a593Smuzhiyun #include <limits.h>             /* For CHAR_BIT */
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #include "rootlessCommon.h"
40*4882a593Smuzhiyun #include "colormapst.h"
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun unsigned int rootless_CopyBytes_threshold = 0;
43*4882a593Smuzhiyun unsigned int rootless_CopyWindow_threshold = 0;
44*4882a593Smuzhiyun int rootlessGlobalOffsetX = 0;
45*4882a593Smuzhiyun int rootlessGlobalOffsetY = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun RegionRec rootlessHugeRoot = { {-32767, -32767, 32767, 32767}, NULL };
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /* Following macro from miregion.c */
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun /*  true iff two Boxes overlap */
52*4882a593Smuzhiyun #define EXTENTCHECK(r1,r2) \
53*4882a593Smuzhiyun       (!( ((r1)->x2 <= (r2)->x1)  || \
54*4882a593Smuzhiyun           ((r1)->x1 >= (r2)->x2)  || \
55*4882a593Smuzhiyun           ((r1)->y2 <= (r2)->y1)  || \
56*4882a593Smuzhiyun           ((r1)->y1 >= (r2)->y2) ) )
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /*
59*4882a593Smuzhiyun  * TopLevelParent
60*4882a593Smuzhiyun  *  Returns the top-level parent of pWindow.
61*4882a593Smuzhiyun  *  The root is the top-level parent of itself, even though the root is
62*4882a593Smuzhiyun  *  not otherwise considered to be a top-level window.
63*4882a593Smuzhiyun  */
64*4882a593Smuzhiyun WindowPtr
TopLevelParent(WindowPtr pWindow)65*4882a593Smuzhiyun TopLevelParent(WindowPtr pWindow)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun     WindowPtr top;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun     if (IsRoot(pWindow))
70*4882a593Smuzhiyun         return pWindow;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun     top = pWindow;
73*4882a593Smuzhiyun     while (top && !IsTopLevel(top))
74*4882a593Smuzhiyun         top = top->parent;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun     return top;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun  * IsFramedWindow
81*4882a593Smuzhiyun  *  Returns TRUE if this window is visible inside a frame
82*4882a593Smuzhiyun  *  (e.g. it is visible and has a top-level or root parent)
83*4882a593Smuzhiyun  */
84*4882a593Smuzhiyun Bool
IsFramedWindow(WindowPtr pWin)85*4882a593Smuzhiyun IsFramedWindow(WindowPtr pWin)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun     WindowPtr top;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     if (!dixPrivateKeyRegistered(&rootlessWindowPrivateKeyRec))
90*4882a593Smuzhiyun         return FALSE;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun     if (!pWin->realized)
93*4882a593Smuzhiyun         return FALSE;
94*4882a593Smuzhiyun     top = TopLevelParent(pWin);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     return (top && WINREC(top));
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun Bool
RootlessResolveColormap(ScreenPtr pScreen,int first_color,int n_colors,uint32_t * colors)100*4882a593Smuzhiyun RootlessResolveColormap(ScreenPtr pScreen, int first_color,
101*4882a593Smuzhiyun                         int n_colors, uint32_t * colors)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun     int last, i;
104*4882a593Smuzhiyun     ColormapPtr map;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     map = RootlessGetColormap(pScreen);
107*4882a593Smuzhiyun     if (map == NULL || map->class != PseudoColor)
108*4882a593Smuzhiyun         return FALSE;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun     last = min(map->pVisual->ColormapEntries, first_color + n_colors);
111*4882a593Smuzhiyun     for (i = max(0, first_color); i < last; i++) {
112*4882a593Smuzhiyun         Entry *ent = map->red + i;
113*4882a593Smuzhiyun         uint16_t red, green, blue;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun         if (!ent->refcnt)
116*4882a593Smuzhiyun             continue;
117*4882a593Smuzhiyun         if (ent->fShared) {
118*4882a593Smuzhiyun             red = ent->co.shco.red->color;
119*4882a593Smuzhiyun             green = ent->co.shco.green->color;
120*4882a593Smuzhiyun             blue = ent->co.shco.blue->color;
121*4882a593Smuzhiyun         }
122*4882a593Smuzhiyun         else {
123*4882a593Smuzhiyun             red = ent->co.local.red;
124*4882a593Smuzhiyun             green = ent->co.local.green;
125*4882a593Smuzhiyun             blue = ent->co.local.blue;
126*4882a593Smuzhiyun         }
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun         colors[i - first_color] = (0xFF000000UL
129*4882a593Smuzhiyun                                    | ((uint32_t) red & 0xff00) << 8
130*4882a593Smuzhiyun                                    | (green & 0xff00)
131*4882a593Smuzhiyun                                    | (blue >> 8));
132*4882a593Smuzhiyun     }
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun     return TRUE;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun  * RootlessStartDrawing
139*4882a593Smuzhiyun  *  Prepare a window for direct access to its backing buffer.
140*4882a593Smuzhiyun  *  Each top-level parent has a Pixmap representing its backing buffer,
141*4882a593Smuzhiyun  *  which all of its children inherit.
142*4882a593Smuzhiyun  */
143*4882a593Smuzhiyun void
RootlessStartDrawing(WindowPtr pWindow)144*4882a593Smuzhiyun RootlessStartDrawing(WindowPtr pWindow)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun     ScreenPtr pScreen = pWindow->drawable.pScreen;
147*4882a593Smuzhiyun     WindowPtr top = TopLevelParent(pWindow);
148*4882a593Smuzhiyun     RootlessWindowRec *winRec;
149*4882a593Smuzhiyun     PixmapPtr curPixmap;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     if (top == NULL)
152*4882a593Smuzhiyun         return;
153*4882a593Smuzhiyun     winRec = WINREC(top);
154*4882a593Smuzhiyun     if (winRec == NULL)
155*4882a593Smuzhiyun         return;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun     // Make sure the window's top-level parent is prepared for drawing.
158*4882a593Smuzhiyun     if (!winRec->is_drawing) {
159*4882a593Smuzhiyun         int bw = wBorderWidth(top);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun         SCREENREC(pScreen)->imp->StartDrawing(winRec->wid, &winRec->pixelData,
162*4882a593Smuzhiyun                                               &winRec->bytesPerRow);
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun         winRec->pixmap =
165*4882a593Smuzhiyun             GetScratchPixmapHeader(pScreen, winRec->width, winRec->height,
166*4882a593Smuzhiyun                                    top->drawable.depth,
167*4882a593Smuzhiyun                                    top->drawable.bitsPerPixel,
168*4882a593Smuzhiyun                                    winRec->bytesPerRow, winRec->pixelData);
169*4882a593Smuzhiyun         SetPixmapBaseToScreen(winRec->pixmap,
170*4882a593Smuzhiyun                               top->drawable.x - bw, top->drawable.y - bw);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun         winRec->is_drawing = TRUE;
173*4882a593Smuzhiyun     }
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun     curPixmap = pScreen->GetWindowPixmap(pWindow);
176*4882a593Smuzhiyun     if (curPixmap == winRec->pixmap) {
177*4882a593Smuzhiyun         RL_DEBUG_MSG("Window %p already has winRec->pixmap %p; not pushing\n",
178*4882a593Smuzhiyun                      pWindow, winRec->pixmap);
179*4882a593Smuzhiyun     }
180*4882a593Smuzhiyun     else {
181*4882a593Smuzhiyun         PixmapPtr oldPixmap =
182*4882a593Smuzhiyun             dixLookupPrivate(&pWindow->devPrivates,
183*4882a593Smuzhiyun                              rootlessWindowOldPixmapPrivateKey);
184*4882a593Smuzhiyun         if (oldPixmap != NULL) {
185*4882a593Smuzhiyun             if (oldPixmap == curPixmap)
186*4882a593Smuzhiyun                 RL_DEBUG_MSG
187*4882a593Smuzhiyun                     ("Window %p's curPixmap %p is the same as its oldPixmap; strange\n",
188*4882a593Smuzhiyun                      pWindow, curPixmap);
189*4882a593Smuzhiyun             else
190*4882a593Smuzhiyun                 RL_DEBUG_MSG("Window %p's existing oldPixmap %p being lost!\n",
191*4882a593Smuzhiyun                              pWindow, oldPixmap);
192*4882a593Smuzhiyun         }
193*4882a593Smuzhiyun         dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey,
194*4882a593Smuzhiyun                       curPixmap);
195*4882a593Smuzhiyun         pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
196*4882a593Smuzhiyun     }
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun /*
200*4882a593Smuzhiyun  * RootlessStopDrawing
201*4882a593Smuzhiyun  *  Stop drawing to a window's backing buffer. If flush is true,
202*4882a593Smuzhiyun  *  damaged regions are flushed to the screen.
203*4882a593Smuzhiyun  */
204*4882a593Smuzhiyun static int
RestorePreDrawingPixmapVisitor(WindowPtr pWindow,void * data)205*4882a593Smuzhiyun RestorePreDrawingPixmapVisitor(WindowPtr pWindow, void *data)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun     RootlessWindowRec *winRec = (RootlessWindowRec *) data;
208*4882a593Smuzhiyun     ScreenPtr pScreen = pWindow->drawable.pScreen;
209*4882a593Smuzhiyun     PixmapPtr exPixmap = pScreen->GetWindowPixmap(pWindow);
210*4882a593Smuzhiyun     PixmapPtr oldPixmap =
211*4882a593Smuzhiyun         dixLookupPrivate(&pWindow->devPrivates,
212*4882a593Smuzhiyun                          rootlessWindowOldPixmapPrivateKey);
213*4882a593Smuzhiyun     if (oldPixmap == NULL) {
214*4882a593Smuzhiyun         if (exPixmap == winRec->pixmap)
215*4882a593Smuzhiyun             RL_DEBUG_MSG
216*4882a593Smuzhiyun                 ("Window %p appears to be in drawing mode (ex-pixmap %p equals winRec->pixmap, which is being freed) but has no oldPixmap!\n",
217*4882a593Smuzhiyun                  pWindow, exPixmap);
218*4882a593Smuzhiyun     }
219*4882a593Smuzhiyun     else {
220*4882a593Smuzhiyun         if (exPixmap != winRec->pixmap)
221*4882a593Smuzhiyun             RL_DEBUG_MSG
222*4882a593Smuzhiyun                 ("Window %p appears to be in drawing mode (oldPixmap %p) but ex-pixmap %p not winRec->pixmap %p!\n",
223*4882a593Smuzhiyun                  pWindow, oldPixmap, exPixmap, winRec->pixmap);
224*4882a593Smuzhiyun         if (oldPixmap == winRec->pixmap)
225*4882a593Smuzhiyun             RL_DEBUG_MSG
226*4882a593Smuzhiyun                 ("Window %p's oldPixmap %p is winRec->pixmap, which has just been freed!\n",
227*4882a593Smuzhiyun                  pWindow, oldPixmap);
228*4882a593Smuzhiyun         pScreen->SetWindowPixmap(pWindow, oldPixmap);
229*4882a593Smuzhiyun         dixSetPrivate(&pWindow->devPrivates, rootlessWindowOldPixmapPrivateKey,
230*4882a593Smuzhiyun                       NULL);
231*4882a593Smuzhiyun     }
232*4882a593Smuzhiyun     return WT_WALKCHILDREN;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun void
RootlessStopDrawing(WindowPtr pWindow,Bool flush)236*4882a593Smuzhiyun RootlessStopDrawing(WindowPtr pWindow, Bool flush)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun     ScreenPtr pScreen = pWindow->drawable.pScreen;
239*4882a593Smuzhiyun     WindowPtr top = TopLevelParent(pWindow);
240*4882a593Smuzhiyun     RootlessWindowRec *winRec;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun     if (top == NULL)
243*4882a593Smuzhiyun         return;
244*4882a593Smuzhiyun     winRec = WINREC(top);
245*4882a593Smuzhiyun     if (winRec == NULL)
246*4882a593Smuzhiyun         return;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun     if (winRec->is_drawing) {
249*4882a593Smuzhiyun         SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun         FreeScratchPixmapHeader(winRec->pixmap);
252*4882a593Smuzhiyun         TraverseTree(top, RestorePreDrawingPixmapVisitor, (void *) winRec);
253*4882a593Smuzhiyun         winRec->pixmap = NULL;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun         winRec->is_drawing = FALSE;
256*4882a593Smuzhiyun     }
257*4882a593Smuzhiyun     else if (flush) {
258*4882a593Smuzhiyun         SCREENREC(pScreen)->imp->UpdateRegion(winRec->wid, NULL);
259*4882a593Smuzhiyun     }
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun     if (flush && winRec->is_reorder_pending) {
262*4882a593Smuzhiyun         winRec->is_reorder_pending = FALSE;
263*4882a593Smuzhiyun         RootlessReorderWindow(pWindow);
264*4882a593Smuzhiyun     }
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /*
268*4882a593Smuzhiyun  * RootlessDamageRegion
269*4882a593Smuzhiyun  *  Mark a damaged region as requiring redisplay to screen.
270*4882a593Smuzhiyun  *  pRegion is in GLOBAL coordinates.
271*4882a593Smuzhiyun  */
272*4882a593Smuzhiyun void
RootlessDamageRegion(WindowPtr pWindow,RegionPtr pRegion)273*4882a593Smuzhiyun RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun     RootlessWindowRec *winRec;
276*4882a593Smuzhiyun     RegionRec clipped;
277*4882a593Smuzhiyun     WindowPtr pTop;
278*4882a593Smuzhiyun     BoxPtr b1, b2;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun     RL_DEBUG_MSG("Damaged win 0x%x ", pWindow);
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun     pTop = TopLevelParent(pWindow);
283*4882a593Smuzhiyun     if (pTop == NULL)
284*4882a593Smuzhiyun         return;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun     winRec = WINREC(pTop);
287*4882a593Smuzhiyun     if (winRec == NULL)
288*4882a593Smuzhiyun         return;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun     /* We need to intersect the drawn region with the clip of the window
291*4882a593Smuzhiyun        to avoid marking places we didn't actually draw (which can cause
292*4882a593Smuzhiyun        problems when the window has an extra client-side backing store)
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun        But this is a costly operation and since we'll normally just be
295*4882a593Smuzhiyun        drawing inside the clip, go to some lengths to avoid the general
296*4882a593Smuzhiyun        case intersection. */
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun     b1 = RegionExtents(&pWindow->borderClip);
299*4882a593Smuzhiyun     b2 = RegionExtents(pRegion);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun     if (EXTENTCHECK(b1, b2)) {
302*4882a593Smuzhiyun         /* Regions may overlap. */
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun         if (RegionNumRects(pRegion) == 1) {
305*4882a593Smuzhiyun             int in;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun             /* Damaged region only has a single rect, so we can
308*4882a593Smuzhiyun                just compare that against the region */
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun             in = RegionContainsRect(&pWindow->borderClip, RegionRects(pRegion));
311*4882a593Smuzhiyun             if (in == rgnIN) {
312*4882a593Smuzhiyun                 /* clip totally contains pRegion */
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun                 SCREENREC(pWindow->drawable.pScreen)->imp->DamageRects(winRec->
315*4882a593Smuzhiyun                                                                        wid,
316*4882a593Smuzhiyun                                                                        RegionNumRects
317*4882a593Smuzhiyun                                                                        (pRegion),
318*4882a593Smuzhiyun                                                                        RegionRects
319*4882a593Smuzhiyun                                                                        (pRegion),
320*4882a593Smuzhiyun                                                                        -winRec->
321*4882a593Smuzhiyun                                                                        x,
322*4882a593Smuzhiyun                                                                        -winRec->
323*4882a593Smuzhiyun                                                                        y);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun                 RootlessQueueRedisplay(pTop->drawable.pScreen);
326*4882a593Smuzhiyun                 goto out;
327*4882a593Smuzhiyun             }
328*4882a593Smuzhiyun             else if (in == rgnOUT) {
329*4882a593Smuzhiyun                 /* clip doesn't contain pRegion */
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun                 goto out;
332*4882a593Smuzhiyun             }
333*4882a593Smuzhiyun         }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun         /* clip overlaps pRegion, need to intersect */
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun         RegionNull(&clipped);
338*4882a593Smuzhiyun         RegionIntersect(&clipped, &pWindow->borderClip, pRegion);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun         SCREENREC(pWindow->drawable.pScreen)->imp->DamageRects(winRec->wid,
341*4882a593Smuzhiyun                                                                RegionNumRects
342*4882a593Smuzhiyun                                                                (&clipped),
343*4882a593Smuzhiyun                                                                RegionRects
344*4882a593Smuzhiyun                                                                (&clipped),
345*4882a593Smuzhiyun                                                                -winRec->x,
346*4882a593Smuzhiyun                                                                -winRec->y);
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun         RegionUninit(&clipped);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun         RootlessQueueRedisplay(pTop->drawable.pScreen);
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun  out:
354*4882a593Smuzhiyun #ifdef ROOTLESSDEBUG
355*4882a593Smuzhiyun     {
356*4882a593Smuzhiyun         BoxRec *box = RegionRects(pRegion), *end;
357*4882a593Smuzhiyun         int numBox = RegionNumRects(pRegion);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun         for (end = box + numBox; box < end; box++) {
360*4882a593Smuzhiyun             RL_DEBUG_MSG("Damage rect: %i, %i, %i, %i\n",
361*4882a593Smuzhiyun                          box->x1, box->x2, box->y1, box->y2);
362*4882a593Smuzhiyun         }
363*4882a593Smuzhiyun     }
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun     return;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /*
369*4882a593Smuzhiyun  * RootlessDamageBox
370*4882a593Smuzhiyun  *  Mark a damaged box as requiring redisplay to screen.
371*4882a593Smuzhiyun  *  pRegion is in GLOBAL coordinates.
372*4882a593Smuzhiyun  */
373*4882a593Smuzhiyun void
RootlessDamageBox(WindowPtr pWindow,BoxPtr pBox)374*4882a593Smuzhiyun RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun     RegionRec region;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun     RegionInit(&region, pBox, 1);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun     RootlessDamageRegion(pWindow, &region);
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun     RegionUninit(&region);      /* no-op */
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun /*
386*4882a593Smuzhiyun  * RootlessDamageRect
387*4882a593Smuzhiyun  *  Mark a damaged rectangle as requiring redisplay to screen.
388*4882a593Smuzhiyun  *  (x, y, w, h) is in window-local coordinates.
389*4882a593Smuzhiyun  */
390*4882a593Smuzhiyun void
RootlessDamageRect(WindowPtr pWindow,int x,int y,int w,int h)391*4882a593Smuzhiyun RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun     BoxRec box;
394*4882a593Smuzhiyun     RegionRec region;
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun     x += pWindow->drawable.x;
397*4882a593Smuzhiyun     y += pWindow->drawable.y;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun     box.x1 = x;
400*4882a593Smuzhiyun     box.x2 = x + w;
401*4882a593Smuzhiyun     box.y1 = y;
402*4882a593Smuzhiyun     box.y2 = y + h;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun     RegionInit(&region, &box, 1);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun     RootlessDamageRegion(pWindow, &region);
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun     RegionUninit(&region);      /* no-op */
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun /*
412*4882a593Smuzhiyun  * RootlessRedisplay
413*4882a593Smuzhiyun  *  Stop drawing and redisplay the damaged region of a window.
414*4882a593Smuzhiyun  */
415*4882a593Smuzhiyun void
RootlessRedisplay(WindowPtr pWindow)416*4882a593Smuzhiyun RootlessRedisplay(WindowPtr pWindow)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun     RootlessStopDrawing(pWindow, TRUE);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun /*
422*4882a593Smuzhiyun  * RootlessRepositionWindows
423*4882a593Smuzhiyun  *  Reposition all windows on a screen to their correct positions.
424*4882a593Smuzhiyun  */
425*4882a593Smuzhiyun void
RootlessRepositionWindows(ScreenPtr pScreen)426*4882a593Smuzhiyun RootlessRepositionWindows(ScreenPtr pScreen)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun     WindowPtr root = pScreen->root;
429*4882a593Smuzhiyun     WindowPtr win;
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun     if (root != NULL) {
432*4882a593Smuzhiyun         RootlessRepositionWindow(root);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun         for (win = root->firstChild; win; win = win->nextSib) {
435*4882a593Smuzhiyun             if (WINREC(win) != NULL)
436*4882a593Smuzhiyun                 RootlessRepositionWindow(win);
437*4882a593Smuzhiyun         }
438*4882a593Smuzhiyun     }
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun /*
442*4882a593Smuzhiyun  * RootlessRedisplayScreen
443*4882a593Smuzhiyun  *  Walk every window on a screen and redisplay the damaged regions.
444*4882a593Smuzhiyun  */
445*4882a593Smuzhiyun void
RootlessRedisplayScreen(ScreenPtr pScreen)446*4882a593Smuzhiyun RootlessRedisplayScreen(ScreenPtr pScreen)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun     WindowPtr root = pScreen->root;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun     if (root != NULL) {
451*4882a593Smuzhiyun         WindowPtr win;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun         RootlessRedisplay(root);
454*4882a593Smuzhiyun         for (win = root->firstChild; win; win = win->nextSib) {
455*4882a593Smuzhiyun             if (WINREC(win) != NULL) {
456*4882a593Smuzhiyun                 RootlessRedisplay(win);
457*4882a593Smuzhiyun             }
458*4882a593Smuzhiyun         }
459*4882a593Smuzhiyun     }
460*4882a593Smuzhiyun }
461