1706f2543Smrg/*
2706f2543Smrg
3706f2543SmrgCopyright 1993, 1998  The Open Group
4706f2543Smrg
5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software and its
6706f2543Smrgdocumentation for any purpose is hereby granted without fee, provided that
7706f2543Smrgthe above copyright notice appear in all copies and that both that
8706f2543Smrgcopyright notice and this permission notice appear in supporting
9706f2543Smrgdocumentation.
10706f2543Smrg
11706f2543SmrgThe above copyright notice and this permission notice shall be included
12706f2543Smrgin all copies or substantial portions of the Software.
13706f2543Smrg
14706f2543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15706f2543SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16706f2543SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17706f2543SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18706f2543SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19706f2543SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20706f2543SmrgOTHER DEALINGS IN THE SOFTWARE.
21706f2543Smrg
22706f2543SmrgExcept as contained in this notice, the name of The Open Group shall
23706f2543Smrgnot be used in advertising or otherwise to promote the sale, use or
24706f2543Smrgother dealings in this Software without prior written authorization
25706f2543Smrgfrom The Open Group.
26706f2543Smrg
27706f2543Smrg*/
28706f2543Smrg
29706f2543Smrg
30706f2543Smrg#ifdef HAVE_DIX_CONFIG_H
31706f2543Smrg#include <dix-config.h>
32706f2543Smrg#endif
33706f2543Smrg
34706f2543Smrg#include "scrnintstr.h"
35706f2543Smrg#include "gcstruct.h"
36706f2543Smrg#include "pixmapstr.h"
37706f2543Smrg#include "windowstr.h"
38706f2543Smrg#include "migc.h"
39706f2543Smrg
40706f2543Smrg/* ARGSUSED */
41706f2543Smrgvoid
42706f2543SmrgmiChangeGC(GCPtr pGC, unsigned long mask)
43706f2543Smrg{
44706f2543Smrg    return;
45706f2543Smrg}
46706f2543Smrg
47706f2543Smrgvoid
48706f2543SmrgmiDestroyGC(GCPtr pGC)
49706f2543Smrg{
50706f2543Smrg    if (pGC->pRotatedPixmap)
51706f2543Smrg	(*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
52706f2543Smrg    if (pGC->freeCompClip)
53706f2543Smrg	RegionDestroy(pGC->pCompositeClip);
54706f2543Smrg}
55706f2543Smrg
56706f2543Smrgvoid
57706f2543SmrgmiDestroyClip(GCPtr pGC)
58706f2543Smrg{
59706f2543Smrg    if (pGC->clientClipType == CT_NONE)
60706f2543Smrg	return;
61706f2543Smrg    else if (pGC->clientClipType == CT_PIXMAP)
62706f2543Smrg    {
63706f2543Smrg	(*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
64706f2543Smrg    }
65706f2543Smrg    else
66706f2543Smrg    {
67706f2543Smrg	/*
68706f2543Smrg	 * we know we'll never have a list of rectangles, since ChangeClip
69706f2543Smrg	 * immediately turns them into a region
70706f2543Smrg	 */
71706f2543Smrg	RegionDestroy(pGC->clientClip);
72706f2543Smrg    }
73706f2543Smrg    pGC->clientClip = NULL;
74706f2543Smrg    pGC->clientClipType = CT_NONE;
75706f2543Smrg}
76706f2543Smrg
77706f2543Smrgvoid
78706f2543SmrgmiChangeClip( GCPtr pGC, int type, pointer pvalue, int nrects)
79706f2543Smrg{
80706f2543Smrg    (*pGC->funcs->DestroyClip) (pGC);
81706f2543Smrg    if (type == CT_PIXMAP)
82706f2543Smrg    {
83706f2543Smrg	/* convert the pixmap to a region */
84706f2543Smrg	pGC->clientClip = (pointer) BitmapToRegion(pGC->pScreen,
85706f2543Smrg							(PixmapPtr) pvalue);
86706f2543Smrg	(*pGC->pScreen->DestroyPixmap) (pvalue);
87706f2543Smrg    }
88706f2543Smrg    else if (type == CT_REGION)
89706f2543Smrg    {
90706f2543Smrg	/* stuff the region in the GC */
91706f2543Smrg	pGC->clientClip = pvalue;
92706f2543Smrg    }
93706f2543Smrg    else if (type != CT_NONE)
94706f2543Smrg    {
95706f2543Smrg	pGC->clientClip = (pointer) RegionFromRects(nrects,
96706f2543Smrg						      (xRectangle *) pvalue,
97706f2543Smrg								    type);
98706f2543Smrg	free(pvalue);
99706f2543Smrg    }
100706f2543Smrg    pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
101706f2543Smrg    pGC->stateChanges |= GCClipMask;
102706f2543Smrg}
103706f2543Smrg
104706f2543Smrgvoid
105706f2543SmrgmiCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
106706f2543Smrg{
107706f2543Smrg    RegionPtr       prgnNew;
108706f2543Smrg
109706f2543Smrg    switch (pgcSrc->clientClipType)
110706f2543Smrg    {
111706f2543Smrg      case CT_PIXMAP:
112706f2543Smrg	((PixmapPtr) pgcSrc->clientClip)->refcnt++;
113706f2543Smrg	/* Fall through !! */
114706f2543Smrg      case CT_NONE:
115706f2543Smrg	(*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
116706f2543Smrg				   pgcSrc->clientClip, 0);
117706f2543Smrg	break;
118706f2543Smrg      case CT_REGION:
119706f2543Smrg	prgnNew = RegionCreate(NULL, 1);
120706f2543Smrg	RegionCopy(prgnNew, (RegionPtr) (pgcSrc->clientClip));
121706f2543Smrg	(*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
122706f2543Smrg	break;
123706f2543Smrg    }
124706f2543Smrg}
125706f2543Smrg
126706f2543Smrg/* ARGSUSED */
127706f2543Smrgvoid
128706f2543SmrgmiCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
129706f2543Smrg{
130706f2543Smrg    return;
131706f2543Smrg}
132706f2543Smrg
133706f2543Smrgvoid
134706f2543SmrgmiComputeCompositeClip( GCPtr pGC, DrawablePtr pDrawable)
135706f2543Smrg{
136706f2543Smrg    if (pDrawable->type == DRAWABLE_WINDOW)
137706f2543Smrg    {
138706f2543Smrg	WindowPtr       pWin = (WindowPtr) pDrawable;
139706f2543Smrg	RegionPtr       pregWin;
140706f2543Smrg	Bool            freeTmpClip, freeCompClip;
141706f2543Smrg
142706f2543Smrg	if (pGC->subWindowMode == IncludeInferiors)
143706f2543Smrg	{
144706f2543Smrg	    pregWin = NotClippedByChildren(pWin);
145706f2543Smrg	    freeTmpClip = TRUE;
146706f2543Smrg	}
147706f2543Smrg	else
148706f2543Smrg	{
149706f2543Smrg	    pregWin = &pWin->clipList;
150706f2543Smrg	    freeTmpClip = FALSE;
151706f2543Smrg	}
152706f2543Smrg	freeCompClip = pGC->freeCompClip;
153706f2543Smrg
154706f2543Smrg	/*
155706f2543Smrg	 * if there is no client clip, we can get by with just keeping the
156706f2543Smrg	 * pointer we got, and remembering whether or not should destroy (or
157706f2543Smrg	 * maybe re-use) it later.  this way, we avoid unnecessary copying of
158706f2543Smrg	 * regions.  (this wins especially if many clients clip by children
159706f2543Smrg	 * and have no client clip.)
160706f2543Smrg	 */
161706f2543Smrg	if (pGC->clientClipType == CT_NONE)
162706f2543Smrg	{
163706f2543Smrg	    if (freeCompClip)
164706f2543Smrg		RegionDestroy(pGC->pCompositeClip);
165706f2543Smrg	    pGC->pCompositeClip = pregWin;
166706f2543Smrg	    pGC->freeCompClip = freeTmpClip;
167706f2543Smrg	}
168706f2543Smrg	else
169706f2543Smrg	{
170706f2543Smrg	    /*
171706f2543Smrg	     * we need one 'real' region to put into the composite clip. if
172706f2543Smrg	     * pregWin the current composite clip are real, we can get rid of
173706f2543Smrg	     * one. if pregWin is real and the current composite clip isn't,
174706f2543Smrg	     * use pregWin for the composite clip. if the current composite
175706f2543Smrg	     * clip is real and pregWin isn't, use the current composite
176706f2543Smrg	     * clip. if neither is real, create a new region.
177706f2543Smrg	     */
178706f2543Smrg
179706f2543Smrg	    RegionTranslate(pGC->clientClip,
180706f2543Smrg					 pDrawable->x + pGC->clipOrg.x,
181706f2543Smrg					 pDrawable->y + pGC->clipOrg.y);
182706f2543Smrg
183706f2543Smrg	    if (freeCompClip)
184706f2543Smrg	    {
185706f2543Smrg		RegionIntersect(pGC->pCompositeClip,
186706f2543Smrg					    pregWin, pGC->clientClip);
187706f2543Smrg		if (freeTmpClip)
188706f2543Smrg		    RegionDestroy(pregWin);
189706f2543Smrg	    }
190706f2543Smrg	    else if (freeTmpClip)
191706f2543Smrg	    {
192706f2543Smrg		RegionIntersect(pregWin, pregWin, pGC->clientClip);
193706f2543Smrg		pGC->pCompositeClip = pregWin;
194706f2543Smrg	    }
195706f2543Smrg	    else
196706f2543Smrg	    {
197706f2543Smrg		pGC->pCompositeClip = RegionCreate(NullBox, 0);
198706f2543Smrg		RegionIntersect(pGC->pCompositeClip,
199706f2543Smrg				       pregWin, pGC->clientClip);
200706f2543Smrg	    }
201706f2543Smrg	    pGC->freeCompClip = TRUE;
202706f2543Smrg	    RegionTranslate(pGC->clientClip,
203706f2543Smrg					 -(pDrawable->x + pGC->clipOrg.x),
204706f2543Smrg					 -(pDrawable->y + pGC->clipOrg.y));
205706f2543Smrg	}
206706f2543Smrg    }	/* end of composite clip for a window */
207706f2543Smrg    else
208706f2543Smrg    {
209706f2543Smrg	BoxRec          pixbounds;
210706f2543Smrg
211706f2543Smrg	/* XXX should we translate by drawable.x/y here ? */
212706f2543Smrg	/* If you want pixmaps in offscreen memory, yes */
213706f2543Smrg	pixbounds.x1 = pDrawable->x;
214706f2543Smrg	pixbounds.y1 = pDrawable->y;
215706f2543Smrg	pixbounds.x2 = pDrawable->x + pDrawable->width;
216706f2543Smrg	pixbounds.y2 = pDrawable->y + pDrawable->height;
217706f2543Smrg
218706f2543Smrg	if (pGC->freeCompClip)
219706f2543Smrg	{
220706f2543Smrg	    RegionReset(pGC->pCompositeClip, &pixbounds);
221706f2543Smrg	}
222706f2543Smrg	else
223706f2543Smrg	{
224706f2543Smrg	    pGC->freeCompClip = TRUE;
225706f2543Smrg	    pGC->pCompositeClip = RegionCreate(&pixbounds, 1);
226706f2543Smrg	}
227706f2543Smrg
228706f2543Smrg	if (pGC->clientClipType == CT_REGION)
229706f2543Smrg	{
230706f2543Smrg	    if(pDrawable->x || pDrawable->y) {
231706f2543Smrg	        RegionTranslate(pGC->clientClip,
232706f2543Smrg					  pDrawable->x + pGC->clipOrg.x,
233706f2543Smrg					  pDrawable->y + pGC->clipOrg.y);
234706f2543Smrg	        RegionIntersect(pGC->pCompositeClip,
235706f2543Smrg				pGC->pCompositeClip, pGC->clientClip);
236706f2543Smrg	        RegionTranslate(pGC->clientClip,
237706f2543Smrg					  -(pDrawable->x + pGC->clipOrg.x),
238706f2543Smrg					  -(pDrawable->y + pGC->clipOrg.y));
239706f2543Smrg	    } else {
240706f2543Smrg	        RegionTranslate(pGC->pCompositeClip,
241706f2543Smrg					 -pGC->clipOrg.x, -pGC->clipOrg.y);
242706f2543Smrg	        RegionIntersect(pGC->pCompositeClip,
243706f2543Smrg				pGC->pCompositeClip, pGC->clientClip);
244706f2543Smrg	        RegionTranslate(pGC->pCompositeClip,
245706f2543Smrg					 pGC->clipOrg.x, pGC->clipOrg.y);
246706f2543Smrg	    }
247706f2543Smrg	}
248706f2543Smrg    }	/* end of composite clip for pixmap */
249706f2543Smrg} /* end miComputeCompositeClip */
250