1*4882a593Smuzhiyun /***********************************************************
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1987, 1998 The Open Group
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
22*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
23*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun All Rights Reserved
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this software and its
30*4882a593Smuzhiyun documentation for any purpose and without fee is hereby granted,
31*4882a593Smuzhiyun provided that the above copyright notice appear in all copies and that
32*4882a593Smuzhiyun both that copyright notice and this permission notice appear in
33*4882a593Smuzhiyun supporting documentation, and that the name of Digital not be
34*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution of the
35*4882a593Smuzhiyun software without specific, written prior permission.
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38*4882a593Smuzhiyun ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39*4882a593Smuzhiyun DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40*4882a593Smuzhiyun ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42*4882a593Smuzhiyun ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43*4882a593Smuzhiyun SOFTWARE.
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun ******************************************************************/
46*4882a593Smuzhiyun /*****************************************************************
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy
51*4882a593Smuzhiyun of this software and associated documentation files (the "Software"), to deal
52*4882a593Smuzhiyun in the Software without restriction, including without limitation the rights
53*4882a593Smuzhiyun to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54*4882a593Smuzhiyun copies of the Software.
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
57*4882a593Smuzhiyun all copies or substantial portions of the Software.
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
62*4882a593Smuzhiyun DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
63*4882a593Smuzhiyun BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
64*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
65*4882a593Smuzhiyun IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun Except as contained in this notice, the name of Digital Equipment Corporation
68*4882a593Smuzhiyun shall not be used in advertising or otherwise to promote the sale, use or other
69*4882a593Smuzhiyun dealings in this Software without prior written authorization from Digital
70*4882a593Smuzhiyun Equipment Corporation.
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun ******************************************************************/
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
75*4882a593Smuzhiyun #include <dix-config.h>
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun #include <X11/X.h>
79*4882a593Smuzhiyun #include <X11/Xproto.h>
80*4882a593Smuzhiyun #include <X11/Xprotostr.h>
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun #include "misc.h"
83*4882a593Smuzhiyun #include "regionstr.h"
84*4882a593Smuzhiyun #include "scrnintstr.h"
85*4882a593Smuzhiyun #include "gcstruct.h"
86*4882a593Smuzhiyun #include "windowstr.h"
87*4882a593Smuzhiyun #include "pixmap.h"
88*4882a593Smuzhiyun #include "input.h"
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun #include "dixstruct.h"
91*4882a593Smuzhiyun #include "mi.h"
92*4882a593Smuzhiyun #include <X11/Xmd.h>
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun #include "globals.h"
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun #ifdef PANORAMIX
97*4882a593Smuzhiyun #include "panoramiX.h"
98*4882a593Smuzhiyun #include "panoramiXsrv.h"
99*4882a593Smuzhiyun #endif
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun /*
102*4882a593Smuzhiyun machine-independent graphics exposure code. any device that uses
103*4882a593Smuzhiyun the region package can call this.
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun #ifndef RECTLIMIT
107*4882a593Smuzhiyun #define RECTLIMIT 25 /* pick a number, any number > 8 */
108*4882a593Smuzhiyun #endif
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun /* miHandleExposures
111*4882a593Smuzhiyun generate a region for exposures for areas that were copied from obscured or
112*4882a593Smuzhiyun non-existent areas to non-obscured areas of the destination. Paint the
113*4882a593Smuzhiyun background for the region, if the destination is a window.
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun NOTE:
116*4882a593Smuzhiyun this should generally be called, even if graphicsExposures is false,
117*4882a593Smuzhiyun because this is where bits get recovered from backing store.
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun */
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun RegionPtr
miHandleExposures(DrawablePtr pSrcDrawable,DrawablePtr pDstDrawable,GCPtr pGC,int srcx,int srcy,int width,int height,int dstx,int dsty)122*4882a593Smuzhiyun miHandleExposures(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
123*4882a593Smuzhiyun GCPtr pGC, int srcx, int srcy, int width, int height,
124*4882a593Smuzhiyun int dstx, int dsty)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun RegionPtr prgnSrcClip; /* drawable-relative source clip */
127*4882a593Smuzhiyun RegionRec rgnSrcRec;
128*4882a593Smuzhiyun RegionPtr prgnDstClip; /* drawable-relative dest clip */
129*4882a593Smuzhiyun RegionRec rgnDstRec;
130*4882a593Smuzhiyun BoxRec srcBox; /* unclipped source */
131*4882a593Smuzhiyun RegionRec rgnExposed; /* exposed region, calculated source-
132*4882a593Smuzhiyun relative, made dst relative to
133*4882a593Smuzhiyun intersect with visible parts of
134*4882a593Smuzhiyun dest and send events to client,
135*4882a593Smuzhiyun and then screen relative to paint
136*4882a593Smuzhiyun the window background
137*4882a593Smuzhiyun */
138*4882a593Smuzhiyun WindowPtr pSrcWin;
139*4882a593Smuzhiyun BoxRec expBox = { 0, };
140*4882a593Smuzhiyun Bool extents;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun /* avoid work if we can */
143*4882a593Smuzhiyun if (!pGC->graphicsExposures &&
144*4882a593Smuzhiyun (pDstDrawable->type == DRAWABLE_PIXMAP) &&
145*4882a593Smuzhiyun ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
146*4882a593Smuzhiyun (((WindowPtr) pSrcDrawable)->backStorage == 0)))
147*4882a593Smuzhiyun return NULL;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun srcBox.x1 = srcx;
150*4882a593Smuzhiyun srcBox.y1 = srcy;
151*4882a593Smuzhiyun srcBox.x2 = srcx + width;
152*4882a593Smuzhiyun srcBox.y2 = srcy + height;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
155*4882a593Smuzhiyun BoxRec TsrcBox;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun TsrcBox.x1 = srcx + pSrcDrawable->x;
158*4882a593Smuzhiyun TsrcBox.y1 = srcy + pSrcDrawable->y;
159*4882a593Smuzhiyun TsrcBox.x2 = TsrcBox.x1 + width;
160*4882a593Smuzhiyun TsrcBox.y2 = TsrcBox.y1 + height;
161*4882a593Smuzhiyun pSrcWin = (WindowPtr) pSrcDrawable;
162*4882a593Smuzhiyun if (pGC->subWindowMode == IncludeInferiors) {
163*4882a593Smuzhiyun prgnSrcClip = NotClippedByChildren(pSrcWin);
164*4882a593Smuzhiyun if ((RegionContainsRect(prgnSrcClip, &TsrcBox)) == rgnIN) {
165*4882a593Smuzhiyun RegionDestroy(prgnSrcClip);
166*4882a593Smuzhiyun return NULL;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun else {
170*4882a593Smuzhiyun if ((RegionContainsRect(&pSrcWin->clipList, &TsrcBox)) == rgnIN)
171*4882a593Smuzhiyun return NULL;
172*4882a593Smuzhiyun prgnSrcClip = &rgnSrcRec;
173*4882a593Smuzhiyun RegionNull(prgnSrcClip);
174*4882a593Smuzhiyun RegionCopy(prgnSrcClip, &pSrcWin->clipList);
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun RegionTranslate(prgnSrcClip, -pSrcDrawable->x, -pSrcDrawable->y);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun else {
179*4882a593Smuzhiyun BoxRec box;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
182*4882a593Smuzhiyun (srcBox.x2 <= pSrcDrawable->width) &&
183*4882a593Smuzhiyun (srcBox.y2 <= pSrcDrawable->height))
184*4882a593Smuzhiyun return NULL;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun box.x1 = 0;
187*4882a593Smuzhiyun box.y1 = 0;
188*4882a593Smuzhiyun box.x2 = pSrcDrawable->width;
189*4882a593Smuzhiyun box.y2 = pSrcDrawable->height;
190*4882a593Smuzhiyun prgnSrcClip = &rgnSrcRec;
191*4882a593Smuzhiyun RegionInit(prgnSrcClip, &box, 1);
192*4882a593Smuzhiyun pSrcWin = NULL;
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun if (pDstDrawable == pSrcDrawable) {
196*4882a593Smuzhiyun prgnDstClip = prgnSrcClip;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun else if (pDstDrawable->type != DRAWABLE_PIXMAP) {
199*4882a593Smuzhiyun if (pGC->subWindowMode == IncludeInferiors) {
200*4882a593Smuzhiyun prgnDstClip = NotClippedByChildren((WindowPtr) pDstDrawable);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun else {
203*4882a593Smuzhiyun prgnDstClip = &rgnDstRec;
204*4882a593Smuzhiyun RegionNull(prgnDstClip);
205*4882a593Smuzhiyun RegionCopy(prgnDstClip, &((WindowPtr) pDstDrawable)->clipList);
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun RegionTranslate(prgnDstClip, -pDstDrawable->x, -pDstDrawable->y);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun else {
210*4882a593Smuzhiyun BoxRec box;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun box.x1 = 0;
213*4882a593Smuzhiyun box.y1 = 0;
214*4882a593Smuzhiyun box.x2 = pDstDrawable->width;
215*4882a593Smuzhiyun box.y2 = pDstDrawable->height;
216*4882a593Smuzhiyun prgnDstClip = &rgnDstRec;
217*4882a593Smuzhiyun RegionInit(prgnDstClip, &box, 1);
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* drawable-relative source region */
221*4882a593Smuzhiyun RegionInit(&rgnExposed, &srcBox, 1);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /* now get the hidden parts of the source box */
224*4882a593Smuzhiyun RegionSubtract(&rgnExposed, &rgnExposed, prgnSrcClip);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /* move them over the destination */
227*4882a593Smuzhiyun RegionTranslate(&rgnExposed, dstx - srcx, dsty - srcy);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun /* intersect with visible areas of dest */
230*4882a593Smuzhiyun RegionIntersect(&rgnExposed, &rgnExposed, prgnDstClip);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* intersect with client clip region. */
233*4882a593Smuzhiyun if (pGC->clientClip)
234*4882a593Smuzhiyun RegionIntersect(&rgnExposed, &rgnExposed, pGC->clientClip);
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /*
237*4882a593Smuzhiyun * If we have LOTS of rectangles, we decide to take the extents
238*4882a593Smuzhiyun * and force an exposure on that. This should require much less
239*4882a593Smuzhiyun * work overall, on both client and server. This is cheating, but
240*4882a593Smuzhiyun * isn't prohibited by the protocol ("spontaneous combustion" :-)
241*4882a593Smuzhiyun * for windows.
242*4882a593Smuzhiyun */
243*4882a593Smuzhiyun extents = pGC->graphicsExposures &&
244*4882a593Smuzhiyun (RegionNumRects(&rgnExposed) > RECTLIMIT) &&
245*4882a593Smuzhiyun (pDstDrawable->type != DRAWABLE_PIXMAP);
246*4882a593Smuzhiyun if (pSrcWin) {
247*4882a593Smuzhiyun RegionPtr region;
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun if (!(region = wClipShape(pSrcWin)))
250*4882a593Smuzhiyun region = wBoundingShape(pSrcWin);
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun * If you try to CopyArea the extents of a shaped window, compacting the
253*4882a593Smuzhiyun * exposed region will undo all our work!
254*4882a593Smuzhiyun */
255*4882a593Smuzhiyun if (extents && pSrcWin && region &&
256*4882a593Smuzhiyun (RegionContainsRect(region, &srcBox) != rgnIN))
257*4882a593Smuzhiyun extents = FALSE;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun if (extents) {
260*4882a593Smuzhiyun expBox = *RegionExtents(&rgnExposed);
261*4882a593Smuzhiyun RegionReset(&rgnExposed, &expBox);
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
264*4882a593Smuzhiyun (((WindowPtr) pDstDrawable)->backgroundState != None)) {
265*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDstDrawable;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /* make the exposed area screen-relative */
268*4882a593Smuzhiyun RegionTranslate(&rgnExposed, pDstDrawable->x, pDstDrawable->y);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun if (extents) {
271*4882a593Smuzhiyun /* PaintWindow doesn't clip, so we have to */
272*4882a593Smuzhiyun RegionIntersect(&rgnExposed, &rgnExposed, &pWin->clipList);
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun pDstDrawable->pScreen->PaintWindow((WindowPtr) pDstDrawable,
275*4882a593Smuzhiyun &rgnExposed, PW_BACKGROUND);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (extents) {
278*4882a593Smuzhiyun RegionReset(&rgnExposed, &expBox);
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun else
281*4882a593Smuzhiyun RegionTranslate(&rgnExposed, -pDstDrawable->x, -pDstDrawable->y);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun if (prgnDstClip == &rgnDstRec) {
284*4882a593Smuzhiyun RegionUninit(prgnDstClip);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun else if (prgnDstClip != prgnSrcClip) {
287*4882a593Smuzhiyun RegionDestroy(prgnDstClip);
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun if (prgnSrcClip == &rgnSrcRec) {
291*4882a593Smuzhiyun RegionUninit(prgnSrcClip);
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun else {
294*4882a593Smuzhiyun RegionDestroy(prgnSrcClip);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (pGC->graphicsExposures) {
298*4882a593Smuzhiyun /* don't look */
299*4882a593Smuzhiyun RegionPtr exposed = RegionCreate(NullBox, 0);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun *exposed = rgnExposed;
302*4882a593Smuzhiyun return exposed;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun else {
305*4882a593Smuzhiyun RegionUninit(&rgnExposed);
306*4882a593Smuzhiyun return NULL;
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun void
miSendExposures(WindowPtr pWin,RegionPtr pRgn,int dx,int dy)311*4882a593Smuzhiyun miSendExposures(WindowPtr pWin, RegionPtr pRgn, int dx, int dy)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun BoxPtr pBox;
314*4882a593Smuzhiyun int numRects;
315*4882a593Smuzhiyun xEvent *pEvent, *pe;
316*4882a593Smuzhiyun int i;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun pBox = RegionRects(pRgn);
319*4882a593Smuzhiyun numRects = RegionNumRects(pRgn);
320*4882a593Smuzhiyun if (!(pEvent = calloc(1, numRects * sizeof(xEvent))))
321*4882a593Smuzhiyun return;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun for (i = numRects, pe = pEvent; --i >= 0; pe++, pBox++) {
324*4882a593Smuzhiyun pe->u.u.type = Expose;
325*4882a593Smuzhiyun pe->u.expose.window = pWin->drawable.id;
326*4882a593Smuzhiyun pe->u.expose.x = pBox->x1 - dx;
327*4882a593Smuzhiyun pe->u.expose.y = pBox->y1 - dy;
328*4882a593Smuzhiyun pe->u.expose.width = pBox->x2 - pBox->x1;
329*4882a593Smuzhiyun pe->u.expose.height = pBox->y2 - pBox->y1;
330*4882a593Smuzhiyun pe->u.expose.count = i;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun #ifdef PANORAMIX
334*4882a593Smuzhiyun if (!noPanoramiXExtension) {
335*4882a593Smuzhiyun int scrnum = pWin->drawable.pScreen->myNum;
336*4882a593Smuzhiyun int x = 0, y = 0;
337*4882a593Smuzhiyun XID realWin = 0;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun if (!pWin->parent) {
340*4882a593Smuzhiyun x = screenInfo.screens[scrnum]->x;
341*4882a593Smuzhiyun y = screenInfo.screens[scrnum]->y;
342*4882a593Smuzhiyun pWin = screenInfo.screens[0]->root;
343*4882a593Smuzhiyun realWin = pWin->drawable.id;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun else if (scrnum) {
346*4882a593Smuzhiyun PanoramiXRes *win;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun win = PanoramiXFindIDByScrnum(XRT_WINDOW,
349*4882a593Smuzhiyun pWin->drawable.id, scrnum);
350*4882a593Smuzhiyun if (!win) {
351*4882a593Smuzhiyun free(pEvent);
352*4882a593Smuzhiyun return;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun realWin = win->info[0].id;
355*4882a593Smuzhiyun dixLookupWindow(&pWin, realWin, serverClient, DixSendAccess);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun if (x || y || scrnum)
358*4882a593Smuzhiyun for (i = 0; i < numRects; i++) {
359*4882a593Smuzhiyun pEvent[i].u.expose.window = realWin;
360*4882a593Smuzhiyun pEvent[i].u.expose.x += x;
361*4882a593Smuzhiyun pEvent[i].u.expose.y += y;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun #endif
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun DeliverEvents(pWin, pEvent, numRects, NullWindow);
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun free(pEvent);
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun void
miWindowExposures(WindowPtr pWin,RegionPtr prgn)372*4882a593Smuzhiyun miWindowExposures(WindowPtr pWin, RegionPtr prgn)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun RegionPtr exposures = prgn;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun if (prgn && !RegionNil(prgn)) {
377*4882a593Smuzhiyun RegionRec expRec;
378*4882a593Smuzhiyun int clientInterested =
379*4882a593Smuzhiyun (pWin->eventMask | wOtherEventMasks(pWin)) & ExposureMask;
380*4882a593Smuzhiyun if (clientInterested && (RegionNumRects(prgn) > RECTLIMIT)) {
381*4882a593Smuzhiyun /*
382*4882a593Smuzhiyun * If we have LOTS of rectangles, we decide to take the extents
383*4882a593Smuzhiyun * and force an exposure on that. This should require much less
384*4882a593Smuzhiyun * work overall, on both client and server. This is cheating, but
385*4882a593Smuzhiyun * isn't prohibited by the protocol ("spontaneous combustion" :-).
386*4882a593Smuzhiyun */
387*4882a593Smuzhiyun BoxRec box = *RegionExtents(prgn);
388*4882a593Smuzhiyun exposures = &expRec;
389*4882a593Smuzhiyun RegionInit(exposures, &box, 1);
390*4882a593Smuzhiyun RegionReset(prgn, &box);
391*4882a593Smuzhiyun /* miPaintWindow doesn't clip, so we have to */
392*4882a593Smuzhiyun RegionIntersect(prgn, prgn, &pWin->clipList);
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun pWin->drawable.pScreen->PaintWindow(pWin, prgn, PW_BACKGROUND);
395*4882a593Smuzhiyun if (clientInterested)
396*4882a593Smuzhiyun miSendExposures(pWin, exposures,
397*4882a593Smuzhiyun pWin->drawable.x, pWin->drawable.y);
398*4882a593Smuzhiyun if (exposures == &expRec)
399*4882a593Smuzhiyun RegionUninit(exposures);
400*4882a593Smuzhiyun RegionEmpty(prgn);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun void
miPaintWindow(WindowPtr pWin,RegionPtr prgn,int what)405*4882a593Smuzhiyun miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun ScreenPtr pScreen = pWin->drawable.pScreen;
408*4882a593Smuzhiyun ChangeGCVal gcval[6];
409*4882a593Smuzhiyun BITS32 gcmask;
410*4882a593Smuzhiyun GCPtr pGC;
411*4882a593Smuzhiyun int i;
412*4882a593Smuzhiyun BoxPtr pbox;
413*4882a593Smuzhiyun xRectangle *prect;
414*4882a593Smuzhiyun int numRects;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /*
417*4882a593Smuzhiyun * Distance from screen to destination drawable, use this
418*4882a593Smuzhiyun * to adjust rendering coordinates which come in in screen space
419*4882a593Smuzhiyun */
420*4882a593Smuzhiyun int draw_x_off, draw_y_off;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun /*
423*4882a593Smuzhiyun * Tile offset for drawing; these need to align the tile
424*4882a593Smuzhiyun * to the appropriate window origin
425*4882a593Smuzhiyun */
426*4882a593Smuzhiyun int tile_x_off, tile_y_off;
427*4882a593Smuzhiyun PixUnion fill;
428*4882a593Smuzhiyun Bool solid = TRUE;
429*4882a593Smuzhiyun DrawablePtr drawable = &pWin->drawable;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (what == PW_BACKGROUND) {
432*4882a593Smuzhiyun while (pWin->backgroundState == ParentRelative)
433*4882a593Smuzhiyun pWin = pWin->parent;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun draw_x_off = drawable->x;
436*4882a593Smuzhiyun draw_y_off = drawable->y;
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun tile_x_off = pWin->drawable.x - draw_x_off;
439*4882a593Smuzhiyun tile_y_off = pWin->drawable.y - draw_y_off;
440*4882a593Smuzhiyun fill = pWin->background;
441*4882a593Smuzhiyun #ifdef COMPOSITE
442*4882a593Smuzhiyun if (pWin->inhibitBGPaint)
443*4882a593Smuzhiyun return;
444*4882a593Smuzhiyun #endif
445*4882a593Smuzhiyun switch (pWin->backgroundState) {
446*4882a593Smuzhiyun case None:
447*4882a593Smuzhiyun return;
448*4882a593Smuzhiyun case BackgroundPixmap:
449*4882a593Smuzhiyun solid = FALSE;
450*4882a593Smuzhiyun break;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun else {
454*4882a593Smuzhiyun PixmapPtr pixmap;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun fill = pWin->border;
457*4882a593Smuzhiyun solid = pWin->borderIsPixel;
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /* servers without pixmaps draw their own borders */
460*4882a593Smuzhiyun if (!pScreen->GetWindowPixmap)
461*4882a593Smuzhiyun return;
462*4882a593Smuzhiyun pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
463*4882a593Smuzhiyun drawable = &pixmap->drawable;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun while (pWin->backgroundState == ParentRelative)
466*4882a593Smuzhiyun pWin = pWin->parent;
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun tile_x_off = pWin->drawable.x;
469*4882a593Smuzhiyun tile_y_off = pWin->drawable.y;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun #ifdef COMPOSITE
472*4882a593Smuzhiyun draw_x_off = pixmap->screen_x;
473*4882a593Smuzhiyun draw_y_off = pixmap->screen_y;
474*4882a593Smuzhiyun tile_x_off -= draw_x_off;
475*4882a593Smuzhiyun tile_y_off -= draw_y_off;
476*4882a593Smuzhiyun #else
477*4882a593Smuzhiyun draw_x_off = 0;
478*4882a593Smuzhiyun draw_y_off = 0;
479*4882a593Smuzhiyun #endif
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun gcval[0].val = GXcopy;
483*4882a593Smuzhiyun gcmask = GCFunction;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun #ifdef ROOTLESS_SAFEALPHA
486*4882a593Smuzhiyun /* Bit mask for alpha channel with a particular number of bits per
487*4882a593Smuzhiyun * pixel. Note that we only care for 32bpp data. Mac OS X uses planar
488*4882a593Smuzhiyun * alpha for 16bpp.
489*4882a593Smuzhiyun */
490*4882a593Smuzhiyun #define RootlessAlphaMask(bpp) ((bpp) == 32 ? 0xFF000000 : 0)
491*4882a593Smuzhiyun #endif
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (solid) {
494*4882a593Smuzhiyun #ifdef ROOTLESS_SAFEALPHA
495*4882a593Smuzhiyun gcval[1].val =
496*4882a593Smuzhiyun fill.pixel | RootlessAlphaMask(pWin->drawable.bitsPerPixel);
497*4882a593Smuzhiyun #else
498*4882a593Smuzhiyun gcval[1].val = fill.pixel;
499*4882a593Smuzhiyun #endif
500*4882a593Smuzhiyun gcval[2].val = FillSolid;
501*4882a593Smuzhiyun gcmask |= GCForeground | GCFillStyle;
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun else {
504*4882a593Smuzhiyun int c = 1;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun #ifdef ROOTLESS_SAFEALPHA
507*4882a593Smuzhiyun gcval[c++].val =
508*4882a593Smuzhiyun ((CARD32) -1) & ~RootlessAlphaMask(pWin->drawable.bitsPerPixel);
509*4882a593Smuzhiyun gcmask |= GCPlaneMask;
510*4882a593Smuzhiyun #endif
511*4882a593Smuzhiyun gcval[c++].val = FillTiled;
512*4882a593Smuzhiyun gcval[c++].ptr = (void *) fill.pixmap;
513*4882a593Smuzhiyun gcval[c++].val = tile_x_off;
514*4882a593Smuzhiyun gcval[c++].val = tile_y_off;
515*4882a593Smuzhiyun gcmask |= GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun prect = xallocarray(RegionNumRects(prgn), sizeof(xRectangle));
519*4882a593Smuzhiyun if (!prect)
520*4882a593Smuzhiyun return;
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun pGC = GetScratchGC(drawable->depth, drawable->pScreen);
523*4882a593Smuzhiyun if (!pGC) {
524*4882a593Smuzhiyun free(prect);
525*4882a593Smuzhiyun return;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun ChangeGC(NullClient, pGC, gcmask, gcval);
529*4882a593Smuzhiyun ValidateGC(drawable, pGC);
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun numRects = RegionNumRects(prgn);
532*4882a593Smuzhiyun pbox = RegionRects(prgn);
533*4882a593Smuzhiyun for (i = numRects; --i >= 0; pbox++, prect++) {
534*4882a593Smuzhiyun prect->x = pbox->x1 - draw_x_off;
535*4882a593Smuzhiyun prect->y = pbox->y1 - draw_y_off;
536*4882a593Smuzhiyun prect->width = pbox->x2 - pbox->x1;
537*4882a593Smuzhiyun prect->height = pbox->y2 - pbox->y1;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun prect -= numRects;
540*4882a593Smuzhiyun (*pGC->ops->PolyFillRect) (drawable, pGC, numRects, prect);
541*4882a593Smuzhiyun free(prect);
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun FreeScratchGC(pGC);
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun /* MICLEARDRAWABLE -- sets the entire drawable to the background color of
547*4882a593Smuzhiyun * the GC. Useful when we have a scratch drawable and need to initialize
548*4882a593Smuzhiyun * it. */
549*4882a593Smuzhiyun void
miClearDrawable(DrawablePtr pDraw,GCPtr pGC)550*4882a593Smuzhiyun miClearDrawable(DrawablePtr pDraw, GCPtr pGC)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun ChangeGCVal fg, bg;
553*4882a593Smuzhiyun xRectangle rect;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun fg.val = pGC->fgPixel;
556*4882a593Smuzhiyun bg.val = pGC->bgPixel;
557*4882a593Smuzhiyun rect.x = 0;
558*4882a593Smuzhiyun rect.y = 0;
559*4882a593Smuzhiyun rect.width = pDraw->width;
560*4882a593Smuzhiyun rect.height = pDraw->height;
561*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCForeground, &bg);
562*4882a593Smuzhiyun ValidateGC(pDraw, pGC);
563*4882a593Smuzhiyun (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect);
564*4882a593Smuzhiyun ChangeGC(NullClient, pGC, GCForeground, &fg);
565*4882a593Smuzhiyun ValidateGC(pDraw, pGC);
566*4882a593Smuzhiyun }
567