Open Tracker License
Terms and Conditions
Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice applies to all licensees
and shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Be Incorporated shall not be
used in advertising or otherwise to promote the sale, use or other dealings in
this Software without prior written authorization from Be Incorporated.
Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
of Be Incorporated in the United States and other countries. Other brand product
names are registered trademarks or trademarks of their respective holders.
All rights reserved.
*/
#include <ControlLook.h>
#include <Debug.h>
#include <Screen.h>
#include <Volume.h>
#include <fs_info.h>
#include "Bitmaps.h"
#include "FSUtils.h"
#include "IconCache.h"
#include "MimeTypes.h"
#include "Model.h"
#include "Thumbnails.h"
#ifdef LOG_DISK_HITS
# define PRINT_DISK_HITS(ARGS) _debugPrintf ARGS
#else
# define PRINT_DISK_HITS(ARGS) (void)0
#endif
#ifdef LOG_ADD_ITEM
# define PRINT_ADD_ITEM(ARGS) _debugPrintf ARGS
#else
# define PRINT_ADD_ITEM(ARGS) (void)0
#endif
#undef NODE_CACHE_ASYNC_DRAWS
BSize IconCache::sMiniIconSize;
static inline icon_size
icon_size_for(BSize size)
{
ASSERT(size.Width() == size.Height());
return (icon_size)(size.IntegerWidth() + 1);
}
IconCacheEntry::IconCacheEntry()
:
fLargeIcon(NULL),
fHighlightedLargeIcon(NULL),
fMiniIcon(NULL),
fHighlightedMiniIcon(NULL),
fAliasTo(NULL)
{
}
IconCacheEntry::~IconCacheEntry()
{
if (fAliasTo == NULL) {
delete fLargeIcon;
delete fHighlightedLargeIcon;
delete fMiniIcon;
delete fHighlightedMiniIcon;
fLargeIcon = NULL;
fHighlightedLargeIcon = NULL;
fMiniIcon = NULL;
fHighlightedMiniIcon = NULL;
}
fAliasTo = NULL;
}
void
IconCacheEntry::SetAliasFor(const SharedIconCache* sharedCache,
const SharedCacheEntry* entry)
{
sharedCache->SetAliasFor(this, entry);
ASSERT(fAliasTo != NULL);
}
IconCacheEntry*
IconCacheEntry::ResolveIfAlias(const SharedIconCache* sharedCache)
{
return sharedCache->ResolveIfAlias(this);
}
IconCacheEntry*
IconCacheEntry::ResolveIfAlias(const SharedIconCache* sharedCache,
IconCacheEntry* entry)
{
if (entry == NULL)
return NULL;
return sharedCache->ResolveIfAlias(entry);
}
bool
IconCacheEntry::CanConstructBitmap(IconDrawMode mode, BSize) const
{
if (mode == kSelected) {
return true;
}
return false;
}
bool
IconCacheEntry::HaveIconBitmap(IconDrawMode mode, BSize size) const
{
ASSERT(mode == kSelected || mode == kNormalIcon);
if (mode == kNormalIcon) {
return size == IconCache::sMiniIconSize ? fMiniIcon != NULL
: fLargeIcon != NULL
&& fLargeIcon->Bounds().Size() == size;
} else if (mode == kSelected) {
return size == IconCache::sMiniIconSize ? fHighlightedMiniIcon != NULL
: fHighlightedLargeIcon != NULL
&& fHighlightedLargeIcon->Bounds().Size() == size;
}
return false;
}
BBitmap*
IconCacheEntry::IconForMode(IconDrawMode mode, BSize size) const
{
ASSERT(mode == kSelected || mode == kNormalIcon);
if (mode == kNormalIcon) {
if (size == IconCache::sMiniIconSize)
return fMiniIcon;
else
return fLargeIcon;
} else if (mode == kSelected) {
if (size == IconCache::sMiniIconSize)
return fHighlightedMiniIcon;
else
return fHighlightedLargeIcon;
}
return NULL;
}
bool
IconCacheEntry::IconHitTest(BPoint where, IconDrawMode mode,
BSize size) const
{
ASSERT(where.x < size.width && where.y < size.height);
BBitmap* bitmap = IconForMode(mode, size);
if (bitmap == NULL)
return false;
uchar* bits = (uchar*)bitmap->Bits();
ASSERT(bits != NULL);
BRect bounds(bitmap->Bounds());
bounds.InsetBy((bounds.Width() + 1.0) / 8.0, (bounds.Height() + 1.0) / 8.0);
if (bounds.Contains(where))
return true;
switch (bitmap->ColorSpace()) {
case B_RGBA32:
return *(bits + (int32)(floorf(where.y) * bitmap->BytesPerRow()
+ floorf(where.x) * 4 + 3)) > 20;
case B_CMAP8:
return *(bits + (int32)(floorf(where.y) * icon_size_for(size) + where.x))
!= B_TRANSPARENT_8_BIT;
default:
return true;
}
}
BBitmap*
IconCacheEntry::ConstructBitmap(BBitmap* constructFrom,
IconDrawMode requestedMode, IconDrawMode constructFromMode,
BSize size, LazyBitmapAllocator* lazyBitmap)
{
ASSERT(requestedMode == kSelected && constructFromMode == kNormalIcon);
if (requestedMode == kSelected && constructFromMode == kNormalIcon) {
return IconCache::sIconCache->MakeSelectedIcon(constructFrom, size,
lazyBitmap);
}
return NULL;
}
BBitmap*
IconCacheEntry::ConstructBitmap(IconDrawMode requestedMode, BSize size,
LazyBitmapAllocator* lazyBitmap)
{
BBitmap* source = (size == IconCache::sMiniIconSize) ? fMiniIcon : fLargeIcon;
ASSERT(source != NULL);
return ConstructBitmap(source, requestedMode, kNormalIcon, size,
lazyBitmap);
}
bool
IconCacheEntry::AlternateModeForIconConstructing(IconDrawMode requestedMode,
IconDrawMode &alternate, BSize)
{
if ((requestedMode & kSelected) != 0) {
alternate = kNormalIcon;
return true;
}
return false;
}
void
IconCacheEntry::SetIcon(BBitmap* bitmap, IconDrawMode mode, BSize size)
{
BBitmap** icon = NULL;
if (mode == kNormalIcon) {
if (size == IconCache::sMiniIconSize)
icon = &fMiniIcon;
else
icon = &fLargeIcon;
} else if (mode == kSelectedIcon) {
if (size == IconCache::sMiniIconSize)
icon = &fHighlightedMiniIcon;
else
icon = &fHighlightedLargeIcon;
}
if (icon == NULL)
TRESPASS();
if ((*icon) != NULL)
delete *icon;
*icon = bitmap;
}
IconCache::IconCache()
:
fInitHighlightTable(true)
{
InitHighlightTable();
sMiniIconSize = be_control_look->ComposeIconSize(B_MINI_ICON);
}
IconCacheEntry*
IconCache::GetIconForPreferredApp(const char* fileTypeSignature,
const char* preferredApp, IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry)
{
ASSERT(fSharedCache.IsLocked());
if (preferredApp == NULL || *preferredApp == '\0')
return NULL;
if (entry == NULL) {
entry = fSharedCache.FindItem(fileTypeSignature, preferredApp);
if (entry != NULL) {
entry = entry->ResolveIfAlias(&fSharedCache, entry);
#if xDEBUG
PRINT(("File %s; Line %d # looking for %s, type %s, found %x\n",
__FILE__, __LINE__, preferredApp, fileTypeSignature, entry));
#endif
if (entry->HaveIconBitmap(mode, size))
return entry;
}
}
if (entry == NULL || !entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
PRINT_DISK_HITS(
("File %s; Line %d # hitting disk for preferredApp %s, type %s\n",
__FILE__, __LINE__, preferredApp, fileTypeSignature));
BMimeType preferredAppType(preferredApp);
BString signature(fileTypeSignature);
signature.ToLower();
if (preferredAppType.GetIconForType(signature.String(),
lazyBitmap->Get(), icon_size_for(size)) != B_OK) {
return NULL;
}
BBitmap* bitmap = lazyBitmap->Adopt();
if (entry == NULL) {
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry for preferredApp %s, "
"type %s\n", __FILE__, __LINE__, preferredApp,
fileTypeSignature));
entry = fSharedCache.AddItem(fileTypeSignature, preferredApp);
}
entry->SetIcon(bitmap, kNormalIcon, size);
}
if (mode != kNormalIcon
&& entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
return entry;
}
IconCacheEntry*
IconCache::GetIconFromMetaMime(const char* fileType, IconDrawMode mode,
BSize size, LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry)
{
ASSERT(fSharedCache.IsLocked());
if (entry == NULL)
entry = fSharedCache.FindItem(fileType);
if (entry != NULL) {
entry = entry->ResolveIfAlias(&fSharedCache, entry);
if (entry->HaveIconBitmap(mode, size))
return entry;
}
if (entry == NULL || !entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
PRINT_DISK_HITS(("File %s; Line %d # hitting disk for metamime %s\n",
__FILE__, __LINE__, fileType));
BMimeType mime(fileType);
if (mime.GetIcon(lazyBitmap->Get(), icon_size_for(size)) != B_OK) {
char preferredAppSig[B_MIME_TYPE_LENGTH];
if (mime.GetPreferredApp(preferredAppSig) != B_OK)
return NULL;
SharedCacheEntry* aliasTo = NULL;
if (entry != NULL) {
aliasTo
= (SharedCacheEntry*)entry->ResolveIfAlias(&fSharedCache);
}
aliasTo = (SharedCacheEntry*)GetIconForPreferredApp(fileType,
preferredAppSig, mode, size, lazyBitmap, aliasTo);
if (aliasTo == NULL)
return NULL;
if (entry == NULL) {
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry as alias for type %s\n",
__FILE__, __LINE__, fileType));
entry = fSharedCache.AddItem(fileType);
entry->SetAliasFor(&fSharedCache, aliasTo);
}
ASSERT(aliasTo->HaveIconBitmap(mode, size));
return aliasTo;
}
BBitmap* bitmap = lazyBitmap->Adopt();
if (entry == NULL) {
PRINT_ADD_ITEM(("File %s; Line %d # adding entry for type %s\n",
__FILE__, __LINE__, fileType));
entry = fSharedCache.AddItem(fileType);
}
entry->SetIcon(bitmap, kNormalIcon, size);
}
ASSERT(entry != NULL);
if (mode != kNormalIcon
&& entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
#if xDEBUG
if (!entry->HaveIconBitmap(mode, size))
PRINT(("failing on %s, mode %ld, size %ld\n", fileType, mode, size));
#endif
ASSERT(entry->HaveIconBitmap(mode, size));
return entry;
}
IconCacheEntry*
IconCache::GetIconFromFileTypes(ModelNodeLazyOpener* modelOpener,
IconSource &source, IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry)
{
ASSERT(fSharedCache.IsLocked());
Model* model = modelOpener->TargetModel();
const char* fileType = model->MimeType();
const char* nodePreferredApp = model->PreferredAppSignature();
if (source == kUnknownSource || source == kUnknownNotFromNode
|| source == kPreferredAppForNode) {
if (nodePreferredApp[0]) {
entry = GetIconForPreferredApp(fileType, nodePreferredApp, mode,
size, lazyBitmap, entry);
#if xDEBUG
PRINT(("File %s; Line %d # looking for %s, type %s, found %x\n",
__FILE__, __LINE__, nodePreferredApp, fileType, entry));
#endif
if (entry != NULL) {
source = kPreferredAppForNode;
ASSERT(entry->HaveIconBitmap(mode, size));
return entry;
}
}
if (source == kPreferredAppForNode)
source = kUnknownSource;
}
entry = GetIconFromMetaMime(fileType, mode, size, lazyBitmap, entry);
if (entry == NULL) {
BMimeType mime(fileType);
if (!mime.IsSupertypeOnly()) {
BMimeType superType;
mime.GetSupertype(&superType);
const char* superTypeFileType = superType.Type();
if (superTypeFileType != NULL) {
entry = GetIconFromMetaMime(superTypeFileType, mode, size,
lazyBitmap, entry);
}
#if DEBUG
else {
PRINT(("File %s; Line %d # failed to get supertype for "
"type %s\n", __FILE__, __LINE__, fileType));
}
#endif
}
}
ASSERT(entry == NULL || entry->HaveIconBitmap(mode, size));
if (entry != NULL) {
if (nodePreferredApp != NULL && *nodePreferredApp != '\0') {
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry as alias for "
"preferredApp %s, type %s\n",
__FILE__, __LINE__, nodePreferredApp, fileType));
IconCacheEntry* aliasedEntry
= fSharedCache.AddItem(fileType, nodePreferredApp);
aliasedEntry->SetAliasFor(&fSharedCache,
(SharedCacheEntry*)entry);
source = kPreferredAppForNode;
} else
source = kMetaMime;
#if DEBUG
if (!entry->HaveIconBitmap(mode, size))
model->PrintToStream();
#endif
ASSERT(entry->HaveIconBitmap(mode, size));
}
return entry;
}
IconCacheEntry*
IconCache::GetVolumeIcon(AutoLock<SimpleIconCache>*nodeCacheLocker,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model* model, IconSource &source,
IconDrawMode mode, BSize size, LazyBitmapAllocator* lazyBitmap)
{
*resultingOpenCache = nodeCacheLocker;
nodeCacheLocker->Lock();
IconCacheEntry* entry = 0;
if (source != kUnknownSource) {
entry = fNodeCache.FindItem(model->NodeRef());
if (entry != NULL) {
entry = IconCacheEntry::ResolveIfAlias(&fSharedCache, entry);
if (source == kTrackerDefault) {
*resultingOpenCache = sharedCacheLocker;
sharedCacheLocker->Lock();
}
if (entry->HaveIconBitmap(mode, size))
return entry;
}
}
if (entry == NULL || !entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
BVolume volume(model->NodeRef()->device);
if (volume.IsShared()) {
BBitmap* bitmap = lazyBitmap->Get();
GetTrackerResources()->GetIconResource(R_ShareIcon,
icon_size_for(size), bitmap);
if (entry == NULL) {
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry for model %s\n",
__FILE__, __LINE__, model->Name()));
entry = fNodeCache.AddItem(model->NodeRef());
}
entry->SetIcon(lazyBitmap->Adopt(), kNormalIcon, size);
} else if (volume.GetIcon(lazyBitmap->Get(), icon_size_for(size)) == B_OK) {
BBitmap* bitmap = lazyBitmap->Adopt();
ASSERT(bitmap != NULL);
if (entry == NULL) {
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry for model %s\n",
__FILE__, __LINE__, model->Name()));
entry = fNodeCache.AddItem(model->NodeRef());
}
ASSERT(entry != NULL);
entry->SetIcon(bitmap, kNormalIcon, size);
source = kVolume;
} else {
*resultingOpenCache = sharedCacheLocker;
sharedCacheLocker->Lock();
entry = GetIconFromMetaMime(B_VOLUME_MIMETYPE, mode,
size, lazyBitmap, entry);
}
}
if (mode != kNormalIcon && entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
return entry;
}
IconCacheEntry*
IconCache::GetRootIcon(AutoLock<SimpleIconCache>*,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model*, IconSource &source, IconDrawMode mode,
BSize size, LazyBitmapAllocator* lazyBitmap)
{
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
source = kTrackerSupplied;
return GetIconFromMetaMime(B_ROOT_MIMETYPE, mode, size, lazyBitmap, 0);
}
IconCacheEntry*
IconCache::GetPrinterIcon(AutoLock<SimpleIconCache>*,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model*, IconSource &source, IconDrawMode mode,
BSize size, LazyBitmapAllocator* lazyBitmap)
{
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
source = kTrackerSupplied;
return GetIconFromMetaMime(B_PRINTER_MIMETYPE, mode, size, lazyBitmap, 0);
}
IconCacheEntry*
IconCache::GetWellKnownIcon(AutoLock<SimpleIconCache>*,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model* model, IconSource &source, IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap)
{
const WellKnowEntryList::WellKnownEntry* wellKnownEntry
= WellKnowEntryList::MatchEntry(model->NodeRef());
if (wellKnownEntry == NULL)
return NULL;
BString type("tracker/active_");
type += wellKnownEntry->name;
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
source = kTrackerSupplied;
IconCacheEntry* entry = fSharedCache.FindItem(type.String());
if (entry != NULL) {
entry = entry->ResolveIfAlias(&fSharedCache, entry);
if (entry->HaveIconBitmap(mode, size))
return entry;
}
if (entry == NULL || !entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
int32 resourceId = -1;
switch ((uint32)wellKnownEntry->which) {
case B_BOOT_DISK:
resourceId = R_BootVolumeIcon;
break;
case B_BEOS_DIRECTORY:
resourceId = R_BeosFolderIcon;
break;
case B_USER_DIRECTORY:
resourceId = R_HomeDirIcon;
break;
case B_SYSTEM_FONTS_DIRECTORY:
case B_SYSTEM_NONPACKAGED_FONTS_DIRECTORY:
case B_USER_FONTS_DIRECTORY:
case B_USER_NONPACKAGED_FONTS_DIRECTORY:
resourceId = R_FontDirIcon;
break;
case B_BEOS_APPS_DIRECTORY:
case B_APPS_DIRECTORY:
case B_USER_DESKBAR_APPS_DIRECTORY:
resourceId = R_AppsDirIcon;
break;
case B_BEOS_PREFERENCES_DIRECTORY:
case B_PREFERENCES_DIRECTORY:
case B_USER_DESKBAR_PREFERENCES_DIRECTORY:
resourceId = R_PrefsDirIcon;
break;
case B_USER_MAIL_DIRECTORY:
resourceId = R_MailDirIcon;
break;
case B_USER_QUERIES_DIRECTORY:
resourceId = R_QueryDirIcon;
break;
case B_SYSTEM_DEVELOP_DIRECTORY:
case B_SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY:
case B_USER_DESKBAR_DEVELOP_DIRECTORY:
resourceId = R_DevelopDirIcon;
break;
case B_USER_CONFIG_DIRECTORY:
resourceId = R_ConfigDirIcon;
break;
case B_USER_PEOPLE_DIRECTORY:
resourceId = R_PersonDirIcon;
break;
case B_USER_DOWNLOADS_DIRECTORY:
resourceId = R_DownloadDirIcon;
break;
default:
return NULL;
}
entry = fSharedCache.AddItem(type.String());
BBitmap* bitmap = lazyBitmap->Get();
GetTrackerResources()->GetIconResource(resourceId,
icon_size_for(size), bitmap);
entry->SetIcon(lazyBitmap->Adopt(), kNormalIcon, size);
}
if (mode != kNormalIcon
&& entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
ASSERT(entry->HaveIconBitmap(mode, size));
return entry;
}
IconCacheEntry*
IconCache::GetNodeIcon(ModelNodeLazyOpener* modelOpener,
AutoLock<SimpleIconCache>* nodeCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model* model, IconSource& source,
IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry, bool permanent)
{
*resultingOpenCache = nodeCacheLocker;
(*resultingOpenCache)->Lock();
entry = fNodeCache.FindItem(model->NodeRef());
if (entry == NULL || !entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
modelOpener->OpenNode();
PRINT_DISK_HITS(("File %s; Line %d # hitting disk for node %s\n",
__FILE__, __LINE__, model->Name()));
BFile* file = NULL;
status_t result = B_ERROR;
if (model->IsExecutable()
&& (file = dynamic_cast<BFile*>(model->Node())) != NULL) {
result = GetAppIconFromAttr(file, lazyBitmap->Get(), icon_size_for(size));
} else {
result = GetThumbnailFromAttr(model, lazyBitmap->Get(), size);
if (result != B_OK && result != B_BUSY) {
result = GetFileIconFromAttr(model->Node(), lazyBitmap->Get(),
icon_size_for(size));
}
}
if (result == B_OK) {
BBitmap* bitmap = lazyBitmap->Adopt();
PRINT_ADD_ITEM(("File %s; Line %d # adding entry for model %s\n",
__FILE__, __LINE__, model->Name()));
entry = fNodeCache.AddItem(model->NodeRef(), permanent);
ASSERT(entry != NULL);
entry->SetIcon(bitmap, kNormalIcon, size);
if (mode != kNormalIcon) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
source = kNode;
}
}
if (entry == NULL) {
(*resultingOpenCache)->Unlock();
*resultingOpenCache = NULL;
} else if (!entry->HaveIconBitmap(mode, size)
&& entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
ASSERT(entry->HaveIconBitmap(mode, size));
}
return entry;
}
IconCacheEntry*
IconCache::GetGenericIcon(AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model* model, IconSource &source,
IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry)
{
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
entry = GetIconFromMetaMime(B_FILE_MIMETYPE, mode, size, lazyBitmap, 0);
if (entry == NULL)
return NULL;
PRINT_ADD_ITEM(
("File %s; Line %d # adding entry for preferredApp %s, type %s\n",
__FILE__, __LINE__, model->PreferredAppSignature(),
model->MimeType()));
IconCacheEntry* aliasedEntry = fSharedCache.AddItem(
model->MimeType(), model->PreferredAppSignature());
aliasedEntry->SetAliasFor(&fSharedCache, (SharedCacheEntry*)entry);
source = kMetaMime;
ASSERT(entry->HaveIconBitmap(mode, size));
return entry;
}
IconCacheEntry*
IconCache::GetFallbackIcon(AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingOpenCache,
Model* model, IconDrawMode mode, BSize size,
LazyBitmapAllocator* lazyBitmap, IconCacheEntry* entry)
{
*resultingOpenCache = sharedCacheLocker;
(*resultingOpenCache)->Lock();
entry = fSharedCache.AddItem(model->MimeType(),
model->PreferredAppSignature());
BBitmap* bitmap = lazyBitmap->Get();
GetTrackerResources()->GetIconResource(R_FileIcon,
icon_size_for(size), bitmap);
entry->SetIcon(lazyBitmap->Adopt(), kNormalIcon, size);
if (mode != kNormalIcon) {
entry->ConstructBitmap(mode, size, lazyBitmap);
entry->SetIcon(lazyBitmap->Adopt(), mode, size);
}
ASSERT(entry->HaveIconBitmap(mode, size));
return entry;
}
IconCacheEntry*
IconCache::Preload(AutoLock<SimpleIconCache>* nodeCacheLocker,
AutoLock<SimpleIconCache>* sharedCacheLocker,
AutoLock<SimpleIconCache>** resultingCache,
Model* model, IconDrawMode mode, BSize size,
bool permanent)
{
IconCacheEntry* entry = NULL;
AutoLock<SimpleIconCache>* resultingOpenCache = NULL;
{
ModelNodeLazyOpener modelOpener(model);
LazyBitmapAllocator lazyBitmap(size);
IconSource source = model->IconFrom();
if (source == kUnknownSource || source == kUnknownNotFromNode) {
if (model->IsRoot()) {
entry = GetRootIcon(nodeCacheLocker, sharedCacheLocker, &resultingOpenCache, model,
source, mode, size, &lazyBitmap);
ASSERT(entry != NULL);
} else if (model->IsVolume()) {
entry = GetNodeIcon(&modelOpener, nodeCacheLocker,
&resultingOpenCache, model, source, mode, size,
&lazyBitmap, entry, permanent);
if (entry == NULL || !entry->HaveIconBitmap(mode, size)) {
entry = GetVolumeIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode,
size, &lazyBitmap);
}
} else if (model->IsPrintersDir()) {
entry = GetPrinterIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode, size, &lazyBitmap);
ASSERT(entry != NULL);
} else {
if (source == kUnknownSource) {
entry = GetNodeIcon(&modelOpener, nodeCacheLocker,
&resultingOpenCache, model, source,
mode, size, &lazyBitmap, entry, permanent);
}
if (entry == NULL) {
modelOpener.OpenNode();
resultingOpenCache = sharedCacheLocker;
resultingOpenCache->Lock();
entry = GetIconFromFileTypes(&modelOpener, source, mode,
size, &lazyBitmap, 0);
if (entry == NULL) {
entry = GetGenericIcon(sharedCacheLocker,
&resultingOpenCache, model, source, mode,
size, &lazyBitmap, entry);
}
}
}
model->SetIconFrom(source);
} else {
switch (source) {
case kNode:
resultingOpenCache = nodeCacheLocker;
resultingOpenCache->Lock();
entry = GetNodeIcon(&modelOpener, nodeCacheLocker,
&resultingOpenCache, model, source, mode,
size, &lazyBitmap, entry, permanent);
if (entry != NULL) {
entry = IconCacheEntry::ResolveIfAlias(&fSharedCache,
entry);
if (!entry->HaveIconBitmap(mode, size)
&& entry->HaveIconBitmap(NORMAL_ICON_ONLY, size)) {
entry->ConstructBitmap(mode, size, &lazyBitmap);
entry->SetIcon(lazyBitmap.Adopt(), mode, size);
}
ASSERT(entry->HaveIconBitmap(mode, size));
}
break;
case kTrackerSupplied:
if (model->IsRoot()) {
entry = GetRootIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode, size,
&lazyBitmap);
break;
} else if (model->IsPrintersDir()) {
entry = GetPrinterIcon(nodeCacheLocker, sharedCacheLocker,
&resultingOpenCache, model, source, mode, size,
&lazyBitmap);
break;
} else {
entry = GetWellKnownIcon(nodeCacheLocker,
sharedCacheLocker, &resultingOpenCache, model,
source, mode, size, &lazyBitmap);
if (entry != NULL)
break;
}
case kTrackerDefault:
case kVolume:
if (model->IsVolume()) {
entry = GetNodeIcon(&modelOpener, nodeCacheLocker,
&resultingOpenCache, model, source,
mode, size, &lazyBitmap, entry, permanent);
if (entry == NULL
|| !entry->HaveIconBitmap(mode, size)) {
entry = GetVolumeIcon(nodeCacheLocker,
sharedCacheLocker, &resultingOpenCache, model,
source, mode, size, &lazyBitmap);
}
break;
}
case kMetaMime:
case kPreferredAppForType:
case kPreferredAppForNode:
resultingOpenCache = sharedCacheLocker;
resultingOpenCache->Lock();
entry = GetIconFromFileTypes(&modelOpener, source, mode,
size, &lazyBitmap, 0);
if (entry == NULL || !entry->HaveIconBitmap(mode, size)) {
entry = GetGenericIcon(sharedCacheLocker,
&resultingOpenCache, model, source, mode, size,
&lazyBitmap, entry);
}
model->SetIconFrom(source);
ASSERT(entry != NULL);
ASSERT(entry->HaveIconBitmap(mode, size));
break;
default:
TRESPASS();
break;
}
}
if (entry == NULL || !entry->HaveIconBitmap(mode, size)) {
PRINT(
("icon cache complete miss, falling back on generic icon "
"for %s\n", model->Name()));
entry = GetGenericIcon(sharedCacheLocker, &resultingOpenCache,
model, source, mode, size, &lazyBitmap, entry);
if (entry == NULL || !entry->HaveIconBitmap(mode, size)) {
PRINT(
("icon cache complete miss, falling back on generic "
"icon for %s\n", model->Name()));
entry = GetFallbackIcon(sharedCacheLocker,
&resultingOpenCache, model, mode, size, &lazyBitmap,
entry);
}
model->SetIconFrom(kUnknownSource);
}
}
ASSERT(entry != NULL && entry->HaveIconBitmap(mode, size));
if (resultingCache != NULL)
*resultingCache = resultingOpenCache;
return entry;
}
void
IconCache::Draw(Model* model, BView* view, BPoint where, IconDrawMode mode,
BSize size, bool async)
{
AutoLock<SimpleIconCache> nodeCacheLocker(&fNodeCache, false);
AutoLock<SimpleIconCache> sharedCacheLocker(&fSharedCache, false);
AutoLock<SimpleIconCache>* resultingCacheLocker;
IconCacheEntry* entry = Preload(&nodeCacheLocker, &sharedCacheLocker,
&resultingCacheLocker, model, mode, size, false);
if (entry == NULL)
return;
ASSERT(entry != NULL);
ASSERT(entry->HaveIconBitmap(mode, size));
resultingCacheLocker->LockedItem()->Draw(entry, view, where, mode,
size, async);
}
void
IconCache::SyncDraw(Model* model, BView* view, BPoint where,
IconDrawMode mode, BSize size,
void (*blitFunc)(BView*, BPoint, BBitmap*, void*),
void* passThruState)
{
AutoLock<SimpleIconCache> nodeCacheLocker(&fNodeCache, false);
AutoLock<SimpleIconCache> sharedCacheLocker(&fSharedCache, false);
AutoLock<SimpleIconCache>* resultingCacheLocker;
IconCacheEntry* entry = Preload(&nodeCacheLocker, &sharedCacheLocker,
&resultingCacheLocker, model, mode, size, false);
if (entry == NULL)
return;
ASSERT(entry != NULL);
ASSERT(entry->HaveIconBitmap(mode, size));
resultingCacheLocker->LockedItem()->Draw(entry, view, where,
mode, size, blitFunc, passThruState);
}
void
IconCache::Preload(Model* model, IconDrawMode mode, BSize size,
bool permanent)
{
AutoLock<SimpleIconCache> nodeCacheLocker(&fNodeCache, false);
AutoLock<SimpleIconCache> sharedCacheLocker(&fSharedCache, false);
Preload(&nodeCacheLocker, &sharedCacheLocker, 0, model, mode, size,
permanent);
}
status_t
IconCache::Preload(const char* fileType, IconDrawMode mode, BSize size)
{
AutoLock<SimpleIconCache> sharedCacheLocker(&fSharedCache);
LazyBitmapAllocator lazyBitmap(size);
BMimeType mime(fileType);
char preferredAppSig[B_MIME_TYPE_LENGTH];
status_t result = mime.GetPreferredApp(preferredAppSig);
if (result != B_OK)
return result;
IconCacheEntry* entry = GetIconForPreferredApp(fileType, preferredAppSig,
mode, size, &lazyBitmap, 0);
if (entry != NULL)
return B_OK;
result = mime.GetIcon(lazyBitmap.Get(), icon_size_for(size));
if (result != B_OK)
return result;
entry = fSharedCache.AddItem(fileType);
BBitmap* bitmap = lazyBitmap.Adopt();
entry->SetIcon(bitmap, kNormalIcon, size);
if (mode != kNormalIcon) {
entry->ConstructBitmap(mode, size, &lazyBitmap);
entry->SetIcon(lazyBitmap.Adopt(), mode, size);
}
return B_OK;
}
void
IconCache::Deleting(const Model* model)
{
AutoLock<SimpleIconCache> lock(&fNodeCache);
if (model->IconFrom() == kNode)
fNodeCache.Deleting(model->NodeRef());
}
void
IconCache::Removing(const Model* model)
{
AutoLock<SimpleIconCache> lock(&fNodeCache);
if (model->IconFrom() == kNode)
fNodeCache.Removing(model->NodeRef());
}
void
IconCache::Deleting(const BView* view)
{
AutoLock<SimpleIconCache> lock(&fNodeCache);
fNodeCache.Deleting(view);
}
void
IconCache::IconChanged(Model* model)
{
AutoLock<SimpleIconCache> lock(&fNodeCache);
if (model->IconFrom() == kNode || model->IconFrom() == kVolume)
fNodeCache.Deleting(model->NodeRef());
model->ResetIconFrom();
}
void
IconCache::IconChanged(const char* mimeType, const char* appSignature)
{
AutoLock<SimpleIconCache> sharedLock(&fSharedCache);
SharedCacheEntry* entry = fSharedCache.FindItem(mimeType, appSignature);
if (entry == NULL)
return;
AutoLock<SimpleIconCache> nodeLock(&fNodeCache);
entry = (SharedCacheEntry*)fSharedCache.ResolveIfAlias(entry);
ASSERT(entry != NULL);
fNodeCache.RemoveAliasesTo(entry);
fSharedCache.RemoveAliasesTo(entry);
fSharedCache.IconChanged(entry);
}
BBitmap*
IconCache::MakeSelectedIcon(const BBitmap* normal, BSize size,
LazyBitmapAllocator* lazyBitmap)
{
return MakeTransformedIcon(normal, size, fHighlightTable, lazyBitmap);
}
#if xDEBUG
static void
DumpBitmap(const BBitmap* bitmap)
{
if (bitmap == NULL) {
printf("NULL bitmap passed to DumpBitmap\n");
return;
}
int32 length = bitmap->BitsLength();
printf("data length %ld \n", length);
int32 columns = (int32)bitmap->Bounds().Width() + 1;
const unsigned char* bitPtr = (const unsigned char*)bitmap->Bits();
for (; length >= 0; length--) {
for (int32 columnIndex = 0; columnIndex < columns;
columnIndex++, length--)
printf("%c%c", "0123456789ABCDEF"[(*bitPtr)/0x10],
"0123456789ABCDEF"[(*bitPtr++)%0x10]);
printf("\n");
}
printf("\n");
}
#endif
void
IconCache::InitHighlightTable()
{
BScreen screen(B_MAIN_SCREEN_ID);
rgb_color color;
for (int32 index = 0; index < kColorTransformTableSize; index++) {
color = screen.ColorForIndex((uchar)index);
fHighlightTable[index] = screen.IndexForColor(tint_color(color, 1.3f));
}
fHighlightTable[B_TRANSPARENT_8_BIT] = B_TRANSPARENT_8_BIT;
fInitHighlightTable = false;
}
BBitmap*
IconCache::MakeTransformedIcon(const BBitmap* source, BSize ,
int32 colorTransformTable[], LazyBitmapAllocator* lazyBitmap)
{
if (fInitHighlightTable)
InitHighlightTable();
BBitmap* result = lazyBitmap->Get();
uint8* src = (uint8*)source->Bits();
uint8* dst = (uint8*)result->Bits();
if (result->ColorSpace() != source->ColorSpace()
|| result->Bounds() != source->Bounds()) {
printf("IconCache::MakeTransformedIcon() - bitmap format mismatch!\n");
return NULL;
}
switch (result->ColorSpace()) {
case B_RGB32:
case B_RGBA32: {
uint32 width = source->Bounds().IntegerWidth() + 1;
uint32 height = source->Bounds().IntegerHeight() + 1;
uint32 srcBPR = source->BytesPerRow();
uint32 dstBPR = result->BytesPerRow();
for (uint32 y = 0; y < height; y++) {
uint8* d = dst;
uint8* s = src;
for (uint32 x = 0; x < width; x++) {
d[0] = (int)s[0] * 168 >> 8;
d[1] = (int)s[1] * 168 >> 8;
d[2] = (int)s[2] * 168 >> 8;
d[3] = s[3];
d += 4;
s += 4;
}
dst += dstBPR;
src += srcBPR;
}
break;
}
case B_CMAP8: {
int32 bitsLength = result->BitsLength();
for (int32 i = 0; i < bitsLength; i++)
*dst++ = (uint8)colorTransformTable[*src++];
break;
}
default:
memset(dst, 0, result->BitsLength());
break;
}
return result;
}
bool
IconCache::IconHitTest(BPoint where, const Model* model, IconDrawMode mode,
BSize size)
{
AutoLock<SimpleIconCache> nodeCacheLocker(&fNodeCache, false);
AutoLock<SimpleIconCache> sharedCacheLocker(&fSharedCache, false);
AutoLock<SimpleIconCache>* resultingCacheLocker;
IconCacheEntry* entry = Preload(&nodeCacheLocker, &sharedCacheLocker,
&resultingCacheLocker, const_cast<Model*>(model), mode, size, false);
if (entry != NULL)
return entry->IconHitTest(where, mode, size);
return false;
}
void
IconCacheEntry::RetireIcons(BObjectList<BBitmap, true>* retiredBitmapList)
{
if (fLargeIcon != NULL) {
retiredBitmapList->AddItem(fLargeIcon);
fLargeIcon = NULL;
}
if (fHighlightedLargeIcon != NULL) {
retiredBitmapList->AddItem(fHighlightedLargeIcon);
fHighlightedLargeIcon = NULL;
}
if (fMiniIcon != NULL) {
retiredBitmapList->AddItem(fMiniIcon);
fMiniIcon = NULL;
}
if (fHighlightedMiniIcon != NULL) {
retiredBitmapList->AddItem(fHighlightedMiniIcon);
fHighlightedMiniIcon = NULL;
}
int32 count = retiredBitmapList->CountItems();
if (count > 10 * 1024) {
PRINT(("nuking old icons from the retired bitmap list\n"));
for (count = 512; count > 0; count--)
delete retiredBitmapList->RemoveItemAt(0);
}
}
SharedIconCache::SharedIconCache()
:
SimpleIconCache("Tracker shared icon cache"),
fHashTable(),
fRetiredBitmaps(256)
{
fHashTable.Init(256);
}
void
SharedIconCache::Draw(IconCacheEntry* entry, BView* view, BPoint where,
IconDrawMode mode, BSize size, bool async)
{
((SharedCacheEntry*)entry)->Draw(view, where, mode, size, async);
}
void
SharedIconCache::Draw(IconCacheEntry* entry, BView* view, BPoint where,
IconDrawMode mode, BSize size, void (*blitFunc)(BView*, BPoint,
BBitmap*, void*), void* passThruState)
{
((SharedCacheEntry*)entry)->Draw(view, where, mode, size,
blitFunc, passThruState);
}
SharedCacheEntry*
SharedIconCache::FindItem(const char* fileType,
const char* appSignature) const
{
ASSERT(fileType);
if (!fileType)
fileType = B_FILE_MIMETYPE;
return fHashTable.Lookup(SharedCacheEntry::TypeAndSignature(fileType,
appSignature));
}
SharedCacheEntry*
SharedIconCache::AddItem(const char* fileType, const char* appSignature)
{
ASSERT(fileType != NULL);
if (fileType == NULL)
fileType = B_FILE_MIMETYPE;
SharedCacheEntry* entry = new SharedCacheEntry(fileType, appSignature);
if (fHashTable.Insert(entry) == B_OK)
return entry;
delete entry;
return NULL;
}
void
SharedIconCache::IconChanged(SharedCacheEntry* entry)
{
ASSERT(entry->fAliasTo == NULL);
entry->RetireIcons(&fRetiredBitmaps);
fHashTable.Remove(entry);
}
void
SharedIconCache::RemoveAliasesTo(SharedCacheEntry* alias)
{
EntryHashTable::Iterator it = fHashTable.GetIterator();
while (it.HasNext()) {
SharedCacheEntry* entry = it.Next();
if (entry->fAliasTo == alias)
fHashTable.RemoveUnchecked(entry);
}
}
void
SharedIconCache::SetAliasFor(IconCacheEntry* entry,
const SharedCacheEntry* original) const
{
entry->fAliasTo = original;
}
SharedCacheEntry::SharedCacheEntry()
:
fNext(NULL)
{
}
SharedCacheEntry::SharedCacheEntry(const char* fileType,
const char* appSignature)
:
fNext(NULL),
fFileType(fileType),
fAppSignature(appSignature)
{
}
void
SharedCacheEntry::Draw(BView* view, BPoint where, IconDrawMode mode,
BSize size, bool async)
{
BBitmap* bitmap = IconForMode(mode, size);
ASSERT(bitmap != NULL);
drawing_mode oldMode = view->DrawingMode();
if (bitmap->ColorSpace() == B_RGBA32) {
if (oldMode != B_OP_ALPHA) {
view->SetDrawingMode(B_OP_ALPHA);
view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
}
} else
view->SetDrawingMode(B_OP_OVER);
if (async)
view->DrawBitmapAsync(bitmap, where);
else
view->DrawBitmap(bitmap, where);
view->SetDrawingMode(oldMode);
}
void
SharedCacheEntry::Draw(BView* view, BPoint where, IconDrawMode mode,
BSize size, void (*blitFunc)(BView*, BPoint, BBitmap*, void*),
void* passThruState)
{
BBitmap* bitmap = IconForMode(mode, size);
if (bitmap == NULL)
return;
(blitFunc)(view, where, bitmap, passThruState);
}
size_t
SharedCacheEntry::Hash(const TypeAndSignature& typeAndSignature)
{
size_t hash = SeededHashString(typeAndSignature.type, 0);
if (typeAndSignature.signature != NULL
&& *typeAndSignature.signature != '\0')
hash = SeededHashString(typeAndSignature.signature, hash);
return hash;
}
size_t
SharedCacheEntry::Hash() const
{
return Hash(TypeAndSignature(fFileType.String(), fAppSignature.String()));
}
bool
SharedCacheEntry::operator==(const TypeAndSignature& typeAndSignature) const
{
return fFileType == typeAndSignature.type
&& fAppSignature == typeAndSignature.signature;
}
NodeCacheEntry::NodeCacheEntry(bool permanent)
:
fNext(NULL),
fPermanent(permanent)
{
}
NodeCacheEntry::NodeCacheEntry(const node_ref* node, bool permanent)
:
fNext(NULL),
fRef(*node),
fPermanent(permanent)
{
}
void
NodeCacheEntry::Draw(BView* view, BPoint where, IconDrawMode mode,
BSize size, bool async)
{
BBitmap* bitmap = IconForMode(mode, size);
if (bitmap == NULL)
return;
drawing_mode oldMode = view->DrawingMode();
if (bitmap->ColorSpace() == B_RGBA32) {
if (oldMode != B_OP_ALPHA) {
view->SetDrawingMode(B_OP_ALPHA);
view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
}
} else
view->SetDrawingMode(B_OP_OVER);
if (false && async) {
TRESPASS();
view->DrawBitmapAsync(bitmap, where);
} else
view->DrawBitmap(bitmap, where);
view->SetDrawingMode(oldMode);
}
void
NodeCacheEntry::Draw(BView* view, BPoint where, IconDrawMode mode,
BSize size, void (*blitFunc)(BView*, BPoint, BBitmap*, void*),
void* passThruState)
{
BBitmap* bitmap = IconForMode(mode, size);
if (bitmap == NULL)
return;
(blitFunc)(view, where, bitmap, passThruState);
}
const node_ref*
NodeCacheEntry::Node() const
{
return &fRef;
}
size_t
NodeCacheEntry::Hash() const
{
return Hash(&fRef);
}
size_t
NodeCacheEntry::Hash(const node_ref* node)
{
return node->device ^ ((uint32*)&node->node)[0]
^ ((uint32*)&node->node)[1];
}
bool
NodeCacheEntry::operator==(const node_ref* node) const
{
return fRef == *node;
}
bool
NodeCacheEntry::Permanent() const
{
return fPermanent;
}
NodeIconCache::NodeIconCache()
:
SimpleIconCache("Tracker node icon cache")
{
fHashTable.Init(100);
}
void
NodeIconCache::Draw(IconCacheEntry* entry, BView* view, BPoint where,
IconDrawMode mode, BSize size, bool async)
{
((NodeCacheEntry*)entry)->Draw(view, where, mode, size, async);
}
void
NodeIconCache::Draw(IconCacheEntry* entry, BView* view, BPoint where,
IconDrawMode mode, BSize size,
void (*blitFunc)(BView*, BPoint, BBitmap*, void*), void* passThruState)
{
((NodeCacheEntry*)entry)->Draw(view, where, mode, size,
blitFunc, passThruState);
}
NodeCacheEntry*
NodeIconCache::FindItem(const node_ref* node) const
{
return fHashTable.Lookup(node);
}
NodeCacheEntry*
NodeIconCache::AddItem(const node_ref* node, bool permanent)
{
NodeCacheEntry* entry = new NodeCacheEntry(node, permanent);
if (fHashTable.Insert(entry) == B_OK)
return entry;
delete entry;
return NULL;
}
void
NodeIconCache::Deleting(const node_ref* node)
{
NodeCacheEntry* entry = FindItem(node);
if (entry == NULL || entry->Permanent())
return;
fHashTable.Remove(entry);
}
void
NodeIconCache::Removing(const node_ref* node)
{
NodeCacheEntry* entry = FindItem(node);
ASSERT(entry != NULL);
if (entry == NULL)
return;
fHashTable.Remove(entry);
}
void
NodeIconCache::Deleting(const BView*)
{
#ifdef NODE_CACHE_ASYNC_DRAWS
TRESPASS();
#endif
}
void
NodeIconCache::IconChanged(const Model* model)
{
Deleting(model->NodeRef());
}
void
NodeIconCache::RemoveAliasesTo(SharedCacheEntry* alias)
{
EntryHashTable::Iterator it = fHashTable.GetIterator();
while (it.HasNext()) {
NodeCacheEntry* entry = it.Next();
if (entry->fAliasTo == alias)
fHashTable.RemoveUnchecked(entry);
}
}
SimpleIconCache::SimpleIconCache(const char* name)
:
fLock(name)
{
}
void
SimpleIconCache::Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
BSize, bool)
{
TRESPASS();
}
void
SimpleIconCache::Draw(IconCacheEntry*, BView*, BPoint, IconDrawMode,
BSize, void(*)(BView*, BPoint, BBitmap*, void*), void*)
{
TRESPASS();
}
bool
SimpleIconCache::Lock()
{
return fLock.Lock();
}
void
SimpleIconCache::Unlock()
{
fLock.Unlock();
}
bool
SimpleIconCache::IsLocked() const
{
return fLock.IsLocked();
}
LazyBitmapAllocator::LazyBitmapAllocator(BSize size,
color_space colorSpace, bool preallocate)
:
fBitmap(NULL),
fSize(size),
fColorSpace(colorSpace)
{
if (preallocate)
Get();
}
LazyBitmapAllocator::~LazyBitmapAllocator()
{
delete fBitmap;
}
BBitmap*
LazyBitmapAllocator::Get()
{
if (fBitmap == NULL)
fBitmap = new BBitmap(BRect(BPoint(0, 0), fSize), fColorSpace);
return fBitmap;
}
BBitmap*
LazyBitmapAllocator::Adopt()
{
if (fBitmap == NULL)
Get();
BBitmap* bitmap = fBitmap;
fBitmap = NULL;
return bitmap;
}
IconCache* IconCache::sIconCache;