2005-06-17 23:10:15 +04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2001-2005, Haiku, Inc.
|
|
|
|
* Distributed under the terms of the MIT license.
|
|
|
|
*
|
|
|
|
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
|
|
|
*/
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
#include <Directory.h>
|
|
|
|
#include <Rect.h>
|
|
|
|
#include <File.h>
|
|
|
|
#include <Message.h>
|
|
|
|
#include <Entry.h>
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
#include "AppServer.h"
|
2005-06-17 23:10:15 +04:00
|
|
|
#include "ColorSet.h"
|
|
|
|
#include "DefaultDecorator.h"
|
|
|
|
#include "ServerConfig.h"
|
|
|
|
#include "DecorManager.h"
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// Globals
|
|
|
|
DecorManager gDecorManager;
|
|
|
|
|
|
|
|
|
|
|
|
Decorator* create_default_decorator(BRect rect, int32 wlook, int32 wfeel,
|
|
|
|
int32 wflags);
|
|
|
|
|
|
|
|
// This is a class used only by the DecorManager to track all the decorators in memory
|
2005-06-24 07:31:41 +04:00
|
|
|
class DecorInfo {
|
2005-06-17 23:10:15 +04:00
|
|
|
public:
|
|
|
|
DecorInfo(const image_id &id, const char *name,
|
|
|
|
create_decorator *alloc);
|
|
|
|
~DecorInfo(void);
|
|
|
|
image_id GetID(void) const { return fID; }
|
2005-06-24 07:31:41 +04:00
|
|
|
const char* GetName(void) const { return fName.String(); }
|
|
|
|
Decorator* Instantiate(BRect rect, const char *title,
|
2005-06-17 23:10:15 +04:00
|
|
|
int32 wlook, int32 wfeel,
|
|
|
|
int32 wflags, DisplayDriver *ddriver);
|
|
|
|
private:
|
|
|
|
image_id fID;
|
|
|
|
BString fName;
|
|
|
|
create_decorator *fAllocator;
|
|
|
|
};
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
DecorInfo::DecorInfo(const image_id &id, const char *name, create_decorator *alloc)
|
2005-06-24 07:31:41 +04:00
|
|
|
:
|
|
|
|
fID(id),
|
2005-06-17 23:10:15 +04:00
|
|
|
fName(name),
|
|
|
|
fAllocator(alloc)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
DecorInfo::~DecorInfo(void)
|
|
|
|
{
|
|
|
|
// Do nothing. Normal programming practice would say that one should unload
|
|
|
|
// the object's associate image_id. However, there is some funkiness with
|
|
|
|
// the R5 kernel in which addons aren't unloaded when unload_add_on() is
|
|
|
|
// called -- perhaps it's lazy unloading or something. In any event, it
|
|
|
|
// causes crashes which are *extremely* hard to track down to this.
|
|
|
|
|
|
|
|
// Considering the usage of DecorInfo and DecorManager, we can live with
|
|
|
|
// this because the app_server will not the DecorManager is freed only
|
|
|
|
// when the app_server quits. It's not pretty, but it gets the job done.
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
Decorator *
|
|
|
|
DecorInfo::Instantiate(BRect rect, const char *title, int32 wlook, int32 wfeel,
|
2005-06-24 07:31:41 +04:00
|
|
|
int32 wflags, DisplayDriver *ddriver)
|
2005-06-17 23:10:15 +04:00
|
|
|
{
|
|
|
|
Decorator *dec = fAllocator(rect, wlook, wfeel, wflags);
|
|
|
|
|
|
|
|
dec->SetDriver(ddriver);
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
gGUIColorSet.Lock();
|
|
|
|
dec->SetColors(gGUIColorSet);
|
|
|
|
gGUIColorSet.Unlock();
|
2005-06-17 23:10:15 +04:00
|
|
|
|
|
|
|
dec->SetTitle(title);
|
|
|
|
|
|
|
|
return dec;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
|
|
|
DecorManager::DecorManager()
|
|
|
|
:
|
|
|
|
fDecorList(0),
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor(NULL)
|
|
|
|
{
|
|
|
|
// Start with the default decorator - index is always 0
|
|
|
|
DecorInfo *defaultDecor = new DecorInfo(-1, "Default", create_default_decorator);
|
|
|
|
fDecorList.AddItem( defaultDecor );
|
|
|
|
|
|
|
|
// Add any on disk
|
|
|
|
RescanDecorators();
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// 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);
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
BMessage settings;
|
|
|
|
BFile file(SERVER_SETTINGS_DIR "decorator_settings", B_READ_ONLY);
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// Fallback to the default decorator if something goes wrong
|
2005-06-24 07:31:41 +04:00
|
|
|
if (file.InitCheck() == B_OK && settings.Unflatten(&file) == B_OK) {
|
2005-06-17 23:10:15 +04:00
|
|
|
BString itemtext;
|
2005-06-24 07:31:41 +04:00
|
|
|
if (settings.FindString("decorator", &itemtext) == B_OK) {
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor = FindDecor(itemtext.String());
|
|
|
|
}
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
if (!fCurrentDecor)
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor = (DecorInfo*) fDecorList.ItemAt(0L);
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
DecorManager::~DecorManager()
|
2005-06-17 23:10:15 +04:00
|
|
|
{
|
|
|
|
EmptyList();
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
void
|
2005-06-24 07:31:41 +04:00
|
|
|
DecorManager::RescanDecorators()
|
2005-06-17 23:10:15 +04:00
|
|
|
{
|
|
|
|
BDirectory dir(DECORATORS_DIR);
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
if (dir.InitCheck() != B_OK)
|
2005-06-17 23:10:15 +04:00
|
|
|
return;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
entry_ref ref;
|
|
|
|
BString fullpath;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
while (dir.GetNextRef(&ref) == B_OK) {
|
2005-06-17 23:10:15 +04:00
|
|
|
fullpath = DECORATORS_DIR;
|
|
|
|
fullpath += ref.name;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// 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.
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
if (FindDecor(ref.name))
|
2005-06-17 23:10:15 +04:00
|
|
|
continue;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
image_id tempID = load_add_on(fullpath.String());
|
2005-06-24 07:31:41 +04:00
|
|
|
if (tempID == B_ERROR)
|
2005-06-17 23:10:15 +04:00
|
|
|
continue;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// 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.
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
create_decorator *createfunc;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// Get the instantiation function
|
|
|
|
status_t status = get_image_symbol(tempID, "instantiate_decorator",
|
|
|
|
B_SYMBOL_TYPE_TEXT, (void**)&createfunc);
|
2005-06-24 07:31:41 +04:00
|
|
|
if (status != B_OK) {
|
2005-06-17 23:10:15 +04:00
|
|
|
unload_add_on(tempID);
|
|
|
|
continue;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
fDecorList.AddItem(new DecorInfo(tempID, ref.name, createfunc));
|
2005-06-17 23:10:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
Decorator *
|
|
|
|
DecorManager::AllocateDecorator(BRect rect, const char *title,
|
|
|
|
int32 wlook, int32 wfeel,
|
|
|
|
int32 wflags, DisplayDriver *ddriver)
|
|
|
|
{
|
|
|
|
// Create a new instance of the current decorator. Ownership is that of the caller
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
if (!fCurrentDecor) {
|
2005-06-17 23:10:15 +04:00
|
|
|
// We should *never* be here. If we do, it's a bug.
|
|
|
|
debugger("DecorManager::AllocateDecorator has a NULL decorator");
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
return fCurrentDecor->Instantiate(rect, title, wlook, wfeel, wflags, ddriver);
|
2005-06-17 23:10:15 +04:00
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
int32
|
|
|
|
DecorManager::CountDecorators(void) const
|
|
|
|
{
|
|
|
|
return fDecorList.CountItems();
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
int32
|
|
|
|
DecorManager::GetDecorator(void) const
|
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
return fDecorList.IndexOf(fCurrentDecor);
|
2005-06-17 23:10:15 +04:00
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
bool
|
|
|
|
DecorManager::SetDecorator(const int32 &index)
|
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
DecorInfo *newDecInfo = (DecorInfo*)fDecorList.ItemAt(index);
|
|
|
|
|
|
|
|
if (newDecInfo) {
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor = newDecInfo;
|
|
|
|
return true;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
bool
|
|
|
|
DecorManager::SetR5Decorator(const int32 &value)
|
|
|
|
{
|
|
|
|
BString string;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
switch (value) {
|
|
|
|
case 0: string = "BeOS"; break;
|
|
|
|
case 1: string = "AmigaOS"; break;
|
|
|
|
case 2: string = "Windows"; break;
|
|
|
|
case 3: string = "MacOS"; break;
|
2005-06-17 23:10:15 +04:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
DecorInfo *newDecInfo = FindDecor(string.String());
|
2005-06-24 07:31:41 +04:00
|
|
|
if (newDecInfo) {
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor = newDecInfo;
|
|
|
|
return true;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
const char *
|
|
|
|
DecorManager::GetDecoratorName(const int32 &index)
|
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
DecorInfo *info = (DecorInfo*)fDecorList.ItemAt(index);
|
|
|
|
|
|
|
|
if (info)
|
2005-06-17 23:10:15 +04:00
|
|
|
return info->GetName();
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
void
|
|
|
|
DecorManager::EmptyList(void)
|
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
for (int32 i = 0; i < fDecorList.CountItems(); i++) {
|
|
|
|
DecorInfo *info = (DecorInfo*)fDecorList.ItemAt(i);
|
2005-06-17 23:10:15 +04:00
|
|
|
delete info;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
fCurrentDecor = NULL;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
DecorInfo*
|
|
|
|
DecorManager::FindDecor(const char *name)
|
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
if (!name)
|
2005-06-17 23:10:15 +04:00
|
|
|
return NULL;
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
for (int32 i = 0; i < fDecorList.CountItems(); i++) {
|
|
|
|
DecorInfo *info = (DecorInfo*)fDecorList.ItemAt(i);
|
|
|
|
|
|
|
|
if (info && strcmp(name, info->GetName()) == 0)
|
2005-06-17 23:10:15 +04:00
|
|
|
return info;
|
|
|
|
}
|
2005-06-24 07:31:41 +04:00
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-06-24 07:31:41 +04:00
|
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
2005-06-17 23:10:15 +04:00
|
|
|
// This is the allocator function for the default decorator
|
2005-06-24 07:31:41 +04:00
|
|
|
Decorator*
|
|
|
|
create_default_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
|
2005-06-17 23:10:15 +04:00
|
|
|
{
|
2005-06-24 07:31:41 +04:00
|
|
|
return new DefaultDecorator(rect, wlook, wfeel, wflags);
|
2005-06-17 23:10:15 +04:00
|
|
|
}
|
|
|
|
|