DecorManager::DecorManager() : BLocker("DecorManager"), fDecorList(0), fCurrentDecor(NULL) { // Start with the default decorator - index is always 0 DecorInfo *defaultDecor = new DecorInfo(-1, "Default", NULL); fDecorList.AddItem(defaultDecor); // Add any on disk RescanDecorators(); #if 0 // Find out which one should be the active one BDirectory dir; if (dir.SetTo(SERVER_SETTINGS_DIR) == B_ENTRY_NOT_FOUND) create_directory(SERVER_SETTINGS_DIR, 0777); BMessage settings; BFile file(SERVER_SETTINGS_DIR "decorator_settings", B_READ_ONLY); // Fallback to the default decorator if something goes wrong if (file.InitCheck() == B_OK && settings.Unflatten(&file) == B_OK) { BString itemtext; if (settings.FindString("decorator", &itemtext) == B_OK) { fCurrentDecor = _FindDecor(itemtext.String()); } } #endif if (!fCurrentDecor) fCurrentDecor = (DecorInfo*)fDecorList.ItemAt(0L); }
DecorInfo* DecorInfoUtility::FindDecorator(const BString& string) { if (string.Length() == 0) return CurrentDecorator(); if (string.ICompare("default") == 0) return DefaultDecorator(); BAutolock _(fLock); if (!fHasScanned) ScanDecorators(); // search by path DecorInfo* decor = _FindDecor(string); if (decor != NULL) return decor; // search by name or short cut name for (int i = 1; i < fList.CountItems(); ++i) { decor = fList.ItemAt(i); if (string.ICompare(decor->ShortcutName()) == 0 || string.ICompare(decor->Name()) == 0) { return decor; } } return NULL; }
void DecorManager::RescanDecorators() { BDirectory dir(DECORATORS_DIR); if (dir.InitCheck() != B_OK) return; entry_ref ref; while (dir.GetNextRef(&ref) == B_OK) { BPath path; path.SetTo(DECORATORS_DIR); path.Append(ref.name); // Because this function is used for both initialization and for keeping // the list up to date, check for existence in the list. Note that we // do not check to see if a decorator has been removed. This is for // stability. If there is a decorator in memory already whose file has // been deleted, it is still available until the next boot, at which point // it will obviously not be loaded. if (_FindDecor(ref.name)) continue; image_id image = load_add_on(path.Path()); if (image < 0) continue; // As of now, we do nothing with decorator versions, but the possibility // exists that the API will change even though I cannot forsee any reason // to do so. If we *did* do anything with decorator versions, the // assignment would go here. create_decorator* createFunc; // Get the instantiation function status_t status = get_image_symbol(image, "instantiate_decorator", B_SYMBOL_TYPE_TEXT, (void**)&createFunc); if (status != B_OK) { unload_add_on(image); continue; } // TODO: unload images until they are actually used! fDecorList.AddItem(new DecorInfo(image, ref.name, createFunc)); } }
status_t DecorInfoUtility::_ScanDecorators(BDirectory decoratorDirectory) { BAutolock _(fLock); // First, run through our list and DecorInfos CheckForChanges() if (fHasScanned) { for (int i = fList.CountItems() - 1; i > 0; --i) { DecorInfo* decorInfo = fList.ItemAt(i); bool deleted = false; decorInfo->CheckForChanges(deleted); if (deleted) { fList.RemoveItem(decorInfo); delete decorInfo; } } } entry_ref ref; // Now, look at file system, skip the entries for which we already have // a DecorInfo in the list. while (decoratorDirectory.GetNextRef(&ref) == B_OK) { BPath path(&decoratorDirectory); status_t result = path.Append(ref.name); if (result != B_OK) { fprintf(stderr, "DecorInfoUtility::_ScanDecorators()\tFailed to" "append decorator file to path, skipping: %s.\n", strerror(result)); continue; } if (_FindDecor(path.Path()) != NULL) continue; DecorInfo* decorInfo = new(std::nothrow) DecorInfo(ref); if (decorInfo == NULL || decorInfo->InitCheck() != B_OK) { fprintf(stderr, "DecorInfoUtility::_ScanDecorators()\tInitCheck() " "failure on decorator, skipping.\n"); delete decorInfo; continue; } fList.AddItem(decorInfo); } return B_OK; }
bool DecorManager::SetR5Decorator(int32 value) { BString string; switch (value) { case 0: string = "BeOS"; break; case 1: string = "AmigaOS"; break; case 2: string = "Windows"; break; case 3: string = "MacOS"; break; default: return false; } DecorInfo *newDecInfo = _FindDecor(string.String()); if (newDecInfo) { fCurrentDecor = newDecInfo; return true; } return false; }
status_t DecorInfoUtility::ScanDecorators() { BPath decorPath; status_t ret = find_directory(B_USER_ADDONS_DIRECTORY, &decorPath); if (ret != B_OK) return ret; ret = decorPath.Append("decorators"); if (ret != B_OK) return ret; BDirectory dir(decorPath.Path()); ret = dir.InitCheck(); if (ret != B_OK) { fprintf(stderr, "DecorInfoUtility::ScanDecorators:\tERROR: " "DECORATORS_DIR not found!\n"); return ret; } BAutolock _(fLock); // First, run through our list and DecorInfos CheckForChanges() if (fHasScanned) { for (int i = fList.CountItems() - 1; i > 0; --i) { DecorInfo* decorInfo = fList.ItemAt(i); bool deleted = false; decorInfo->CheckForChanges(deleted); if (deleted) { fList.RemoveItem(decorInfo); delete decorInfo; } } } BPath path; entry_ref ref; // Now, look at file system, skip the entries for which we already have // a DecorInfo in the list. while (dir.GetNextRef(&ref) == B_OK) { path.SetTo(decorPath.Path()); path.Append(ref.name); if (_FindDecor(path.Path()) != NULL) continue; DecorInfo* decorInfo = new(std::nothrow) DecorInfo(ref); if (decorInfo == NULL || decorInfo->InitCheck() != B_OK) { fprintf(stderr, "DecorInfoUtility::ScanDecorators()\tInitCheck() " "failure on decorator, skipping\n"); delete decorInfo; continue; } fList.AddItem(decorInfo); } fHasScanned = true; return B_OK; }