1706f2543Smrg/* 2706f2543Smrg * Copyright © 2004 Eric Anholt 3706f2543Smrg * 4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 6706f2543Smrg * the above copyright notice appear in all copies and that both that 7706f2543Smrg * copyright notice and this permission notice appear in supporting 8706f2543Smrg * documentation, and that the name of Eric Anholt not be used in 9706f2543Smrg * advertising or publicity pertaining to distribution of the software without 10706f2543Smrg * specific, written prior permission. Eric Anholt makes no 11706f2543Smrg * representations about the suitability of this software for any purpose. It 12706f2543Smrg * is provided "as is" without express or implied warranty. 13706f2543Smrg * 14706f2543Smrg * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16706f2543Smrg * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 21706f2543Smrg */ 22706f2543Smrg 23706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 24706f2543Smrg#include <dix-config.h> 25706f2543Smrg#endif 26706f2543Smrg 27706f2543Smrg#include <string.h> 28706f2543Smrg 29706f2543Smrg#include "gcstruct.h" 30706f2543Smrg#include "windowstr.h" 31706f2543Smrg#include "cw.h" 32706f2543Smrg 33706f2543Smrg#define CW_DEBUG 1 34706f2543Smrg 35706f2543Smrg#if CW_DEBUG 36706f2543Smrg#define CW_ASSERT(x) do { \ 37706f2543Smrg if (!(x)) { \ 38706f2543Smrg ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \ 39706f2543Smrg __LINE__); \ 40706f2543Smrg } \ 41706f2543Smrg} while (0) 42706f2543Smrg#else 43706f2543Smrg#define CW_ASSERT(x) do {} while (0) 44706f2543Smrg#endif 45706f2543Smrg 46706f2543SmrgDevPrivateKeyRec cwGCKeyRec; 47706f2543SmrgDevPrivateKeyRec cwScreenKeyRec; 48706f2543SmrgDevPrivateKeyRec cwWindowKeyRec; 49706f2543SmrgDevPrivateKeyRec cwPictureKeyRec; 50706f2543Smrg 51706f2543Smrgextern GCOps cwGCOps; 52706f2543Smrg 53706f2543Smrgstatic Bool 54706f2543SmrgcwCloseScreen (int i, ScreenPtr pScreen); 55706f2543Smrg 56706f2543Smrgstatic void 57706f2543SmrgcwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable); 58706f2543Smrgstatic void 59706f2543SmrgcwChangeGC(GCPtr pGC, unsigned long mask); 60706f2543Smrgstatic void 61706f2543SmrgcwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); 62706f2543Smrgstatic void 63706f2543SmrgcwDestroyGC(GCPtr pGC); 64706f2543Smrgstatic void 65706f2543SmrgcwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); 66706f2543Smrgstatic void 67706f2543SmrgcwCopyClip(GCPtr pgcDst, GCPtr pgcSrc); 68706f2543Smrgstatic void 69706f2543SmrgcwDestroyClip(GCPtr pGC); 70706f2543Smrg 71706f2543SmrgGCFuncs cwGCFuncs = { 72706f2543Smrg cwValidateGC, 73706f2543Smrg cwChangeGC, 74706f2543Smrg cwCopyGC, 75706f2543Smrg cwDestroyGC, 76706f2543Smrg cwChangeClip, 77706f2543Smrg cwDestroyClip, 78706f2543Smrg cwCopyClip, 79706f2543Smrg}; 80706f2543Smrg 81706f2543Smrg/* Find the real drawable to draw to, and provide offsets that will translate 82706f2543Smrg * window coordinates to backing pixmap coordinates. 83706f2543Smrg */ 84706f2543SmrgDrawablePtr 85706f2543SmrgcwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off) 86706f2543Smrg{ 87706f2543Smrg PixmapPtr pPixmap; 88706f2543Smrg 89706f2543Smrg if (pDrawable->type == DRAWABLE_WINDOW && 90706f2543Smrg (pPixmap = getCwPixmap ((WindowPtr) pDrawable))) 91706f2543Smrg { 92706f2543Smrg *x_off = pDrawable->x - pPixmap->screen_x; 93706f2543Smrg *y_off = pDrawable->y - pPixmap->screen_y; 94706f2543Smrg return &pPixmap->drawable; 95706f2543Smrg } else { 96706f2543Smrg *x_off = *y_off = 0; 97706f2543Smrg return pDrawable; 98706f2543Smrg } 99706f2543Smrg} 100706f2543Smrg 101706f2543Smrg#define FUNC_PROLOGUE(pGC, pPriv) do { \ 102706f2543Smrg (pGC)->funcs = (pPriv)->wrapFuncs; \ 103706f2543Smrg (pGC)->ops = (pPriv)->wrapOps; \ 104706f2543Smrg} while (0) 105706f2543Smrg 106706f2543Smrg#define FUNC_EPILOGUE(pGC, pPriv) do { \ 107706f2543Smrg (pPriv)->wrapFuncs = (pGC)->funcs; \ 108706f2543Smrg (pPriv)->wrapOps = (pGC)->ops; \ 109706f2543Smrg (pGC)->funcs = &cwGCFuncs; \ 110706f2543Smrg (pGC)->ops = &cwGCOps; \ 111706f2543Smrg} while (0) 112706f2543Smrg 113706f2543Smrg 114706f2543Smrgstatic Bool 115706f2543SmrgcwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable) 116706f2543Smrg{ 117706f2543Smrg cwGCRec *pPriv = getCwGC(pGC); 118706f2543Smrg int status, x_off, y_off; 119706f2543Smrg XID noexpose = xFalse; 120706f2543Smrg DrawablePtr pBackingDrawable; 121706f2543Smrg 122706f2543Smrg pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); 123706f2543Smrg pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures, 124706f2543Smrg &noexpose, &status, (XID)0, serverClient); 125706f2543Smrg if (status != Success) 126706f2543Smrg return FALSE; 127706f2543Smrg 128706f2543Smrg pPriv->serialNumber = 0; 129706f2543Smrg pPriv->stateChanges = GCAllBits; 130706f2543Smrg 131706f2543Smrg return TRUE; 132706f2543Smrg} 133706f2543Smrg 134706f2543Smrgstatic void 135706f2543SmrgcwDestroyBackingGC(GCPtr pGC) 136706f2543Smrg{ 137706f2543Smrg cwGCPtr pPriv; 138706f2543Smrg 139706f2543Smrg pPriv = (cwGCPtr) getCwGC (pGC); 140706f2543Smrg 141706f2543Smrg if (pPriv->pBackingGC) { 142706f2543Smrg FreeGC(pPriv->pBackingGC, (XID)0); 143706f2543Smrg pPriv->pBackingGC = NULL; 144706f2543Smrg } 145706f2543Smrg} 146706f2543Smrg 147706f2543Smrgstatic void 148706f2543SmrgcwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) 149706f2543Smrg{ 150706f2543Smrg GCPtr pBackingGC; 151706f2543Smrg cwGCPtr pPriv; 152706f2543Smrg DrawablePtr pBackingDrawable; 153706f2543Smrg int x_off, y_off; 154706f2543Smrg 155706f2543Smrg pPriv = (cwGCPtr) getCwGC (pGC); 156706f2543Smrg 157706f2543Smrg FUNC_PROLOGUE(pGC, pPriv); 158706f2543Smrg 159706f2543Smrg /* 160706f2543Smrg * Must call ValidateGC to ensure pGC->pCompositeClip is valid 161706f2543Smrg */ 162706f2543Smrg (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); 163706f2543Smrg 164706f2543Smrg if (!cwDrawableIsRedirWindow(pDrawable)) { 165706f2543Smrg cwDestroyBackingGC(pGC); 166706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 167706f2543Smrg return; 168706f2543Smrg } else { 169706f2543Smrg if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { 170706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 171706f2543Smrg return; 172706f2543Smrg } 173706f2543Smrg } 174706f2543Smrg 175706f2543Smrg pBackingGC = pPriv->pBackingGC; 176706f2543Smrg pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); 177706f2543Smrg 178706f2543Smrg pPriv->stateChanges |= stateChanges; 179706f2543Smrg 180706f2543Smrg /* 181706f2543Smrg * Copy the composite clip into the backing GC if either 182706f2543Smrg * the drawable clip list has changed or the client has changed 183706f2543Smrg * the client clip data 184706f2543Smrg */ 185706f2543Smrg if (pDrawable->serialNumber != pPriv->serialNumber || 186706f2543Smrg (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask))) 187706f2543Smrg { 188706f2543Smrg ChangeGCVal vals[2]; 189706f2543Smrg RegionPtr pCompositeClip; 190706f2543Smrg 191706f2543Smrg pCompositeClip = RegionCreate(NULL, 0); 192706f2543Smrg RegionCopy(pCompositeClip, pGC->pCompositeClip); 193706f2543Smrg 194706f2543Smrg /* Either the drawable has changed, or the clip list in the drawable has 195706f2543Smrg * changed. Copy the new clip list over and set the new translated 196706f2543Smrg * offset for it. 197706f2543Smrg */ 198706f2543Smrg 199706f2543Smrg (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, 200706f2543Smrg (pointer) pCompositeClip, 0); 201706f2543Smrg 202706f2543Smrg vals[0].val = x_off - pDrawable->x; 203706f2543Smrg vals[1].val = y_off - pDrawable->y; 204706f2543Smrg ChangeGC(NullClient, pBackingGC, 205706f2543Smrg (GCClipXOrigin | GCClipYOrigin), vals); 206706f2543Smrg 207706f2543Smrg pPriv->serialNumber = pDrawable->serialNumber; 208706f2543Smrg /* 209706f2543Smrg * Mask off any client clip changes to make sure 210706f2543Smrg * the clip list set above remains in effect 211706f2543Smrg */ 212706f2543Smrg pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask); 213706f2543Smrg } 214706f2543Smrg 215706f2543Smrg if (pPriv->stateChanges) { 216706f2543Smrg CopyGC(pGC, pBackingGC, pPriv->stateChanges); 217706f2543Smrg pPriv->stateChanges = 0; 218706f2543Smrg } 219706f2543Smrg 220706f2543Smrg if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || 221706f2543Smrg (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) 222706f2543Smrg { 223706f2543Smrg ChangeGCVal vals[2]; 224706f2543Smrg vals[0].val = pGC->patOrg.x + x_off; 225706f2543Smrg vals[1].val = pGC->patOrg.y + y_off; 226706f2543Smrg ChangeGC(NullClient, pBackingGC, 227706f2543Smrg (GCTileStipXOrigin | GCTileStipYOrigin), vals); 228706f2543Smrg } 229706f2543Smrg 230706f2543Smrg ValidateGC(pBackingDrawable, pBackingGC); 231706f2543Smrg 232706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 233706f2543Smrg} 234706f2543Smrg 235706f2543Smrgstatic void 236706f2543SmrgcwChangeGC(GCPtr pGC, unsigned long mask) 237706f2543Smrg{ 238706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); 239706f2543Smrg 240706f2543Smrg FUNC_PROLOGUE(pGC, pPriv); 241706f2543Smrg 242706f2543Smrg (*pGC->funcs->ChangeGC) (pGC, mask); 243706f2543Smrg 244706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 245706f2543Smrg} 246706f2543Smrg 247706f2543Smrgstatic void 248706f2543SmrgcwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) 249706f2543Smrg{ 250706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGCDst->devPrivates, cwGCKey); 251706f2543Smrg 252706f2543Smrg FUNC_PROLOGUE(pGCDst, pPriv); 253706f2543Smrg 254706f2543Smrg (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); 255706f2543Smrg 256706f2543Smrg FUNC_EPILOGUE(pGCDst, pPriv); 257706f2543Smrg} 258706f2543Smrg 259706f2543Smrgstatic void 260706f2543SmrgcwDestroyGC(GCPtr pGC) 261706f2543Smrg{ 262706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); 263706f2543Smrg 264706f2543Smrg FUNC_PROLOGUE(pGC, pPriv); 265706f2543Smrg 266706f2543Smrg cwDestroyBackingGC(pGC); 267706f2543Smrg 268706f2543Smrg (*pGC->funcs->DestroyGC) (pGC); 269706f2543Smrg 270706f2543Smrg /* leave it unwrapped */ 271706f2543Smrg} 272706f2543Smrg 273706f2543Smrgstatic void 274706f2543SmrgcwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) 275706f2543Smrg{ 276706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); 277706f2543Smrg 278706f2543Smrg FUNC_PROLOGUE(pGC, pPriv); 279706f2543Smrg 280706f2543Smrg (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects); 281706f2543Smrg 282706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 283706f2543Smrg} 284706f2543Smrg 285706f2543Smrgstatic void 286706f2543SmrgcwCopyClip(GCPtr pgcDst, GCPtr pgcSrc) 287706f2543Smrg{ 288706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pgcDst->devPrivates, cwGCKey); 289706f2543Smrg 290706f2543Smrg FUNC_PROLOGUE(pgcDst, pPriv); 291706f2543Smrg 292706f2543Smrg (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); 293706f2543Smrg 294706f2543Smrg FUNC_EPILOGUE(pgcDst, pPriv); 295706f2543Smrg} 296706f2543Smrg 297706f2543Smrgstatic void 298706f2543SmrgcwDestroyClip(GCPtr pGC) 299706f2543Smrg{ 300706f2543Smrg cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); 301706f2543Smrg 302706f2543Smrg FUNC_PROLOGUE(pGC, pPriv); 303706f2543Smrg 304706f2543Smrg (*pGC->funcs->DestroyClip)(pGC); 305706f2543Smrg 306706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 307706f2543Smrg} 308706f2543Smrg 309706f2543Smrg/* 310706f2543Smrg * Screen wrappers. 311706f2543Smrg */ 312706f2543Smrg 313706f2543Smrg#define SCREEN_PROLOGUE(pScreen, field) \ 314706f2543Smrg ((pScreen)->field = getCwScreen(pScreen)->field) 315706f2543Smrg 316706f2543Smrg#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \ 317706f2543Smrg getCwScreen(pScreen)->field = (pScreen)->field; \ 318706f2543Smrg (pScreen)->field = (wrapper); \ 319706f2543Smrg} while (0) 320706f2543Smrg 321706f2543Smrgstatic Bool 322706f2543SmrgcwCreateGC(GCPtr pGC) 323706f2543Smrg{ 324706f2543Smrg cwGCPtr pPriv = getCwGC(pGC); 325706f2543Smrg ScreenPtr pScreen = pGC->pScreen; 326706f2543Smrg Bool ret; 327706f2543Smrg 328706f2543Smrg SCREEN_PROLOGUE(pScreen, CreateGC); 329706f2543Smrg 330706f2543Smrg if ( (ret = (*pScreen->CreateGC)(pGC)) ) 331706f2543Smrg FUNC_EPILOGUE(pGC, pPriv); 332706f2543Smrg 333706f2543Smrg SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); 334706f2543Smrg 335706f2543Smrg return ret; 336706f2543Smrg} 337706f2543Smrg 338706f2543Smrgstatic void 339706f2543SmrgcwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format, 340706f2543Smrg unsigned long planemask, char *pdstLine) 341706f2543Smrg{ 342706f2543Smrg ScreenPtr pScreen = pSrc->pScreen; 343706f2543Smrg DrawablePtr pBackingDrawable; 344706f2543Smrg int src_off_x, src_off_y; 345706f2543Smrg 346706f2543Smrg SCREEN_PROLOGUE(pScreen, GetImage); 347706f2543Smrg 348706f2543Smrg pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); 349706f2543Smrg 350706f2543Smrg CW_OFFSET_XY_SRC(x, y); 351706f2543Smrg 352706f2543Smrg (*pScreen->GetImage)(pBackingDrawable, x, y, w, h, format, planemask, 353706f2543Smrg pdstLine); 354706f2543Smrg 355706f2543Smrg SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); 356706f2543Smrg} 357706f2543Smrg 358706f2543Smrgstatic void 359706f2543SmrgcwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth, 360706f2543Smrg int nspans, char *pdstStart) 361706f2543Smrg{ 362706f2543Smrg ScreenPtr pScreen = pSrc->pScreen; 363706f2543Smrg DrawablePtr pBackingDrawable; 364706f2543Smrg int i; 365706f2543Smrg int src_off_x, src_off_y; 366706f2543Smrg 367706f2543Smrg SCREEN_PROLOGUE(pScreen, GetSpans); 368706f2543Smrg 369706f2543Smrg pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); 370706f2543Smrg 371706f2543Smrg for (i = 0; i < nspans; i++) 372706f2543Smrg CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y); 373706f2543Smrg 374706f2543Smrg (*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans, 375706f2543Smrg pdstStart); 376706f2543Smrg 377706f2543Smrg SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); 378706f2543Smrg} 379706f2543Smrg 380706f2543Smrg 381706f2543Smrgstatic void 382706f2543SmrgcwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) 383706f2543Smrg{ 384706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 385706f2543Smrg 386706f2543Smrg SCREEN_PROLOGUE(pScreen, CopyWindow); 387706f2543Smrg 388706f2543Smrg if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { 389706f2543Smrg (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); 390706f2543Smrg } else { 391706f2543Smrg GCPtr pGC; 392706f2543Smrg BoxPtr pExtents; 393706f2543Smrg int x_off, y_off; 394706f2543Smrg int dx, dy; 395706f2543Smrg PixmapPtr pBackingPixmap; 396706f2543Smrg RegionPtr pClip; 397706f2543Smrg int src_x, src_y, dst_x, dst_y, w, h; 398706f2543Smrg 399706f2543Smrg dx = ptOldOrg.x - pWin->drawable.x; 400706f2543Smrg dy = ptOldOrg.y - pWin->drawable.y; 401706f2543Smrg 402706f2543Smrg pExtents = RegionExtents(prgnSrc); 403706f2543Smrg 404706f2543Smrg pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin, 405706f2543Smrg &x_off, &y_off); 406706f2543Smrg 407706f2543Smrg src_x = pExtents->x1 - pBackingPixmap->screen_x; 408706f2543Smrg src_y = pExtents->y1 - pBackingPixmap->screen_y; 409706f2543Smrg w = pExtents->x2 - pExtents->x1; 410706f2543Smrg h = pExtents->y2 - pExtents->y1; 411706f2543Smrg dst_x = src_x - dx; 412706f2543Smrg dst_y = src_y - dy; 413706f2543Smrg 414706f2543Smrg /* Translate region (as required by API) */ 415706f2543Smrg RegionTranslate(prgnSrc, -dx, -dy); 416706f2543Smrg 417706f2543Smrg pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); 418706f2543Smrg /* 419706f2543Smrg * Copy region to GC as clip, aligning as dest clip 420706f2543Smrg */ 421706f2543Smrg pClip = RegionCreate(NULL, 0); 422706f2543Smrg RegionIntersect(pClip, &pWin->borderClip, prgnSrc); 423706f2543Smrg RegionTranslate(pClip, 424706f2543Smrg -pBackingPixmap->screen_x, 425706f2543Smrg -pBackingPixmap->screen_y); 426706f2543Smrg 427706f2543Smrg (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); 428706f2543Smrg 429706f2543Smrg ValidateGC(&pBackingPixmap->drawable, pGC); 430706f2543Smrg 431706f2543Smrg (*pGC->ops->CopyArea) (&pBackingPixmap->drawable, 432706f2543Smrg &pBackingPixmap->drawable, pGC, 433706f2543Smrg src_x, src_y, w, h, dst_x, dst_y); 434706f2543Smrg 435706f2543Smrg (*pGC->funcs->DestroyClip) (pGC); 436706f2543Smrg 437706f2543Smrg FreeScratchGC(pGC); 438706f2543Smrg } 439706f2543Smrg 440706f2543Smrg SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); 441706f2543Smrg} 442706f2543Smrg 443706f2543Smrgstatic PixmapPtr 444706f2543SmrgcwGetWindowPixmap (WindowPtr pWin) 445706f2543Smrg{ 446706f2543Smrg PixmapPtr pPixmap = getCwPixmap (pWin); 447706f2543Smrg 448706f2543Smrg if (!pPixmap) 449706f2543Smrg { 450706f2543Smrg ScreenPtr pScreen = pWin->drawable.pScreen; 451706f2543Smrg SCREEN_PROLOGUE(pScreen, GetWindowPixmap); 452706f2543Smrg if (pScreen->GetWindowPixmap) 453706f2543Smrg pPixmap = (*pScreen->GetWindowPixmap) (pWin); 454706f2543Smrg SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); 455706f2543Smrg } 456706f2543Smrg return pPixmap; 457706f2543Smrg} 458706f2543Smrg 459706f2543Smrgstatic void 460706f2543SmrgcwSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) 461706f2543Smrg{ 462706f2543Smrg ScreenPtr pScreen = pWindow->drawable.pScreen; 463706f2543Smrg 464706f2543Smrg if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen)) 465706f2543Smrg pPixmap = NULL; 466706f2543Smrg setCwPixmap (pWindow, pPixmap); 467706f2543Smrg} 468706f2543Smrg 469706f2543Smrg/* Screen initialization/teardown */ 470706f2543Smrgvoid 471706f2543SmrgmiInitializeCompositeWrapper(ScreenPtr pScreen) 472706f2543Smrg{ 473706f2543Smrg cwScreenPtr pScreenPriv; 474706f2543Smrg Bool has_render = GetPictureScreenIfSet(pScreen) != NULL; 475706f2543Smrg 476706f2543Smrg if (!dixRegisterPrivateKey(&cwScreenKeyRec, PRIVATE_SCREEN, 0)) 477706f2543Smrg return; 478706f2543Smrg 479706f2543Smrg if (!dixRegisterPrivateKey(&cwGCKeyRec, PRIVATE_GC, sizeof(cwGCRec))) 480706f2543Smrg return; 481706f2543Smrg 482706f2543Smrg if (!dixRegisterPrivateKey(&cwWindowKeyRec, PRIVATE_WINDOW, 0)) 483706f2543Smrg return; 484706f2543Smrg 485706f2543Smrg if (!dixRegisterPrivateKey(&cwPictureKeyRec, PRIVATE_PICTURE, 0)) 486706f2543Smrg return; 487706f2543Smrg 488706f2543Smrg pScreenPriv = malloc(sizeof(cwScreenRec)); 489706f2543Smrg if (!pScreenPriv) 490706f2543Smrg return; 491706f2543Smrg 492706f2543Smrg dixSetPrivate(&pScreen->devPrivates, cwScreenKey, pScreenPriv); 493706f2543Smrg 494706f2543Smrg SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen); 495706f2543Smrg SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); 496706f2543Smrg SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); 497706f2543Smrg SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); 498706f2543Smrg SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); 499706f2543Smrg 500706f2543Smrg SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap); 501706f2543Smrg SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); 502706f2543Smrg 503706f2543Smrg if (has_render) 504706f2543Smrg cwInitializeRender(pScreen); 505706f2543Smrg} 506706f2543Smrg 507706f2543Smrgstatic Bool 508706f2543SmrgcwCloseScreen (int i, ScreenPtr pScreen) 509706f2543Smrg{ 510706f2543Smrg cwScreenPtr pScreenPriv; 511706f2543Smrg PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); 512706f2543Smrg 513706f2543Smrg pScreenPriv = (cwScreenPtr)dixLookupPrivate(&pScreen->devPrivates, 514706f2543Smrg cwScreenKey); 515706f2543Smrg pScreen->CloseScreen = pScreenPriv->CloseScreen; 516706f2543Smrg pScreen->GetImage = pScreenPriv->GetImage; 517706f2543Smrg pScreen->GetSpans = pScreenPriv->GetSpans; 518706f2543Smrg pScreen->CreateGC = pScreenPriv->CreateGC; 519706f2543Smrg pScreen->CopyWindow = pScreenPriv->CopyWindow; 520706f2543Smrg 521706f2543Smrg if (ps) 522706f2543Smrg cwFiniRender(pScreen); 523706f2543Smrg 524706f2543Smrg free((pointer)pScreenPriv); 525706f2543Smrg 526706f2543Smrg return (*pScreen->CloseScreen)(i, pScreen); 527706f2543Smrg} 528