// -------------------------------------------------------------------------------------- void ReleaseIconListIcons(ListHandle iconList) { short dataLength; IconListCellDataRec cellData; Cell theCell; UInt16 referenceCount; Boolean needRelease = false; dataLength = sizeof(IconListCellDataRec); SetPt(&theCell, 0, 0); LGetCell(&cellData, &dataLength, theCell, iconList); GetIconRefOwners(cellData.icon, &referenceCount); if (referenceCount == 1) // if this is the last instance of the { // IconRefs we should unregister them OSType iconType; /* UnregisterIconRef doesn't decrement the reference count on some versions of Mac OS X (it does on 10.1.5, doesn't on 10.2.8, and does on 10.3.4). To account for this we will retain/acquire the icon, unregister it, then check the reference/owner count. If it's the same then we will also release the icons. We can't release the icons first or UnregisterIconRef will return noSuchIconErr (because the icons will already be disposed). Likewise we can't just release the icons afterwards because they may get disposed of when they're unregistered. */ AcquireIconRef(cellData.icon); for (iconType = 'LIc0'; iconType <= 'LIc9'; iconType++) UnregisterIconRef(kAppSignature, iconType); gIconsRegistered = false; GetIconRefOwners(cellData.icon, &referenceCount); if (referenceCount > 1) needRelease = true; ReleaseIconRef(cellData.icon); } else // otherwise simply release the icons needRelease = true; if (needRelease) { short rowNumber; ReleaseIconRef(cellData.icon); for (rowNumber = 1; rowNumber < kNumberOfRows; rowNumber++) { dataLength = sizeof(IconListCellDataRec); SetPt(&theCell, 0, rowNumber); LGetCell(&cellData, &dataLength, theCell, iconList); ReleaseIconRef(cellData.icon); } } }
static PyObject *Icn_GetIconRefOwners(PyObject *_self, PyObject *_args) { PyObject *_res = NULL; OSErr _err; IconRef theIconRef; UInt16 owners; #ifndef GetIconRefOwners PyMac_PRECHECK(GetIconRefOwners); #endif if (!PyArg_ParseTuple(_args, "O&", ResObj_Convert, &theIconRef)) return NULL; _err = GetIconRefOwners(theIconRef, &owners); if (_err != noErr) return PyMac_Error(_err); _res = Py_BuildValue("H", owners); return _res; }
// -------------------------------------------------------------------------------------- void ReleaseIconDataBrowserItemData(ControlRef iconDataBrowser) { Handle itemsHandle; DataBrowserItemID *items; int itemNumber; IconDBItemDataRec *itemsData[kNumberOfRows]; UInt16 referenceCount; Boolean needRelease = false; itemsHandle = NewHandle(0); // GetDataBrowserItems will resize this for us GetDataBrowserItems(iconDataBrowser, kDataBrowserNoItem, false, kDataBrowserItemAnyState, itemsHandle); /* At this point we have the following: Handle -> Pointer -> DataBrowserItemID[] In our icon data browser, DataBrowserItemID = IconDBItemDataRec pointer So that means we have: Handle -> Pointer -> IconDBItemDataRec pointer -> IconDBItemDataRec */ HLockHi(itemsHandle); // since we're about to dereference this, we need it to stay put items = (DataBrowserItemID *)*itemsHandle; /* While this is technically unnecessary, it will save us a lot of awkward multiple dereferencings and generally make things much easier to read. */ for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) itemsData[itemNumber] = (IconDBItemDataRec *)*(items + itemNumber); GetIconRefOwners((itemsData[0])->icon, &referenceCount); // first, unregister and/or release the icons if (referenceCount == 1) // if this is the last instance of the { // IconRefs we should unregister them OSType iconType; /* UnregisterIconRef doesn't decrement the reference count on some versions of Mac OS X (it does on 10.1.5, doesn't on 10.2.8, and does on 10.3.4). To account for this we will retain/acquire the icon, unregister it, then check the reference/owner count. If it's the same then we will also release the icons. We can't release the icons first or UnregisterIconRef will return noSuchIconErr (because the icons will already be disposed). Likewise we can't just release the icons afterwards because they may get disposed of when they're unregistered. */ AcquireIconRef((itemsData[0])->icon); for (iconType = 'Cat0'; iconType <= 'Cat9'; iconType++) UnregisterIconRef(kAppSignature, iconType); gIconsRegistered = false; GetIconRefOwners((itemsData[0])->icon, &referenceCount); if (referenceCount > 1) needRelease = true; ReleaseIconRef((itemsData[0])->icon); } else // otherwise simply release the icons needRelease = true; if (needRelease) { for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) ReleaseIconRef((itemsData[itemNumber])->icon); } // second, release the strings for (itemNumber = 0; itemNumber < kNumberOfRows; itemNumber++) CFRelease((itemsData[itemNumber])->name); DisposeHandle(itemsHandle); // finally, release our callbacks gCallbackRefCount--; if (gCallbackRefCount == 0) { DisposeDataBrowserItemNotificationUPP(gIconDBCallbacks.u.v1.itemNotificationCallback); DisposeDataBrowserDrawItemUPP(gIconDBCustomCallbacks.u.v1.drawItemCallback); } }