summaryrefslogtreecommitdiff
path: root/miext
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /miext
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'miext')
-rw-r--r--miext/layer/layer.h145
-rw-r--r--miext/layer/layergc.c190
-rw-r--r--miext/layer/layerinit.c359
-rw-r--r--miext/layer/layerpict.c145
-rw-r--r--miext/layer/layerstr.h420
-rw-r--r--miext/layer/layerwin.c483
-rw-r--r--miext/shadow/shadow.c1525
-rw-r--r--miext/shadow/shadow.h172
-rw-r--r--miext/shadow/shalloc.c48
-rw-r--r--miext/shadow/shpacked.c108
-rw-r--r--miext/shadow/shplanar.c168
-rw-r--r--miext/shadow/shplanar8.c170
-rw-r--r--miext/shadow/shrot16pack.c28
-rw-r--r--miext/shadow/shrot16pack_180.c29
-rw-r--r--miext/shadow/shrot16pack_270.c29
-rw-r--r--miext/shadow/shrot16pack_90.c29
-rw-r--r--miext/shadow/shrot32pack.c28
-rw-r--r--miext/shadow/shrot32pack_180.c29
-rw-r--r--miext/shadow/shrot32pack_270.c29
-rw-r--r--miext/shadow/shrot32pack_90.c29
-rw-r--r--miext/shadow/shrot8pack.c28
-rw-r--r--miext/shadow/shrot8pack_180.c29
-rw-r--r--miext/shadow/shrot8pack_270.c29
-rw-r--r--miext/shadow/shrot8pack_90.c29
-rw-r--r--miext/shadow/shrotate.c306
-rw-r--r--miext/shadow/shrotpack.h182
26 files changed, 4766 insertions, 0 deletions
diff --git a/miext/layer/layer.h b/miext/layer/layer.h
new file mode 100644
index 000000000..630438057
--- /dev/null
+++ b/miext/layer/layer.h
@@ -0,0 +1,145 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layer.h,v 1.5 2002/10/03 22:50:21 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _LAYER_H_
+#define _LAYER_H_
+
+#include <shadow.h>
+
+#define LAYER_FB 0
+#define LAYER_SHADOW 1
+
+typedef struct _LayerKind *LayerKindPtr;
+typedef struct _LayerWin *LayerWinPtr;
+typedef struct _LayerList *LayerListPtr;
+typedef struct _LayerGC *LayerGCPtr;
+typedef struct _Layer *LayerPtr;
+typedef struct _LayerScreen *LayerScreenPtr;
+
+/*
+ * We'll try to work without a list of windows in each layer
+ * for now, this will make computing bounding boxes for each
+ * layer rather expensive, so that may need to change at some point.
+ */
+
+#define LAYER_SCREEN_PIXMAP ((PixmapPtr) 1)
+
+typedef struct _Layer {
+ LayerPtr pNext; /* a list of all layers for this screen */
+ LayerKindPtr pKind; /* characteristics of this layer */
+ int refcnt; /* reference count, layer is freed when zero */
+ int windows; /* number of windows, free pixmap when zero */
+ int depth; /* window depth in this layer */
+ PixmapPtr pPixmap; /* pixmap for this layer (may be frame buffer) */
+ Bool freePixmap; /* whether to free this pixmap when done */
+ RegionRec region; /* valid set of pPixmap for drawing */
+ ShadowUpdateProc update; /* for shadow layers, update/window/closure values */
+ ShadowWindowProc window;
+ int randr;
+ void *closure;
+} LayerRec;
+
+/*
+ * Call this before wrapping stuff for acceleration, it
+ * gives layer pointers to the raw frame buffer functions
+ */
+
+Bool
+LayerStartInit (ScreenPtr pScreen);
+
+/*
+ * Initialize wrappers for each acceleration type and
+ * call this function, it will move the needed functions
+ * into a new LayerKind and replace them with the generic
+ * functions.
+ */
+
+int
+LayerNewKind (ScreenPtr pScreen);
+
+/*
+ * Finally, call this function and layer
+ * will wrap the screen functions and prepare for execution
+ */
+
+Bool
+LayerFinishInit (ScreenPtr pScreen);
+
+/*
+ * At any point after LayerStartInit, a new layer can be created.
+ */
+LayerPtr
+LayerCreate (ScreenPtr pScreen,
+ int kind,
+ int depth,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int randr,
+ void *closure);
+
+/*
+ * Create a layer pixmap
+ */
+Bool
+LayerCreatePixmap (ScreenPtr pScreen, LayerPtr pLayer);
+
+/*
+ * Change a layer pixmap
+ */
+void
+LayerSetPixmap (ScreenPtr pScreen, LayerPtr pLayer, PixmapPtr pPixmap);
+
+/*
+ * Destroy a layer pixmap
+ */
+void
+LayerDestroyPixmap (ScreenPtr pScreen, LayerPtr pLayer);
+
+/*
+ * Change a layer kind
+ */
+void
+LayerSetKind (ScreenPtr pScreen, LayerPtr pLayer, int kind);
+
+/*
+ * Destroy a layer. The layer must not contain any windows.
+ */
+void
+LayerDestroy (ScreenPtr pScreen, LayerPtr layer);
+
+/*
+ * Add a window to a layer
+ */
+Bool
+LayerWindowAdd (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin);
+
+/*
+ * Remove a window from a layer
+ */
+
+void
+LayerWindowRemove (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin);
+
+#endif /* _LAYER_H_ */
diff --git a/miext/layer/layergc.c b/miext/layer/layergc.c
new file mode 100644
index 000000000..52490d286
--- /dev/null
+++ b/miext/layer/layergc.c
@@ -0,0 +1,190 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layergc.c,v 1.5 2001/10/28 03:34:15 tsi Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "layerstr.h"
+
+GCFuncs layerGCFuncs = {
+ layerValidateGC, layerChangeGC, layerCopyGC, layerDestroyGC,
+ layerChangeClip, layerDestroyClip, layerCopyClip
+};
+
+#if 0
+/*
+ * XXX dont need this until this supports
+ * separate clipping and multiple layers
+ */
+GCOps layerGCOps = {
+ layerFillSpans, layerSetSpans,
+ layerPutImage, layerCopyArea,
+ layerCopyPlane, layerPolyPoint,
+ layerPolylines, layerPolySegment,
+ layerPolyRectangle, layerPolyArc,
+ layerFillPolygon, layerPolyFillRect,
+ layerPolyFillArc, layerPolyText8,
+ layerPolyText16, layerImageText8,
+ layerImageText16, layerImageGlyphBlt,
+ layerPolyGlyphBlt, layerPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+#endif
+
+Bool
+layerCreateGC (GCPtr pGC)
+{
+ Bool ret = TRUE;
+ LayerKindPtr pLayKind;
+ ScreenPtr pScreen = pGC->pScreen;
+ layerScrPriv(pScreen);
+ layerGCPriv(pGC);
+
+ /*
+ * XXX assume the first layer can handle all GCs
+ */
+ pLayKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pLayKind = pLayScr->pLayers->pKind;
+ pLayGC->pKind = pLayKind;
+ LayerUnwrap (pScreen,pLayGC->pKind,CreateGC);
+
+ if (!(*pScreen->CreateGC) (pGC))
+ ret = FALSE;
+ LayerWrap (pScreen,pLayKind,CreateGC,layerCreateGC);
+
+ LayerWrap (pGC,pLayGC,funcs,&layerGCFuncs);
+
+ return ret;
+}
+
+void
+layerValidateGC(GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw)
+{
+ layerGCPriv(pGC);
+ LayerKindPtr pKind;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ layerWinPriv ((WindowPtr) pDraw);
+ pKind = layerWinLayer (pLayWin)->pKind;
+ }
+ else
+ {
+ /* XXX assume the first layer can handle all pixmaps */
+ layerScrPriv (pDraw->pScreen);
+ pKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pKind = pLayScr->pLayers->pKind;
+ }
+
+ LayerUnwrap (pGC,pLayGC,funcs);
+ if (pKind != pLayGC->pKind)
+ {
+ /*
+ * Clean up the previous user
+ */
+ CreateGCProcPtr CreateGC;
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+
+ pLayGC->pKind = pKind;
+
+ /*
+ * Temporarily unwrap Create GC and let
+ * the new code setup the GC
+ */
+ CreateGC = pGC->pScreen->CreateGC;
+ LayerUnwrap (pGC->pScreen, pLayGC->pKind, CreateGC);
+ (*pGC->pScreen->CreateGC) (pGC);
+ LayerWrap (pGC->pScreen, pLayGC->pKind, CreateGC, CreateGC);
+ }
+
+ (*pGC->funcs->ValidateGC) (pGC, changes, pDraw);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerDestroyGC(GCPtr pGC)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->DestroyGC)(pGC);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerChangeGC (GCPtr pGC,
+ unsigned long mask)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ layerGCPriv(pGCDst);
+ LayerUnwrap (pGCDst,pLayGC,funcs);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ LayerWrap(pGCDst,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerChangeClip (GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+ layerGCPriv(pGCDst);
+ LayerUnwrap (pGCDst,pLayGC,funcs);
+ (*pGCDst->funcs->CopyClip) (pGCDst, pGCSrc);
+ LayerWrap(pGCDst,pLayGC,funcs,&layerGCFuncs);
+}
+
+void
+layerDestroyClip(GCPtr pGC)
+{
+ layerGCPriv(pGC);
+ LayerUnwrap (pGC,pLayGC,funcs);
+ (*pGC->funcs->DestroyClip) (pGC);
+ LayerWrap(pGC,pLayGC,funcs,&layerGCFuncs);
+}
+
diff --git a/miext/layer/layerinit.c b/miext/layer/layerinit.c
new file mode 100644
index 000000000..dfeae6c2d
--- /dev/null
+++ b/miext/layer/layerinit.c
@@ -0,0 +1,359 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerinit.c,v 1.6 2002/11/08 22:19:42 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "layerstr.h"
+
+int layerScrPrivateIndex;
+int layerGCPrivateIndex;
+int layerWinPrivateIndex;
+int layerGeneration;
+
+/*
+ * Call this before wrapping stuff for acceleration, it
+ * gives layer pointers to the raw frame buffer functions
+ */
+
+extern const GCFuncs fbGCFuncs;
+extern GCFuncs shadowGCFuncs;
+
+Bool
+LayerStartInit (ScreenPtr pScreen)
+{
+ LayerScreenPtr pScrPriv;
+
+ if (layerGeneration != serverGeneration)
+ {
+ layerScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (layerScrPrivateIndex == -1)
+ return FALSE;
+ layerGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (layerGCPrivateIndex == -1)
+ return FALSE;
+ layerWinPrivateIndex = AllocateWindowPrivateIndex ();
+ if (layerWinPrivateIndex == -1)
+ return FALSE;
+ layerGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate (pScreen, layerGCPrivateIndex, sizeof (LayerGCRec)))
+ return FALSE;
+ if (!AllocateWindowPrivate (pScreen, layerWinPrivateIndex, sizeof (LayerWinRec)))
+ return FALSE;
+ pScrPriv = (LayerScreenPtr) xalloc (sizeof (LayerScreenRec));
+ if (!pScrPriv)
+ return FALSE;
+ pScrPriv->nkinds = 0;
+ pScrPriv->kinds = 0;
+ pScrPriv->pLayers = 0;
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = (pointer) pScrPriv;
+ /*
+ * Add fb kind -- always 0
+ */
+ if (LayerNewKind (pScreen) < 0)
+ {
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ xfree (pScrPriv);
+ return FALSE;
+ }
+ /*
+ * Add shadow kind -- always 1
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+ if (LayerNewKind (pScreen) < 0)
+ {
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ xfree (pScrPriv->kinds);
+ xfree (pScrPriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Initialize wrappers for each acceleration type and
+ * call this function, it will move the needed functions
+ * into a new LayerKind and replace them with the generic
+ * functions.
+ */
+
+int
+LayerNewKind (ScreenPtr pScreen)
+{
+ layerScrPriv(pScreen);
+ LayerKindPtr pLayKind, pLayKinds;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+#endif
+ LayerPtr pLayer;
+
+ /*
+ * Allocate a new kind structure
+ */
+ if (pLayScr->kinds)
+ pLayKinds = (LayerKindPtr) xrealloc ((pointer) pLayScr->kinds,
+ (pLayScr->nkinds + 1) * sizeof (LayerKindRec));
+ else
+ pLayKinds = (LayerKindPtr) xalloc (sizeof (LayerKindRec));
+ if (!pLayKinds)
+ return -1;
+
+ /*
+ * Fix up existing layers to point at the new kind
+ */
+ for (pLayer = pLayScr->pLayers; pLayer; pLayer = pLayer->pNext)
+ {
+ int kind = pLayer->pKind - pLayScr->kinds;
+
+ pLayer->pKind = &pLayKinds[kind];
+ }
+
+ pLayScr->kinds = pLayKinds;
+ pLayKind = &pLayScr->kinds[pLayScr->nkinds];
+ pLayKind->kind = pLayScr->nkinds;
+
+ /*
+ * Extract wrapped functions from screen and stick in kind
+ */
+ pLayKind->CloseScreen = pScreen->CloseScreen;
+
+ pLayKind->CreateWindow = pScreen->CreateWindow;
+ pLayKind->DestroyWindow = pScreen->DestroyWindow;
+ pLayKind->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pLayKind->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pLayKind->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pLayKind->CopyWindow = pScreen->CopyWindow;
+
+ pLayKind->CreatePixmap = pScreen->CreatePixmap;
+ pLayKind->DestroyPixmap = pScreen->DestroyPixmap;
+
+ pLayKind->CreateGC = pScreen->CreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ pLayKind->Composite = ps->Composite;
+ pLayKind->Glyphs = ps->Glyphs;
+ pLayKind->CompositeRects = ps->CompositeRects;
+ }
+#endif
+ /*
+ * If not underlying frame buffer kind,
+ * replace screen functions with those
+ */
+ if (pLayKind->kind != 0)
+ {
+ pScreen->CloseScreen = pLayKinds->CloseScreen;
+
+ pScreen->CreateWindow = pLayKinds->CreateWindow;
+ pScreen->DestroyWindow = pLayKinds->DestroyWindow;
+ pScreen->ChangeWindowAttributes = pLayKinds->ChangeWindowAttributes;
+ pScreen->PaintWindowBackground = pLayKinds->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pLayKinds->PaintWindowBorder;
+ pScreen->CopyWindow = pLayKinds->CopyWindow;
+
+ pScreen->CreatePixmap = pLayKinds->CreatePixmap;
+ pScreen->DestroyPixmap = pLayKinds->DestroyPixmap;
+
+ pScreen->CreateGC = pLayKinds->CreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ ps->Composite = pLayKinds->Composite;
+ ps->Glyphs = pLayKinds->Glyphs;
+ ps->CompositeRects = pLayKinds->CompositeRects;
+ }
+#endif
+ }
+
+ pLayScr->nkinds++;
+ return pLayKind->kind;
+}
+
+/*
+ * Finally, call this function and layer
+ * will wrap the screen functions and prepare for execution
+ */
+
+Bool
+LayerFinishInit (ScreenPtr pScreen)
+{
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+#endif
+
+ pScreen->CloseScreen = layerCloseScreen;
+
+ pScreen->CreateWindow = layerCreateWindow;
+ pScreen->DestroyWindow = layerDestroyWindow;
+ pScreen->ChangeWindowAttributes = layerChangeWindowAttributes;
+ pScreen->PaintWindowBackground = layerPaintWindowBackground;
+ pScreen->PaintWindowBorder = layerPaintWindowBorder;
+ pScreen->CopyWindow = layerCopyWindow;
+
+ pScreen->CreatePixmap = layerCreatePixmap;
+ pScreen->DestroyPixmap = layerDestroyPixmap;
+
+ pScreen->CreateGC = layerCreateGC;
+
+#ifdef RENDER
+ if (ps)
+ {
+ ps->Composite = layerComposite;
+ ps->Glyphs = layerGlyphs;
+ ps->CompositeRects = layerCompositeRects;
+ }
+#endif
+
+ return TRUE;
+}
+
+/*
+ * At any point after LayerStartInit, a new layer can be created.
+ */
+LayerPtr
+LayerCreate (ScreenPtr pScreen,
+ int kind,
+ int depth,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int randr,
+ void *closure)
+{
+ layerScrPriv(pScreen);
+ LayerPtr pLay, *pPrev;
+ LayerKindPtr pLayKind;
+
+ if (kind < 0 || pLayScr->nkinds <= kind)
+ return 0;
+ pLayKind = &pLayScr->kinds[kind];
+ pLay = (LayerPtr) xalloc (sizeof (LayerRec));
+ if (!pLay)
+ return 0;
+ /*
+ * Initialize the layer
+ */
+ pLay->pNext = 0;
+ pLay->pKind = pLayKind;
+ pLay->refcnt = 1;
+ pLay->windows = 0;
+ pLay->depth = depth;
+ pLay->pPixmap = pPixmap;
+ pLay->update = update;
+ pLay->window = window;
+ pLay->randr = randr;
+ pLay->closure = closure;
+ if (pPixmap == LAYER_SCREEN_PIXMAP)
+ pLay->freePixmap = FALSE;
+ else
+ {
+ pLay->freePixmap = TRUE;
+ if (pPixmap)
+ pPixmap->refcnt++;
+ }
+ REGION_INIT (pScreen, &pLay->region, NullBox, 0);
+ /*
+ * Hook the layer at the end of the list
+ */
+ for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
+ ;
+ *pPrev = pLay;
+ return pLay;
+}
+
+/*
+ * Change a layer pixmap
+ */
+void
+LayerSetPixmap (ScreenPtr pScreen, LayerPtr pLayer, PixmapPtr pPixmap)
+{
+ LayerDestroyPixmap (pScreen, pLayer);
+ pLayer->pPixmap = pPixmap;
+ if (pPixmap == LAYER_SCREEN_PIXMAP)
+ pLayer->freePixmap = FALSE;
+ else
+ {
+ if (pPixmap)
+ pPixmap->refcnt++;
+ pLayer->freePixmap = TRUE;
+ }
+}
+
+/*
+ * Destroy a layer. The layer must not contain any windows.
+ */
+void
+LayerDestroy (ScreenPtr pScreen, LayerPtr pLay)
+{
+ layerScrPriv(pScreen);
+ LayerPtr *pPrev;
+
+ --pLay->refcnt;
+ if (pLay->refcnt > 0)
+ return;
+ /*
+ * Unhook the layer from the list
+ */
+ for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
+ if (*pPrev == pLay)
+ {
+ *pPrev = pLay->pNext;
+ break;
+ }
+ /*
+ * Free associated storage
+ */
+ LayerDestroyPixmap (pScreen, pLay);
+ REGION_UNINIT (pScreen, &pLay->region);
+ xfree (pLay);
+}
+
+/*
+ * CloseScreen wrapper
+ */
+Bool
+layerCloseScreen (int index, ScreenPtr pScreen)
+{
+ layerScrPriv(pScreen);
+ int kind;
+
+ /* XXX this is a mess -- fbCloseScreen can only be called once,
+ * and yet the intervening layers need to be called as well.
+ */
+ kind = pLayScr->nkinds - 1;
+ pScreen->CloseScreen = pLayScr->kinds[kind].CloseScreen;
+ (*pScreen->CloseScreen) (index, pScreen);
+
+ /*
+ * make sure the shadow layer is cleaned up as well
+ */
+ if (kind != LAYER_SHADOW)
+ xfree (shadowGetScrPriv (pScreen));
+
+ xfree (pLayScr->kinds);
+ xfree (pLayScr);
+ pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
+ return TRUE;
+}
diff --git a/miext/layer/layerpict.c b/miext/layer/layerpict.c
new file mode 100644
index 000000000..e233d0271
--- /dev/null
+++ b/miext/layer/layerpict.c
@@ -0,0 +1,145 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerpict.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "layerstr.h"
+
+void
+layerComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, Composite);
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ LayerWrap (ps, pLayer->pKind, Composite, layerComposite);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], Composite);
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], Composite, layerComposite);
+ }
+}
+
+void
+layerGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlist, list, glyphs);
+ LayerWrap (ps, pLayer->pKind, Glyphs, layerGlyphs);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlist, list, glyphs);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], Glyphs, layerGlyphs);
+ }
+}
+
+void
+layerCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects)
+{
+ LayerPtr pLayer;
+ LayerWinLoopRec loop;
+ DrawablePtr pDstDrawable = pDst->pDrawable;
+ ScreenPtr pScreen = pDstDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen (pScreen);
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDstDrawable;
+ for (pLayer = LayerWindowFirst (pWin, &loop);
+ pLayer;
+ pLayer = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap (ps, pLayer->pKind, CompositeRects);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+ LayerWrap (ps, pLayer->pKind, CompositeRects, layerCompositeRects);
+ }
+ LayerWindowDone (pWin, &loop);
+ }
+ else
+ {
+ layerScrPriv (pScreen);
+ LayerUnwrap (ps, &pLayScr->kinds[LAYER_FB], CompositeRects);
+ (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+ LayerWrap (ps, &pLayScr->kinds[LAYER_FB], CompositeRects, layerCompositeRects);
+ }
+}
diff --git a/miext/layer/layerstr.h b/miext/layer/layerstr.h
new file mode 100644
index 000000000..1720a536c
--- /dev/null
+++ b/miext/layer/layerstr.h
@@ -0,0 +1,420 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerstr.h,v 1.3 2002/11/08 22:19:42 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _LAYERSTR_H_
+#define _LAYERSTR_H_
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "layer.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+extern int layerScrPrivateIndex;
+extern int layerGCPrivateIndex;
+extern int layerWinPrivateIndex;
+
+/*
+ * One of these for each possible set of underlying
+ * rendering code. The first kind always points at the
+ * underlying frame buffer code and is created in LayerStartInit
+ * so that LayerNewKind can unwrap the screen and prepare it
+ * for another wrapping sequence.
+ *
+ * The set of functions wrapped here must be at least the union
+ * of all functions wrapped by any rendering layer in use; they're
+ * easy to add, so don't be shy
+ */
+
+typedef struct _LayerKind {
+ int kind; /* kind index */
+
+ CloseScreenProcPtr CloseScreen;
+
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+
+ CreateGCProcPtr CreateGC;
+
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+ CompositeRectsProcPtr CompositeRects;
+
+} LayerKindRec;
+
+#define LayerWrap(orig,lay,member,func) \
+ (((lay)->member = (orig)->member),\
+ ((orig)->member = (func)))
+#define LayerUnwrap(orig,lay,member) \
+ ((orig)->member = (lay)->member)
+
+/*
+ * This is the window private structure allocated for
+ * all windows. There are two possible alternatives here,
+ * either the window belongs to a single layer and uses its
+ * internal clip/borderClip lists or the window belongs to one
+ * or more layers and uses a separate clip/borderclip for each
+ * layer. When this is integrated into the core window struct,
+ * the LayerWinKind can become a single bit saving 8 bytes per
+ * window.
+ */
+
+typedef struct _LayerWin {
+ Bool isList;
+ union {
+ LayerPtr pLayer;
+ LayerListPtr pLayList;
+ } u;
+} LayerWinRec;
+
+typedef struct _LayerList {
+ LayerListPtr pNext; /* list of layers for this window */
+ LayerPtr pLayer; /* the layer */
+ Bool inheritClip; /* use the window clipList/borderClip */
+ RegionRec clipList; /* per-layer clip/border clip lists */
+ RegionRec borderClip;
+} LayerListRec;
+
+#define layerGetWinPriv(pWin) ((LayerWinPtr) (pWin)->devPrivates[layerWinPrivateIndex].ptr)
+#define layerWinPriv(pWin) LayerWinPtr pLayWin = layerGetWinPriv(pWin)
+
+#define layerWinLayer(pLayWin) ((pLayWin)->isList ? (pLayWin)->u.pLayList->pLayer : (pLayWin)->u.pLayer)
+
+typedef struct _LayerWinLoop {
+ LayerWinPtr pLayWin;
+ LayerListPtr pLayList;
+ PixmapPtr pPixmap; /* original window pixmap */
+ RegionRec clipList; /* saved original clipList contents */
+ RegionRec borderClip; /* saved original borderClip contents */
+} LayerWinLoopRec, *LayerWinLoopPtr;
+
+#define layerWinFirstLayer(pLayWin,pLayList) ((pLayWin)->isList ? ((pLayList) = (pLayWin)->u.pLayList)->pLayer : pLayWin->u.pLayer)
+#define layerWinNextLayer(pLayWin,pLayList) ((pLayWin)->isList ? ((pLayList) = (pLayList)->pNext)->pLayer : 0)
+
+LayerPtr
+LayerWindowFirst (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+LayerPtr
+LayerWindowNext (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+void
+LayerWindowDone (WindowPtr pWin, LayerWinLoopPtr pLoop);
+
+
+/*
+ * This is the GC private structure allocated for all GCs.
+ * XXX this is really messed up; I'm not sure how to fix it yet
+ */
+
+typedef struct _LayerGC {
+ GCFuncs *funcs;
+ LayerKindPtr pKind;
+} LayerGCRec;
+
+#define layerGetGCPriv(pGC) ((LayerGCPtr) (pGC)->devPrivates[layerGCPrivateIndex].ptr)
+#define layerGCPriv(pGC) LayerGCPtr pLayGC = layerGetGCPriv(pGC)
+
+/*
+ * This is the screen private, it contains
+ * the layer kinds and the layers themselves
+ */
+typedef struct _LayerScreen {
+ int nkinds; /* number of elements in kinds array */
+ LayerKindPtr kinds; /* created kinds; reallocated when new ones added */
+ LayerPtr pLayers; /* list of layers for this screen */
+} LayerScreenRec;
+
+#define layerGetScrPriv(pScreen) ((LayerScreenPtr) (pScreen)->devPrivates[layerScrPrivateIndex].ptr)
+#define layerScrPriv(pScreen) LayerScreenPtr pLayScr = layerGetScrPriv(pScreen)
+
+Bool
+layerCloseScreen (int index, ScreenPtr pScreen);
+
+Bool
+layerCreateWindow (WindowPtr pWin);
+
+Bool
+layerDestroyWindow (WindowPtr pWin);
+
+Bool
+layerChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
+
+void
+layerPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what);
+
+void
+layerPaintWindowBorder (WindowPtr pWin, RegionPtr pRegion, int what);
+
+void
+layerCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+PixmapPtr
+layerCreatePixmap (ScreenPtr pScreen, int width, int height, int depth);
+
+Bool
+layerDestroyPixmap (PixmapPtr pPixmap);
+
+Bool
+layerCreateGC (GCPtr pGC);
+
+void
+layerComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+void
+layerGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+void
+layerCompositeRects (CARD8 op,
+ PicturePtr pDst,
+ xRenderColor *color,
+ int nRect,
+ xRectangle *rects);
+
+void layerValidateGC(GCPtr, unsigned long, DrawablePtr);
+void layerChangeGC(GCPtr, unsigned long);
+void layerCopyGC(GCPtr, unsigned long, GCPtr);
+void layerDestroyGC(GCPtr);
+void layerChangeClip(GCPtr, int, pointer, int);
+void layerDestroyClip(GCPtr);
+void layerCopyClip(GCPtr, GCPtr);
+
+void
+layerFillSpans(DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted);
+
+void
+layerSetSpans(DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int nspans,
+ int fSorted);
+
+void
+layerPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+RegionPtr
+layerCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+);
+
+RegionPtr
+layerCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+);
+
+void
+layerPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+);
+void
+layerPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+void
+layerPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+layerPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects
+);
+
+void
+layerPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+);
+
+void
+layerFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr pptInit
+);
+
+void
+layerPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+);
+
+void
+layerPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+);
+
+int
+layerPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+);
+
+int
+layerPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+layerImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+);
+
+void
+layerImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+layerImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+layerPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+layerPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+);
+
+#endif /* _LAYERSTR_H_ */
diff --git a/miext/layer/layerwin.c b/miext/layer/layerwin.c
new file mode 100644
index 000000000..8160000c8
--- /dev/null
+++ b/miext/layer/layerwin.c
@@ -0,0 +1,483 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/layer/layerwin.c,v 1.7 2002/11/08 22:19:42 keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "layerstr.h"
+
+static LayerListPtr
+NewLayerList (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ LayerListPtr pLayList;
+
+ pLayList = (LayerListPtr) xalloc (sizeof (LayerListRec));
+ if (!pLayList)
+ return 0;
+ pLayList->pNext = 0;
+ pLayList->pLayer = pLayer;
+ pLayList->inheritClip = TRUE;
+ REGION_INIT (pScreen, &pLayList->clipList, NullBox, 0);
+ REGION_INIT (pScreen, &pLayList->borderClip, NullBox, 0);
+ return pLayList;
+}
+
+static void
+FreeLayerList (ScreenPtr pScreen, LayerListPtr pLayList)
+{
+ REGION_UNINIT (&pScreen, &pLayList->clipList);
+ REGION_UNINIT (&pScreen, &pLayList->borderClip);
+ xfree (pLayList);
+}
+
+/*
+ * Create pixmap for a layer
+ */
+
+Bool
+LayerCreatePixmap (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ LayerKindPtr pKind = pLayer->pKind;
+
+ LayerUnwrap (pScreen, pKind, CreatePixmap);
+ /* XXX create full-screen sized layers all around */
+ pLayer->pPixmap = (*pScreen->CreatePixmap) (pScreen, pScreen->width,
+ pScreen->height, pLayer->depth);
+ LayerWrap (pScreen, pKind, CreatePixmap, layerCreatePixmap);
+ if (!pLayer->pPixmap)
+ return FALSE;
+ if (pLayer->pKind->kind == LAYER_SHADOW)
+ {
+ if (!shadowAdd (pScreen, pLayer->pPixmap, pLayer->update,
+ pLayer->window, pLayer->randr,
+ pLayer->closure))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Destroy pixmap for a layer
+ */
+
+void
+LayerDestroyPixmap (ScreenPtr pScreen, LayerPtr pLayer)
+{
+ if (pLayer->pPixmap)
+ {
+ if (pLayer->pKind->kind == LAYER_SHADOW)
+ shadowRemove (pScreen, pLayer->pPixmap);
+ if (pLayer->freePixmap)
+ {
+ LayerKindPtr pKind = pLayer->pKind;
+
+ LayerUnwrap (pScreen, pKind, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pLayer->pPixmap);
+ LayerWrap (pScreen, pKind, DestroyPixmap, layerDestroyPixmap);
+ }
+ pLayer->pPixmap = 0;
+ }
+}
+
+/*
+ * Add a window to a layer
+ */
+Bool
+LayerWindowAdd (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin)
+{
+ layerWinPriv(pWin);
+
+ if (pLayer->pPixmap == LAYER_SCREEN_PIXMAP)
+ pLayer->pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ else if (!pLayer->pPixmap && !LayerCreatePixmap (pScreen, pLayer))
+ return FALSE;
+ /*
+ * Add a new layer list if needed
+ */
+ if (pLayWin->isList || pLayWin->u.pLayer)
+ {
+ LayerListPtr pPrev;
+ LayerListPtr pLayList;
+
+ if (!pLayWin->isList)
+ {
+ pPrev = NewLayerList (pScreen, pLayWin->u.pLayer);
+ if (!pPrev)
+ return FALSE;
+ }
+ else
+ {
+ for (pPrev = pLayWin->u.pLayList; pPrev->pNext; pPrev = pPrev->pNext)
+ ;
+ }
+ pLayList = NewLayerList (pScreen, pLayer);
+ if (!pLayList)
+ {
+ if (!pLayWin->isList)
+ FreeLayerList (pScreen, pPrev);
+ return FALSE;
+ }
+ pPrev->pNext = pLayList;
+ if (!pLayWin->isList)
+ {
+ pLayWin->isList = TRUE;
+ pLayWin->u.pLayList = pPrev;
+ }
+ }
+ else
+ pLayWin->u.pLayer = pLayer;
+ /*
+ * XXX only one layer supported for drawing, last one wins
+ */
+ (*pScreen->SetWindowPixmap) (pWin, pLayer->pPixmap);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pLayer->refcnt++;
+ pLayer->windows++;
+ return TRUE;
+}
+
+/*
+ * Remove a window from a layer
+ */
+
+void
+LayerWindowRemove (ScreenPtr pScreen, LayerPtr pLayer, WindowPtr pWin)
+{
+ layerWinPriv(pWin);
+
+ if (pLayWin->isList)
+ {
+ LayerListPtr *pPrev;
+ LayerListPtr pLayList;
+
+ for (pPrev = &pLayWin->u.pLayList; (pLayList = *pPrev); pPrev = &pLayList->pNext)
+ {
+ if (pLayList->pLayer == pLayer)
+ {
+ *pPrev = pLayList->pNext;
+ FreeLayerList (pScreen, pLayList);
+ --pLayer->windows;
+ if (pLayer->windows <= 0)
+ LayerDestroyPixmap (pScreen, pLayer);
+ LayerDestroy (pScreen, pLayer);
+ break;
+ }
+ }
+ pLayList = pLayWin->u.pLayList;
+ if (!pLayList)
+ {
+ /*
+ * List is empty, set isList back to false
+ */
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = 0;
+ }
+ else if (!pLayList->pNext && pLayList->inheritClip)
+ {
+ /*
+ * List contains a single element using the
+ * window clip, free the list structure and
+ * host the layer back to the window private
+ */
+ pLayer = pLayList->pLayer;
+ FreeLayerList (pScreen, pLayList);
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = pLayer;
+ }
+ }
+ else
+ {
+ if (pLayWin->u.pLayer == pLayer)
+ {
+ --pLayer->windows;
+ if (pLayer->windows <= 0)
+ LayerDestroyPixmap (pScreen, pLayer);
+ LayerDestroy (pScreen, pLayer);
+ pLayWin->u.pLayer = 0;
+ }
+ }
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+}
+
+/*
+ * Looping primitives for window layering. Usage:
+ *
+ * for (pLayer = LayerWindowFirst (pWin, &loop);
+ * pLayer;
+ * pLayer = LayerWindowNext (&loop))
+ * {
+ * ...
+ * }
+ * LayerWindowDone (pWin, &loop);
+ */
+
+LayerPtr
+LayerWindowFirst (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ layerWinPriv (pWin);
+
+ pLoop->pLayWin = pLayWin;
+ if (!pLayWin->isList)
+ return pLayWin->u.pLayer;
+
+ /*
+ * Preserve original state
+ */
+ pLoop->clipList = pWin->clipList;
+ pLoop->borderClip = pWin->borderClip;
+ pLoop->pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+
+ /*
+ * Set initial list element
+ */
+ pLoop->pLayList = pLayWin->u.pLayList;
+
+ /*
+ * Return first layer
+ */
+ return LayerWindowNext (pWin, pLoop);
+}
+
+LayerPtr
+LayerWindowNext (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ LayerPtr pLayer;
+ LayerWinPtr pLayWin = pLoop->pLayWin;
+ LayerListPtr pLayList;
+
+ if (!pLayWin->isList)
+ return 0;
+
+ pLayList = pLoop->pLayList;
+ pLayer = pLayList->pLayer;
+ /*
+ * Configure window for this layer
+ */
+ (*pWin->drawable.pScreen->SetWindowPixmap) (pWin, pLayer->pPixmap);
+ if (!pLayList->inheritClip)
+ {
+ pWin->clipList = pLayList->clipList;
+ pWin->borderClip = pLayList->borderClip;
+ }
+ /*
+ * Step to next layer list
+ */
+ pLoop->pLayList = pLayList->pNext;
+ /*
+ * Return layer
+ */
+ return pLayer;
+}
+
+void
+LayerWindowDone (WindowPtr pWin, LayerWinLoopPtr pLoop)
+{
+ LayerWinPtr pLayWin = pLoop->pLayWin;
+
+ if (!pLayWin->isList)
+ return;
+ /*
+ * clean up after the loop
+ */
+ pWin->clipList = pLoop->clipList;
+ pWin->borderClip = pLoop->clipList;
+ (*pWin->drawable.pScreen->SetWindowPixmap) (pWin, pLoop->pPixmap);
+}
+
+Bool
+layerCreateWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ layerWinPriv(pWin);
+ layerScrPriv(pScreen);
+ LayerPtr pLayer;
+ Bool ret;
+
+ pLayWin->isList = FALSE;
+ pLayWin->u.pLayer = 0;
+
+ /*
+ * input only windows don't live in any layer
+ */
+ if (pWin->drawable.type == UNDRAWABLE_WINDOW)
+ return TRUE;
+ /*
+ * Use a reasonable default layer -- the first
+ * layer matching the windows depth. Subsystems needing
+ * alternative layering semantics can override this by
+ * replacing this function. Perhaps a new screen function
+ * could be used to select the correct initial window
+ * layer instead.
+ */
+ for (pLayer = pLayScr->pLayers; pLayer; pLayer = pLayer->pNext)
+ if (pLayer->depth == pWin->drawable.depth)
+ break;
+ ret = TRUE;
+ if (pLayer)
+ {
+ pScreen->CreateWindow = pLayer->pKind->CreateWindow;
+ ret = (*pScreen->CreateWindow) (pWin);
+ pLayer->pKind->CreateWindow = pScreen->CreateWindow;
+ pScreen->CreateWindow = layerCreateWindow;
+ LayerWindowAdd (pScreen, pLayer, pWin);
+ }
+ return ret;
+}
+
+Bool
+layerDestroyWindow (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ layerWinPriv(pWin);
+ LayerPtr pLayer;
+ Bool ret = TRUE;
+
+ while ((pLayer = layerWinLayer (pLayWin)))
+ {
+ LayerUnwrap (pScreen, pLayer->pKind, DestroyWindow);
+ ret = (*pScreen->DestroyWindow) (pWin);
+ LayerWrap (pScreen, pLayer->pKind, DestroyWindow, layerDestroyWindow);
+ LayerWindowRemove (pWin->drawable.pScreen, pLayer, pWin);
+ }
+ return ret;
+}
+
+Bool
+layerChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+ Bool ret = TRUE;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,ChangeWindowAttributes);
+ if (!(*pScreen->ChangeWindowAttributes) (pWin, mask))
+ ret = FALSE;
+ LayerWrap(pScreen,pLay->pKind,ChangeWindowAttributes,layerChangeWindowAttributes);
+ }
+ LayerWindowDone (pWin, &loop);
+ return ret;
+}
+
+void
+layerPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+ LayerWrap(pScreen,pLay->pKind,PaintWindowBackground,layerPaintWindowBackground);
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
+void
+layerPaintWindowBorder (WindowPtr pWin, RegionPtr pRegion, int what)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+ LayerWrap(pScreen,pLay->pKind,PaintWindowBorder,layerPaintWindowBorder);
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
+void
+layerCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLay;
+ LayerWinLoopRec loop;
+ int dx = 0, dy = 0;
+
+ for (pLay = LayerWindowFirst (pWin, &loop);
+ pLay;
+ pLay = LayerWindowNext (pWin, &loop))
+ {
+ LayerUnwrap(pScreen,pLay->pKind,CopyWindow);
+ /*
+ * Undo the translation done within the last CopyWindow proc (sigh)
+ */
+ if (dx || dy)
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy);
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ LayerWrap(pScreen,pLay->pKind,CopyWindow,layerCopyWindow);
+ /*
+ * Save offset to undo translation next time around
+ */
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ }
+ LayerWindowDone (pWin, &loop);
+}
+
+PixmapPtr
+layerCreatePixmap (ScreenPtr pScreen, int width, int height, int depth)
+{
+ /* XXX assume the first layer can handle all pixmaps */
+ layerScrPriv (pScreen);
+ LayerKindPtr pKind;
+ PixmapPtr pPixmap;
+
+ pKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pKind = pLayScr->pLayers->pKind;
+ LayerUnwrap (pScreen, pKind, CreatePixmap);
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, depth);
+ LayerWrap (pScreen,pKind,CreatePixmap,layerCreatePixmap);
+ return pPixmap;
+}
+
+Bool
+layerDestroyPixmap (PixmapPtr pPixmap)
+{
+ /* XXX assume the first layer can handle all pixmaps */
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ layerScrPriv (pScreen);
+ LayerKindPtr pKind;
+ Bool ret;
+
+ pKind = &pLayScr->kinds[0];
+ if (pLayScr->pLayers)
+ pKind = pLayScr->pLayers->pKind;
+ LayerUnwrap (pScreen, pKind, DestroyPixmap);
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ LayerWrap (pScreen,pKind,DestroyPixmap,layerDestroyPixmap);
+ return ret;
+}
+
diff --git a/miext/shadow/shadow.c b/miext/shadow/shadow.c
new file mode 100644
index 000000000..60a1555d8
--- /dev/null
+++ b/miext/shadow/shadow.c
@@ -0,0 +1,1525 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shadow.c,v 1.13 2002/12/02 20:37:23 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+
+typedef struct _shadowGCPriv {
+ GCOps *ops;
+ GCFuncs *funcs;
+} shadowGCPrivRec, *shadowGCPrivPtr;
+
+int shadowScrPrivateIndex;
+int shadowGCPrivateIndex;
+int shadowGeneration;
+
+#define shadowGetGCPriv(pGC) \
+ ((shadowGCPrivPtr) (pGC)->devPrivates[shadowGCPrivateIndex].ptr)
+#define shadowGCPriv(pGC) \
+ shadowGCPrivPtr pGCPriv = shadowGetGCPriv(pGC)
+
+#define wrap(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+static void
+shadowRedisplay (ScreenPtr pScreen)
+{
+ shadowScrPriv(pScreen);
+ shadowBufPtr pBuf;
+
+ for (pBuf = pScrPriv->pBuf; pBuf; pBuf = pBuf->pNext)
+ {
+ if (REGION_NOTEMPTY (pScreen, &pBuf->damage))
+ {
+ REGION_INTERSECT (pScreen, &pBuf->damage, &pBuf->damage,
+ &WindowTable[pScreen->myNum]->borderClip);
+ (*pBuf->update) (pScreen, pBuf);
+ REGION_EMPTY (pScreen, &pBuf->damage);
+ }
+ }
+}
+
+static void
+shadowBlockHandler (pointer data,
+ OSTimePtr pTimeout,
+ pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ shadowRedisplay (pScreen);
+}
+
+static void
+shadowWakeupHandler (pointer data, int i, pointer LastSelectMask)
+{
+}
+
+static void
+shadowDamageRegion (WindowPtr pWindow, RegionPtr pRegion)
+{
+ shadowBufPtr pBuf = shadowFindBuf (pWindow);
+
+ if (!pBuf)
+ abort ();
+
+ REGION_INTERSECT(pWindow->drawable.pScreen, pRegion, pRegion,
+ &pWindow->borderClip);
+ REGION_UNION(pWindow->drawable.pScreen, &pBuf->damage, &pBuf->damage,
+ pRegion);
+#ifdef ALWAYS_DISPLAY
+ shadowRedisplay (pWindow->drawable.pScreen);
+#endif
+}
+
+static void
+shadowDamageBox (WindowPtr pWindow, BoxPtr pBox)
+{
+ RegionRec region;
+
+ REGION_INIT (pWindow->drawable.pScreen, &region, pBox, 1);
+ shadowDamageRegion (pWindow, &region);
+}
+
+static void
+shadowDamageRect (WindowPtr pWindow, int x, int y, int w, int h)
+{
+ BoxRec box;
+
+ x += pWindow->drawable.x;
+ y += pWindow->drawable.y;
+ box.x1 = x;
+ box.x2 = x + w;
+ box.y1 = y;
+ box.y2 = y + h;
+ shadowDamageBox (pWindow, &box);
+}
+
+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, pointer, 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)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ shadowScrPriv(pScreen);
+ shadowGCPriv(pGC);
+ Bool ret;
+
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &shadowGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, shadowCreateGC);
+
+ return ret;
+}
+
+void
+shadowWrapGC (GCPtr pGC)
+{
+ shadowGCPriv(pGC);
+
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &shadowGCFuncs;
+}
+
+void
+shadowUnwrapGC (GCPtr pGC)
+{
+ shadowGCPriv(pGC);
+
+ pGC->funcs = pGCPriv->funcs;
+ if (pGCPriv->ops)
+ pGC->ops = pGCPriv->ops;
+}
+
+#define SHADOW_GC_OP_PROLOGUE(pGC, pDraw) \
+ shadowGCPriv(pGC); \
+ GCFuncs *oldFuncs = pGC->funcs; \
+ unwrap(pGCPriv, pGC, funcs); \
+ unwrap(pGCPriv, pGC, ops); \
+
+#define SHADOW_GC_OP_EPILOGUE(pGC, pDraw) \
+ wrap(pGCPriv, pGC, funcs, oldFuncs); \
+ wrap(pGCPriv, pGC, ops, &shadowGCOps)
+
+#define SHADOW_GC_FUNC_PROLOGUE(pGC) \
+ shadowGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define SHADOW_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &shadowGCFuncs); \
+ if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &shadowGCOps)
+
+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,
+ pointer 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);
+}
+
+#define IS_VISIBLE(pWin) 1
+
+
+#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))
+
+#ifdef RENDER
+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)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ shadowScrPriv(pScreen);
+
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ wrap (pScrPriv, ps, Composite, shadowComposite);
+ if (pDst->pDrawable->type == DRAWABLE_WINDOW)
+ shadowDamageRect ((WindowPtr) pDst->pDrawable, xDst, yDst,
+ width, height);
+}
+
+static void
+shadowGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ shadowScrPriv(pScreen);
+ int x, y;
+ int n;
+ GlyphPtr glyph;
+
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, shadowGlyphs);
+ if (pDst->pDrawable->type == DRAWABLE_WINDOW)
+ {
+ x = xSrc;
+ y = ySrc;
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ while (n--)
+ {
+ glyph = *glyphs++;
+ shadowDamageRect ((WindowPtr) pDst->pDrawable,
+ x - glyph->info.x,
+ y - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ list++;
+ }
+ }
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+shadowFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nInit) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nInit;
+ BoxRec box;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidthInit++;
+ 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++;
+
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ } else
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+}
+
+static void
+shadowSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int nspans,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nspans) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nspans;
+ BoxRec box;
+
+ 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++;
+
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ } else
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+}
+
+static void
+shadowPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw)) {
+ BoxRec box;
+
+ box.x1 = x + pDraw->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDraw->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static RegionPtr
+shadowCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ RegionPtr ret;
+ SHADOW_GC_OP_PROLOGUE(pGC, pDst);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDst);
+
+ if(IS_VISIBLE(pDst)) {
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDst, &box);
+ }
+
+ 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;
+ SHADOW_GC_OP_PROLOGUE(pGC, pDst);
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDst);
+
+ if(IS_VISIBLE(pDst)) {
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDst, &box);
+ }
+
+ return ret;
+}
+
+static void
+shadowPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && npt) {
+ BoxRec box;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--npt) {
+ pptInit++;
+ if(box.x1 > pptInit->x) box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x) box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y) box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y) box.y2 = pptInit->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+
+ if(IS_VISIBLE(pDraw) && npt) {
+ BoxRec box;
+ 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) {
+ pptInit++;
+ x += pptInit->x;
+ y += pptInit->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) {
+ pptInit++;
+ if(box.x1 > pptInit->x) box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x) box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y) box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y) box.y2 = pptInit->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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nseg) {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRects, pRects);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nRects)
+ {
+ BoxRec box;
+ int offset1, offset2, offset3;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ while(nRects--)
+ {
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y - offset1;
+ box.x2 = box.x1 + pRects->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+
+ box.x1 = pRects->x + pRects->width - offset1;
+ box.y1 = pRects->y + offset3;
+ box.x2 = box.x1 + offset2;
+ box.y2 = box.y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+
+ box.x1 = pRects->x - offset1;
+ box.y1 = pRects->y + pRects->height - offset1;
+ box.x2 = box.x1 + pRects->width + offset2;
+ box.y2 = box.y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+
+ pRects++;
+ }
+ }
+ }
+
+static void
+shadowPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && narcs) {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && (count > 2)) {
+ DDXPointPtr ppt = pptInit;
+ int i = count;
+ BoxRec box;
+
+ 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++;
+
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ } else
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+}
+
+
+static void
+shadowPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nRectsInit) {
+ BoxRec box;
+ 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 */
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ } else
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+}
+
+
+static void
+shadowPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && narcs) {
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+
+}
+
+static int
+shadowPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int width;
+
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ width -= x;
+
+ if(IS_VISIBLE(pDraw) && (width > 0)) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+
+ return (width + x);
+}
+
+static int
+shadowPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int width;
+
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ width -= x;
+
+ if(IS_VISIBLE(pDraw) && (width > 0)) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+
+ return (width + x);
+}
+
+static void
+shadowImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+static void
+shadowImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+
+static void
+shadowImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nglyph) {
+ int top, bot, width = 0;
+ BoxRec box;
+
+ 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw) && nglyph) {
+ BoxRec box;
+
+ /* 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))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+static void
+shadowPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ SHADOW_GC_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ SHADOW_GC_OP_EPILOGUE(pGC, pDraw);
+
+ if(IS_VISIBLE(pDraw)) {
+ BoxRec box;
+
+ box.x1 = xOrg + pDraw->x;
+ box.x2 = box.x1 + dx;
+ box.y1 = yOrg + pDraw->y;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ shadowDamageBox ((WindowPtr) pDraw, &box);
+ }
+}
+
+
+static void
+shadowPaintWindow(
+ WindowPtr pWindow,
+ RegionPtr prgn,
+ int what
+){
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ shadowScrPriv(pScreen);
+
+ if(what == PW_BACKGROUND) {
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, shadowPaintWindow);
+ } else {
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, shadowPaintWindow);
+ }
+ shadowDamageRegion (pWindow, prgn);
+}
+
+
+static void
+shadowCopyWindow(
+ WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgn
+){
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ shadowScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgn);
+ wrap (pScrPriv, pScreen, CopyWindow, shadowCopyWindow);
+ shadowDamageRegion (pWindow, prgn);
+}
+
+GCOps shadowGCOps = {
+ shadowFillSpans, shadowSetSpans,
+ shadowPutImage, shadowCopyArea,
+ shadowCopyPlane, shadowPolyPoint,
+ shadowPolylines, shadowPolySegment,
+ shadowPolyRectangle, shadowPolyArc,
+ shadowFillPolygon, shadowPolyFillRect,
+ shadowPolyFillArc, shadowPolyText8,
+ shadowPolyText16, shadowImageText8,
+ shadowImageText16, shadowImageGlyphBlt,
+ shadowPolyGlyphBlt, shadowPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+static void
+shadowGetImage (DrawablePtr pDrawable,
+ int sx,
+ int sy,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char * pdstLine)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ shadowScrPriv(pScreen);
+
+ /* Many apps use GetImage to sync with the visable frame buffer */
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ shadowRedisplay (pScreen);
+ unwrap (pScrPriv, pScreen, GetImage);
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+ wrap (pScrPriv, pScreen, GetImage, shadowGetImage);
+}
+
+static void
+shadowRestoreAreas (PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ shadowScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+ xorg, yorg, pWin);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ shadowRestoreAreas);
+ shadowDamageRegion (pWin, prgn);
+}
+
+static Bool
+shadowCloseScreen (int i, ScreenPtr pScreen)
+{
+ shadowScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CreateGC);
+ unwrap (pScrPriv, pScreen, PaintWindowBackground);
+ unwrap (pScrPriv, pScreen, PaintWindowBorder);
+ unwrap (pScrPriv, pScreen, CopyWindow);
+ unwrap (pScrPriv, pScreen, CloseScreen);
+ unwrap (pScrPriv, pScreen, GetImage);
+ unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+ xfree (pScrPriv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+shadowSetup (ScreenPtr pScreen)
+{
+ shadowScrPrivPtr pScrPriv;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ if (shadowGeneration != serverGeneration)
+ {
+ shadowScrPrivateIndex = AllocateScreenPrivateIndex ();
+ if (shadowScrPrivateIndex == -1)
+ return FALSE;
+ shadowGCPrivateIndex = AllocateGCPrivateIndex ();
+ if (shadowGCPrivateIndex == -1)
+ return FALSE;
+ shadowGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate (pScreen, shadowGCPrivateIndex, sizeof (shadowGCPrivRec)))
+ return FALSE;
+ pScrPriv = (shadowScrPrivPtr) xalloc (sizeof (shadowScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ if (!RegisterBlockAndWakeupHandlers (shadowBlockHandler,
+ shadowWakeupHandler,
+ (pointer) pScreen))
+ return FALSE;
+
+ wrap (pScrPriv, pScreen, CreateGC, shadowCreateGC);
+ wrap (pScrPriv, pScreen, PaintWindowBackground, shadowPaintWindow);
+ wrap (pScrPriv, pScreen, PaintWindowBorder, shadowPaintWindow);
+ wrap (pScrPriv, pScreen, CopyWindow, shadowCopyWindow);
+ wrap (pScrPriv, pScreen, CloseScreen, shadowCloseScreen);
+ wrap (pScrPriv, pScreen, GetImage, shadowGetImage);
+ wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+ shadowRestoreAreas);
+#ifdef RENDER
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, shadowGlyphs);
+ wrap (pScrPriv, ps, Composite, shadowComposite);
+ }
+#endif
+ pScrPriv->pBuf = 0;
+
+ pScreen->devPrivates[shadowScrPrivateIndex].ptr = (pointer) pScrPriv;
+ return TRUE;
+}
+
+Bool
+shadowAdd (ScreenPtr pScreen,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int randr,
+ void *closure)
+{
+ shadowScrPriv(pScreen);
+ shadowBufPtr pBuf;
+
+ pBuf = (shadowBufPtr) xalloc (sizeof (shadowBufRec));
+ if (!pBuf)
+ return FALSE;
+ /*
+ * Map simple rotation values to bitmasks; fortunately,
+ * these are all unique
+ */
+ switch (randr) {
+ case 0:
+ randr = SHADOW_ROTATE_0;
+ break;
+ case 90:
+ randr = SHADOW_ROTATE_90;
+ break;
+ case 180:
+ randr = SHADOW_ROTATE_180;
+ break;
+ case 270:
+ randr = SHADOW_ROTATE_270;
+ break;
+ }
+ pBuf->pPixmap = pPixmap;
+ pBuf->update = update;
+ pBuf->window = window;
+ REGION_INIT (pScreen, &pBuf->damage, NullBox, 0);
+ pBuf->pNext = pScrPriv->pBuf;
+ pBuf->randr = randr;
+ pBuf->closure = 0;
+ pScrPriv->pBuf = pBuf;
+ return TRUE;
+}
+
+void
+shadowRemove (ScreenPtr pScreen, PixmapPtr pPixmap)
+{
+ shadowScrPriv(pScreen);
+ shadowBufPtr pBuf, *pPrev;
+
+ for (pPrev = &pScrPriv->pBuf; (pBuf = *pPrev); pPrev = &pBuf->pNext)
+ if (pBuf->pPixmap == pPixmap)
+ {
+ REGION_UNINIT (pScreen, &pBuf->damage);
+ *pPrev = pBuf->pNext;
+ xfree (pBuf);
+ break;
+ }
+}
+
+shadowBufPtr
+shadowFindBuf (WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ shadowScrPriv(pScreen);
+ shadowBufPtr pBuf, *pPrev;
+ PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+
+ for (pPrev = &pScrPriv->pBuf; (pBuf = *pPrev); pPrev = &pBuf->pNext)
+ {
+ if (!pBuf->pPixmap)
+ pBuf->pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ if (pBuf->pPixmap == pPixmap)
+ {
+ /*
+ * Reorder so this one is first next time
+ */
+ if (pPrev != &pScrPriv->pBuf)
+ {
+ *pPrev = pBuf->pNext;
+ pBuf->pNext = pScrPriv->pBuf;
+ pScrPriv->pBuf = pBuf;
+ }
+ return pBuf;
+ }
+ }
+ return 0;
+}
+
+Bool
+shadowInit (ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window)
+{
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+ if (!shadowAdd (pScreen, 0, update, window, SHADOW_ROTATE_0, 0))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h
new file mode 100644
index 000000000..d8ade93dc
--- /dev/null
+++ b/miext/shadow/shadow.h
@@ -0,0 +1,172 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shadow.h,v 1.7 2002/12/02 20:37:24 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifndef _SHADOW_H_
+#define _SHADOW_H_
+
+#include "scrnintstr.h"
+
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+typedef struct _shadowBuf *shadowBufPtr;
+
+typedef void (*ShadowUpdateProc) (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+#define SHADOW_WINDOW_RELOCATE 1
+#define SHADOW_WINDOW_READ 2
+#define SHADOW_WINDOW_WRITE 4
+
+typedef void *(*ShadowWindowProc) (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure);
+
+typedef struct _shadowBuf {
+ shadowBufPtr pNext;
+ ShadowUpdateProc update;
+ ShadowWindowProc window;
+ RegionRec damage;
+ PixmapPtr pPixmap;
+ void *closure;
+ int randr;
+} shadowBufRec;
+
+/* Match defines from randr extension */
+#define SHADOW_ROTATE_0 1
+#define SHADOW_ROTATE_90 2
+#define SHADOW_ROTATE_180 4
+#define SHADOW_ROTATE_270 8
+#define SHADOW_ROTATE_ALL (SHADOW_ROTATE_0|SHADOW_ROTATE_90|\
+ SHADOW_ROTATE_180|SHADOW_ROTATE_270)
+#define SHADOW_REFLECT_X 16
+#define SHADOW_REFLECT_Y 32
+#define SHADOW_REFLECT_ALL (SHADOW_REFLECT_X|SHADOW_REFLECT_Y)
+
+typedef struct _shadowScrPriv {
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ CloseScreenProcPtr CloseScreen;
+ CreateGCProcPtr CreateGC;
+ GetImageProcPtr GetImage;
+#ifdef RENDER
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+#endif
+ shadowBufPtr pBuf;
+ BSFuncRec BackingStoreFuncs;
+} shadowScrPrivRec, *shadowScrPrivPtr;
+
+extern int shadowScrPrivateIndex;
+
+#define shadowGetScrPriv(pScr) ((shadowScrPrivPtr) (pScr)->devPrivates[shadowScrPrivateIndex].ptr)
+#define shadowScrPriv(pScr) shadowScrPrivPtr pScrPriv = shadowGetScrPriv(pScr)
+
+Bool
+shadowSetup (ScreenPtr pScreen);
+
+Bool
+shadowAdd (ScreenPtr pScreen,
+ PixmapPtr pPixmap,
+ ShadowUpdateProc update,
+ ShadowWindowProc window,
+ int randr,
+ void *closure);
+
+void
+shadowRemove (ScreenPtr pScreen, PixmapPtr pPixmap);
+
+shadowBufPtr
+shadowFindBuf (WindowPtr pWindow);
+
+Bool
+shadowInit (ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window);
+
+void *
+shadowAlloc (int width, int height, int bpp);
+
+void
+shadowUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdatePlanar4 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdatePlanar4x8 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate8_90 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate16_90 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate32_90 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate8_180 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate16_180 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate32_180 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate8_270 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate16_270 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowUpdateRotate32_270 (ScreenPtr pScreen,
+ shadowBufPtr pBuf);
+
+void
+shadowWrapGC (GCPtr pGC);
+
+void
+shadowUnwrapGC (GCPtr pGC);
+
+#endif /* _SHADOW_H_ */
diff --git a/miext/shadow/shalloc.c b/miext/shadow/shalloc.c
new file mode 100644
index 000000000..028ec26a5
--- /dev/null
+++ b/miext/shadow/shalloc.c
@@ -0,0 +1,48 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shalloc.c,v 1.1 2000/09/07 23:12:15 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+
+void *
+shadowAlloc (int width, int height, int bpp)
+{
+ int stride;
+ void *fb;
+
+ /* Cant use PixmapBytePad -- the structure is probably not initialized yet */
+ stride = BitmapBytePad (width * bpp);
+ fb = xalloc (stride * height);
+ return fb;
+}
diff --git a/miext/shadow/shpacked.c b/miext/shadow/shpacked.c
new file mode 100644
index 000000000..818a37a8e
--- /dev/null
+++ b/miext/shadow/shpacked.c
@@ -0,0 +1,108 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shpacked.c,v 1.5 2001/10/28 03:34:16 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+void
+shadowUpdatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase = NULL, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+#define PickBit(a,i) (((a) >> (i)) & 1)
+ while (i--)
+ *win++ = *sha++;
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
diff --git a/miext/shadow/shplanar.c b/miext/shadow/shplanar.c
new file mode 100644
index 000000000..148782956
--- /dev/null
+++ b/miext/shadow/shplanar.c
@@ -0,0 +1,168 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shplanar.c,v 1.4 2001/10/28 03:34:16 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+/*
+ * 32 4-bit pixels per write
+ */
+
+#define PL_SHIFT 7
+#define PL_UNIT (1 << PL_SHIFT)
+#define PL_MASK (PL_UNIT - 1)
+
+/*
+ * 32->8 conversion:
+ *
+ * 7 6 5 4 3 2 1 0
+ * A B C D E F G H
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * m . . . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A
+ * m1 G . . . F . . . E . . . D . . . C . . . B . . . A . . . . . . . m << (7 - (p))
+ * m2 . H . . . G . . . F . . . E . . . D . . . C . . . B . . . A . . (m >> (p)) << 2
+ * m3 G E C A m1 & 0x80808080
+ * m4 H F D B m2 & 0x40404040
+ * m5 G H E F C D A B m3 | m4
+ * m6 G H E F C D G H A B E F m5 | (m5 >> 20)
+ * m7 G H E F C D G H A B C D E F G H m6 | (m6 >> 10)
+ */
+
+#if 0
+#define GetBits(p,o,d) {\
+ m = sha[o]; \
+ m1 = m << (7 - (p)); \
+ m2 = (m >> (p)) << 2; \
+ m3 = m1 & 0x80808080; \
+ m4 = m2 & 0x40404040; \
+ m5 = m3 | m4; \
+ m6 = m5 | (m5 >> 20); \
+ d = m6 | (m6 >> 10); \
+}
+#else
+#define GetBits(p,o,d) {\
+ m = sha[o]; \
+ m5 = ((m << (7 - (p))) & 0x80808080) | (((m >> (p)) << 2) & 0x40404040); \
+ m6 = m5 | (m5 >> 20); \
+ d = m6 | (m6 >> 10); \
+}
+#endif
+
+void
+shadowUpdatePlanar4 (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ CARD32 *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ CARD32 *winBase = NULL, *win;
+ CARD32 winSize;
+ int plane;
+ CARD32 m,m5,m6;
+ CARD8 s1, s2, s3, s4;
+
+ fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = (pbox->x1) * shaBpp;
+ y = (pbox->y1);
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT;
+ x &= ~PL_MASK;
+
+ scrLine = (x >> PL_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ while (h--)
+ {
+ for (plane = 0; plane < 4; plane++)
+ {
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ winSize = 0;
+ scrBase = 0;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (CARD32 *) (*pBuf->window) (pScreen,
+ y,
+ (scr << 4) | (plane),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ winSize >>= 2;
+ scrBase = scr;
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+
+ while (i--)
+ {
+ GetBits(plane,0,s1);
+ GetBits(plane,1,s2);
+ GetBits(plane,2,s3);
+ GetBits(plane,3,s4);
+ *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ sha += 4;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
diff --git a/miext/shadow/shplanar8.c b/miext/shadow/shplanar8.c
new file mode 100644
index 000000000..c82b5f931
--- /dev/null
+++ b/miext/shadow/shplanar8.c
@@ -0,0 +1,170 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shplanar8.c,v 1.4 2001/10/28 03:34:16 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+/*
+ * Expose 8bpp depth 4
+ */
+
+/*
+ * 32->8 conversion:
+ *
+ * 7 6 5 4 3 2 1 0
+ * A B C D E F G H
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * m1 D x x x x x x x C x x x x x x x B x x x x x x x A x x x x x x x sha[0] << (7-(p))
+ * m2 x x x x H x x x x x x x G x x x x x x x F x x x x x x x E x x x sha[1] << (3-(p))
+ * m3 D C B A m1 & 0x80808080
+ * m4 H G F E m2 & 0x08080808
+ * m5 D H C G B F A E m3 | m4
+ * m6 D H C G B F m5 >> 9
+ * m7 D H C D G H B C F G A B E F m5 | m6
+ * m8 D H C D G H m7 >> 18
+ * m9 D H C D G H B C D F G H A B C D E F G H m7 | m8
+ */
+
+#define PL_SHIFT 8
+#define PL_UNIT (1 << PL_SHIFT)
+#define PL_MASK (PL_UNIT - 1)
+
+#if 0
+#define GetBits(p,o,d) { \
+ CARD32 m1,m2,m3,m4,m5,m6,m7,m8; \
+ m1 = sha[o] << (7 - (p)); \
+ m2 = sha[(o)+1] << (3 - (p)); \
+ m3 = m1 & 0x80808080; \
+ m4 = m2 & 0x08080808; \
+ m5 = m3 | m4; \
+ m6 = m5 >> 9; \
+ m7 = m5 | m6; \
+ m8 = m7 >> 18; \
+ d = m7 | m8; \
+}
+#else
+#define GetBits(p,o,d) { \
+ CARD32 m5,m7; \
+ m5 = ((sha[o] << (7 - (p))) & 0x80808080) | ((sha[(o)+1] << (3 - (p))) & 0x08080808); \
+ m7 = m5 | (m5 >> 9); \
+ d = m7 | (m7 >> 18); \
+}
+#endif
+
+void
+shadowUpdatePlanar4x8 (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ CARD32 *shaBase, *shaLine, *sha;
+ CARD8 s1, s2, s3, s4;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ CARD32 *winBase = NULL, *win;
+ CARD32 winSize;
+ int plane;
+
+ fbGetStipDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT;
+ x &= ~PL_MASK;
+
+ scrLine = (x >> PL_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ while (h--)
+ {
+ for (plane = 0; plane < 4; plane++)
+ {
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ winSize = 0;
+ scrBase = 0;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (CARD32 *) (*pBuf->window) (pScreen,
+ y,
+ (scr << 4) | (plane),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ winSize >>= 2;
+ scrBase = scr;
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+
+ while (i--)
+ {
+ GetBits(plane,0,s1);
+ GetBits(plane,2,s2);
+ GetBits(plane,4,s3);
+ GetBits(plane,6,s4);
+ *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ sha += 8;
+ }
+ }
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
diff --git a/miext/shadow/shrot16pack.c b/miext/shadow/shrot16pack.c
new file mode 100644
index 000000000..a1ff273de
--- /dev/null
+++ b/miext/shadow/shrot16pack.c
@@ -0,0 +1,28 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack.c,v 1.1 2000/09/08 21:46:45 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate16
+#define Data CARD16
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot16pack_180.c b/miext/shadow/shrot16pack_180.c
new file mode 100644
index 000000000..7ba41833e
--- /dev/null
+++ b/miext/shadow/shrot16pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate16_180
+#define Data CARD16
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot16pack_270.c b/miext/shadow/shrot16pack_270.c
new file mode 100644
index 000000000..0b3c4e0ac
--- /dev/null
+++ b/miext/shadow/shrot16pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate16_270
+#define Data CARD16
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot16pack_90.c b/miext/shadow/shrot16pack_90.c
new file mode 100644
index 000000000..574b3a157
--- /dev/null
+++ b/miext/shadow/shrot16pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot16pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate16_90
+#define Data CARD16
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot32pack.c b/miext/shadow/shrot32pack.c
new file mode 100644
index 000000000..327636efb
--- /dev/null
+++ b/miext/shadow/shrot32pack.c
@@ -0,0 +1,28 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack.c,v 1.1 2000/09/08 21:46:45 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate32
+#define Data CARD32
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot32pack_180.c b/miext/shadow/shrot32pack_180.c
new file mode 100644
index 000000000..838622267
--- /dev/null
+++ b/miext/shadow/shrot32pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate32_180
+#define Data CARD32
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot32pack_270.c b/miext/shadow/shrot32pack_270.c
new file mode 100644
index 000000000..b0dd28316
--- /dev/null
+++ b/miext/shadow/shrot32pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate32_270
+#define Data CARD32
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot32pack_90.c b/miext/shadow/shrot32pack_90.c
new file mode 100644
index 000000000..9bdb18e25
--- /dev/null
+++ b/miext/shadow/shrot32pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot32pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate32_90
+#define Data CARD32
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot8pack.c b/miext/shadow/shrot8pack.c
new file mode 100644
index 000000000..7af181f19
--- /dev/null
+++ b/miext/shadow/shrot8pack.c
@@ -0,0 +1,28 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack.c,v 1.1 2000/09/08 21:46:46 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate8
+#define Data CARD8
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot8pack_180.c b/miext/shadow/shrot8pack_180.c
new file mode 100644
index 000000000..316c0c690
--- /dev/null
+++ b/miext/shadow/shrot8pack_180.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_180.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate8_180
+#define Data CARD8
+#define ROTATE 180
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot8pack_270.c b/miext/shadow/shrot8pack_270.c
new file mode 100644
index 000000000..bed542f6d
--- /dev/null
+++ b/miext/shadow/shrot8pack_270.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_270.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate8_270
+#define Data CARD8
+#define ROTATE 270
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrot8pack_90.c b/miext/shadow/shrot8pack_90.c
new file mode 100644
index 000000000..f2618fc47
--- /dev/null
+++ b/miext/shadow/shrot8pack_90.c
@@ -0,0 +1,29 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrot8pack_90.c,v 1.1 2001/05/29 04:54:13 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#define FUNC shadowUpdateRotate8_90
+#define Data CARD8
+#define ROTATE 90
+
+#include "shrotpack.h"
diff --git a/miext/shadow/shrotate.c b/miext/shadow/shrotate.c
new file mode 100644
index 000000000..1277c2ee1
--- /dev/null
+++ b/miext/shadow/shrotate.c
@@ -0,0 +1,306 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrotate.c,v 1.5 2002/10/09 17:00:11 tsi Exp $
+ *
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+/*
+ * These indicate which way the source (shadow) is scanned when
+ * walking the screen in a particular direction
+ */
+
+#define LEFT_TO_RIGHT 1
+#define RIGHT_TO_LEFT -1
+#define TOP_TO_BOTTOM 2
+#define BOTTOM_TO_TOP -2
+
+void
+shadowUpdateRotatePacked (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBits;
+ FbStride shaStride;
+ int shaBpp;
+ int shaXoff, shaYoff;
+ int box_x1, box_x2, box_y1, box_y2;
+ int sha_x1 = 0, sha_y1 = 0;
+ int scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
+ int scr_x, scr_y;
+ int w;
+ int pixelsPerBits;
+ int pixelsMask;
+ FbStride shaStepOverY = 0, shaStepDownY = 0;
+ FbStride shaStepOverX = 0, shaStepDownX = 0;
+ FbBits *shaLine, *sha;
+ int shaHeight = pShadow->drawable.height;
+ int shaWidth = pShadow->drawable.width;
+ FbBits shaMask;
+ int shaFirstShift, shaShift;
+ int o_x_dir;
+ int o_y_dir;
+ int x_dir;
+ int y_dir;
+
+ fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
+ pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
+ pixelsMask = ~(pixelsPerBits - 1);
+ shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
+ /*
+ * Compute rotation related constants to walk the shadow
+ */
+ o_x_dir = LEFT_TO_RIGHT;
+ o_y_dir = TOP_TO_BOTTOM;
+ if (pBuf->randr & SHADOW_REFLECT_X)
+ o_x_dir = -o_x_dir;
+ if (pBuf->randr & SHADOW_REFLECT_Y)
+ o_y_dir = -o_y_dir;
+ switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
+ case SHADOW_ROTATE_0: /* upper left shadow -> upper left screen */
+ default:
+ x_dir = o_x_dir;
+ y_dir = o_y_dir;
+ break;
+ case SHADOW_ROTATE_90: /* upper right shadow -> upper left screen */
+ x_dir = o_y_dir;
+ y_dir = -o_x_dir;
+ break;
+ case SHADOW_ROTATE_180: /* lower right shadow -> upper left screen */
+ x_dir = -o_x_dir;
+ y_dir = -o_y_dir;
+ break;
+ case SHADOW_ROTATE_270: /* lower left shadow -> upper left screen */
+ x_dir = -o_y_dir;
+ y_dir = o_x_dir;
+ break;
+ }
+ switch (x_dir) {
+ case LEFT_TO_RIGHT:
+ shaStepOverX = shaBpp;
+ shaStepOverY = 0;
+ break;
+ case TOP_TO_BOTTOM:
+ shaStepOverX = 0;
+ shaStepOverY = shaStride;
+ break;
+ case RIGHT_TO_LEFT:
+ shaStepOverX = -shaBpp;
+ shaStepOverY = 0;
+ break;
+ case BOTTOM_TO_TOP:
+ shaStepOverX = 0;
+ shaStepOverY = -shaStride;
+ break;
+ }
+ switch (y_dir) {
+ case TOP_TO_BOTTOM:
+ shaStepDownX = 0;
+ shaStepDownY = shaStride;
+ break;
+ case RIGHT_TO_LEFT:
+ shaStepDownX = -shaBpp;
+ shaStepDownY = 0;
+ break;
+ case BOTTOM_TO_TOP:
+ shaStepDownX = 0;
+ shaStepDownY = -shaStride;
+ break;
+ case LEFT_TO_RIGHT:
+ shaStepDownX = shaBpp;
+ shaStepDownY = 0;
+ break;
+ }
+
+ while (nbox--)
+ {
+ box_x1 = pbox->x1;
+ box_y1 = pbox->y1;
+ box_x2 = pbox->x2;
+ box_y2 = pbox->y2;
+ pbox++;
+
+ /*
+ * Compute screen and shadow locations for this box
+ */
+ switch (x_dir) {
+ case LEFT_TO_RIGHT:
+ scr_x1 = box_x1 & pixelsMask;
+ scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
+
+ sha_x1 = scr_x1;
+ break;
+ case TOP_TO_BOTTOM:
+ scr_x1 = box_y1 & pixelsMask;
+ scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
+
+ sha_y1 = scr_x1;
+ break;
+ case RIGHT_TO_LEFT:
+ scr_x1 = (shaWidth - box_x2) & pixelsMask;
+ scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
+
+ sha_x1 = (shaWidth - scr_x1 - 1);
+ break;
+ case BOTTOM_TO_TOP:
+ scr_x1 = (shaHeight - box_y2) & pixelsMask;
+ scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
+
+ sha_y1 = (shaHeight - scr_x1 - 1);
+ break;
+ }
+ switch (y_dir) {
+ case TOP_TO_BOTTOM:
+ scr_y1 = box_y1;
+ scr_y2 = box_y2;
+
+ sha_y1 = scr_y1;
+ break;
+ case RIGHT_TO_LEFT:
+ scr_y1 = (shaWidth - box_x2);
+ scr_y2 = (shaWidth - box_x1);
+
+ sha_x1 = box_x2 - 1;
+ break;
+ case BOTTOM_TO_TOP:
+ scr_y1 = shaHeight - box_y2;
+ scr_y2 = shaHeight - box_y1;
+
+ sha_y1 = box_y2 - 1;
+ break;
+ case LEFT_TO_RIGHT:
+ scr_y1 = box_x1;
+ scr_y2 = box_x2;
+
+ sha_x1 = box_x1;
+ break;
+ }
+ scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
+ scr_h = scr_y2 - scr_y1;
+ scr_y = scr_y1;
+
+ /* shift amount for first pixel on screen */
+ shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
+
+ /* pointer to shadow data first placed on screen */
+ shaLine = (shaBits +
+ sha_y1 * shaStride +
+ ((sha_x1 * shaBpp) >> FB_SHIFT));
+
+ /*
+ * Copy the bits, always write across the physical frame buffer
+ * to take advantage of write combining.
+ */
+ while (scr_h--)
+ {
+ int p;
+ FbBits bits;
+ FbBits *win;
+ int i;
+ CARD32 winSize;
+
+ sha = shaLine;
+ shaShift = shaFirstShift;
+ w = scr_w;
+ scr_x = scr_x1 * shaBpp >> FB_SHIFT;
+
+ while (w)
+ {
+ /*
+ * Map some of this line
+ */
+ win = (FbBits *) (*pBuf->window) (pScreen,
+ scr_y,
+ scr_x << 2,
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ i = (winSize >> 2);
+ if (i > w)
+ i = w;
+ w -= i;
+ scr_x += i;
+ /*
+ * Copy the portion of the line mapped
+ */
+ while (i--)
+ {
+ bits = 0;
+ p = pixelsPerBits;
+ /*
+ * Build one word of output from multiple inputs
+ *
+ * Note that for 90/270 rotations, this will walk
+ * down the shadow hitting each scanline once.
+ * This is probably not very efficient.
+ */
+ while (p--)
+ {
+ bits = FbScrLeft(bits, shaBpp);
+ bits |= FbScrRight (*sha, shaShift) & shaMask;
+
+ shaShift -= shaStepOverX;
+ if (shaShift >= FB_UNIT)
+ {
+ shaShift -= FB_UNIT;
+ sha--;
+ }
+ else if (shaShift < 0)
+ {
+ shaShift += FB_UNIT;
+ sha++;
+ }
+ sha += shaStepOverY;
+ }
+ *win++ = bits;
+ }
+ }
+ scr_y++;
+ shaFirstShift -= shaStepDownX;
+ if (shaFirstShift >= FB_UNIT)
+ {
+ shaFirstShift -= FB_UNIT;
+ shaLine--;
+ }
+ else if (shaFirstShift < 0)
+ {
+ shaFirstShift += FB_UNIT;
+ shaLine++;
+ }
+ shaLine += shaStepDownY;
+ }
+ }
+}
diff --git a/miext/shadow/shrotpack.h b/miext/shadow/shrotpack.h
new file mode 100644
index 000000000..ce9b4c561
--- /dev/null
+++ b/miext/shadow/shrotpack.h
@@ -0,0 +1,182 @@
+/*
+ * $XFree86: xc/programs/Xserver/miext/shadow/shrotpack.h,v 1.4 2001/10/28 03:34:16 tsi Exp $
+ *
+ * Copyright © 2000 Keith Packard
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+/*
+ * Thanks to Daniel Chemko <dchemko@intrinsyc.com> for making the 90 and 180
+ * orientations work.
+ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "font.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "globals.h"
+#include "gcstruct.h"
+#include "shadow.h"
+#include "fb.h"
+
+#define DANDEBUG 0
+
+#if ROTATE == 270
+
+#define SCRLEFT(x,y,w,h) (pScreen->height - ((y) + (h)))
+#define SCRY(x,y,w,h) (x)
+#define SCRWIDTH(x,y,w,h) (h)
+#define FIRSTSHA(x,y,w,h) (((y) + (h) - 1) * shaStride + (x))
+#define STEPDOWN(x,y,w,h) ((w)--)
+#define NEXTY(x,y,w,h) ((x)++)
+#define SHASTEPX(stride) -(stride)
+#define SHASTEPY(stride) (1)
+
+#elif ROTATE == 90
+
+#define SCRLEFT(x,y,w,h) (y)
+#define SCRY(x,y,w,h) (pScreen->width - ((x) + (w)) - 1)
+#define SCRWIDTH(x,y,w,h) (h)
+#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x + w - 1))
+#define STEPDOWN(x,y,w,h) ((w)--)
+#define NEXTY(x,y,w,h) ((void)(x))
+#define SHASTEPX(stride) (stride)
+#define SHASTEPY(stride) (-1)
+
+#elif ROTATE == 180
+
+#define SCRLEFT(x,y,w,h) (pScreen->width - ((x) + (w)))
+#define SCRY(x,y,w,h) (pScreen->height - ((y) + (h)) - 1)
+#define SCRWIDTH(x,y,w,h) (w)
+#define FIRSTSHA(x,y,w,h) ((y + h - 1) * shaStride + (x + w - 1))
+#define STEPDOWN(x,y,w,h) ((h)--)
+#define NEXTY(x,y,w,h) ((void)(y))
+#define SHASTEPX(stride) (-1)
+#define SHASTEPY(stride) -(stride)
+
+#else
+
+#define SCRLEFT(x,y,w,h) (x)
+#define SCRY(x,y,w,h) (y)
+#define SCRWIDTH(x,y,w,h) (w)
+#define FIRSTSHA(x,y,w,h) ((y) * shaStride + (x))
+#define STEPDOWN(x,y,w,h) ((h)--)
+#define NEXTY(x,y,w,h) ((y)++)
+#define SHASTEPX(stride) (1)
+#define SHASTEPY(stride) (stride)
+
+#endif
+
+void
+FUNC (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
+{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = REGION_NUM_RECTS (damage);
+ BoxPtr pbox = REGION_RECTS (damage);
+ FbBits *shaBits;
+ Data *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ Data *winBase = NULL, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
+ shaBase = (Data *) shaBits;
+ shaStride = shaStride * sizeof (FbBits) / sizeof (Data);
+#if (DANDEBUG > 1)
+ ErrorF ("-> Entering Shadow Update:\r\n |- Origins: pShadow=%x, pScreen=%x, damage=%x\r\n |- Metrics: shaStride=%d, shaBase=%x, shaBpp=%d\r\n | \n", pShadow, pScreen, damage, shaStride, shaBase, shaBpp);
+#endif
+ while (nbox--)
+ {
+ x = pbox->x1;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1);
+ h = pbox->y2 - pbox->y1;
+
+#if (DANDEBUG > 2)
+ ErrorF (" |-> Redrawing box - Metrics: X=%d, Y=%d, Width=%d, Height=%d\n", x, y, w, h);
+#endif
+ scrLine = SCRLEFT(x,y,w,h);
+ shaLine = shaBase + FIRSTSHA(x,y,w,h);
+
+ while (STEPDOWN(x,y,w,h))
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = SCRWIDTH(x,y,w,h);
+ scr = scrLine;
+ sha = shaLine;
+#if (DANDEBUG > 3)
+ ErrorF (" | |-> StepDown - Metrics: width=%d, scr=%x, sha=%x\n", width, scr, sha);
+#endif
+ while (width)
+ {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (Data *) (*pBuf->window) (pScreen,
+ SCRY(x,y,w,h),
+ scr * sizeof (Data),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (Data);
+ i = winSize;
+#if(DANDEBUG > 4)
+ ErrorF (" | | |-> Starting New Line - Metrics: winBase=%x, scrBase=%x, winSize=%d\r\n | | | Xstride=%d, Ystride=%d, w=%d h=%d\n", winBase, scrBase, winSize, SHASTEPX(shaStride), SHASTEPY(shaStride), w, h);
+#endif
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+#if(DANDEBUG > 5)
+ ErrorF (" | | |-> Writing Line - Metrics: win=%x, sha=%x\n", win, sha);
+#endif
+ while (i--)
+ {
+#if(DANDEBUG > 6)
+ ErrorF (" | | |-> Writing Pixel - Metrics: win=%x, sha=%d, remaining=%d\n", win, sha, i);
+#endif
+ *win++ = *sha;
+ sha += SHASTEPX(shaStride);
+ } /* i */
+ } /* width */
+ shaLine += SHASTEPY(shaStride);
+ NEXTY(x,y,w,h);
+ } /* STEPDOWN */
+ pbox++;
+ } /* nbox */
+}