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