From 91515d2132d38f9099624ee5c3b824440aa97936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 16 Jun 2005 21:33:29 +0000 Subject: [PATCH] With the recent changes to the communication mechanism, fake_app_server did not work anymore, and thus, the safemode with the current Bootscript did not work. It now does again. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13192 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/apps/fake_app_server/AppServer.cpp | 499 +++++--- src/tests/apps/fake_app_server/AppServer.h | 67 +- src/tests/apps/fake_app_server/ServerApp.cpp | 1167 ++++-------------- src/tests/apps/fake_app_server/ServerApp.h | 97 +- 4 files changed, 727 insertions(+), 1103 deletions(-) diff --git a/src/tests/apps/fake_app_server/AppServer.cpp b/src/tests/apps/fake_app_server/AppServer.cpp index 7e0c7fddf5..4014c17e75 100644 --- a/src/tests/apps/fake_app_server/AppServer.cpp +++ b/src/tests/apps/fake_app_server/AppServer.cpp @@ -24,34 +24,32 @@ // Description: main manager object for the app_server // //------------------------------------------------------------------------------ -#include #include -#include -#include +#include #include -#include - +#include #include #include -#include "AppServer.h" -#include "ServerProtocol.h" -#include "ServerApp.h" -#include -#if 0 +#include +#include +#include + +#include "BitmapManager.h" #include "ColorSet.h" #include "DisplayDriver.h" -#include "ServerCursor.h" -#include "ServerWindow.h" -#include "DefaultDecorator.h" -#include "RGBColor.h" -#include "BitmapManager.h" -#include "CursorManager.h" -#include "Utils.h" #include "FontServer.h" -#include "Desktop.h" -#include "RootLayer.h" -#endif -#include +#include "RegistrarDefs.h" +#include "RGBColor.h" +#include "ServerApp.h" +#include "ServerCursor.h" +#include "ServerProtocol.h" +#include "SystemPalette.h" +#include "Utils.h" + +#include "AppServer.h" + +//#define DEBUG_KEYHANDLING +//#define DEBUG_SERVER #ifdef DEBUG_KEYHANDLING # include @@ -60,63 +58,133 @@ # define KBTRACE(x) ; #endif -//#define DEBUG_SERVER #ifdef DEBUG_SERVER -# define DEBUG 1 -# include -# define STRACE(x) _sPrintf x +# include +# define STRACE(x) printf x #else # define STRACE(x) ; #endif // Globals +port_id gAppServerPort; + +//! Used to access the app_server from new_decorator +static AppServer *sAppServer = NULL; + +//! Default background color for workspaces +//RGBColor workspace_default_color(51,102,160); + + +/*! + \brief Constructor + + This loads the default fonts, allocates all the major global variables, spawns the main housekeeping + threads, loads user preferences for the UI and decorator, and allocates various locks. +*/ AppServer::AppServer(void) + : + fCursorSem(-1), + fCursorArea(-1) { fMessagePort = create_port(200, SERVER_PORT_NAME); + if (fMessagePort == B_NO_MORE_PORTS) + debugger("app_server could not create message port"); - fAppList = new BList(0); - fQuittingServer= false; + gAppServerPort = fMessagePort; + + // Create the input port. The input_server will send it's messages here. + // TODO: If we want multiple user support we would need an individual + // port for each user and do the following for each RootLayer. + fServerInputPort = create_port(200, SERVER_INPUT_PORT); + if (fServerInputPort == B_NO_MORE_PORTS) + debugger("app_server could not create input port"); + + 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; // This is necessary to mediate access between the Poller and app_server threads - fActiveAppLock= create_sem(1,"app_server_active_sem"); + fActiveAppLock = create_sem(1,"app_server_active_sem"); // This locker is for app_server and Picasso to vy for control of the ServerApp list - fAppListLock= create_sem(1,"app_server_applist_sem"); + 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); + fPicassoThreadID = spawn_thread(PicassoThread, "picasso", B_NORMAL_PRIORITY, this); if (fPicassoThreadID >= 0) resume_thread(fPicassoThreadID); + + fDecoratorName ="Default"; + +#if 0 + LaunchCursorThread(); +#endif } - +/*! + \brief Destructor + + Reached only when the server is asked to shut down in Test mode. Kills all apps, shuts down the + desktop, kills the housekeeping threads, etc. +*/ AppServer::~AppServer(void) { + debugger("We shouldn't be here! MainLoop()::B_QUIT_REQUESTED should see if we can exit the server.\n"); +/* + ServerApp *tempapp; + int32 i; + acquire_sem(fAppListLock); + for(i=0;iCountItems();i++) + { + tempapp=(ServerApp *)fAppList->ItemAt(i); + if(tempapp!=NULL) + delete tempapp; + } + delete fAppList; + release_sem(fAppListLock); + + delete bitmapmanager; + + delete gDesktop; + + // If these threads are still running, kill them - after this, if exit_poller + // is deleted, who knows what will happen... These things will just return an + // error and fail if the threads have already exited. + kill_thread(fPicassoThreadID); + kill_thread(fCursorThreadID); + kill_thread(fISThreadID); + + delete fontserver; + + make_decorator=NULL; +*/ } - +/*! + \brief Thread function for watching for dead apps + \param data Pointer to the app_server to which the thread belongs + \return Throwaway value - always 0 +*/ int32 AppServer::PicassoThread(void *data) { - int32 i; - AppServer *appserver=(AppServer*)data; - ServerApp *app; - for(;;) - { - i = 0; -#if 1 - acquire_sem(appserver->fAppListLock); - for(;;) - { - app=(ServerApp*)appserver->fAppList->ItemAt(i++); - if(!app) + for (;;) { + acquire_sem(sAppServer->fAppListLock); + for (int32 i = 0;;) { + ServerApp *app = (ServerApp *)sAppServer->fAppList->ItemAt(i++); + if (!app) break; app->PingTarget(); } - release_sem(appserver->fAppListLock); -#endif + release_sem(sAppServer->fAppListLock); // we do this every other second so as not to suck *too* many CPU cycles snooze(1000000); } @@ -124,6 +192,28 @@ AppServer::PicassoThread(void *data) } +/*! + \brief Starts Input Server +*/ +void +AppServer::LaunchInputServer() +{ +} + + +/*! + \brief Starts the Cursor Thread +*/ +void +AppServer::LaunchCursorThread() +{ +} + + +/*! + \brief The call that starts it all... + \return Always 0 +*/ thread_id AppServer::Run(void) { @@ -137,23 +227,19 @@ AppServer::Run(void) void AppServer::MainLoop(void) { - BPrivate::PortLink pmsg(-1,fMessagePort); - int32 code=0; - status_t err=B_OK; - - while(1) - { - STRACE(("info: AppServer::MainLoop listening on port %ld.\n", fMessagePort)); - err=pmsg.GetNextMessage(code); + BPrivate::PortLink pmsg(-1, fMessagePort); - if(err(&app_port); + msg.Read(&clientReplyPort); msg.Read(&clientLooperPort); msg.Read(&clientTeamID); msg.Read(&htoken); - msg.ReadString(&app_signature); - - // Create the ServerApp subthread for this app - acquire_sem(fAppListLock); - - port_id server_listen=create_port(DEFAULT_MONITOR_PORT_SIZE, app_signature); - if(server_listenAddItem(newapp); - + fAppList->AddItem(app); + release_sem(fAppListLock); - BPrivate::PortLink replylink(app_port); + BPrivate::PortLink replylink(clientReplyPort); replylink.StartMessage(SERVER_TRUE); - replylink.Attach(newapp->fMessagePort); + replylink.Attach(serverListen); replylink.Flush(); - // This is necessary because BPrivate::PortLink::ReadString allocates memory - if(app_signature) - free(app_signature); - + // This is necessary because BPortLink::ReadString allocates memory + free(appSignature); break; } case AS_DELETE_APP: { // Delete a ServerApp. Received only from the respective ServerApp when a // BApplication asks it to quit. - + // Attached Data: // 1) thread_id - thread ID of the ServerApp to be deleted - - int32 i=0, - appnum=fAppList->CountItems(); - - ServerApp *srvapp=NULL; - thread_id srvapp_id=-1; - if(msg.Read(&srvapp_id)CountItems(); + ServerApp *srvapp = NULL; + thread_id srvapp_id = -1; + + if (msg.Read(&srvapp_id) < B_OK) break; acquire_sem(fAppListLock); // Run through the list of apps and nuke the proper one - for(i= 0; i < appnum; i++) - { - srvapp=(ServerApp *)fAppList->ItemAt(i); + for (i = 0; i < appnum; i++) { + srvapp = (ServerApp *)fAppList->ItemAt(i); - if(srvapp != NULL && srvapp->fMonitorThreadID== srvapp_id) - { - srvapp=(ServerApp *)fAppList->RemoveItem(i); - if(srvapp) - { - status_t temp; - wait_for_thread(srvapp_id, &temp); + if (srvapp != NULL && srvapp->MonitorThreadID() == srvapp_id) { + srvapp = (ServerApp *)fAppList->RemoveItem(i); + if (srvapp) { delete srvapp; - srvapp= NULL; + srvapp = NULL; } break; // jump out of our for() loop } @@ -278,53 +450,94 @@ AppServer::DispatchMessage(int32 code, BPrivate::PortLink &msg) release_sem(fAppListLock); break; } -#endif - case AS_QUERY_FONTS_CHANGED: + case B_QUIT_REQUESTED: { - // Seeing how the client merely wants an answer, we'll skip the BPrivate::PortLink - // and all its overhead and just write the code to port. - port_id replyport; - if (msg.Read(&replyport) < B_OK) - break; - BPrivate::PortLink replylink(replyport); - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); break; } - case AS_GET_DECORATOR: - { - // Attached Data: - // 1) port_id reply port - - port_id replyport=-1; - if(msg.Read(&replyport)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 + \return the corresponding ServerApp or NULL if not found + + This call should be made only when necessary because it locks the app list + while it does its searching. +*/ +ServerApp * +AppServer::FindApp(const char *sig) +{ + if (!sig) + return NULL; + + ServerApp *foundapp=NULL; + + acquire_sem(fAppListLock); + + for(int32 i=0; iCountItems();i++) + { + foundapp=(ServerApp*)fAppList->ItemAt(i); + if(foundapp && foundapp->Title() == sig) + { + release_sem(fAppListLock); + return foundapp; + } + } + + release_sem(fAppListLock); + + // couldn't find a match + return NULL; +} + + +// #pragma mark - + + +/*! + \brief Entry function to run the entire server + \param argc Number of command-line arguments present + \param argv String array of the command-line arguments + \return -1 if the app_server is already running, 0 if everything's OK. +*/ int -main(int argc, char **argv) +main(int argc, char** argv) { // There can be only one.... - if (find_port(SERVER_PORT_NAME) != B_NAME_NOT_FOUND) + if (find_port(SERVER_PORT_NAME) >= B_OK) return -1; + srand(real_time_clock_usecs()); AppServer app_server; app_server.Run(); return 0; diff --git a/src/tests/apps/fake_app_server/AppServer.h b/src/tests/apps/fake_app_server/AppServer.h index be65d313be..f661ef98ad 100644 --- a/src/tests/apps/fake_app_server/AppServer.h +++ b/src/tests/apps/fake_app_server/AppServer.h @@ -1,5 +1,11 @@ -#ifndef _OPENBEOS_APP_SERVER_H_ -#define _OPENBEOS_APP_SERVER_H_ +/* + * Copyright (c) 2001-2005, Haiku, Inc. + * Distributed under the terms of the MIT license. + * + * Author: DarkWyrm + */ +#ifndef _HAIKU_APP_SERVER_H_ +#define _HAIKU_APP_SERVER_H_ #include #include @@ -21,6 +27,15 @@ namespace BPrivate { class PortLink; }; +/*! + \class AppServer AppServer.h + \brief main manager object for the app_server + + File for the main app_server thread. This particular thread monitors for + application start and quit messages. It also starts the housekeeping threads + and initializes most of the server's globals. +*/ + class AppServer { public: AppServer(void); @@ -31,18 +46,58 @@ public: 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); private: + void LaunchCursorThread(); + void LaunchInputServer(); + + friend Decorator* new_decorator(BRect rect, const char *title, + int32 wlook, int32 wfeel, int32 wflags, DisplayDriver *ddriver); + + // global function pointer + create_decorator *make_decorator; + port_id fMessagePort; - bool fQuittingServer; + 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; + + port_id fISASPort; + port_id fISPort; - sem_id fActiveAppLock, fAppListLock; + sem_id fActiveAppLock, + fAppListLock, + fDecoratorLock; + + DisplayDriver *fDriver; }; -extern AppServer *app_server; +Decorator *new_decorator(BRect rect, const char *title, int32 wlook, int32 wfeel, + int32 wflags, DisplayDriver *ddriver); -#endif +extern BitmapManager *bitmapmanager; +extern ColorSet gui_colorset; +extern AppServer *app_server; +extern port_id gAppServerPort; + +#endif /* _HAIKU_APP_SERVER_H_ */ diff --git a/src/tests/apps/fake_app_server/ServerApp.cpp b/src/tests/apps/fake_app_server/ServerApp.cpp index 95389e3ebf..ec6df44c07 100644 --- a/src/tests/apps/fake_app_server/ServerApp.cpp +++ b/src/tests/apps/fake_app_server/ServerApp.cpp @@ -1,70 +1,47 @@ -//------------------------------------------------------------------------------ -// 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: ServerApp.cpp -// Author: DarkWyrm -// Description: Server-side BApplication counterpart -// -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + * Adrian Oanca + * Stephan Aßmus + * Stefano Ceccherini (burton666@libero.it) + * Axel Dörfler, axeld@pinc-software.de + */ + + #include #include #include -#include +#include +#include #include #include #include #include +#include #include -#include #include "AppServer.h" -#include "BGet++.h" -#if 0 #include "BitmapManager.h" -#include "CursorManager.h" +#include "BGet++.h" -#include "Desktop.h" #include "DisplayDriver.h" #include "FontServer.h" -#include "RAMLinkMsgReader.h" -#include "RootLayer.h" -#endif #include "ServerApp.h" -#include "ServerConfig.h" -#include "Utils.h" -#if 0 -#include "ServerScreen.h" -#include "ServerWindow.h" #include "ServerCursor.h" #include "ServerBitmap.h" -#include "ServerPicture.h" -#include "WinBorder.h" +#include "ServerConfig.h" +#include "SystemPalette.h" #include "LayerData.h" -#endif +#include "Utils.h" //#define DEBUG_SERVERAPP + #ifdef DEBUG_SERVERAPP -# define DEBUG 1 -# include -# define STRACE(x) _sPrintf x +# include +# define STRACE(x) printf x #else # define STRACE(x) ; #endif @@ -86,95 +63,112 @@ MIME fSignature. */ ServerApp::ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort, - team_id clientTeamID, int32 handlerID, char *signature) + team_id clientTeamID, int32 handlerID, const char* signature) + : + fClientAppPort(sendport), + fMessagePort(rcvport), + fClientLooperPort(clientLooperPort), + fSignature(signature), + fMonitorThreadID(-1), + fClientTeamID(clientTeamID), + fLink(fClientAppPort, fMessagePort), + fSWindowList(new BList()), + fBitmapList(new BList()), + fPictureList(new BList()), + fAppCursor(NULL), + fLockSem(create_sem(1, "ServerApp sem")), + fCursorHidden(false), + fIsActive(false), + //fHandlerToken(handlerID), + fSharedMem(new AreaPool), + fQuitting(false) { - // it will be of *very* musch use in correct window order - fClientTeamID = clientTeamID; - - // what to send a message to the client? Write a BMessage to this port. - fClientLooperPort = clientLooperPort; - - // need to copy the fSignature because the message buffer - // owns the copy which we are passed as a parameter. - fSignature=(signature)?signature:"application/x-vnd.NULL-application-signature"; - - // token ID of the BApplication's BHandler object. Used for BMessage target specification - fHandlerToken=handlerID; - - // fClientAppPort is the our BApplication's event port - fClientAppPort=sendport; - - // fMessagePort is the port we receive messages from our BApplication - fMessagePort=rcvport; - - fMsgReader = new BPrivate::LinkReceiver(fMessagePort); - fMsgSender = new BPrivate::LinkSender(fClientAppPort); - - fIsActive=false; - - fSharedMem=new AreaPool; - fLockSem=create_sem(1,"ServerApp sem"); + if (fSignature == "") + fSignature = "application/x-vnd.NULL-application-signature"; Run(); - STRACE(("ServerApp %s:\n",fSignature.String())); - STRACE(("\tBApp port: %ld\n",fClientAppPort)); - STRACE(("\tReceiver port: %ld\n",fMessagePort)); + STRACE(("ServerApp %s:\n", fSignature.String())); + STRACE(("\tBApp port: %ld\n", fClientAppPort)); + STRACE(("\tReceiver port: %ld\n", fMessagePort)); } + //! Does all necessary teardown for application ServerApp::~ServerApp(void) { STRACE(("*ServerApp %s:~ServerApp()\n",fSignature.String())); + + fQuitting = true; + + for (int32 i = 0; i< fBitmapList->CountItems(); i++) { + delete static_cast(fBitmapList->ItemAt(i)); + } + delete fBitmapList; - delete fMsgReader; - delete fMsgSender; + delete fPictureList; + + // This shouldn't be necessary -- all cursors owned by the app + // should be cleaned up by RemoveAppCursors +// if(fAppCursor) +// delete fAppCursor; delete_sem(fLockSem); - STRACE(("#ServerApp %s:~ServerApp()\n",fSignature.String())); + STRACE(("#ServerApp %s:~ServerApp()\n", fSignature.String())); - // Kill the monitor thread if it exists - thread_info info; - if(get_thread_info(fMonitorThreadID,&info)==B_OK) - kill_thread(fMonitorThreadID); + // TODO: Is this the right place for this ? + // From what I've understood, this is the port created by + // the BApplication (?), but if I delete it in there, GetNextMessage() + // in the MonitorApp thread never returns. Cleanup. + delete_port(fMessagePort); + + status_t dummyStatus; + wait_for_thread(fMonitorThreadID, &dummyStatus); delete fSharedMem; + + STRACE(("ServerApp %s::~ServerApp(): Exiting\n", fSignature.String())); } /*! \brief Starts the ServerApp monitoring for messages \return false if the application couldn't start, true if everything went OK. */ -bool ServerApp::Run(void) +bool +ServerApp::Run(void) { // Unlike a BApplication, a ServerApp is *supposed* to return immediately - // when its Run() function is called. - fMonitorThreadID=spawn_thread(MonitorApp,fSignature.String(),B_NORMAL_PRIORITY,this); - if(fMonitorThreadID==B_NO_MORE_THREADS || fMonitorThreadID==B_NO_MEMORY) + // when its Run() function is called. + fMonitorThreadID = spawn_thread(MonitorApp, fSignature.String(), B_NORMAL_PRIORITY, this); + if (fMonitorThreadID < B_OK) return false; - resume_thread(fMonitorThreadID); - return true; + return resume_thread(fMonitorThreadID) == B_OK; } - +/*! + \brief Pings the target app to make sure it's still working + \return true if target is still "alive" and false if "He's dead, Jim." + "But that's impossible..." + + This function is called by the app_server thread to ensure that + the target app still exists. We do this not by sending a message + but by calling get_port_info. We don't want to send ping messages + just because the app might simply be hung. If this is the case, it + should be up to the user to kill it. If the app has been killed, its + ports will be invalid. Thus, if get_port_info returns an error, we + tell the app_server to delete the respective ServerApp. +*/ bool ServerApp::PingTarget(void) { team_info tinfo; - if(get_team_info(fClientTeamID,&tinfo)==B_BAD_TEAM_ID) - { - port_id serverport=find_port(SERVER_PORT_NAME); - if(serverport==B_NAME_NOT_FOUND) - { - printf("PANIC: ServerApp %s could not find the app_server port in PingTarget()!\n",fSignature.String()); - return false; - } - fMsgSender->SetPort(serverport); - fMsgSender->StartMessage(AS_DELETE_APP); - fMsgSender->Attach(&fMonitorThreadID,sizeof(thread_id)); - fMsgSender->Flush(); + if (get_team_info(fClientTeamID, &tinfo) == B_BAD_TEAM_ID) { + BPrivate::LinkSender link(gAppServerPort); + link.StartMessage(AS_DELETE_APP); + link.Attach(&fMonitorThreadID, sizeof(thread_id)); + link.Flush(); return false; } return true; @@ -184,9 +178,10 @@ ServerApp::PingTarget(void) \brief Send a message to the ServerApp with no attachments \param code ID code of the message to post */ -void ServerApp::PostMessage(int32 code) +void +ServerApp::PostMessage(int32 code) { - BPrivate::PortLink link(fMessagePort); + BPrivate::LinkSender link(fMessagePort); link.StartMessage(code); link.Flush(); } @@ -195,14 +190,12 @@ void ServerApp::PostMessage(int32 code) \brief Send a message to the ServerApp's BApplication \param msg The message to send */ -void ServerApp::SendMessageToClient(const BMessage *msg) const +void +ServerApp::SendMessageToClient(const BMessage *msg) const { - ssize_t size; - char *buffer; - - size=msg->FlattenedSize(); - buffer=new char[size]; - + ssize_t size = msg->FlattenedSize(); + char *buffer = new char[size]; + if (msg->Flatten(buffer, size) == B_OK) write_port(fClientLooperPort, msg->what, buffer, size); else @@ -218,77 +211,61 @@ void ServerApp::SendMessageToClient(const BMessage *msg) const This changes an internal flag and also sets the current cursor to the one specified by the application */ -void ServerApp::Activate(bool value) +void +ServerApp::Activate(bool value) { - fIsActive=value; + fIsActive = value; SetAppCursor(); } - + + //! Sets the cursor to the application cursor, if any. -void ServerApp::SetAppCursor(void) +void +ServerApp::SetAppCursor(void) { } + /*! \brief The thread function ServerApps use to monitor messages \param data Pointer to the thread's ServerApp object \return Throwaway value - always 0 */ -int32 ServerApp::MonitorApp(void *data) +int32 +ServerApp::MonitorApp(void *data) { // Message-dispatching loop for the ServerApp - + ServerApp *app = (ServerApp *)data; - BPrivate::LinkReceiver msgqueue(app->fMessagePort); - - bool quitting = false; + BPrivate::LinkReceiver &reader = app->fLink.Receiver(); + int32 code; status_t err = B_OK; - - while(!quitting) - { + + while (!app->fQuitting) { STRACE(("info: ServerApp::MonitorApp listening on port %ld.\n", app->fMessagePort)); -// err = msgqueue.GetNextReply(&code); - err = msgqueue.GetNextMessage(code); - if (err < B_OK) + err = reader.GetNextMessage(code, B_INFINITE_TIMEOUT); + if (err < B_OK) { + STRACE(("ServerApp::MonitorApp(): GetNextMessage returned %s\n", strerror(err))); + + // ToDo: this should kill the app, but it doesn't work + BPrivate::LinkSender link(gAppServerPort); + link.StartMessage(AS_DELETE_APP); + link.Attach(&app->fMonitorThreadID, sizeof(thread_id)); + link.Flush(); break; + } - switch(code) - { - case AS_CREATE_WINDOW: - { - BRect frame; - uint32 look, feel, flags, wkspaces; - int32 token = B_NULL_TOKEN; - port_id sendPort = -1; - port_id looperPort = -1; - char *title = NULL; - - msgqueue.Read(&frame); - msgqueue.Read(&look); - msgqueue.Read(&feel); - msgqueue.Read(&flags); - msgqueue.Read(&wkspaces); - msgqueue.Read(&token); - msgqueue.Read(&sendPort); - msgqueue.Read(&looperPort); - msgqueue.ReadString(&title); - - STRACE(("ServerApp %s: Got 'New Window' message, trying to do smething...\n",app->fSignature.String())); - - if (title) - free(title); - - break; - } + switch (code) { case AS_QUIT_APP: { // This message is received only when the app_server is asked to shut down in // test/debug mode. Of course, if we are testing while using AccelerantDriver, we do // NOT want to shut down client applications. The server can be quit o in this fashion // through the driver's interface, such as closing the ViewDriver's window. - - STRACE(("ServerApp %s:Server shutdown notification received\n",app->fSignature.String())); + + STRACE(("ServerApp %s:Server shutdown notification received\n", + app->fSignature.String())); // If we are using the real, accelerated version of the // DisplayDriver, we do NOT want the user to be able shut down @@ -300,37 +277,25 @@ int32 ServerApp::MonitorApp(void *data) { STRACE(("ServerApp %s: B_QUIT_REQUESTED\n",app->fSignature.String())); // Our BApplication sent us this message when it quit. - // We need to ask the app_server to delete our monitor - // ADI: No! This is a bad solution. A thead should continue its - // execution until its exit point, and this can *very* easily be done - quitting=true; - // see... no need to ask the main thread to kill us. - // still... it will delete this ServerApp object. - port_id serverport = find_port(SERVER_PORT_NAME); - if(serverport == B_NAME_NOT_FOUND){ - printf("PANIC: ServerApp %s could not find the app_server port!\n",app->fSignature.String()); - break; - } - app->fMsgSender->SetPort(serverport); - app->fMsgSender->StartMessage(AS_DELETE_APP); - app->fMsgSender->Attach(&app->fMonitorThreadID, sizeof(thread_id)); - app->fMsgSender->Flush(); + // We need to ask the app_server to delete ourself. + BPrivate::LinkSender sender(gAppServerPort); + sender.StartMessage(AS_DELETE_APP); + sender.Attach(&app->fMonitorThreadID, sizeof(thread_id)); + sender.Flush(); break; } + default: - { - STRACE(("ServerApp %s: Got a Message to dispatch\n",app->fSignature.String())); - app->DispatchMessage(code, msgqueue); + STRACE(("ServerApp %s: Got a Message to dispatch\n", app->fSignature.String())); + app->DispatchMessage(code, reader); break; - } } + } - } // end for - - // clean exit. return 0; } + /*! \brief Handler function for BApplication API messages \param code Identifier code for the message. Equivalent to BMessage::what @@ -340,15 +305,10 @@ int32 ServerApp::MonitorApp(void *data) All attachments are placed in the buffer via a PortLink, so it will be a matter of casting and incrementing an index variable to access them. */ -void ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &msg) +void +ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { - BPrivate::PortLink replylink; - - switch(code) - { -// case AS_UPDATE_COLORS: -// case AS_UPDATE_FONTS: -// break; + switch (code) { case AS_ACQUIRE_SERVERMEM: { // This particular call is more than a bit of a pain in the neck. We are given a @@ -360,43 +320,36 @@ void ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &msg) // Attached Data: // 1) size_t requested size // 2) port_id reply_port - + size_t memsize; - port_id replyport; - - msg.Read(&memsize); - msg.Read(&replyport); - + link.Read(&memsize); + // TODO: I wonder if ACQUIRE_SERVERMEM should have a minimum size requirement? - void *sharedmem=fSharedMem->GetBuffer(memsize); - - replylink.SetSenderPort(replyport); - if(memsize<1 || sharedmem==NULL) - { - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); + void *sharedmem = fSharedMem->GetBuffer(memsize); + + if (memsize < 1 || sharedmem == NULL) { + fLink.StartMessage(SERVER_FALSE); + fLink.Flush(); break; } - area_id owningArea=area_for(sharedmem); - area_info ai; - - if(owningArea==B_ERROR || get_area_info(owningArea,&ai)!=B_OK) - { - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); + area_id owningArea = area_for(sharedmem); + area_info info; + + if (owningArea == B_ERROR || get_area_info(owningArea, &info) < B_OK) { + fLink.StartMessage(SERVER_FALSE); + fLink.Flush(); break; } - - int32 areaoffset=((int32*)sharedmem)-((int32*)ai.address); + + int32 areaoffset = (addr_t)sharedmem - (addr_t)info.address; STRACE(("Successfully allocated shared memory of size %ld\n",memsize)); - - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(owningArea); - replylink.Attach(areaoffset); - replylink.Flush(); - + + fLink.StartMessage(SERVER_TRUE); + fLink.Attach(owningArea); + fLink.Attach(areaoffset); + fLink.Flush(); break; } case AS_RELEASE_SERVERMEM: @@ -407,743 +360,121 @@ void ServerApp::DispatchMessage(int32 code, BPrivate::LinkReceiver &msg) // 2) int32 area offset area_id owningArea; - area_info ai; int32 areaoffset; - void *sharedmem; + + link.Read(&owningArea); + link.Read(&areaoffset); - msg.Read(&owningArea); - msg.Read(&areaoffset); - - if(owningArea<0 || get_area_info(owningArea,&ai)!=B_OK) + area_info areaInfo; + if (owningArea < 0 || get_area_info(owningArea, &areaInfo) != B_OK) break; STRACE(("Successfully freed shared memory\n")); - sharedmem=((int32*)ai.address)+areaoffset; + void *sharedmem = ((int32*)areaInfo.address) + areaoffset; fSharedMem->ReleaseBuffer(sharedmem); break; } - case AS_CREATE_BITMAP: + + case AS_CURRENT_WORKSPACE: { - STRACE(("ServerApp %s: Received BBitmap creation request\n",fSignature.String())); - // Allocate a bitmap for an application - - // Attached Data: - // 1) BRect bounds - // 2) color_space space - // 3) int32 bitmap_flags - // 4) int32 bytes_per_row - // 5) int32 screen_id::id - // 6) port_id reply port - - // Reply Code: SERVER_TRUE - // Reply Data: - // 1) int32 server token - // 2) area_id id of the area in which the bitmap data resides - // 3) int32 area pointer offset used to calculate fBasePtr - - // First, let's attempt to allocate the bitmap - port_id replyport = -1; - BRect r; - color_space cs; - int32 f,bpr; - screen_id s; + STRACE(("ServerApp %s: get current workspace\n", fSignature.String())); - msg.Read(&r); - msg.Read(&cs); - msg.Read(&f); - msg.Read(&bpr); - msg.Read(&s); - msg.Read(&replyport); - - STRACE(("ServerApp %s: Create Bitmap (%.1f,%.1f,%.1f,%.1f)\n", - fSignature.String(),r.left,r.top,r.right,r.bottom)); - - replylink.SetSenderPort(replyport); -/* if(sbmp) - { - fBitmapList->AddItem(sbmp); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(sbmp->Token()); - replylink.Attach(sbmp->Area()); - replylink.Attach(sbmp->AreaOffset()); - } - else*/ - { - // alternatively, if something went wrong, we reply with SERVER_FALSE - replylink.StartMessage(SERVER_FALSE); - } - replylink.Flush(); - + // TODO: Locking this way is not nice + fLink.StartMessage(SERVER_TRUE); + fLink.Attach(0); + fLink.Flush(); break; } - case AS_DELETE_BITMAP: - { - STRACE(("ServerApp %s: received BBitmap delete request\n",fSignature.String())); - // Delete a bitmap's allocated memory - - // Attached Data: - // 1) int32 token - // 2) int32 reply port - // Reply Code: SERVER_TRUE if successful, - // SERVER_FALSE if the buffer was already deleted or was not found - port_id replyport = -1; - int32 bmp_id; - - msg.Read(&bmp_id); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Flush(); - break; - } - case AS_CREATE_PICTURE: - { - // TODO: Implement AS_CREATE_PICTURE - STRACE(("ServerApp %s: Create Picture unimplemented\n",fSignature.String())); - - break; - } - case AS_DELETE_PICTURE: - { - // TODO: Implement AS_DELETE_PICTURE - STRACE(("ServerApp %s: Delete Picture unimplemented\n",fSignature.String())); - - break; - } - case AS_CLONE_PICTURE: - { - // TODO: Implement AS_CLONE_PICTURE - STRACE(("ServerApp %s: Clone Picture unimplemented\n",fSignature.String())); - - break; - } - case AS_DOWNLOAD_PICTURE: - { - // TODO; Implement AS_DOWNLOAD_PICTURE - - // What is this particular function call for, anyway? - STRACE(("ServerApp %s: Download Picture unimplemented\n",fSignature.String())); - - break; - } case AS_ACTIVATE_WORKSPACE: - break; + { + STRACE(("ServerApp %s: activate workspace\n", fSignature.String())); + + // TODO: See above + int32 index; + link.Read(&index); + // no reply - case AS_SHOW_CURSOR: - fCursorHidden=false; - break; - case AS_HIDE_CURSOR: - fCursorHidden=true; - break; - case AS_OBSCURE_CURSOR: break; + } + case AS_QUERY_CURSOR_HIDDEN: { - STRACE(("ServerApp %s: Received IsCursorHidden request\n",fSignature.String())); + STRACE(("ServerApp %s: Received IsCursorHidden request\n", fSignature.String())); // Attached data // 1) int32 port to reply to - int32 replyport; - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(fCursorHidden ? SERVER_TRUE : SERVER_FALSE); - replylink.Flush(); + fLink.StartMessage(fCursorHidden ? SERVER_TRUE : SERVER_FALSE); + fLink.Flush(); break; } - case AS_SET_CURSOR_DATA: - case AS_SET_CURSOR_BCURSOR: - break; - case AS_CREATE_BCURSOR: - { - STRACE(("ServerApp %s: Create BCursor\n",fSignature.String())); - // Attached data: - // 1) 68 bytes of fAppCursor data - // 2) port_id reply port - - port_id replyport = -1; - int8 cdata[68]; - msg.Read(cdata,68); - msg.Read(&replyport); - - // Synchronous message - BApplication is waiting on the cursor's ID - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(-1); - replylink.Flush(); - break; - } - case AS_DELETE_BCURSOR: - { - STRACE(("ServerApp %s: Delete BCursor\n",fSignature.String())); - // Attached data: - // 1) int32 token ID of the cursor to delete - int32 ctoken = B_NULL_TOKEN; - msg.Read(&ctoken); - break; - } - case AS_GET_SCROLLBAR_INFO: - { - STRACE(("ServerApp %s: Get ScrollBar info\n",fSignature.String())); - // Attached data: - // 1) port_id reply port - synchronous message - - scroll_bar_info sbi; - - port_id replyport; - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(sbi); - replylink.Flush(); - break; - } - case AS_SET_SCROLLBAR_INFO: - { - STRACE(("ServerApp %s: Set ScrollBar info\n",fSignature.String())); - // Attached Data: - // 1) scroll_bar_info scroll bar info structure - scroll_bar_info sbi; - msg.Read(&sbi); - break; - } - case AS_FOCUS_FOLLOWS_MOUSE: - { - STRACE(("ServerApp %s: query Focus Follow Mouse in use\n",fSignature.String())); - // Attached data: - // 1) port_id reply port - synchronous message - - port_id replyport; - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(true); - replylink.Flush(); - break; - } - case AS_SET_FOCUS_FOLLOWS_MOUSE: - { - STRACE(("ServerApp %s: Set Focus Follows Mouse in use\n",fSignature.String())); -/* // Attached Data: - // 1) scroll_bar_info scroll bar info structure - scroll_bar_info sbi; - msg.Read(&sbi); - - desktop->SetScrollBarInfo(sbi);*/ - break; - } - case AS_SET_MOUSE_MODE: - { - STRACE(("ServerApp %s: Set Focus Follows Mouse mode\n",fSignature.String())); - // Attached Data: - // 1) enum mode_mouse FFM mouse mode - mode_mouse mmode; - msg.Read(&mmode); - break; - } - case AS_GET_MOUSE_MODE: - { - STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n",fSignature.String())); - // Attached data: - // 1) port_id reply port - synchronous message - - mode_mouse mmode = (mode_mouse)0; - - port_id replyport = -1; - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(mmode); - replylink.Flush(); - break; - } - case AS_GET_UI_COLOR: - { - STRACE(("ServerApp %s: Get UI color\n",fSignature.String())); - - rgb_color color = {0,0,0,0}; - int32 whichcolor; - port_id replyport = -1; - - msg.Read(&whichcolor); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(color); - replylink.Flush(); - break; - } - case AS_UPDATED_CLIENT_FONTLIST: - { - STRACE(("ServerApp %s: Acknowledged update of client-side font list\n",fSignature.String())); - break; - } - case AS_QUERY_FONTS_CHANGED: - { - FTRACE(("ServerApp %s: AS_QUERY_FONTS_CHANGED unimplemented\n",fSignature.String())); - // Attached Data: - // 1) bool check flag - // 2) port_id reply_port - - // if just checking, just give an answer, - // if not and needs updated, - // sync the font list and return true else return false - break; - } - case AS_GET_FAMILY_NAME: - { - FTRACE(("ServerApp %s: AS_GET_FAMILY_NAME\n",fSignature.String())); - // Attached Data: - // 1) int32 the ID of the font family to get - // 2) port_id reply port - - // Returns: - // 1) font_family - name of family - // 2) uint32 - flags of font family (B_IS_FIXED || B_HAS_TUNED_FONT) - int32 famid; - port_id replyport; - - msg.Read(&famid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_STYLE_NAME: - { - FTRACE(("ServerApp %s: AS_GET_STYLE_NAME\n",fSignature.String())); - // Attached Data: - // 1) font_family The name of the font family - // 2) int32 ID of the style to get - // 3) port_id reply port - - // Returns: - // 1) font_style - name of the style - // 2) uint16 - appropriate face values - // 3) uint32 - flags of font style (B_IS_FIXED || B_HAS_TUNED_FONT) - - font_family fam; - int32 styid; - port_id replyport; - - msg.Read(fam,sizeof(font_family)); - msg.Read(&styid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_FAMILY_AND_STYLE: - { - FTRACE(("ServerApp %s: AS_GET_FAMILY_AND_STYLE\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) port_id reply port - - // Returns: - // 1) font_family The name of the font family - // 2) font_style - name of the style - uint16 famid, styid; - port_id replyport; - - msg.Read(&famid); - msg.Read(&styid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_FONT_DIRECTION: - { - FTRACE(("ServerApp %s: AS_GET_FONT_DIRECTION unimplemented\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) port_id reply port - - // Returns: - // 1) font_direction direction of font - - // NOTE: While this may be unimplemented, we can safely return - // SERVER_FALSE. This will force the BFont code to default to - // B_LEFT_TO_RIGHT, which is what the vast majority of fonts will be. - // This will be fixed later. - int32 famid, styid; - port_id replyport; - - msg.Read(&famid); - msg.Read(&styid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - -/* fontserver->Lock(); - FontStyle *fstyle=fontserver->GetStyle(famid,styid); - if(fstyle) - { - font_direction dir=fstyle->GetDirection(); - - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(dir); - replylink.Flush(); - } - else - { -*/ replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); -// } - -// fontserver->Unlock(); - break; - } - case AS_GET_STRING_WIDTH: - { - FTRACE(("ServerApp %s: AS_GET_STRING_WIDTH\n",fSignature.String())); - // Attached Data: - // 1) string String to measure - // 2) int32 string length to measure - // 3) uint16 ID of family - // 4) uint16 ID of style - // 5) float point size of font - // 6) uint8 spacing to use - // 7) port_id reply port - - // Returns: - // 1) float - width of the string in pixels - char *string=NULL; - int32 length; - uint16 family,style; - float size; - uint8 spacing; - port_id replyport; - - msg.ReadString(&string); - msg.Read(&length); - msg.Read(&family); - msg.Read(&style); - msg.Read(&size); - msg.Read(&spacing); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_FONT_BOUNDING_BOX: - { - FTRACE(("ServerApp %s: AS_GET_BOUNDING_BOX unimplemented\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) port_id reply port - - // Returns: - // 1) BRect - box holding entire font - - break; - } - case AS_GET_TUNED_COUNT: - { - FTRACE(("ServerApp %s: AS_GET_TUNED_COUNT\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) port_id reply port - - // Returns: - // 1) int32 - number of font strikes available - int32 famid, styid; - port_id replyport; - - msg.Read(&famid); - msg.Read(&styid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_TUNED_INFO: - { - FTRACE(("ServerApp %s: AS_GET_TUNED_INFO unimplmemented\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) uint32 - index of the particular font strike - // 4) port_id reply port - - // Returns: - // 1) tuned_font_info - info on the strike specified - break; - } - case AS_QUERY_FONT_FIXED: - { - FTRACE(("ServerApp %s: AS_QUERY_FONT_FIXED unimplmemented\n",fSignature.String())); - // Attached Data: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) port_id reply port - - // Returns: - // 1) bool - font is/is not fixed - int32 famid, styid; - port_id replyport; - - msg.Read(&famid); - msg.Read(&styid); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_FAMILY_NAME: - { - FTRACE(("ServerApp %s: AS_SET_FAMILY_NAME\n",fSignature.String())); - // Attached Data: - // 1) font_family - name of font family to use - // 2) port_id - reply port - - // Returns: - // 1) uint16 - family ID - - port_id replyport; - font_family fam; - - msg.Read(fam,sizeof(font_family)); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_FAMILY_AND_STYLE: - { - FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_STYLE\n",fSignature.String())); - // Attached Data: - // 1) font_family - name of font family to use - // 2) font_style - name of style in family - // 3) port_id - reply port - - // Returns: - // 1) uint16 - family ID - // 2) uint16 - style ID - - port_id replyport; - font_family fam; - font_style sty; - - msg.Read(fam,sizeof(font_family)); - msg.Read(sty,sizeof(font_style)); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_FAMILY_AND_STYLE_FROM_ID: - { - FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_STYLE_FROM_ID\n",fSignature.String())); - // Attached Data: - // 1) uint16 - ID of font family to use - // 2) uint16 - ID of style in family - // 3) port_id - reply port - - // Returns: - // 1) uint16 - face of the font - - port_id replyport; - uint16 fam, sty; - - msg.Read(&fam); - msg.Read(&sty); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_FAMILY_AND_FACE: - { - FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_FACE unimplmemented\n",fSignature.String())); - // Attached Data: - // 1) font_family - name of font family to use - // 2) uint16 - font face - // 3) port_id - reply port - - // Returns: - // 1) uint16 - family ID - // 2) uint16 - style ID - - // TODO: Check R5 for error condition behavior in SET_FAMILY_AND_FACE - break; - } - case AS_COUNT_FONT_FAMILIES: - { - FTRACE(("ServerApp %s: AS_COUNT_FONT_FAMILIES\n",fSignature.String())); - // Attached Data: - // 1) port_id - reply port - - // Returns: - // 1) int32 - # of font families - port_id replyport; - - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_TRUE); - replylink.Attach(0); - replylink.Flush(); - break; - } - case AS_COUNT_FONT_STYLES: - { - FTRACE(("ServerApp %s: AS_COUNT_FONT_STYLES\n",fSignature.String())); - // Attached Data: - // 1) font_family - name of font family - // 2) port_id - reply port - - // Returns: - // 1) int32 - # of font styles - port_id replyport; - font_family fam; - - msg.Read(fam,sizeof(font_family)); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_SYSFONT_PLAIN: - { - FTRACE(("ServerApp %s: AS_SET_SYSFONT_PLAIN\n",fSignature.String())); - // Attached Data: - // port_id reply port - - // Returns: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) float - size in points - // 4) uint16 - face flags - // 5) uint32 - font flags - - port_id replyport; - msg.Read(&replyport); - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_GET_FONT_HEIGHT: - { - FTRACE(("ServerApp %s: AS_GET_FONT_HEIGHT\n",fSignature.String())); - // Attached Data: - // 1) uint16 family ID - // 2) uint16 style ID - // 3) float size - // 4) port_id reply port - uint16 famid,styid; - float ptsize; - port_id replyport; - - msg.Read(&famid); - msg.Read(&styid); - msg.Read(&ptsize); - msg.Read(&replyport); - - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_SYSFONT_BOLD: - { - FTRACE(("ServerApp %s: AS_SET_SYSFONT_BOLD\n",fSignature.String())); - // Attached Data: - // port_id reply port - - // Returns: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) float - size in points - // 4) uint16 - face flags - // 5) uint32 - font flags - - port_id replyport; - msg.Read(&replyport); - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } - case AS_SET_SYSFONT_FIXED: - { - FTRACE(("ServerApp %s: AS_SET_SYSFONT_FIXED\n",fSignature.String())); - // Attached Data: - // port_id reply port - - // Returns: - // 1) uint16 - family ID - // 2) uint16 - style ID - // 3) float - size in points - // 4) uint16 - face flags - // 5) uint32 - font flags - - port_id replyport; - msg.Read(&replyport); - replylink.SetSenderPort(replyport); - - replylink.StartMessage(SERVER_FALSE); - replylink.Flush(); - break; - } default: - { - STRACE(("ServerApp %s received unhandled message code offset %s\n",fSignature.String(), - MsgCodeToBString(code).String())); + printf("ServerApp %s received unhandled message code offset %lx\n", + fSignature.String(), code); + + if (link.NeedsReply()) { + // the client is now blocking and waiting for a reply! + fLink.StartMessage(SERVER_FALSE); + fLink.Flush(); + } else + puts("message doesn't need a reply!"); break; - } } } +int32 +ServerApp::CountBitmaps() const +{ + return fBitmapList ? fBitmapList->CountItems() : 0; +} + + +/*! + \brief Looks up a ServerApp's ServerBitmap in its list + \param token ID token of the bitmap to find + \return The bitmap having that ID or NULL if not found +*/ +ServerBitmap * +ServerApp::FindBitmap(int32 token) const +{ + ServerBitmap *bitmap; + for (int32 i = 0; i < fBitmapList->CountItems(); i++) { + bitmap = static_cast(fBitmapList->ItemAt(i)); + if (bitmap && bitmap->Token() == token) + return bitmap; + } + + return NULL; +} + + +int32 +ServerApp::CountPictures() const +{ + return fPictureList ? fPictureList->CountItems() : 0; +} + + +ServerPicture * +ServerApp::FindPicture(int32 token) const +{ + return NULL; +} + + team_id -ServerApp::ClientTeamID() +ServerApp::ClientTeamID() const { return fClientTeamID; } + +thread_id +ServerApp::MonitorThreadID() const +{ + return fMonitorThreadID; +} + diff --git a/src/tests/apps/fake_app_server/ServerApp.h b/src/tests/apps/fake_app_server/ServerApp.h index dd7b878044..e74d52d36e 100644 --- a/src/tests/apps/fake_app_server/ServerApp.h +++ b/src/tests/apps/fake_app_server/ServerApp.h @@ -30,17 +30,15 @@ #include #include -#include -#include -//#include "FMWList.h" +#include -class AppServer; +class AreaPool; class BMessage; class BList; class DisplayDriver; +class ServerPicture; class ServerCursor; class ServerBitmap; -class AreaPool; namespace BPrivate { class PortLink; @@ -50,64 +48,91 @@ namespace BPrivate { \class ServerApp ServerApp.h \brief Counterpart to BApplication within the app_server */ -class ServerApp -{ +class ServerApp { public: ServerApp(port_id sendport, port_id rcvport, port_id clientLooperPort, - team_id clientTeamID, int32 handlerID, char *signature); - virtual ~ServerApp(void); + team_id clientTeamID, int32 handlerID, const char* signature); + virtual ~ServerApp(void); bool Run(void); - static int32 MonitorApp(void *data); + /* + TODO: These aren't even implemented... void Lock(void); void Unlock(void); bool IsLocked(void); - + */ /*! \brief Determines whether the application is the active one \return true if active, false if not. */ bool IsActive(void) const { return fIsActive; } - void Activate(bool value); + bool PingTarget(void); void PostMessage(int32 code); - void SendMessageToClient( const BMessage* msg ) const; + void SetAppCursor(void); - team_id ClientTeamID(); + team_id ClientTeamID() const; + thread_id MonitorThreadID() const; -const char * Title() const { return fSignature.String(); } -protected: - friend class AppServer; - friend class ServerWindow; + const char *Title() const { return fSignature.String(); } - void DispatchMessage(int32 code, BPrivate::LinkReceiver &link); + int32 CountBitmaps() const; + ServerBitmap *FindBitmap(int32 token) const; - port_id fClientAppPort, - fMessagePort, - // TODO: find out why there is both the app port and the looper port. Do - // we really need both? - fClientLooperPort; - - BString fSignature; - thread_id fMonitorThreadID; - - team_id fClientTeamID; - - BPrivate::LinkReceiver *fMsgReader; - BPrivate::LinkSender *fMsgSender; + int32 CountPictures() const; + ServerPicture *FindPicture(int32 token) const; -/* BList *fSWindowList, + AreaPool *AppAreaPool() { return fSharedMem; } + +private: + void DispatchMessage(int32 code, BPrivate::LinkReceiver &link); + + static int32 MonitorApp(void *data); + + // our BApplication's event port + port_id fClientAppPort; + // port we receive messages from our BApplication + port_id fMessagePort; + // TODO: find out why there is both the app port and the looper port. Do + // we really need both? Actually, we aren't using any of these ports, + // as BAppServerLink/BPortlink's messages always contain the reply port + // To send a message to the client, write a BMessage to this port + port_id fClientLooperPort; + + BString fSignature; + + thread_id fMonitorThreadID; + team_id fClientTeamID; + + BPrivate::PortLink fLink; + + // TODO: + // - Are really Bitmaps and Pictures stored per application and not globally ? + // - As we reference these stuff by token, what about putting them in hash tables ? + BList *fSWindowList, *fBitmapList, *fPictureList; -*/ sem_id fLockSem; + + ServerCursor *fAppCursor; + + // TODO: Not used. + sem_id fLockSem; + bool fCursorHidden; bool fIsActive; - int32 fHandlerToken; + + // token ID of the BApplication's BHandler object. + // Used for BMessage target specification + // TODO: Is it still needed ? We aren't using it. + //int32 fHandlerToken; + AreaPool *fSharedMem; + + bool fQuitting; }; -#endif +#endif // _SERVERAPP_H_