diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index 24d630cd81..9d87c2a834 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -18,7 +18,9 @@ // input messages from the Input Server. The other is the "main" port for // the server and is utilized mostly by BApplication objects. #define SERVER_PORT_NAME "OBappserver" -#define SERVER_INPUT_PORT "OBinputport" +#if TEST_MODE +# define SERVER_INPUT_PORT "OBinputport" +#endif enum { // Used for quick replies from the app_server @@ -26,7 +28,6 @@ enum { SERVER_FALSE = B_ERROR, AS_REGISTER_INPUT_SERVER = 1, - AS_ACQUIRED_INPUT_STREAM, AS_GET_DESKTOP, // Desktop definitions diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index a81f522f9d..868998c246 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -19,6 +19,7 @@ #include "Desktop.h" #include "FontManager.h" #include "HWInterface.h" +#include "InputManager.h" #include "Layer.h" #include "RGBColor.h" #include "RegistrarDefs.h" @@ -47,16 +48,8 @@ #include -//#define DEBUG_KEYHANDLING + //#define DEBUG_SERVER - -#ifdef DEBUG_KEYHANDLING -# include -# define KBTRACE(x) printf x -#else -# define KBTRACE(x) ; -#endif - #ifdef DEBUG_SERVER # include # define STRACE(x) printf x @@ -94,6 +87,8 @@ AppServer::AppServer() sAppServer = this; + gInputManager = new InputManager(); + // Create the font server and scan the proper directories. gFontManager = new FontManager; if (gFontManager->InitCheck() != B_OK) @@ -206,48 +201,6 @@ AppServer::_LaunchInputServer() // if at any time, one of these ports is error prone, it might mean input_server is gone // then relaunch input_server } - - -/*! - \brief Starts the Cursor Thread -*/ -void -AppServer::_LaunchCursorThread() -{ - // Spawn our cursor thread - fCursorThreadID = spawn_thread(_CursorThread, "CursorThreadOfTheDeath", - B_REAL_TIME_DISPLAY_PRIORITY - 1, this); - if (fCursorThreadID >= 0) - resume_thread(fCursorThreadID); - -} - - -/*! - \brief The Cursor Thread task -*/ -int32 -AppServer::_CursorThread(void* data) -{ - AppServer *server = (AppServer *)data; - - server->_LaunchInputServer(); - - do { - while (acquire_sem(server->fCursorSem) == B_OK) { - BPoint p; - p.y = *server->fCursorAddr & 0x7fff; - p.x = *server->fCursorAddr >> 15 & 0x7fff; - - //sDesktop->GetHWInterface()->MoveCursorTo(p.x, p.y); - STRACE(("CursorThread : %f, %f\n", p.x, p.y)); - } - - snooze(100000); - } while (!server->IsQuitting()); - - return B_OK; -} #endif diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 0855847117..278690caee 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -11,47 +11,40 @@ /** Class used to encapsulate desktop management */ -#include +#include "Desktop.h" -#include -#include +#include "AppServer.h" +#include "DesktopSettingsPrivate.h" +#include "DrawingEngine.h" +#include "HWInterface.h" +#include "InputManager.h" +#include "Layer.h" +#include "RootLayer.h" +#include "ServerApp.h" +#include "ServerConfig.h" +#include "ServerScreen.h" +#include "ServerWindow.h" +#include "WinBorder.h" +#include "Workspace.h" #include #include -#include "AppServer.h" -#include "DrawingEngine.h" -#include "Layer.h" -#include "RootLayer.h" -#include "ServerConfig.h" -#include "ServerScreen.h" -#include "ServerApp.h" -#include "ServerWindow.h" -#include "WinBorder.h" -#include "Workspace.h" -#include "DesktopSettingsPrivate.h" +#include +#include +#include +#include -#ifdef __HAIKU__ -# define USE_ACCELERANT 1 -#else -# define USE_ACCELERANT 0 +#if TEST_MODE +# include "EventStream.h" #endif -#if USE_ACCELERANT -# include "AccelerantHWInterface.h" -#else -# include "ViewHWInterface.h" -#endif - -#include "Desktop.h" - //#define DEBUG_DESKTOP - #ifdef DEBUG_DESKTOP # define STRACE(a) printf(a) #else -# define STRACE(a) /* nothing */ +# define STRACE(a) ; #endif @@ -104,14 +97,60 @@ Desktop::Init() fRootLayer = new RootLayer(name, 4, this, GetDrawingEngine()); #if TEST_MODE - RegisterInputServer(find_port(SERVER_INPUT_PORT)); - // this is where the ViewHWInterface will send its input events to + gInputManager->AddStream(new InputServerStream); #endif + fEventDispatcher.SetTo(gInputManager->GetStream()); + fEventDispatcher.SetHWInterface(fVirtualScreen.HWInterface()); + + // temporary hack to get things started + class MouseFilter : public BMessageFilter { + public: + MouseFilter(RootLayer* layer) + : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE), + fRootLayer(layer) + { + } + + virtual filter_result + Filter(BMessage* message, BHandler** /*_target*/) + { + fRootLayer->Lock(); + fRootLayer->MouseEventHandler(message); + fRootLayer->Unlock(); + return B_SKIP_MESSAGE; + } + + private: + RootLayer* fRootLayer; + }; + class KeyFilter : public BMessageFilter { + public: + KeyFilter(RootLayer* layer) + : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE), + fRootLayer(layer) + { + } + + virtual filter_result + Filter(BMessage* message, BHandler** /*_target*/) + { + fRootLayer->Lock(); + fRootLayer->KeyboardEventHandler(message); + fRootLayer->Unlock(); + return B_SKIP_MESSAGE; + } + + private: + RootLayer* fRootLayer; + }; + fEventDispatcher.SetMouseFilter(new MouseFilter(fRootLayer)); + fEventDispatcher.SetKeyFilter(new KeyFilter(fRootLayer)); // take care of setting the default cursor ServerCursor *cursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT); if (cursor) fVirtualScreen.HWInterface()->SetCursor(cursor); + fVirtualScreen.HWInterface()->SetCursorVisible(true); } @@ -341,16 +380,6 @@ Desktop::_ActivateApp(team_id team) } -void -Desktop::RegisterInputServer(port_id port) -{ - fInputPort = port; - fRootLayer->RunThread(); - - fVirtualScreen.HWInterface()->SetCursorVisible(true); -} - - /*! \brief Send a quick (no attachments) message to all applications diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 87362821e2..68f295d54e 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -51,8 +51,7 @@ class Desktop : public MessageLooper, public ScreenOwner { uid_t UserID() const { return fUserID; } virtual port_id MessagePort() const { return fMessagePort; } - void RegisterInputServer(port_id port); - port_id InputServerPort() { return fInputPort; } + ::EventDispatcher& EventDispatcher() { return fEventDispatcher; } void BroadcastToAllApps(int32 code); @@ -106,7 +105,7 @@ class Desktop : public MessageLooper, public ScreenOwner { ::VirtualScreen fVirtualScreen; DesktopSettings::Private* fSettings; port_id fMessagePort; - EventDispatcher fEventDispatcher; + ::EventDispatcher fEventDispatcher; port_id fInputPort; BLocker fAppListLock; diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index d87b5057f5..601faa2307 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -10,6 +10,7 @@ #include "EventDispatcher.h" #include "EventStream.h" #include "HWInterface.h" +#include "InputManager.h" #include #include @@ -19,6 +20,14 @@ #include +//#define TRACE_EVENTS +#ifdef TRACE_EVENTS +# define ETRACE(x) printf x +#else +# define ETRACE(x) ; +#endif + + /*! The differentiation between messenger and token looks odd, but it really has a reason as well: @@ -68,11 +77,16 @@ EventDispatcher::~EventDispatcher() status_t -EventDispatcher::SetTo(EventStream& stream) +EventDispatcher::SetTo(EventStream* stream) { + ETRACE(("event dispatcher: stream = %p\n", stream)); + _Unset(); - fStream = &stream; + if (stream == NULL) + return B_OK; + + fStream = stream; return _Run(); } @@ -93,12 +107,18 @@ EventDispatcher::InitCheck() void EventDispatcher::_Unset() { + if (fStream == NULL) + return; + fStream->SendQuit(); wait_for_thread(fThread, NULL); wait_for_thread(fCursorThread, NULL); fThread = fCursorThread = -1; + + gInputManager->PutStream(fStream); + fStream = NULL; } @@ -111,6 +131,8 @@ EventDispatcher::_Run() return fThread; if (fStream->SupportsCursorThread()) { + ETRACE(("event stream supports cursor thread!\n")); + fCursorThread = spawn_thread(_cursor_looper, "cursor loop", B_REAL_TIME_DISPLAY_PRIORITY - 5, this); if (resume_thread(fCursorThread) != B_OK) { @@ -556,6 +578,7 @@ EventDispatcher::_event_looper(void* _dispatcher) { EventDispatcher* dispatcher = (EventDispatcher*)_dispatcher; + ETRACE(("Start event loop\n")); dispatcher->_EventLoop(); return B_OK; } @@ -567,6 +590,7 @@ EventDispatcher::_cursor_looper(void* _dispatcher) { EventDispatcher* dispatcher = (EventDispatcher*)_dispatcher; + ETRACE(("Start cursor loop\n")); dispatcher->_CursorLoop(); return B_OK; } diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index 27d5cf4c4a..b51e6221fc 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -24,7 +24,7 @@ class EventDispatcher : public BLocker { EventDispatcher(); ~EventDispatcher(); - status_t SetTo(EventStream& stream); + status_t SetTo(EventStream* stream); status_t InitCheck(); void SetFocus(BMessenger* messenger); @@ -41,8 +41,6 @@ class EventDispatcher : public BLocker { bool HasCursorThread(); void SetHWInterface(HWInterface* interface); - EventStream* Stream(); - private: struct event_target; diff --git a/src/servers/app/EventStream.cpp b/src/servers/app/EventStream.cpp index 8a7c0c99cc..20819e1eee 100644 --- a/src/servers/app/EventStream.cpp +++ b/src/servers/app/EventStream.cpp @@ -9,6 +9,8 @@ #include "EventStream.h" +#include +#include #include #include @@ -32,19 +34,53 @@ EventStream::SupportsCursorThread() const } +bool +EventStream::GetNextCursorPosition(BPoint& where) +{ + return false; +} + + // #pragma mark - -InputServerStream::InputServerStream(port_id port, port_id inputServerPort) +InputServerStream::InputServerStream(BMessenger& messenger) : - fPort(port), + fInputServer(messenger), + fPort(-1), fQuitting(false) { + BMessage message(IS_ACQUIRE_INPUT); + fCursorArea = create_area("shared cursor", (void **)&fCursorBuffer, B_ANY_ADDRESS, + B_PAGE_SIZE, B_LAZY_LOCK, B_READ_AREA | B_WRITE_AREA); + if (fCursorArea >= B_OK) + message.AddInt32("cursor area", fCursorArea); + + BMessage reply; + if (messenger.SendMessage(&message, &reply) != B_OK) + return; + + if (reply.FindInt32("event port", &fPort) != B_OK) + fPort = -1; + if (reply.FindInt32("cursor semaphore", &fCursorSemaphore) != B_OK) + fCursorSemaphore = -1; } +#if TEST_MODE +InputServerStream::InputServerStream() + : + fQuitting(false), + fCursorSemaphore(-1) +{ + fPort = find_port(SERVER_INPUT_PORT); +} +#endif + + InputServerStream::~InputServerStream() { + delete_area(fCursorArea); } diff --git a/src/servers/app/EventStream.h b/src/servers/app/EventStream.h index 1f45114a2e..734301074d 100644 --- a/src/servers/app/EventStream.h +++ b/src/servers/app/EventStream.h @@ -9,6 +9,7 @@ #define EVENT_STREAM_H +#include #include struct shared_cursor; @@ -25,13 +26,17 @@ class EventStream { virtual bool SupportsCursorThread() const; virtual bool GetNextEvent(BMessage** _event) = 0; - virtual bool GetNextCursorPosition(BPoint& where) = 0; + virtual bool GetNextCursorPosition(BPoint& where); }; -class InputServerStream { +class InputServerStream : public EventStream { public: - InputServerStream(port_id port, port_id inputServerPort); + InputServerStream(BMessenger& inputServerMessenger); +#if TEST_MODE + InputServerStream(); +#endif + virtual ~InputServerStream(); virtual bool IsValid(); @@ -46,6 +51,7 @@ class InputServerStream { status_t _MessageFromPort(BMessage** _message, bigtime_t timeout = B_INFINITE_TIMEOUT); + BMessenger fInputServer; BMessageQueue fEvents; port_id fPort; bool fQuitting; diff --git a/src/servers/app/InputManager.cpp b/src/servers/app/InputManager.cpp index df05a8160d..1115f8c797 100644 --- a/src/servers/app/InputManager.cpp +++ b/src/servers/app/InputManager.cpp @@ -37,7 +37,6 @@ bool InputManager::AddStream(EventStream* stream) { BAutolock _(this); -printf("got stream: %p\n", stream); return fFreeStreams.AddItem(stream); } @@ -57,7 +56,6 @@ InputManager::GetStream() EventStream* stream = NULL; do { -printf("remove invalid stream: %p\n", stream); delete stream; // this deletes the previous invalid stream @@ -68,7 +66,6 @@ printf("remove invalid stream: %p\n", stream); return NULL; fUsedStreams.AddItem(stream); -printf("return stream: %p\n", stream); return stream; } diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 7aceab8625..32ade9dcb8 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -30,6 +30,7 @@ Server app_server : FontFamily.cpp FontManager.cpp HashTable.cpp + InputManager.cpp Layer.cpp MessageLooper.cpp MultiLocker.cpp diff --git a/src/servers/app/MultiLocker.cpp b/src/servers/app/MultiLocker.cpp index b232f5c9da..3213bbf353 100644 --- a/src/servers/app/MultiLocker.cpp +++ b/src/servers/app/MultiLocker.cpp @@ -53,7 +53,6 @@ MultiLocker::MultiLocker(const char* semaphoreBaseName) system_info sys; get_system_info(&sys); fMaxThreads = sys.max_threads; - printf("max_threads: %ld used_threads: %ld\n", sys.max_threads, sys.used_threads); fDebugArray = (int32 *) malloc(fMaxThreads * sizeof(int32)); for (int32 i = 0; i < fMaxThreads; i++) { fDebugArray[i] = 0; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index 95dac1f2a1..9299efaa5c 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -69,9 +69,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fDirtyForRedraw(), - fThreadID(B_ERROR), - fListenPort(-1), - fButtons(0), fLastMousePosition(0.0, 0.0), @@ -82,8 +79,7 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fWMState(), fWinBorderIndex(0), - fScreenShotIndex(1), - fQuiting(false) + fScreenShotIndex(1) { //NOTE: be careful about this one. fRootLayer = this; @@ -127,9 +123,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fDrawState->SetHighColor(RGBColor(255, 255, 255)); fDrawState->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor()); - // Spawn our working thread - fThreadID = spawn_thread(WorkingThread, name, B_DISPLAY_PRIORITY, this); - #if ON_SCREEN_DEBUGGING_INFO DebugInfoManager::Default()->SetRootLayer(this); #endif @@ -139,28 +132,18 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, // RootLayer starts with valid visible regions fFullVisible.Set(Bounds()); fVisible.Set(Bounds()); + + // first make sure we are actualy visible + MarkForRebuild(Bounds()); + MarkForRedraw(Bounds()); + + TriggerRebuild(); + TriggerRedraw(); } RootLayer::~RootLayer() { - fQuiting = true; - - BMessage quitMsg(B_QUIT_REQUESTED); - ssize_t length = quitMsg.FlattenedSize(); - char buffer[length]; - if (quitMsg.Flatten(buffer,length) < B_OK) { - // failed to flatten? - kill_thread(fThreadID); - } - else{ - write_port(fListenPort, 0, buffer, length); - - status_t dummy; - wait_for_thread(fThreadID, &dummy); - } - - delete fDragMessage; for (int32 i = 0; i < fWsCount; i++) @@ -175,103 +158,6 @@ RootLayer::~RootLayer() } -void -RootLayer::RunThread() -{ - if (fThreadID > 0) - resume_thread(fThreadID); - else - CRITICAL("Can not create any more threads.\n"); -} - -/*! - \brief Thread function for handling input messages and calculating visible regions. - \param data Pointer to the app_server to which the thread belongs - \return Throwaway value - always 0 -*/ -int32 -RootLayer::WorkingThread(void *data) -{ - RootLayer *oneRootLayer = (RootLayer*)data; - - oneRootLayer->Lock(); - oneRootLayer->fListenPort = oneRootLayer->fDesktop->InputServerPort(); - - // first make sure we are actualy visible - - oneRootLayer->MarkForRebuild(oneRootLayer->Bounds()); - oneRootLayer->MarkForRedraw(oneRootLayer->Bounds()); - - oneRootLayer->TriggerRebuild(); - oneRootLayer->TriggerRedraw(); - - oneRootLayer->Unlock(); - - STRACE(("info: RootLayer(%s)::WorkingThread listening on port %ld.\n", oneRootLayer->Name(), oneRootLayer->fListenPort)); - while (!oneRootLayer->fQuiting) { - BMessage *msg = oneRootLayer->ReadMessageFromPort(B_INFINITE_TIMEOUT); - if (msg) - oneRootLayer->fQueue.AddMessage(msg); - - int32 msgCount = port_count(oneRootLayer->fListenPort); - for (int32 i = 0; i < msgCount; ++i) { - msg = oneRootLayer->ReadMessageFromPort(0); - if (msg) - oneRootLayer->fQueue.AddMessage(msg); - } - - // loop as long as there are messages in the queue and the port is empty. - bool dispatchNextMessage = true; - while(dispatchNextMessage && !oneRootLayer->fQuiting) { - BMessage *currentMessage = oneRootLayer->fQueue.NextMessage(); - - if (!currentMessage) - // no more messages - dispatchNextMessage = false; - else { - oneRootLayer->Lock(); - - switch (currentMessage->what) { - // We don't need to do anything with these two, so just pass them - // onto the active application. Eventually, we will end up passing - // them onto the window which is currently under the cursor. - case B_MOUSE_DOWN: - case B_MOUSE_UP: - case B_MOUSE_MOVED: - case B_MOUSE_WHEEL_CHANGED: - oneRootLayer->MouseEventHandler(currentMessage); - break; - - case B_KEY_DOWN: - case B_KEY_UP: - case B_UNMAPPED_KEY_DOWN: - case B_UNMAPPED_KEY_UP: - case B_MODIFIERS_CHANGED: - oneRootLayer->KeyboardEventHandler(currentMessage); - break; - - case B_QUIT_REQUESTED: - exit_thread(0); - break; - - default: - printf("RootLayer(%s)::WorkingThread received unexpected code %lx\n", oneRootLayer->Name(), msg->what); - break; - } - - oneRootLayer->Unlock(); - - delete currentMessage; - - // Are any messages on the port? - if (port_count(oneRootLayer->fListenPort) > 0) - dispatchNextMessage = false; - } - } - } - return 0; -} - void RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel) { @@ -1599,72 +1485,6 @@ RootLayer::AddDebugInfo(const char* string) #endif // ON_SCREEN_DEBUGGING_INFO -// taken from BLooper -void * -RootLayer::ReadRawFromPort(int32 *msgCode, bigtime_t timeout) -{ - int8 *msgBuffer = NULL; - ssize_t bufferSize; - - do { - bufferSize = port_buffer_size_etc(fListenPort, B_RELATIVE_TIMEOUT, timeout); - } while (bufferSize == B_INTERRUPTED); - - if (bufferSize < B_OK) - return NULL; - - if (bufferSize > 0) - msgBuffer = new int8[bufferSize]; - - // we don't want to wait again here, since that can only mean - // that someone else has read our message and our bufferSize - // is now probably wrong - bufferSize = read_port_etc(fListenPort, msgCode, msgBuffer, bufferSize, - B_RELATIVE_TIMEOUT, 0); - if (bufferSize < B_OK) { - delete[] msgBuffer; - return NULL; - } - - return msgBuffer; -} - - -BMessage * -RootLayer::ReadMessageFromPort(bigtime_t tout) -{ - int32 msgcode; - BMessage* bmsg; - - void* msgbuffer = ReadRawFromPort(&msgcode, tout); - if (!msgbuffer) - return NULL; - - bmsg = ConvertToMessage(msgbuffer, msgcode); - - delete[] (int8*)msgbuffer; - - return bmsg; -} - - -BMessage* -RootLayer::ConvertToMessage(void* raw, int32 code) -{ - BMessage* message = new BMessage(code); - - if (raw != NULL) { - if (message->Unflatten((const char*)raw) != B_OK) { - printf("Convert To BMessage FAILED. port message code was: %ld - %c%c%c%c\n", - code, (int8)(code >> 24), (int8)(code >> 16), (int8)(code >> 8), (int8)code); - delete message; - return NULL; - } - } - - return message; -} - void RootLayer::MarkForRedraw(const BRegion &dirty) { diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index 0a09f11968..73a294de67 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -109,13 +109,10 @@ public: void LayerRemoved(Layer* layer); - static int32 WorkingThread(void *data); - // Other methods bool Lock() { return fAllRegionsLock.Lock(); } void Unlock() { fAllRegionsLock.Unlock(); } bool IsLocked() { return fAllRegionsLock.IsLocked(); } - void RunThread(); void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel); @@ -153,10 +150,6 @@ friend class Desktop; inline HWInterface* GetHWInterface() const { return fDesktop->GetHWInterface(); } - void* ReadRawFromPort(int32 *msgCode, bigtime_t timeout); - BMessage* ReadMessageFromPort(bigtime_t tout); - BMessage* ConvertToMessage(void* raw, int32 code); - Desktop* fDesktop; BMessage* fDragMessage; Layer* fLastLayerUnderMouse; @@ -171,10 +164,6 @@ friend class Desktop; BRegion fDirtyForRedraw; - thread_id fThreadID; - port_id fListenPort; - BMessageQueue fQueue; - int32 fButtons; BPoint fLastMousePosition; @@ -190,7 +179,6 @@ friend class Desktop; mutable int32 fWinBorderIndex; int32 fScreenShotIndex; - bool fQuiting; #if ON_SCREEN_DEBUGGING_INFO friend class DebugInfoManager; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index ead3bfddfc..d5a2ecf6b3 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -28,10 +28,9 @@ #include #include -#include #include - -#include +#include +#include #include "AppServer.h" #include "BGet++.h" @@ -41,8 +40,10 @@ #include "Desktop.h" #include "DecorManager.h" #include "DrawingEngine.h" +#include "EventStream.h" #include "FontManager.h" #include "HWInterface.h" +#include "InputManager.h" #include "OffscreenServerWindow.h" #include "RAMLinkMsgReader.h" #include "RootLayer.h" @@ -86,13 +87,11 @@ static const uint32 kMsgAppQuit = 'appQ'; MIME fSignature. */ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, - port_id clientLooperPort, team_id clientTeam, int32 handlerID, + port_id clientLooperPort, team_id clientTeam, int32 clientToken, const char* signature) : MessageLooper("application"), fMessagePort(-1), fClientReplyPort(clientReplyPort), - fClientLooperPort(clientLooperPort), - fClientToken(handlerID), fDesktop(desktop), fSignature(signature), fClientTeam(clientTeam), @@ -122,6 +121,9 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, return; } + BMessenger::Private(fClientMessenger).SetTo(fClientTeam, + clientLooperPort, clientToken, false); + ServerCursor *defaultCursor = fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT); @@ -273,17 +275,9 @@ ServerApp::Quit(sem_id shutdownSemaphore) \param msg The message to send */ void -ServerApp::SendMessageToClient(const BMessage *msg) const +ServerApp::SendMessageToClient(BMessage *msg) const { - 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 - printf("PANIC: ServerApp: '%s': can't flatten message in 'SendMessageToClient()'\n", Signature()); - - delete [] buffer; + fClientMessenger.SendMessage(msg); } @@ -398,32 +392,31 @@ ServerApp::_MessageLooper() \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. */ void -ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) +ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { switch (code) { case AS_REGISTER_INPUT_SERVER: { - BMessage message(IS_ACQUIRE_INPUT); - SendMessageToClient(&message); - break; - } - case AS_ACQUIRED_INPUT_STREAM: - { - bool hasKeyboard, hasMouse; - link.Read(&hasKeyboard); - link.Read(&hasMouse); + EventStream* stream = new (nothrow) InputServerStream(fClientMessenger); + if (stream != NULL + && (!stream->IsValid() || !gInputManager->AddStream(stream))) { + delete stream; + break; + } - port_id port; - link.Read(&port); - sem_id sem; - if (link.Read(&sem) == B_OK) - fDesktop->RegisterInputServer(port); + // TODO: this should be done using notifications (so that an abandoned + // stream will get noticed directly) + if (fDesktop->EventDispatcher().InitCheck() != B_OK) { + fDesktop->EventDispatcher().SetTo(gInputManager->GetStream()); + fDesktop->EventDispatcher().SetHWInterface(fDesktop->GetHWInterface()); + fDesktop->GetHWInterface()->SetCursorVisible(true); + } break; } case AS_CREATE_WINDOW: diff --git a/src/servers/app/ServerApp.h b/src/servers/app/ServerApp.h index 551a2dcf9f..fa8563043f 100644 --- a/src/servers/app/ServerApp.h +++ b/src/servers/app/ServerApp.h @@ -55,7 +55,7 @@ class ServerApp : public MessageLooper { bool IsActive(void) const { return fIsActive; } void Activate(bool value); - void SendMessageToClient(const BMessage* msg) const; + void SendMessageToClient(BMessage* msg) const; void SetAppCursor(void); @@ -86,6 +86,7 @@ class ServerApp : public MessageLooper { port_id fClientReplyPort; // our BApplication's event port + BMessenger fClientMessenger; port_id fClientLooperPort; int32 fClientToken; // To send a BMessage to the client (port + token) diff --git a/src/servers/input/InputServer.cpp b/src/servers/input/InputServer.cpp index f2c67bb8c9..3960748be1 100644 --- a/src/servers/input/InputServer.cpp +++ b/src/servers/input/InputServer.cpp @@ -406,7 +406,7 @@ InputServer::_AcquireInput(BMessage& message, BMessage& reply) { // TODO: it currently just gets everything we have area_id area; - if (message.FindInt32("cursor_area", &area) == B_OK) { + if (message.FindInt32("cursor area", &area) == B_OK) { // try to clone the area fCursorBuffer = NULL; @@ -423,25 +423,15 @@ InputServer::_AcquireInput(BMessage& message, BMessage& reply) return fAppServerPort; } - // TODO: would be nice if we could just reply to this message... -#if 0 - reply.AddBool("has_keyboard", true); - reply.AddBool("has_mouse", true); + reply.AddBool("has keyboard", true); + reply.AddBool("has mouse", true); reply.AddInt32("event port", fAppServerPort); if (fCursorBuffer != NULL) { // cursor shared buffer is supported reply.AddInt32("cursor semaphore", fCursorSem); } -#else - BPrivate::AppServerLink link; - link.StartMessage(AS_ACQUIRED_INPUT_STREAM); - link.Attach(true); - link.Attach(true); - link.Attach(fAppServerPort); - link.Attach(fCursorSem); - link.Flush(); -#endif + return B_OK; } @@ -554,8 +544,8 @@ InputServer::MessageReceived(BMessage* message) // app_server communication case IS_ACQUIRE_INPUT: - _AcquireInput(*message, reply); - return; + status = _AcquireInput(*message, reply); + break; case IS_RELEASE_INPUT: _ReleaseInput(message); return; diff --git a/src/tests/servers/app/Jamfile b/src/tests/servers/app/Jamfile index d20b7406ff..35e6378f24 100644 --- a/src/tests/servers/app/Jamfile +++ b/src/tests/servers/app/Jamfile @@ -89,6 +89,7 @@ Server haiku_app_server : BitmapManager.cpp CursorManager.cpp DecorManager.cpp + InputManager.cpp ScreenManager.cpp AppServer.cpp