diff options
Diffstat (limited to 'composite/compinit.c')
-rw-r--r-- | composite/compinit.c | 389 |
1 files changed, 389 insertions, 0 deletions
diff --git a/composite/compinit.c b/composite/compinit.c new file mode 100644 index 000000000..5109a74fa --- /dev/null +++ b/composite/compinit.c @@ -0,0 +1,389 @@ +/* + * $Id$ + * + * Copyright © 2003 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_CONFIG_H +#include <config.h> +#endif +#include "compint.h" + +int CompScreenPrivateIndex; +int CompWindowPrivateIndex; +int CompSubwindowsPrivateIndex; +int CompGeneration; + +static Bool +compCloseScreen (int index, ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret; + + pScreen->CloseScreen = cs->CloseScreen; + pScreen->BlockHandler = cs->BlockHandler; + pScreen->InstallColormap = cs->InstallColormap; + pScreen->ReparentWindow = cs->ReparentWindow; + pScreen->MoveWindow = cs->MoveWindow; + pScreen->ResizeWindow = cs->ResizeWindow; + pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; + + pScreen->ClipNotify = cs->ClipNotify; + pScreen->PaintWindowBackground = cs->PaintWindowBackground; + pScreen->UnrealizeWindow = cs->UnrealizeWindow; + pScreen->RealizeWindow = cs->RealizeWindow; + pScreen->DestroyWindow = cs->DestroyWindow; + pScreen->CreateWindow = cs->CreateWindow; + pScreen->CopyWindow = cs->CopyWindow; + pScreen->PositionWindow = cs->PositionWindow; + xfree (cs); + pScreen->devPrivates[CompScreenPrivateIndex].ptr = 0; + ret = (*pScreen->CloseScreen) (index, pScreen); + return ret; +} + +static void +compInstallColormap (ColormapPtr pColormap) +{ + VisualPtr pVisual = pColormap->pVisual; + ScreenPtr pScreen = pColormap->pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + int a; + + for (a = 0; a < NUM_COMP_ALTERNATE_VISUALS; a++) + if (pVisual->vid == cs->alternateVisuals[a]) + return; + pScreen->InstallColormap = cs->InstallColormap; + (*pScreen->InstallColormap) (pColormap); + cs->InstallColormap = pScreen->InstallColormap; + pScreen->InstallColormap = compInstallColormap; +} + +static void +compScreenUpdate (ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen (pScreen); + + compCheckTree (pScreen); + if (cs->damaged) + { + compWindowUpdate (WindowTable[pScreen->myNum]); + cs->damaged = FALSE; + } +} + +static void +compBlockHandler (int i, + pointer blockData, + pointer pTimeout, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + CompScreenPtr cs = GetCompScreen (pScreen); + + pScreen->BlockHandler = cs->BlockHandler; + compScreenUpdate (pScreen); + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + cs->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = compBlockHandler; +} + +/* + * Add alternate visuals -- always expose an ARGB32 and RGB24 visual + */ + +static DepthPtr +compFindVisuallessDepth (ScreenPtr pScreen, int d) +{ + int i; + + for (i = 0; i < pScreen->numDepths; i++) + { + DepthPtr depth = &pScreen->allowedDepths[i]; + if (depth->depth == d) + { + /* + * Make sure it doesn't have visuals already + */ + if (depth->numVids) + return 0; + /* + * looks fine + */ + return depth; + } + } + /* + * If there isn't one, then it's gonna be hard to have + * an associated visual + */ + return 0; +} + +typedef struct _alternateVisual { + int depth; + CARD32 format; +} CompAlternateVisual; + +static CompAlternateVisual altVisuals[NUM_COMP_ALTERNATE_VISUALS] = { +#if COMP_INCLUDE_RGB24_VISUAL + { 24, PICT_r8g8b8 }, +#endif + { 32, PICT_a8r8g8b8 }, +}; + +static Bool +compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs) +{ + VisualPtr visuals; + DepthPtr depths[NUM_COMP_ALTERNATE_VISUALS]; + PictFormatPtr pPictFormats[NUM_COMP_ALTERNATE_VISUALS]; + int i; + int numVisuals; + VisualID *vids[NUM_COMP_ALTERNATE_VISUALS]; + XID *installedCmaps; + ColormapPtr installedCmap; + int numInstalledCmaps; + int numAlternate = 0; + int alt; + + memset (cs->alternateVisuals, '\0', sizeof (cs->alternateVisuals)); + + for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++) + { + DepthPtr depth; + PictFormatPtr pPictFormat; + + depth = compFindVisuallessDepth (pScreen, altVisuals[alt].depth); + if (!depth) + continue; + /* + * Find the right picture format + */ + pPictFormat = PictureMatchFormat (pScreen, altVisuals[alt].depth, + altVisuals[alt].format); + if (!pPictFormat) + continue; + + /* + * Allocate vid list for this depth + */ + vids[numAlternate] = xalloc (sizeof (VisualID)); + if (!vids[numAlternate]) + continue; + depths[numAlternate] = depth; + pPictFormats[numAlternate] = pPictFormat; + numAlternate++; + } + + if (!numAlternate) + return TRUE; + + /* + * Find the installed colormaps + */ + installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); + if (!installedCmaps) + { + for (alt = 0; alt < numAlternate; alt++) + xfree (vids[alt]); + return FALSE; + } + numInstalledCmaps = (*pScreen->ListInstalledColormaps) (pScreen, + installedCmaps); + + /* + * realloc the visual array to fit the new one in place + */ + numVisuals = pScreen->numVisuals; + visuals = xrealloc (pScreen->visuals, + (numVisuals + numAlternate) * sizeof (VisualRec)); + if (!visuals) + { + for (alt = 0; alt < numAlternate; alt++) + xfree (vids[alt]); + xfree (installedCmaps); + return FALSE; + } + + /* + * Fix up any existing installed colormaps -- we'll assume that + * the only ones created so far have been installed. If this + * isn't true, we'll have to walk the resource database looking + * for all colormaps. + */ + for (i = 0; i < numInstalledCmaps; i++) + { + int j; + + installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); + if (!installedCmap) + continue; + j = installedCmap->pVisual - pScreen->visuals; + installedCmap->pVisual = &visuals[j]; + } + + xfree (installedCmaps); + + pScreen->visuals = visuals; + pScreen->numVisuals = numVisuals + numAlternate; + + for (alt = 0; alt < numAlternate; alt++) + { + DepthPtr depth = depths[alt]; + PictFormatPtr pPictFormat = pPictFormats[alt]; + VisualPtr visual = &visuals[numVisuals + alt]; + unsigned long alphaMask; + + /* + * Initialize the visual + */ + visual->class = TrueColor; + visual->bitsPerRGBValue = 8; + + visual->vid = FakeClientID (0); + visual->redMask = (((unsigned long) pPictFormat->direct.redMask) << + pPictFormat->direct.red); + visual->greenMask = (((unsigned long) pPictFormat->direct.greenMask) << + pPictFormat->direct.green); + visual->blueMask = (((unsigned long) pPictFormat->direct.blueMask) << + pPictFormat->direct.blue); + alphaMask = (((unsigned long) pPictFormat->direct.alphaMask) << + pPictFormat->direct.alpha); + visual->offsetRed = pPictFormat->direct.red; + visual->offsetGreen = pPictFormat->direct.green; + visual->offsetBlue = pPictFormat->direct.blue; + /* + * Include A bits in this (unlike GLX which includes only RGB) + * This lets DIX compute suitable masks for colormap allocations + */ + visual->nplanes = Ones (visual->redMask | + visual->greenMask | + visual->blueMask | + alphaMask); + /* + * find widest component + */ + visual->ColormapEntries = (1 << max (Ones (visual->redMask), + max (Ones (visual->greenMask), + Ones (visual->blueMask)))); + + /* + * remember the visual ID to detect auto-update windows + */ + cs->alternateVisuals[alt] = visual->vid; + + /* + * Fix up the depth + */ + vids[alt][0] = visual->vid; + depth->numVids = 1; + depth->vids = vids[alt]; + } + return TRUE; +} + +Bool +compScreenInit (ScreenPtr pScreen) +{ + CompScreenPtr cs; + + if (CompGeneration != serverGeneration) + { + CompScreenPrivateIndex = AllocateScreenPrivateIndex (); + if (CompScreenPrivateIndex == -1) + return FALSE; + CompWindowPrivateIndex = AllocateWindowPrivateIndex (); + if (CompWindowPrivateIndex == -1) + return FALSE; + CompSubwindowsPrivateIndex = AllocateWindowPrivateIndex (); + if (CompSubwindowsPrivateIndex == -1) + return FALSE; + CompGeneration = serverGeneration; + } + if (!AllocateWindowPrivate (pScreen, CompWindowPrivateIndex, 0)) + return FALSE; + + if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivateIndex, 0)) + return FALSE; + + if (GetCompScreen (pScreen)) + return TRUE; + cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec)); + if (!cs) + return FALSE; + + cs->damaged = FALSE; + + if (!compAddAlternateVisuals (pScreen, cs)) + { + xfree (cs); + return FALSE; + } + + cs->PositionWindow = pScreen->PositionWindow; + pScreen->PositionWindow = compPositionWindow; + + cs->CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = compCopyWindow; + + cs->CreateWindow = pScreen->CreateWindow; + pScreen->CreateWindow = compCreateWindow; + + cs->DestroyWindow = pScreen->DestroyWindow; + pScreen->DestroyWindow = compDestroyWindow; + + cs->RealizeWindow = pScreen->RealizeWindow; + pScreen->RealizeWindow = compRealizeWindow; + + cs->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = compUnrealizeWindow; + + cs->PaintWindowBackground = pScreen->PaintWindowBackground; + pScreen->PaintWindowBackground = compPaintWindowBackground; + + cs->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = compClipNotify; + + cs->MoveWindow = pScreen->MoveWindow; + pScreen->MoveWindow = compMoveWindow; + + cs->ResizeWindow = pScreen->ResizeWindow; + pScreen->ResizeWindow = compResizeWindow; + + cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; + pScreen->ChangeBorderWidth = compChangeBorderWidth; + + cs->ReparentWindow = pScreen->ReparentWindow; + pScreen->ReparentWindow = compReparentWindow; + + cs->InstallColormap = pScreen->InstallColormap; + pScreen->InstallColormap = compInstallColormap; + + cs->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = compBlockHandler; + + cs->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = compCloseScreen; + + pScreen->devPrivates[CompScreenPrivateIndex].ptr = (pointer) cs; + return TRUE; +} |