summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2014-04-10 13:42:42 -0400
committerKeith Packard <keithp@keithp.com>2014-04-21 21:33:52 -0700
commit2dcb1672620ef5f16111517e9e7a98cf97deb678 (patch)
tree10c74c2bb11a5263df7ed1125433ebbf25394e0e
parent8edeac202ecbace859b7889dd811424471dcca73 (diff)
shadowfb: Port to miext/damage (#31303, #65547)
Somewhat shocking how much simpler this is, isn't it? We no longer need to wrap the screen or GC or Picture, because damage does it for us, which is doubly great since the old shadowfb code didn't wrap _enough_ things (border updates and Render glyphs, at least). The only real difference now between this and shadow is a) shadow will let you track arbitrary pixmaps, and b) shadow's update hook runs off the BlockHandler whereas shadowfb is immediate. Tested on nouveau. Signed-off-by: Adam Jackson <ajax@redhat.com> Reviewed-by: Keith Packard <keithp@keithp.com> Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--hw/xfree86/shadowfb/shadow.c1587
1 files changed, 58 insertions, 1529 deletions
diff --git a/hw/xfree86/shadowfb/shadow.c b/hw/xfree86/shadowfb/shadow.c
index 43529398a..7412213fe 100644
--- a/hw/xfree86/shadowfb/shadow.c
+++ b/hw/xfree86/shadowfb/shadow.c
@@ -1,8 +1,8 @@
/*
Copyright (C) 1999. The XFree86 Project Inc.
+ Copyright 2014 Red Hat, Inc.
Written by Mark Vojkovich (mvojkovi@ucsd.edu)
-
Pre-fb-write callbacks and RENDER support - Nolan Leake (nolan@vmware.com)
*/
@@ -29,107 +29,22 @@
#include "picturestr.h"
static Bool ShadowCloseScreen(ScreenPtr pScreen);
-static void ShadowCopyWindow(WindowPtr pWin,
- DDXPointRec ptOldOrg, RegionPtr prgn);
-static Bool ShadowCreateGC(GCPtr pGC);
-
-static Bool ShadowEnterVT(ScrnInfoPtr pScrn);
-static void ShadowLeaveVT(ScrnInfoPtr pScrn);
-
-static void ShadowComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst, CARD16 width, CARD16 height);
+static Bool ShadowCreateScreenResources(ScreenPtr pScreen);
typedef struct {
ScrnInfoPtr pScrn;
RefreshAreaFuncPtr preRefresh;
RefreshAreaFuncPtr postRefresh;
CloseScreenProcPtr CloseScreen;
- CopyWindowProcPtr CopyWindow;
- CreateGCProcPtr CreateGC;
- ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
- CompositeProcPtr Composite;
- Bool (*EnterVT) (ScrnInfoPtr);
- void (*LeaveVT) (ScrnInfoPtr);
- Bool vtSema;
} ShadowScreenRec, *ShadowScreenPtr;
-typedef struct {
- const GCOps *ops;
- const GCFuncs *funcs;
-} ShadowGCRec, *ShadowGCPtr;
-
static DevPrivateKeyRec ShadowScreenKeyRec;
-#define ShadowScreenKey (&ShadowScreenKeyRec)
-
-static DevPrivateKeyRec ShadowGCKeyRec;
-
-#define ShadowGCKey (&ShadowGCKeyRec)
-
-#define GET_SCREEN_PRIVATE(pScreen) \
- (ShadowScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, ShadowScreenKey)
-#define GET_GC_PRIVATE(pGC) \
- (ShadowGCPtr)dixLookupPrivate(&(pGC)->devPrivates, ShadowGCKey)
-
-#define SHADOW_GC_FUNC_PROLOGUE(pGC)\
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
- (pGC)->funcs = pGCPriv->funcs;\
- if(pGCPriv->ops)\
- (pGC)->ops = pGCPriv->ops
-
-#define SHADOW_GC_FUNC_EPILOGUE(pGC)\
- pGCPriv->funcs = (pGC)->funcs;\
- (pGC)->funcs = &ShadowGCFuncs;\
- if(pGCPriv->ops) {\
- pGCPriv->ops = (pGC)->ops;\
- (pGC)->ops = &ShadowGCOps;\
- }
-
-#define SHADOW_GC_OP_PROLOGUE(pGC)\
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
- const GCFuncs *oldFuncs = pGC->funcs;\
- pGC->funcs = pGCPriv->funcs;\
- pGC->ops = pGCPriv->ops
-
-#define SHADOW_GC_OP_EPILOGUE(pGC)\
- pGCPriv->ops = pGC->ops;\
- pGC->funcs = oldFuncs;\
- pGC->ops = &ShadowGCOps
-
-#define IS_VISIBLE(pWin) (pPriv->vtSema && \
- (((WindowPtr)pWin)->visibility != VisibilityFullyObscured))
-
-#define TRIM_BOX(box, pGC) { \
- BoxPtr extents = &pGC->pCompositeClip->extents;\
- if(box.x1 < extents->x1) box.x1 = extents->x1; \
- if(box.x2 > extents->x2) box.x2 = extents->x2; \
- if(box.y1 < extents->y1) box.y1 = extents->y1; \
- if(box.y2 > extents->y2) box.y2 = extents->y2; \
- }
-
-#define TRANSLATE_BOX(box, pDraw) { \
- box.x1 += pDraw->x; \
- box.x2 += pDraw->x; \
- box.y1 += pDraw->y; \
- box.y2 += pDraw->y; \
- }
-
-#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
- TRANSLATE_BOX(box, pDraw); \
- TRIM_BOX(box, pGC); \
- }
-
-#define BOX_NOT_EMPTY(box) \
- (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+static ShadowScreenPtr
+shadowfbGetScreenPrivate(ScreenPtr pScreen)
+{
+ return dixLookupPrivate(&(pScreen)->devPrivates, &ShadowScreenKeyRec)
+}
Bool
ShadowFBInit2(ScreenPtr pScreen,
@@ -146,14 +61,10 @@ ShadowFBInit2(ScreenPtr pScreen,
if (!dixRegisterPrivateKey(&ShadowScreenKeyRec, PRIVATE_SCREEN, 0))
return FALSE;
- if (!dixRegisterPrivateKey
- (&ShadowGCKeyRec, PRIVATE_GC, sizeof(ShadowGCRec)))
- return FALSE;
-
if (!(pPriv = (ShadowScreenPtr) malloc(sizeof(ShadowScreenRec))))
return FALSE;
- dixSetPrivate(&pScreen->devPrivates, ShadowScreenKey, pPriv);
+ dixSetPrivate(&pScreen->devPrivates, &ShadowScreenKeyRec, pPriv);
pPriv->pScrn = pScrn;
pPriv->preRefresh = preRefreshArea;
@@ -161,24 +72,10 @@ ShadowFBInit2(ScreenPtr pScreen,
pPriv->vtSema = TRUE;
pPriv->CloseScreen = pScreen->CloseScreen;
- pPriv->CopyWindow = pScreen->CopyWindow;
- pPriv->CreateGC = pScreen->CreateGC;
- pPriv->ModifyPixmapHeader = pScreen->ModifyPixmapHeader;
-
- pPriv->EnterVT = pScrn->EnterVT;
- pPriv->LeaveVT = pScrn->LeaveVT;
+ pPriv->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CloseScreen = ShadowCloseScreen;
- pScreen->CopyWindow = ShadowCopyWindow;
- pScreen->CreateGC = ShadowCreateGC;
-
- pScrn->EnterVT = ShadowEnterVT;
- pScrn->LeaveVT = ShadowLeaveVT;
-
- if (ps) {
- pPriv->Composite = ps->Composite;
- ps->Composite = ShadowComposite;
- }
+ pScreen->CreateScreenResources = ShadowCreateScreenResources;
return TRUE;
}
@@ -189,1451 +86,83 @@ ShadowFBInit(ScreenPtr pScreen, RefreshAreaFuncPtr refreshArea)
return ShadowFBInit2(pScreen, NULL, refreshArea);
}
-/**********************************************************/
-
-static Bool
-ShadowEnterVT(ScrnInfoPtr pScrn)
-{
- Bool ret;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen);
-
- pScrn->EnterVT = pPriv->EnterVT;
- ret = (*pPriv->EnterVT) (pScrn);
- pPriv->EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = ShadowEnterVT;
- if (ret) {
- pPriv->vtSema = TRUE;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-ShadowLeaveVT(ScrnInfoPtr pScrn)
-{
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen);
-
- pPriv->vtSema = FALSE;
-
- pScrn->LeaveVT = pPriv->LeaveVT;
- (*pPriv->LeaveVT) (pScrn);
- pPriv->LeaveVT = pScrn->LeaveVT;
- pScrn->LeaveVT = ShadowLeaveVT;
-}
-
-/**********************************************************/
-
-static Bool
-ShadowCloseScreen(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- pScreen->CloseScreen = pPriv->CloseScreen;
- pScreen->CopyWindow = pPriv->CopyWindow;
- pScreen->CreateGC = pPriv->CreateGC;
- pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
-
- pScrn->EnterVT = pPriv->EnterVT;
- pScrn->LeaveVT = pPriv->LeaveVT;
-
- if (ps) {
- ps->Composite = pPriv->Composite;
- }
-
- free((void *) pPriv);
-
- return (*pScreen->CloseScreen) (pScreen);
-}
+/*
+ * Note that we don't do DamageEmpty, or indeed look at the region inside the
+ * DamagePtr at all. This is an optimization, believe it or not. The
+ * incoming RegionPtr is the new damage, and if we were to empty the region
+ * miext/damage would just have to waste time reallocating and re-unioning
+ * it every time, whereas if we leave it around the union gets fast-pathed
+ * away.
+ */
static void
-ShadowCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgn)
+shadowfbReportPre(DamagePtr damage, RegionPtr reg, void *closure)
{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- int num = 0;
- RegionRec rgnDst;
-
- if (pPriv->vtSema) {
- RegionNull(&rgnDst);
- RegionCopy(&rgnDst, prgn);
-
- RegionTranslate(&rgnDst,
- pWin->drawable.x - ptOldOrg.x,
- pWin->drawable.y - ptOldOrg.y);
- RegionIntersect(&rgnDst, &pWin->borderClip, &rgnDst);
- if ((num = RegionNumRects(&rgnDst))) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst));
- }
- else {
- RegionUninit(&rgnDst);
- }
- }
+ ShadowScreenPtr pPriv = closure;
- pScreen->CopyWindow = pPriv->CopyWindow;
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn);
- pScreen->CopyWindow = ShadowCopyWindow;
+ if (!pPriv->pScrn->vtSema)
+ return;
- if (num) {
- if (pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, num, RegionRects(&rgnDst));
- RegionUninit(&rgnDst);
- }
+ pPriv->preRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg));
}
static void
-ShadowComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+shadowfbReportPost(DamagePtr damage, RegionPtr reg, void *closure)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec box;
- BoxPtr extents;
- Bool boxNotEmpty = FALSE;
-
- if (pPriv->vtSema && pDst->pDrawable->type == DRAWABLE_WINDOW) {
-
- box.x1 = pDst->pDrawable->x + xDst;
- box.y1 = pDst->pDrawable->y + yDst;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- extents = &pDst->pCompositeClip->extents;
- if (box.x1 < extents->x1)
- box.x1 = extents->x1;
- if (box.x2 > extents->x2)
- box.x2 = extents->x2;
- if (box.y1 < extents->y1)
- box.y1 = extents->y1;
- if (box.y2 > extents->y2)
- box.y2 = extents->y2;
-
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
+ ShadowScreenPtr pPriv = closure;
- ps->Composite = pPriv->Composite;
- (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc,
- xMask, yMask, xDst, yDst, width, height);
- ps->Composite = ShadowComposite;
+ if (!pPriv->pScrn->vtSema)
+ return;
- if (pPriv->postRefresh && boxNotEmpty) {
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
+ pPriv->postRefresh(pPriv->pScrn, RegionNumRects(reg), RegionRects(reg));
}
-/**********************************************************/
-
-static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void ShadowChangeGC(GCPtr, unsigned long);
-static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
-static void ShadowDestroyGC(GCPtr);
-static void ShadowChangeClip(GCPtr, int, void *, int);
-static void ShadowDestroyClip(GCPtr);
-static void ShadowCopyClip(GCPtr, GCPtr);
-
-GCFuncs ShadowGCFuncs = {
- ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC,
- ShadowChangeClip, ShadowDestroyClip, ShadowCopyClip
-};
-
-extern GCOps ShadowGCOps;
-
static Bool
-ShadowCreateGC(GCPtr pGC)
+ShadowCreateScreenResources(ScreenPtr pScreen)
{
- ScreenPtr pScreen = pGC->pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);
Bool ret;
+ WindowPtr pWin = pScreen->root;
+ ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen);
- pScreen->CreateGC = pPriv->CreateGC;
- if ((ret = (*pScreen->CreateGC) (pGC))) {
- pGCPriv->ops = NULL;
- pGCPriv->funcs = pGC->funcs;
- pGC->funcs = &ShadowGCFuncs;
- }
- pScreen->CreateGC = ShadowCreateGC;
-
- return ret;
-}
-
-static void
-ShadowValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGC);
- (*pGC->funcs->ValidateGC) (pGC, changes, pDraw);
- if (pDraw->type == DRAWABLE_WINDOW)
- pGCPriv->ops = pGC->ops; /* just so it's not NULL */
- else
- pGCPriv->ops = NULL;
- SHADOW_GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-ShadowDestroyGC(GCPtr pGC)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGC);
- (*pGC->funcs->DestroyGC) (pGC);
- SHADOW_GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-ShadowChangeGC(GCPtr pGC, unsigned long mask)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- SHADOW_GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-ShadowCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- SHADOW_GC_FUNC_EPILOGUE(pGCDst);
-}
-
-static void
-ShadowChangeClip(GCPtr pGC, int type, void *pvalue, int nrects)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- SHADOW_GC_FUNC_EPILOGUE(pGC);
-}
-
-static void
-ShadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- SHADOW_GC_FUNC_PROLOGUE(pgcDst);
- (*pgcDst->funcs->CopyClip) (pgcDst, pgcSrc);
- SHADOW_GC_FUNC_EPILOGUE(pgcDst);
-}
-
-static void
-ShadowDestroyClip(GCPtr pGC)
-{
- SHADOW_GC_FUNC_PROLOGUE(pGC);
- (*pGC->funcs->DestroyClip) (pGC);
- SHADOW_GC_FUNC_EPILOGUE(pGC);
-}
-
-/**********************************************************/
-
-static void
-ShadowFillSpans(DrawablePtr pDraw,
- GC * pGC,
- int nInit, DDXPointPtr pptInit, int *pwidthInit, int fSorted)
-{
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nInit) {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nInit;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
+ pScreen->CreateScreenResources = pPriv->CreateScreenResources;
+ ret = pScreen->CreateScreenResources(pWin);
+ pPriv->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = ShadowCreateScreenResources;
- while (--i) {
- ppt++;
- pwidth++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- if (box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
-
- box.y2++;
-
- if (!pGC->miTranslate) {
- TRANSLATE_BOX(box, pDraw);
- }
- TRIM_BOX(box, pGC);
-
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->FillSpans) (pDraw, pGC, nInit, pptInit, pwidthInit,
- fSorted);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
- else
- (*pGC->ops->FillSpans) (pDraw, pGC, nInit, pptInit, pwidthInit,
- fSorted);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowSetSpans(DrawablePtr pDraw,
- GCPtr pGC,
- char *pcharsrc,
- DDXPointPtr pptInit, int *pwidthInit, int nspans, int fSorted)
-{
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nspans) {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nspans;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
-
- while (--i) {
- ppt++;
- pwidth++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- if (box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
-
- box.y2++;
-
- if (!pGC->miTranslate) {
- TRANSLATE_BOX(box, pDraw);
- }
- TRIM_BOX(box, pGC);
-
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->SetSpans) (pDraw, pGC, pcharsrc, pptInit,
- pwidthInit, nspans, fSorted);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
- else
- (*pGC->ops->SetSpans) (pDraw, pGC, pcharsrc, pptInit,
- pwidthInit, nspans, fSorted);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPutImage(DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x, int y, int w, int h,
- int leftPad, int format, char *pImage)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw)) {
- box.x1 = x + pDraw->x;
- box.x2 = box.x1 + w;
- box.y1 = y + pDraw->y;
- box.y2 = box.y1 + h;
+ /* this might look like it leaks, but the damage code reaps listeners
+ * when their drawable disappears.
+ */
+ if (ret) {
+ DamagePtr damage;
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
+ if (pPriv->preRefresh) {
+ damage = DamageCreate(shadowfbReportPre, NULL,
+ DamageReportRawRegion,
+ TRUE, pScreen, pPriv);
+ DamageRegister(&pWin->drawable, damage);
}
- }
-
- (*pGC->ops->PutImage) (pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static RegionPtr
-ShadowCopyArea(DrawablePtr pSrc,
- DrawablePtr pDst,
- GC * pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty)
-{
- RegionPtr ret;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDst)) {
- box.x1 = dstx + pDst->x;
- box.x2 = box.x1 + width;
- box.y1 = dsty + pDst->y;
- box.y2 = box.y1 + height;
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
+ if (pPriv->postRefresh) {
+ damage = DamageCreate(shadowfbReportPost, NULL,
+ DamageReportRawRegion,
+ TRUE, pScreen, pPriv);
+ DamageSetReportAfterOp(damage, TRUE);
+ DamageRegister(&pWin->drawable, damage);
}
}
- ret = (*pGC->ops->CopyArea) (pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
return ret;
}
-static RegionPtr
-ShadowCopyPlane(DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty, unsigned long bitPlane)
-{
- RegionPtr ret;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDst)) {
- box.x1 = dstx + pDst->x;
- box.x2 = box.x1 + width;
- box.y1 = dsty + pDst->y;
- box.y2 = box.y1 + height;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- ret = (*pGC->ops->CopyPlane) (pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty,
- bitPlane);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return ret;
-}
-
-static void
-ShadowPolyPoint(DrawablePtr pDraw,
- GCPtr pGC, int mode, int nptInit, xPoint * pptInit)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nptInit) {
- xPoint *ppt = pptInit;
- int npt = nptInit;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
-
- /* this could be slow if the points were spread out */
-
- while (--npt) {
- ppt++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- else if (box.x2 < ppt->x)
- box.x2 = ppt->x;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyPoint) (pDraw, pGC, mode, nptInit, pptInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolylines(DrawablePtr pDraw,
- GCPtr pGC, int mode, int nptInit, DDXPointPtr pptInit)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nptInit) {
- DDXPointPtr ppt = pptInit;
- int npt = nptInit;
- int extra = pGC->lineWidth >> 1;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
-
- if (npt > 1) {
- if (pGC->joinStyle == JoinMiter)
- extra = 6 * pGC->lineWidth;
- else if (pGC->capStyle == CapProjecting)
- extra = pGC->lineWidth;
- }
-
- if (mode == CoordModePrevious) {
- int x = box.x1;
- int y = box.y1;
-
- while (--npt) {
- ppt++;
- x += ppt->x;
- y += ppt->y;
- if (box.x1 > x)
- box.x1 = x;
- else if (box.x2 < x)
- box.x2 = x;
- if (box.y1 > y)
- box.y1 = y;
- else if (box.y2 < y)
- box.y2 = y;
- }
- }
- else {
- while (--npt) {
- ppt++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- else if (box.x2 < ppt->x)
- box.x2 = ppt->x;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->Polylines) (pDraw, pGC, mode, nptInit, pptInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolySegment(DrawablePtr pDraw,
- GCPtr pGC, int nsegInit, xSegment * pSegInit)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nsegInit) {
- int extra = pGC->lineWidth;
- xSegment *pSeg = pSegInit;
- int nseg = nsegInit;
-
- if (pGC->capStyle != CapProjecting)
- extra >>= 1;
-
- if (pSeg->x2 > pSeg->x1) {
- box.x1 = pSeg->x1;
- box.x2 = pSeg->x2;
- }
- else {
- box.x2 = pSeg->x1;
- box.x1 = pSeg->x2;
- }
-
- if (pSeg->y2 > pSeg->y1) {
- box.y1 = pSeg->y1;
- box.y2 = pSeg->y2;
- }
- else {
- box.y2 = pSeg->y1;
- box.y1 = pSeg->y2;
- }
-
- while (--nseg) {
- pSeg++;
- if (pSeg->x2 > pSeg->x1) {
- if (pSeg->x1 < box.x1)
- box.x1 = pSeg->x1;
- if (pSeg->x2 > box.x2)
- box.x2 = pSeg->x2;
- }
- else {
- if (pSeg->x2 < box.x1)
- box.x1 = pSeg->x2;
- if (pSeg->x1 > box.x2)
- box.x2 = pSeg->x1;
- }
- if (pSeg->y2 > pSeg->y1) {
- if (pSeg->y1 < box.y1)
- box.y1 = pSeg->y1;
- if (pSeg->y2 > box.y2)
- box.y2 = pSeg->y2;
- }
- else {
- if (pSeg->y2 < box.y1)
- box.y1 = pSeg->y2;
- if (pSeg->y1 > box.y2)
- box.y2 = pSeg->y1;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolySegment) (pDraw, pGC, nsegInit, pSegInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyRectangle(DrawablePtr pDraw,
- GCPtr pGC, int nRectsInit, xRectangle *pRectsInit)
-{
- BoxRec box;
- BoxPtr pBoxInit = NULL;
- Bool boxNotEmpty = FALSE;
- int num = 0;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nRectsInit) {
- xRectangle *pRects = pRectsInit;
- int nRects = nRectsInit;
-
- if (nRects >= 32) {
- int extra = pGC->lineWidth >> 1;
-
- box.x1 = pRects->x;
- box.x2 = box.x1 + pRects->width;
- box.y1 = pRects->y;
- box.y2 = box.y1 + pRects->height;
-
- while (--nRects) {
- pRects++;
- if (box.x1 > pRects->x)
- box.x1 = pRects->x;
- if (box.x2 < (pRects->x + pRects->width))
- box.x2 = pRects->x + pRects->width;
- if (box.y1 > pRects->y)
- box.y1 = pRects->y;
- if (box.y2 < (pRects->y + pRects->height))
- box.y2 = pRects->y + pRects->height;
- }
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
- else {
- BoxPtr pbox;
- int offset1, offset2, offset3;
-
- offset2 = pGC->lineWidth;
- if (!offset2)
- offset2 = 1;
- offset1 = offset2 >> 1;
- offset3 = offset2 - offset1;
-
- pBoxInit = (BoxPtr) malloc(nRects * 4 * sizeof(BoxRec));
- pbox = pBoxInit;
-
- while (nRects--) {
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y - offset1;
- pbox->x2 = pbox->x1 + pRects->width + offset2;
- pbox->y2 = pbox->y1 + offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if (BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y + offset3;
- pbox->x2 = pbox->x1 + offset2;
- pbox->y2 = pbox->y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if (BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x + pRects->width - offset1;
- pbox->y1 = pRects->y + offset3;
- pbox->x2 = pbox->x1 + offset2;
- pbox->y2 = pbox->y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if (BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y + pRects->height - offset1;
- pbox->x2 = pbox->x1 + pRects->width + offset2;
- pbox->y2 = pbox->y1 + offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if (BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pRects++;
- }
-
- if (num) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, num, pBoxInit);
- }
- else {
- free(pBoxInit);
- }
- }
- }
-
- (*pGC->ops->PolyRectangle) (pDraw, pGC, nRectsInit, pRectsInit);
-
- if (boxNotEmpty && pPriv->postRefresh) {
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
- else if (num) {
- if (pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, num, pBoxInit);
- free(pBoxInit);
- }
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static void
-ShadowPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcsInit, xArc * parcsInit)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && narcsInit) {
- int narcs = narcsInit;
- xArc *parcs = parcsInit;
- int extra = pGC->lineWidth >> 1;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while (--narcs) {
- parcs++;
- if (box.x1 > parcs->x)
- box.x1 = parcs->x;
- if (box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if (box.y1 > parcs->y)
- box.y1 = parcs->y;
- if (box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- if (extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyArc) (pDraw, pGC, narcsInit, parcsInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static void
-ShadowFillPolygon(DrawablePtr pDraw,
- GCPtr pGC,
- int shape, int mode, int count, DDXPointPtr pptInit)
-{
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && (count > 2)) {
- DDXPointPtr ppt = pptInit;
- int i = count;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x2 = box.x1 = ppt->x;
- box.y2 = box.y1 = ppt->y;
-
- if (mode != CoordModeOrigin) {
- int x = box.x1;
- int y = box.y1;
-
- while (--i) {
- ppt++;
- x += ppt->x;
- y += ppt->y;
- if (box.x1 > x)
- box.x1 = x;
- else if (box.x2 < x)
- box.x2 = x;
- if (box.y1 > y)
- box.y1 = y;
- else if (box.y2 < y)
- box.y2 = y;
- }
- }
- else {
- while (--i) {
- ppt++;
- if (box.x1 > ppt->x)
- box.x1 = ppt->x;
- else if (box.x2 < ppt->x)
- box.x2 = ppt->x;
- if (box.y1 > ppt->y)
- box.y1 = ppt->y;
- else if (box.y2 < ppt->y)
- box.y2 = ppt->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->FillPolygon) (pDraw, pGC, shape, mode, count, pptInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
- else
- (*pGC->ops->FillPolygon) (pDraw, pGC, shape, mode, count, pptInit);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyFillRect(DrawablePtr pDraw,
- GCPtr pGC, int nRectsInit, xRectangle *pRectsInit)
-{
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nRectsInit) {
- BoxRec box;
- Bool boxNotEmpty = FALSE;
- xRectangle *pRects = pRectsInit;
- int nRects = nRectsInit;
-
- box.x1 = pRects->x;
- box.x2 = box.x1 + pRects->width;
- box.y1 = pRects->y;
- box.y2 = box.y1 + pRects->height;
-
- while (--nRects) {
- pRects++;
- if (box.x1 > pRects->x)
- box.x1 = pRects->x;
- if (box.x2 < (pRects->x + pRects->width))
- box.x2 = pRects->x + pRects->width;
- if (box.y1 > pRects->y)
- box.y1 = pRects->y;
- if (box.y2 < (pRects->y + pRects->height))
- box.y2 = pRects->y + pRects->height;
- }
-
- /* cfb messes with the pRectsInit so we have to do our
- calculations first */
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->PolyFillRect) (pDraw, pGC, nRectsInit, pRectsInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
- }
- else
- (*pGC->ops->PolyFillRect) (pDraw, pGC, nRectsInit, pRectsInit);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcsInit, xArc * parcsInit)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && narcsInit) {
- xArc *parcs = parcsInit;
- int narcs = narcsInit;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while (--narcs) {
- parcs++;
- if (box.x1 > parcs->x)
- box.x1 = parcs->x;
- if (box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if (box.y1 > parcs->y)
- box.y1 = parcs->y;
- if (box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyFillArc) (pDraw, pGC, narcsInit, parcsInit);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowTextExtent(FontPtr pFont, int count, char *chars,
- FontEncoding fontEncoding, BoxPtr box)
-{
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
-
- GetGlyphs(pFont, (unsigned long) count, (unsigned char *) chars,
- fontEncoding, &n, charinfo);
- w = 0;
- for (i = 0; i < n; i++) {
- w += charinfo[i]->metrics.characterWidth;
- }
- if (i) {
- w += charinfo[i - 1]->metrics.rightSideBearing;
- }
-
- box->x1 = 0;
- if (n) {
- if (charinfo[0]->metrics.leftSideBearing < 0) {
- box->x1 = charinfo[0]->metrics.leftSideBearing;
- }
- }
- box->x2 = w;
- box->y1 = -FONTMAXBOUNDS(pFont, ascent);
- box->y2 = FONTMAXBOUNDS(pFont, descent);
-}
-
-static void
-ShadowFontToBox(BoxPtr BB, DrawablePtr pDrawable, GCPtr pGC, int x, int y,
- int count, char *chars, int wide)
-{
- FontPtr pFont;
-
- pFont = pGC->font;
- if (pFont->info.constantWidth) {
- int ascent, descent, left, right = 0;
-
- ascent = max(pFont->info.fontAscent, pFont->info.maxbounds.ascent);
- descent = max(pFont->info.fontDescent, pFont->info.maxbounds.descent);
- left = pFont->info.maxbounds.leftSideBearing;
- if (count > 0) {
- right = (count - 1) * pFont->info.maxbounds.characterWidth;
- }
- right += pFont->info.maxbounds.rightSideBearing;
- BB->x1 =
- max(pDrawable->x + x - left,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->x1);
- BB->y1 =
- max(pDrawable->y + y - ascent,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->y1);
- BB->x2 =
- min(pDrawable->x + x + right,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->x2);
- BB->y2 =
- min(pDrawable->y + y + descent,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->y2);
- }
- else {
- ShadowTextExtent(pFont, count, chars, wide ? (FONTLASTROW(pFont) == 0)
- ? Linear16Bit : TwoD16Bit : Linear8Bit, BB);
- BB->x1 =
- max(pDrawable->x + x + BB->x1,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->x1);
- BB->y1 =
- max(pDrawable->y + y + BB->y1,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->y1);
- BB->x2 =
- min(pDrawable->x + x + BB->x2,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->x2);
- BB->y2 =
- min(pDrawable->y + y + BB->y2,
- RegionExtents(&((WindowPtr) pDrawable)->winSize)->y2);
- }
-}
-
-static int
-ShadowPolyText8(DrawablePtr pDraw,
- GCPtr pGC, int x, int y, int count, char *chars)
-{
- int width;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw)) {
- ShadowFontToBox(&box, pDraw, pGC, x, y, count, chars, 0);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- width = (*pGC->ops->PolyText8) (pDraw, pGC, x, y, count, chars);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return width;
-}
-
-static int
-ShadowPolyText16(DrawablePtr pDraw,
- GCPtr pGC, int x, int y, int count, unsigned short *chars)
-{
- int width;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw)) {
- ShadowFontToBox(&box, pDraw, pGC, x, y, count, (char *) chars, 1);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- width = (*pGC->ops->PolyText16) (pDraw, pGC, x, y, count, chars);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return width;
-}
-
-static void
-ShadowImageText8(DrawablePtr pDraw,
- GCPtr pGC, int x, int y, int count, char *chars)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && count) {
- int top, bot, Min, Max;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if (Min > 0)
- Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if (Max < 0)
- Max = 0;
-
- /* ugh */
- box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = pDraw->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageText8) (pDraw, pGC, x, y, count, chars);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowImageText16(DrawablePtr pDraw,
- GCPtr pGC, int x, int y, int count, unsigned short *chars)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && count) {
- int top, bot, Min, Max;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if (Min > 0)
- Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if (Max < 0)
- Max = 0;
-
- /* ugh */
- box.x1 = pDraw->x + x + Min + FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = pDraw->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageText16) (pDraw, pGC, x, y, count, chars);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowImageGlyphBlt(DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- unsigned int nglyphInit,
- CharInfoPtr * ppciInit, void *pglyphBase)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nglyphInit) {
- CharInfoPtr *ppci = ppciInit;
- unsigned int nglyph = nglyphInit;
- int top, bot, width = 0;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- box.x1 = ppci[0]->metrics.leftSideBearing;
- if (box.x1 > 0)
- box.x1 = 0;
- box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
- ppci[nglyph - 1]->metrics.characterWidth;
- if (box.x2 < 0)
- box.x2 = 0;
-
- box.x2 += pDraw->x + x;
- box.x1 += pDraw->x + x;
-
- while (nglyph--) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if (width > 0)
- box.x2 += width;
- else
- box.x1 += width;
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageGlyphBlt) (pDraw, pGC, x, y, nglyphInit,
- ppciInit, pglyphBase);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyGlyphBlt(DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- unsigned int nglyphInit,
- CharInfoPtr * ppciInit, void *pglyphBase)
-{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw) && nglyphInit) {
- CharInfoPtr *ppci = ppciInit;
- unsigned int nglyph = nglyphInit;
-
- /* ugh */
- box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing;
- box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
-
- if (nglyph > 1) {
- int width = 0;
-
- while (--nglyph) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if (width > 0)
- box.x2 += width;
- else
- box.x1 += width;
- }
-
- box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
- box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyGlyphBlt) (pDraw, pGC, x, y, nglyphInit,
- ppciInit, pglyphBase);
-
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPushPixels(GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw, int dx, int dy, int xOrg, int yOrg)
+static Bool
+ShadowCloseScreen(ScreenPtr pScreen)
{
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if (IS_VISIBLE(pDraw)) {
- box.x1 = xOrg;
- box.y1 = yOrg;
-
- if (!pGC->miTranslate) {
- box.x1 += pDraw->x;
- box.y1 += pDraw->y;
- }
+ ShadowScreenPtr pPriv = shadowfbGetScreenPrivate(pScreen);
- box.x2 = box.x1 + dx;
- box.y2 = box.y1 + dy;
-
- TRIM_BOX(box, pGC);
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh) (pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PushPixels) (pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ pScreen->CloseScreen = pPriv->CloseScreen;
+ pScreen->CreateScreenResources = pPriv->CreateScreenResources;
- if (boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh) (pPriv->pScrn, 1, &box);
+ free((pointer) pPriv);
- SHADOW_GC_OP_EPILOGUE(pGC);
+ return (*pScreen->CloseScreen) (pScreen);
}
-
-GCOps ShadowGCOps = {
- ShadowFillSpans, ShadowSetSpans,
- ShadowPutImage, ShadowCopyArea,
- ShadowCopyPlane, ShadowPolyPoint,
- ShadowPolylines, ShadowPolySegment,
- ShadowPolyRectangle, ShadowPolyArc,
- ShadowFillPolygon, ShadowPolyFillRect,
- ShadowPolyFillArc, ShadowPolyText8,
- ShadowPolyText16, ShadowImageText8,
- ShadowImageText16, ShadowImageGlyphBlt,
- ShadowPolyGlyphBlt, ShadowPushPixels,
-};