Abstract cursor refcounting

Too many callers relied on the refcnt being handled correctly. Use a simple
wrapper to handle that case.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2013-05-15 19:01:11 +10:00
parent 35c2e263db
commit 9a5ad65330
10 changed files with 73 additions and 56 deletions

View File

@ -531,15 +531,16 @@ CreateSaverWindow(ScreenPtr pScreen)
mask |= CWBorderPixmap; mask |= CWBorderPixmap;
} }
if (pAttr->pCursor) { if (pAttr->pCursor) {
CursorPtr cursor;
if (!pWin->optional) if (!pWin->optional)
if (!MakeWindowOptional(pWin)) { if (!MakeWindowOptional(pWin)) {
FreeResource(pWin->drawable.id, RT_NONE); FreeResource(pWin->drawable.id, RT_NONE);
return FALSE; return FALSE;
} }
pAttr->pCursor->refcnt++; cursor = RefCursor(pAttr->pCursor);
if (pWin->optional->cursor) if (pWin->optional->cursor)
FreeCursor(pWin->optional->cursor, (Cursor) 0); FreeCursor(pWin->optional->cursor, (Cursor) 0);
pWin->optional->cursor = pAttr->pCursor; pWin->optional->cursor = cursor;
pWin->cursorIsNone = FALSE; pWin->cursorIsNone = FALSE;
CheckWindowOptionalNeed(pWin); CheckWindowOptionalNeed(pWin);
mask |= CWCursor; mask |= CWCursor;
@ -1065,8 +1066,7 @@ ScreenSaverSetAttributes(ClientPtr client)
client->errorValue = cursorID; client->errorValue = cursorID;
goto PatchUp; goto PatchUp;
} }
pCursor->refcnt++; pAttr->pCursor = RefCursor(pCursor);
pAttr->pCursor = pCursor;
pAttr->mask &= ~CWCursor; pAttr->mask &= ~CWCursor;
} }
break; break;

View File

@ -114,9 +114,13 @@ FreeCursor(pointer value, XID cid)
ScreenPtr pscr; ScreenPtr pscr;
DeviceIntPtr pDev = NULL; /* unused anyway */ DeviceIntPtr pDev = NULL; /* unused anyway */
if (--pCurs->refcnt != 0)
UnrefCursor(pCurs);
if (CursorRefCount(pCurs) != 0)
return Success; return Success;
BUG_WARN(CursorRefCount(pCurs) < 0);
for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
pscr = screenInfo.screens[nscr]; pscr = screenInfo.screens[nscr];
(void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); (void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs);
@ -127,6 +131,33 @@ FreeCursor(pointer value, XID cid)
return Success; return Success;
} }
CursorPtr
RefCursor(CursorPtr cursor)
{
ErrorF("%s ::::: cursor is %p", __func__, cursor);
if (cursor) {
xorg_backtrace();
cursor->refcnt++;
}
ErrorF("\n");
return cursor;
}
CursorPtr
UnrefCursor(CursorPtr cursor)
{
if (cursor)
cursor->refcnt--;
return cursor;
}
int
CursorRefCount(const CursorPtr cursor)
{
return cursor ? cursor->refcnt : 0;
}
/* /*
* We check for empty cursors so that we won't have to display them * We check for empty cursors so that we won't have to display them
*/ */

View File

