e03198972c
Add XSERV_t, TRANS_SERVER, TRANS_REOPEN to quash warnings. Add #include <dix-config.h> or <xorg-config.h>, as appropriate, to all source files in the xserver/xorg tree, predicated on defines of HAVE_{DIX,XORG}_CONFIG_H. Change all Xfont includes to <X11/fonts/foo.h>.
364 lines
9.3 KiB
C
364 lines
9.3 KiB
C
/*
|
|
* $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;
|
|
}
|