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