New upstream version 3.5.99.27

This commit is contained in:
geos_one
2025-08-08 20:00:36 +02:00
commit bc8d10cc33
4267 changed files with 1757978 additions and 0 deletions

View File

@@ -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))

View File

@@ -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->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);
}

View File

@@ -0,0 +1,174 @@
/*
* 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) \
(pPicture->pDrawable ? (cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr : 0)
#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);

View File

@@ -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);
}

View File

@@ -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 */