diff options
Diffstat (limited to 'nx-X11/programs/Xserver/miext/layer')
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/Imakefile | 49 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layer.h | 149 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layergc.c | 194 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layerinit.c | 363 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layerpict.c | 149 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layerstr.h | 425 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/layerwin.c | 487 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/miext/layer/laymodule.c | 60 |
8 files changed, 1876 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/miext/layer/Imakefile b/nx-X11/programs/Xserver/miext/layer/Imakefile new file mode 100644 index 000000000..32507d20a --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/Imakefile @@ -0,0 +1,49 @@ +XCOMM $XFree86: xc/programs/Xserver/miext/layer/Imakefile,v 1.1 2001/05/29 04:54:13 keithp Exp $ +XCOMM +XCOMM + +#define IHaveModules +#include <Server.tmpl> + +#if (defined(XFree86Version) || defined(XorgVersion)) +#if DoLoadableServer +XFMODSRC = laymodule.c +XFMODOBJ = laymodule.o +#endif +#endif + +#if BuildRender +RENDERSRC = layerpict.c +RENDEROBJ = layerpict.o +#endif + +SRCS = layergc.c \ + layerinit.c \ + $(RENDERSRC) \ + layerwin.c \ + $(XFMODSRC) + +OBJS = layergc.o \ + layerinit.o \ + $(RENDEROBJ) \ + layerwin.o \ + $(XFMODOBJ) + + INCLUDES = -I. -I../shadow -I../../mi -I../../fb -I../../include -I$(XINCLUDESRC) \ + -I$(FONTINCSRC) -I$(XF86SRC)/common $(EXTRAINCLUDES) \ + -I../../render -I$(EXTINCSRC) + LINTLIBS = ../../dix/llib-ldix.ln ../../os/llib-los.ln \ + ../../mi/llib-lmi.ln + +NormalLibraryObjectRule() +LibraryModuleTarget(layer,$(OBJS)) +LintLibraryTarget(layer,$(SRCS)) + +NormalLintTarget($(SRCS)) + +InstallLibraryModule(layer,$(MODULEDIR),.) + +DependTarget() + +InstallDriverSDKLibraryModule(layer,$(DRIVERSDKMODULEDIR),.) +InstallDriverSDKNonExecFile(layer.h,$(DRIVERSDKINCLUDEDIR)) diff --git a/nx-X11/programs/Xserver/miext/layer/layer.h b/nx-X11/programs/Xserver/miext/layer/layer.h new file mode 100644 index 000000000..e8f3a856e --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layer.h @@ -0,0 +1,149 @@ +/* + * $XFree86: xc/programs/Xserver/miext/layer/layer.h,v 1.4 2001/08/01 00:44:58 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#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/nx-X11/programs/Xserver/miext/layer/layergc.c b/nx-X11/programs/Xserver/miext/layer/layergc.c new file mode 100644 index 000000000..343edfcf5 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layergc.c @@ -0,0 +1,194 @@ +/* + * $XFree86: xc/programs/Xserver/miext/layer/layergc.c,v 1.4 2001/08/27 03:55:46 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#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/nx-X11/programs/Xserver/miext/layer/layerinit.c b/nx-X11/programs/Xserver/miext/layer/layerinit.c new file mode 100644 index 000000000..994c6747c --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layerinit.c @@ -0,0 +1,363 @@ +/* + * $XFree86: xc/programs/Xserver/miext/layer/layerinit.c,v 1.6tsi 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#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_NULL(pScreen, &pLay->region); + /* + * 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/nx-X11/programs/Xserver/miext/layer/layerpict.c b/nx-X11/programs/Xserver/miext/layer/layerpict.c new file mode 100644 index 000000000..16e46f0ab --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layerpict.c @@ -0,0 +1,149 @@ +/* + * $XFree86$ + * + * 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#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/nx-X11/programs/Xserver/miext/layer/layerstr.h b/nx-X11/programs/Xserver/miext/layer/layerstr.h new file mode 100644 index 000000000..fb5a0d411 --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layerstr.h @@ -0,0 +1,425 @@ +/* + * $XFree86: xc/programs/Xserver/miext/layer/layerstr.h,v 1.2 2001/06/04 09:45:41 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _LAYERSTR_H_ +#define _LAYERSTR_H_ + +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/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; +#ifdef RENDER + CompositeProcPtr Composite; + GlyphsProcPtr Glyphs; + CompositeRectsProcPtr CompositeRects; +#endif +} 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); + +#ifdef RENDER +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); +#endif +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/nx-X11/programs/Xserver/miext/layer/layerwin.c b/nx-X11/programs/Xserver/miext/layer/layerwin.c new file mode 100644 index 000000000..7afe90ade --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/layerwin.c @@ -0,0 +1,487 @@ +/* + * $XFree86: xc/programs/Xserver/miext/layer/layerwin.c,v 1.7tsi 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. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#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_NULL (pScreen, &pLayList->clipList); + REGION_NULL (pScreen, &pLayList->borderClip); + 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/nx-X11/programs/Xserver/miext/layer/laymodule.c b/nx-X11/programs/Xserver/miext/layer/laymodule.c new file mode 100644 index 000000000..5af41617a --- /dev/null +++ b/nx-X11/programs/Xserver/miext/layer/laymodule.c @@ -0,0 +1,60 @@ +/* + * $XFree86$ + * + * 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. + */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifdef XFree86LOADER + +#include "xf86Module.h" +#include <X11/X.h> +#include "scrnintstr.h" +#include "windowstr.h" +#include <X11/fonts/font.h> +#include "dixfontstr.h" +#include <X11/fonts/fontstruct.h> +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "layer.h" + +static XF86ModuleVersionInfo VersRec = +{ + "layer", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_ANSIC, /* Only need the ansic layer */ + ABI_ANSIC_VERSION, + MOD_CLASS_NONE, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +XF86ModuleData layerModuleData = { &VersRec, NULL, NULL }; + +#endif |