diff options
Diffstat (limited to 'nx-X11/programs/Xserver/miext/cw')
-rw-r--r-- | nx-X11/programs/Xserver/miext/cw/Imakefile | 22 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/cw/cw.c | 701 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/cw/cw.h | 173 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/cw/cw_ops.c | 472 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/cw/cw_render.c | 473 |
5 files changed, 1841 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/miext/cw/Imakefile b/nx-X11/programs/Xserver/miext/cw/Imakefile new file mode 100644 index 000000000..395e60a48 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/cw/Imakefile @@ -0,0 +1,22 @@ +#include <Server.tmpl> + +SRCS = cw.c cw_ops.c cw_render.c + +OBJS = cw.o cw_ops.o cw_render.o + + INCLUDES = -I../../mi -I../../fb -I../../render -I../../composite \ + -I../../include -I$(XINCLUDESRC) $(EXTRAINCLUDES) \ + -I$(EXTINCSRC) \ + `pkg-config --cflags-only-I pixman-1` + LINTLIBS = ../../dix/llib-ldix.ln ../../os/llib-los.ln \ + ../../mi/llib-lmi.ln + +NormalLibraryObjectRule() +NormalLibraryTarget(cw,$(OBJS)) +LintLibraryTarget(cw,$(SRCS)) + +NormalLintTarget($(SRCS)) + +DependTarget() + +InstallDriverSDKNonExecFile(cw.h,$(DRIVERSDKINCLUDEDIR)) diff --git a/nx-X11/programs/Xserver/miext/cw/cw.c b/nx-X11/programs/Xserver/miext/cw/cw.c new file mode 100644 index 000000000..d9ca55f7e --- /dev/null +++ b/nx-X11/programs/Xserver/miext/cw/cw.c @@ -0,0 +1,701 @@ +/* + * 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. + */ +/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw.c,v 1.23 2005/10/02 08:28:26 anholt Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#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 + +int cwGCIndex; +int cwScreenIndex; +int cwWindowIndex; +#ifdef RENDER +int cwPictureIndex; +#endif +static Bool cwDisabled[MAXSCREENS]; +static unsigned long cwGeneration = 0; +extern GCOps cwGCOps; + +static Bool +cwCloseScreen (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, void * 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); + 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 = RegionCreate(NULL, 0); + RegionCopy(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, + (void *) 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)(pGC)->devPrivates[cwGCIndex].ptr; + + 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)(pGCDst)->devPrivates[cwGCIndex].ptr; + + FUNC_PROLOGUE(pGCDst, pPriv); + + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + + FUNC_EPILOGUE(pGCDst, pPriv); +} + +static void +cwDestroyGC(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr; + + FUNC_PROLOGUE(pGC, pPriv); + + cwDestroyBackingGC(pGC); + + (*pGC->funcs->DestroyGC) (pGC); + + /* leave it unwrapped */ +} + +static void +cwChangeClip(GCPtr pGC, int type, void * pvalue, int nrects) +{ + cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr; + + 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)(pgcDst)->devPrivates[cwGCIndex].ptr; + + FUNC_PROLOGUE(pgcDst, pPriv); + + (*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); + + FUNC_EPILOGUE(pgcDst, pPriv); +} + +static void +cwDestroyClip(GCPtr pGC) +{ + cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr; + + 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 +cwFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, unsigned long pixel) +{ + ScreenPtr pScreen = pDrawable->pScreen; + GCPtr pGC; + BoxPtr pBox; + int nbox, i; + ChangeGCVal v[3]; + + pGC = GetScratchGC(pDrawable->depth, pScreen); + v[0].val = GXcopy; + v[1].val = pixel; + v[2].val = FillSolid; + dixChangeGC(NullClient, pGC, (GCFunction | GCForeground | GCFillStyle), + NULL, v); + ValidateGC(pDrawable, pGC); + + pBox = RegionRects(pRegion); + nbox = RegionNumRects(pRegion); + + for (i = 0; i < nbox; i++, pBox++) { + xRectangle rect; + rect.x = pBox->x1; + rect.y = pBox->y1; + rect.width = pBox->x2 - pBox->x1; + rect.height = pBox->y2 - pBox->y1; + (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &rect); + } + + FreeScratchGC(pGC); +} + +static void +cwFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, + int x_off, int y_off) +{ + ScreenPtr pScreen = pDrawable->pScreen; + GCPtr pGC; + BoxPtr pBox; + int nbox, i; + ChangeGCVal v[5]; + + pGC = GetScratchGC(pDrawable->depth, pScreen); + v[0].val = GXcopy; + v[1].val = FillTiled; + v[2].ptr = (void *) pTile; + v[3].val = x_off; + v[4].val = y_off; + dixChangeGC(NullClient, pGC, (GCFunction | GCFillStyle | GCTile | + GCTileStipXOrigin | GCTileStipYOrigin), NULL, v); + + ValidateGC(pDrawable, pGC); + + pBox = RegionRects(pRegion); + nbox = RegionNumRects(pRegion); + + for (i = 0; i < nbox; i++, pBox++) { + xRectangle rect; + rect.x = pBox->x1; + rect.y = pBox->y1; + rect.width = pBox->x2 - pBox->x1; + rect.height = pBox->y2 - pBox->y1; + (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &rect); + } + + FreeScratchGC(pGC); +} + +static void +cwPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, PaintWindowBackground); + + if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { + (*pScreen->PaintWindowBackground)(pWin, pRegion, what); + } else { + DrawablePtr pBackingDrawable; + int x_off, y_off, x_screen, y_screen; + + while (pWin && pWin->backgroundState == ParentRelative) + pWin = pWin->parent; + + pBackingDrawable = cwGetBackingDrawable((DrawablePtr)pWin, &x_off, + &y_off); + + x_screen = x_off - pWin->drawable.x; + y_screen = y_off - pWin->drawable.y; + + if (pWin && (pWin->backgroundState == BackgroundPixel || + pWin->backgroundState == BackgroundPixmap)) + { + RegionTranslate(pRegion, x_screen, y_screen); + + if (pWin->backgroundState == BackgroundPixel) { + cwFillRegionSolid(pBackingDrawable, pRegion, + pWin->background.pixel); + } else { + cwFillRegionTiled(pBackingDrawable, pRegion, + pWin->background.pixmap, x_off, y_off); + } + + RegionTranslate(pRegion, -x_screen, -y_screen); + } + } + + SCREEN_EPILOGUE(pScreen, PaintWindowBackground, cwPaintWindowBackground); +} + +static void +cwPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, PaintWindowBorder); + + if (!cwDrawableIsRedirWindow((DrawablePtr)pWin)) { + (*pScreen->PaintWindowBorder)(pWin, pRegion, what); + } else { + DrawablePtr pBackingDrawable; + int x_off, y_off, x_screen, y_screen; + + pBackingDrawable = cwGetBackingDrawable((DrawablePtr)pWin, &x_off, + &y_off); + + x_screen = x_off - pWin->drawable.x; + y_screen = y_off - pWin->drawable.y; + + RegionTranslate(pRegion, x_screen, y_screen); + + if (pWin->borderIsPixel) { + cwFillRegionSolid(pBackingDrawable, pRegion, pWin->border.pixel); + } else { + cwFillRegionTiled(pBackingDrawable, pRegion, pWin->border.pixmap, + x_off, y_off); + } + + RegionTranslate(pRegion, -x_screen, -y_screen); + } + + SCREEN_EPILOGUE(pScreen, PaintWindowBorder, cwPaintWindowBorder); +} + +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 = RegionExtents(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) */ + RegionTranslate(prgnSrc, -dx, -dy); + + pGC = GetScratchGC(pBackingPixmap->drawable.depth, pScreen); + /* + * Copy region to GC as clip, aligning as dest clip + */ + pClip = RegionCreate(NULL, 0); + RegionIntersect(pClip, &pWin->borderClip, prgnSrc); + RegionTranslate(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; + + if (cwDisabled[pScreen->myNum]) + return; + + if (cwGeneration != serverGeneration) + { + cwScreenIndex = AllocateScreenPrivateIndex(); + if (cwScreenIndex < 0) + return; + cwGCIndex = AllocateGCPrivateIndex(); + cwWindowIndex = AllocateWindowPrivateIndex(); +#ifdef RENDER + cwPictureIndex = AllocatePicturePrivateIndex(); +#endif + cwGeneration = serverGeneration; + } + if (!AllocateGCPrivate(pScreen, cwGCIndex, sizeof(cwGCRec))) + return; + if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0)) + return; +#ifdef RENDER + if (!AllocatePicturePrivate(pScreen, cwPictureIndex, 0)) + return; +#endif + pScreenPriv = (cwScreenPtr)malloc(sizeof(cwScreenRec)); + if (!pScreenPriv) + return; + + pScreen->devPrivates[cwScreenIndex].ptr = (void *)pScreenPriv; + + SCREEN_EPILOGUE(pScreen, CloseScreen, cwCloseScreen); + SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage); + SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans); + SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); + SCREEN_EPILOGUE(pScreen, PaintWindowBackground, cwPaintWindowBackground); + SCREEN_EPILOGUE(pScreen, PaintWindowBorder, cwPaintWindowBorder); + SCREEN_EPILOGUE(pScreen, CopyWindow, cwCopyWindow); + + SCREEN_EPILOGUE(pScreen, SetWindowPixmap, cwSetWindowPixmap); + SCREEN_EPILOGUE(pScreen, GetWindowPixmap, cwGetWindowPixmap); + +#ifdef RENDER + if (GetPictureScreen (pScreen)) + cwInitializeRender(pScreen); +#endif +} + +void +miDisableCompositeWrapper(ScreenPtr pScreen) +{ + cwDisabled[pScreen->myNum] = TRUE; +} + +static Bool +cwCloseScreen (ScreenPtr pScreen) +{ + cwScreenPtr pScreenPriv; +#ifdef RENDER + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); +#endif + + pScreenPriv = (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr; + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->CreateGC = pScreenPriv->CreateGC; + pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground; + pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder; + pScreen->CopyWindow = pScreenPriv->CopyWindow; + +#ifdef RENDER + if (ps) + cwFiniRender(pScreen); +#endif + + free((void *)pScreenPriv); + + return (*pScreen->CloseScreen)(pScreen); +} diff --git a/nx-X11/programs/Xserver/miext/cw/cw.h b/nx-X11/programs/Xserver/miext/cw/cw.h new file mode 100644 index 000000000..de4746be6 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/cw/cw.h @@ -0,0 +1,173 @@ +/* + * 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. + */ +/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw.h,v 1.14 2005/12/09 18:32:46 ajax Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "gcstruct.h" +#include "picturestr.h" + +/* + * One of these structures is allocated per GC that gets used with a window with + * backing pixmap. + */ + +typedef struct { + GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures + * set FALSE and the clientClip set to + * clip output to the valid regions of the + * backing pixmap. */ + unsigned long serialNumber; /* clientClip computed time */ + unsigned long stateChanges; /* changes in parent gc since last copy */ + GCOps *wrapOps; /* wrapped ops */ + GCFuncs *wrapFuncs; /* wrapped funcs */ +} cwGCRec, *cwGCPtr; + +extern int cwGCIndex; + +#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr) +#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (void *) (p)) + +/* + * One of these structures is allocated per Picture that gets used with a + * window with a backing pixmap + */ + +typedef struct { + PicturePtr pBackingPicture; + unsigned long serialNumber; + unsigned long stateChanges; +} cwPictureRec, *cwPicturePtr; + +#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr) +#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (void *) (p)) + +extern int cwPictureIndex; + +extern int cwWindowIndex; + +#define cwWindowPrivate(pWindow) ((pWindow)->devPrivates[cwWindowIndex].ptr) +#define getCwPixmap(pWindow) ((PixmapPtr) cwWindowPrivate(pWindow)) +#define setCwPixmap(pWindow,pPixmap) (cwWindowPrivate(pWindow) = (void *) (pPixmap)) + +#define cwDrawableIsRedirWindow(pDraw) \ + ((pDraw)->type == DRAWABLE_WINDOW && \ + getCwPixmap((WindowPtr) (pDraw)) != NULL) + +typedef struct { + /* + * screen func wrappers + */ + CloseScreenProcPtr CloseScreen; + GetImageProcPtr GetImage; + GetSpansProcPtr GetSpans; + CreateGCProcPtr CreateGC; + + PaintWindowBackgroundProcPtr PaintWindowBackground; + PaintWindowBorderProcPtr PaintWindowBorder; + CopyWindowProcPtr CopyWindow; + + GetWindowPixmapProcPtr GetWindowPixmap; + SetWindowPixmapProcPtr SetWindowPixmap; + +#ifdef RENDER + DestroyPictureProcPtr DestroyPicture; + ChangePictureClipProcPtr ChangePictureClip; + DestroyPictureClipProcPtr DestroyPictureClip; + + ChangePictureProcPtr ChangePicture; + ValidatePictureProcPtr ValidatePicture; + + CompositeProcPtr Composite; + CompositeRectsProcPtr CompositeRects; + + TrapezoidsProcPtr Trapezoids; + TrianglesProcPtr Triangles; + TriStripProcPtr TriStrip; + TriFanProcPtr TriFan; + + RasterizeTrapezoidProcPtr RasterizeTrapezoid; +#endif +} cwScreenRec, *cwScreenPtr; + +extern int cwScreenIndex; + +#define getCwScreen(pScreen) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr) +#define setCwScreen(pScreen,p) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr = (p)) + +#define CW_OFFSET_XYPOINTS(ppt, npt) do { \ + DDXPointPtr _ppt = (DDXPointPtr)(ppt); \ + int _i; \ + for (_i = 0; _i < npt; _i++) { \ + _ppt[_i].x += dst_off_x; \ + _ppt[_i].y += dst_off_y; \ + } \ +} while (0) + +#define CW_OFFSET_RECTS(prect, nrect) do { \ + int _i; \ + for (_i = 0; _i < nrect; _i++) { \ + (prect)[_i].x += dst_off_x; \ + (prect)[_i].y += dst_off_y; \ + } \ +} while (0) + +#define CW_OFFSET_ARCS(parc, narc) do { \ + int _i; \ + for (_i = 0; _i < narc; _i++) { \ + (parc)[_i].x += dst_off_x; \ + (parc)[_i].y += dst_off_y; \ + } \ +} while (0) + +#define CW_OFFSET_XY_DST(x, y) do { \ + (x) = (x) + dst_off_x; \ + (y) = (y) + dst_off_y; \ +} while (0) + +#define CW_OFFSET_XY_SRC(x, y) do { \ + (x) = (x) + src_off_x; \ + (y) = (y) + src_off_y; \ +} while (0) + +/* cw.c */ +DrawablePtr +cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off); + +/* cw_render.c */ + +void +cwInitializeRender (ScreenPtr pScreen); + +void +cwFiniRender (ScreenPtr pScreen); + +/* cw.c */ + +void +miInitializeCompositeWrapper(ScreenPtr pScreen); + +/* Must be called before miInitializeCompositeWrapper */ +void +miDisableCompositeWrapper(ScreenPtr pScreen); diff --git a/nx-X11/programs/Xserver/miext/cw/cw_ops.c b/nx-X11/programs/Xserver/miext/cw/cw_ops.c new file mode 100644 index 000000000..826a0eeca --- /dev/null +++ b/nx-X11/programs/Xserver/miext/cw/cw_ops.c @@ -0,0 +1,472 @@ +/* + * 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. + */ +/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw_ops.c,v 1.9 2005/07/03 07:02:01 daniels Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdlib.h> + +#include "gcstruct.h" +#include "cw.h" + +#define SETUP_BACKING_DST(_pDst, _pGC) \ + cwGCPtr pGCPrivate = getCwGC (_pGC); \ + int dst_off_x, dst_off_y; \ + DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \ + &dst_off_y); \ + GCPtr pBackingGC = pGCPrivate->pBackingGC ? pGCPrivate->pBackingGC : _pGC + +#define SETUP_BACKING_SRC(pSrc, pGC) \ + int src_off_x, src_off_y; \ + DrawablePtr pBackingSrc = cwGetBackingDrawable(pSrc, &src_off_x, \ + &src_off_y) + +#define PROLOGUE(pGC) do { \ + pGC->funcs = pGCPrivate->wrapFuncs;\ + pGC->ops = pGCPrivate->wrapOps;\ +} while (0) + +#define EPILOGUE(pGC) do { \ + pGCPrivate->wrapFuncs = (pGC)->funcs; \ + pGCPrivate->wrapOps = (pGC)->ops; \ + (pGC)->funcs = &cwGCFuncs; \ + (pGC)->ops = &cwGCOps; \ +} while (0) + +extern GCFuncs cwGCFuncs; + +/* + * GC ops -- wrap each GC operation with our own function + */ + +static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit, + DDXPointPtr pptInit, int *pwidthInit, int fSorted); +static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); +static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + char *pBits); +static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, + int dstx, int dsty); +static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, + int dstx, int dsty, unsigned long plane); +static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, + xPoint *pptInit); +static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); +static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, + xSegment *pSegs); +static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, + int nrects, xRectangle *pRects); +static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs); +static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, + int count, DDXPointPtr pPts); +static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, + int nrectFill, xRectangle *prectInit); +static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, + int narcs, xArc *parcs); +static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + int count, char *chars); +static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, + int count, char *chars); +static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, + unsigned int nglyph, CharInfoPtr *ppci, + void * pglyphBase); +static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, + unsigned int nglyph, CharInfoPtr *ppci, + void * pglyphBase); +static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, + int w, int h, int x, int y); + +GCOps cwGCOps = { + cwFillSpans, + cwSetSpans, + cwPutImage, + cwCopyArea, + cwCopyPlane, + cwPolyPoint, + cwPolylines, + cwPolySegment, + cwPolyRectangle, + cwPolyArc, + cwFillPolygon, + cwPolyFillRect, + cwPolyFillArc, + cwPolyText8, + cwPolyText16, + cwImageText8, + cwImageText16, + cwImageGlyphBlt, + cwPolyGlyphBlt, + cwPushPixels +}; + +static void +cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt, + int *pwidth, int fSorted) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XYPOINTS(ppt, nspans); + + (*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC, nspans, ppt, + pwidth, fSorted); + + EPILOGUE(pGC); +} + +static void +cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt, + int *pwidth, int nspans, int fSorted) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XYPOINTS(ppt, nspans); + + (*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc, ppt, pwidth, + nspans, fSorted); + + EPILOGUE(pGC); +} + +static void +cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h, + int leftPad, int format, char *pBits) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, x, y, w, h, + leftPad, format, pBits); + + EPILOGUE(pGC); +} + +static RegionPtr +cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, + int w, int h, int dstx, int dsty) +{ + int odstx, odsty; + RegionPtr exposed = NULL; + SETUP_BACKING_DST(pDst, pGC); + SETUP_BACKING_SRC(pSrc, pGC); + + PROLOGUE(pGC); + + odstx = dstx; + odsty = dsty; + CW_OFFSET_XY_DST(dstx, dsty); + CW_OFFSET_XY_SRC(srcx, srcy); + + exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst, + pBackingGC, srcx, srcy, w, h, + dstx, dsty); + + if (exposed != NULL) + RegionTranslate(exposed, odstx - dstx, odsty - dsty); + + EPILOGUE(pGC); + + return exposed; +} + +static RegionPtr +cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, + int w, int h, int dstx, int dsty, unsigned long plane) +{ + int odstx, odsty; + RegionPtr exposed = NULL; + SETUP_BACKING_DST(pDst, pGC); + SETUP_BACKING_SRC(pSrc, pGC); + + PROLOGUE(pGC); + + odstx = dstx; + odsty = dsty; + CW_OFFSET_XY_DST(dstx, dsty); + CW_OFFSET_XY_SRC(srcx, srcy); + + exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst, + pBackingGC, srcx, srcy, w, h, + dstx, dsty, plane); + + if (exposed != NULL) + RegionTranslate(exposed, odstx - dstx, odsty - dsty); + + EPILOGUE(pGC); + + return exposed; +} + +static void +cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + if (mode == CoordModeOrigin) + CW_OFFSET_XYPOINTS(ppt, npt); + else + CW_OFFSET_XYPOINTS(ppt, 1); + + (*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt, ppt); + + EPILOGUE(pGC); +} + +static void +cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + if (mode == CoordModeOrigin) + CW_OFFSET_XYPOINTS(ppt, npt); + else + CW_OFFSET_XYPOINTS(ppt, 1); + + (*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt, ppt); + + EPILOGUE(pGC); +} + +static void +cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XYPOINTS(pSegs, nseg * 2); + + (*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg, pSegs); + + EPILOGUE(pGC); +} + +static void +cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_RECTS(pRects, nrects); + + (*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects, pRects); + + EPILOGUE(pGC); +} + +static void +cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_RECTS(pArcs, narcs); + + (*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs, pArcs); + + EPILOGUE(pGC); +} + +static void +cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt, + DDXPointPtr ppt) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + if (mode == CoordModeOrigin) + CW_OFFSET_XYPOINTS(ppt, npt); + else + CW_OFFSET_XYPOINTS(ppt, 1); + + (*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode, npt, + ppt); + + EPILOGUE(pGC); +} + +static void +cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_RECTS(pRects, nrects); + + (*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects, pRects); + + EPILOGUE(pGC); +} + +static void +cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_RECTS(parcs, narcs); + + (*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs, parcs); + + EPILOGUE(pGC); +} + +static int +cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars) +{ + int result; + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, x, y, + count, chars); + + EPILOGUE(pGC); + + return result; +} + +static int +cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, + unsigned short *chars) +{ + int result; + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, x, y, + count, chars); + + EPILOGUE(pGC); + return result; +} + +static void +cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, x, y, count, + chars); + + EPILOGUE(pGC); +} + +static void +cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, + unsigned short *chars) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, x, y, count, + chars); + + EPILOGUE(pGC); +} + +static void +cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, void * pglyphBase) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph, + ppci, pglyphBase); + + EPILOGUE(pGC); +} + +static void +cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, void * pglyphBase) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, x, y, nglyph, + ppci, pglyphBase); + + EPILOGUE(pGC); +} + +static void +cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h, + int x, int y) +{ + SETUP_BACKING_DST(pDst, pGC); + + PROLOGUE(pGC); + + CW_OFFSET_XY_DST(x, y); + + (*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h, + x, y); + + EPILOGUE(pGC); +} + diff --git a/nx-X11/programs/Xserver/miext/cw/cw_render.c b/nx-X11/programs/Xserver/miext/cw/cw_render.c new file mode 100644 index 000000000..a44d7c4d2 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/cw/cw_render.c @@ -0,0 +1,473 @@ +/* + * 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. + */ +/* $Header: /cvs/xorg/xc/programs/Xserver/miext/cw/cw_render.c,v 1.14 2005/07/03 07:02:01 daniels Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> + +#include "gcstruct.h" +#include "windowstr.h" +#include "cw.h" + +#ifdef RENDER + +#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); +} + +#endif /* RENDER */ |