@ -931,8 +931,7 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
(*pScreen->DisplayCursor) (pDev, pScreen, cursor); (*pScreen->DisplayCursor) (pDev, pScreen, cursor);
FreeCursor(pSprite->current, (Cursor) 0); FreeCursor(pSprite->current, (Cursor) 0);
pSprite->current = cursor; pSprite->current = RefCursor(cursor);
pSprite->current->refcnt++;
} }
} }
@ -3210,11 +3209,10 @@ InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
pSprite->pEnqueueScreen = screenInfo.screens[0]; pSprite->pEnqueueScreen = screenInfo.screens[0];
pSprite->pDequeueScreen = pSprite->pEnqueueScreen; pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
} }
if (pCursor) pCursor = RefCursor(pCursor);
pCursor->refcnt++;
if (pSprite->current) if (pSprite->current)
FreeCursor(pSprite->current, None); FreeCursor(pSprite->current, None);
pSprite->current = pCursor; pSprite->current = RefCursor(pCursor);
if (pScreen) { if (pScreen) {
(*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current); (*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
@ -3293,9 +3291,7 @@ UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
pSprite->hotLimits.x2 = pScreen->width; pSprite->hotLimits.x2 = pScreen->width;
pSprite->hotLimits.y2 = pScreen->height; pSprite->hotLimits.y2 = pScreen->height;
pSprite->win = win; pSprite->win = win;
pCursor = wCursor(win); pCursor = RefCursor(wCursor(win));
if (pCursor)
pCursor->refcnt++;
if (pSprite->current) if (pSprite->current)
FreeCursor(pSprite->current, 0); FreeCursor(pSprite->current, 0);
pSprite->current = pCursor; pSprite->current = pCursor;
@ -4945,9 +4941,7 @@ ProcChangeActivePointerGrab(ClientPtr client)
(CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER)) (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
return Success; return Success;
oldCursor = grab->cursor; oldCursor = grab->cursor;
grab->cursor = newCursor; grab->cursor = RefCursor(newCursor);
if (newCursor)
newCursor->refcnt++;
PostNewCursor(device); PostNewCursor(device);
if (oldCursor) if (oldCursor)
FreeCursor(oldCursor, (Cursor) 0); FreeCursor(oldCursor, (Cursor) 0);
@ -5092,9 +5086,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
else else
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask); xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
tempGrab->device = dev; tempGrab->device = dev;
tempGrab->cursor = cursor; tempGrab->cursor = RefCursor(cursor);
if (cursor)
tempGrab->cursor->refcnt++;
tempGrab->confineTo = confineTo; tempGrab->confineTo = confineTo;
tempGrab->grabtype = grabtype; tempGrab->grabtype = grabtype;
(*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE); (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);

View File

@ -241,13 +241,11 @@ CreateGrab(int client, DeviceIntPtr device, DeviceIntPtr modDevice,
grab->detail.exact = keybut; grab->detail.exact = keybut;
grab->detail.pMask = NULL; grab->detail.pMask = NULL;
grab->confineTo = confineTo; grab->confineTo = confineTo;
grab->cursor = cursor; grab->cursor = RefCursor(cursor);
grab->next = NULL; grab->next = NULL;
if (grabtype == XI2) if (grabtype == XI2)
xi2mask_merge(grab->xi2mask, mask->xi2mask); xi2mask_merge(grab->xi2mask, mask->xi2mask);
if (cursor)
cursor->refcnt++;
return grab; return grab;
} }
@ -274,9 +272,6 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
Mask *details_mask = NULL; Mask *details_mask = NULL;
XI2Mask *xi2mask; XI2Mask *xi2mask;
if (src->cursor)
src->cursor->refcnt++;
if (src->modifiersDetail.pMask) { if (src->modifiersDetail.pMask) {
int len = MasksPerDetailMask * sizeof(Mask); int len = MasksPerDetailMask * sizeof(Mask);
@ -314,6 +309,7 @@ CopyGrab(GrabPtr dst, const GrabPtr src)
dst->modifiersDetail.pMask = mdetails_mask; dst->modifiersDetail.pMask = mdetails_mask;
dst->detail.pMask = details_mask; dst->detail.pMask = details_mask;
dst->xi2mask = xi2mask; dst->xi2mask = xi2mask;
dst->cursor = RefCursor(src->cursor);
xi2mask_merge(dst->xi2mask, src->xi2mask); xi2mask_merge(dst->xi2mask, src->xi2mask);

View File

@ -547,8 +547,7 @@ InitRootWindow(WindowPtr pWin)
(*pScreen->PositionWindow) (pWin, 0, 0); (*pScreen->PositionWindow) (pWin, 0, 0);
pWin->cursorIsNone = FALSE; pWin->cursorIsNone = FALSE;
pWin->optional->cursor = rootCursor; pWin->optional->cursor = RefCursor(rootCursor);
rootCursor->refcnt++;
if (party_like_its_1989) { if (party_like_its_1989) {
MakeRootTile(pWin); MakeRootTile(pWin);
@ -1416,8 +1415,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
else if (pWin->parent && pCursor == wCursor(pWin->parent)) else if (pWin->parent && pCursor == wCursor(pWin->parent))
checkOptional = TRUE; checkOptional = TRUE;
pOldCursor = pWin->optional->cursor; pOldCursor = pWin->optional->cursor;
pWin->optional->cursor = pCursor; pWin->optional->cursor = RefCursor(pCursor);
pCursor->refcnt++;
pWin->cursorIsNone = FALSE; pWin->cursorIsNone = FALSE;
/* /*
* check on any children now matching the new cursor * check on any children now matching the new cursor
@ -3323,8 +3321,7 @@ MakeWindowOptional(WindowPtr pWin)
parentOptional = FindWindowWithOptional(pWin)->optional; parentOptional = FindWindowWithOptional(pWin)->optional;
optional->visual = parentOptional->visual; optional->visual = parentOptional->visual;
if (!pWin->cursorIsNone) { if (!pWin->cursorIsNone) {
optional->cursor = parentOptional->cursor; optional->cursor = RefCursor(parentOptional->cursor);
optional->cursor->refcnt++;
} }
else { else {
optional->cursor = None; optional->cursor = None;
@ -3412,8 +3409,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor)) if (pCursor && WindowParentHasDeviceCursor(pWin, pDev, pCursor))
pNode->cursor = None; pNode->cursor = None;
else { else {
pNode->cursor = pCursor; pNode->cursor = RefCursor(pCursor);
pCursor->refcnt++;
} }
pNode = pPrev = NULL; pNode = pPrev = NULL;
@ -3421,8 +3417,7 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) { for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) { if (WindowSeekDeviceCursor(pChild, pDev, &pNode, &pPrev)) {
if (pNode->cursor == None) { /* inherited from parent */ if (pNode->cursor == None) { /* inherited from parent */
pNode->cursor = pOldCursor; pNode->cursor = RefCursor(pOldCursor);
pOldCursor->refcnt++;
} }
else if (pNode->cursor == pCursor) { else if (pNode->cursor == pCursor) {
pNode->cursor = None; pNode->cursor = None;

View File

@ -481,7 +481,7 @@ xf86_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
++cursor->refcnt; cursor = RefCursor(cursor);
if (xf86_config->cursor) if (xf86_config->cursor)
FreeCursor(xf86_config->cursor, None); FreeCursor(xf86_config->cursor, None);
xf86_config->cursor = cursor; xf86_config->cursor = cursor;
@ -500,7 +500,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
++cursor->refcnt; cursor = RefCursor(cursor);
if (xf86_config->cursor) if (xf86_config->cursor)
FreeCursor(xf86_config->cursor, None); FreeCursor(xf86_config->cursor, None);
xf86_config->cursor = cursor; xf86_config->cursor = cursor;

View File

@ -271,7 +271,7 @@ xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
xf86CursorScreenKey); xf86CursorScreenKey);
if (pCurs->refcnt <= 1) if (CursorRefCount(pCurs) <= 1)
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen, dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
NULL); NULL);
@ -285,7 +285,7 @@ xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
(xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates, (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
xf86CursorScreenKey); xf86CursorScreenKey);
if (pCurs->refcnt <= 1) { if (CursorRefCount(pCurs) <= 1) {
free(dixLookupScreenPrivate free(dixLookupScreenPrivate
(&pCurs->devPrivates, CursorScreenKey, pScreen)); (&pCurs->devPrivates, CursorScreenKey, pScreen));
dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen, dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
@ -322,37 +322,37 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
/* only update for VCP, otherwise we get cursor jumps when removing a /* only update for VCP, otherwise we get cursor jumps when removing a
sprite. The second cursor is never HW rendered anyway. */ sprite. The second cursor is never HW rendered anyway. */
if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) { if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer) {
pCurs->refcnt++; CursorPtr cursor = RefCursor(pCurs);
if (ScreenPriv->CurrentCursor) if (ScreenPriv->CurrentCursor)
FreeCursor(ScreenPriv->CurrentCursor, None); FreeCursor(ScreenPriv->CurrentCursor, None);
ScreenPriv->CurrentCursor = pCurs; ScreenPriv->CurrentCursor = cursor;
ScreenPriv->x = x; ScreenPriv->x = x;
ScreenPriv->y = y; ScreenPriv->y = y;
ScreenPriv->CursorToRestore = NULL; ScreenPriv->CursorToRestore = NULL;
ScreenPriv->HotX = pCurs->bits->xhot; ScreenPriv->HotX = cursor->bits->xhot;
ScreenPriv->HotY = pCurs->bits->yhot; ScreenPriv->HotY = cursor->bits->yhot;
if (!infoPtr->pScrn->vtSema) if (!infoPtr->pScrn->vtSema)
ScreenPriv->SavedCursor = pCurs; ScreenPriv->SavedCursor = cursor;
if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) && if (infoPtr->pScrn->vtSema && xorg_list_is_empty(&pScreen->pixmap_dirty_list) &&
(ScreenPriv->ForceHWCursorCount || (ScreenPriv->ForceHWCursorCount ||
(( ((
#ifdef ARGB_CURSOR #ifdef ARGB_CURSOR
pCurs->bits->argb && cursor->bits->argb &&
infoPtr->UseHWCursorARGB && infoPtr->UseHWCursorARGB &&
(*infoPtr->UseHWCursorARGB)(pScreen, pCurs)) || (*infoPtr->UseHWCursorARGB)(pScreen, cursor)) ||
(pCurs->bits->argb == 0 && (cursor->bits->argb == 0 &&
#endif #endif
(pCurs->bits->height <= infoPtr->MaxHeight) && (cursor->bits->height <= infoPtr->MaxHeight) &&
(pCurs->bits->width <= infoPtr->MaxWidth) && (cursor->bits->width <= infoPtr->MaxWidth) &&
(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, pCurs)))))) { (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor) (pScreen, cursor)))))) {
if (ScreenPriv->SWCursor) /* remove the SW cursor */ if (ScreenPriv->SWCursor) /* remove the SW cursor */
(*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen,
NullCursor, x, y); NullCursor, x, y);
xf86SetCursor(pScreen, pCurs, x, y); xf86SetCursor(pScreen, cursor, x, y);
ScreenPriv->SWCursor = FALSE; ScreenPriv->SWCursor = FALSE;
ScreenPriv->isUp = TRUE; ScreenPriv->isUp = TRUE;

View File

@ -71,6 +71,10 @@ extern _X_EXPORT CursorPtr rootCursor;
extern _X_EXPORT int FreeCursor(pointer /*pCurs */ , extern _X_EXPORT int FreeCursor(pointer /*pCurs */ ,
XID /*cid */ ); XID /*cid */ );
extern _X_EXPORT CursorPtr RefCursor(CursorPtr /* cursor */);
extern _X_EXPORT CursorPtr UnrefCursor(CursorPtr /* cursor */);
extern _X_EXPORT int CursorRefCount(const CursorPtr /* cursor */);
extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ , extern _X_EXPORT int AllocARGBCursor(unsigned char * /*psrcbits */ ,
unsigned char * /*pmaskbits */ , unsigned char * /*pmaskbits */ ,
CARD32 * /*argb */ , CARD32 * /*argb */ ,

View File

@ -383,8 +383,7 @@ AnimCursorCreate(CursorPtr *cursors, CARD32 *deltas, int ncursor,
ac->elts = (AnimCurElt *) (ac + 1); ac->elts = (AnimCurElt *) (ac + 1);
for (i = 0; i < ncursor; i++) { for (i = 0; i < ncursor; i++) {
cursors[i]->refcnt++; ac->elts[i].pCursor = RefCursor(cursors[i]);
ac->elts[i].pCursor = cursors[i];
ac->elts[i].delay = deltas[i]; ac->elts[i].delay = deltas[i];
} }

View File

@ -613,12 +613,12 @@ ReplaceCursorLookup(pointer value, XID id, pointer closure)
} }
if (pCursor && pCursor != rcl->pNew) { if (pCursor && pCursor != rcl->pNew) {
if ((*rcl->testCursor) (pCursor, rcl->closure)) { if ((*rcl->testCursor) (pCursor, rcl->closure)) {
rcl->pNew->refcnt++; CursorPtr curs = RefCursor(rcl->pNew);
/* either redirect reference or update resource database */ /* either redirect reference or update resource database */
if (pCursorRef) if (pCursorRef)
*pCursorRef = rcl->pNew; *pCursorRef = curs;
else else
ChangeResourceValue(id, RT_CURSOR, rcl->pNew); ChangeResourceValue(id, RT_CURSOR, curs);
FreeCursor(pCursor, cursor); FreeCursor(pCursor, cursor);
} }
} }