xref: /OK3568_Linux_fs/external/xserver/composite/compwindow.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun  * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun  * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun  * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the next
12*4882a593Smuzhiyun  * paragraph) shall be included in all copies or substantial portions of the
13*4882a593Smuzhiyun  * Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*4882a593Smuzhiyun  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*4882a593Smuzhiyun  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*4882a593Smuzhiyun  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*4882a593Smuzhiyun  * DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * Copyright © 2003 Keith Packard
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
26*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
27*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that
28*4882a593Smuzhiyun  * copyright notice and this permission notice appear in supporting
29*4882a593Smuzhiyun  * documentation, and that the name of Keith Packard not be used in
30*4882a593Smuzhiyun  * advertising or publicity pertaining to distribution of the software without
31*4882a593Smuzhiyun  * specific, written prior permission.  Keith Packard makes no
32*4882a593Smuzhiyun  * representations about the suitability of this software for any purpose.  It
33*4882a593Smuzhiyun  * is provided "as is" without express or implied warranty.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
36*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
37*4882a593Smuzhiyun  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
39*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
40*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
41*4882a593Smuzhiyun  * PERFORMANCE OF THIS SOFTWARE.
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
45*4882a593Smuzhiyun #include <dix-config.h>
46*4882a593Smuzhiyun #endif
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #include "compint.h"
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #ifdef PANORAMIX
51*4882a593Smuzhiyun #include "panoramiXsrv.h"
52*4882a593Smuzhiyun #endif
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #ifdef COMPOSITE_DEBUG
55*4882a593Smuzhiyun static int
compCheckWindow(WindowPtr pWin,void * data)56*4882a593Smuzhiyun compCheckWindow(WindowPtr pWin, void *data)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
59*4882a593Smuzhiyun     PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
60*4882a593Smuzhiyun     PixmapPtr pParentPixmap =
61*4882a593Smuzhiyun         pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
62*4882a593Smuzhiyun     PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun     if (!pWin->parent) {
65*4882a593Smuzhiyun         assert(pWin->redirectDraw == RedirectDrawNone);
66*4882a593Smuzhiyun         assert(pWinPixmap == pScreenPixmap);
67*4882a593Smuzhiyun     }
68*4882a593Smuzhiyun     else if (pWin->redirectDraw != RedirectDrawNone) {
69*4882a593Smuzhiyun         assert(pWinPixmap != pParentPixmap);
70*4882a593Smuzhiyun         assert(pWinPixmap != pScreenPixmap);
71*4882a593Smuzhiyun     }
72*4882a593Smuzhiyun     else {
73*4882a593Smuzhiyun         assert(pWinPixmap == pParentPixmap);
74*4882a593Smuzhiyun     }
75*4882a593Smuzhiyun     assert(0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
76*4882a593Smuzhiyun     assert(0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
77*4882a593Smuzhiyun     if (pParentPixmap)
78*4882a593Smuzhiyun         assert(0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
79*4882a593Smuzhiyun     return WT_WALKCHILDREN;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun void
compCheckTree(ScreenPtr pScreen)83*4882a593Smuzhiyun compCheckTree(ScreenPtr pScreen)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun     WalkTree(pScreen, compCheckWindow, 0);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun #endif
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun typedef struct _compPixmapVisit {
90*4882a593Smuzhiyun     WindowPtr pWindow;
91*4882a593Smuzhiyun     PixmapPtr pPixmap;
92*4882a593Smuzhiyun     int bw;
93*4882a593Smuzhiyun } CompPixmapVisitRec, *CompPixmapVisitPtr;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun static Bool
compRepaintBorder(ClientPtr pClient,void * closure)96*4882a593Smuzhiyun compRepaintBorder(ClientPtr pClient, void *closure)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun     WindowPtr pWindow;
99*4882a593Smuzhiyun     int rc =
100*4882a593Smuzhiyun         dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient,
101*4882a593Smuzhiyun                         DixWriteAccess);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun     if (rc == Success) {
104*4882a593Smuzhiyun         RegionRec exposed;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun         RegionNull(&exposed);
107*4882a593Smuzhiyun         RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
108*4882a593Smuzhiyun         pWindow->drawable.pScreen->PaintWindow(pWindow, &exposed, PW_BORDER);
109*4882a593Smuzhiyun         RegionUninit(&exposed);
110*4882a593Smuzhiyun     }
111*4882a593Smuzhiyun     return TRUE;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun static int
compSetPixmapVisitWindow(WindowPtr pWindow,void * data)115*4882a593Smuzhiyun compSetPixmapVisitWindow(WindowPtr pWindow, void *data)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun     CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
118*4882a593Smuzhiyun     ScreenPtr pScreen = pWindow->drawable.pScreen;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
121*4882a593Smuzhiyun         return WT_DONTWALKCHILDREN;
122*4882a593Smuzhiyun     (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
123*4882a593Smuzhiyun     /*
124*4882a593Smuzhiyun      * Recompute winSize and borderSize.  This is duplicate effort
125*4882a593Smuzhiyun      * when resizing pixmaps, but necessary when changing redirection.
126*4882a593Smuzhiyun      * Might be nice to fix this.
127*4882a593Smuzhiyun      */
128*4882a593Smuzhiyun     SetWinSize(pWindow);
129*4882a593Smuzhiyun     SetBorderSize(pWindow);
130*4882a593Smuzhiyun     if (pVisit->bw)
131*4882a593Smuzhiyun         QueueWorkProc(compRepaintBorder, serverClient,
132*4882a593Smuzhiyun                       (void *) (intptr_t) pWindow->drawable.id);
133*4882a593Smuzhiyun     return WT_WALKCHILDREN;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun void
compSetPixmap(WindowPtr pWindow,PixmapPtr pPixmap,int bw)137*4882a593Smuzhiyun compSetPixmap(WindowPtr pWindow, PixmapPtr pPixmap, int bw)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun     CompPixmapVisitRec visitRec;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     visitRec.pWindow = pWindow;
142*4882a593Smuzhiyun     visitRec.pPixmap = pPixmap;
143*4882a593Smuzhiyun     visitRec.bw = bw;
144*4882a593Smuzhiyun     TraverseTree(pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
145*4882a593Smuzhiyun     compCheckTree(pWindow->drawable.pScreen);
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun Bool
compCheckRedirect(WindowPtr pWin)149*4882a593Smuzhiyun compCheckRedirect(WindowPtr pWin)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun     CompWindowPtr cw = GetCompWindow(pWin);
152*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
153*4882a593Smuzhiyun     Bool should;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun     should = pWin->realized && (pWin->drawable.class != InputOnly) &&
156*4882a593Smuzhiyun         (cw != NULL) && (pWin->parent != NULL);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun     /* Never redirect the overlay window */
159*4882a593Smuzhiyun     if (cs->pOverlayWin != NULL) {
160*4882a593Smuzhiyun         if (pWin == cs->pOverlayWin) {
161*4882a593Smuzhiyun             should = FALSE;
162*4882a593Smuzhiyun         }
163*4882a593Smuzhiyun     }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun     if (should != (pWin->redirectDraw != RedirectDrawNone)) {
166*4882a593Smuzhiyun         if (should)
167*4882a593Smuzhiyun             return compAllocPixmap(pWin);
168*4882a593Smuzhiyun         else {
169*4882a593Smuzhiyun             ScreenPtr pScreen = pWin->drawable.pScreen;
170*4882a593Smuzhiyun             PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun             compSetParentPixmap(pWin);
173*4882a593Smuzhiyun             compRestoreWindow(pWin, pPixmap);
174*4882a593Smuzhiyun             (*pScreen->DestroyPixmap) (pPixmap);
175*4882a593Smuzhiyun         }
176*4882a593Smuzhiyun     }
177*4882a593Smuzhiyun     else if (should) {
178*4882a593Smuzhiyun         if (cw->update == CompositeRedirectAutomatic)
179*4882a593Smuzhiyun             pWin->redirectDraw = RedirectDrawAutomatic;
180*4882a593Smuzhiyun         else
181*4882a593Smuzhiyun             pWin->redirectDraw = RedirectDrawManual;
182*4882a593Smuzhiyun     }
183*4882a593Smuzhiyun     return TRUE;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun static int
updateOverlayWindow(ScreenPtr pScreen)187*4882a593Smuzhiyun updateOverlayWindow(ScreenPtr pScreen)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun     CompScreenPtr cs;
190*4882a593Smuzhiyun     WindowPtr pWin;             /* overlay window */
191*4882a593Smuzhiyun     XID vlist[2];
192*4882a593Smuzhiyun     int w = pScreen->width;
193*4882a593Smuzhiyun     int h = pScreen->height;
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun #ifdef PANORAMIX
196*4882a593Smuzhiyun     if (!noPanoramiXExtension) {
197*4882a593Smuzhiyun         w = PanoramiXPixWidth;
198*4882a593Smuzhiyun         h = PanoramiXPixHeight;
199*4882a593Smuzhiyun     }
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun     cs = GetCompScreen(pScreen);
203*4882a593Smuzhiyun     if ((pWin = cs->pOverlayWin) != NULL) {
204*4882a593Smuzhiyun         if ((pWin->drawable.width == w) && (pWin->drawable.height == h))
205*4882a593Smuzhiyun             return Success;
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun         /* Let's resize the overlay window. */
208*4882a593Smuzhiyun         vlist[0] = w;
209*4882a593Smuzhiyun         vlist[1] = h;
210*4882a593Smuzhiyun         return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
211*4882a593Smuzhiyun     }
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun     /* Let's be on the safe side and not assume an overlay window is
214*4882a593Smuzhiyun        always allocated. */
215*4882a593Smuzhiyun     return Success;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun Bool
compPositionWindow(WindowPtr pWin,int x,int y)219*4882a593Smuzhiyun compPositionWindow(WindowPtr pWin, int x, int y)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
222*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
223*4882a593Smuzhiyun     Bool ret = TRUE;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun     pScreen->PositionWindow = cs->PositionWindow;
226*4882a593Smuzhiyun     /*
227*4882a593Smuzhiyun      * "Shouldn't need this as all possible places should be wrapped
228*4882a593Smuzhiyun      *
229*4882a593Smuzhiyun      compCheckRedirect (pWin);
230*4882a593Smuzhiyun      */
231*4882a593Smuzhiyun #ifdef COMPOSITE_DEBUG
232*4882a593Smuzhiyun     if ((pWin->redirectDraw != RedirectDrawNone) !=
233*4882a593Smuzhiyun         (pWin->viewable && (GetCompWindow(pWin) != NULL)))
234*4882a593Smuzhiyun         OsAbort();
235*4882a593Smuzhiyun #endif
236*4882a593Smuzhiyun     if (pWin->redirectDraw != RedirectDrawNone) {
237*4882a593Smuzhiyun         PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
238*4882a593Smuzhiyun         int bw = wBorderWidth(pWin);
239*4882a593Smuzhiyun         int nx = pWin->drawable.x - bw;
240*4882a593Smuzhiyun         int ny = pWin->drawable.y - bw;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun         if (pPixmap->screen_x != nx || pPixmap->screen_y != ny) {
243*4882a593Smuzhiyun             pPixmap->screen_x = nx;
244*4882a593Smuzhiyun             pPixmap->screen_y = ny;
245*4882a593Smuzhiyun             pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
246*4882a593Smuzhiyun         }
247*4882a593Smuzhiyun     }
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun     if (!(*pScreen->PositionWindow) (pWin, x, y))
250*4882a593Smuzhiyun         ret = FALSE;
251*4882a593Smuzhiyun     cs->PositionWindow = pScreen->PositionWindow;
252*4882a593Smuzhiyun     pScreen->PositionWindow = compPositionWindow;
253*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
254*4882a593Smuzhiyun     if (updateOverlayWindow(pScreen) != Success)
255*4882a593Smuzhiyun         ret = FALSE;
256*4882a593Smuzhiyun     return ret;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun Bool
compRealizeWindow(WindowPtr pWin)260*4882a593Smuzhiyun compRealizeWindow(WindowPtr pWin)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
263*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
264*4882a593Smuzhiyun     Bool ret = TRUE;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun     pScreen->RealizeWindow = cs->RealizeWindow;
267*4882a593Smuzhiyun     compCheckRedirect(pWin);
268*4882a593Smuzhiyun     if (!(*pScreen->RealizeWindow) (pWin))
269*4882a593Smuzhiyun         ret = FALSE;
270*4882a593Smuzhiyun     cs->RealizeWindow = pScreen->RealizeWindow;
271*4882a593Smuzhiyun     pScreen->RealizeWindow = compRealizeWindow;
272*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
273*4882a593Smuzhiyun     return ret;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun Bool
compUnrealizeWindow(WindowPtr pWin)277*4882a593Smuzhiyun compUnrealizeWindow(WindowPtr pWin)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
280*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
281*4882a593Smuzhiyun     Bool ret = TRUE;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun     pScreen->UnrealizeWindow = cs->UnrealizeWindow;
284*4882a593Smuzhiyun     compCheckRedirect(pWin);
285*4882a593Smuzhiyun     if (!(*pScreen->UnrealizeWindow) (pWin))
286*4882a593Smuzhiyun         ret = FALSE;
287*4882a593Smuzhiyun     cs->UnrealizeWindow = pScreen->UnrealizeWindow;
288*4882a593Smuzhiyun     pScreen->UnrealizeWindow = compUnrealizeWindow;
289*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
290*4882a593Smuzhiyun     return ret;
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun /*
294*4882a593Smuzhiyun  * Called after the borderClip for the window has settled down
295*4882a593Smuzhiyun  * We use this to make sure our extra borderClip has the right origin
296*4882a593Smuzhiyun  */
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun void
compClipNotify(WindowPtr pWin,int dx,int dy)299*4882a593Smuzhiyun compClipNotify(WindowPtr pWin, int dx, int dy)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
302*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
303*4882a593Smuzhiyun     CompWindowPtr cw = GetCompWindow(pWin);
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun     if (cw) {
306*4882a593Smuzhiyun         if (cw->borderClipX != pWin->drawable.x ||
307*4882a593Smuzhiyun             cw->borderClipY != pWin->drawable.y) {
308*4882a593Smuzhiyun             RegionTranslate(&cw->borderClip,
309*4882a593Smuzhiyun                             pWin->drawable.x - cw->borderClipX,
310*4882a593Smuzhiyun                             pWin->drawable.y - cw->borderClipY);
311*4882a593Smuzhiyun             cw->borderClipX = pWin->drawable.x;
312*4882a593Smuzhiyun             cw->borderClipY = pWin->drawable.y;
313*4882a593Smuzhiyun         }
314*4882a593Smuzhiyun     }
315*4882a593Smuzhiyun     if (cs->ClipNotify) {
316*4882a593Smuzhiyun         pScreen->ClipNotify = cs->ClipNotify;
317*4882a593Smuzhiyun         (*pScreen->ClipNotify) (pWin, dx, dy);
318*4882a593Smuzhiyun         cs->ClipNotify = pScreen->ClipNotify;
319*4882a593Smuzhiyun         pScreen->ClipNotify = compClipNotify;
320*4882a593Smuzhiyun     }
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun Bool
compIsAlternateVisual(ScreenPtr pScreen,XID visual)324*4882a593Smuzhiyun compIsAlternateVisual(ScreenPtr pScreen, XID visual)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
327*4882a593Smuzhiyun     int i;
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun     for (i = 0; cs && i < cs->numAlternateVisuals; i++)
330*4882a593Smuzhiyun         if (cs->alternateVisuals[i] == visual)
331*4882a593Smuzhiyun             return TRUE;
332*4882a593Smuzhiyun     return FALSE;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun static Bool
compIsImplicitRedirectException(ScreenPtr pScreen,XID parentVisual,XID winVisual)336*4882a593Smuzhiyun compIsImplicitRedirectException(ScreenPtr pScreen,
337*4882a593Smuzhiyun                                 XID parentVisual, XID winVisual)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
340*4882a593Smuzhiyun     int i;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
343*4882a593Smuzhiyun         if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
344*4882a593Smuzhiyun             cs->implicitRedirectExceptions[i].winVisual == winVisual)
345*4882a593Smuzhiyun             return TRUE;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun     return FALSE;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun static Bool
compImplicitRedirect(WindowPtr pWin,WindowPtr pParent)351*4882a593Smuzhiyun compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun     if (pParent) {
354*4882a593Smuzhiyun         ScreenPtr pScreen = pWin->drawable.pScreen;
355*4882a593Smuzhiyun         XID winVisual = wVisual(pWin);
356*4882a593Smuzhiyun         XID parentVisual = wVisual(pParent);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun         if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
359*4882a593Smuzhiyun             return FALSE;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun         if (winVisual != parentVisual &&
362*4882a593Smuzhiyun             (compIsAlternateVisual(pScreen, winVisual) ||
363*4882a593Smuzhiyun              compIsAlternateVisual(pScreen, parentVisual)))
364*4882a593Smuzhiyun             return TRUE;
365*4882a593Smuzhiyun     }
366*4882a593Smuzhiyun     return FALSE;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun static void
compFreeOldPixmap(WindowPtr pWin)370*4882a593Smuzhiyun compFreeOldPixmap(WindowPtr pWin)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun     if (pWin->redirectDraw != RedirectDrawNone) {
375*4882a593Smuzhiyun         CompWindowPtr cw = GetCompWindow(pWin);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun         if (cw->pOldPixmap) {
378*4882a593Smuzhiyun             (*pScreen->DestroyPixmap) (cw->pOldPixmap);
379*4882a593Smuzhiyun             cw->pOldPixmap = NullPixmap;
380*4882a593Smuzhiyun         }
381*4882a593Smuzhiyun     }
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun void
compMoveWindow(WindowPtr pWin,int x,int y,WindowPtr pSib,VTKind kind)385*4882a593Smuzhiyun compMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
386*4882a593Smuzhiyun {
387*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
388*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun     pScreen->MoveWindow = cs->MoveWindow;
391*4882a593Smuzhiyun     (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
392*4882a593Smuzhiyun     cs->MoveWindow = pScreen->MoveWindow;
393*4882a593Smuzhiyun     pScreen->MoveWindow = compMoveWindow;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun     compFreeOldPixmap(pWin);
396*4882a593Smuzhiyun     compCheckTree(pScreen);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun void
compResizeWindow(WindowPtr pWin,int x,int y,unsigned int w,unsigned int h,WindowPtr pSib)400*4882a593Smuzhiyun compResizeWindow(WindowPtr pWin, int x, int y,
401*4882a593Smuzhiyun                  unsigned int w, unsigned int h, WindowPtr pSib)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
404*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun     pScreen->ResizeWindow = cs->ResizeWindow;
407*4882a593Smuzhiyun     (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
408*4882a593Smuzhiyun     cs->ResizeWindow = pScreen->ResizeWindow;
409*4882a593Smuzhiyun     pScreen->ResizeWindow = compResizeWindow;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun     compFreeOldPixmap(pWin);
412*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun void
compChangeBorderWidth(WindowPtr pWin,unsigned int bw)416*4882a593Smuzhiyun compChangeBorderWidth(WindowPtr pWin, unsigned int bw)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
419*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun     pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
422*4882a593Smuzhiyun     (*pScreen->ChangeBorderWidth) (pWin, bw);
423*4882a593Smuzhiyun     cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
424*4882a593Smuzhiyun     pScreen->ChangeBorderWidth = compChangeBorderWidth;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun     compFreeOldPixmap(pWin);
427*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun void
compReparentWindow(WindowPtr pWin,WindowPtr pPriorParent)431*4882a593Smuzhiyun compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
434*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
435*4882a593Smuzhiyun     CompWindowPtr cw;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun     pScreen->ReparentWindow = cs->ReparentWindow;
438*4882a593Smuzhiyun     /*
439*4882a593Smuzhiyun      * Remove any implicit redirect due to synthesized visual
440*4882a593Smuzhiyun      */
441*4882a593Smuzhiyun     if (compImplicitRedirect(pWin, pPriorParent))
442*4882a593Smuzhiyun         compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
443*4882a593Smuzhiyun     /*
444*4882a593Smuzhiyun      * Handle subwindows redirection
445*4882a593Smuzhiyun      */
446*4882a593Smuzhiyun     compUnredirectOneSubwindow(pPriorParent, pWin);
447*4882a593Smuzhiyun     compRedirectOneSubwindow(pWin->parent, pWin);
448*4882a593Smuzhiyun     /*
449*4882a593Smuzhiyun      * Add any implict redirect due to synthesized visual
450*4882a593Smuzhiyun      */
451*4882a593Smuzhiyun     if (compImplicitRedirect(pWin, pWin->parent))
452*4882a593Smuzhiyun         compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun     /*
455*4882a593Smuzhiyun      * Allocate any necessary redirect pixmap
456*4882a593Smuzhiyun      * (this actually should never be true; pWin is always unmapped)
457*4882a593Smuzhiyun      */
458*4882a593Smuzhiyun     compCheckRedirect(pWin);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun     /*
461*4882a593Smuzhiyun      * Reset pixmap pointers as appropriate
462*4882a593Smuzhiyun      */
463*4882a593Smuzhiyun     if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
464*4882a593Smuzhiyun         compSetPixmap(pWin, (*pScreen->GetWindowPixmap) (pWin->parent),
465*4882a593Smuzhiyun                       pWin->borderWidth);
466*4882a593Smuzhiyun     /*
467*4882a593Smuzhiyun      * Call down to next function
468*4882a593Smuzhiyun      */
469*4882a593Smuzhiyun     if (pScreen->ReparentWindow)
470*4882a593Smuzhiyun         (*pScreen->ReparentWindow) (pWin, pPriorParent);
471*4882a593Smuzhiyun     cs->ReparentWindow = pScreen->ReparentWindow;
472*4882a593Smuzhiyun     pScreen->ReparentWindow = compReparentWindow;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun     cw = GetCompWindow(pWin);
475*4882a593Smuzhiyun     if (pWin->damagedDescendants || (cw && cw->damaged))
476*4882a593Smuzhiyun         compMarkAncestors(pWin);
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun void
compCopyWindow(WindowPtr pWin,DDXPointRec ptOldOrg,RegionPtr prgnSrc)482*4882a593Smuzhiyun compCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
485*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
486*4882a593Smuzhiyun     int dx = 0, dy = 0;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun     if (pWin->redirectDraw != RedirectDrawNone) {
489*4882a593Smuzhiyun         PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
490*4882a593Smuzhiyun         CompWindowPtr cw = GetCompWindow(pWin);
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun         assert(cw->oldx != COMP_ORIGIN_INVALID);
493*4882a593Smuzhiyun         assert(cw->oldy != COMP_ORIGIN_INVALID);
494*4882a593Smuzhiyun         if (cw->pOldPixmap) {
495*4882a593Smuzhiyun             /*
496*4882a593Smuzhiyun              * Ok, the old bits are available in pOldPixmap and
497*4882a593Smuzhiyun              * need to be copied to pNewPixmap.
498*4882a593Smuzhiyun              */
499*4882a593Smuzhiyun             RegionRec rgnDst;
500*4882a593Smuzhiyun             GCPtr pGC;
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun             dx = ptOldOrg.x - pWin->drawable.x;
503*4882a593Smuzhiyun             dy = ptOldOrg.y - pWin->drawable.y;
504*4882a593Smuzhiyun             RegionTranslate(prgnSrc, -dx, -dy);
505*4882a593Smuzhiyun 
506*4882a593Smuzhiyun             RegionNull(&rgnDst);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun             RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun             RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun             dx = dx + pPixmap->screen_x - cw->oldx;
513*4882a593Smuzhiyun             dy = dy + pPixmap->screen_y - cw->oldy;
514*4882a593Smuzhiyun             pGC = GetScratchGC(pPixmap->drawable.depth, pScreen);
515*4882a593Smuzhiyun             if (pGC) {
516*4882a593Smuzhiyun                 BoxPtr pBox = RegionRects(&rgnDst);
517*4882a593Smuzhiyun                 int nBox = RegionNumRects(&rgnDst);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun                 ValidateGC(&pPixmap->drawable, pGC);
520*4882a593Smuzhiyun                 while (nBox--) {
521*4882a593Smuzhiyun                     (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
522*4882a593Smuzhiyun                                                   &pPixmap->drawable,
523*4882a593Smuzhiyun                                                   pGC,
524*4882a593Smuzhiyun                                                   pBox->x1 + dx, pBox->y1 + dy,
525*4882a593Smuzhiyun                                                   pBox->x2 - pBox->x1,
526*4882a593Smuzhiyun                                                   pBox->y2 - pBox->y1,
527*4882a593Smuzhiyun                                                   pBox->x1, pBox->y1);
528*4882a593Smuzhiyun                     pBox++;
529*4882a593Smuzhiyun                 }
530*4882a593Smuzhiyun                 FreeScratchGC(pGC);
531*4882a593Smuzhiyun             }
532*4882a593Smuzhiyun             RegionUninit(&rgnDst);
533*4882a593Smuzhiyun             return;
534*4882a593Smuzhiyun         }
535*4882a593Smuzhiyun         dx = pPixmap->screen_x - cw->oldx;
536*4882a593Smuzhiyun         dy = pPixmap->screen_y - cw->oldy;
537*4882a593Smuzhiyun         ptOldOrg.x += dx;
538*4882a593Smuzhiyun         ptOldOrg.y += dy;
539*4882a593Smuzhiyun     }
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun     pScreen->CopyWindow = cs->CopyWindow;
542*4882a593Smuzhiyun     if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y) {
543*4882a593Smuzhiyun         if (dx || dy)
544*4882a593Smuzhiyun             RegionTranslate(prgnSrc, dx, dy);
545*4882a593Smuzhiyun         (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
546*4882a593Smuzhiyun         if (dx || dy)
547*4882a593Smuzhiyun             RegionTranslate(prgnSrc, -dx, -dy);
548*4882a593Smuzhiyun     }
549*4882a593Smuzhiyun     else {
550*4882a593Smuzhiyun         ptOldOrg.x -= dx;
551*4882a593Smuzhiyun         ptOldOrg.y -= dy;
552*4882a593Smuzhiyun         RegionTranslate(prgnSrc,
553*4882a593Smuzhiyun                         pWin->drawable.x - ptOldOrg.x,
554*4882a593Smuzhiyun                         pWin->drawable.y - ptOldOrg.y);
555*4882a593Smuzhiyun         DamageDamageRegion(&pWin->drawable, prgnSrc);
556*4882a593Smuzhiyun     }
557*4882a593Smuzhiyun     cs->CopyWindow = pScreen->CopyWindow;
558*4882a593Smuzhiyun     pScreen->CopyWindow = compCopyWindow;
559*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun Bool
compCreateWindow(WindowPtr pWin)563*4882a593Smuzhiyun compCreateWindow(WindowPtr pWin)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
566*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
567*4882a593Smuzhiyun     Bool ret;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun     pScreen->CreateWindow = cs->CreateWindow;
570*4882a593Smuzhiyun     ret = (*pScreen->CreateWindow) (pWin);
571*4882a593Smuzhiyun     if (pWin->parent && ret) {
572*4882a593Smuzhiyun         CompSubwindowsPtr csw = GetCompSubwindows(pWin->parent);
573*4882a593Smuzhiyun         CompClientWindowPtr ccw;
574*4882a593Smuzhiyun         PixmapPtr parent_pixmap = (*pScreen->GetWindowPixmap)(pWin->parent);
575*4882a593Smuzhiyun         PixmapPtr window_pixmap = (*pScreen->GetWindowPixmap)(pWin);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun         if (window_pixmap != parent_pixmap)
578*4882a593Smuzhiyun             (*pScreen->SetWindowPixmap) (pWin, parent_pixmap);
579*4882a593Smuzhiyun         if (csw)
580*4882a593Smuzhiyun             for (ccw = csw->clients; ccw; ccw = ccw->next)
581*4882a593Smuzhiyun                 compRedirectWindow(clients[CLIENT_ID(ccw->id)],
582*4882a593Smuzhiyun                                    pWin, ccw->update);
583*4882a593Smuzhiyun         if (compImplicitRedirect(pWin, pWin->parent))
584*4882a593Smuzhiyun             compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
585*4882a593Smuzhiyun     }
586*4882a593Smuzhiyun     cs->CreateWindow = pScreen->CreateWindow;
587*4882a593Smuzhiyun     pScreen->CreateWindow = compCreateWindow;
588*4882a593Smuzhiyun     compCheckTree(pWin->drawable.pScreen);
589*4882a593Smuzhiyun     return ret;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun Bool
compDestroyWindow(WindowPtr pWin)593*4882a593Smuzhiyun compDestroyWindow(WindowPtr pWin)
594*4882a593Smuzhiyun {
595*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
596*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
597*4882a593Smuzhiyun     CompWindowPtr cw;
598*4882a593Smuzhiyun     CompSubwindowsPtr csw;
599*4882a593Smuzhiyun     Bool ret;
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun     pScreen->DestroyWindow = cs->DestroyWindow;
602*4882a593Smuzhiyun     while ((cw = GetCompWindow(pWin)))
603*4882a593Smuzhiyun         FreeResource(cw->clients->id, RT_NONE);
604*4882a593Smuzhiyun     while ((csw = GetCompSubwindows(pWin)))
605*4882a593Smuzhiyun         FreeResource(csw->clients->id, RT_NONE);
606*4882a593Smuzhiyun 
607*4882a593Smuzhiyun     if (pWin->redirectDraw != RedirectDrawNone) {
608*4882a593Smuzhiyun         PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun         compSetParentPixmap(pWin);
611*4882a593Smuzhiyun         (*pScreen->DestroyPixmap) (pPixmap);
612*4882a593Smuzhiyun     }
613*4882a593Smuzhiyun     ret = (*pScreen->DestroyWindow) (pWin);
614*4882a593Smuzhiyun     cs->DestroyWindow = pScreen->DestroyWindow;
615*4882a593Smuzhiyun     pScreen->DestroyWindow = compDestroyWindow;
616*4882a593Smuzhiyun /*    compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
617*4882a593Smuzhiyun     return ret;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun void
compSetRedirectBorderClip(WindowPtr pWin,RegionPtr pRegion)621*4882a593Smuzhiyun compSetRedirectBorderClip(WindowPtr pWin, RegionPtr pRegion)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun     CompWindowPtr cw = GetCompWindow(pWin);
624*4882a593Smuzhiyun     RegionRec damage;
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun     RegionNull(&damage);
627*4882a593Smuzhiyun     /*
628*4882a593Smuzhiyun      * Align old border clip with new border clip
629*4882a593Smuzhiyun      */
630*4882a593Smuzhiyun     RegionTranslate(&cw->borderClip,
631*4882a593Smuzhiyun                     pWin->drawable.x - cw->borderClipX,
632*4882a593Smuzhiyun                     pWin->drawable.y - cw->borderClipY);
633*4882a593Smuzhiyun     /*
634*4882a593Smuzhiyun      * Compute newly visible portion of window for repaint
635*4882a593Smuzhiyun      */
636*4882a593Smuzhiyun     RegionSubtract(&damage, pRegion, &cw->borderClip);
637*4882a593Smuzhiyun     /*
638*4882a593Smuzhiyun      * Report that as damaged so it will be redrawn
639*4882a593Smuzhiyun      */
640*4882a593Smuzhiyun     DamageDamageRegion(&pWin->drawable, &damage);
641*4882a593Smuzhiyun     RegionUninit(&damage);
642*4882a593Smuzhiyun     /*
643*4882a593Smuzhiyun      * Save the new border clip region
644*4882a593Smuzhiyun      */
645*4882a593Smuzhiyun     RegionCopy(&cw->borderClip, pRegion);
646*4882a593Smuzhiyun     cw->borderClipX = pWin->drawable.x;
647*4882a593Smuzhiyun     cw->borderClipY = pWin->drawable.y;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun RegionPtr
compGetRedirectBorderClip(WindowPtr pWin)651*4882a593Smuzhiyun compGetRedirectBorderClip(WindowPtr pWin)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun     CompWindowPtr cw = GetCompWindow(pWin);
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun     return &cw->borderClip;
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun static void
compWindowUpdateAutomatic(WindowPtr pWin)659*4882a593Smuzhiyun compWindowUpdateAutomatic(WindowPtr pWin)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun     CompWindowPtr cw = GetCompWindow(pWin);
662*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
663*4882a593Smuzhiyun     WindowPtr pParent = pWin->parent;
664*4882a593Smuzhiyun     PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
665*4882a593Smuzhiyun     PictFormatPtr pSrcFormat = PictureWindowFormat(pWin);
666*4882a593Smuzhiyun     PictFormatPtr pDstFormat = PictureWindowFormat(pWin->parent);
667*4882a593Smuzhiyun     int error;
668*4882a593Smuzhiyun     RegionPtr pRegion = DamageRegion(cw->damage);
669*4882a593Smuzhiyun     PicturePtr pSrcPicture = CreatePicture(0, &pSrcPixmap->drawable,
670*4882a593Smuzhiyun                                            pSrcFormat,
671*4882a593Smuzhiyun                                            0, 0,
672*4882a593Smuzhiyun                                            serverClient,
673*4882a593Smuzhiyun                                            &error);
674*4882a593Smuzhiyun     XID subwindowMode = IncludeInferiors;
675*4882a593Smuzhiyun     PicturePtr pDstPicture = CreatePicture(0, &pParent->drawable,
676*4882a593Smuzhiyun                                            pDstFormat,
677*4882a593Smuzhiyun                                            CPSubwindowMode,
678*4882a593Smuzhiyun                                            &subwindowMode,
679*4882a593Smuzhiyun                                            serverClient,
680*4882a593Smuzhiyun                                            &error);
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun     /*
683*4882a593Smuzhiyun      * First move the region from window to screen coordinates
684*4882a593Smuzhiyun      */
685*4882a593Smuzhiyun     RegionTranslate(pRegion, pWin->drawable.x, pWin->drawable.y);
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun     /*
688*4882a593Smuzhiyun      * Clip against the "real" border clip
689*4882a593Smuzhiyun      */
690*4882a593Smuzhiyun     RegionIntersect(pRegion, pRegion, &cw->borderClip);
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun     /*
693*4882a593Smuzhiyun      * Now translate from screen to dest coordinates
694*4882a593Smuzhiyun      */
695*4882a593Smuzhiyun     RegionTranslate(pRegion, -pParent->drawable.x, -pParent->drawable.y);
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun     /*
698*4882a593Smuzhiyun      * Clip the picture
699*4882a593Smuzhiyun      */
700*4882a593Smuzhiyun     SetPictureClipRegion(pDstPicture, 0, 0, pRegion);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun     /*
703*4882a593Smuzhiyun      * And paint
704*4882a593Smuzhiyun      */
705*4882a593Smuzhiyun     CompositePicture(PictOpSrc, pSrcPicture, 0, pDstPicture,
706*4882a593Smuzhiyun                      0, 0,      /* src_x, src_y */
707*4882a593Smuzhiyun                      0, 0,      /* msk_x, msk_y */
708*4882a593Smuzhiyun                      pSrcPixmap->screen_x - pParent->drawable.x,
709*4882a593Smuzhiyun                      pSrcPixmap->screen_y - pParent->drawable.y,
710*4882a593Smuzhiyun                      pSrcPixmap->drawable.width, pSrcPixmap->drawable.height);
711*4882a593Smuzhiyun     FreePicture(pSrcPicture, 0);
712*4882a593Smuzhiyun     FreePicture(pDstPicture, 0);
713*4882a593Smuzhiyun     /*
714*4882a593Smuzhiyun      * Empty the damage region.  This has the nice effect of
715*4882a593Smuzhiyun      * rendering the translations above harmless
716*4882a593Smuzhiyun      */
717*4882a593Smuzhiyun     DamageEmpty(cw->damage);
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun static void
compPaintWindowToParent(WindowPtr pWin)721*4882a593Smuzhiyun compPaintWindowToParent(WindowPtr pWin)
722*4882a593Smuzhiyun {
723*4882a593Smuzhiyun     compPaintChildrenToWindow(pWin);
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun     if (pWin->redirectDraw != RedirectDrawNone) {
726*4882a593Smuzhiyun         CompWindowPtr cw = GetCompWindow(pWin);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun         if (cw->damaged) {
729*4882a593Smuzhiyun             compWindowUpdateAutomatic(pWin);
730*4882a593Smuzhiyun             cw->damaged = FALSE;
731*4882a593Smuzhiyun         }
732*4882a593Smuzhiyun     }
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun void
compPaintChildrenToWindow(WindowPtr pWin)736*4882a593Smuzhiyun compPaintChildrenToWindow(WindowPtr pWin)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun     WindowPtr pChild;
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun     if (!pWin->damagedDescendants)
741*4882a593Smuzhiyun         return;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun     for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
744*4882a593Smuzhiyun         compPaintWindowToParent(pChild);
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun     pWin->damagedDescendants = FALSE;
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun WindowPtr
CompositeRealChildHead(WindowPtr pWin)750*4882a593Smuzhiyun CompositeRealChildHead(WindowPtr pWin)
751*4882a593Smuzhiyun {
752*4882a593Smuzhiyun     WindowPtr pChild, pChildBefore;
753*4882a593Smuzhiyun     CompScreenPtr cs;
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun     if (!pWin->parent &&
756*4882a593Smuzhiyun         (screenIsSaved == SCREEN_SAVER_ON) &&
757*4882a593Smuzhiyun         (HasSaverWindow(pWin->drawable.pScreen))) {
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun         /* First child is the screen saver; see if next child is the overlay */
760*4882a593Smuzhiyun         pChildBefore = pWin->firstChild;
761*4882a593Smuzhiyun         pChild = pChildBefore->nextSib;
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun     }
764*4882a593Smuzhiyun     else {
765*4882a593Smuzhiyun         pChildBefore = NullWindow;
766*4882a593Smuzhiyun         pChild = pWin->firstChild;
767*4882a593Smuzhiyun     }
768*4882a593Smuzhiyun 
769*4882a593Smuzhiyun     if (!pChild) {
770*4882a593Smuzhiyun         return NullWindow;
771*4882a593Smuzhiyun     }
772*4882a593Smuzhiyun 
773*4882a593Smuzhiyun     cs = GetCompScreen(pWin->drawable.pScreen);
774*4882a593Smuzhiyun     if (pChild == cs->pOverlayWin) {
775*4882a593Smuzhiyun         return pChild;
776*4882a593Smuzhiyun     }
777*4882a593Smuzhiyun     else {
778*4882a593Smuzhiyun         return pChildBefore;
779*4882a593Smuzhiyun     }
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun int
compConfigNotify(WindowPtr pWin,int x,int y,int w,int h,int bw,WindowPtr pSib)783*4882a593Smuzhiyun compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
784*4882a593Smuzhiyun                  int bw, WindowPtr pSib)
785*4882a593Smuzhiyun {
786*4882a593Smuzhiyun     ScreenPtr pScreen = pWin->drawable.pScreen;
787*4882a593Smuzhiyun     CompScreenPtr cs = GetCompScreen(pScreen);
788*4882a593Smuzhiyun     Bool ret = 0;
789*4882a593Smuzhiyun     WindowPtr pParent = pWin->parent;
790*4882a593Smuzhiyun     int draw_x, draw_y;
791*4882a593Smuzhiyun     Bool alloc_ret;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun     if (cs->ConfigNotify) {
794*4882a593Smuzhiyun         pScreen->ConfigNotify = cs->ConfigNotify;
795*4882a593Smuzhiyun         ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib);
796*4882a593Smuzhiyun         cs->ConfigNotify = pScreen->ConfigNotify;
797*4882a593Smuzhiyun         pScreen->ConfigNotify = compConfigNotify;
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun         if (ret)
800*4882a593Smuzhiyun             return ret;
801*4882a593Smuzhiyun     }
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun     if (pWin->redirectDraw == RedirectDrawNone)
804*4882a593Smuzhiyun         return Success;
805*4882a593Smuzhiyun 
806*4882a593Smuzhiyun     compCheckTree(pScreen);
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun     draw_x = pParent->drawable.x + x + bw;
809*4882a593Smuzhiyun     draw_y = pParent->drawable.y + y + bw;
810*4882a593Smuzhiyun     alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw);
811*4882a593Smuzhiyun 
812*4882a593Smuzhiyun     if (alloc_ret == FALSE)
813*4882a593Smuzhiyun         return BadAlloc;
814*4882a593Smuzhiyun     return Success;
815*4882a593Smuzhiyun }
816