xserver/composite compalloc.c,1.10,1.11 compint.h,1.10,1.11
Keith Packard
xserver-commit at pdx.freedesktop.org
Sat Jan 21 20:50:17 PST 2006
Committed by: keithp
Update of /cvs/xserver/xserver/composite
In directory gabe:/tmp/cvs-serv21727/composite
Modified Files:
compalloc.c compint.h
Log Message:
2006-01-21 Keith Packard <keithp at keithp.com>
* composite/compalloc.c: (compEnsureWindowPrivate),
(compCheckWindowPrivateNeeded), (compSaveBeforeRedirect),
(compRestoreAfterRedirect), (compRedirectWindow),
(compFreeClientWindow), (compRedirectSubwindows),
(compFreeClientSubwindows):
* composite/compint.h:
Eliminate one of the two WindowPrivate indices to save
memory in unredirected windows.
Clear StructureNotify and SubstructureNotify bits as necessary
to avoid delivering MapNotify/UnmapNotify events during
redirect allocation/deallocation.
Index: compalloc.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compalloc.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- compalloc.c 8 Feb 2005 22:39:20 -0000 1.10
+++ compalloc.c 22 Jan 2006 04:50:15 -0000 1.11
@@ -48,6 +48,113 @@
cw->damage = 0;
}
+static CompWindowPrivatePtr
+compEnsureWindowPrivate (WindowPtr pWin)
+{
+ CompWindowPrivatePtr cwp = GetCompWindowPrivate(pWin);
+
+ if (!cwp)
+ {
+ cwp = xalloc (sizeof (CompWindowPrivateRec));
+ if (!cwp)
+ return NULL;
+ cwp->window = NULL;
+ cwp->subwindows = NULL;
+ pWin->devPrivates[CompWindowPrivateIndex].ptr = cwp;
+ }
+ return cwp;
+}
+
+static void
+compCheckWindowPrivateNeeded (WindowPtr pWin)
+{
+ CompWindowPrivatePtr cwp = GetCompWindowPrivate(pWin);
+
+ if (cwp)
+ {
+ if (cwp->window == NULL &&
+ cwp->subwindows == NULL)
+ {
+ pWin->devPrivates[CompWindowPrivateIndex].ptr = NULL;
+ xfree (cwp);
+ }
+ }
+}
+
+typedef struct {
+ Bool overrideRedirect;
+ Mask selfEventMask;
+ Mask selfOtherEventMasks;
+ Mask parentEventMask;
+ Mask parentOtherEventMasks;
+} CompRedirectPreserveRec, *CompRedirectPreservePtr;
+
+static void
+compSaveBeforeRedirect (WindowPtr pWin, CompRedirectPreservePtr pPreserve)
+{
+ WindowPtr pParent = pWin->parent;
+
+ /* OverrideRedirect TRUE */
+ pPreserve->overrideRedirect = pWin->overrideRedirect;
+ pWin->overrideRedirect = TRUE;
+
+ /* Disable StructureNotify on self */
+ pPreserve->selfEventMask = pWin->eventMask;
+ pWin->eventMask &= ~StructureNotifyMask;
+ if (pWin->optional)
+ {
+ pPreserve->selfOtherEventMasks = pWin->optional->otherEventMasks;
+ pWin->optional->otherEventMasks &= ~StructureNotifyMask;
+ }
+ else
+ pPreserve->selfOtherEventMasks = 0;
+
+ /* Disable SubstructureNotify on parent */
+ if (pParent)
+ {
+ pPreserve->parentEventMask = pParent->eventMask;
+ pParent->eventMask &= ~SubstructureNotifyMask;
+ if (pParent->optional)
+ {
+ pPreserve->parentOtherEventMasks = pParent->optional->otherEventMasks;
+ pParent->optional->otherEventMasks &= ~SubstructureNotifyMask;
+ }
+ else
+ pPreserve->parentOtherEventMasks = 0;
+ }
+}
+
+static Bool
+compRestoreAfterRedirect (WindowPtr pWin, CompRedirectPreservePtr pPreserve)
+{
+ WindowPtr pParent = pWin->parent;
+
+ /* OverrideRedirect */
+ pWin->overrideRedirect = pPreserve->overrideRedirect;
+
+ /* EventMask */
+ pWin->eventMask = pPreserve->selfEventMask;
+ if (pPreserve->selfOtherEventMasks)
+ {
+ if (!MakeWindowOptional (pWin))
+ return FALSE;
+ pWin->optional->otherEventMasks = pPreserve->selfOtherEventMasks;
+ }
+
+ /* Parent event mask */
+ if (pParent)
+ {
+ pParent->eventMask = pPreserve->parentEventMask;
+ if (pPreserve->parentOtherEventMasks)
+ {
+ if (!MakeWindowOptional (pParent))
+ return FALSE;
+ pParent->optional->otherEventMasks = pPreserve->parentOtherEventMasks;
+ }
+ }
+ return TRUE;
+}
+
/*
* Redirect one window for one client
*/
@@ -57,6 +164,7 @@
CompWindowPtr cw = GetCompWindow (pWin);
CompClientWindowPtr ccw;
Bool wasMapped = pWin->mapped;
+ CompRedirectPreserveRec preserve;
/*
* Only one Manual update is allowed
@@ -81,10 +189,16 @@
*/
if (!cw)
{
+ CompWindowPrivatePtr cwp = compEnsureWindowPrivate (pWin);
+ if (!cwp) {
+ xfree (ccw);
+ return BadAlloc;
+ }
cw = xalloc (sizeof (CompWindowRec));
if (!cw)
{
xfree (ccw);
+ compCheckWindowPrivateNeeded (pWin);
return BadAlloc;
}
cw->damage = DamageCreate (compReportDamage,
@@ -97,10 +211,16 @@
{
xfree (ccw);
xfree (cw);
+ compCheckWindowPrivateNeeded (pWin);
return BadAlloc;
}
if (wasMapped)
+ {
+ compSaveBeforeRedirect (pWin, &preserve);
UnmapWindow (pWin, FALSE);
+ if (!compRestoreAfterRedirect (pWin, &preserve))
+ return BadAlloc;
+ }
REGION_NULL (pScreen, &cw->borderClip);
cw->update = CompositeRedirectAutomatic;
@@ -109,7 +229,7 @@
cw->oldy = COMP_ORIGIN_INVALID;
cw->damageRegistered = FALSE;
cw->damaged = FALSE;
- pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
+ cwp->window = cw;
}
ccw->next = cw->clients;
cw->clients = ccw;
@@ -132,10 +252,10 @@
}
if (wasMapped && !pWin->mapped)
{
- Bool overrideRedirect = pWin->overrideRedirect;
- pWin->overrideRedirect = TRUE;
+ compSaveBeforeRedirect (pWin, &preserve);
MapWindow (pWin, pClient);
- pWin->overrideRedirect = overrideRedirect;
+ if (!compRestoreAfterRedirect (pWin, &preserve))
+ return BadAlloc;
}
return Success;
@@ -148,10 +268,15 @@
void
compFreeClientWindow (WindowPtr pWin, XID id)
{
- CompWindowPtr cw = GetCompWindow (pWin);
+ CompWindowPrivatePtr cwp = GetCompWindowPrivate (pWin);
+ CompWindowPtr cw;
CompClientWindowPtr ccw, *prev;
Bool wasMapped = pWin->mapped;
+ CompRedirectPreserveRec preserve;
+ if (!cwp)
+ return;
+ cw = cwp->window;
if (!cw)
return;
for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
@@ -168,7 +293,12 @@
if (!cw->clients)
{
if (wasMapped)
+ {
+ compSaveBeforeRedirect (pWin, &preserve);
UnmapWindow (pWin, FALSE);
+ (void) compRestoreAfterRedirect (pWin, &preserve);
+
+ }
if (pWin->redirectDraw)
compFreePixmap (pWin);
@@ -178,8 +308,9 @@
REGION_UNINIT (pScreen, &cw->borderClip);
- pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
+ cwp->window = NULL;
xfree (cw);
+ compCheckWindowPrivateNeeded (pWin);
}
else if (cw->update == CompositeRedirectAutomatic &&
!cw->damageRegistered && pWin->redirectDraw)
@@ -190,10 +321,9 @@
}
if (wasMapped && !pWin->mapped)
{
- Bool overrideRedirect = pWin->overrideRedirect;
- pWin->overrideRedirect = TRUE;
+ compSaveBeforeRedirect (pWin, &preserve);
MapWindow (pWin, clients[CLIENT_ID(id)]);
- pWin->overrideRedirect = overrideRedirect;
+ (void) compRestoreAfterRedirect (pWin, &preserve);
}
}
@@ -229,6 +359,7 @@
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
CompClientWindowPtr ccw;
WindowPtr pChild;
+ CompWindowPrivatePtr cwp;
/*
* Only one Manual update is allowed
@@ -250,17 +381,24 @@
/*
* Now make sure there's a per-window structure to hang this from
*/
+ cwp = compEnsureWindowPrivate (pWin);
if (!csw)
{
+ if (!cwp)
+ {
+ xfree (ccw);
+ return BadAlloc;
+ }
csw = xalloc (sizeof (CompSubwindowsRec));
if (!csw)
{
+ compCheckWindowPrivateNeeded (pWin);
xfree (ccw);
return BadAlloc;
}
csw->update = CompositeRedirectAutomatic;
csw->clients = 0;
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = csw;
+ cwp->subwindows = csw;
}
/*
* Redirect all existing windows
@@ -275,7 +413,8 @@
if (!csw->clients)
{
xfree (csw);
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
+ cwp->subwindows = NULL;
+ compCheckWindowPrivateNeeded (pWin);
}
xfree (ccw);
return ret;
@@ -307,10 +446,13 @@
void
compFreeClientSubwindows (WindowPtr pWin, XID id)
{
- CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompWindowPrivatePtr cwp = GetCompWindowPrivate (pWin);
+ CompSubwindowsPtr csw = cwp ? cwp->subwindows : NULL;
CompClientWindowPtr ccw, *prev;
WindowPtr pChild;
+ if (!cwp)
+ return;
if (!csw)
return;
for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
@@ -348,8 +490,9 @@
*/
if (!csw->clients)
{
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
xfree (csw);
+ cwp->subwindows = NULL;
+ compCheckWindowPrivateNeeded (pWin);
}
}
Index: compint.h
===================================================================
RCS file: /cvs/xserver/xserver/composite/compint.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- compint.h 8 Feb 2005 22:39:20 -0000 1.10
+++ compint.h 22 Jan 2006 04:50:15 -0000 1.11
@@ -59,7 +59,7 @@
struct _CompClientWindow *next;
XID id;
int update;
-} CompClientWindowRec, *CompClientWindowPtr;
+} CompClientWindowRec, *CompClientWindowPtr;
typedef struct _CompWindow {
RegionRec borderClip;
@@ -81,6 +81,11 @@
CompClientWindowPtr clients;
} CompSubwindowsRec, *CompSubwindowsPtr;
+typedef struct _CompWindowPrivate {
+ CompWindowPtr window;
+ CompSubwindowsPtr subwindows;
+} CompWindowPrivateRec, *CompWindowPrivatePtr;
+
#ifndef COMP_INCLUDE_RGB24_VISUAL
#define COMP_INCLUDE_RGB24_VISUAL 0
#endif
@@ -126,11 +131,11 @@
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))
+#define GetCompWindowPrivate(w) ((CompWindowPrivatePtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
+#define GetCompWindow(w) (GetCompWindowPrivate(w) ? GetCompWindowPrivate(w)->window : NULL)
+#define GetCompSubwindows(w) (GetCompWindowPrivate(w) ? GetCompWindowPrivate(w)->subwindows : NULL)
extern RESTYPE CompositeClientWindowType;
extern RESTYPE CompositeClientSubwindowsType;
More information about the xserver-commit
mailing list