diff options
Diffstat (limited to 'xorg-server/composite')
-rw-r--r-- | xorg-server/composite/compalloc.c | 1295 | ||||
-rw-r--r-- | xorg-server/composite/compext.c | 1174 | ||||
-rw-r--r-- | xorg-server/composite/compinit.c | 788 | ||||
-rw-r--r-- | xorg-server/composite/compoverlay.c | 320 |
4 files changed, 1789 insertions, 1788 deletions
diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c index 73adc72d0..e56a27e96 100644 --- a/xorg-server/composite/compalloc.c +++ b/xorg-server/composite/compalloc.c @@ -1,647 +1,648 @@ -/* - * Copyright © 2006 Sun Microsystems, Inc. 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" - -static void -compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) -{ - WindowPtr pWin = (WindowPtr) closure; - ScreenPtr pScreen = pWin->drawable.pScreen; - CompScreenPtr cs = GetCompScreen (pScreen); - CompWindowPtr cw = GetCompWindow (pWin); - - cs->damaged = TRUE; - cw->damaged = TRUE; -} - -static void -compDestroyDamage (DamagePtr pDamage, void *closure) -{ - WindowPtr pWin = (WindowPtr) closure; - CompWindowPtr cw = GetCompWindow (pWin); - - cw->damage = 0; -} - -/* - * Redirect one window for one client - */ -int -compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw; - Bool wasMapped = pWin->mapped; - CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); - - if (pWin == cs->pOverlayWin) { - return Success; - } - - if (!pWin->parent) - return BadMatch; - - /* - * Only one Manual update is allowed - */ - if (cw && update == CompositeRedirectManual) - for (ccw = cw->clients; ccw; ccw = ccw->next) - if (ccw->update == CompositeRedirectManual) - return BadAccess; - - /* - * Allocate per-client per-window structure - * The client *could* allocate multiple, but while supported, - * it is not expected to be common - */ - ccw = xalloc (sizeof (CompClientWindowRec)); - if (!ccw) - return BadAlloc; - ccw->id = FakeClientID (pClient->index); - ccw->update = update; - /* - * Now make sure there's a per-window structure to hang this from - */ - if (!cw) - { - cw = xalloc (sizeof (CompWindowRec)); - if (!cw) - { - xfree (ccw); - return BadAlloc; - } - cw->damage = DamageCreate (compReportDamage, - compDestroyDamage, - DamageReportNonEmpty, - FALSE, - pWin->drawable.pScreen, - pWin); - if (!cw->damage) - { - xfree (ccw); - xfree (cw); - return BadAlloc; - } - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - - REGION_NULL (pScreen, &cw->borderClip); - cw->borderClipX = 0; - cw->borderClipY = 0; - cw->update = CompositeRedirectAutomatic; - cw->clients = 0; - cw->oldx = COMP_ORIGIN_INVALID; - cw->oldy = COMP_ORIGIN_INVALID; - cw->damageRegistered = FALSE; - cw->damaged = FALSE; - dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw); - } - ccw->next = cw->clients; - cw->clients = ccw; - if (!AddResource (ccw->id, CompositeClientWindowType, pWin)) - return BadAlloc; - if (ccw->update == CompositeRedirectManual) - { - /* If the window was CompositeRedirectAutomatic, then - * unmap the window so that the parent clip list will - * be correctly recomputed. - */ - if (pWin->mapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - if (cw->damageRegistered) - { - DamageUnregister (&pWin->drawable, cw->damage); - cw->damageRegistered = FALSE; - } - cw->update = CompositeRedirectManual; - } - - if (!compCheckRedirect (pWin)) - { - FreeResource (ccw->id, RT_NONE); - return BadAlloc; - } - if (wasMapped && !pWin->mapped) - { - Bool overrideRedirect = pWin->overrideRedirect; - pWin->overrideRedirect = TRUE; - DisableMapUnmapEvents (pWin); - MapWindow (pWin, pClient); - EnableMapUnmapEvents (pWin); - pWin->overrideRedirect = overrideRedirect; - } - - return Success; -} - -/* - * Free one of the per-client per-window resources, clearing - * redirect and the per-window pointer as appropriate - */ -void -compFreeClientWindow (WindowPtr pWin, XID id) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw, *prev; - Bool wasMapped = pWin->mapped; - - if (!cw) - return; - for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) - { - if (ccw->id == id) - { - *prev = ccw->next; - if (ccw->update == CompositeRedirectManual) - cw->update = CompositeRedirectAutomatic; - xfree (ccw); - break; - } - } - if (!cw->clients) - { - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - - if (pWin->redirectDraw != RedirectDrawNone) - compFreePixmap (pWin); - - if (cw->damage) - DamageDestroy (cw->damage); - - REGION_UNINIT (pScreen, &cw->borderClip); - - dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); - xfree (cw); - } - else if (cw->update == CompositeRedirectAutomatic && - !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) - { - DamageRegister (&pWin->drawable, cw->damage); - cw->damageRegistered = TRUE; - pWin->redirectDraw = RedirectDrawAutomatic; - DamageRegionAppend(&pWin->drawable, &pWin->borderSize); - } - if (wasMapped && !pWin->mapped) - { - Bool overrideRedirect = pWin->overrideRedirect; - pWin->overrideRedirect = TRUE; - DisableMapUnmapEvents (pWin); - MapWindow (pWin, clients[CLIENT_ID(id)]); - EnableMapUnmapEvents (pWin); - pWin->overrideRedirect = overrideRedirect; - } -} - -/* - * This is easy, just free the appropriate resource. - */ - -int -compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw; - - if (!cw) - return BadValue; - - for (ccw = cw->clients; ccw; ccw = ccw->next) - if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) - { - FreeResource (ccw->id, RT_NONE); - return Success; - } - return BadValue; -} - -/* - * Redirect all subwindows for one client - */ - -int -compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw; - WindowPtr pChild; - - /* - * Only one Manual update is allowed - */ - if (csw && update == CompositeRedirectManual) - for (ccw = csw->clients; ccw; ccw = ccw->next) - if (ccw->update == CompositeRedirectManual) - return BadAccess; - /* - * Allocate per-client per-window structure - * The client *could* allocate multiple, but while supported, - * it is not expected to be common - */ - ccw = xalloc (sizeof (CompClientWindowRec)); - if (!ccw) - return BadAlloc; - ccw->id = FakeClientID (pClient->index); - ccw->update = update; - /* - * Now make sure there's a per-window structure to hang this from - */ - if (!csw) - { - csw = xalloc (sizeof (CompSubwindowsRec)); - if (!csw) - { - xfree (ccw); - return BadAlloc; - } - csw->update = CompositeRedirectAutomatic; - csw->clients = 0; - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw); - } - /* - * Redirect all existing windows - */ - for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) - { - int ret = compRedirectWindow (pClient, pChild, update); - if (ret != Success) - { - for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib) - (void) compUnredirectWindow (pClient, pChild, update); - if (!csw->clients) - { - xfree (csw); - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0); - } - xfree (ccw); - return ret; - } - } - /* - * Hook into subwindows list - */ - ccw->next = csw->clients; - csw->clients = ccw; - if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin)) - return BadAlloc; - if (ccw->update == CompositeRedirectManual) - { - csw->update = CompositeRedirectManual; - /* - * tell damage extension that damage events for this client are - * critical output - */ - DamageExtSetCritical (pClient, TRUE); - } - return Success; -} - -/* - * Free one of the per-client per-subwindows resources, - * which frees one redirect per subwindow - */ -void -compFreeClientSubwindows (WindowPtr pWin, XID id) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw, *prev; - WindowPtr pChild; - - if (!csw) - return; - for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next) - { - if (ccw->id == id) - { - ClientPtr pClient = clients[CLIENT_ID(id)]; - - *prev = ccw->next; - if (ccw->update == CompositeRedirectManual) - { - /* - * tell damage extension that damage events for this client are - * critical output - */ - DamageExtSetCritical (pClient, FALSE); - csw->update = CompositeRedirectAutomatic; - if (pWin->mapped) - (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE); - } - - /* - * Unredirect all existing subwindows - */ - for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) - (void) compUnredirectWindow (pClient, pChild, ccw->update); - - xfree (ccw); - break; - } - } - - /* - * Check if all of the per-client records are gone - */ - if (!csw->clients) - { - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); - xfree (csw); - } -} - -/* - * This is easy, just free the appropriate resource. - */ - -int -compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw; - - if (!csw) - return BadValue; - for (ccw = csw->clients; ccw; ccw = ccw->next) - if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) - { - FreeResource (ccw->id, RT_NONE); - return Success; - } - return BadValue; -} - -/* - * Add redirection information for one subwindow (during reparent) - */ - -int -compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pParent); - CompClientWindowPtr ccw; - - if (!csw) - return Success; - for (ccw = csw->clients; ccw; ccw = ccw->next) - { - int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)], - pWin, ccw->update); - if (ret != Success) - return ret; - } - return Success; -} - -/* - * Remove redirection information for one subwindow (during reparent) - */ - -int -compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pParent); - CompClientWindowPtr ccw; - - if (!csw) - return Success; - for (ccw = csw->clients; ccw; ccw = ccw->next) - { - int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)], - pWin, ccw->update); - if (ret != Success) - return ret; - } - return Success; -} - -static PixmapPtr -compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - WindowPtr pParent = pWin->parent; - PixmapPtr pPixmap; - - pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, - CREATE_PIXMAP_USAGE_BACKING_PIXMAP); - - if (!pPixmap) - return 0; - - pPixmap->screen_x = x; - pPixmap->screen_y = y; - - if (pParent->drawable.depth == pWin->drawable.depth) - { - GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); - - /* - * Copy bits from the parent into the new pixmap so that it will - * have "reasonable" contents in case for background None areas. - */ - if (pGC) - { - XID val = IncludeInferiors; - - ValidateGC(&pPixmap->drawable, pGC); - dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL); - (*pGC->ops->CopyArea) (&pParent->drawable, - &pPixmap->drawable, - pGC, - x - pParent->drawable.x, - y - pParent->drawable.y, - w, h, 0, 0); - FreeScratchGC (pGC); - } - } - else - { - PictFormatPtr pSrcFormat = compWindowFormat (pParent); - PictFormatPtr pDstFormat = compWindowFormat (pWin); - XID inferiors = IncludeInferiors; - int error; - - PicturePtr pSrcPicture = CreatePicture (None, - &pParent->drawable, - pSrcFormat, - CPSubwindowMode, - &inferiors, - serverClient, &error); - - PicturePtr pDstPicture = CreatePicture (None, - &pPixmap->drawable, - pDstFormat, - 0, 0, - serverClient, &error); - - if (pSrcPicture && pDstPicture) - { - CompositePicture (PictOpSrc, - pSrcPicture, - NULL, - pDstPicture, - x - pParent->drawable.x, - y - pParent->drawable.y, - 0, 0, 0, 0, w, h); - } - if (pSrcPicture) - FreePicture (pSrcPicture, 0); - if (pDstPicture) - FreePicture (pDstPicture, 0); - } - return pPixmap; -} - -Bool -compAllocPixmap (WindowPtr pWin) -{ - int bw = (int) pWin->borderWidth; - int x = pWin->drawable.x - bw; - int y = pWin->drawable.y - bw; - int w = pWin->drawable.width + (bw << 1); - int h = pWin->drawable.height + (bw << 1); - PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h); - CompWindowPtr cw = GetCompWindow (pWin); - - if (!pPixmap) - return FALSE; - if (cw->update == CompositeRedirectAutomatic) - pWin->redirectDraw = RedirectDrawAutomatic; - else - pWin->redirectDraw = RedirectDrawManual; - - compSetPixmap (pWin, pPixmap); - cw->oldx = COMP_ORIGIN_INVALID; - cw->oldy = COMP_ORIGIN_INVALID; - cw->damageRegistered = FALSE; - if (cw->update == CompositeRedirectAutomatic) - { - DamageRegister (&pWin->drawable, cw->damage); - cw->damageRegistered = TRUE; - } - return TRUE; -} - -void -compFreePixmap (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - PixmapPtr pRedirectPixmap, pParentPixmap; - CompWindowPtr cw = GetCompWindow (pWin); - - if (cw->damageRegistered) - { - DamageUnregister (&pWin->drawable, cw->damage); - cw->damageRegistered = FALSE; - DamageEmpty (cw->damage); - } - /* - * Move the parent-constrained border clip region back into - * the window so that ValidateTree will handle the unmap - * case correctly. Unmap adds the window borderClip to the - * parent exposed area; regions beyond the parent cause crashes - */ - REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip); - pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin); - pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); - pWin->redirectDraw = RedirectDrawNone; - compSetPixmap (pWin, pParentPixmap); - (*pScreen->DestroyPixmap) (pRedirectPixmap); -} - -/* - * Make sure the pixmap is the right size and offset. Allocate a new - * pixmap to change size, adjust origin to change offset, leaving the - * old pixmap in cw->pOldPixmap so bits can be recovered - */ -Bool -compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y, - unsigned int w, unsigned int h, int bw) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin); - PixmapPtr pNew; - CompWindowPtr cw = GetCompWindow (pWin); - int pix_x, pix_y; - int pix_w, pix_h; - - assert (cw && pWin->redirectDraw != RedirectDrawNone); - cw->oldx = pOld->screen_x; - cw->oldy = pOld->screen_y; - pix_x = draw_x - bw; - pix_y = draw_y - bw; - pix_w = w + (bw << 1); - pix_h = h + (bw << 1); - if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) - { - pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h); - if (!pNew) - return FALSE; - cw->pOldPixmap = pOld; - compSetPixmap (pWin, pNew); - } - else - { - pNew = pOld; - cw->pOldPixmap = 0; - } - pNew->screen_x = pix_x; - pNew->screen_y = pix_y; - return TRUE; -} +/*
+ * Copyright © 2006 Sun Microsystems, Inc. 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"
+
+static void
+compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ cs->damaged = TRUE;
+ cw->damaged = TRUE;
+}
+
+static void
+compDestroyDamage (DamagePtr pDamage, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ cw->damage = 0;
+}
+
+/*
+ * Redirect one window for one client
+ */
+int
+compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+ Bool wasMapped = pWin->mapped;
+ CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+
+ if (pWin == cs->pOverlayWin) {
+ return Success;
+ }
+
+ if (!pWin->parent)
+ return BadMatch;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (cw && update == CompositeRedirectManual)
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = malloc(sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!cw)
+ {
+ cw = malloc(sizeof (CompWindowRec));
+ if (!cw)
+ {
+ free(ccw);
+ return BadAlloc;
+ }
+ cw->damage = DamageCreate (compReportDamage,
+ compDestroyDamage,
+ DamageReportNonEmpty,
+ FALSE,
+ pWin->drawable.pScreen,
+ pWin);
+ if (!cw->damage)
+ {
+ free(ccw);
+ free(cw);
+ return BadAlloc;
+ }
+ if (wasMapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+
+ REGION_NULL (pScreen, &cw->borderClip);
+ cw->borderClipX = 0;
+ cw->borderClipY = 0;
+ cw->update = CompositeRedirectAutomatic;
+ cw->clients = 0;
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ cw->damaged = FALSE;
+ dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
+ }
+ ccw->next = cw->clients;
+ cw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ /* If the window was CompositeRedirectAutomatic, then
+ * unmap the window so that the parent clip list will
+ * be correctly recomputed.
+ */
+ if (pWin->mapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+ if (cw->damageRegistered)
+ {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ }
+ cw->update = CompositeRedirectManual;
+ }
+
+ if (!compCheckRedirect (pWin))
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return BadAlloc;
+ }
+ if (wasMapped && !pWin->mapped)
+ {
+ Bool overrideRedirect = pWin->overrideRedirect;
+ pWin->overrideRedirect = TRUE;
+ DisableMapUnmapEvents (pWin);
+ MapWindow (pWin, pClient);
+ EnableMapUnmapEvents (pWin);
+ pWin->overrideRedirect = overrideRedirect;
+ }
+
+ return Success;
+}
+
+/*
+ * Free one of the per-client per-window resources, clearing
+ * redirect and the per-window pointer as appropriate
+ */
+void
+compFreeClientWindow (WindowPtr pWin, XID id)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw, *prev;
+ Bool wasMapped = pWin->mapped;
+
+ if (!cw)
+ return;
+ for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ cw->update = CompositeRedirectAutomatic;
+ free(ccw);
+ break;
+ }
+ }
+ if (!cw->clients)
+ {
+ if (wasMapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+
+ if (pWin->redirectDraw != RedirectDrawNone)
+ compFreePixmap (pWin);
+
+ if (cw->damage)
+ DamageDestroy (cw->damage);
+
+ REGION_UNINIT (pScreen, &cw->borderClip);
+
+ dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL);
+ free(cw);
+ }
+ else if (cw->update == CompositeRedirectAutomatic &&
+ !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
+ {
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ DamageRegionAppend(&pWin->drawable, &pWin->borderSize);
+ }
+ if (wasMapped && !pWin->mapped)
+ {
+ Bool overrideRedirect = pWin->overrideRedirect;
+ pWin->overrideRedirect = TRUE;
+ DisableMapUnmapEvents (pWin);
+ MapWindow (pWin, clients[CLIENT_ID(id)]);
+ EnableMapUnmapEvents (pWin);
+ pWin->overrideRedirect = overrideRedirect;
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!cw)
+ return BadValue;
+
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Redirect all subwindows for one client
+ */
+
+int
+compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+ WindowPtr pChild;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (csw && update == CompositeRedirectManual)
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = malloc(sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!csw)
+ {
+ csw = malloc(sizeof (CompSubwindowsRec));
+ if (!csw)
+ {
+ free(ccw);
+ return BadAlloc;
+ }
+ csw->update = CompositeRedirectAutomatic;
+ csw->clients = 0;
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw);
+ }
+ /*
+ * Redirect all existing windows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ int ret = compRedirectWindow (pClient, pChild, update);
+ if (ret != Success)
+ {
+ for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib)
+ (void) compUnredirectWindow (pClient, pChild, update);
+ if (!csw->clients)
+ {
+ free(csw);
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0);
+ }
+ free(ccw);
+ return ret;
+ }
+ }
+ /*
+ * Hook into subwindows list
+ */
+ ccw->next = csw->clients;
+ csw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ csw->update = CompositeRedirectManual;
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, TRUE);
+ }
+ return Success;
+}
+
+/*
+ * Free one of the per-client per-subwindows resources,
+ * which frees one redirect per subwindow
+ */
+void
+compFreeClientSubwindows (WindowPtr pWin, XID id)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw, *prev;
+ WindowPtr pChild;
+
+ if (!csw)
+ return;
+ for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ ClientPtr pClient = clients[CLIENT_ID(id)];
+
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, FALSE);
+ csw->update = CompositeRedirectAutomatic;
+ if (pWin->mapped)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE);
+ }
+
+ /*
+ * Unredirect all existing subwindows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ (void) compUnredirectWindow (pClient, pChild, ccw->update);
+
+ free(ccw);
+ break;
+ }
+ }
+
+ /*
+ * Check if all of the per-client records are gone
+ */
+ if (!csw->clients)
+ {
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL);
+ free(csw);
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return BadValue;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Add redirection information for one subwindow (during reparent)
+ */
+
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+/*
+ * Remove redirection information for one subwindow (during reparent)
+ */
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+static PixmapPtr
+compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+ PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+
+ if (!pPixmap)
+ return 0;
+
+ pPixmap->screen_x = x;
+ pPixmap->screen_y = y;
+
+ if (pParent->drawable.depth == pWin->drawable.depth)
+ {
+ GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ /*
+ * Copy bits from the parent into the new pixmap so that it will
+ * have "reasonable" contents in case for background None areas.
+ */
+ if (pGC)
+ {
+ ChangeGCVal val;
+ val.val = IncludeInferiors;
+
+ ValidateGC(&pPixmap->drawable, pGC);
+ ChangeGC (serverClient, pGC, GCSubwindowMode, &val);
+ (*pGC->ops->CopyArea) (&pParent->drawable,
+ &pPixmap->drawable,
+ pGC,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ w, h, 0, 0);
+ FreeScratchGC (pGC);
+ }
+ }
+ else
+ {
+ PictFormatPtr pSrcFormat = compWindowFormat (pParent);
+ PictFormatPtr pDstFormat = compWindowFormat (pWin);
+ XID inferiors = IncludeInferiors;
+ int error;
+
+ PicturePtr pSrcPicture = CreatePicture (None,
+ &pParent->drawable,
+ pSrcFormat,
+ CPSubwindowMode,
+ &inferiors,
+ serverClient, &error);
+
+ PicturePtr pDstPicture = CreatePicture (None,
+ &pPixmap->drawable,
+ pDstFormat,
+ 0, 0,
+ serverClient, &error);
+
+ if (pSrcPicture && pDstPicture)
+ {
+ CompositePicture (PictOpSrc,
+ pSrcPicture,
+ NULL,
+ pDstPicture,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ 0, 0, 0, 0, w, h);
+ }
+ if (pSrcPicture)
+ FreePicture (pSrcPicture, 0);
+ if (pDstPicture)
+ FreePicture (pDstPicture, 0);
+ }
+ return pPixmap;
+}
+
+Bool
+compAllocPixmap (WindowPtr pWin)
+{
+ int bw = (int) pWin->borderWidth;
+ int x = pWin->drawable.x - bw;
+ int y = pWin->drawable.y - bw;
+ int w = pWin->drawable.width + (bw << 1);
+ int h = pWin->drawable.height + (bw << 1);
+ PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (!pPixmap)
+ return FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ else
+ pWin->redirectDraw = RedirectDrawManual;
+
+ compSetPixmap (pWin, pPixmap);
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ {
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ }
+ return TRUE;
+}
+
+void
+compFreePixmap (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pRedirectPixmap, pParentPixmap;
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (cw->damageRegistered)
+ {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ DamageEmpty (cw->damage);
+ }
+ /*
+ * Move the parent-constrained border clip region back into
+ * the window so that ValidateTree will handle the unmap
+ * case correctly. Unmap adds the window borderClip to the
+ * parent exposed area; regions beyond the parent cause crashes
+ */
+ REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip);
+ pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
+ pWin->redirectDraw = RedirectDrawNone;
+ compSetPixmap (pWin, pParentPixmap);
+ (*pScreen->DestroyPixmap) (pRedirectPixmap);
+}
+
+/*
+ * Make sure the pixmap is the right size and offset. Allocate a new
+ * pixmap to change size, adjust origin to change offset, leaving the
+ * old pixmap in cw->pOldPixmap so bits can be recovered
+ */
+Bool
+compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
+ unsigned int w, unsigned int h, int bw)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
+ PixmapPtr pNew;
+ CompWindowPtr cw = GetCompWindow (pWin);
+ int pix_x, pix_y;
+ int pix_w, pix_h;
+
+ assert (cw && pWin->redirectDraw != RedirectDrawNone);
+ cw->oldx = pOld->screen_x;
+ cw->oldy = pOld->screen_y;
+ pix_x = draw_x - bw;
+ pix_y = draw_y - bw;
+ pix_w = w + (bw << 1);
+ pix_h = h + (bw << 1);
+ if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
+ {
+ pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
+ if (!pNew)
+ return FALSE;
+ cw->pOldPixmap = pOld;
+ compSetPixmap (pWin, pNew);
+ }
+ else
+ {
+ pNew = pOld;
+ cw->pOldPixmap = 0;
+ }
+ pNew->screen_x = pix_x;
+ pNew->screen_y = pix_y;
+ return TRUE;
+}
diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c index 17c4bae1e..664b0fcc3 100644 --- a/xorg-server/composite/compext.c +++ b/xorg-server/composite/compext.c @@ -1,587 +1,587 @@ -/* - * Copyright © 2006 Sun Microsystems, Inc. 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 "xace.h" -#include "protocol-versions.h" - -static CARD8 CompositeReqCode; -static int CompositeClientPrivateKeyIndex; -static DevPrivateKey CompositeClientPrivateKey = &CompositeClientPrivateKeyIndex; -RESTYPE CompositeClientWindowType; -RESTYPE CompositeClientSubwindowsType; -RESTYPE CompositeClientOverlayType; - -typedef struct _CompositeClient { - int major_version; - int minor_version; -} CompositeClientRec, *CompositeClientPtr; - -#define GetCompositeClient(pClient) ((CompositeClientPtr) \ - dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) - -static void -CompositeClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - CompositeClientPtr pCompositeClient = GetCompositeClient (pClient); - - pCompositeClient->major_version = 0; - pCompositeClient->minor_version = 0; -} - -static int -FreeCompositeClientWindow (pointer value, XID ccwid) -{ - WindowPtr pWin = value; - - compFreeClientWindow (pWin, ccwid); - return Success; -} - -static int -FreeCompositeClientSubwindows (pointer value, XID ccwid) -{ - WindowPtr pWin = value; - - compFreeClientSubwindows (pWin, ccwid); - return Success; -} - -static int -FreeCompositeClientOverlay (pointer value, XID ccwid) -{ - CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; - - compFreeOverlayClient (pOc); - return Success; -} - -static int -ProcCompositeQueryVersion (ClientPtr client) -{ - CompositeClientPtr pCompositeClient = GetCompositeClient (client); - xCompositeQueryVersionReply rep; - register int n; - REQUEST(xCompositeQueryVersionReq); - - REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { - rep.majorVersion = stuff->majorVersion; - rep.minorVersion = stuff->minorVersion; - } else { - rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; - rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; - } - pCompositeClient->major_version = rep.majorVersion; - pCompositeClient->minor_version = rep.minorVersion; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep); - return(client->noClientException); -} - -#define VERIFY_WINDOW(pWindow, wid, client, mode) \ - do { \ - int err; \ - err = dixLookupResourceByType((pointer *) &pWindow, wid, \ - RT_WINDOW, client, mode); \ - if (err == BadValue) { \ - client->errorValue = wid; \ - return BadWindow; \ - } else if (err != Success) { \ - client->errorValue = wid; \ - return err; \ - } \ - } while (0) - -static int -ProcCompositeRedirectWindow (ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xCompositeRedirectWindowReq); - - REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); - VERIFY_WINDOW(pWin, stuff->window, client, - DixSetAttrAccess|DixManageAccess|DixBlendAccess); - - return compRedirectWindow (client, pWin, stuff->update); -} - -static int -ProcCompositeRedirectSubwindows (ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xCompositeRedirectSubwindowsReq); - - REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); - VERIFY_WINDOW(pWin, stuff->window, client, - DixSetAttrAccess|DixManageAccess|DixBlendAccess); - - return compRedirectSubwindows (client, pWin, stuff->update); -} - -static int -ProcCompositeUnredirectWindow (ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xCompositeUnredirectWindowReq); - - REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); - VERIFY_WINDOW(pWin, stuff->window, client, - DixSetAttrAccess|DixManageAccess|DixBlendAccess); - - return compUnredirectWindow (client, pWin, stuff->update); -} - -static int -ProcCompositeUnredirectSubwindows (ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xCompositeUnredirectSubwindowsReq); - - REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); - VERIFY_WINDOW(pWin, stuff->window, client, - DixSetAttrAccess|DixManageAccess|DixBlendAccess); - - return compUnredirectSubwindows (client, pWin, stuff->update); -} - -static int -ProcCompositeCreateRegionFromBorderClip (ClientPtr client) -{ - WindowPtr pWin; - CompWindowPtr cw; - RegionPtr pBorderClip, pRegion; - REQUEST(xCompositeCreateRegionFromBorderClipReq); - - REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); - VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); - LEGAL_NEW_RESOURCE (stuff->region, client); - - cw = GetCompWindow (pWin); - if (cw) - pBorderClip = &cw->borderClip; - else - pBorderClip = &pWin->borderClip; - pRegion = XFixesRegionCopy (pBorderClip); - if (!pRegion) - return BadAlloc; - REGION_TRANSLATE (pScreen, pRegion, -pWin->drawable.x, -pWin->drawable.y); - - if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) - return BadAlloc; - - return(client->noClientException); -} - -static int -ProcCompositeNameWindowPixmap (ClientPtr client) -{ - WindowPtr pWin; - CompWindowPtr cw; - PixmapPtr pPixmap; - int rc; - REQUEST(xCompositeNameWindowPixmapReq); - - REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); - VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); - - if (!pWin->viewable) - return BadMatch; - - LEGAL_NEW_RESOURCE (stuff->pixmap, client); - - cw = GetCompWindow (pWin); - if (!cw) - return BadMatch; - - pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); - if (!pPixmap) - return BadMatch; - - /* security creation/labeling check */ - rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, - pPixmap, RT_WINDOW, pWin, DixCreateAccess); - if (rc != Success) - return rc; - - ++pPixmap->refcnt; - - if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap)) - return BadAlloc; - - return(client->noClientException); -} - - -static int -ProcCompositeGetOverlayWindow (ClientPtr client) -{ - REQUEST(xCompositeGetOverlayWindowReq); - xCompositeGetOverlayWindowReply rep; - WindowPtr pWin; - ScreenPtr pScreen; - CompScreenPtr cs; - CompOverlayClientPtr pOc; - int rc; - - REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); - VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); - pScreen = pWin->drawable.pScreen; - - /* - * Create an OverlayClient structure to mark this client's - * interest in the overlay window - */ - pOc = compCreateOverlayClient(pScreen, client); - if (pOc == NULL) - return BadAlloc; - - /* - * Make sure the overlay window exists - */ - cs = GetCompScreen(pScreen); - if (cs->pOverlayWin == NULL) - if (!compCreateOverlayWindow(pScreen)) - { - FreeResource (pOc->resource, RT_NONE); - return BadAlloc; - } - - rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, - RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); - if (rc != Success) - { - FreeResource (pOc->resource, RT_NONE); - return rc; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.overlayWin = cs->pOverlayWin->drawable.id; - - if (client->swapped) - { - int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.overlayWin, n); - } - (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); - - return client->noClientException; -} - -static int -ProcCompositeReleaseOverlayWindow (ClientPtr client) -{ - REQUEST(xCompositeReleaseOverlayWindowReq); - WindowPtr pWin; - ScreenPtr pScreen; - CompOverlayClientPtr pOc; - - REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); - VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); - pScreen = pWin->drawable.pScreen; - - /* - * Has client queried a reference to the overlay window - * on this screen? If not, generate an error. - */ - pOc = compFindOverlayClient (pWin->drawable.pScreen, client); - if (pOc == NULL) - return BadMatch; - - /* The delete function will free the client structure */ - FreeResource (pOc->resource, RT_NONE); - - return client->noClientException; -} - -static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { - ProcCompositeQueryVersion, - ProcCompositeRedirectWindow, - ProcCompositeRedirectSubwindows, - ProcCompositeUnredirectWindow, - ProcCompositeUnredirectSubwindows, - ProcCompositeCreateRegionFromBorderClip, - ProcCompositeNameWindowPixmap, - ProcCompositeGetOverlayWindow, - ProcCompositeReleaseOverlayWindow, -}; - -static int -ProcCompositeDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < CompositeNumberRequests) - return (*ProcCompositeVector[stuff->data]) (client); - else - return BadRequest; -} - -static int -SProcCompositeQueryVersion (ClientPtr client) -{ - int n; - REQUEST(xCompositeQueryVersionReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeRedirectWindow (ClientPtr client) -{ - int n; - REQUEST(xCompositeRedirectWindowReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); - swapl (&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeRedirectSubwindows (ClientPtr client) -{ - int n; - REQUEST(xCompositeRedirectSubwindowsReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); - swapl (&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeUnredirectWindow (ClientPtr client) -{ - int n; - REQUEST(xCompositeUnredirectWindowReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); - swapl (&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeUnredirectSubwindows (ClientPtr client) -{ - int n; - REQUEST(xCompositeUnredirectSubwindowsReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); - swapl (&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeCreateRegionFromBorderClip (ClientPtr client) -{ - int n; - REQUEST(xCompositeCreateRegionFromBorderClipReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); - swapl (&stuff->region, n); - swapl (&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeNameWindowPixmap (ClientPtr client) -{ - int n; - REQUEST(xCompositeNameWindowPixmapReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); - swapl (&stuff->window, n); - swapl (&stuff->pixmap, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeGetOverlayWindow (ClientPtr client) -{ - int n; - REQUEST(xCompositeGetOverlayWindowReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); - swapl(&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int -SProcCompositeReleaseOverlayWindow (ClientPtr client) -{ - int n; - REQUEST(xCompositeReleaseOverlayWindowReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); - swapl(&stuff->window, n); - return (*ProcCompositeVector[stuff->compositeReqType]) (client); -} - -static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { - SProcCompositeQueryVersion, - SProcCompositeRedirectWindow, - SProcCompositeRedirectSubwindows, - SProcCompositeUnredirectWindow, - SProcCompositeUnredirectSubwindows, - SProcCompositeCreateRegionFromBorderClip, - SProcCompositeNameWindowPixmap, - SProcCompositeGetOverlayWindow, - SProcCompositeReleaseOverlayWindow, -}; - -static int -SProcCompositeDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < CompositeNumberRequests) - return (*SProcCompositeVector[stuff->data]) (client); - else - return BadRequest; -} - -void -CompositeExtensionInit (void) -{ - ExtensionEntry *extEntry; - int s; - - /* Assume initialization is going to fail */ - noCompositeExtension = TRUE; - - for (s = 0; s < screenInfo.numScreens; s++) { - ScreenPtr pScreen = screenInfo.screens[s]; - VisualPtr vis; - - /* Composite on 8bpp pseudocolor root windows appears to fail, so - * just disable it on anything pseudocolor for safety. - */ - for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++) - ; - if ((vis->class | DynamicClass) == PseudoColor) - return; - - /* Ensure that Render is initialized, which is required for automatic - * compositing. - */ - if (GetPictureScreenIfSet(pScreen) == NULL) - return; - } -#ifdef PANORAMIX - /* Xinerama's rewriting of window drawing before Composite gets to it - * breaks Composite. - */ - if (!noPanoramiXExtension) - return; -#endif - - CompositeClientWindowType = CreateNewResourceType - (FreeCompositeClientWindow, "CompositeClientWindow"); - if (!CompositeClientWindowType) - return; - - CompositeClientSubwindowsType = CreateNewResourceType - (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); - if (!CompositeClientSubwindowsType) - return; - - CompositeClientOverlayType = CreateNewResourceType - (FreeCompositeClientOverlay, "CompositeClientOverlay"); - if (!CompositeClientOverlayType) - return; - - if (!dixRequestPrivate(CompositeClientPrivateKey, - sizeof(CompositeClientRec))) - return; - - if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0)) - return; - - for (s = 0; s < screenInfo.numScreens; s++) - if (!compScreenInit (screenInfo.screens[s])) - return; - - extEntry = AddExtension (COMPOSITE_NAME, 0, 0, - ProcCompositeDispatch, SProcCompositeDispatch, - NULL, StandardMinorOpcode); - if (!extEntry) - return; - CompositeReqCode = (CARD8) extEntry->base; - - miRegisterRedirectBorderClipProc (compSetRedirectBorderClip, - compGetRedirectBorderClip); - - /* Initialization succeeded */ - noCompositeExtension = FALSE; -} +/*
+ * Copyright © 2006 Sun Microsystems, Inc. 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 "xace.h"
+#include "protocol-versions.h"
+
+static CARD8 CompositeReqCode;
+static int CompositeClientPrivateKeyIndex;
+static DevPrivateKey CompositeClientPrivateKey = &CompositeClientPrivateKeyIndex;
+RESTYPE CompositeClientWindowType;
+RESTYPE CompositeClientSubwindowsType;
+RESTYPE CompositeClientOverlayType;
+
+typedef struct _CompositeClient {
+ int major_version;
+ int minor_version;
+} CompositeClientRec, *CompositeClientPtr;
+
+#define GetCompositeClient(pClient) ((CompositeClientPtr) \
+ dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
+
+static void
+CompositeClientCallback (CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
+ ClientPtr pClient = clientinfo->client;
+ CompositeClientPtr pCompositeClient = GetCompositeClient (pClient);
+
+ pCompositeClient->major_version = 0;
+ pCompositeClient->minor_version = 0;
+}
+
+static int
+FreeCompositeClientWindow (pointer value, XID ccwid)
+{
+ WindowPtr pWin = value;
+
+ compFreeClientWindow (pWin, ccwid);
+ return Success;
+}
+
+static int
+FreeCompositeClientSubwindows (pointer value, XID ccwid)
+{
+ WindowPtr pWin = value;
+
+ compFreeClientSubwindows (pWin, ccwid);
+ return Success;
+}
+
+static int
+FreeCompositeClientOverlay (pointer value, XID ccwid)
+{
+ CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
+
+ compFreeOverlayClient (pOc);
+ return Success;
+}
+
+static int
+ProcCompositeQueryVersion (ClientPtr client)
+{
+ CompositeClientPtr pCompositeClient = GetCompositeClient (client);
+ xCompositeQueryVersionReply rep;
+ register int n;
+ REQUEST(xCompositeQueryVersionReq);
+
+ REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
+ rep.majorVersion = stuff->majorVersion;
+ rep.minorVersion = stuff->minorVersion;
+ } else {
+ rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
+ }
+ pCompositeClient->major_version = rep.majorVersion;
+ pCompositeClient->minor_version = rep.minorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+#define VERIFY_WINDOW(pWindow, wid, client, mode) \
+ do { \
+ int err; \
+ err = dixLookupResourceByType((pointer *) &pWindow, wid, \
+ RT_WINDOW, client, mode); \
+ if (err == BadValue) { \
+ client->errorValue = wid; \
+ return BadWindow; \
+ } else if (err != Success) { \
+ client->errorValue = wid; \
+ return err; \
+ } \
+ } while (0)
+
+static int
+ProcCompositeRedirectWindow (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeRedirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess|DixManageAccess|DixBlendAccess);
+
+ return compRedirectWindow (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeRedirectSubwindows (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess|DixManageAccess|DixBlendAccess);
+
+ return compRedirectSubwindows (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeUnredirectWindow (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess|DixManageAccess|DixBlendAccess);
+
+ return compUnredirectWindow (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeUnredirectSubwindows (ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+ VERIFY_WINDOW(pWin, stuff->window, client,
+ DixSetAttrAccess|DixManageAccess|DixBlendAccess);
+
+ return compUnredirectSubwindows (client, pWin, stuff->update);
+}
+
+static int
+ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ RegionPtr pBorderClip, pRegion;
+ REQUEST(xCompositeCreateRegionFromBorderClipReq);
+
+ REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ LEGAL_NEW_RESOURCE (stuff->region, client);
+
+ cw = GetCompWindow (pWin);
+ if (cw)
+ pBorderClip = &cw->borderClip;
+ else
+ pBorderClip = &pWin->borderClip;
+ pRegion = XFixesRegionCopy (pBorderClip);
+ if (!pRegion)
+ return BadAlloc;
+ REGION_TRANSLATE (pScreen, pRegion, -pWin->drawable.x, -pWin->drawable.y);
+
+ if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
+ return BadAlloc;
+
+ return Success;
+}
+
+static int
+ProcCompositeNameWindowPixmap (ClientPtr client)
+{
+ WindowPtr pWin;
+ CompWindowPtr cw;
+ PixmapPtr pPixmap;
+ int rc;
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+
+ if (!pWin->viewable)
+ return BadMatch;
+
+ LEGAL_NEW_RESOURCE (stuff->pixmap, client);
+
+ cw = GetCompWindow (pWin);
+ if (!cw)
+ return BadMatch;
+
+ pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ if (!pPixmap)
+ return BadMatch;
+
+ /* security creation/labeling check */
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
+ pPixmap, RT_WINDOW, pWin, DixCreateAccess);
+ if (rc != Success)
+ return rc;
+
+ ++pPixmap->refcnt;
+
+ if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
+ return BadAlloc;
+
+ return Success;
+}
+
+
+static int
+ProcCompositeGetOverlayWindow (ClientPtr client)
+{
+ REQUEST(xCompositeGetOverlayWindowReq);
+ xCompositeGetOverlayWindowReply rep;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompScreenPtr cs;
+ CompOverlayClientPtr pOc;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Create an OverlayClient structure to mark this client's
+ * interest in the overlay window
+ */
+ pOc = compCreateOverlayClient(pScreen, client);
+ if (pOc == NULL)
+ return BadAlloc;
+
+ /*
+ * Make sure the overlay window exists
+ */
+ cs = GetCompScreen(pScreen);
+ if (cs->pOverlayWin == NULL)
+ if (!compCreateOverlayWindow(pScreen))
+ {
+ FreeResource (pOc->resource, RT_NONE);
+ return BadAlloc;
+ }
+
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
+ RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
+ if (rc != Success)
+ {
+ FreeResource (pOc->resource, RT_NONE);
+ return rc;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.overlayWin = cs->pOverlayWin->drawable.id;
+
+ if (client->swapped)
+ {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.overlayWin, n);
+ }
+ (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
+
+ return Success;
+}
+
+static int
+ProcCompositeReleaseOverlayWindow (ClientPtr client)
+{
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ CompOverlayClientPtr pOc;
+
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+ VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * Has client queried a reference to the overlay window
+ * on this screen? If not, generate an error.
+ */
+ pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
+ if (pOc == NULL)
+ return BadMatch;
+
+ /* The delete function will free the client structure */
+ FreeResource (pOc->resource, RT_NONE);
+
+ return Success;
+}
+
+static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
+ ProcCompositeQueryVersion,
+ ProcCompositeRedirectWindow,
+ ProcCompositeRedirectSubwindows,
+ ProcCompositeUnredirectWindow,
+ ProcCompositeUnredirectSubwindows,
+ ProcCompositeCreateRegionFromBorderClip,
+ ProcCompositeNameWindowPixmap,
+ ProcCompositeGetOverlayWindow,
+ ProcCompositeReleaseOverlayWindow,
+};
+
+static int
+ProcCompositeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < CompositeNumberRequests)
+ return (*ProcCompositeVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+static int
+SProcCompositeQueryVersion (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
+ swapl(&stuff->majorVersion, n);
+ swapl(&stuff->minorVersion, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeRedirectWindow (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeRedirectWindowReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
+ swapl (&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeRedirectSubwindows (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeRedirectSubwindowsReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
+ swapl (&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeUnredirectWindow (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeUnredirectWindowReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
+ swapl (&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeUnredirectSubwindows (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeUnredirectSubwindowsReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
+ swapl (&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeCreateRegionFromBorderClipReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
+ swapl (&stuff->region, n);
+ swapl (&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeNameWindowPixmap (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeNameWindowPixmapReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
+ swapl (&stuff->window, n);
+ swapl (&stuff->pixmap, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeGetOverlayWindow (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeGetOverlayWindowReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
+ swapl(&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int
+SProcCompositeReleaseOverlayWindow (ClientPtr client)
+{
+ int n;
+ REQUEST(xCompositeReleaseOverlayWindowReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
+ swapl(&stuff->window, n);
+ return (*ProcCompositeVector[stuff->compositeReqType]) (client);
+}
+
+static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
+ SProcCompositeQueryVersion,
+ SProcCompositeRedirectWindow,
+ SProcCompositeRedirectSubwindows,
+ SProcCompositeUnredirectWindow,
+ SProcCompositeUnredirectSubwindows,
+ SProcCompositeCreateRegionFromBorderClip,
+ SProcCompositeNameWindowPixmap,
+ SProcCompositeGetOverlayWindow,
+ SProcCompositeReleaseOverlayWindow,
+};
+
+static int
+SProcCompositeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < CompositeNumberRequests)
+ return (*SProcCompositeVector[stuff->data]) (client);
+ else
+ return BadRequest;
+}
+
+void
+CompositeExtensionInit (void)
+{
+ ExtensionEntry *extEntry;
+ int s;
+
+ /* Assume initialization is going to fail */
+ noCompositeExtension = TRUE;
+
+ for (s = 0; s < screenInfo.numScreens; s++) {
+ ScreenPtr pScreen = screenInfo.screens[s];
+ VisualPtr vis;
+
+ /* Composite on 8bpp pseudocolor root windows appears to fail, so
+ * just disable it on anything pseudocolor for safety.
+ */
+ for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++)
+ ;
+ if ((vis->class | DynamicClass) == PseudoColor)
+ return;
+
+ /* Ensure that Render is initialized, which is required for automatic
+ * compositing.
+ */
+ if (GetPictureScreenIfSet(pScreen) == NULL)
+ return;
+ }
+#ifdef PANORAMIX
+ /* Xinerama's rewriting of window drawing before Composite gets to it
+ * breaks Composite.
+ */
+ if (!noPanoramiXExtension)
+ return;
+#endif
+
+ CompositeClientWindowType = CreateNewResourceType
+ (FreeCompositeClientWindow, "CompositeClientWindow");
+ if (!CompositeClientWindowType)
+ return;
+
+ CompositeClientSubwindowsType = CreateNewResourceType
+ (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
+ if (!CompositeClientSubwindowsType)
+ return;
+
+ CompositeClientOverlayType = CreateNewResourceType
+ (FreeCompositeClientOverlay, "CompositeClientOverlay");
+ if (!CompositeClientOverlayType)
+ return;
+
+ if (!dixRequestPrivate(CompositeClientPrivateKey,
+ sizeof(CompositeClientRec)))
+ return;
+
+ if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
+ return;
+
+ for (s = 0; s < screenInfo.numScreens; s++)
+ if (!compScreenInit (screenInfo.screens[s]))
+ return;
+
+ extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
+ ProcCompositeDispatch, SProcCompositeDispatch,
+ NULL, StandardMinorOpcode);
+ if (!extEntry)
+ return;
+ CompositeReqCode = (CARD8) extEntry->base;
+
+ miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
+ compGetRedirectBorderClip);
+
+ /* Initialization succeeded */
+ noCompositeExtension = FALSE;
+}
diff --git a/xorg-server/composite/compinit.c b/xorg-server/composite/compinit.c index e8b563de6..9a99ce633 100644 --- a/xorg-server/composite/compinit.c +++ b/xorg-server/composite/compinit.c @@ -1,394 +1,394 @@ -/* - * Copyright © 2006 Sun Microsystems, Inc. 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" - -static int CompScreenPrivateKeyIndex; -DevPrivateKey CompScreenPrivateKey = &CompScreenPrivateKeyIndex; -static int CompWindowPrivateKeyIndex; -DevPrivateKey CompWindowPrivateKey = &CompWindowPrivateKeyIndex; -static int CompSubwindowsPrivateKeyIndex; -DevPrivateKey CompSubwindowsPrivateKey = &CompSubwindowsPrivateKeyIndex; - - -static Bool -compCloseScreen (int index, ScreenPtr pScreen) -{ - CompScreenPtr cs = GetCompScreen (pScreen); - Bool ret; - - xfree (cs->alternateVisuals); - - pScreen->CloseScreen = cs->CloseScreen; - pScreen->BlockHandler = cs->BlockHandler; - pScreen->InstallColormap = cs->InstallColormap; - pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; - pScreen->ReparentWindow = cs->ReparentWindow; - 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; - - xfree (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 -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; -} - -/* - * 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 = xrealloc(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 (GetCompScreen (pScreen)) - return TRUE; - cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec)); - if (!cs) - return FALSE; - - cs->damaged = FALSE; - cs->overlayWid = FakeClientID(0); - cs->pOverlayWin = NULL; - cs->pOverlayClients = NULL; - - cs->numAlternateVisuals = 0; - cs->alternateVisuals = NULL; - - 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->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->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; - pScreen->ChangeWindowAttributes = compChangeWindowAttributes; - - cs->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = compBlockHandler; - - cs->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = compCloseScreen; - - dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs); - - RegisterRealChildHeadProc(CompositeRealChildHead); - - return TRUE; -} +/*
+ * Copyright © 2006 Sun Microsystems, Inc. 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"
+
+static int CompScreenPrivateKeyIndex;
+DevPrivateKey CompScreenPrivateKey = &CompScreenPrivateKeyIndex;
+static int CompWindowPrivateKeyIndex;
+DevPrivateKey CompWindowPrivateKey = &CompWindowPrivateKeyIndex;
+static int CompSubwindowsPrivateKeyIndex;
+DevPrivateKey CompSubwindowsPrivateKey = &CompSubwindowsPrivateKeyIndex;
+
+
+static Bool
+compCloseScreen (int index, ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ Bool ret;
+
+ free(cs->alternateVisuals);
+
+ pScreen->CloseScreen = cs->CloseScreen;
+ pScreen->BlockHandler = cs->BlockHandler;
+ pScreen->InstallColormap = cs->InstallColormap;
+ pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
+ pScreen->ReparentWindow = cs->ReparentWindow;
+ 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;
+
+ 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
+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;
+}
+
+/*
+ * 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 (GetCompScreen (pScreen))
+ return TRUE;
+ cs = (CompScreenPtr) malloc(sizeof (CompScreenRec));
+ if (!cs)
+ return FALSE;
+
+ cs->damaged = 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->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 = pScreen->BlockHandler;
+ pScreen->BlockHandler = compBlockHandler;
+
+ cs->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = compCloseScreen;
+
+ dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
+
+ RegisterRealChildHeadProc(CompositeRealChildHead);
+
+ return TRUE;
+}
diff --git a/xorg-server/composite/compoverlay.c b/xorg-server/composite/compoverlay.c index 6d73f003d..453259e92 100644 --- a/xorg-server/composite/compoverlay.c +++ b/xorg-server/composite/compoverlay.c @@ -1,160 +1,160 @@ -/* - * Copyright © 2006 Sun Microsystems, Inc. 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 "xace.h" - -/* - * Delete the given overlay client list element from its screen list. - */ -void -compFreeOverlayClient (CompOverlayClientPtr pOcToDel) -{ - ScreenPtr pScreen = pOcToDel->pScreen; - CompScreenPtr cs = GetCompScreen (pScreen); - CompOverlayClientPtr *pPrev, pOc; - - for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) - { - if (pOc == pOcToDel) { - *pPrev = pOc->pNext; - xfree (pOc); - break; - } - } - - /* Destroy overlay window when there are no more clients using it */ - if (cs->pOverlayClients == NULL) - compDestroyOverlayWindow (pScreen); -} - -/* - * Return the client's first overlay client rec from the given screen - */ -CompOverlayClientPtr -compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - CompOverlayClientPtr pOc; - - for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext) - if (pOc->pClient == pClient) - return pOc; - - return NULL; -} - -/* - * Create an overlay client object for the given client - */ -CompOverlayClientPtr -compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - CompOverlayClientPtr pOc; - - pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec)); - if (pOc == NULL) - return NULL; - - pOc->pClient = pClient; - pOc->pScreen = pScreen; - pOc->resource = FakeClientID(pClient->index); - pOc->pNext = cs->pOverlayClients; - cs->pOverlayClients = pOc; - - /* - * Create a resource for this element so it can be deleted - * when the client goes away. - */ - if (!AddResource (pOc->resource, CompositeClientOverlayType, (pointer) pOc)) - return NULL; - - return pOc; -} - -/* - * Create the overlay window and map it - */ -Bool -compCreateOverlayWindow (ScreenPtr pScreen) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - WindowPtr pRoot = WindowTable[pScreen->myNum]; - WindowPtr pWin; - XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */ - int result; - - pWin = cs->pOverlayWin = - CreateWindow (cs->overlayWid, pRoot, - 0, 0, pScreen->width, pScreen->height, 0, - InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0], - pRoot->drawable.depth, - serverClient, pScreen->rootVisual, &result); - if (pWin == NULL) - return FALSE; - - if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) - return FALSE; - - MapWindow(pWin, serverClient); - - return TRUE; -} - -/* - * Destroy the overlay window - */ -void -compDestroyOverlayWindow (ScreenPtr pScreen) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - - cs->pOverlayWin = NullWindow; - FreeResource (cs->overlayWid, RT_NONE); -} - +/*
+ * Copyright © 2006 Sun Microsystems, Inc. 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 "xace.h"
+
+/*
+ * Delete the given overlay client list element from its screen list.
+ */
+void
+compFreeOverlayClient (CompOverlayClientPtr pOcToDel)
+{
+ ScreenPtr pScreen = pOcToDel->pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompOverlayClientPtr *pPrev, pOc;
+
+ for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext)
+ {
+ if (pOc == pOcToDel) {
+ *pPrev = pOc->pNext;
+ free(pOc);
+ break;
+ }
+ }
+
+ /* Destroy overlay window when there are no more clients using it */
+ if (cs->pOverlayClients == NULL)
+ compDestroyOverlayWindow (pScreen);
+}
+
+/*
+ * Return the client's first overlay client rec from the given screen
+ */
+CompOverlayClientPtr
+compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
+ if (pOc->pClient == pClient)
+ return pOc;
+
+ return NULL;
+}
+
+/*
+ * Create an overlay client object for the given client
+ */
+CompOverlayClientPtr
+compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ pOc = (CompOverlayClientPtr) malloc(sizeof(CompOverlayClientRec));
+ if (pOc == NULL)
+ return NULL;
+
+ pOc->pClient = pClient;
+ pOc->pScreen = pScreen;
+ pOc->resource = FakeClientID(pClient->index);
+ pOc->pNext = cs->pOverlayClients;
+ cs->pOverlayClients = pOc;
+
+ /*
+ * Create a resource for this element so it can be deleted
+ * when the client goes away.
+ */
+ if (!AddResource (pOc->resource, CompositeClientOverlayType, (pointer) pOc))
+ return NULL;
+
+ return pOc;
+}
+
+/*
+ * Create the overlay window and map it
+ */
+Bool
+compCreateOverlayWindow (ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ WindowPtr pWin;
+ XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
+ int result;
+
+ pWin = cs->pOverlayWin =
+ CreateWindow (cs->overlayWid, pRoot,
+ 0, 0, pScreen->width, pScreen->height, 0,
+ InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
+ pRoot->drawable.depth,
+ serverClient, pScreen->rootVisual, &result);
+ if (pWin == NULL)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ MapWindow(pWin, serverClient);
+
+ return TRUE;
+}
+
+/*
+ * Destroy the overlay window
+ */
+void
+compDestroyOverlayWindow (ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ cs->pOverlayWin = NullWindow;
+ FreeResource (cs->overlayWid, RT_NONE);
+}
+
|