xserver/composite compalloc.c,1.10,1.11 compint.h,1.10,1.11
Keith Packard <xserver-commit-u7BhqnqprCWvj1b/[email protected]> Sat, 21 Jan 2006 20:50:17 -0800 (PST)
| Newsgroups | gmane.comp.freedesktop.xserver.cvs |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> * 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;