Cleanup for decorator management code
Updated a couple headers Moved all decorator code to ServerApp where it belongs Modified AppServer::Broadcast to allow ServerApps send messages to all apps without having to have a global AppServer instance git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13204 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1b5aeb312e
commit
550d6a5375
@ -1,29 +1,9 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||
//
|
||||
// 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 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 MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
//
|
||||
// File Name: AppServer.cpp
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Description: main manager object for the app_server
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#include <Accelerant.h>
|
||||
#include <AppDefs.h>
|
||||
#include <Directory.h>
|
||||
@ -38,6 +18,7 @@
|
||||
#include "BitmapManager.h"
|
||||
#include "ColorSet.h"
|
||||
#include "CursorManager.h"
|
||||
#include "DecorManager.h"
|
||||
#include "DefaultDecorator.h"
|
||||
#include "Desktop.h"
|
||||
#include "DisplayDriver.h"
|
||||
@ -76,8 +57,7 @@ Desktop *gDesktop;
|
||||
|
||||
port_id gAppServerPort;
|
||||
|
||||
//! Used to access the app_server from new_decorator
|
||||
static AppServer *sAppServer = NULL;
|
||||
static AppServer *sAppServer;
|
||||
|
||||
//! Default background color for workspaces
|
||||
//RGBColor workspace_default_color(51,102,160);
|
||||
@ -114,11 +94,8 @@ AppServer::AppServer(void) :
|
||||
|
||||
fAppList = new BList();
|
||||
fQuittingServer = false;
|
||||
make_decorator = NULL;
|
||||
|
||||
// We need this in order for new_decorator to be able to instantiate new decorators
|
||||
sAppServer = this;
|
||||
|
||||
|
||||
// Create the font server and scan the proper directories.
|
||||
fontserver = new FontServer;
|
||||
fontserver->Lock();
|
||||
@ -178,8 +155,6 @@ AppServer::AppServer(void) :
|
||||
if (LoadColorSet(SERVER_SETTINGS_DIR COLOR_SETTINGS_NAME,&gui_colorset)!=B_OK)
|
||||
gui_colorset.SetToDefaults();
|
||||
|
||||
InitDecorators();
|
||||
|
||||
// Set up the Desktop
|
||||
gDesktop = new Desktop();
|
||||
gDesktop->Init();
|
||||
@ -196,16 +171,11 @@ AppServer::AppServer(void) :
|
||||
// This locker is for app_server and Picasso to vy for control of the ServerApp list
|
||||
fAppListLock = create_sem(1,"app_server_applist_sem");
|
||||
|
||||
// This locker is to mediate access to the make_decorator pointer
|
||||
fDecoratorLock = create_sem(1,"app_server_decor_sem");
|
||||
|
||||
// Spawn our thread-monitoring thread
|
||||
fPicassoThreadID = spawn_thread(PicassoThread, "picasso", B_NORMAL_PRIORITY, this);
|
||||
if (fPicassoThreadID >= 0)
|
||||
resume_thread(fPicassoThreadID);
|
||||
|
||||
fDecoratorName ="Default";
|
||||
|
||||
#if 0
|
||||
LaunchCursorThread();
|
||||
#endif
|
||||
@ -430,92 +400,6 @@ AppServer::MainLoop(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Loads the specified decorator and sets the system's decorator to it.
|
||||
\param path Path to the decorator to load
|
||||
\return True if successful, false if not.
|
||||
|
||||
If the server cannot load the specified decorator, nothing changes. Passing a
|
||||
NULL string to this function sets the decorator to the internal one.
|
||||
*/
|
||||
bool
|
||||
AppServer::LoadDecorator(const char *path)
|
||||
{
|
||||
// Loads a window decorator based on the supplied path and forces a decorator update.
|
||||
// If it cannot load the specified decorator, it will retain the current one and
|
||||
// return false. Note that passing a NULL string to this function sets the decorator
|
||||
// to the internal one.
|
||||
|
||||
// passing the string "Default" will set the window decorator to the app_server's
|
||||
// internal one
|
||||
if(!path)
|
||||
{
|
||||
make_decorator= NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
create_decorator *pcreatefunc= NULL;
|
||||
status_t stat;
|
||||
image_id addon;
|
||||
|
||||
addon = load_add_on(path);
|
||||
if (addon < B_OK)
|
||||
return false;
|
||||
|
||||
// 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 to a global would
|
||||
// go here.
|
||||
|
||||
// Get the instantiation function
|
||||
stat = get_image_symbol(addon, "instantiate_decorator",
|
||||
B_SYMBOL_TYPE_TEXT, (void**)&pcreatefunc);
|
||||
if (stat != B_OK) {
|
||||
unload_add_on(addon);
|
||||
return false;
|
||||
}
|
||||
|
||||
BPath temppath(path);
|
||||
fDecoratorName=temppath.Leaf();
|
||||
|
||||
acquire_sem(fDecoratorLock);
|
||||
make_decorator=pcreatefunc;
|
||||
fDecoratorID=addon;
|
||||
release_sem(fDecoratorLock);
|
||||
return true;
|
||||
}
|
||||
|
||||
//! Loads decorator settings on disk or the default if settings are invalid
|
||||
void
|
||||
AppServer::InitDecorators(void)
|
||||
{
|
||||
BMessage settings;
|
||||
|
||||
BDirectory dir;
|
||||
if (dir.SetTo(SERVER_SETTINGS_DIR) == B_ENTRY_NOT_FOUND)
|
||||
create_directory(SERVER_SETTINGS_DIR, 0777);
|
||||
|
||||
BString path(SERVER_SETTINGS_DIR);
|
||||
path += "DecoratorSettings";
|
||||
BFile file(path.String(), B_READ_ONLY);
|
||||
|
||||
if (file.InitCheck() == B_OK
|
||||
&& settings.Unflatten(&file) == B_OK) {
|
||||
BString itemtext;
|
||||
if (settings.FindString("decorator", &itemtext) == B_OK) {
|
||||
path.SetTo(DECORATORS_DIR);
|
||||
path += itemtext;
|
||||
if (LoadDecorator(path.String()))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We got this far, so something must have gone wrong. We set make_decorator
|
||||
// to NULL so that the decorator allocation routine knows to utilize the included
|
||||
// default decorator instead of an addon.
|
||||
make_decorator = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Message handling function for all messages sent to the app_server
|
||||
\param code ID of the message sent
|
||||
@ -650,73 +534,6 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg)
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_SET_DECORATOR:
|
||||
{
|
||||
// Received from an application when the user wants to set the window
|
||||
// decorator to a new one
|
||||
|
||||
// Attached Data:
|
||||
// char * name of the decorator in the decorators path to use
|
||||
|
||||
char *decname=NULL;
|
||||
msg.ReadString(&decname);
|
||||
if (decname) {
|
||||
if (strcmp(decname, "Default") != 0) {
|
||||
BString decpath;
|
||||
decpath.SetTo(DECORATORS_DIR);
|
||||
decpath += decname;
|
||||
if (LoadDecorator(decpath.String()))
|
||||
Broadcast(AS_UPDATE_DECORATOR);
|
||||
} else {
|
||||
LoadDecorator(NULL);
|
||||
Broadcast(AS_UPDATE_DECORATOR);
|
||||
}
|
||||
}
|
||||
free(decname);
|
||||
break;
|
||||
}
|
||||
case AS_GET_DECORATOR:
|
||||
{
|
||||
// Attached Data:
|
||||
// 1) port_id reply port
|
||||
|
||||
port_id replyport = -1;
|
||||
if (msg.Read<port_id>(&replyport)<B_OK)
|
||||
return;
|
||||
|
||||
BPrivate::PortLink replylink(replyport);
|
||||
replylink.StartMessage(AS_GET_DECORATOR);
|
||||
replylink.AttachString(fDecoratorName.String());
|
||||
replylink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_R5_SET_DECORATOR:
|
||||
{
|
||||
// Sort of supports Tracker's nifty Easter Egg. It was easy to do and
|
||||
// it's kind of neat, so why not?
|
||||
|
||||
// Attached Data:
|
||||
// char * name of the decorator in the decorators path to use
|
||||
|
||||
int32 decindex = 0;
|
||||
if (msg.Read<int32>(&decindex)<B_OK)
|
||||
break;
|
||||
|
||||
BString decpath;
|
||||
decpath.SetTo(DECORATORS_DIR);
|
||||
switch(decindex) {
|
||||
case 0: decpath+="BeOS"; break;
|
||||
case 1: decpath+="AmigaOS"; break;
|
||||
case 2: decpath+="Windows"; break;
|
||||
case 3: decpath+="MacOS"; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (LoadDecorator(decpath.String()))
|
||||
Broadcast(AS_UPDATE_DECORATOR);
|
||||
|
||||
break;
|
||||
}
|
||||
case B_QUIT_REQUESTED:
|
||||
{
|
||||
#if TEST_MODE
|
||||
@ -727,7 +544,7 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg)
|
||||
// test apps to quit. This situation will occur only when the server
|
||||
// is compiled as a regular Be application.
|
||||
|
||||
Broadcast(AS_QUIT_APP);
|
||||
BroadcastToAllApps(AS_QUIT_APP);
|
||||
|
||||
// we have to wait until *all* threads have finished!
|
||||
ServerApp *app;
|
||||
@ -788,28 +605,6 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Send a quick (no attachments) message to all applications
|
||||
|
||||
Quite useful for notification for things like server shutdown, system
|
||||
color changes, etc.
|
||||
*/
|
||||
void
|
||||
AppServer::Broadcast(int32 code)
|
||||
{
|
||||
acquire_sem(fAppListLock);
|
||||
|
||||
for (int32 i = 0; i < fAppList->CountItems(); i++) {
|
||||
ServerApp *app = (ServerApp *)fAppList->ItemAt(i);
|
||||
|
||||
if (!app)
|
||||
{ printf("PANIC in AppServer::Broadcast()\n"); continue; }
|
||||
app->PostMessage(code);
|
||||
}
|
||||
|
||||
release_sem(fAppListLock);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Finds the application with the given signature
|
||||
\param sig MIME signature of the application to find
|
||||
@ -844,41 +639,30 @@ AppServer::FindApp(const char *sig)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Send a quick (no attachments) message to all applications
|
||||
|
||||
Quite useful for notification for things like server shutdown, system
|
||||
color changes, etc.
|
||||
*/
|
||||
void
|
||||
BroadcastToAllApps(const int32 &code)
|
||||
{
|
||||
acquire_sem(sAppServer->fAppListLock);
|
||||
|
||||
for (int32 i = 0; i < sAppServer->fAppList->CountItems(); i++) {
|
||||
ServerApp *app = (ServerApp *)sAppServer->fAppList->ItemAt(i);
|
||||
|
||||
if (!app)
|
||||
{ printf("PANIC in Broadcast()\n"); continue; }
|
||||
app->PostMessage(code);
|
||||
}
|
||||
|
||||
release_sem(sAppServer->fAppListLock);
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
/*!
|
||||
\brief Creates a new decorator instance
|
||||
\param rect Frame size
|
||||
\param title Title string for the "window"
|
||||
\param wlook Window look type. See Window.h
|
||||
\param wfeel Window feel type. See Window.h
|
||||
\param wflags Window flags. See Window.h
|
||||
|
||||
If a decorator has not been set, we use the default one packaged in with the app_server
|
||||
being that we can't do anything with a window without one.
|
||||
*/
|
||||
Decorator *
|
||||
new_decorator(BRect rect, const char *title, int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver)
|
||||
{
|
||||
Decorator *dec=NULL;
|
||||
|
||||
if (!sAppServer->make_decorator)
|
||||
dec = new DefaultDecorator(rect, wlook, wfeel, wflags);
|
||||
else
|
||||
dec = sAppServer->make_decorator(rect, wlook, wfeel, wflags);
|
||||
|
||||
gui_colorset.Lock();
|
||||
dec->SetDriver(ddriver);
|
||||
dec->SetColors(gui_colorset);
|
||||
dec->SetTitle(title);
|
||||
gui_colorset.Unlock();
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Entry function to run the entire server
|
||||
\param argc Number of command-line arguments present
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <Application.h>
|
||||
#include <Window.h>
|
||||
#include <String.h>
|
||||
#include "Decorator.h"
|
||||
|
||||
#include "ServerConfig.h"
|
||||
|
||||
class Layer;
|
||||
@ -22,6 +22,8 @@ class ServerApp;
|
||||
class DisplayDriver;
|
||||
class CursorManager;
|
||||
class BitmapManager;
|
||||
class DecorManager;
|
||||
class ColorSet;
|
||||
|
||||
namespace BPrivate {
|
||||
class PortLink;
|
||||
@ -42,64 +44,48 @@ class AppServer
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
AppServer(void);
|
||||
~AppServer(void);
|
||||
AppServer(void);
|
||||
~AppServer(void);
|
||||
|
||||
static int32 PollerThread(void *data);
|
||||
static int32 PicassoThread(void *data);
|
||||
thread_id Run(void);
|
||||
void MainLoop(void);
|
||||
static int32 PollerThread(void *data);
|
||||
static int32 PicassoThread(void *data);
|
||||
thread_id Run(void);
|
||||
void MainLoop(void);
|
||||
|
||||
bool LoadDecorator(const char *path);
|
||||
void InitDecorators(void);
|
||||
|
||||
void DispatchMessage(int32 code, BPrivate::PortLink &link);
|
||||
void Broadcast(int32 code);
|
||||
|
||||
ServerApp* FindApp(const char *sig);
|
||||
void DispatchMessage(int32 code, BPrivate::PortLink &link);
|
||||
ServerApp* FindApp(const char *sig);
|
||||
|
||||
private:
|
||||
void LaunchCursorThread();
|
||||
void LaunchInputServer();
|
||||
static int32 CursorThread(void *data);
|
||||
friend void BroadcastToAllApps(const int32 &code);
|
||||
|
||||
void LaunchCursorThread();
|
||||
void LaunchInputServer();
|
||||
static int32 CursorThread(void *data);
|
||||
|
||||
friend Decorator* new_decorator(BRect rect, const char *title,
|
||||
int32 wlook, int32 wfeel, int32 wflags, DisplayDriver *ddriver);
|
||||
port_id fMessagePort;
|
||||
port_id fServerInputPort;
|
||||
|
||||
volatile bool fQuittingServer;
|
||||
|
||||
BList *fAppList;
|
||||
thread_id fPicassoThreadID;
|
||||
|
||||
// global function pointer
|
||||
create_decorator *make_decorator;
|
||||
|
||||
port_id fMessagePort;
|
||||
port_id fServerInputPort;
|
||||
|
||||
image_id fDecoratorID;
|
||||
|
||||
BString fDecoratorName;
|
||||
|
||||
volatile bool fQuittingServer;
|
||||
|
||||
BList *fAppList;
|
||||
thread_id fPicassoThreadID;
|
||||
thread_id fISThreadID;
|
||||
thread_id fCursorThreadID;
|
||||
sem_id fCursorSem;
|
||||
area_id fCursorArea;
|
||||
uint32 *fCursorAddr;
|
||||
|
||||
thread_id fISThreadID;
|
||||
thread_id fCursorThreadID;
|
||||
sem_id fCursorSem;
|
||||
area_id fCursorArea;
|
||||
uint32 *fCursorAddr;
|
||||
|
||||
port_id fISASPort;
|
||||
port_id fISPort;
|
||||
port_id fISASPort;
|
||||
port_id fISPort;
|
||||
|
||||
sem_id fActiveAppLock,
|
||||
fAppListLock,
|
||||
fDecoratorLock;
|
||||
sem_id fActiveAppLock;
|
||||
sem_id fAppListLock;
|
||||
sem_id fDecoratorLock;
|
||||
|
||||
DisplayDriver *fDriver;
|
||||
DisplayDriver *fDriver;
|
||||
};
|
||||
|
||||
Decorator *new_decorator(BRect rect, const char *title, int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver);
|
||||
|
||||
extern BitmapManager *bitmapmanager;
|
||||
extern ColorSet gui_colorset;
|
||||
extern AppServer *app_server;
|
||||
|
285
src/servers/app/DecorManager.cpp
Normal file
285
src/servers/app/DecorManager.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Rect.h>
|
||||
#include <File.h>
|
||||
#include <Message.h>
|
||||
#include <Entry.h>
|
||||
|
||||
#include "ColorSet.h"
|
||||
#include "DefaultDecorator.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "DecorManager.h"
|
||||
|
||||
// Globals
|
||||
DecorManager gDecorManager;
|
||||
|
||||
extern ColorSet gui_colorset;
|
||||
|
||||
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
|
||||
class DecorInfo
|
||||
{
|
||||
public:
|
||||
DecorInfo(const image_id &id, const char *name,
|
||||
create_decorator *alloc);
|
||||
~DecorInfo(void);
|
||||
image_id GetID(void) const { return fID; }
|
||||
const char * GetName(void) const { return fName.String(); }
|
||||
Decorator * Instantiate(BRect rect, const char *title,
|
||||
int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver);
|
||||
private:
|
||||
|
||||
image_id fID;
|
||||
BString fName;
|
||||
create_decorator *fAllocator;
|
||||
};
|
||||
|
||||
DecorInfo::DecorInfo(const image_id &id, const char *name, create_decorator *alloc)
|
||||
: fID(id),
|
||||
fName(name),
|
||||
fAllocator(alloc)
|
||||
{
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
Decorator *
|
||||
DecorInfo::Instantiate(BRect rect, const char *title, int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver)
|
||||
{
|
||||
Decorator *dec = fAllocator(rect, wlook, wfeel, wflags);
|
||||
|
||||
dec->SetDriver(ddriver);
|
||||
|
||||
gui_colorset.Lock();
|
||||
dec->SetColors(gui_colorset);
|
||||
gui_colorset.Unlock();
|
||||
|
||||
dec->SetTitle(title);
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
DecorManager::DecorManager(void)
|
||||
: fDecorList(0),
|
||||
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();
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
if(!fCurrentDecor)
|
||||
fCurrentDecor = (DecorInfo*) fDecorList.ItemAt(0L);
|
||||
}
|
||||
|
||||
DecorManager::~DecorManager(void)
|
||||
{
|
||||
EmptyList();
|
||||
}
|
||||
|
||||
void
|
||||
DecorManager::RescanDecorators(void)
|
||||
{
|
||||
BDirectory dir(DECORATORS_DIR);
|
||||
|
||||
if(dir.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
entry_ref ref;
|
||||
BString fullpath;
|
||||
|
||||
while(dir.GetNextRef(&ref)==B_OK)
|
||||
{
|
||||
fullpath = DECORATORS_DIR;
|
||||
fullpath += 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 tempID = load_add_on(fullpath.String());
|
||||
if(tempID == B_ERROR)
|
||||
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(tempID, "instantiate_decorator",
|
||||
B_SYMBOL_TYPE_TEXT, (void**)&createfunc);
|
||||
|
||||
if (status != B_OK)
|
||||
{
|
||||
unload_add_on(tempID);
|
||||
continue;
|
||||
}
|
||||
|
||||
fDecorList.AddItem( new DecorInfo(tempID, ref.name, createfunc) );
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if(!fCurrentDecor)
|
||||
{
|
||||
// We should *never* be here. If we do, it's a bug.
|
||||
debugger("DecorManager::AllocateDecorator has a NULL decorator");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fCurrentDecor->Instantiate(rect,title,wlook,wfeel,wflags,ddriver);
|
||||
}
|
||||
|
||||
int32
|
||||
DecorManager::CountDecorators(void) const
|
||||
{
|
||||
return fDecorList.CountItems();
|
||||
}
|
||||
|
||||
int32
|
||||
DecorManager::GetDecorator(void) const
|
||||
{
|
||||
return fDecorList.IndexOf( fCurrentDecor );
|
||||
}
|
||||
|
||||
bool
|
||||
DecorManager::SetDecorator(const int32 &index)
|
||||
{
|
||||
DecorInfo *newDecInfo = (DecorInfo*) fDecorList.ItemAt(index);
|
||||
|
||||
if(newDecInfo)
|
||||
{
|
||||
fCurrentDecor = newDecInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DecorManager::SetR5Decorator(const 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;
|
||||
}
|
||||
|
||||
const char *
|
||||
DecorManager::GetDecoratorName(const int32 &index)
|
||||
{
|
||||
DecorInfo *info = (DecorInfo*) fDecorList.ItemAt(index);
|
||||
|
||||
if(info)
|
||||
return info->GetName();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
DecorManager::EmptyList(void)
|
||||
{
|
||||
for(int32 i=0; i < fDecorList.CountItems(); i++)
|
||||
{
|
||||
DecorInfo *info=(DecorInfo*)fDecorList.ItemAt(i);
|
||||
delete info;
|
||||
}
|
||||
|
||||
fCurrentDecor = NULL;
|
||||
}
|
||||
|
||||
DecorInfo*
|
||||
DecorManager::FindDecor(const char *name)
|
||||
{
|
||||
if(!name)
|
||||
return NULL;
|
||||
|
||||
for(int32 i=0; i<fDecorList.CountItems(); i++)
|
||||
{
|
||||
DecorInfo *info = (DecorInfo*) fDecorList.ItemAt(i);
|
||||
|
||||
if(info && strcmp(name, info->GetName())==0 )
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This is the allocator function for the default decorator
|
||||
Decorator* create_default_decorator(BRect rect, int32 wlook, int32 wfeel, int32 wflags)
|
||||
{
|
||||
return new DefaultDecorator(rect,wlook,wfeel,wflags);
|
||||
}
|
||||
|
53
src/servers/app/DecorManager.h
Normal file
53
src/servers/app/DecorManager.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
*/
|
||||
#ifndef DECORMANAGER_H
|
||||
#define DECORMANAGER_H
|
||||
|
||||
#include <image.h>
|
||||
#include <String.h>
|
||||
#include <Locker.h>
|
||||
#include <List.h>
|
||||
|
||||
#include "Decorator.h"
|
||||
#include "DisplayDriver.h"
|
||||
|
||||
class DecorInfo;
|
||||
|
||||
class DecorManager : public BLocker
|
||||
{
|
||||
public:
|
||||
DecorManager(void);
|
||||
~DecorManager(void);
|
||||
|
||||
void RescanDecorators(void);
|
||||
|
||||
Decorator * AllocateDecorator(BRect rect, const char *title,
|
||||
int32 wlook, int32 wfeel,
|
||||
int32 wflags, DisplayDriver *ddriver);
|
||||
|
||||
int32 CountDecorators(void) const;
|
||||
|
||||
int32 GetDecorator(void) const;
|
||||
bool SetDecorator(const int32 &index);
|
||||
bool SetR5Decorator(const int32 &value);
|
||||
const char * GetDecoratorName(const int32 &index);
|
||||
|
||||
// TODO: Implement this method once the rest of the necessary infrastructure
|
||||
// is in place
|
||||
// status_t GetPreview(const int32 &index, ServerBitmap *bitmap);
|
||||
|
||||
private:
|
||||
void EmptyList(void);
|
||||
DecorInfo* FindDecor(const char *name);
|
||||
|
||||
BList fDecorList;
|
||||
DecorInfo* fCurrentDecor;
|
||||
};
|
||||
|
||||
extern DecorManager gDecorManager;
|
||||
|
||||
#endif
|
@ -82,6 +82,7 @@ Server app_server :
|
||||
Desktop.cpp
|
||||
ServerApp.cpp
|
||||
ServerWindow.cpp
|
||||
DecorManager.cpp
|
||||
|
||||
# DisplayDriver Classes
|
||||
$(VIEW_DRIVER_SOURCES)
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "BitmapManager.h"
|
||||
#include "BGet++.h"
|
||||
#include "CursorManager.h"
|
||||
|
||||
#include "DecorManager.h"
|
||||
#include "Desktop.h"
|
||||
#include "DisplayDriver.h"
|
||||
#include "FontServer.h"
|
||||
@ -547,6 +547,72 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_SET_DECORATOR:
|
||||
{
|
||||
// Received from an application when the user wants to set the window
|
||||
// decorator to a new one
|
||||
|
||||
// Attached Data:
|
||||
// int32 the index of the decorator to use
|
||||
|
||||
int32 index;
|
||||
link.Read<int32>(&index);
|
||||
if(gDecorManager.SetDecorator(index))
|
||||
BroadcastToAllApps(AS_UPDATE_DECORATOR);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_COUNT_DECORATORS:
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(gDecorManager.CountDecorators());
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_GET_DECORATOR:
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(gDecorManager.GetDecorator());
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_GET_DECORATOR_NAME:
|
||||
{
|
||||
int32 index;
|
||||
link.Read<int32>(&index);
|
||||
|
||||
BString str(gDecorManager.GetDecoratorName(index));
|
||||
if(str.CountChars() > 0)
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.AttachString(str.String());
|
||||
}
|
||||
else
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_R5_SET_DECORATOR:
|
||||
{
|
||||
// Sort of supports Tracker's nifty Easter Egg. It was easy to do and
|
||||
// it's kind of neat, so why not?
|
||||
|
||||
// Attached Data:
|
||||
// int32 value of the decorator to use
|
||||
// 0: BeOS
|
||||
// 1: Amiga
|
||||
// 2: Windows
|
||||
// 3: MacOS
|
||||
|
||||
int32 decindex = 0;
|
||||
link.Read<int32>(&decindex);
|
||||
|
||||
if(gDecorManager.SetR5Decorator(decindex))
|
||||
BroadcastToAllApps(AS_UPDATE_DECORATOR);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_CREATE_BITMAP:
|
||||
{
|
||||
STRACE(("ServerApp %s: Received BBitmap creation request\n",fSignature.String()));
|
||||
@ -650,10 +716,13 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
case AS_DOWNLOAD_PICTURE:
|
||||
{
|
||||
// TODO; Implement AS_DOWNLOAD_PICTURE
|
||||
STRACE(("ServerApp %s: Download Picture unimplemented\n", fSignature.String()));
|
||||
|
||||
// What is this particular function call for, anyway?
|
||||
STRACE(("ServerApp %s: Download Picture unimplemented\n", fSignature.String()));
|
||||
|
||||
|
||||
// DW: I think originally it might have been to support
|
||||
// the undocumented Flatten function.
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -906,8 +975,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<ColorSet>(&gui_colorset);
|
||||
gui_colorset.Unlock();
|
||||
|
||||
// TODO: Broadcast an AS_UPDATE_COLORS to all apps
|
||||
|
||||
BroadcastToAllApps(AS_UPDATE_COLORS);
|
||||
break;
|
||||
}
|
||||
case AS_GET_UI_COLOR:
|
||||
@ -927,6 +995,7 @@ ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
|
||||
case AS_UPDATED_CLIENT_FONTLIST:
|
||||
{
|
||||
STRACE(("ServerApp %s: Acknowledged update of client-side font list\n",
|
||||
|
@ -1,31 +1,11 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||
//
|
||||
// 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 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 MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
//
|
||||
// File Name: WinBorder.cpp
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@cotty.iren.ro>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Layer subclass which handles window management
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
* Adi Oanca <adioanca@cotty.iren.ro>
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
#include <Locker.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
@ -34,8 +14,8 @@
|
||||
#include <Debug.h>
|
||||
#include "DebugInfoManager.h"
|
||||
|
||||
#include "AppServer.h" // for new_decorator()
|
||||
#include "Decorator.h"
|
||||
#include "DecorManager.h"
|
||||
#include "Desktop.h"
|
||||
#include "Globals.h"
|
||||
#include "MessagePrivate.h"
|
||||
@ -135,7 +115,8 @@ WinBorder::WinBorder(const BRect &r,
|
||||
QuietlySetFeel(wfeel);
|
||||
|
||||
if (fFeel != B_NO_BORDER_WINDOW_LOOK) {
|
||||
fDecorator = new_decorator(r, name, fLook, fFeel, fWindowFlags, fDriver);
|
||||
fDecorator = gDecorManager.AllocateDecorator(r, name, fLook, fFeel,
|
||||
fWindowFlags, fDriver);
|
||||
if (fDecorator)
|
||||
fDecorator->GetSizeLimits(&fMinWidth, &fMinHeight, &fMaxWidth, &fMaxHeight);
|
||||
}
|
||||
|
@ -1,31 +1,11 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||
//
|
||||
// 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 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 MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
//
|
||||
// File Name: WinBorder.h
|
||||
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
// Adi Oanca <adioanca@cotty.iren.ro>
|
||||
// Stephan Aßmus <superstippi@gmx.de>
|
||||
// Description: Layer subclass which handles window management
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2001-2005, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||
* Adi Oanca <adioanca@cotty.iren.ro>
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
#ifndef _WINBORDER_H_
|
||||
#define _WINBORDER_H_
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user