#include "layerstr.h"
int layerScrPrivateIndex;
int layerGCPrivateIndex;
int layerWinPrivateIndex;
int layerGeneration;
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;
if (LayerNewKind (pScreen) < 0)
{
pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
xfree (pScrPriv);
return FALSE;
}
if (!shadowSetup (pScreen))
return FALSE;
if (LayerNewKind (pScreen) < 0)
{
pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
xfree (pScrPriv->kinds);
xfree (pScrPriv);
return FALSE;
}
return TRUE;
}
int
LayerNewKind (ScreenPtr pScreen)
{
layerScrPriv(pScreen);
LayerKindPtr pLayKind, pLayKinds;
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreen (pScreen);
#endif
LayerPtr pLayer;
if (pLayScr->kinds)
pLayKinds = (LayerKindPtr) xrealloc ((pointer) pLayScr->kinds,
(pLayScr->nkinds + 1) * sizeof (LayerKindRec));
else
pLayKinds = (LayerKindPtr) xalloc (sizeof (LayerKindRec));
if (!pLayKinds)
return -1;
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;
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 (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;
}
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;
}
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;
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);
for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
;
*pPrev = pLay;
return pLay;
}
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;
}
}
void
LayerDestroy (ScreenPtr pScreen, LayerPtr pLay)
{
layerScrPriv(pScreen);
LayerPtr *pPrev;
--pLay->refcnt;
if (pLay->refcnt > 0)
return;
for (pPrev = &pLayScr->pLayers; *pPrev; pPrev = &(*pPrev)->pNext)
if (*pPrev == pLay)
{
*pPrev = pLay->pNext;
break;
}
LayerDestroyPixmap (pScreen, pLay);
REGION_UNINIT (pScreen, &pLay->region);
xfree (pLay);
}
Bool
layerCloseScreen (int index, ScreenPtr pScreen)
{
layerScrPriv(pScreen);
int kind;
kind = pLayScr->nkinds - 1;
pScreen->CloseScreen = pLayScr->kinds[kind].CloseScreen;
(*pScreen->CloseScreen) (index, pScreen);
if (kind != LAYER_SHADOW)
xfree (shadowGetScrPriv (pScreen));
xfree (pLayScr->kinds);
xfree (pLayScr);
pScreen->devPrivates[layerScrPrivateIndex].ptr = 0;
return TRUE;
}