diff options
Diffstat (limited to 'xorg-server/composite')
-rw-r--r-- | xorg-server/composite/compalloc.c | 147 | ||||
-rw-r--r-- | xorg-server/composite/compint.h | 669 | ||||
-rw-r--r-- | xorg-server/composite/compwindow.c | 1651 |
3 files changed, 1264 insertions, 1203 deletions
diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c index 7164c0d3c..5c27631e1 100644 --- a/xorg-server/composite/compalloc.c +++ b/xorg-server/composite/compalloc.c @@ -104,6 +104,35 @@ compDestroyDamage (DamagePtr pDamage, void *closure) cw->damage = 0; } +static Bool +compMarkWindows(WindowPtr pWin, + WindowPtr *ppLayerWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pLayerWin = pWin; + + if (!pWin->viewable) + return FALSE; + + (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin); + (*pScreen->MarkWindow)(pLayerWin->parent); + + *ppLayerWin = pLayerWin; + + return TRUE; +} + +static void +compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther); + (*pScreen->HandleExposures)(pLayerWin->parent); + if (pScreen->PostValidateTree) + (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTOther); +} + /* * Redirect one window for one client */ @@ -112,8 +141,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) { CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw; - Bool wasMapped = pWin->mapped; CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); + WindowPtr pLayerWin; + Bool anyMarked = FALSE; if (pWin == cs->pOverlayWin) { return Success; @@ -163,16 +193,14 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) free(cw); return BadAlloc; } - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } + anyMarked = compMarkWindows (pWin, &pLayerWin); + + /* Make sure our borderClip is correct for ValidateTree */ RegionNull(&cw->borderClip); - cw->borderClipX = 0; - cw->borderClipY = 0; + RegionCopy(&cw->borderClip, &pWin->borderClip); + cw->borderClipX = pWin->drawable.x; + cw->borderClipY = pWin->drawable.y; cw->update = CompositeRedirectAutomatic; cw->clients = 0; cw->oldx = COMP_ORIGIN_INVALID; @@ -188,16 +216,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) 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 (!anyMarked) + anyMarked = compMarkWindows (pWin, &pLayerWin); + if (cw->damageRegistered) { DamageUnregister (&pWin->drawable, cw->damage); @@ -205,25 +226,51 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) } cw->update = CompositeRedirectManual; } + else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) { + if (!anyMarked) + anyMarked = compMarkWindows (pWin, &pLayerWin); + } 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; - } + + if (anyMarked) + compHandleMarkedWindows (pWin, pLayerWin); return Success; } +void +compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pParent = pWin->parent; + + if (pParent->drawable.depth == pWin->drawable.depth) { + GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); + int bw = (int) pWin->borderWidth; + int x = bw; + int y = bw; + int w = pWin->drawable.width; + int h = pWin->drawable.height; + + if (pGC) { + ChangeGCVal val; + val.val = IncludeInferiors; + ChangeGC (NullClient, pGC, GCSubwindowMode, &val); + ValidateGC(&pWin->drawable, pGC); + (*pGC->ops->CopyArea) (&pPixmap->drawable, + &pWin->drawable, + pGC, + x, y, w, h, 0, 0); + FreeScratchGC (pGC); + } + } +} + /* * Free one of the per-client per-window resources, clearing * redirect and the per-window pointer as appropriate @@ -231,9 +278,12 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) void compFreeClientWindow (WindowPtr pWin, XID id) { + ScreenPtr pScreen = pWin->drawable.pScreen; CompWindowPtr cw = GetCompWindow (pWin); CompClientWindowPtr ccw, *prev; - Bool wasMapped = pWin->mapped; + Bool anyMarked = FALSE; + WindowPtr pLayerWin; + PixmapPtr pPixmap = NULL; if (!cw) return; @@ -250,15 +300,12 @@ compFreeClientWindow (WindowPtr pWin, XID id) } if (!cw->clients) { - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } + anyMarked = compMarkWindows (pWin, &pLayerWin); - if (pWin->redirectDraw != RedirectDrawNone) - compFreePixmap (pWin); + if (pWin->redirectDraw != RedirectDrawNone) { + pPixmap = (*pScreen->GetWindowPixmap) (pWin); + compSetParentPixmap (pWin); + } if (cw->damage) DamageDestroy (cw->damage); @@ -271,19 +318,20 @@ compFreeClientWindow (WindowPtr pWin, XID id) else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) { + anyMarked = compMarkWindows (pWin, &pLayerWin); + DamageRegister (&pWin->drawable, cw->damage); cw->damageRegistered = TRUE; pWin->redirectDraw = RedirectDrawAutomatic; DamageDamageRegion(&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; + + if (anyMarked) + compHandleMarkedWindows (pWin, pLayerWin); + + if (pPixmap) { + compRestoreWindow (pWin, pPixmap); + (*pScreen->DestroyPixmap) (pPixmap); } } @@ -536,9 +584,8 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map) { ChangeGCVal val; val.val = IncludeInferiors; - + ChangeGC (NullClient, pGC, GCSubwindowMode, &val); ValidateGC(&pPixmap->drawable, pGC); - ChangeGC (serverClient, pGC, GCSubwindowMode, &val); (*pGC->ops->CopyArea) (&pParent->drawable, &pPixmap->drawable, pGC, @@ -617,10 +664,10 @@ compAllocPixmap (WindowPtr pWin) } void -compFreePixmap (WindowPtr pWin) +compSetParentPixmap (WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen; - PixmapPtr pRedirectPixmap, pParentPixmap; + PixmapPtr pParentPixmap; CompWindowPtr cw = GetCompWindow (pWin); if (cw->damageRegistered) @@ -636,11 +683,9 @@ compFreePixmap (WindowPtr pWin) * parent exposed area; regions beyond the parent cause crashes */ RegionCopy(&pWin->borderClip, &cw->borderClip); - pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin); pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); pWin->redirectDraw = RedirectDrawNone; compSetPixmap (pWin, pParentPixmap); - (*pScreen->DestroyPixmap) (pRedirectPixmap); } /* diff --git a/xorg-server/composite/compint.h b/xorg-server/composite/compint.h index 55cd6459e..bb5335d70 100644 --- a/xorg-server/composite/compint.h +++ b/xorg-server/composite/compint.h @@ -1,333 +1,336 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright © 2003 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _COMPINT_H_
-#define _COMPINT_H_
-
-#include "misc.h"
-#include "scrnintstr.h"
-#include "os.h"
-#include "regionstr.h"
-#include "validate.h"
-#include "windowstr.h"
-#include "input.h"
-#include "resource.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "dixstruct.h"
-#include "gcstruct.h"
-#include "servermd.h"
-#include "dixevents.h"
-#include "globals.h"
-#include "picturestr.h"
-#include "extnsionst.h"
-#include "privates.h"
-#include "mi.h"
-#include "damage.h"
-#include "damageextint.h"
-#include "xfixes.h"
-#include <X11/extensions/compositeproto.h>
-#include <assert.h>
-
-/*
- * enable this for debugging
-
- #define COMPOSITE_DEBUG
- */
-
-typedef struct _CompClientWindow {
- struct _CompClientWindow *next;
- XID id;
- int update;
-} CompClientWindowRec, *CompClientWindowPtr;
-
-typedef struct _CompWindow {
- RegionRec borderClip;
- DamagePtr damage; /* for automatic update mode */
- Bool damageRegistered;
- Bool damaged;
- int update;
- CompClientWindowPtr clients;
- int oldx;
- int oldy;
- PixmapPtr pOldPixmap;
- int borderClipX, borderClipY;
-} CompWindowRec, *CompWindowPtr;
-
-#define COMP_ORIGIN_INVALID 0x80000000
-
-typedef struct _CompSubwindows {
- int update;
- CompClientWindowPtr clients;
-} CompSubwindowsRec, *CompSubwindowsPtr;
-
-#ifndef COMP_INCLUDE_RGB24_VISUAL
-#define COMP_INCLUDE_RGB24_VISUAL 0
-#endif
-
-typedef struct _CompOverlayClientRec *CompOverlayClientPtr;
-
-typedef struct _CompOverlayClientRec {
- CompOverlayClientPtr pNext;
- ClientPtr pClient;
- ScreenPtr pScreen;
- XID resource;
-} CompOverlayClientRec;
-
-typedef struct _CompScreen {
- PositionWindowProcPtr PositionWindow;
- CopyWindowProcPtr CopyWindow;
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- ClipNotifyProcPtr ClipNotify;
- /*
- * Called from ConfigureWindow, these
- * three track changes to the offscreen storage
- * geometry
- */
- ConfigNotifyProcPtr ConfigNotify;
- MoveWindowProcPtr MoveWindow;
- ResizeWindowProcPtr ResizeWindow;
- ChangeBorderWidthProcPtr ChangeBorderWidth;
- /*
- * Reparenting has an effect on Subwindows redirect
- */
- ReparentWindowProcPtr ReparentWindow;
-
- /*
- * Colormaps for new visuals better not get installed
- */
- InstallColormapProcPtr InstallColormap;
-
- /*
- * Fake backing store via automatic redirection
- */
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
-
- ScreenBlockHandlerProcPtr BlockHandler;
- CloseScreenProcPtr CloseScreen;
- int numAlternateVisuals;
- VisualID *alternateVisuals;
-
- WindowPtr pOverlayWin;
- Window overlayWid;
- CompOverlayClientPtr pOverlayClients;
-
- GetImageProcPtr GetImage;
- SourceValidateProcPtr SourceValidate;
-} CompScreenRec, *CompScreenPtr;
-
-extern DevPrivateKeyRec CompScreenPrivateKeyRec;
-#define CompScreenPrivateKey (&CompScreenPrivateKeyRec)
-
-extern DevPrivateKeyRec CompWindowPrivateKeyRec;
-#define CompWindowPrivateKey (&CompWindowPrivateKeyRec)
-
-extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
-#define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec)
-
-#define GetCompScreen(s) ((CompScreenPtr) \
- dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey))
-#define GetCompWindow(w) ((CompWindowPtr) \
- dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey))
-#define GetCompSubwindows(w) ((CompSubwindowsPtr) \
- dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey))
-
-extern RESTYPE CompositeClientWindowType;
-extern RESTYPE CompositeClientSubwindowsType;
-extern RESTYPE CompositeClientOverlayType;
-
-/*
- * compalloc.c
- */
-
-Bool
-compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
-
-void
-compFreeClientWindow (WindowPtr pWin, XID id);
-
-int
-compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
-
-int
-compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
-
-void
-compFreeClientSubwindows (WindowPtr pWin, XID id);
-
-int
-compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
-
-int
-compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
-
-int
-compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
-
-Bool
-compAllocPixmap (WindowPtr pWin);
-
-void
-compFreePixmap (WindowPtr pWin);
-
-Bool
-compReallocPixmap (WindowPtr pWin, int x, int y,
- unsigned int w, unsigned int h, int bw);
-
-/*
- * compext.c
- */
-
-void
-CompositeExtensionInit (void);
-
-/*
- * compinit.c
- */
-
-Bool
-compScreenInit (ScreenPtr pScreen);
-
-/*
- * compoverlay.c
- */
-
-void
-compFreeOverlayClient (CompOverlayClientPtr pOcToDel);
-
-CompOverlayClientPtr
-compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient);
-
-CompOverlayClientPtr
-compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient);
-
-Bool
-compCreateOverlayWindow (ScreenPtr pScreen);
-
-void
-compDestroyOverlayWindow (ScreenPtr pScreen);
-
-/*
- * compwindow.c
- */
-
-#ifdef COMPOSITE_DEBUG
-void
-compCheckTree (ScreenPtr pScreen);
-#else
-#define compCheckTree(s)
-#endif
-
-PictFormatPtr
-compWindowFormat (WindowPtr pWin);
-
-void
-compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
-
-Bool
-compCheckRedirect (WindowPtr pWin);
-
-Bool
-compPositionWindow (WindowPtr pWin, int x, int y);
-
-Bool
-compRealizeWindow (WindowPtr pWin);
-
-Bool
-compUnrealizeWindow (WindowPtr pWin);
-
-void
-compClipNotify (WindowPtr pWin, int dx, int dy);
-
-void
-compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
-
-void
-compResizeWindow (WindowPtr pWin, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib);
-
-void
-compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
-
-void
-compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
-
-Bool
-compCreateWindow (WindowPtr pWin);
-
-Bool
-compDestroyWindow (WindowPtr pWin);
-
-void
-compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
-
-RegionPtr
-compGetRedirectBorderClip (WindowPtr pWin);
-
-void
-compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-
-void
-compPaintChildrenToWindow (WindowPtr pWin);
-
-WindowPtr
-CompositeRealChildHead (WindowPtr pWin);
-
-int
-DeleteWindowNoInputDevices(pointer value, XID wid);
-
-int
-compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
- int bw, WindowPtr pSib);
-
-void PanoramiXCompositeInit (void);
-void PanoramiXCompositeReset (void);
-
-#endif /* _COMPINT_H_ */
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright © 2003 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#ifndef _COMPINT_H_ +#define _COMPINT_H_ + +#include "misc.h" +#include "scrnintstr.h" +#include "os.h" +#include "regionstr.h" +#include "validate.h" +#include "windowstr.h" +#include "input.h" +#include "resource.h" +#include "colormapst.h" +#include "cursorstr.h" +#include "dixstruct.h" +#include "gcstruct.h" +#include "servermd.h" +#include "dixevents.h" +#include "globals.h" +#include "picturestr.h" +#include "extnsionst.h" +#include "privates.h" +#include "mi.h" +#include "damage.h" +#include "damageextint.h" +#include "xfixes.h" +#include <X11/extensions/compositeproto.h> +#include <assert.h> + +/* + * enable this for debugging + + #define COMPOSITE_DEBUG + */ + +typedef struct _CompClientWindow { + struct _CompClientWindow *next; + XID id; + int update; +} CompClientWindowRec, *CompClientWindowPtr; + +typedef struct _CompWindow { + RegionRec borderClip; + DamagePtr damage; /* for automatic update mode */ + Bool damageRegistered; + Bool damaged; + int update; + CompClientWindowPtr clients; + int oldx; + int oldy; + PixmapPtr pOldPixmap; + int borderClipX, borderClipY; +} CompWindowRec, *CompWindowPtr; + +#define COMP_ORIGIN_INVALID 0x80000000 + +typedef struct _CompSubwindows { + int update; + CompClientWindowPtr clients; +} CompSubwindowsRec, *CompSubwindowsPtr; + +#ifndef COMP_INCLUDE_RGB24_VISUAL +#define COMP_INCLUDE_RGB24_VISUAL 0 +#endif + +typedef struct _CompOverlayClientRec *CompOverlayClientPtr; + +typedef struct _CompOverlayClientRec { + CompOverlayClientPtr pNext; + ClientPtr pClient; + ScreenPtr pScreen; + XID resource; +} CompOverlayClientRec; + +typedef struct _CompScreen { + PositionWindowProcPtr PositionWindow; + CopyWindowProcPtr CopyWindow; + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + ClipNotifyProcPtr ClipNotify; + /* + * Called from ConfigureWindow, these + * three track changes to the offscreen storage + * geometry + */ + ConfigNotifyProcPtr ConfigNotify; + MoveWindowProcPtr MoveWindow; + ResizeWindowProcPtr ResizeWindow; + ChangeBorderWidthProcPtr ChangeBorderWidth; + /* + * Reparenting has an effect on Subwindows redirect + */ + ReparentWindowProcPtr ReparentWindow; + + /* + * Colormaps for new visuals better not get installed + */ + InstallColormapProcPtr InstallColormap; + + /* + * Fake backing store via automatic redirection + */ + ChangeWindowAttributesProcPtr ChangeWindowAttributes; + + ScreenBlockHandlerProcPtr BlockHandler; + CloseScreenProcPtr CloseScreen; + int numAlternateVisuals; + VisualID *alternateVisuals; + + WindowPtr pOverlayWin; + Window overlayWid; + CompOverlayClientPtr pOverlayClients; + + GetImageProcPtr GetImage; + SourceValidateProcPtr SourceValidate; +} CompScreenRec, *CompScreenPtr; + +extern DevPrivateKeyRec CompScreenPrivateKeyRec; +#define CompScreenPrivateKey (&CompScreenPrivateKeyRec) + +extern DevPrivateKeyRec CompWindowPrivateKeyRec; +#define CompWindowPrivateKey (&CompWindowPrivateKeyRec) + +extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec; +#define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec) + +#define GetCompScreen(s) ((CompScreenPtr) \ + dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey)) +#define GetCompWindow(w) ((CompWindowPtr) \ + dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey)) +#define GetCompSubwindows(w) ((CompSubwindowsPtr) \ + dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey)) + +extern RESTYPE CompositeClientWindowType; +extern RESTYPE CompositeClientSubwindowsType; +extern RESTYPE CompositeClientOverlayType; + +/* + * compalloc.c + */ + +Bool +compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update); + +void +compFreeClientWindow (WindowPtr pWin, XID id); + +int +compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update); + +int +compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update); + +void +compFreeClientSubwindows (WindowPtr pWin, XID id); + +int +compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update); + +int +compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin); + +int +compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin); + +Bool +compAllocPixmap (WindowPtr pWin); + +void +compSetParentPixmap (WindowPtr pWin); + +void +compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap); + +Bool +compReallocPixmap (WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, int bw); + +/* + * compext.c + */ + +void +CompositeExtensionInit (void); + +/* + * compinit.c + */ + +Bool +compScreenInit (ScreenPtr pScreen); + +/* + * compoverlay.c + */ + +void +compFreeOverlayClient (CompOverlayClientPtr pOcToDel); + +CompOverlayClientPtr +compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient); + +CompOverlayClientPtr +compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient); + +Bool +compCreateOverlayWindow (ScreenPtr pScreen); + +void +compDestroyOverlayWindow (ScreenPtr pScreen); + +/* + * compwindow.c + */ + +#ifdef COMPOSITE_DEBUG +void +compCheckTree (ScreenPtr pScreen); +#else +#define compCheckTree(s) +#endif + +PictFormatPtr +compWindowFormat (WindowPtr pWin); + +void +compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap); + +Bool +compCheckRedirect (WindowPtr pWin); + +Bool +compPositionWindow (WindowPtr pWin, int x, int y); + +Bool +compRealizeWindow (WindowPtr pWin); + +Bool +compUnrealizeWindow (WindowPtr pWin); + +void +compClipNotify (WindowPtr pWin, int dx, int dy); + +void +compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind); + +void +compResizeWindow (WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib); + +void +compChangeBorderWidth (WindowPtr pWin, unsigned int border_width); + +void +compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent); + +Bool +compCreateWindow (WindowPtr pWin); + +Bool +compDestroyWindow (WindowPtr pWin); + +void +compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion); + +RegionPtr +compGetRedirectBorderClip (WindowPtr pWin); + +void +compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void +compPaintChildrenToWindow (WindowPtr pWin); + +WindowPtr +CompositeRealChildHead (WindowPtr pWin); + +int +DeleteWindowNoInputDevices(pointer value, XID wid); + +int +compConfigNotify(WindowPtr pWin, int x, int y, int w, int h, + int bw, WindowPtr pSib); + +void PanoramiXCompositeInit (void); +void PanoramiXCompositeReset (void); + +#endif /* _COMPINT_H_ */ diff --git a/xorg-server/composite/compwindow.c b/xorg-server/composite/compwindow.c index ef1f7f154..d2a866d6f 100644 --- a/xorg-server/composite/compwindow.c +++ b/xorg-server/composite/compwindow.c @@ -1,819 +1,832 @@ -/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Copyright © 2003 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "compint.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-#ifdef COMPOSITE_DEBUG
-static int
-compCheckWindow (WindowPtr pWin, pointer data)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
- PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
- PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
-
- if (!pWin->parent)
- {
- assert (pWin->redirectDraw == RedirectDrawNone);
- assert (pWinPixmap == pScreenPixmap);
- }
- else if (pWin->redirectDraw != RedirectDrawNone)
- {
- assert (pWinPixmap != pParentPixmap);
- assert (pWinPixmap != pScreenPixmap);
- }
- else
- {
- assert (pWinPixmap == pParentPixmap);
- }
- assert (0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
- assert (0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
- if (pParentPixmap)
- assert (0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
- return WT_WALKCHILDREN;
-}
-
-void
-compCheckTree (ScreenPtr pScreen)
-{
- WalkTree (pScreen, compCheckWindow, 0);
-}
-#endif
-
-typedef struct _compPixmapVisit {
- WindowPtr pWindow;
- PixmapPtr pPixmap;
-} CompPixmapVisitRec, *CompPixmapVisitPtr;
-
-static Bool
-compRepaintBorder (ClientPtr pClient, pointer closure)
-{
- WindowPtr pWindow;
- int rc = dixLookupWindow(&pWindow, (XID)(intptr_t)closure, pClient, DixWriteAccess);
-
- if (rc == Success) {
- RegionRec exposed;
-
- RegionNull(&exposed);
- RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
- miPaintWindow(pWindow, &exposed, PW_BORDER);
- RegionUninit(&exposed);
- }
- return TRUE;
-}
-
-static int
-compSetPixmapVisitWindow (WindowPtr pWindow, pointer data)
-{
- CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
- ScreenPtr pScreen = pWindow->drawable.pScreen;
-
- if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
- return WT_DONTWALKCHILDREN;
- (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
- /*
- * Recompute winSize and borderSize. This is duplicate effort
- * when resizing pixmaps, but necessary when changing redirection.
- * Might be nice to fix this.
- */
- SetWinSize (pWindow);
- SetBorderSize (pWindow);
- if (HasBorder (pWindow))
- QueueWorkProc (compRepaintBorder, serverClient,
- (pointer)(intptr_t) pWindow->drawable.id);
- return WT_WALKCHILDREN;
-}
-
-void
-compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
-{
- CompPixmapVisitRec visitRec;
-
- visitRec.pWindow = pWindow;
- visitRec.pPixmap = pPixmap;
- TraverseTree (pWindow, compSetPixmapVisitWindow, (pointer) &visitRec);
- compCheckTree (pWindow->drawable.pScreen);
-}
-
-Bool
-compCheckRedirect (WindowPtr pWin)
-{
- CompWindowPtr cw = GetCompWindow (pWin);
- CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
- Bool should;
-
- should = pWin->realized && (pWin->drawable.class != InputOnly) &&
- (cw != NULL) && (pWin->parent != NULL);
-
- /* Never redirect the overlay window */
- if (cs->pOverlayWin != NULL) {
- if (pWin == cs->pOverlayWin) {
- should = FALSE;
- }
- }
-
- if (should != (pWin->redirectDraw != RedirectDrawNone))
- {
- if (should)
- return compAllocPixmap (pWin);
- else
- compFreePixmap (pWin);
- }
- return TRUE;
-}
-
-static int
-updateOverlayWindow(ScreenPtr pScreen)
-{
- CompScreenPtr cs;
- WindowPtr pWin; /* overlay window */
- XID vlist[2];
- int w = pScreen->width;
- int h = pScreen->height;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension)
- {
- w = PanoramiXPixWidth;
- h = PanoramiXPixHeight;
- }
-#endif
-
- cs = GetCompScreen(pScreen);
- if ((pWin = cs->pOverlayWin) != NULL) {
- if ((pWin->drawable.width == w) &&
- (pWin->drawable.height == h))
- return Success;
-
- /* Let's resize the overlay window. */
- vlist[0] = w;
- vlist[1] = h;
- return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
- }
-
- /* Let's be on the safe side and not assume an overlay window is always allocated. */
- return Success;
-}
-
-Bool
-compPositionWindow (WindowPtr pWin, int x, int y)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret = TRUE;
-
- pScreen->PositionWindow = cs->PositionWindow;
- /*
- * "Shouldn't need this as all possible places should be wrapped
- *
- compCheckRedirect (pWin);
- */
-#ifdef COMPOSITE_DEBUG
- if ((pWin->redirectDraw != RedirectDrawNone) !=
- (pWin->viewable && (GetCompWindow(pWin) != NULL)))
- OsAbort ();
-#endif
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
- int bw = wBorderWidth (pWin);
- int nx = pWin->drawable.x - bw;
- int ny = pWin->drawable.y - bw;
-
- if (pPixmap->screen_x != nx || pPixmap->screen_y != ny)
- {
- pPixmap->screen_x = nx;
- pPixmap->screen_y = ny;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
- }
-
- if (!(*pScreen->PositionWindow) (pWin, x, y))
- ret = FALSE;
- cs->PositionWindow = pScreen->PositionWindow;
- pScreen->PositionWindow = compPositionWindow;
- compCheckTree (pWin->drawable.pScreen);
- if (updateOverlayWindow(pScreen) != Success)
- ret = FALSE;
- return ret;
-}
-
-Bool
-compRealizeWindow (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret = TRUE;
-
- pScreen->RealizeWindow = cs->RealizeWindow;
- compCheckRedirect (pWin);
- if (!(*pScreen->RealizeWindow) (pWin))
- ret = FALSE;
- cs->RealizeWindow = pScreen->RealizeWindow;
- pScreen->RealizeWindow = compRealizeWindow;
- compCheckTree (pWin->drawable.pScreen);
- return ret;
-}
-
-Bool
-compUnrealizeWindow (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret = TRUE;
-
- pScreen->UnrealizeWindow = cs->UnrealizeWindow;
- compCheckRedirect (pWin);
- if (!(*pScreen->UnrealizeWindow) (pWin))
- ret = FALSE;
- cs->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreen->UnrealizeWindow = compUnrealizeWindow;
- compCheckTree (pWin->drawable.pScreen);
- return ret;
-}
-
-/*
- * Called after the borderClip for the window has settled down
- * We use this to make sure our extra borderClip has the right origin
- */
-
-void
-compClipNotify (WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- CompWindowPtr cw = GetCompWindow (pWin);
-
- if (cw)
- {
- if (cw->borderClipX != pWin->drawable.x ||
- cw->borderClipY != pWin->drawable.y)
- {
- RegionTranslate(&cw->borderClip,
- pWin->drawable.x - cw->borderClipX,
- pWin->drawable.y - cw->borderClipY);
- cw->borderClipX = pWin->drawable.x;
- cw->borderClipY = pWin->drawable.y;
- }
- }
- if (cs->ClipNotify)
- {
- pScreen->ClipNotify = cs->ClipNotify;
- (*pScreen->ClipNotify) (pWin, dx, dy);
- cs->ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = compClipNotify;
- }
-}
-
-/*
- * Returns TRUE if the window needs server-provided automatic redirect,
- * which is true if the child and parent aren't both regular or ARGB visuals
- */
-
-static Bool
-compIsAlternateVisual (ScreenPtr pScreen,
- XID visual)
-{
- CompScreenPtr cs = GetCompScreen (pScreen);
- int i;
-
- for (i = 0; i < cs->numAlternateVisuals; i++)
- if (cs->alternateVisuals[i] == visual)
- return TRUE;
- return FALSE;
-}
-
-static Bool
-compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
-{
- if (pParent)
- {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XID winVisual = wVisual (pWin);
- XID parentVisual = wVisual (pParent);
-
- if (winVisual != parentVisual &&
- (compIsAlternateVisual (pScreen, winVisual) ||
- compIsAlternateVisual (pScreen, parentVisual)))
- return TRUE;
- }
- return FALSE;
-}
-
-static void compFreeOldPixmap(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- CompWindowPtr cw = GetCompWindow (pWin);
- if (cw->pOldPixmap)
- {
- (*pScreen->DestroyPixmap) (cw->pOldPixmap);
- cw->pOldPixmap = NullPixmap;
- }
- }
-}
-void
-compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->MoveWindow = cs->MoveWindow;
- (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
- cs->MoveWindow = pScreen->MoveWindow;
- pScreen->MoveWindow = compMoveWindow;
-
- compFreeOldPixmap(pWin);
- compCheckTree (pScreen);
-}
-
-void
-compResizeWindow (WindowPtr pWin, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->ResizeWindow = cs->ResizeWindow;
- (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
- cs->ResizeWindow = pScreen->ResizeWindow;
- pScreen->ResizeWindow = compResizeWindow;
-
- compFreeOldPixmap(pWin);
- compCheckTree (pWin->drawable.pScreen);
-}
-
-void
-compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
- (*pScreen->ChangeBorderWidth) (pWin, bw);
- cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
- pScreen->ChangeBorderWidth = compChangeBorderWidth;
-
- compFreeOldPixmap(pWin);
- compCheckTree (pWin->drawable.pScreen);
-}
-
-void
-compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
-
- pScreen->ReparentWindow = cs->ReparentWindow;
- /*
- * Remove any implicit redirect due to synthesized visual
- */
- if (compImplicitRedirect (pWin, pPriorParent))
- compUnredirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
- /*
- * Handle subwindows redirection
- */
- compUnredirectOneSubwindow (pPriorParent, pWin);
- compRedirectOneSubwindow (pWin->parent, pWin);
- /*
- * Add any implict redirect due to synthesized visual
- */
- if (compImplicitRedirect (pWin, pWin->parent))
- compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
-
- /*
- * Allocate any necessary redirect pixmap
- * (this actually should never be true; pWin is always unmapped)
- */
- compCheckRedirect (pWin);
-
- /*
- * Reset pixmap pointers as appropriate
- */
- if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
- compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
- /*
- * Call down to next function
- */
- if (pScreen->ReparentWindow)
- (*pScreen->ReparentWindow) (pWin, pPriorParent);
- cs->ReparentWindow = pScreen->ReparentWindow;
- pScreen->ReparentWindow = compReparentWindow;
- compCheckTree (pWin->drawable.pScreen);
-}
-
-void
-compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- int dx = 0, dy = 0;
-
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
- CompWindowPtr cw = GetCompWindow (pWin);
-
- assert (cw->oldx != COMP_ORIGIN_INVALID);
- assert (cw->oldy != COMP_ORIGIN_INVALID);
- if (cw->pOldPixmap)
- {
- /*
- * Ok, the old bits are available in pOldPixmap and
- * need to be copied to pNewPixmap.
- */
- RegionRec rgnDst;
- PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
- GCPtr pGC;
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- RegionTranslate(prgnSrc, -dx, -dy);
-
- RegionNull(&rgnDst);
-
- RegionIntersect(&rgnDst,
- &pWin->borderClip, prgnSrc);
-
- RegionTranslate(&rgnDst,
- -pPixmap->screen_x, -pPixmap->screen_y);
-
- dx = dx + pPixmap->screen_x - cw->oldx;
- dy = dy + pPixmap->screen_y - cw->oldy;
- pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
- if (pGC)
- {
- BoxPtr pBox = RegionRects (&rgnDst);
- int nBox = RegionNumRects (&rgnDst);
-
- ValidateGC(&pPixmap->drawable, pGC);
- while (nBox--)
- {
- (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
- &pPixmap->drawable,
- pGC,
- pBox->x1 + dx, pBox->y1 + dy,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- pBox->x1, pBox->y1);
- pBox++;
- }
- FreeScratchGC (pGC);
- }
- return;
- }
- dx = pPixmap->screen_x - cw->oldx;
- dy = pPixmap->screen_y - cw->oldy;
- ptOldOrg.x += dx;
- ptOldOrg.y += dy;
- }
-
- pScreen->CopyWindow = cs->CopyWindow;
- if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y)
- {
- if (dx || dy)
- RegionTranslate(prgnSrc, dx, dy);
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- if (dx || dy)
- RegionTranslate(prgnSrc, -dx, -dy);
- }
- else
- {
- ptOldOrg.x -= dx;
- ptOldOrg.y -= dy;
- RegionTranslate(prgnSrc,
- pWin->drawable.x - ptOldOrg.x,
- pWin->drawable.y - ptOldOrg.y);
- DamageDamageRegion(&pWin->drawable, prgnSrc);
- }
- cs->CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = compCopyWindow;
- compCheckTree (pWin->drawable.pScreen);
-}
-
-Bool
-compCreateWindow (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret;
-
- pScreen->CreateWindow = cs->CreateWindow;
- ret = (*pScreen->CreateWindow) (pWin);
- if (pWin->parent && ret)
- {
- CompSubwindowsPtr csw = GetCompSubwindows (pWin->parent);
- CompClientWindowPtr ccw;
-
- (*pScreen->SetWindowPixmap) (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
- if (csw)
- for (ccw = csw->clients; ccw; ccw = ccw->next)
- compRedirectWindow (clients[CLIENT_ID(ccw->id)],
- pWin, ccw->update);
- if (compImplicitRedirect (pWin, pWin->parent))
- compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
- }
- cs->CreateWindow = pScreen->CreateWindow;
- pScreen->CreateWindow = compCreateWindow;
- compCheckTree (pWin->drawable.pScreen);
- return ret;
-}
-
-Bool
-compDestroyWindow (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- CompWindowPtr cw;
- CompSubwindowsPtr csw;
- Bool ret;
-
- pScreen->DestroyWindow = cs->DestroyWindow;
- while ((cw = GetCompWindow (pWin)))
- FreeResource (cw->clients->id, RT_NONE);
- while ((csw = GetCompSubwindows (pWin)))
- FreeResource (csw->clients->id, RT_NONE);
-
- if (pWin->redirectDraw != RedirectDrawNone)
- compFreePixmap (pWin);
- ret = (*pScreen->DestroyWindow) (pWin);
- cs->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = compDestroyWindow;
-/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
- return ret;
-}
-
-void
-compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
-{
- CompWindowPtr cw = GetCompWindow (pWin);
- RegionRec damage;
-
- RegionNull(&damage);
- /*
- * Align old border clip with new border clip
- */
- RegionTranslate(&cw->borderClip,
- pWin->drawable.x - cw->borderClipX,
- pWin->drawable.y - cw->borderClipY);
- /*
- * Compute newly visible portion of window for repaint
- */
- RegionSubtract(&damage, pRegion, &cw->borderClip);
- /*
- * Report that as damaged so it will be redrawn
- */
- DamageDamageRegion(&pWin->drawable, &damage);
- RegionUninit(&damage);
- /*
- * Save the new border clip region
- */
- RegionCopy(&cw->borderClip, pRegion);
- cw->borderClipX = pWin->drawable.x;
- cw->borderClipY = pWin->drawable.y;
-}
-
-RegionPtr
-compGetRedirectBorderClip (WindowPtr pWin)
-{
- CompWindowPtr cw = GetCompWindow (pWin);
-
- return &cw->borderClip;
-}
-
-static VisualPtr
-compGetWindowVisual (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- VisualID vid = wVisual (pWin);
- int i;
-
- for (i = 0; i < pScreen->numVisuals; i++)
- if (pScreen->visuals[i].vid == vid)
- return &pScreen->visuals[i];
- return 0;
-}
-
-PictFormatPtr
-compWindowFormat (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- return PictureMatchVisual (pScreen, pWin->drawable.depth,
- compGetWindowVisual (pWin));
-}
-
-static void
-compWindowUpdateAutomatic (WindowPtr pWin)
-{
- CompWindowPtr cw = GetCompWindow (pWin);
- ScreenPtr pScreen = pWin->drawable.pScreen;
- WindowPtr pParent = pWin->parent;
- PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
- PictFormatPtr pSrcFormat = compWindowFormat (pWin);
- PictFormatPtr pDstFormat = compWindowFormat (pWin->parent);
- int error;
- RegionPtr pRegion = DamageRegion (cw->damage);
- PicturePtr pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
- pSrcFormat,
- 0, 0,
- serverClient,
- &error);
- XID subwindowMode = IncludeInferiors;
- PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable,
- pDstFormat,
- CPSubwindowMode,
- &subwindowMode,
- serverClient,
- &error);
-
- /*
- * First move the region from window to screen coordinates
- */
- RegionTranslate(pRegion,
- pWin->drawable.x, pWin->drawable.y);
-
- /*
- * Clip against the "real" border clip
- */
- RegionIntersect(pRegion, pRegion, &cw->borderClip);
-
- /*
- * Now translate from screen to dest coordinates
- */
- RegionTranslate(pRegion,
- -pParent->drawable.x, -pParent->drawable.y);
-
- /*
- * Clip the picture
- */
- SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
-
- /*
- * And paint
- */
- CompositePicture (PictOpSrc,
- pSrcPicture,
- 0,
- pDstPicture,
- 0, 0, /* src_x, src_y */
- 0, 0, /* msk_x, msk_y */
- pSrcPixmap->screen_x - pParent->drawable.x,
- pSrcPixmap->screen_y - pParent->drawable.y,
- pSrcPixmap->drawable.width,
- pSrcPixmap->drawable.height);
- FreePicture (pSrcPicture, 0);
- FreePicture (pDstPicture, 0);
- /*
- * Empty the damage region. This has the nice effect of
- * rendering the translations above harmless
- */
- DamageEmpty (cw->damage);
-}
-
-static void
-compPaintWindowToParent (WindowPtr pWin)
-{
- compPaintChildrenToWindow (pWin);
-
- if (pWin->redirectDraw != RedirectDrawNone)
- {
- CompWindowPtr cw = GetCompWindow(pWin);
-
- if (cw->damaged)
- {
- compWindowUpdateAutomatic (pWin);
- cw->damaged = FALSE;
- }
- }
-}
-
-void
-compPaintChildrenToWindow (WindowPtr pWin)
-{
- WindowPtr pChild;
-
- if (!pWin->damagedDescendants)
- return;
-
- for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
- compPaintWindowToParent (pChild);
-
- pWin->damagedDescendants = FALSE;
-}
-
-WindowPtr
-CompositeRealChildHead (WindowPtr pWin)
-{
- WindowPtr pChild, pChildBefore;
- CompScreenPtr cs;
-
- if (!pWin->parent &&
- (screenIsSaved == SCREEN_SAVER_ON) &&
- (HasSaverWindow (pWin->drawable.pScreen))) {
-
- /* First child is the screen saver; see if next child is the overlay */
- pChildBefore = pWin->firstChild;
- pChild = pChildBefore->nextSib;
-
- } else {
- pChildBefore = NullWindow;
- pChild = pWin->firstChild;
- }
-
- if (!pChild) {
- return NullWindow;
- }
-
- cs = GetCompScreen(pWin->drawable.pScreen);
- if (pChild == cs->pOverlayWin) {
- return pChild;
- } else {
- return pChildBefore;
- }
-}
-
-int
-compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
- int bw, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret = 0;
- WindowPtr pParent = pWin->parent;
- int draw_x, draw_y;
- Bool alloc_ret;
-
- if (cs->ConfigNotify)
- {
- pScreen->ConfigNotify = cs->ConfigNotify;
- ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
- cs->ConfigNotify = pScreen->ConfigNotify;
- pScreen->ConfigNotify = compConfigNotify;
-
- if (ret)
- return ret;
- }
-
- if (pWin->redirectDraw == RedirectDrawNone)
- return Success;
-
- compCheckTree (pScreen);
-
- draw_x = pParent->drawable.x + x + bw;
- draw_y = pParent->drawable.y + y + bw;
- alloc_ret = compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
-
- if (alloc_ret == FALSE)
- return BadAlloc;
- return Success;
-}
+/* + * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright © 2003 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "compint.h" + +#ifdef PANORAMIX +#include "panoramiXsrv.h" +#endif + +#ifdef COMPOSITE_DEBUG +static int +compCheckWindow (WindowPtr pWin, pointer data) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin); + PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0; + PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen); + + if (!pWin->parent) + { + assert (pWin->redirectDraw == RedirectDrawNone); + assert (pWinPixmap == pScreenPixmap); + } + else if (pWin->redirectDraw != RedirectDrawNone) + { + assert (pWinPixmap != pParentPixmap); + assert (pWinPixmap != pScreenPixmap); + } + else + { + assert (pWinPixmap == pParentPixmap); + } + assert (0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3); + assert (0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3); + if (pParentPixmap) + assert (0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3); + return WT_WALKCHILDREN; +} + +void +compCheckTree (ScreenPtr pScreen) +{ + WalkTree (pScreen, compCheckWindow, 0); +} +#endif + +typedef struct _compPixmapVisit { + WindowPtr pWindow; + PixmapPtr pPixmap; +} CompPixmapVisitRec, *CompPixmapVisitPtr; + +static Bool +compRepaintBorder (ClientPtr pClient, pointer closure) +{ + WindowPtr pWindow; + int rc = dixLookupWindow(&pWindow, (XID)(intptr_t)closure, pClient, DixWriteAccess); + + if (rc == Success) { + RegionRec exposed; + + RegionNull(&exposed); + RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize); + miPaintWindow(pWindow, &exposed, PW_BORDER); + RegionUninit(&exposed); + } + return TRUE; +} + +static int +compSetPixmapVisitWindow (WindowPtr pWindow, pointer data) +{ + CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data; + ScreenPtr pScreen = pWindow->drawable.pScreen; + + if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone) + return WT_DONTWALKCHILDREN; + (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap); + /* + * Recompute winSize and borderSize. This is duplicate effort + * when resizing pixmaps, but necessary when changing redirection. + * Might be nice to fix this. + */ + SetWinSize (pWindow); + SetBorderSize (pWindow); + if (HasBorder (pWindow)) + QueueWorkProc (compRepaintBorder, serverClient, + (pointer)(intptr_t) pWindow->drawable.id); + return WT_WALKCHILDREN; +} + +void +compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap) +{ + CompPixmapVisitRec visitRec; + + visitRec.pWindow = pWindow; + visitRec.pPixmap = pPixmap; + TraverseTree (pWindow, compSetPixmapVisitWindow, (pointer) &visitRec); + compCheckTree (pWindow->drawable.pScreen); +} + +Bool +compCheckRedirect (WindowPtr pWin) +{ + CompWindowPtr cw = GetCompWindow (pWin); + CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); + Bool should; + + should = pWin->realized && (pWin->drawable.class != InputOnly) && + (cw != NULL) && (pWin->parent != NULL); + + /* Never redirect the overlay window */ + if (cs->pOverlayWin != NULL) { + if (pWin == cs->pOverlayWin) { + should = FALSE; + } + } + + if (should != (pWin->redirectDraw != RedirectDrawNone)) + { + if (should) + return compAllocPixmap (pWin); + else { + ScreenPtr pScreen = pWin->drawable.pScreen; + PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); + compSetParentPixmap (pWin); + compRestoreWindow (pWin, pPixmap); + (*pScreen->DestroyPixmap) (pPixmap); + } + } else if (should) { + if (cw->update == CompositeRedirectAutomatic) + pWin->redirectDraw = RedirectDrawAutomatic; + else + pWin->redirectDraw = RedirectDrawManual; + } + return TRUE; +} + +static int +updateOverlayWindow(ScreenPtr pScreen) +{ + CompScreenPtr cs; + WindowPtr pWin; /* overlay window */ + XID vlist[2]; + int w = pScreen->width; + int h = pScreen->height; + +#ifdef PANORAMIX + if (!noPanoramiXExtension) + { + w = PanoramiXPixWidth; + h = PanoramiXPixHeight; + } +#endif + + cs = GetCompScreen(pScreen); + if ((pWin = cs->pOverlayWin) != NULL) { + if ((pWin->drawable.width == w) && + (pWin->drawable.height == h)) + return Success; + + /* Let's resize the overlay window. */ + vlist[0] = w; + vlist[1] = h; + return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin)); + } + + /* Let's be on the safe side and not assume an overlay window is always allocated. */ + return Success; +} + +Bool +compPositionWindow (WindowPtr pWin, int x, int y) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret = TRUE; + + pScreen->PositionWindow = cs->PositionWindow; + /* + * "Shouldn't need this as all possible places should be wrapped + * + compCheckRedirect (pWin); + */ +#ifdef COMPOSITE_DEBUG + if ((pWin->redirectDraw != RedirectDrawNone) != + (pWin->viewable && (GetCompWindow(pWin) != NULL))) + OsAbort (); +#endif + if (pWin->redirectDraw != RedirectDrawNone) + { + PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); + int bw = wBorderWidth (pWin); + int nx = pWin->drawable.x - bw; + int ny = pWin->drawable.y - bw; + + if (pPixmap->screen_x != nx || pPixmap->screen_y != ny) + { + pPixmap->screen_x = nx; + pPixmap->screen_y = ny; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } + } + + if (!(*pScreen->PositionWindow) (pWin, x, y)) + ret = FALSE; + cs->PositionWindow = pScreen->PositionWindow; + pScreen->PositionWindow = compPositionWindow; + compCheckTree (pWin->drawable.pScreen); + if (updateOverlayWindow(pScreen) != Success) + ret = FALSE; + return ret; +} + +Bool +compRealizeWindow (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret = TRUE; + + pScreen->RealizeWindow = cs->RealizeWindow; + compCheckRedirect (pWin); + if (!(*pScreen->RealizeWindow) (pWin)) + ret = FALSE; + cs->RealizeWindow = pScreen->RealizeWindow; + pScreen->RealizeWindow = compRealizeWindow; + compCheckTree (pWin->drawable.pScreen); + return ret; +} + +Bool +compUnrealizeWindow (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret = TRUE; + + pScreen->UnrealizeWindow = cs->UnrealizeWindow; + compCheckRedirect (pWin); + if (!(*pScreen->UnrealizeWindow) (pWin)) + ret = FALSE; + cs->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = compUnrealizeWindow; + compCheckTree (pWin->drawable.pScreen); + return ret; +} + +/* + * Called after the borderClip for the window has settled down + * We use this to make sure our extra borderClip has the right origin + */ + +void +compClipNotify (WindowPtr pWin, int dx, int dy) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + CompWindowPtr cw = GetCompWindow (pWin); + + if (cw) + { + if (cw->borderClipX != pWin->drawable.x || + cw->borderClipY != pWin->drawable.y) + { + RegionTranslate(&cw->borderClip, + pWin->drawable.x - cw->borderClipX, + pWin->drawable.y - cw->borderClipY); + cw->borderClipX = pWin->drawable.x; + cw->borderClipY = pWin->drawable.y; + } + } + if (cs->ClipNotify) + { + pScreen->ClipNotify = cs->ClipNotify; + (*pScreen->ClipNotify) (pWin, dx, dy); + cs->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = compClipNotify; + } +} + +/* + * Returns TRUE if the window needs server-provided automatic redirect, + * which is true if the child and parent aren't both regular or ARGB visuals + */ + +static Bool +compIsAlternateVisual (ScreenPtr pScreen, + XID visual) +{ + CompScreenPtr cs = GetCompScreen (pScreen); + int i; + + for (i = 0; i < cs->numAlternateVisuals; i++) + if (cs->alternateVisuals[i] == visual) + return TRUE; + return FALSE; +} + +static Bool +compImplicitRedirect (WindowPtr pWin, WindowPtr pParent) +{ + if (pParent) + { + ScreenPtr pScreen = pWin->drawable.pScreen; + XID winVisual = wVisual (pWin); + XID parentVisual = wVisual (pParent); + + if (winVisual != parentVisual && + (compIsAlternateVisual (pScreen, winVisual) || + compIsAlternateVisual (pScreen, parentVisual))) + return TRUE; + } + return FALSE; +} + +static void compFreeOldPixmap(WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + if (pWin->redirectDraw != RedirectDrawNone) + { + CompWindowPtr cw = GetCompWindow (pWin); + if (cw->pOldPixmap) + { + (*pScreen->DestroyPixmap) (cw->pOldPixmap); + cw->pOldPixmap = NullPixmap; + } + } +} +void +compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + + pScreen->MoveWindow = cs->MoveWindow; + (*pScreen->MoveWindow) (pWin, x, y, pSib, kind); + cs->MoveWindow = pScreen->MoveWindow; + pScreen->MoveWindow = compMoveWindow; + + compFreeOldPixmap(pWin); + compCheckTree (pScreen); +} + +void +compResizeWindow (WindowPtr pWin, int x, int y, + unsigned int w, unsigned int h, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + + pScreen->ResizeWindow = cs->ResizeWindow; + (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib); + cs->ResizeWindow = pScreen->ResizeWindow; + pScreen->ResizeWindow = compResizeWindow; + + compFreeOldPixmap(pWin); + compCheckTree (pWin->drawable.pScreen); +} + +void +compChangeBorderWidth (WindowPtr pWin, unsigned int bw) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + + pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; + (*pScreen->ChangeBorderWidth) (pWin, bw); + cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; + pScreen->ChangeBorderWidth = compChangeBorderWidth; + + compFreeOldPixmap(pWin); + compCheckTree (pWin->drawable.pScreen); +} + +void +compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + + pScreen->ReparentWindow = cs->ReparentWindow; + /* + * Remove any implicit redirect due to synthesized visual + */ + if (compImplicitRedirect (pWin, pPriorParent)) + compUnredirectWindow (serverClient, pWin, CompositeRedirectAutomatic); + /* + * Handle subwindows redirection + */ + compUnredirectOneSubwindow (pPriorParent, pWin); + compRedirectOneSubwindow (pWin->parent, pWin); + /* + * Add any implict redirect due to synthesized visual + */ + if (compImplicitRedirect (pWin, pWin->parent)) + compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic); + + /* + * Allocate any necessary redirect pixmap + * (this actually should never be true; pWin is always unmapped) + */ + compCheckRedirect (pWin); + + /* + * Reset pixmap pointers as appropriate + */ + if (pWin->parent && pWin->redirectDraw == RedirectDrawNone) + compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent)); + /* + * Call down to next function + */ + if (pScreen->ReparentWindow) + (*pScreen->ReparentWindow) (pWin, pPriorParent); + cs->ReparentWindow = pScreen->ReparentWindow; + pScreen->ReparentWindow = compReparentWindow; + compCheckTree (pWin->drawable.pScreen); +} + +void +compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + int dx = 0, dy = 0; + + if (pWin->redirectDraw != RedirectDrawNone) + { + PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); + CompWindowPtr cw = GetCompWindow (pWin); + + assert (cw->oldx != COMP_ORIGIN_INVALID); + assert (cw->oldy != COMP_ORIGIN_INVALID); + if (cw->pOldPixmap) + { + /* + * Ok, the old bits are available in pOldPixmap and + * need to be copied to pNewPixmap. + */ + RegionRec rgnDst; + PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); + GCPtr pGC; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + RegionTranslate(prgnSrc, -dx, -dy); + + RegionNull(&rgnDst); + + RegionIntersect(&rgnDst, + &pWin->borderClip, prgnSrc); + + RegionTranslate(&rgnDst, + -pPixmap->screen_x, -pPixmap->screen_y); + + dx = dx + pPixmap->screen_x - cw->oldx; + dy = dy + pPixmap->screen_y - cw->oldy; + pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); + if (pGC) + { + BoxPtr pBox = RegionRects (&rgnDst); + int nBox = RegionNumRects (&rgnDst); + + ValidateGC(&pPixmap->drawable, pGC); + while (nBox--) + { + (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable, + &pPixmap->drawable, + pGC, + pBox->x1 + dx, pBox->y1 + dy, + pBox->x2 - pBox->x1, + pBox->y2 - pBox->y1, + pBox->x1, pBox->y1); + pBox++; + } + FreeScratchGC (pGC); + } + return; + } + dx = pPixmap->screen_x - cw->oldx; + dy = pPixmap->screen_y - cw->oldy; + ptOldOrg.x += dx; + ptOldOrg.y += dy; + } + + pScreen->CopyWindow = cs->CopyWindow; + if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y) + { + if (dx || dy) + RegionTranslate(prgnSrc, dx, dy); + (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); + if (dx || dy) + RegionTranslate(prgnSrc, -dx, -dy); + } + else + { + ptOldOrg.x -= dx; + ptOldOrg.y -= dy; + RegionTranslate(prgnSrc, + pWin->drawable.x - ptOldOrg.x, + pWin->drawable.y - ptOldOrg.y); + DamageDamageRegion(&pWin->drawable, prgnSrc); + } + cs->CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = compCopyWindow; + compCheckTree (pWin->drawable.pScreen); +} + +Bool +compCreateWindow (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret; + + pScreen->CreateWindow = cs->CreateWindow; + ret = (*pScreen->CreateWindow) (pWin); + if (pWin->parent && ret) + { + CompSubwindowsPtr csw = GetCompSubwindows (pWin->parent); + CompClientWindowPtr ccw; + + (*pScreen->SetWindowPixmap) (pWin, (*pScreen->GetWindowPixmap) (pWin->parent)); + if (csw) + for (ccw = csw->clients; ccw; ccw = ccw->next) + compRedirectWindow (clients[CLIENT_ID(ccw->id)], + pWin, ccw->update); + if (compImplicitRedirect (pWin, pWin->parent)) + compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic); + } + cs->CreateWindow = pScreen->CreateWindow; + pScreen->CreateWindow = compCreateWindow; + compCheckTree (pWin->drawable.pScreen); + return ret; +} + +Bool +compDestroyWindow (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + CompWindowPtr cw; + CompSubwindowsPtr csw; + Bool ret; + + pScreen->DestroyWindow = cs->DestroyWindow; + while ((cw = GetCompWindow (pWin))) + FreeResource (cw->clients->id, RT_NONE); + while ((csw = GetCompSubwindows (pWin))) + FreeResource (csw->clients->id, RT_NONE); + + if (pWin->redirectDraw != RedirectDrawNone) { + PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin); + compSetParentPixmap (pWin); + (*pScreen->DestroyPixmap) (pPixmap); + } + ret = (*pScreen->DestroyWindow) (pWin); + cs->DestroyWindow = pScreen->DestroyWindow; + pScreen->DestroyWindow = compDestroyWindow; +/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/ + return ret; +} + +void +compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion) +{ + CompWindowPtr cw = GetCompWindow (pWin); + RegionRec damage; + + RegionNull(&damage); + /* + * Align old border clip with new border clip + */ + RegionTranslate(&cw->borderClip, + pWin->drawable.x - cw->borderClipX, + pWin->drawable.y - cw->borderClipY); + /* + * Compute newly visible portion of window for repaint + */ + RegionSubtract(&damage, pRegion, &cw->borderClip); + /* + * Report that as damaged so it will be redrawn + */ + DamageDamageRegion(&pWin->drawable, &damage); + RegionUninit(&damage); + /* + * Save the new border clip region + */ + RegionCopy(&cw->borderClip, pRegion); + cw->borderClipX = pWin->drawable.x; + cw->borderClipY = pWin->drawable.y; +} + +RegionPtr +compGetRedirectBorderClip (WindowPtr pWin) +{ + CompWindowPtr cw = GetCompWindow (pWin); + + return &cw->borderClip; +} + +static VisualPtr +compGetWindowVisual (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + VisualID vid = wVisual (pWin); + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + if (pScreen->visuals[i].vid == vid) + return &pScreen->visuals[i]; + return 0; +} + +PictFormatPtr +compWindowFormat (WindowPtr pWin) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + return PictureMatchVisual (pScreen, pWin->drawable.depth, + compGetWindowVisual (pWin)); +} + +static void +compWindowUpdateAutomatic (WindowPtr pWin) +{ + CompWindowPtr cw = GetCompWindow (pWin); + ScreenPtr pScreen = pWin->drawable.pScreen; + WindowPtr pParent = pWin->parent; + PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin); + PictFormatPtr pSrcFormat = compWindowFormat (pWin); + PictFormatPtr pDstFormat = compWindowFormat (pWin->parent); + int error; + RegionPtr pRegion = DamageRegion (cw->damage); + PicturePtr pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable, + pSrcFormat, + 0, 0, + serverClient, + &error); + XID subwindowMode = IncludeInferiors; + PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable, + pDstFormat, + CPSubwindowMode, + &subwindowMode, + serverClient, + &error); + + /* + * First move the region from window to screen coordinates + */ + RegionTranslate(pRegion, + pWin->drawable.x, pWin->drawable.y); + + /* + * Clip against the "real" border clip + */ + RegionIntersect(pRegion, pRegion, &cw->borderClip); + + /* + * Now translate from screen to dest coordinates + */ + RegionTranslate(pRegion, + -pParent->drawable.x, -pParent->drawable.y); + + /* + * Clip the picture + */ + SetPictureClipRegion (pDstPicture, 0, 0, pRegion); + + /* + * And paint + */ + CompositePicture (PictOpSrc, + pSrcPicture, + 0, + pDstPicture, + 0, 0, /* src_x, src_y */ + 0, 0, /* msk_x, msk_y */ + pSrcPixmap->screen_x - pParent->drawable.x, + pSrcPixmap->screen_y - pParent->drawable.y, + pSrcPixmap->drawable.width, + pSrcPixmap->drawable.height); + FreePicture (pSrcPicture, 0); + FreePicture (pDstPicture, 0); + /* + * Empty the damage region. This has the nice effect of + * rendering the translations above harmless + */ + DamageEmpty (cw->damage); +} + +static void +compPaintWindowToParent (WindowPtr pWin) +{ + compPaintChildrenToWindow (pWin); + + if (pWin->redirectDraw != RedirectDrawNone) + { + CompWindowPtr cw = GetCompWindow(pWin); + + if (cw->damaged) + { + compWindowUpdateAutomatic (pWin); + cw->damaged = FALSE; + } + } +} + +void +compPaintChildrenToWindow (WindowPtr pWin) +{ + WindowPtr pChild; + + if (!pWin->damagedDescendants) + return; + + for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) + compPaintWindowToParent (pChild); + + pWin->damagedDescendants = FALSE; +} + +WindowPtr +CompositeRealChildHead (WindowPtr pWin) +{ + WindowPtr pChild, pChildBefore; + CompScreenPtr cs; + + if (!pWin->parent && + (screenIsSaved == SCREEN_SAVER_ON) && + (HasSaverWindow (pWin->drawable.pScreen))) { + + /* First child is the screen saver; see if next child is the overlay */ + pChildBefore = pWin->firstChild; + pChild = pChildBefore->nextSib; + + } else { + pChildBefore = NullWindow; + pChild = pWin->firstChild; + } + + if (!pChild) { + return NullWindow; + } + + cs = GetCompScreen(pWin->drawable.pScreen); + if (pChild == cs->pOverlayWin) { + return pChild; + } else { + return pChildBefore; + } +} + +int +compConfigNotify(WindowPtr pWin, int x, int y, int w, int h, + int bw, WindowPtr pSib) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + CompScreenPtr cs = GetCompScreen (pScreen); + Bool ret = 0; + WindowPtr pParent = pWin->parent; + int draw_x, draw_y; + Bool alloc_ret; + + if (cs->ConfigNotify) + { + pScreen->ConfigNotify = cs->ConfigNotify; + ret = (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib); + cs->ConfigNotify = pScreen->ConfigNotify; + pScreen->ConfigNotify = compConfigNotify; + + if (ret) + return ret; + } + + if (pWin->redirectDraw == RedirectDrawNone) + return Success; + + compCheckTree (pScreen); + + draw_x = pParent->drawable.x + x + bw; + draw_y = pParent->drawable.y + y + bw; + alloc_ret = compReallocPixmap (pWin, draw_x, draw_y, w, h, bw); + + if (alloc_ret == FALSE) + return BadAlloc; + return Success; +} |