1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1993, 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
12*4882a593Smuzhiyun in all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
24*4882a593Smuzhiyun other dealings in this Software without prior written authorization
25*4882a593Smuzhiyun from The Open Group.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
30*4882a593Smuzhiyun #include <dix-config.h>
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #include "scrnintstr.h"
34*4882a593Smuzhiyun #include "gcstruct.h"
35*4882a593Smuzhiyun #include "pixmapstr.h"
36*4882a593Smuzhiyun #include "windowstr.h"
37*4882a593Smuzhiyun #include "migc.h"
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* ARGSUSED */
40*4882a593Smuzhiyun void
miChangeGC(GCPtr pGC,unsigned long mask)41*4882a593Smuzhiyun miChangeGC(GCPtr pGC, unsigned long mask)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun return;
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun void
miDestroyGC(GCPtr pGC)47*4882a593Smuzhiyun miDestroyGC(GCPtr pGC)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun if (pGC->freeCompClip)
50*4882a593Smuzhiyun RegionDestroy(pGC->pCompositeClip);
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun void
miDestroyClip(GCPtr pGC)54*4882a593Smuzhiyun miDestroyClip(GCPtr pGC)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun if (pGC->clientClip)
57*4882a593Smuzhiyun RegionDestroy(pGC->clientClip);
58*4882a593Smuzhiyun pGC->clientClip = NULL;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun void
miChangeClip(GCPtr pGC,int type,void * pvalue,int nrects)62*4882a593Smuzhiyun miChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun (*pGC->funcs->DestroyClip) (pGC);
65*4882a593Smuzhiyun if (type == CT_PIXMAP) {
66*4882a593Smuzhiyun /* convert the pixmap to a region */
67*4882a593Smuzhiyun pGC->clientClip = BitmapToRegion(pGC->pScreen, (PixmapPtr) pvalue);
68*4882a593Smuzhiyun (*pGC->pScreen->DestroyPixmap) (pvalue);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun else if (type == CT_REGION) {
71*4882a593Smuzhiyun /* stuff the region in the GC */
72*4882a593Smuzhiyun pGC->clientClip = pvalue;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun else if (type != CT_NONE) {
75*4882a593Smuzhiyun pGC->clientClip = RegionFromRects(nrects, (xRectangle *) pvalue, type);
76*4882a593Smuzhiyun free(pvalue);
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun pGC->stateChanges |= GCClipMask;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun void
miCopyClip(GCPtr pgcDst,GCPtr pgcSrc)82*4882a593Smuzhiyun miCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
83*4882a593Smuzhiyun {
84*4882a593Smuzhiyun if (pgcSrc->clientClip) {
85*4882a593Smuzhiyun RegionPtr prgnNew = RegionCreate(NULL, 1);
86*4882a593Smuzhiyun RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip));
87*4882a593Smuzhiyun (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, prgnNew, 0);
88*4882a593Smuzhiyun } else {
89*4882a593Smuzhiyun (*pgcDst->funcs->ChangeClip) (pgcDst, CT_NONE, NULL, 0);
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* ARGSUSED */
94*4882a593Smuzhiyun void
miCopyGC(GCPtr pGCSrc,unsigned long changes,GCPtr pGCDst)95*4882a593Smuzhiyun miCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun return;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun void
miComputeCompositeClip(GCPtr pGC,DrawablePtr pDrawable)101*4882a593Smuzhiyun miComputeCompositeClip(GCPtr pGC, DrawablePtr pDrawable)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun if (pDrawable->type == DRAWABLE_WINDOW) {
104*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDrawable;
105*4882a593Smuzhiyun RegionPtr pregWin;
106*4882a593Smuzhiyun Bool freeTmpClip, freeCompClip;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun if (pGC->subWindowMode == IncludeInferiors) {
109*4882a593Smuzhiyun pregWin = NotClippedByChildren(pWin);
110*4882a593Smuzhiyun freeTmpClip = TRUE;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun else {
113*4882a593Smuzhiyun pregWin = &pWin->clipList;
114*4882a593Smuzhiyun freeTmpClip = FALSE;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun freeCompClip = pGC->freeCompClip;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /*
119*4882a593Smuzhiyun * if there is no client clip, we can get by with just keeping the
120*4882a593Smuzhiyun * pointer we got, and remembering whether or not should destroy (or
121*4882a593Smuzhiyun * maybe re-use) it later. this way, we avoid unnecessary copying of
122*4882a593Smuzhiyun * regions. (this wins especially if many clients clip by children
123*4882a593Smuzhiyun * and have no client clip.)
124*4882a593Smuzhiyun */
125*4882a593Smuzhiyun if (!pGC->clientClip) {
126*4882a593Smuzhiyun if (freeCompClip)
127*4882a593Smuzhiyun RegionDestroy(pGC->pCompositeClip);
128*4882a593Smuzhiyun pGC->pCompositeClip = pregWin;
129*4882a593Smuzhiyun pGC->freeCompClip = freeTmpClip;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun else {
132*4882a593Smuzhiyun /*
133*4882a593Smuzhiyun * we need one 'real' region to put into the composite clip. if
134*4882a593Smuzhiyun * pregWin the current composite clip are real, we can get rid of
135*4882a593Smuzhiyun * one. if pregWin is real and the current composite clip isn't,
136*4882a593Smuzhiyun * use pregWin for the composite clip. if the current composite
137*4882a593Smuzhiyun * clip is real and pregWin isn't, use the current composite
138*4882a593Smuzhiyun * clip. if neither is real, create a new region.
139*4882a593Smuzhiyun */
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun RegionTranslate(pGC->clientClip,
142*4882a593Smuzhiyun pDrawable->x + pGC->clipOrg.x,
143*4882a593Smuzhiyun pDrawable->y + pGC->clipOrg.y);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun if (freeCompClip) {
146*4882a593Smuzhiyun RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
147*4882a593Smuzhiyun if (freeTmpClip)
148*4882a593Smuzhiyun RegionDestroy(pregWin);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun else if (freeTmpClip) {
151*4882a593Smuzhiyun RegionIntersect(pregWin, pregWin, pGC->clientClip);
152*4882a593Smuzhiyun pGC->pCompositeClip = pregWin;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun else {
155*4882a593Smuzhiyun pGC->pCompositeClip = RegionCreate(NullBox, 0);
156*4882a593Smuzhiyun RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun pGC->freeCompClip = TRUE;
159*4882a593Smuzhiyun RegionTranslate(pGC->clientClip,
160*4882a593Smuzhiyun -(pDrawable->x + pGC->clipOrg.x),
161*4882a593Smuzhiyun -(pDrawable->y + pGC->clipOrg.y));
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun } /* end of composite clip for a window */
164*4882a593Smuzhiyun else {
165*4882a593Smuzhiyun BoxRec pixbounds;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /* XXX should we translate by drawable.x/y here ? */
168*4882a593Smuzhiyun /* If you want pixmaps in offscreen memory, yes */
169*4882a593Smuzhiyun pixbounds.x1 = pDrawable->x;
170*4882a593Smuzhiyun pixbounds.y1 = pDrawable->y;
171*4882a593Smuzhiyun pixbounds.x2 = pDrawable->x + pDrawable->width;
172*4882a593Smuzhiyun pixbounds.y2 = pDrawable->y + pDrawable->height;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun if (pGC->freeCompClip) {
175*4882a593Smuzhiyun RegionReset(pGC->pCompositeClip, &pixbounds);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun else {
178*4882a593Smuzhiyun pGC->freeCompClip = TRUE;
179*4882a593Smuzhiyun pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun if (pGC->clientClip) {
183*4882a593Smuzhiyun if (pDrawable->x || pDrawable->y) {
184*4882a593Smuzhiyun RegionTranslate(pGC->clientClip,
185*4882a593Smuzhiyun pDrawable->x + pGC->clipOrg.x,
186*4882a593Smuzhiyun pDrawable->y + pGC->clipOrg.y);
187*4882a593Smuzhiyun RegionIntersect(pGC->pCompositeClip,
188*4882a593Smuzhiyun pGC->pCompositeClip, pGC->clientClip);
189*4882a593Smuzhiyun RegionTranslate(pGC->clientClip,
190*4882a593Smuzhiyun -(pDrawable->x + pGC->clipOrg.x),
191*4882a593Smuzhiyun -(pDrawable->y + pGC->clipOrg.y));
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun else {
194*4882a593Smuzhiyun RegionTranslate(pGC->pCompositeClip,
195*4882a593Smuzhiyun -pGC->clipOrg.x, -pGC->clipOrg.y);
196*4882a593Smuzhiyun RegionIntersect(pGC->pCompositeClip,
197*4882a593Smuzhiyun pGC->pCompositeClip, pGC->clientClip);
198*4882a593Smuzhiyun RegionTranslate(pGC->pCompositeClip,
199*4882a593Smuzhiyun pGC->clipOrg.x, pGC->clipOrg.y);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun } /* end of composite clip for pixmap */
203*4882a593Smuzhiyun } /* end miComputeCompositeClip */
204