diff options
Diffstat (limited to 'xorg-server/composite/compinit.c')
-rw-r--r-- | xorg-server/composite/compinit.c | 831 |
1 files changed, 416 insertions, 415 deletions
diff --git a/xorg-server/composite/compinit.c b/xorg-server/composite/compinit.c index 291b759be..eaa125681 100644 --- a/xorg-server/composite/compinit.c +++ b/xorg-server/composite/compinit.c @@ -1,415 +1,416 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * 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_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "compint.h"
-#include "compositeext.h"
-
-DevPrivateKeyRec CompScreenPrivateKeyRec;
-DevPrivateKeyRec CompWindowPrivateKeyRec;
-DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
-
-static Bool
-compCloseScreen (int index, ScreenPtr pScreen)
-{
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret;
-
- free(cs->alternateVisuals);
-
- pScreen->CloseScreen = cs->CloseScreen;
- pScreen->InstallColormap = cs->InstallColormap;
- pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
- pScreen->ReparentWindow = cs->ReparentWindow;
- pScreen->ConfigNotify = cs->ConfigNotify;
- pScreen->MoveWindow = cs->MoveWindow;
- pScreen->ResizeWindow = cs->ResizeWindow;
- pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
-
- pScreen->ClipNotify = cs->ClipNotify;
- pScreen->UnrealizeWindow = cs->UnrealizeWindow;
- pScreen->RealizeWindow = cs->RealizeWindow;
- pScreen->DestroyWindow = cs->DestroyWindow;
- pScreen->CreateWindow = cs->CreateWindow;
- pScreen->CopyWindow = cs->CopyWindow;
- pScreen->PositionWindow = cs->PositionWindow;
-
- pScreen->GetImage = cs->GetImage;
- pScreen->SourceValidate = cs->SourceValidate;
-
- free(cs);
- dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
- 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 < cs->numAlternateVisuals; a++)
- if (pVisual->vid == cs->alternateVisuals[a])
- return;
- pScreen->InstallColormap = cs->InstallColormap;
- (*pScreen->InstallColormap) (pColormap);
- cs->InstallColormap = pScreen->InstallColormap;
- pScreen->InstallColormap = compInstallColormap;
-}
-
-/* Fake backing store via automatic redirection */
-static Bool
-compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret;
-
- pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
- ret = pScreen->ChangeWindowAttributes(pWin, mask);
-
- if (ret && (mask & CWBackingStore) &&
- pScreen->backingStoreSupport != NotUseful) {
- if (pWin->backingStore != NotUseful) {
- compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
- pWin->backStorage = (pointer) (intptr_t) 1;
- } else {
- compUnredirectWindow(serverClient, pWin,
- CompositeRedirectAutomatic);
- pWin->backStorage = NULL;
- }
- }
-
- pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
-
- return ret;
-}
-
-static void
-compGetImage (DrawablePtr pDrawable,
- int sx, int sy,
- int w, int h,
- unsigned int format,
- unsigned long planemask,
- char *pdstLine)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->GetImage = cs->GetImage;
- if (pDrawable->type == DRAWABLE_WINDOW)
- compPaintChildrenToWindow ((WindowPtr) pDrawable);
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
- cs->GetImage = pScreen->GetImage;
- pScreen->GetImage = compGetImage;
-}
-
-static void compSourceValidate(DrawablePtr pDrawable,
- int x, int y,
- int width, int height,
- unsigned int subWindowMode)
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->SourceValidate = cs->SourceValidate;
- if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors)
- compPaintChildrenToWindow ((WindowPtr) pDrawable);
- if (pScreen->SourceValidate)
- (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
- subWindowMode);
- cs->SourceValidate = pScreen->SourceValidate;
- pScreen->SourceValidate = compSourceValidate;
-}
-
-/*
- * 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;
-}
-
-/*
- * Add a list of visual IDs to the list of visuals to implicitly redirect.
- */
-static Bool
-compRegisterAlternateVisuals (CompScreenPtr cs, VisualID *vids, int nVisuals)
-{
- VisualID *p;
-
- p = realloc(cs->alternateVisuals,
- sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals));
- if(p == NULL)
- return FALSE;
-
- memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
-
- cs->alternateVisuals = p;
- cs->numAlternateVisuals += nVisuals;
-
- return TRUE;
-}
-
-Bool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids,
- int nVisuals)
-{
- CompScreenPtr cs = GetCompScreen (pScreen);
- return compRegisterAlternateVisuals(cs, vids, nVisuals);
-}
-
-typedef struct _alternateVisual {
- int depth;
- CARD32 format;
-} CompAlternateVisual;
-
-static CompAlternateVisual altVisuals[] = {
-#if COMP_INCLUDE_RGB24_VISUAL
- { 24, PICT_r8g8b8 },
-#endif
- { 32, PICT_a8r8g8b8 },
-};
-
-static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
- sizeof(CompAlternateVisual);
-
-static Bool
-compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs,
- CompAlternateVisual *alt)
-{
- VisualPtr visual;
- DepthPtr depth;
- PictFormatPtr pPictFormat;
- unsigned long alphaMask;
-
- /*
- * The ARGB32 visual is always available. Other alternate depth visuals
- * are only provided if their depth is less than the root window depth.
- * There's no deep reason for this.
- */
- if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
- return FALSE;
-
- depth = compFindVisuallessDepth (pScreen, alt->depth);
- if (!depth)
- /* alt->depth doesn't exist or already has alternate visuals. */
- return TRUE;
-
- pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format);
- if (!pPictFormat)
- return FALSE;
-
- if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
- return FALSE;
- }
-
- visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */
-
- /* Initialize the visual */
- visual->bitsPerRGBValue = 8;
- if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
- visual->class = PseudoColor;
- visual->nplanes = PICT_FORMAT_BPP(alt->format);
- visual->ColormapEntries = 1 << visual->nplanes;
- } else {
- DirectFormatRec *direct = &pPictFormat->direct;
- visual->class = TrueColor;
- visual->redMask = ((unsigned long)direct->redMask) << direct->red;
- visual->greenMask = ((unsigned long)direct->greenMask) << direct->green;
- visual->blueMask = ((unsigned long)direct->blueMask) << direct->blue;
- alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha;
- visual->offsetRed = direct->red;
- visual->offsetGreen = direct->green;
- visual->offsetBlue = 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 */
- compRegisterAlternateVisuals(cs, &visual->vid, 1);
-
- return TRUE;
-}
-
-static Bool
-compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
-{
- int alt, ret = 0;
-
- for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
- ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
-
- return !!ret;
-}
-
-Bool
-compScreenInit (ScreenPtr pScreen)
-{
- CompScreenPtr cs;
-
- if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
- if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
- return FALSE;
-
- if (GetCompScreen (pScreen))
- return TRUE;
- cs = (CompScreenPtr) malloc(sizeof (CompScreenRec));
- if (!cs)
- return FALSE;
-
- cs->overlayWid = FakeClientID(0);
- cs->pOverlayWin = NULL;
- cs->pOverlayClients = NULL;
-
- cs->numAlternateVisuals = 0;
- cs->alternateVisuals = NULL;
-
- if (!compAddAlternateVisuals (pScreen, cs))
- {
- free(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->ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = compClipNotify;
-
- cs->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = compConfigNotify;
-
- 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->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
- pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
-
- cs->BlockHandler = NULL;
-
- cs->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = compCloseScreen;
-
- cs->GetImage = pScreen->GetImage;
- pScreen->GetImage = compGetImage;
-
- cs->SourceValidate = pScreen->SourceValidate;
- pScreen->SourceValidate = compSourceValidate;
-
- dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
-
- RegisterRealChildHeadProc(CompositeRealChildHead);
-
- return TRUE;
-}
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * 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_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "compint.h" +#include "compositeext.h" + +DevPrivateKeyRec CompScreenPrivateKeyRec; +DevPrivateKeyRec CompWindowPrivateKeyRec; +DevPrivateKeyRec CompSubwindowsPrivateKeyRec; + +static Bool +compCloseScreen(int index, ScreenPtr pScreen) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + Bool ret; + + free(cs->alternateVisuals); + + pScreen->CloseScreen = cs->CloseScreen; + pScreen->InstallColormap = cs->InstallColormap; + pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; + pScreen->ReparentWindow = cs->ReparentWindow; + pScreen->ConfigNotify = cs->ConfigNotify; + pScreen->MoveWindow = cs->MoveWindow; + pScreen->ResizeWindow = cs->ResizeWindow; + pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; + + pScreen->ClipNotify = cs->ClipNotify; + pScreen->UnrealizeWindow = cs->UnrealizeWindow; + pScreen->RealizeWindow = cs->RealizeWindow; + pScreen->DestroyWindow = cs->DestroyWindow; + pScreen->CreateWindow = cs->CreateWindow; + pScreen->CopyWindow = cs->CopyWindow; + pScreen->PositionWindow = cs->PositionWindow; + + pScreen->GetImage = cs->GetImage; + pScreen->SourceValidate = cs->SourceValidate; + + free(cs); + dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL); + 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 < cs->numAlternateVisuals; a++) + if (pVisual->vid == cs->alternateVisuals[a]) + return; + pScreen->InstallColormap = cs->InstallColormap; + (*pScreen->InstallColormap) (pColormap); + cs->InstallColormap = pScreen->InstallColormap; + pScreen->InstallColormap = compInstallColormap; +} + +/* Fake backing store via automatic redirection */ +static Bool +compChangeWindowAttributes(WindowPtr pWin, unsigned long mask) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen(pScreen); + Bool ret; + + pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; + ret = pScreen->ChangeWindowAttributes(pWin, mask); + + if (ret && (mask & CWBackingStore) && + pScreen->backingStoreSupport != NotUseful) { + if (pWin->backingStore != NotUseful) { + compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); + pWin->backStorage = (pointer) (intptr_t) 1; + } + else { + compUnredirectWindow(serverClient, pWin, + CompositeRedirectAutomatic); + pWin->backStorage = NULL; + } + } + + pScreen->ChangeWindowAttributes = compChangeWindowAttributes; + + return ret; +} + +static void +compGetImage(DrawablePtr pDrawable, + int sx, int sy, + int w, int h, + unsigned int format, unsigned long planemask, char *pdstLine) +{ + ScreenPtr pScreen = pDrawable->pScreen; + CompScreenPtr cs = GetCompScreen(pScreen); + + pScreen->GetImage = cs->GetImage; + if (pDrawable->type == DRAWABLE_WINDOW) + compPaintChildrenToWindow((WindowPtr) pDrawable); + (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); + cs->GetImage = pScreen->GetImage; + pScreen->GetImage = compGetImage; +} + +static void +compSourceValidate(DrawablePtr pDrawable, + int x, int y, + int width, int height, unsigned int subWindowMode) +{ + ScreenPtr pScreen = pDrawable->pScreen; + CompScreenPtr cs = GetCompScreen(pScreen); + + pScreen->SourceValidate = cs->SourceValidate; + if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors) + compPaintChildrenToWindow((WindowPtr) pDrawable); + if (pScreen->SourceValidate) + (*pScreen->SourceValidate) (pDrawable, x, y, width, height, + subWindowMode); + cs->SourceValidate = pScreen->SourceValidate; + pScreen->SourceValidate = compSourceValidate; +} + +/* + * 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; +} + +/* + * Add a list of visual IDs to the list of visuals to implicitly redirect. + */ +static Bool +compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals) +{ + VisualID *p; + + p = realloc(cs->alternateVisuals, + sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals)); + if (p == NULL) + return FALSE; + + memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals); + + cs->alternateVisuals = p; + cs->numAlternateVisuals += nVisuals; + + return TRUE; +} + +Bool +CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, + int nVisuals) +{ + CompScreenPtr cs = GetCompScreen(pScreen); + + return compRegisterAlternateVisuals(cs, vids, nVisuals); +} + +typedef struct _alternateVisual { + int depth; + CARD32 format; +} CompAlternateVisual; + +static CompAlternateVisual altVisuals[] = { +#if COMP_INCLUDE_RGB24_VISUAL + {24, PICT_r8g8b8}, +#endif + {32, PICT_a8r8g8b8}, +}; + +static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) / + sizeof(CompAlternateVisual); + +static Bool +compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs, + CompAlternateVisual * alt) +{ + VisualPtr visual; + DepthPtr depth; + PictFormatPtr pPictFormat; + unsigned long alphaMask; + + /* + * The ARGB32 visual is always available. Other alternate depth visuals + * are only provided if their depth is less than the root window depth. + * There's no deep reason for this. + */ + if (alt->depth >= pScreen->rootDepth && alt->depth != 32) + return FALSE; + + depth = compFindVisuallessDepth(pScreen, alt->depth); + if (!depth) + /* alt->depth doesn't exist or already has alternate visuals. */ + return TRUE; + + pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format); + if (!pPictFormat) + return FALSE; + + if (ResizeVisualArray(pScreen, 1, depth) == FALSE) { + return FALSE; + } + + visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */ + + /* Initialize the visual */ + visual->bitsPerRGBValue = 8; + if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) { + visual->class = PseudoColor; + visual->nplanes = PICT_FORMAT_BPP(alt->format); + visual->ColormapEntries = 1 << visual->nplanes; + } + else { + DirectFormatRec *direct = &pPictFormat->direct; + + visual->class = TrueColor; + visual->redMask = ((unsigned long) direct->redMask) << direct->red; + visual->greenMask = + ((unsigned long) direct->greenMask) << direct->green; + visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue; + alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha; + visual->offsetRed = direct->red; + visual->offsetGreen = direct->green; + visual->offsetBlue = 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 */ + compRegisterAlternateVisuals(cs, &visual->vid, 1); + + return TRUE; +} + +static Bool +compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs) +{ + int alt, ret = 0; + + for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++) + ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt); + + return ! !ret; +} + +Bool +compScreenInit(ScreenPtr pScreen) +{ + CompScreenPtr cs; + + if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0)) + return FALSE; + + if (GetCompScreen(pScreen)) + return TRUE; + cs = (CompScreenPtr) malloc(sizeof(CompScreenRec)); + if (!cs) + return FALSE; + + cs->overlayWid = FakeClientID(0); + cs->pOverlayWin = NULL; + cs->pOverlayClients = NULL; + + cs->numAlternateVisuals = 0; + cs->alternateVisuals = NULL; + + if (!compAddAlternateVisuals(pScreen, cs)) { + free(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->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = compClipNotify; + + cs->ConfigNotify = pScreen->ConfigNotify; + pScreen->ConfigNotify = compConfigNotify; + + 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->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + pScreen->ChangeWindowAttributes = compChangeWindowAttributes; + + cs->BlockHandler = NULL; + + cs->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = compCloseScreen; + + cs->GetImage = pScreen->GetImage; + pScreen->GetImage = compGetImage; + + cs->SourceValidate = pScreen->SourceValidate; + pScreen->SourceValidate = compSourceValidate; + + dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs); + + RegisterRealChildHeadProc(CompositeRealChildHead); + + return TRUE; +} |