2003-01-24 17:36:15 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Copyright (c) 2001-2002, OpenBeOS
|
|
|
|
//
|
|
|
|
// 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 <bpmagic@columbus.rr.com>
|
|
|
|
// Description: Server-side BApplication counterpart
|
|
|
|
//
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include <AppDefs.h>
|
|
|
|
#include <List.h>
|
|
|
|
#include <String.h>
|
2003-01-24 18:19:27 +03:00
|
|
|
#include <PortLink.h>
|
2003-01-24 17:36:15 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2003-03-12 17:29:59 +03:00
|
|
|
#include <ServerProtocol.h>
|
2003-01-24 17:36:15 +03:00
|
|
|
|
2003-03-12 17:29:59 +03:00
|
|
|
#include "BitmapManager.h"
|
2003-01-24 17:36:15 +03:00
|
|
|
#include "CursorManager.h"
|
2003-01-24 18:19:27 +03:00
|
|
|
#include "Desktop.h"
|
2003-01-24 17:36:15 +03:00
|
|
|
#include "DisplayDriver.h"
|
|
|
|
#include "FontServer.h"
|
|
|
|
#include "ServerApp.h"
|
2003-02-07 15:53:57 +03:00
|
|
|
#include "ServerWindow.h"
|
2003-01-24 17:36:15 +03:00
|
|
|
#include "ServerCursor.h"
|
|
|
|
#include "ServerBitmap.h"
|
2003-03-21 18:49:28 +03:00
|
|
|
#include "ServerPicture.h"
|
2003-01-24 17:36:15 +03:00
|
|
|
#include "ServerConfig.h"
|
|
|
|
#include "LayerData.h"
|
2003-03-19 04:12:53 +03:00
|
|
|
#include "Utils.h"
|
|
|
|
|
2003-03-21 18:49:28 +03:00
|
|
|
//#define DEBUG_SERVERAPP
|
2003-01-24 17:36:15 +03:00
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Constructor
|
|
|
|
\param sendport port ID for the BApplication which will receive the
|
|
|
|
ServerApp's messages
|
|
|
|
\param rcvport port by which the ServerApp will receive messages from its
|
|
|
|
BApplication.
|
|
|
|
\param _signature NULL-terminated string which contains the BApplication's
|
|
|
|
MIME _signature.
|
|
|
|
*/
|
2003-03-19 04:12:53 +03:00
|
|
|
ServerApp::ServerApp(port_id sendport, port_id rcvport, int32 handlerID, char *signature)
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// need to copy the _signature because the message buffer
|
|
|
|
// owns the copy which we are passed as a parameter.
|
2003-03-19 04:12:53 +03:00
|
|
|
_signature=(signature)?signature:"application/x-vnd.unknown-application";
|
|
|
|
|
|
|
|
// token ID of the BApplication's BHandler object. Used for BMessage target specification
|
|
|
|
_handlertoken=handlerID;
|
2003-01-24 17:36:15 +03:00
|
|
|
|
|
|
|
// _sender is the our BApplication's event port
|
|
|
|
_sender=sendport;
|
|
|
|
_applink=new PortLink(_sender);
|
|
|
|
_applink->SetPort(_sender);
|
|
|
|
|
|
|
|
// Gotta get the team ID so we can ping the application
|
|
|
|
port_info pinfo;
|
|
|
|
get_port_info(_sender,&pinfo);
|
|
|
|
_target_id=pinfo.team;
|
|
|
|
|
|
|
|
// _receiver is the port we receive messages from our BApplication
|
|
|
|
_receiver=rcvport;
|
|
|
|
|
|
|
|
_winlist=new BList(0);
|
|
|
|
_bmplist=new BList(0);
|
2003-03-21 18:49:28 +03:00
|
|
|
_piclist=new BList(0);
|
2003-01-24 17:36:15 +03:00
|
|
|
_isactive=false;
|
|
|
|
|
|
|
|
ServerCursor *defaultc=cursormanager->GetCursor(B_CURSOR_DEFAULT);
|
|
|
|
|
|
|
|
_appcursor=(defaultc)?new ServerCursor(defaultc):NULL;
|
|
|
|
_lock=create_sem(1,"ServerApp sem");
|
|
|
|
|
2003-04-05 05:51:35 +04:00
|
|
|
_driver=GetGfxDriver(ActiveScreen());
|
2003-02-24 00:40:44 +03:00
|
|
|
_cursorhidden=false;
|
2003-03-19 04:12:53 +03:00
|
|
|
|
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s:\n",_signature.String());
|
|
|
|
printf("\tBApp port: %ld\n",_sender);
|
|
|
|
printf("\tReceiver port: %ld\n",_receiver);
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//! Does all necessary teardown for application
|
|
|
|
ServerApp::~ServerApp(void)
|
|
|
|
{
|
2003-03-19 04:12:53 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s:~ServerApp()\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
int32 i;
|
|
|
|
|
2003-02-07 15:53:57 +03:00
|
|
|
ServerWindow *tempwin;
|
2003-01-24 17:36:15 +03:00
|
|
|
for(i=0;i<_winlist->CountItems();i++)
|
|
|
|
{
|
|
|
|
tempwin=(ServerWindow*)_winlist->ItemAt(i);
|
|
|
|
if(tempwin)
|
|
|
|
delete tempwin;
|
|
|
|
}
|
|
|
|
_winlist->MakeEmpty();
|
|
|
|
delete _winlist;
|
2003-02-07 15:53:57 +03:00
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
ServerBitmap *tempbmp;
|
|
|
|
for(i=0;i<_bmplist->CountItems();i++)
|
|
|
|
{
|
|
|
|
tempbmp=(ServerBitmap*)_bmplist->ItemAt(i);
|
|
|
|
if(tempbmp)
|
|
|
|
delete tempbmp;
|
|
|
|
}
|
|
|
|
_bmplist->MakeEmpty();
|
|
|
|
delete _bmplist;
|
|
|
|
|
2003-03-21 18:49:28 +03:00
|
|
|
ServerPicture *temppic;
|
|
|
|
for(i=0;i<_piclist->CountItems();i++)
|
|
|
|
{
|
|
|
|
temppic=(ServerPicture*)_piclist->ItemAt(i);
|
|
|
|
if(temppic)
|
|
|
|
delete temppic;
|
|
|
|
}
|
|
|
|
_piclist->MakeEmpty();
|
|
|
|
delete _piclist;
|
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
delete _applink;
|
|
|
|
_applink=NULL;
|
|
|
|
if(_appcursor)
|
|
|
|
delete _appcursor;
|
|
|
|
|
|
|
|
// Kill the monitor thread if it exists
|
|
|
|
thread_info info;
|
|
|
|
if(get_thread_info(_monitor_thread,&info)==B_OK)
|
|
|
|
kill_thread(_monitor_thread);
|
|
|
|
|
|
|
|
cursormanager->RemoveAppCursors(_signature.String());
|
|
|
|
delete_sem(_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Starts the ServerApp monitoring for messages
|
|
|
|
\return false if the application couldn't start, true if everything went OK.
|
|
|
|
*/
|
|
|
|
bool ServerApp::Run(void)
|
|
|
|
{
|
2003-03-19 04:12:53 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s:Run()\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
// Unlike a BApplication, a ServerApp is *supposed* to return immediately
|
|
|
|
// when its Run() function is called.
|
|
|
|
_monitor_thread=spawn_thread(MonitorApp,_signature.String(),B_NORMAL_PRIORITY,this);
|
|
|
|
if(_monitor_thread==B_NO_MORE_THREADS || _monitor_thread==B_NO_MEMORY)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
resume_thread(_monitor_thread);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\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(_target_id,&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",_signature.String());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
_applink->SetPort(serverport);
|
2003-02-24 18:47:06 +03:00
|
|
|
_applink->SetOpCode(AS_DELETE_APP);
|
2003-01-24 17:36:15 +03:00
|
|
|
_applink->Attach(&_monitor_thread,sizeof(thread_id));
|
|
|
|
_applink->Flush();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-01-27 22:43:15 +03:00
|
|
|
/*!
|
|
|
|
\brief Send a message to the ServerApp with no attachments
|
|
|
|
\param code ID code of the message to post
|
|
|
|
*/
|
2003-02-04 03:20:15 +03:00
|
|
|
void ServerApp::PostMessage(int32 code, size_t size, int8 *buffer)
|
2003-01-27 22:43:15 +03:00
|
|
|
{
|
2003-02-04 03:20:15 +03:00
|
|
|
write_port(_receiver,code, buffer, size);
|
2003-01-27 22:43:15 +03:00
|
|
|
}
|
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
/*!
|
|
|
|
\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)
|
|
|
|
{
|
|
|
|
ServerApp *app=(ServerApp *)data;
|
|
|
|
|
|
|
|
// Message-dispatching loop for the ServerApp
|
|
|
|
int32 msgcode;
|
|
|
|
int8 *msgbuffer=NULL;
|
|
|
|
ssize_t buffersize,bytesread;
|
|
|
|
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
buffersize=port_buffer_size(app->_receiver);
|
|
|
|
|
|
|
|
if(buffersize>0)
|
|
|
|
{
|
|
|
|
// buffers are PortLink messages. Allocate necessary buffer and
|
|
|
|
// we'll cast it as a BMessage.
|
|
|
|
msgbuffer=new int8[buffersize];
|
|
|
|
bytesread=read_port(app->_receiver,&msgcode,msgbuffer,buffersize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bytesread=read_port(app->_receiver,&msgcode,NULL,0);
|
|
|
|
if (bytesread != B_BAD_PORT_ID && bytesread != B_TIMED_OUT && bytesread != B_WOULD_BLOCK)
|
|
|
|
{
|
|
|
|
switch(msgcode)
|
|
|
|
{
|
|
|
|
// -------------- Messages received from the Server ------------------------
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_QUIT_APP:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-19 04:12:53 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s:Server shutdown notification received\n",app->_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
// If we are using the real, accelerated version of the
|
|
|
|
// DisplayDriver, we do NOT want the user to be able shut down
|
|
|
|
// the server. The results would NOT be pretty
|
2003-03-19 04:12:53 +03:00
|
|
|
if(DISPLAYDRIVER!=HWDRIVER)
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// This message is received from the app_server thread
|
|
|
|
// because the server was asked to quit. Thus, we
|
|
|
|
// ask all apps to quit. This is NOT the same as system
|
|
|
|
// shutdown and will happen only in testing
|
2003-03-23 23:52:37 +03:00
|
|
|
|
|
|
|
// For now, it seems that we can't seem to try to play nice and tell
|
|
|
|
// an application to quit, so we'll just have to go postal. XD
|
|
|
|
|
|
|
|
// BMessage *shutdown=new BMessage(_QUIT_);
|
2003-03-19 04:20:20 +03:00
|
|
|
// SendMessage(app->_sender,shutdown);
|
2003-03-23 23:52:37 +03:00
|
|
|
|
|
|
|
// DIE! DIE! DIE! :P
|
|
|
|
port_info pi;
|
|
|
|
get_port_info(app->_sender,&pi);
|
|
|
|
kill_team(pi.team);
|
|
|
|
app->PostMessage(B_QUIT_REQUESTED);
|
2003-03-19 04:12:53 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s:Sent server shutdown message to BApp\n",app->_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// -------------- Messages received from the Application ------------------
|
|
|
|
case B_QUIT_REQUESTED:
|
|
|
|
{
|
|
|
|
// Our BApplication sent us this message when it quit.
|
|
|
|
// We need to ask the app_server to delete our monitor
|
|
|
|
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->_signature.String());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
app->_applink->SetPort(serverport);
|
2003-02-24 18:47:06 +03:00
|
|
|
app->_applink->SetOpCode(AS_DELETE_APP);
|
2003-01-24 17:36:15 +03:00
|
|
|
app->_applink->Attach(&app->_monitor_thread,sizeof(thread_id));
|
|
|
|
app->_applink->Flush();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
2003-03-12 17:29:59 +03:00
|
|
|
app->_DispatchMessage(msgcode, msgbuffer);
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(buffersize>0)
|
|
|
|
delete msgbuffer;
|
|
|
|
|
|
|
|
if(msgcode==B_QUIT_REQUESTED)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit_thread(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Handler function for BApplication API messages
|
|
|
|
\param code Identifier code for the message. Equivalent to BMessage::what
|
|
|
|
\param buffer Any attachments
|
|
|
|
|
|
|
|
Note that the buffer's exact format is determined by the particular message.
|
|
|
|
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.
|
|
|
|
*/
|
2003-03-12 17:29:59 +03:00
|
|
|
void ServerApp::_DispatchMessage(int32 code, int8 *buffer)
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
int8 *index=buffer;
|
|
|
|
LayerData ld;
|
|
|
|
|
|
|
|
switch(code)
|
|
|
|
{
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_UPDATED_CLIENT_FONTLIST:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Client font list update confirmed\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
// received when the client-side global font list has been
|
|
|
|
// refreshed
|
|
|
|
fontserver->Lock();
|
|
|
|
fontserver->FontsUpdated();
|
|
|
|
fontserver->Unlock();
|
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_CREATE_WINDOW:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// Create the ServerWindow to node monitor a new OBWindow
|
|
|
|
|
|
|
|
// Attached data:
|
|
|
|
// 1) port_id reply port
|
|
|
|
// 2) BRect window frame
|
|
|
|
// 3) uint32 window flags
|
|
|
|
// 4) port_id window's message port
|
|
|
|
// 5) uint32 workspace index
|
2003-03-19 04:12:53 +03:00
|
|
|
// 6) int32 BHandler token of the window
|
|
|
|
// 7) const char * title
|
2003-01-24 17:36:15 +03:00
|
|
|
|
|
|
|
// Find the necessary data
|
|
|
|
port_id reply_port=*((port_id*)index); index+=sizeof(port_id);
|
|
|
|
BRect rect=*((BRect*)index); index+=sizeof(BRect);
|
|
|
|
|
|
|
|
uint32 winlook=*((uint32*)index); index+=sizeof(uint32);
|
|
|
|
uint32 winfeel=*((uint32*)index); index+=sizeof(uint32);
|
|
|
|
uint32 winflags=*((uint32*)index); index+=sizeof(uint32);
|
|
|
|
|
|
|
|
port_id win_port=*((port_id*)index); index+=sizeof(port_id);
|
2003-03-19 04:12:53 +03:00
|
|
|
int32 htoken=*((int32*)index); index+=sizeof(int32);
|
2003-01-24 17:36:15 +03:00
|
|
|
uint32 workspace=*((uint32*)index); index+=sizeof(uint32);
|
|
|
|
|
|
|
|
// Create the ServerWindow object for this window
|
|
|
|
ServerWindow *newwin=new ServerWindow(rect,(const char *)index,
|
2003-03-19 04:12:53 +03:00
|
|
|
winlook, winfeel, winflags,this,win_port,workspace,htoken);
|
2003-01-24 17:36:15 +03:00
|
|
|
_winlist->AddItem(newwin);
|
|
|
|
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n",
|
|
|
|
_signature.String(),(const char *)index,rect.left,rect.top,rect.right,rect.bottom);
|
|
|
|
#endif
|
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
// Window looper is waiting for our reply. Send back the
|
|
|
|
// ServerWindow's message port
|
|
|
|
PortLink *replylink=new PortLink(reply_port);
|
2003-02-24 18:47:06 +03:00
|
|
|
replylink->SetOpCode(AS_SET_SERVER_PORT);
|
2003-01-24 17:36:15 +03:00
|
|
|
replylink->Attach((int32)newwin->_receiver);
|
2003-03-12 22:34:47 +03:00
|
|
|
replylink->Attach((int32)newwin->_token);
|
2003-01-24 17:36:15 +03:00
|
|
|
replylink->Flush();
|
|
|
|
|
|
|
|
delete replylink;
|
2003-02-07 15:53:57 +03:00
|
|
|
break;
|
2003-01-24 17:36:15 +03:00
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_DELETE_WINDOW:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// Received from a ServerWindow when its window quits
|
|
|
|
|
|
|
|
// Attached data:
|
2003-02-24 18:47:06 +03:00
|
|
|
// 1) uint32 ServerWindow ID token
|
2003-01-24 17:36:15 +03:00
|
|
|
ServerWindow *w;
|
2003-02-24 18:47:06 +03:00
|
|
|
uint32 winid=*((uint32*)index);
|
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
for(int32 i=0;i<_winlist->CountItems();i++)
|
|
|
|
{
|
|
|
|
w=(ServerWindow*)_winlist->ItemAt(i);
|
2003-02-24 18:47:06 +03:00
|
|
|
if(w->_token==winid)
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Deleting window %s\n",_signature.String(),w->Title());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
_winlist->RemoveItem(w);
|
|
|
|
delete w;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-02-07 15:53:57 +03:00
|
|
|
break;
|
2003-01-24 17:36:15 +03:00
|
|
|
}
|
2003-03-12 17:29:59 +03:00
|
|
|
case AS_CREATE_BITMAP:
|
|
|
|
{
|
|
|
|
// Allocate a bitmap for an application
|
|
|
|
|
|
|
|
// Attached Data:
|
|
|
|
// 1) port_id reply port
|
|
|
|
// 2) BRect bounds
|
|
|
|
// 3) color_space space
|
|
|
|
// 4) int32 bitmap_flags
|
|
|
|
// 5) int32 bytes_per_row
|
|
|
|
// 6) int32 screen_id::id
|
|
|
|
|
|
|
|
// 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=*((port_id*)index); index+=sizeof(port_id);
|
|
|
|
BRect r=*((BRect*)index); index+=sizeof(BRect);
|
|
|
|
color_space cs=*((color_space*)index); index+=sizeof(color_space);
|
|
|
|
int32 f=*((int32*)index); index+=sizeof(int32);
|
|
|
|
int32 bpr=*((int32*)index); index+=sizeof(int32);
|
|
|
|
|
|
|
|
screen_id s;
|
|
|
|
s.id=*((int32*)index);
|
|
|
|
|
|
|
|
ServerBitmap *sbmp=bitmapmanager->CreateBitmap(r,cs,f,bpr,s);
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Create Bitmap (%.1f,%.1f,%.1f,%.1f)\n",
|
|
|
|
_signature.String(),r.left,r.top,r.right,r.bottom);
|
|
|
|
#endif
|
2003-03-12 17:29:59 +03:00
|
|
|
if(sbmp)
|
|
|
|
{
|
|
|
|
// list for doing faster lookups for a bitmap than what the BitmapManager
|
|
|
|
// can do.
|
|
|
|
_bmplist->AddItem(sbmp);
|
|
|
|
_applink->SetOpCode(SERVER_TRUE);
|
|
|
|
_applink->Attach(sbmp->Token());
|
|
|
|
_applink->Attach(sbmp->Area());
|
|
|
|
_applink->Attach(sbmp->AreaOffset());
|
|
|
|
_applink->Flush();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// alternatively, if something went wrong, we reply with SERVER_FALSE
|
|
|
|
write_port(replyport,SERVER_FALSE,NULL,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_DELETE_BITMAP:
|
|
|
|
{
|
|
|
|
// Delete a bitmap's allocated memory
|
|
|
|
|
|
|
|
// Attached Data:
|
|
|
|
// 1) int32 reply port
|
|
|
|
// 2) int32 token
|
|
|
|
|
|
|
|
// Reply Code: SERVER_TRUE if successful,
|
|
|
|
// SERVER_FALSE if the buffer was already deleted or was not found
|
|
|
|
port_id replyport=*((port_id*)index); index+=sizeof(port_id);
|
|
|
|
|
|
|
|
ServerBitmap *sbmp=_FindBitmap(*((int32*)index));
|
|
|
|
if(sbmp)
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Deleting Bitmap %ld\n",_signature.String(),*((int32*)index));
|
|
|
|
#endif
|
2003-03-12 17:29:59 +03:00
|
|
|
_bmplist->RemoveItem(sbmp);
|
|
|
|
bitmapmanager->DeleteBitmap(sbmp);
|
|
|
|
write_port(replyport,SERVER_TRUE,NULL,0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
write_port(replyport,SERVER_FALSE,NULL,0);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2003-03-21 18:49:28 +03:00
|
|
|
case AS_CREATE_PICTURE:
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
// TODO: Implement
|
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Create Picture unimplemented\n",_signature.String());
|
|
|
|
#endif
|
2003-03-21 18:49:28 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_DELETE_PICTURE:
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
// TODO: Implement
|
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Delete Picture unimplemented\n",_signature.String());
|
|
|
|
#endif
|
2003-03-21 18:49:28 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_CLONE_PICTURE:
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
// TODO: Implement
|
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Clone Picture unimplemented\n",_signature.String());
|
|
|
|
#endif
|
2003-03-21 18:49:28 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AS_DOWNLOAD_PICTURE:
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
// TODO; Implement
|
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Download Picture unimplemented\n",_signature.String());
|
|
|
|
#endif
|
2003-03-21 18:49:28 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_SET_SCREEN_MODE:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// Attached data
|
|
|
|
// 1) int32 workspace #
|
|
|
|
// 2) uint32 screen mode
|
|
|
|
// 3) bool make default
|
|
|
|
int32 workspace=*((int32*)index); index+=sizeof(int32);
|
|
|
|
uint32 mode=*((uint32*)index); index+=sizeof(uint32);
|
|
|
|
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: SetScreenMode: workspace %ld, mode %lu\n",_signature.String(), workspace, mode);
|
|
|
|
#endif
|
2003-04-05 05:51:35 +04:00
|
|
|
SetSpace(workspace,mode,ActiveScreen(),*((bool*)index));
|
2003-01-24 18:19:27 +03:00
|
|
|
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_ACTIVATE_WORKSPACE:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
|
|
|
// Attached data
|
|
|
|
// 1) int32 workspace index
|
|
|
|
|
|
|
|
// Error-checking is done in ActivateWorkspace, so this is a safe call
|
2003-01-24 18:19:27 +03:00
|
|
|
SetWorkspace(*((int32*)index));
|
|
|
|
break;
|
2003-01-24 17:36:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Theoretically, we could just call the driver directly, but we will
|
|
|
|
// call the CursorManager's version to allow for future expansion
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_SHOW_CURSOR:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Show Cursor\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
cursormanager->ShowCursor();
|
2003-02-24 00:40:44 +03:00
|
|
|
_cursorhidden=false;
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_HIDE_CURSOR:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Hide Cursor\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
cursormanager->HideCursor();
|
2003-02-24 00:40:44 +03:00
|
|
|
_cursorhidden=true;
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_OBSCURE_CURSOR:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Obscure Cursor\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
cursormanager->ObscureCursor();
|
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_QUERY_CURSOR_HIDDEN:
|
2003-02-24 00:40:44 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: Query Cursor Hidden\n",_signature.String());
|
|
|
|
#endif
|
2003-02-24 00:40:44 +03:00
|
|
|
// Attached data
|
|
|
|
// 1) int32 port to reply to
|
2003-02-24 18:47:06 +03:00
|
|
|
write_port(*((port_id*)index),(_cursorhidden)?SERVER_TRUE:SERVER_FALSE,NULL,0);
|
2003-02-24 00:40:44 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_SET_CURSOR_DATA:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: SetCursor(cursor data *)\n",_signature.String());
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
// Attached data: 68 bytes of _appcursor data
|
|
|
|
|
|
|
|
int8 cdata[68];
|
|
|
|
memcpy(cdata, buffer, 68);
|
|
|
|
|
|
|
|
// Because we don't want an overaccumulation of these particular
|
|
|
|
// cursors, we will delete them if there is an existing one. It would
|
|
|
|
// otherwise be easy to crash the server by calling SetCursor a
|
|
|
|
// sufficient number of times
|
|
|
|
if(_appcursor)
|
2003-02-20 23:14:57 +03:00
|
|
|
cursormanager->DeleteCursor(_appcursor->ID());
|
2003-01-24 17:36:15 +03:00
|
|
|
|
|
|
|
_appcursor=new ServerCursor(cdata);
|
2003-02-24 18:47:06 +03:00
|
|
|
_appcursor->SetAppSignature(_signature.String());
|
2003-01-24 17:36:15 +03:00
|
|
|
cursormanager->AddCursor(_appcursor);
|
2003-02-20 23:14:57 +03:00
|
|
|
cursormanager->SetCursor(_appcursor->ID());
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-02-24 18:47:06 +03:00
|
|
|
case AS_SET_CURSOR_BCURSOR:
|
2003-01-24 17:36:15 +03:00
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s: SetCursor(BCursor)\n",_signature.String());
|
|
|
|
#endif
|
2003-02-24 18:47:06 +03:00
|
|
|
// Attached data:
|
|
|
|
// 1) port_id reply port
|
|
|
|
// 2) 68 bytes of _appcursor data
|
|
|
|
|
|
|
|
port_id replyport=*((port_id*)index);
|
|
|
|
index+=sizeof(port_id);
|
|
|
|
|
|
|
|
int8 cdata[68];
|
|
|
|
memcpy(cdata, index, 68);
|
|
|
|
|
|
|
|
_appcursor=new ServerCursor(cdata);
|
|
|
|
_appcursor->SetAppSignature(_signature.String());
|
|
|
|
cursormanager->AddCursor(_appcursor);
|
|
|
|
cursormanager->SetCursor(_appcursor->ID());
|
|
|
|
|
|
|
|
// Synchronous message - BApplication is waiting on the cursor's ID
|
|
|
|
PortLink replylink(replyport);
|
|
|
|
replylink.SetOpCode(AS_SET_CURSOR_BCURSOR);
|
|
|
|
replylink.Attach(_appcursor->ID());
|
|
|
|
replylink.Flush();
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
2003-03-23 23:52:37 +03:00
|
|
|
#ifdef DEBUG_SERVERAPP
|
|
|
|
printf("ServerApp %s received unhandled message code %lx\n",_signature.String(),code);
|
|
|
|
#endif
|
2003-01-24 17:36:15 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-03-12 17:29:59 +03:00
|
|
|
|
|
|
|
/*!
|
|
|
|
\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)
|
|
|
|
{
|
|
|
|
ServerBitmap *temp;
|
|
|
|
for(int32 i=0; i<_bmplist->CountItems();i++)
|
|
|
|
{
|
|
|
|
temp=(ServerBitmap*)_bmplist->ItemAt(i);
|
|
|
|
if(temp && temp->Token()==token)
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|