From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/miext/cw/cw.c | 1044 +++++++++++++++++++------------------- xorg-server/miext/cw/cw_render.c | 938 +++++++++++++++++----------------- 2 files changed, 991 insertions(+), 991 deletions(-) (limited to 'xorg-server/miext/cw') diff --git a/xorg-server/miext/cw/cw.c b/xorg-server/miext/cw/cw.c index 247cb83e1..72a90c699 100644 --- a/xorg-server/miext/cw/cw.c +++ b/xorg-server/miext/cw/cw.c @@ -1,522 +1,522 @@ -/* - * Copyright © 2004 Eric Anholt - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Eric Anholt not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Eric Anholt makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include "gcstruct.h" -#include "windowstr.h" -#include "cw.h" - -#define CW_DEBUG 1 - -#if CW_DEBUG -#define CW_ASSERT(x) do { \ - if (!(x)) { \ - ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \ - __LINE__); \ - } \ -} while (0) -#else -#define CW_ASSERT(x) do {} while (0) -#endif - -static int cwGCKeyIndex; -DevPrivateKey cwGCKey = &cwGCKeyIndex; -static int cwScreenKeyIndex; -DevPrivateKey cwScreenKey = &cwScreenKeyIndex; -static int cwWindowKeyIndex; -DevPrivateKey cwWindowKey = &cwWindowKeyIndex; -static int cwPictureKeyIndex; -DevPrivateKey cwPictureKey = &cwPictureKeyIndex; -extern GCOps cwGCOps; - -static Bool -cwCloseScreen (int i, ScreenPtr pScreen); - -static void -cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable); -static void -cwChangeGC(GCPtr pGC, unsigned long mask); -static void -cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); -static void -cwDestroyGC(GCPtr pGC); -static void -cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); -static void -cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc); -static void -cwDestroyClip(GCPtr pGC); - -GCFuncs cwGCFuncs = { - cwValidateGC, - cwChangeGC, - cwCopyGC, - cwDestroyGC, - cwChangeClip, - cwDestroyClip, - cwCopyClip, -}; - -/* Find the real drawable to draw to, and provide offsets that will translate - * window coordinates to backing pixmap coordinates. - */ -DrawablePtr -cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off) -{ - PixmapPtr pPixmap; - - if (pDrawable->type == DRAWABLE_WINDOW && - (pPixmap = getCwPixmap ((WindowPtr) pDrawable))) - { - *x_off = pDrawable->x - pPixmap->screen_x; - *y_off = pDrawable->y - pPixmap->screen_y; - return &pPixmap->drawable; - } else { - *x_off = *y_off = 0; - return pDrawable; - } -} - -#define FUNC_PROLOGUE(pGC, pPriv) do { \ - (pGC)->funcs = (pPriv)->wrapFuncs; \ - (pGC)->ops = (pPriv)->wrapOps; \ -} while (0) - -#define FUNC_EPILOGUE(pGC, pPriv) do { \ - (pPriv)->wrapFuncs = (pGC)->funcs; \ - (pPriv)->wrapOps = (pGC)->ops; \ - (pGC)->funcs = &cwGCFuncs; \ - (pGC)->ops = &cwGCOps; \ -} while (0) - - -static Bool -cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable) -{ - cwGCRec *pPriv = getCwGC(pGC); - int status, x_off, y_off; - XID noexpose = xFalse; - DrawablePtr pBackingDrawable; - - pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); - pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures, - &noexpose, &status, (XID)0, serverClient); - if (status != Success) - return FALSE; - - pPriv->serialNumber = 0; - pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1; - - return TRUE; -} - -static void -cwDestroyBackingGC(GCPtr pGC) -{ - cwGCPtr pPriv; - - pPriv = (cwGCPtr) getCwGC (pGC); - - if (pPriv->pBackingGC) { - FreeGC(pPriv->pBackingGC, (XID)0); - pPriv->pBackingGC = NULL; - } -} - -static void -cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) -{ - GCPtr pBackingGC; - cwGCPtr pPriv; - DrawablePtr pBackingDrawable; - int x_off, y_off; - - pPriv = (cwGCPtr) getCwGC (pGC); - - FUNC_PROLOGUE(pGC, pPriv); - - /* - * Must call ValidateGC to ensure pGC->pCompositeClip is valid - */ - (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); - - if (!cwDrawableIsRedirWindow(pDrawable)) { - cwDestroyBackingGC(pGC); - FUNC_EPILOGUE(pGC, pPriv); - return; - } else { - if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { - FUNC_EPILOGUE(pGC, pPriv); - return; - } - } - - pBackingGC = pPriv->pBackingGC; - pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); - - pPriv->stateChanges |= stateChanges; - - /* - * Copy the composite clip into the backing GC if either - * the drawable clip list has changed or the client has changed - * the client clip data - */ - if (pDrawable->serialNumber != pPriv->serialNumber || - (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask))) - { - XID vals[2]; - RegionPtr pCompositeClip; - - pCompositeClip = REGION_CREATE (pScreen, NULL, 0); - REGION_COPY (pScreen, pCompositeClip, pGC->pCompositeClip); - - /* Either the drawable has changed, or the clip list in the drawable has - * changed. Copy the new clip list over and set the new translated - * offset for it. - */ - - (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, - (pointer) pCompositeClip, 0); - - vals[0] = x_off - pDrawable->x; - vals[1] = y_off - pDrawable->y; - dixChangeGC(NullClient, pBackingGC, - (GCClipXOrigin | GCClipYOrigin), vals, NULL); - - pPriv->serialNumber = pDrawable->serialNumber; - /* - * Mask off any client clip changes to make sure - * the clip list set above remains in effect - */ - pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask); - } - - if (pPriv->stateChanges) { - CopyGC(pGC, pBackingGC, pPriv->stateChanges); - pPriv->stateChanges = 0; - } - - if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || - (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) - { - XID vals[2]; - vals[0] = pGC->patOrg.x + x_off; - vals[1] = pGC->patOrg.y + y_off; - dixChangeGC(NullClient, pBackingGC, - (GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL); - } - - ValidateGC(pBackingDrawable, pBackingGC); - - FUNC_EPILOGUE(pGC, pPriv); -} - -static void -cwChangeGC(GCPtr pGC, unsigned long mask) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pGC, pPriv); - - (*pGC->funcs->ChangeGC) (pGC, mask); - - FUNC_EPILOGUE(pGC, pPriv); -} - -static void -cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGCDst->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pGCDst, pPriv); - - (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - - FUNC_EPILOGUE(pGCDst, pPriv); -} - -static void -cwDestroyGC(GCPtr pGC) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pGC, pPriv); - - cwDestroyBackingGC(pGC); - - (*pGC->funcs->DestroyGC) (pGC); - - /* leave it unwrapped */ -} - -static void -cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pGC, pPriv); - - (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects); - - FUNC_EPILOGUE(pGC, pPriv); -} - -static void -cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pgcDst->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pgcDst, pPriv); - - (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - - FUNC_EPILOGUE(pgcDst, pPriv); -} - -static void -cwDestroyClip(GCPtr pGC) -{ - cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); - - FUNC_PROLOGUE(pGC, pPriv); - - (*pGC->funcs->DestroyClip)(pGC); - - FUNC_EPILOGUE(pGC, pPriv); -} - -/* - * Screen wrappers. - */ - -#define SCREEN_PROLOGUE(pScreen, field) \ - ((pScreen)->field = getCwScreen(pScreen)->field) - -#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \ - getCwScreen(pScreen)->field = (pScreen)->field; \ - (pScreen)->field = (wrapper); \ -} while (0) - -static Bool -cwCreateGC(GCPtr pGC) -{ - cwGCPtr pPriv = getCwGC(pGC); - ScreenPtr pScreen = pGC->pScreen; - Bool ret; - - bzero(pPriv, sizeof(cwGCRec)); - SCREEN_PROLOGUE(pScreen, CreateGC); - - if ( (ret = (*pScreen->CreateGC)(pGC)) ) - FUNC_EPILOGUE(pGC, pPriv); - - SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); - - return ret; -} - -static void -cwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format, - unsigned long planemask, char *pdstLine) -{ - ScreenPtr pScreen = pSrc->pScreen; - DrawablePtr pBackingDrawable; - int src_off_x, src_off_y; - - SCREEN_PROLOGUE(pScreen, GetImage); - - pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); - - CW_OFFSET_XY_SRC(x, y); - - (*pScreen->GetImage)(pBackingDrawable, x, y, w, h, format, planemask, - pdstLine); - - SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); -} - -static void -cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth, - int nspans, char *pdstStart) -{ - ScreenPtr pScreen = pSrc->pScreen; - DrawablePtr pBackingDrawable; - int i; - int src_off_x, src_off_y; - - SCREEN_PROLOGUE(pScreen, GetSpans); - - pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); - - for (i = 0; i < nspans; i++) - CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y); - - (*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans, - pdstStart); - - SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); -} - - -static void -cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE(pScreen, CopyWindow); - - if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { - (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); - } else { - GCPtr pGC; - BoxPtr pExtents; - int x_off, y_off; - int dx, dy; - PixmapPtr pBackingPixmap; - RegionPtr pClip; - int src_x, src_y, dst_x, dst_y, w, h; - - dx = ptOldOrg.x - pWin->drawable.x; - dy = ptOldOrg.y - pWin->drawable.y; - - pExtents = REGION_EXTENTS(pScreen, prgnSrc); - - pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin, - &x_off, &y_off); - - src_x = pExtents->x1 - pBackingPixmap->screen_x; - src_y = pExtents->y1 - pBackingPixmap->screen_y; - w = pExtents->x2 - pExtents->x1; - h = pExtents->y2 - pExtents->y1; - dst_x = src_x - dx; - dst_y = src_y - dy; - - /* Translate region (as required by API) */ - REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); - - pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); - /* - * Copy region to GC as clip, aligning as dest clip - */ - pClip = REGION_CREATE (pScreen, NULL, 0); - REGION_INTERSECT(pScreen, pClip, &pWin->borderClip, prgnSrc); - REGION_TRANSLATE(pScreen, pClip, - -pBackingPixmap->screen_x, - -pBackingPixmap->screen_y); - - (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); - - ValidateGC(&pBackingPixmap->drawable, pGC); - - (*pGC->ops->CopyArea) (&pBackingPixmap->drawable, - &pBackingPixmap->drawable, pGC, - src_x, src_y, w, h, dst_x, dst_y); - - (*pGC->funcs->DestroyClip) (pGC); - - FreeScratchGC(pGC); - } - - SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); -} - -static PixmapPtr -cwGetWindowPixmap (WindowPtr pWin) -{ - PixmapPtr pPixmap = getCwPixmap (pWin); - - if (!pPixmap) - { - ScreenPtr pScreen = pWin->drawable.pScreen; - SCREEN_PROLOGUE(pScreen, GetWindowPixmap); - if (pScreen->GetWindowPixmap) - pPixmap = (*pScreen->GetWindowPixmap) (pWin); - SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); - } - return pPixmap; -} - -static void -cwSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pWindow->drawable.pScreen; - - if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen)) - pPixmap = NULL; - setCwPixmap (pWindow, pPixmap); -} - -/* Screen initialization/teardown */ -void -miInitializeCompositeWrapper(ScreenPtr pScreen) -{ - cwScreenPtr pScreenPriv; - Bool has_render = GetPictureScreenIfSet(pScreen) != NULL; - - if (!dixRequestPrivate(cwGCKey, sizeof(cwGCRec))) - return; - - pScreenPriv = xalloc(sizeof(cwScreenRec)); - if (!pScreenPriv) - return; - - dixSetPrivate(&pScreen->devPrivates, cwScreenKey, pScreenPriv); - - SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen); - SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); - SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); - SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); - SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); - - SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap); - SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); - - if (has_render) - cwInitializeRender(pScreen); -} - -static Bool -cwCloseScreen (int i, ScreenPtr pScreen) -{ - cwScreenPtr pScreenPriv; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - - pScreenPriv = (cwScreenPtr)dixLookupPrivate(&pScreen->devPrivates, - cwScreenKey); - pScreen->CloseScreen = pScreenPriv->CloseScreen; - pScreen->GetImage = pScreenPriv->GetImage; - pScreen->GetSpans = pScreenPriv->GetSpans; - pScreen->CreateGC = pScreenPriv->CreateGC; - pScreen->CopyWindow = pScreenPriv->CopyWindow; - - if (ps) - cwFiniRender(pScreen); - - xfree((pointer)pScreenPriv); - - return (*pScreen->CloseScreen)(i, pScreen); -} +/* + * Copyright © 2004 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "gcstruct.h" +#include "windowstr.h" +#include "cw.h" + +#define CW_DEBUG 1 + +#if CW_DEBUG +#define CW_ASSERT(x) do { \ + if (!(x)) { \ + ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \ + __LINE__); \ + } \ +} while (0) +#else +#define CW_ASSERT(x) do {} while (0) +#endif + +static int cwGCKeyIndex; +DevPrivateKey cwGCKey = &cwGCKeyIndex; +static int cwScreenKeyIndex; +DevPrivateKey cwScreenKey = &cwScreenKeyIndex; +static int cwWindowKeyIndex; +DevPrivateKey cwWindowKey = &cwWindowKeyIndex; +static int cwPictureKeyIndex; +DevPrivateKey cwPictureKey = &cwPictureKeyIndex; +extern GCOps cwGCOps; + +static Bool +cwCloseScreen (int i, ScreenPtr pScreen); + +static void +cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable); +static void +cwChangeGC(GCPtr pGC, unsigned long mask); +static void +cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +static void +cwDestroyGC(GCPtr pGC); +static void +cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects); +static void +cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc); +static void +cwDestroyClip(GCPtr pGC); + +GCFuncs cwGCFuncs = { + cwValidateGC, + cwChangeGC, + cwCopyGC, + cwDestroyGC, + cwChangeClip, + cwDestroyClip, + cwCopyClip, +}; + +/* Find the real drawable to draw to, and provide offsets that will translate + * window coordinates to backing pixmap coordinates. + */ +DrawablePtr +cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off) +{ + PixmapPtr pPixmap; + + if (pDrawable->type == DRAWABLE_WINDOW && + (pPixmap = getCwPixmap ((WindowPtr) pDrawable))) + { + *x_off = pDrawable->x - pPixmap->screen_x; + *y_off = pDrawable->y - pPixmap->screen_y; + return &pPixmap->drawable; + } else { + *x_off = *y_off = 0; + return pDrawable; + } +} + +#define FUNC_PROLOGUE(pGC, pPriv) do { \ + (pGC)->funcs = (pPriv)->wrapFuncs; \ + (pGC)->ops = (pPriv)->wrapOps; \ +} while (0) + +#define FUNC_EPILOGUE(pGC, pPriv) do { \ + (pPriv)->wrapFuncs = (pGC)->funcs; \ + (pPriv)->wrapOps = (pGC)->ops; \ + (pGC)->funcs = &cwGCFuncs; \ + (pGC)->ops = &cwGCOps; \ +} while (0) + + +static Bool +cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable) +{ + cwGCRec *pPriv = getCwGC(pGC); + int status, x_off, y_off; + XID noexpose = xFalse; + DrawablePtr pBackingDrawable; + + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures, + &noexpose, &status, (XID)0, serverClient); + if (status != Success) + return FALSE; + + pPriv->serialNumber = 0; + pPriv->stateChanges = GCAllBits; + + return TRUE; +} + +static void +cwDestroyBackingGC(GCPtr pGC) +{ + cwGCPtr pPriv; + + pPriv = (cwGCPtr) getCwGC (pGC); + + if (pPriv->pBackingGC) { + FreeGC(pPriv->pBackingGC, (XID)0); + pPriv->pBackingGC = NULL; + } +} + +static void +cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) +{ + GCPtr pBackingGC; + cwGCPtr pPriv; + DrawablePtr pBackingDrawable; + int x_off, y_off; + + pPriv = (cwGCPtr) getCwGC (pGC); + + FUNC_PROLOGUE(pGC, pPriv); + + /* + * Must call ValidateGC to ensure pGC->pCompositeClip is valid + */ + (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); + + if (!cwDrawableIsRedirWindow(pDrawable)) { + cwDestroyBackingGC(pGC); + FUNC_EPILOGUE(pGC, pPriv); + return; + } else { + if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) { + FUNC_EPILOGUE(pGC, pPriv); + return; + } + } + + pBackingGC = pPriv->pBackingGC; + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + + pPriv->stateChanges |= stateChanges; + + /* + * Copy the composite clip into the backing GC if either + * the drawable clip list has changed or the client has changed + * the client clip data + */ + if (pDrawable->serialNumber != pPriv->serialNumber || + (pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask))) + { + ChangeGCVal vals[2]; + RegionPtr pCompositeClip; + + pCompositeClip = REGION_CREATE (pScreen, NULL, 0); + REGION_COPY (pScreen, pCompositeClip, pGC->pCompositeClip); + + /* Either the drawable has changed, or the clip list in the drawable has + * changed. Copy the new clip list over and set the new translated + * offset for it. + */ + + (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, + (pointer) pCompositeClip, 0); + + vals[0].val = x_off - pDrawable->x; + vals[1].val = y_off - pDrawable->y; + ChangeGC(NullClient, pBackingGC, + (GCClipXOrigin | GCClipYOrigin), vals); + + pPriv->serialNumber = pDrawable->serialNumber; + /* + * Mask off any client clip changes to make sure + * the clip list set above remains in effect + */ + pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask); + } + + if (pPriv->stateChanges) { + CopyGC(pGC, pBackingGC, pPriv->stateChanges); + pPriv->stateChanges = 0; + } + + if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x || + (pGC->patOrg.y + y_off) != pBackingGC->patOrg.y) + { + ChangeGCVal vals[2]; + vals[0].val = pGC->patOrg.x + x_off; + vals[1].val = pGC->patOrg.y + y_off; + ChangeGC(NullClient, pBackingGC, + (GCTileStipXOrigin | GCTileStipYOrigin), vals); + } + + ValidateGC(pBackingDrawable, pBackingGC); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwChangeGC(GCPtr pGC, unsigned long mask) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->ChangeGC) (pGC, mask); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGCDst->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGCDst, pPriv); + + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + + FUNC_EPILOGUE(pGCDst, pPriv); +} + +static void +cwDestroyGC(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + cwDestroyBackingGC(pGC); + + (*pGC->funcs->DestroyGC) (pGC); + + /* leave it unwrapped */ +} + +static void +cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects); + + FUNC_EPILOGUE(pGC, pPriv); +} + +static void +cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pgcDst->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pgcDst, pPriv); + + (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); + + FUNC_EPILOGUE(pgcDst, pPriv); +} + +static void +cwDestroyClip(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr)dixLookupPrivate(&pGC->devPrivates, cwGCKey); + + FUNC_PROLOGUE(pGC, pPriv); + + (*pGC->funcs->DestroyClip)(pGC); + + FUNC_EPILOGUE(pGC, pPriv); +} + +/* + * Screen wrappers. + */ + +#define SCREEN_PROLOGUE(pScreen, field) \ + ((pScreen)->field = getCwScreen(pScreen)->field) + +#define SCREEN_EPILOGUE(pScreen, field, wrapper) do { \ + getCwScreen(pScreen)->field = (pScreen)->field; \ + (pScreen)->field = (wrapper); \ +} while (0) + +static Bool +cwCreateGC(GCPtr pGC) +{ + cwGCPtr pPriv = getCwGC(pGC); + ScreenPtr pScreen = pGC->pScreen; + Bool ret; + + bzero(pPriv, sizeof(cwGCRec)); + SCREEN_PROLOGUE(pScreen, CreateGC); + + if ( (ret = (*pScreen->CreateGC)(pGC)) ) + FUNC_EPILOGUE(pGC, pPriv); + + SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); + + return ret; +} + +static void +cwGetImage(DrawablePtr pSrc, int x, int y, int w, int h, unsigned int format, + unsigned long planemask, char *pdstLine) +{ + ScreenPtr pScreen = pSrc->pScreen; + DrawablePtr pBackingDrawable; + int src_off_x, src_off_y; + + SCREEN_PROLOGUE(pScreen, GetImage); + + pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); + + CW_OFFSET_XY_SRC(x, y); + + (*pScreen->GetImage)(pBackingDrawable, x, y, w, h, format, planemask, + pdstLine); + + SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); +} + +static void +cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth, + int nspans, char *pdstStart) +{ + ScreenPtr pScreen = pSrc->pScreen; + DrawablePtr pBackingDrawable; + int i; + int src_off_x, src_off_y; + + SCREEN_PROLOGUE(pScreen, GetSpans); + + pBackingDrawable = cwGetBackingDrawable(pSrc, &src_off_x, &src_off_y); + + for (i = 0; i < nspans; i++) + CW_OFFSET_XY_SRC(ppt[i].x, ppt[i].y); + + (*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans, + pdstStart); + + SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); +} + + +static void +cwCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, CopyWindow); + + if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { + (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc); + } else { + GCPtr pGC; + BoxPtr pExtents; + int x_off, y_off; + int dx, dy; + PixmapPtr pBackingPixmap; + RegionPtr pClip; + int src_x, src_y, dst_x, dst_y, w, h; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + + pExtents = REGION_EXTENTS(pScreen, prgnSrc); + + pBackingPixmap = (PixmapPtr) cwGetBackingDrawable((DrawablePtr)pWin, + &x_off, &y_off); + + src_x = pExtents->x1 - pBackingPixmap->screen_x; + src_y = pExtents->y1 - pBackingPixmap->screen_y; + w = pExtents->x2 - pExtents->x1; + h = pExtents->y2 - pExtents->y1; + dst_x = src_x - dx; + dst_y = src_y - dy; + + /* Translate region (as required by API) */ + REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy); + + pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); + /* + * Copy region to GC as clip, aligning as dest clip + */ + pClip = REGION_CREATE (pScreen, NULL, 0); + REGION_INTERSECT(pScreen, pClip, &pWin->borderClip, prgnSrc); + REGION_TRANSLATE(pScreen, pClip, + -pBackingPixmap->screen_x, + -pBackingPixmap->screen_y); + + (*pGC->funcs->ChangeClip) (pGC, CT_REGION, pClip, 0); + + ValidateGC(&pBackingPixmap->drawable, pGC); + + (*pGC->ops->CopyArea) (&pBackingPixmap->drawable, + &pBackingPixmap->drawable, pGC, + src_x, src_y, w, h, dst_x, dst_y); + + (*pGC->funcs->DestroyClip) (pGC); + + FreeScratchGC(pGC); + } + + SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); +} + +static PixmapPtr +cwGetWindowPixmap (WindowPtr pWin) +{ + PixmapPtr pPixmap = getCwPixmap (pWin); + + if (!pPixmap) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + SCREEN_PROLOGUE(pScreen, GetWindowPixmap); + if (pScreen->GetWindowPixmap) + pPixmap = (*pScreen->GetWindowPixmap) (pWin); + SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); + } + return pPixmap; +} + +static void +cwSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pWindow->drawable.pScreen; + + if (pPixmap == (*pScreen->GetScreenPixmap) (pScreen)) + pPixmap = NULL; + setCwPixmap (pWindow, pPixmap); +} + +/* Screen initialization/teardown */ +void +miInitializeCompositeWrapper(ScreenPtr pScreen) +{ + cwScreenPtr pScreenPriv; + Bool has_render = GetPictureScreenIfSet(pScreen) != NULL; + + if (!dixRequestPrivate(cwGCKey, sizeof(cwGCRec))) + return; + + pScreenPriv = malloc(sizeof(cwScreenRec)); + if (!pScreenPriv) + return; + + dixSetPrivate(&pScreen->devPrivates, cwScreenKey, pScreenPriv); + + SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen); + SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); + SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); + SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); + SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); + + SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap); + SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); + + if (has_render) + cwInitializeRender(pScreen); +} + +static Bool +cwCloseScreen (int i, ScreenPtr pScreen) +{ + cwScreenPtr pScreenPriv; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + pScreenPriv = (cwScreenPtr)dixLookupPrivate(&pScreen->devPrivates, + cwScreenKey); + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->CreateGC = pScreenPriv->CreateGC; + pScreen->CopyWindow = pScreenPriv->CopyWindow; + + if (ps) + cwFiniRender(pScreen); + + free((pointer)pScreenPriv); + + return (*pScreen->CloseScreen)(i, pScreen); +} diff --git a/xorg-server/miext/cw/cw_render.c b/xorg-server/miext/cw/cw_render.c index dfe2681e0..260509ce0 100644 --- a/xorg-server/miext/cw/cw_render.c +++ b/xorg-server/miext/cw/cw_render.c @@ -1,469 +1,469 @@ -/* - * Copyright © 2004 Eric Anholt - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Eric Anholt not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Eric Anholt makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include "gcstruct.h" -#include "windowstr.h" -#include "cw.h" - -#define cwPsDecl(pScreen) \ - PictureScreenPtr ps = GetPictureScreen (pScreen); \ - cwScreenPtr pCwScreen = getCwScreen (pScreen) - -#define cwPicturePrivate \ - cwPicturePtr pPicturePrivate = getCwPicture(pPicture) - -#define cwSrcPictureDecl \ - int src_picture_x_off, src_picture_y_off; \ - PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \ - &src_picture_x_off,\ - &src_picture_y_off) - -#define cwDstPictureDecl \ - int dst_picture_x_off, dst_picture_y_off; \ - PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \ - &dst_picture_x_off,\ - &dst_picture_y_off) - -#define cwMskPictureDecl \ - int msk_picture_x_off = 0, msk_picture_y_off = 0; \ - PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \ - cwGetBackingPicture(pMskPicture, \ - &msk_picture_x_off,\ - &msk_picture_y_off)) - -#define cwPsUnwrap(elt) { \ - ps->elt = pCwScreen->elt; \ -} - -#define cwPsWrap(elt,func) { \ - pCwScreen->elt = ps->elt; \ - ps->elt = func; \ -} - -static cwPicturePtr -cwCreatePicturePrivate (PicturePtr pPicture) -{ - WindowPtr pWindow = (WindowPtr) pPicture->pDrawable; - PixmapPtr pPixmap = getCwPixmap (pWindow); - int error; - cwPicturePtr pPicturePrivate; - - pPicturePrivate = xalloc (sizeof (cwPictureRec)); - if (!pPicturePrivate) - return NULL; - - pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable, - pPicture->pFormat, - 0, 0, serverClient, - &error); - if (!pPicturePrivate->pBackingPicture) - { - xfree (pPicturePrivate); - return NULL; - } - - /* - * Ensure that this serial number does not match the window's - */ - pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber; - pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1; - - setCwPicture(pPicture, pPicturePrivate); - - return pPicturePrivate; -} - -static void -cwDestroyPicturePrivate (PicturePtr pPicture) -{ - cwPicturePrivate; - - if (pPicturePrivate) - { - if (pPicturePrivate->pBackingPicture) - FreePicture (pPicturePrivate->pBackingPicture, 0); - xfree (pPicturePrivate); - setCwPicture(pPicture, NULL); - } -} - -static PicturePtr -cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off) -{ - cwPicturePrivate; - - if (pPicturePrivate) - { - DrawablePtr pDrawable = pPicture->pDrawable; - WindowPtr pWindow = (WindowPtr) pDrawable; - PixmapPtr pPixmap = getCwPixmap (pWindow); - - *x_off = pDrawable->x - pPixmap->screen_x; - *y_off = pDrawable->y - pPixmap->screen_y; - - return pPicturePrivate->pBackingPicture; - } - else - { - *x_off = *y_off = 0; - return pPicture; - } -} - -static void -cwDestroyPicture (PicturePtr pPicture) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - - cwPsUnwrap(DestroyPicture); - cwDestroyPicturePrivate (pPicture); - (*ps->DestroyPicture) (pPicture); - cwPsWrap(DestroyPicture, cwDestroyPicture); -} - -static void -cwChangePicture (PicturePtr pPicture, Mask mask) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwPicturePtr pPicturePrivate = getCwPicture(pPicture); - - cwPsUnwrap(ChangePicture); - (*ps->ChangePicture) (pPicture, mask); - if (pPicturePrivate) - pPicturePrivate->stateChanges |= mask; - cwPsWrap(ChangePicture, cwChangePicture); -} - - -static void -cwValidatePicture (PicturePtr pPicture, - Mask mask) -{ - DrawablePtr pDrawable = pPicture->pDrawable; - ScreenPtr pScreen = pDrawable->pScreen; - cwPsDecl(pScreen); - cwPicturePrivate; - - cwPsUnwrap(ValidatePicture); - - /* - * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid - */ - (*ps->ValidatePicture) (pPicture, mask); - - if (!cwDrawableIsRedirWindow (pDrawable)) - { - if (pPicturePrivate) - cwDestroyPicturePrivate (pPicture); - } - else - { - PicturePtr pBackingPicture; - DrawablePtr pBackingDrawable; - int x_off, y_off; - - pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); - - if (pPicturePrivate && - pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable) - { - cwDestroyPicturePrivate (pPicture); - pPicturePrivate = 0; - } - - if (!pPicturePrivate) - { - pPicturePrivate = cwCreatePicturePrivate (pPicture); - if (!pPicturePrivate) - { - cwPsWrap(ValidatePicture, cwValidatePicture); - return; - } - } - - pBackingPicture = pPicturePrivate->pBackingPicture; - - /* - * Always copy transform and filters because there's no - * indication of when they've changed - */ - SetPictureTransform(pBackingPicture, pPicture->transform); - - if (pBackingPicture->filter != pPicture->filter || - pPicture->filter_nparams > 0) - { - char *filter = PictureGetFilterName (pPicture->filter); - - SetPictureFilter(pBackingPicture, - filter, strlen (filter), - pPicture->filter_params, - pPicture->filter_nparams); - } - - pPicturePrivate->stateChanges |= mask; - - if (pPicturePrivate->serialNumber != pDrawable->serialNumber || - (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask))) - { - SetPictureClipRegion (pBackingPicture, - x_off - pDrawable->x, - y_off - pDrawable->y, - pPicture->pCompositeClip); - - pPicturePrivate->serialNumber = pDrawable->serialNumber; - pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask); - } - - CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture); - - ValidatePicture (pBackingPicture); - } - cwPsWrap(ValidatePicture, cwValidatePicture); -} - -static void -cwComposite (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pMskPicture, - PicturePtr pDstPicture, - INT16 xSrc, - INT16 ySrc, - INT16 xMsk, - INT16 yMsk, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwMskPictureDecl; - cwDstPictureDecl; - - cwPsUnwrap(Composite); - (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - xMsk + msk_picture_x_off, yMsk + msk_picture_y_off, - xDst + dst_picture_x_off, yDst + dst_picture_y_off, - width, height); - cwPsWrap(Composite, cwComposite); -} - -static void -cwCompositeRects (CARD8 op, - PicturePtr pDstPicture, - xRenderColor *color, - int nRect, - xRectangle *rects) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwDstPictureDecl; - int i; - - cwPsUnwrap(CompositeRects); - for (i = 0; i < nRect; i++) - { - rects[i].x += dst_picture_x_off; - rects[i].y += dst_picture_y_off; - } - (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects); - cwPsWrap(CompositeRects, cwCompositeRects); -} - -static void -cwTrapezoids (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int ntrap, - xTrapezoid *traps) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(Trapezoids); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < ntrap; i++) - { - traps[i].top += dst_picture_y_off << 16; - traps[i].bottom += dst_picture_y_off << 16; - traps[i].left.p1.x += dst_picture_x_off << 16; - traps[i].left.p1.y += dst_picture_y_off << 16; - traps[i].left.p2.x += dst_picture_x_off << 16; - traps[i].left.p2.y += dst_picture_y_off << 16; - traps[i].right.p1.x += dst_picture_x_off << 16; - traps[i].right.p1.y += dst_picture_y_off << 16; - traps[i].right.p2.x += dst_picture_x_off << 16; - traps[i].right.p2.y += dst_picture_y_off << 16; - } - } - (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - ntrap, traps); - cwPsWrap(Trapezoids, cwTrapezoids); -} - -static void -cwTriangles (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int ntri, - xTriangle *tris) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(Triangles); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < ntri; i++) - { - tris[i].p1.x += dst_picture_x_off << 16; - tris[i].p1.y += dst_picture_y_off << 16; - tris[i].p2.x += dst_picture_x_off << 16; - tris[i].p2.y += dst_picture_y_off << 16; - tris[i].p3.x += dst_picture_x_off << 16; - tris[i].p3.y += dst_picture_y_off << 16; - } - } - (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - ntri, tris); - cwPsWrap(Triangles, cwTriangles); -} - -static void -cwTriStrip (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(TriStrip); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < npoint; i++) - { - points[i].x += dst_picture_x_off << 16; - points[i].y += dst_picture_y_off << 16; - } - } - (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - npoint, points); - cwPsWrap(TriStrip, cwTriStrip); -} - -static void -cwTriFan (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int npoint, - xPointFixed *points) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - int i; - - cwPsUnwrap(TriFan); - if (dst_picture_x_off || dst_picture_y_off) { - for (i = 0; i < npoint; i++) - { - points[i].x += dst_picture_x_off << 16; - points[i].y += dst_picture_y_off << 16; - } - } - (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - npoint, points); - cwPsWrap(TriFan, cwTriFan); -} - -void -cwInitializeRender (ScreenPtr pScreen) -{ - cwPsDecl (pScreen); - - cwPsWrap(DestroyPicture, cwDestroyPicture); - cwPsWrap(ChangePicture, cwChangePicture); - cwPsWrap(ValidatePicture, cwValidatePicture); - cwPsWrap(Composite, cwComposite); - cwPsWrap(CompositeRects, cwCompositeRects); - cwPsWrap(Trapezoids, cwTrapezoids); - cwPsWrap(Triangles, cwTriangles); - cwPsWrap(TriStrip, cwTriStrip); - cwPsWrap(TriFan, cwTriFan); - /* There is no need to wrap AddTraps as far as we can tell. AddTraps can - * only be done on alpha-only pictures, and we won't be getting - * alpha-only window pictures, so there's no need to translate. - */ -} - -void -cwFiniRender (ScreenPtr pScreen) -{ - cwPsDecl (pScreen); - - cwPsUnwrap(DestroyPicture); - cwPsUnwrap(ChangePicture); - cwPsUnwrap(ValidatePicture); - cwPsUnwrap(Composite); - cwPsUnwrap(CompositeRects); - cwPsUnwrap(Trapezoids); - cwPsUnwrap(Triangles); - cwPsUnwrap(TriStrip); - cwPsUnwrap(TriFan); -} - +/* + * Copyright © 2004 Eric Anholt + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Eric Anholt not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Eric Anholt makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "gcstruct.h" +#include "windowstr.h" +#include "cw.h" + +#define cwPsDecl(pScreen) \ + PictureScreenPtr ps = GetPictureScreen (pScreen); \ + cwScreenPtr pCwScreen = getCwScreen (pScreen) + +#define cwPicturePrivate \ + cwPicturePtr pPicturePrivate = getCwPicture(pPicture) + +#define cwSrcPictureDecl \ + int src_picture_x_off, src_picture_y_off; \ + PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \ + &src_picture_x_off,\ + &src_picture_y_off) + +#define cwDstPictureDecl \ + int dst_picture_x_off, dst_picture_y_off; \ + PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \ + &dst_picture_x_off,\ + &dst_picture_y_off) + +#define cwMskPictureDecl \ + int msk_picture_x_off = 0, msk_picture_y_off = 0; \ + PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \ + cwGetBackingPicture(pMskPicture, \ + &msk_picture_x_off,\ + &msk_picture_y_off)) + +#define cwPsUnwrap(elt) { \ + ps->elt = pCwScreen->elt; \ +} + +#define cwPsWrap(elt,func) { \ + pCwScreen->elt = ps->elt; \ + ps->elt = func; \ +} + +static cwPicturePtr +cwCreatePicturePrivate (PicturePtr pPicture) +{ + WindowPtr pWindow = (WindowPtr) pPicture->pDrawable; + PixmapPtr pPixmap = getCwPixmap (pWindow); + int error; + cwPicturePtr pPicturePrivate; + + pPicturePrivate = malloc(sizeof (cwPictureRec)); + if (!pPicturePrivate) + return NULL; + + pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable, + pPicture->pFormat, + 0, 0, serverClient, + &error); + if (!pPicturePrivate->pBackingPicture) + { + free(pPicturePrivate); + return NULL; + } + + /* + * Ensure that this serial number does not match the window's + */ + pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber; + pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1; + + setCwPicture(pPicture, pPicturePrivate); + + return pPicturePrivate; +} + +static void +cwDestroyPicturePrivate (PicturePtr pPicture) +{ + cwPicturePrivate; + + if (pPicturePrivate) + { + if (pPicturePrivate->pBackingPicture) + FreePicture (pPicturePrivate->pBackingPicture, 0); + free(pPicturePrivate); + setCwPicture(pPicture, NULL); + } +} + +static PicturePtr +cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off) +{ + cwPicturePrivate; + + if (pPicturePrivate) + { + DrawablePtr pDrawable = pPicture->pDrawable; + WindowPtr pWindow = (WindowPtr) pDrawable; + PixmapPtr pPixmap = getCwPixmap (pWindow); + + *x_off = pDrawable->x - pPixmap->screen_x; + *y_off = pDrawable->y - pPixmap->screen_y; + + return pPicturePrivate->pBackingPicture; + } + else + { + *x_off = *y_off = 0; + return pPicture; + } +} + +static void +cwDestroyPicture (PicturePtr pPicture) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + + cwPsUnwrap(DestroyPicture); + cwDestroyPicturePrivate (pPicture); + (*ps->DestroyPicture) (pPicture); + cwPsWrap(DestroyPicture, cwDestroyPicture); +} + +static void +cwChangePicture (PicturePtr pPicture, Mask mask) +{ + ScreenPtr pScreen = pPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwPicturePtr pPicturePrivate = getCwPicture(pPicture); + + cwPsUnwrap(ChangePicture); + (*ps->ChangePicture) (pPicture, mask); + if (pPicturePrivate) + pPicturePrivate->stateChanges |= mask; + cwPsWrap(ChangePicture, cwChangePicture); +} + + +static void +cwValidatePicture (PicturePtr pPicture, + Mask mask) +{ + DrawablePtr pDrawable = pPicture->pDrawable; + ScreenPtr pScreen = pDrawable->pScreen; + cwPsDecl(pScreen); + cwPicturePrivate; + + cwPsUnwrap(ValidatePicture); + + /* + * Must call ValidatePicture to ensure pPicture->pCompositeClip is valid + */ + (*ps->ValidatePicture) (pPicture, mask); + + if (!cwDrawableIsRedirWindow (pDrawable)) + { + if (pPicturePrivate) + cwDestroyPicturePrivate (pPicture); + } + else + { + PicturePtr pBackingPicture; + DrawablePtr pBackingDrawable; + int x_off, y_off; + + pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); + + if (pPicturePrivate && + pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable) + { + cwDestroyPicturePrivate (pPicture); + pPicturePrivate = 0; + } + + if (!pPicturePrivate) + { + pPicturePrivate = cwCreatePicturePrivate (pPicture); + if (!pPicturePrivate) + { + cwPsWrap(ValidatePicture, cwValidatePicture); + return; + } + } + + pBackingPicture = pPicturePrivate->pBackingPicture; + + /* + * Always copy transform and filters because there's no + * indication of when they've changed + */ + SetPictureTransform(pBackingPicture, pPicture->transform); + + if (pBackingPicture->filter != pPicture->filter || + pPicture->filter_nparams > 0) + { + char *filter = PictureGetFilterName (pPicture->filter); + + SetPictureFilter(pBackingPicture, + filter, strlen (filter), + pPicture->filter_params, + pPicture->filter_nparams); + } + + pPicturePrivate->stateChanges |= mask; + + if (pPicturePrivate->serialNumber != pDrawable->serialNumber || + (pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask))) + { + SetPictureClipRegion (pBackingPicture, + x_off - pDrawable->x, + y_off - pDrawable->y, + pPicture->pCompositeClip); + + pPicturePrivate->serialNumber = pDrawable->serialNumber; + pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask); + } + + CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture); + + ValidatePicture (pBackingPicture); + } + cwPsWrap(ValidatePicture, cwValidatePicture); +} + +static void +cwComposite (CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pMskPicture, + PicturePtr pDstPicture, + INT16 xSrc, + INT16 ySrc, + INT16 xMsk, + INT16 yMsk, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwMskPictureDecl; + cwDstPictureDecl; + + cwPsUnwrap(Composite); + (*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + xMsk + msk_picture_x_off, yMsk + msk_picture_y_off, + xDst + dst_picture_x_off, yDst + dst_picture_y_off, + width, height); + cwPsWrap(Composite, cwComposite); +} + +static void +cwCompositeRects (CARD8 op, + PicturePtr pDstPicture, + xRenderColor *color, + int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwDstPictureDecl; + int i; + + cwPsUnwrap(CompositeRects); + for (i = 0; i < nRect; i++) + { + rects[i].x += dst_picture_x_off; + rects[i].y += dst_picture_y_off; + } + (*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects); + cwPsWrap(CompositeRects, cwCompositeRects); +} + +static void +cwTrapezoids (CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntrap, + xTrapezoid *traps) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(Trapezoids); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < ntrap; i++) + { + traps[i].top += dst_picture_y_off << 16; + traps[i].bottom += dst_picture_y_off << 16; + traps[i].left.p1.x += dst_picture_x_off << 16; + traps[i].left.p1.y += dst_picture_y_off << 16; + traps[i].left.p2.x += dst_picture_x_off << 16; + traps[i].left.p2.y += dst_picture_y_off << 16; + traps[i].right.p1.x += dst_picture_x_off << 16; + traps[i].right.p1.y += dst_picture_y_off << 16; + traps[i].right.p2.x += dst_picture_x_off << 16; + traps[i].right.p2.y += dst_picture_y_off << 16; + } + } + (*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + ntrap, traps); + cwPsWrap(Trapezoids, cwTrapezoids); +} + +static void +cwTriangles (CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int ntri, + xTriangle *tris) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(Triangles); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < ntri; i++) + { + tris[i].p1.x += dst_picture_x_off << 16; + tris[i].p1.y += dst_picture_y_off << 16; + tris[i].p2.x += dst_picture_x_off << 16; + tris[i].p2.y += dst_picture_y_off << 16; + tris[i].p3.x += dst_picture_x_off << 16; + tris[i].p3.y += dst_picture_y_off << 16; + } + } + (*ps->Triangles) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + ntri, tris); + cwPsWrap(Triangles, cwTriangles); +} + +static void +cwTriStrip (CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(TriStrip); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < npoint; i++) + { + points[i].x += dst_picture_x_off << 16; + points[i].y += dst_picture_y_off << 16; + } + } + (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + npoint, points); + cwPsWrap(TriStrip, cwTriStrip); +} + +static void +cwTriFan (CARD8 op, + PicturePtr pSrcPicture, + PicturePtr pDstPicture, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int npoint, + xPointFixed *points) +{ + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + cwPsDecl(pScreen); + cwSrcPictureDecl; + cwDstPictureDecl; + int i; + + cwPsUnwrap(TriFan); + if (dst_picture_x_off || dst_picture_y_off) { + for (i = 0; i < npoint; i++) + { + points[i].x += dst_picture_x_off << 16; + points[i].y += dst_picture_y_off << 16; + } + } + (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, + xSrc + src_picture_x_off, ySrc + src_picture_y_off, + npoint, points); + cwPsWrap(TriFan, cwTriFan); +} + +void +cwInitializeRender (ScreenPtr pScreen) +{ + cwPsDecl (pScreen); + + cwPsWrap(DestroyPicture, cwDestroyPicture); + cwPsWrap(ChangePicture, cwChangePicture); + cwPsWrap(ValidatePicture, cwValidatePicture); + cwPsWrap(Composite, cwComposite); + cwPsWrap(CompositeRects, cwCompositeRects); + cwPsWrap(Trapezoids, cwTrapezoids); + cwPsWrap(Triangles, cwTriangles); + cwPsWrap(TriStrip, cwTriStrip); + cwPsWrap(TriFan, cwTriFan); + /* There is no need to wrap AddTraps as far as we can tell. AddTraps can + * only be done on alpha-only pictures, and we won't be getting + * alpha-only window pictures, so there's no need to translate. + */ +} + +void +cwFiniRender (ScreenPtr pScreen) +{ + cwPsDecl (pScreen); + + cwPsUnwrap(DestroyPicture); + cwPsUnwrap(ChangePicture); + cwPsUnwrap(ValidatePicture); + cwPsUnwrap(Composite); + cwPsUnwrap(CompositeRects); + cwPsUnwrap(Trapezoids); + cwPsUnwrap(Triangles); + cwPsUnwrap(TriStrip); + cwPsUnwrap(TriFan); +} + -- cgit v1.2.3