[xserver-commit] xserver/composite Makefile.am,1.1,1.2 compalloc.c,1.1,1.2 compinit.c,1.2,1.3 compint.h,1.1,1.2 compwindow.c,1.2,1.3
Keith Packard
xserver-commit@pdx.freedesktop.org
Thu, 06 Nov 2003 20:26:10 -0800
Committed by: keithp
Update of /cvs/xserver/xserver/composite
In directory pdx:/tmp/cvs-serv20575/composite
Modified Files:
Makefile.am compalloc.c compinit.c compint.h compwindow.c
Log Message:
* composite/Makefile.am:
* composite/compalloc.c: (compRedirectWindow),
(compFreeClientWindow), (compUnredirectWindow),
(compRedirectSubwindows), (compFreeClientSubwindows),
(compUnredirectSubwindows), (compAllocPixmap), (compFreePixmap):
* composite/compinit.c: (compScreenInit):
* composite/compint.h:
* composite/compwindow.c: (compShouldBeRedirected),
(compCheckRedirect), (compCreateWindow):
* fb/fbwindow.c: (fbCopyWindow):
* xfixes/region.c: (XFixesRegionCopy),
(ProcXFixesCreateRegionFromWindow), (ProcXFixesCreateRegionFromGC),
(ProcXFixesCreateRegionFromPicture), (ProcXFixesSetGCClipRegion),
(ProcXFixesSetWindowShapeRegion):
* xfixes/xfixes.h:
Finish up preliminary Composite extension implementation.
Export XFixesRegionCopy from xfixes for Composite.
Use window pixmap for fbCopyWindow, not root window.
Index: Makefile.am
===================================================================
RCS file: /cvs/xserver/xserver/composite/Makefile.am,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Makefile.am 5 Nov 2003 05:45:30 -0000 1.1
+++ Makefile.am 7 Nov 2003 04:26:08 -0000 1.2
@@ -3,12 +3,14 @@
-I$(top_srcdir)/Xext \
-I$(top_srcdir)/render \
-I$(top_srcdir)/miext/damage \
+ -I$(top_srcdir)/xfixes \
@XSERVER_CFLAGS@
noinst_LIBRARIES = libcomposite.a
libcomposite_a_SOURCES = \
compalloc.c \
+ compext.c \
compint.h \
compinit.c \
compwindow.c
Index: compalloc.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compalloc.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- compalloc.c 5 Nov 2003 05:45:31 -0000 1.1
+++ compalloc.c 7 Nov 2003 04:26:08 -0000 1.2
@@ -46,6 +46,272 @@
cw->damage = 0;
}
+/*
+ * Redirect one window for one client
+ */
+int
+compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+
+ /*
+ * 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,
+ DamageReportRawRegion,
+ FALSE,
+ pWin);
+ if (!cw->damage)
+ {
+ xfree (ccw);
+ xfree (cw);
+ return BadAlloc;
+ }
+ cw->update = CompositeRedirectAutomatic;
+ cw->clients = 0;
+ pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
+ }
+ ccw->next = cw->clients;
+ cw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ cw->update = CompositeRedirectManual;
+
+ if (!compCheckRedirect (pWin))
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return BadAlloc;
+ }
+
+ 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;
+
+ 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)
+ {
+ pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
+
+ (void) compCheckRedirect (pWin);
+
+ if (cw->damage)
+ DamageDestroy (cw->damage);
+ REGION_UNINIT (pScreen, &cw->borderClip);
+ xfree (cw);
+ }
+}
+
+/*
+ * 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;
+ pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 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);
+ pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 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;
+ 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)
+ csw->update = CompositeRedirectAutomatic;
+
+ /*
+ * Unredirect all existing subwindows
+ */
+ for (pChild = pWin->lastChild; pWin; pWin = pWin->prevSib)
+ (void) compUnredirectWindow (pClient, pChild, ccw->update);
+
+ xfree (ccw);
+ break;
+ }
+ }
+
+ /*
+ * Check if all of the per-client records are gone
+ */
+ if (!csw->clients)
+ {
+ pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
+ 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;
+}
+
Bool
compAllocPixmap (WindowPtr pWin)
{
@@ -53,39 +319,20 @@
PixmapPtr pPixmap;
int bw = (int) pWin->borderWidth;
int x, y, w, h;
- CompWindowPtr cw;
+ CompWindowPtr cw = GetCompWindow (pWin);
- cw = xalloc (sizeof (CompWindowRec));
- if (!cw)
- return FALSE;
- cw->damage = DamageCreate (compReportDamage,
- compDestroyDamage,
- DamageReportRawRegion,
- FALSE,
- pWin);
- if (!cw->damage)
- {
- xfree (cw);
- return FALSE;
- }
x = pWin->drawable.x - bw;
y = pWin->drawable.y - bw;
w = pWin->drawable.width + (bw << 1);
h = pWin->drawable.height + (bw << 1);
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
if (!pPixmap)
- {
- DamageDestroy (cw->damage);
- xfree (cw);
return FALSE;
- }
pPixmap->drawable.x = -x;
pPixmap->drawable.y = -y;
pWin->redirectDraw = TRUE;
compSetPixmap (pWin, pPixmap);
REGION_INIT (pScreen, &cw->borderClip, NullBox, 0);
- cw->update = CompositeRedirectAutomatic;
- pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
DamageRegister (&pWin->drawable, cw->damage);
return TRUE;
}
@@ -95,16 +342,7 @@
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pRedirectPixmap, pParentPixmap;
- CompWindowPtr cw = GetCompWindow (pWin);
- REGION_UNINIT (pScreen, &cw->borderClip);
- if (cw->damage)
- {
- DamageUnregister (&pWin->drawable, cw->damage);
- DamageDestroy (cw->damage);
- }
- xfree (cw);
- pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
pWin->redirectDraw = FALSE;
Index: compinit.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compinit.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- compinit.c 5 Nov 2003 06:46:13 -0000 1.2
+++ compinit.c 7 Nov 2003 04:26:08 -0000 1.3
@@ -29,6 +29,7 @@
int CompScreenPrivateIndex;
int CompWindowPrivateIndex;
+int CompSubwindowsPrivateIndex;
int CompGeneration;
static Bool
@@ -81,7 +82,7 @@
pScreen->BlockHandler = compBlockHandler;
}
-static Bool
+Bool
compScreenInit (ScreenPtr pScreen)
{
CompScreenPtr cs;
@@ -94,11 +95,17 @@
CompWindowPrivateIndex = AllocateWindowPrivateIndex ();
if (CompWindowPrivateIndex == -1)
return FALSE;
+ CompSubwindowsPrivateIndex = AllocateWindowPrivateIndex ();
+ if (CompSubwindowsPrivateIndex == -1)
+ return FALSE;
CompGeneration = serverGeneration;
}
if (!AllocateWindowPrivate (pScreen, CompWindowPrivateIndex, 0))
return FALSE;
+ if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivateIndex, 0))
+ return FALSE;
+
if (GetCompScreen (pScreen))
return TRUE;
cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec));
@@ -135,16 +142,3 @@
pScreen->devPrivates[CompScreenPrivateIndex].ptr = (pointer) cs;
return TRUE;
}
-
-void
-CompositeExtensionInit (void)
-{
- int s;
-
- if (!getenv ("XCOMPOSITE"))
- return;
- for (s = 0; s < screenInfo.numScreens; s++)
- if (!compScreenInit (screenInfo.screens[s]))
- return;
- miRegisterRedirectBorderClipProc (compRedirectBorderClip);
-}
Index: compint.h
===================================================================
RCS file: /cvs/xserver/xserver/composite/compint.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- compint.h 5 Nov 2003 05:45:31 -0000 1.1
+++ compint.h 7 Nov 2003 04:26:08 -0000 1.2
@@ -40,16 +40,31 @@
#include "servermd.h"
#include "dixevents.h"
#include "globals.h"
+#include "picturestr.h"
+#include "extnsionst.h"
#include "mi.h"
#include "damage.h"
+#include "xfixes.h"
#include <X11/extensions/compositeproto.h>
+typedef struct _CompClientWindow {
+ struct _CompClientWindow *next;
+ XID id;
+ int update;
+} CompClientWindowRec, *CompClientWindowPtr;
+
typedef struct _CompWindow {
RegionRec borderClip;
- DamagePtr damage;
+ DamagePtr damage; /* for automatic update mode */
int update;
+ CompClientWindowPtr clients;
} CompWindowRec, *CompWindowPtr;
+typedef struct _CompSubwindows {
+ int update;
+ CompClientWindowPtr clients;
+} CompSubwindowsRec, *CompSubwindowsPtr;
+
extern int CompPixmapPrivateIndex;
typedef struct _CompScreen {
@@ -71,27 +86,75 @@
extern int CompScreenPrivateIndex;
extern int CompWindowPrivateIndex;
+extern int CompSubwindowsPrivateIndex;
#define GetCompScreen(s) ((CompScreenPtr) ((s)->devPrivates[CompScreenPrivateIndex].ptr))
#define GetCompWindow(w) ((CompWindowPtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
+#define GetCompSubwindows(w) ((CompSubwindowsPtr) ((w)->devPrivates[CompSubwindowsPrivateIndex].ptr))
+
+extern RESTYPE CompositeClientWindowType;
+extern RESTYPE CompositeClientSubwindowsType;
+
+/*
+ * compalloc.c
+ */
+
+Bool
+compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
void
-compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
+compFreeClientWindow (WindowPtr pWin, XID id);
+
+int
+compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
+
+int
+compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
void
-compCheckTree (ScreenPtr pScreen);
+compFreeClientSubwindows (WindowPtr pWin, XID id);
+
+int
+compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
Bool
-compPositionWindow (WindowPtr pWin, int x, int y);
+compAllocPixmap (WindowPtr pWin);
void
-compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+compFreePixmap (WindowPtr pWin);
Bool
-compCreateWindow (WindowPtr pWin);
+compReallocPixmap (WindowPtr pWin);
+
+/*
+ * compext.c
+ */
+
+void
+CompositeExtensionInit (void);
+
+/*
+ * compinit.c
+ */
Bool
-compDestroyWindow (WindowPtr pWin);
+compScreenInit (ScreenPtr pScreen);
+
+/*
+ * compwindow.c
+ */
+
+void
+compCheckTree (ScreenPtr pScreen);
+
+void
+compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
+
+Bool
+compCheckRedirect (WindowPtr pWin);
+
+Bool
+compPositionWindow (WindowPtr pWin, int x, int y);
Bool
compRealizeWindow (WindowPtr pWin);
@@ -102,22 +165,19 @@
void
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
-void
-compWindowUpdate (WindowPtr pWin);
-
-void
-compRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
-
Bool
-compReallocPixmap (WindowPtr pWin);
+compCreateWindow (WindowPtr pWin);
Bool
-compAllocPixmap (WindowPtr pWin);
+compDestroyWindow (WindowPtr pWin);
void
-compFreePixmap (WindowPtr pWin);
+compRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
void
-CompositeExtensionInit (void);
+compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+
+void
+compWindowUpdate (WindowPtr pWin);
#endif /* _COMPINT_H_ */
Index: compwindow.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compwindow.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- compwindow.c 5 Nov 2003 06:46:13 -0000 1.2
+++ compwindow.c 7 Nov 2003 04:26:08 -0000 1.3
@@ -26,7 +26,6 @@
#include <config.h>
#endif
#include "compint.h"
-#include "picturestr.h"
#undef NDEBUG
#include <assert.h>
@@ -85,14 +84,13 @@
static Bool
compShouldBeRedirected (WindowPtr pWin)
{
- /* XXX static policy during development - redirect children of root */
- return pWin->viewable && pWin->parent && !pWin->parent->parent;
+ return pWin->viewable && GetCompWindow (pWin);
}
-static Bool
+Bool
compCheckRedirect (WindowPtr pWin)
{
- Bool should = compShouldBeRedirected (pWin);
+ Bool should = compShouldBeRedirected (pWin);
if (should != pWin->redirectDraw)
{
@@ -194,14 +192,23 @@
Bool
compCreateWindow (WindowPtr pWin)
{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- Bool ret;
+ 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);
+ }
cs->CreateWindow = pScreen->CreateWindow;
pScreen->CreateWindow = compCreateWindow;
compCheckTree (pWin->drawable.pScreen);