aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/composite
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/composite')
-rw-r--r--xorg-server/composite/compalloc.c1294
-rw-r--r--xorg-server/composite/compoverlay.c324
-rw-r--r--xorg-server/composite/makefile9
3 files changed, 820 insertions, 807 deletions
diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c
index 73adc72d0..978fe5c17 100644
--- a/xorg-server/composite/compalloc.c
+++ b/xorg-server/composite/compalloc.c
@@ -1,647 +1,647 @@
-/*
- * 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 = 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 = xcalloc (1,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;
+}
diff --git a/xorg-server/composite/compoverlay.c b/xorg-server/composite/compoverlay.c
index 6d73f003d..ce6db9977 100644
--- a/xorg-server/composite/compoverlay.c
+++ b/xorg-server/composite/compoverlay.c
@@ -1,160 +1,164 @@
-/*
- * 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
+
+#ifdef CreateWindow
+#undef CreateWindow
+#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);
+}
+
diff --git a/xorg-server/composite/makefile b/xorg-server/composite/makefile
new file mode 100644
index 000000000..1ab95ebba
--- /dev/null
+++ b/xorg-server/composite/makefile
@@ -0,0 +1,9 @@
+
+LIBRARY=libcomposite
+
+CSRCS = \
+ compalloc.c \
+ compext.c \
+ compinit.c \
+ compoverlay.c \
+ compwindow.c