diff --git a/headers/private/app/AppMisc.h b/headers/private/app/AppMisc.h index ad4a30d621..ac263d6ed2 100644 --- a/headers/private/app/AppMisc.h +++ b/headers/private/app/AppMisc.h @@ -16,6 +16,9 @@ struct entry_ref; namespace BPrivate { +class ServerLink; + + status_t get_app_path(team_id team, char *buffer); status_t get_app_path(char *buffer); status_t get_app_ref(team_id team, entry_ref *ref, bool traverse = true); @@ -26,6 +29,10 @@ thread_id main_thread_for(team_id team); bool is_app_showing_modal_window(team_id team); +port_id get_app_server_port(); +status_t create_desktop_connection(ServerLink* link, const char* name, + int32 capacity); + } // namespace BPrivate // _get_object_token_ diff --git a/headers/private/app/DesktopLink.h b/headers/private/app/DesktopLink.h index 2d896373c3..20fa0b15df 100644 --- a/headers/private/app/DesktopLink.h +++ b/headers/private/app/DesktopLink.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku. + * Copyright 2006-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -15,14 +15,11 @@ namespace BPrivate { class DesktopLink : public PortLink { - public: - DesktopLink(); - virtual ~DesktopLink(); +public: + DesktopLink(); + virtual ~DesktopLink(); - status_t InitCheck() const; - - private: - port_id fReplyPort; + status_t InitCheck() const; }; } // namespace BPrivate diff --git a/headers/private/app/PortLink.h b/headers/private/app/PortLink.h index 132a711db5..a31841792c 100644 --- a/headers/private/app/PortLink.h +++ b/headers/private/app/PortLink.h @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -14,14 +14,15 @@ namespace BPrivate { -class PortLink : public ServerLink { - public: - PortLink(port_id sender = -1, port_id receiver = -1); - virtual ~PortLink(); - void SetTo(port_id sender, port_id receiver); +class PortLink : public ServerLink { +public: + PortLink(port_id sender = -1, + port_id receiver = -1); + virtual ~PortLink(); }; + } // namespace BPrivate #endif /* _PORT_LINK_H */ diff --git a/headers/private/app/ServerLink.h b/headers/private/app/ServerLink.h index d295bc4b72..4b1e73da10 100644 --- a/headers/private/app/ServerLink.h +++ b/headers/private/app/ServerLink.h @@ -32,56 +32,68 @@ class BGradient; namespace BPrivate { class ServerLink { - public: - ServerLink(); - virtual ~ServerLink(); +public: + ServerLink(); + virtual ~ServerLink(); - // send methods + void SetTo(port_id sender, port_id receiver); - void SetSenderPort(port_id port); - port_id SenderPort(); + // send methods - status_t StartMessage(int32 code, size_t minSize = 0); - void CancelMessage(); - status_t EndMessage(); + void SetSenderPort(port_id port); + port_id SenderPort(); - status_t Flush(bigtime_t timeout = B_INFINITE_TIMEOUT, bool needsReply = false); - status_t Attach(const void *data, ssize_t size); - status_t AttachString(const char *string, int32 length = -1); - status_t AttachRegion(const BRegion ®ion); - status_t AttachShape(BShape &shape); - status_t AttachGradient(const BGradient &gradient); - template status_t Attach(const Type& data); + status_t StartMessage(int32 code, size_t minSize = 0); + void CancelMessage(); + status_t EndMessage(); - // receive methods + status_t Flush(bigtime_t timeout = B_INFINITE_TIMEOUT, + bool needsReply = false); + status_t Attach(const void* data, ssize_t size); + status_t AttachString(const char* string, + int32 length = -1); + status_t AttachRegion(const BRegion& region); + status_t AttachShape(BShape& shape); + status_t AttachGradient(const BGradient& gradient); - void SetReceiverPort(port_id port); - port_id ReceiverPort(); + template + status_t Attach(const Type& data); - status_t GetNextMessage(int32 &code, bigtime_t timeout = B_INFINITE_TIMEOUT); - bool NeedsReply() const; - status_t Read(void *data, ssize_t size); - status_t ReadString(char *buffer, size_t bufferSize); - status_t ReadString(BString& string, size_t* _length = NULL); - status_t ReadString(char** _string, size_t* _length = NULL); - status_t ReadRegion(BRegion *region); - status_t ReadShape(BShape *shape); - status_t ReadGradient(BGradient **gradient); - template status_t Read(Type *data); + // receive methods - // convenience methods + void SetReceiverPort(port_id port); + port_id ReceiverPort(); - status_t FlushWithReply(int32 &code); - LinkSender &Sender() { return *fSender; } - LinkReceiver &Receiver() { return *fReceiver; } + status_t GetNextMessage(int32& code, + bigtime_t timeout = B_INFINITE_TIMEOUT); + bool NeedsReply() const; + status_t Read(void* data, ssize_t size); + status_t ReadString(char* buffer, size_t bufferSize); + status_t ReadString(BString& string, + size_t* _length = NULL); + status_t ReadString(char** _string, + size_t* _length = NULL); + status_t ReadRegion(BRegion* region); + status_t ReadShape(BShape* shape); + status_t ReadGradient(BGradient** _gradient); + + template + status_t Read(Type* data); - protected: - LinkSender *fSender; - LinkReceiver *fReceiver; + // convenience methods + + status_t FlushWithReply(int32& code); + LinkSender& Sender() { return *fSender; } + LinkReceiver& Receiver() { return *fReceiver; } + +protected: + LinkSender* fSender; + LinkReceiver* fReceiver; }; -// sender inline functions +// #pragma mark - sender inline functions + inline void ServerLink::SetSenderPort(port_id port) @@ -89,110 +101,129 @@ ServerLink::SetSenderPort(port_id port) fSender->SetPort(port); } + inline port_id ServerLink::SenderPort() { return fSender->Port(); } + inline status_t ServerLink::StartMessage(int32 code, size_t minSize) { return fSender->StartMessage(code, minSize); } + inline status_t ServerLink::EndMessage() { return fSender->EndMessage(); } + inline void ServerLink::CancelMessage() { fSender->CancelMessage(); } + inline status_t ServerLink::Flush(bigtime_t timeout, bool needsReply) { return fSender->Flush(timeout, needsReply); } + inline status_t -ServerLink::Attach(const void *data, ssize_t size) +ServerLink::Attach(const void* data, ssize_t size) { return fSender->Attach(data, size); } + inline status_t -ServerLink::AttachString(const char *string, int32 length) +ServerLink::AttachString(const char* string, int32 length) { return fSender->AttachString(string, length); } + template status_t -ServerLink::Attach(const Type &data) +ServerLink::Attach(const Type& data) { return Attach(&data, sizeof(Type)); } + // #pragma mark - receiver inline functions + inline void ServerLink::SetReceiverPort(port_id port) { fReceiver->SetPort(port); } + inline port_id ServerLink::ReceiverPort() { return fReceiver->Port(); } + inline status_t -ServerLink::GetNextMessage(int32 &code, bigtime_t timeout) +ServerLink::GetNextMessage(int32& code, bigtime_t timeout) { return fReceiver->GetNextMessage(code, timeout); } + inline bool ServerLink::NeedsReply() const { return fReceiver->NeedsReply(); } + inline status_t -ServerLink::Read(void *data, ssize_t size) +ServerLink::Read(void* data, ssize_t size) { return fReceiver->Read(data, size); } + inline status_t -ServerLink::ReadString(char *buffer, size_t bufferSize) +ServerLink::ReadString(char* buffer, size_t bufferSize) { return fReceiver->ReadString(buffer, bufferSize); } + inline status_t ServerLink::ReadString(BString& string, size_t* _length) { return fReceiver->ReadString(string, _length); } + inline status_t ServerLink::ReadString(char** _string, size_t* _length) { return fReceiver->ReadString(_string, _length); } + template status_t -ServerLink::Read(Type *data) +ServerLink::Read(Type* data) { return Read(data, sizeof(Type)); } + } // namespace BPrivate #endif /* _SERVER_LINK_H */ diff --git a/src/kits/app/AppMisc.cpp b/src/kits/app/AppMisc.cpp index b5d7fa47a1..c3047bb97b 100644 --- a/src/kits/app/AppMisc.cpp +++ b/src/kits/app/AppMisc.cpp @@ -8,12 +8,17 @@ #include + +#include +#include +#include + #include #include #include -#include -#include +#include +#include namespace BPrivate { @@ -158,4 +163,55 @@ is_app_showing_modal_window(team_id team) return true; } + +port_id +get_app_server_port() +{ + static port_id sServerPort = -1; + + if (sServerPort < 0) { + // No need for synchronization - in the worst case, we'll call + // find_port() twice. + sServerPort = find_port(SERVER_PORT_NAME); + } + + return sServerPort; +} + + +/*! Creates a connection with the desktop. +*/ +status_t +create_desktop_connection(ServerLink* link, const char* name, int32 capacity) +{ + port_id serverPort = get_app_server_port(); + if (serverPort < 0) + return serverPort; + + // Create the port so that the app_server knows where to send messages + port_id clientPort = create_port(capacity, name); + if (clientPort < 0) + return clientPort; + + link->SetTo(serverPort, clientPort); + + link->StartMessage(AS_GET_DESKTOP); + link->Attach(clientPort); + link->Attach(getuid()); + link->AttachString(getenv("TARGET_SCREEN")); + link->Attach(AS_PROTOCOL_VERSION); + + int32 code; + if (link->FlushWithReply(code) != B_OK || code != B_OK) { + link->SetSenderPort(-1); + return B_ERROR; + } + + link->Read(&serverPort); + link->SetSenderPort(serverPort); + + return B_OK; +} + + } // namespace BPrivate diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 2df2202dc8..eaeea80cad 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -1228,33 +1228,10 @@ BApplication::_InitGUIContext() status_t BApplication::_ConnectToServer() { - port_id serverPort = find_port(SERVER_PORT_NAME); - if (serverPort < B_OK) - return serverPort; - - // Create the port so that the app_server knows where to send messages - port_id clientPort = create_port(100, "aSetTo(serverPort, clientPort); - - fServerLink->StartMessage(AS_GET_DESKTOP); - fServerLink->Attach(clientPort); - fServerLink->Attach(getuid()); - fServerLink->AttachString(getenv("TARGET_SCREEN")); - fServerLink->Attach(AS_PROTOCOL_VERSION); - - int32 code; - if (fServerLink->FlushWithReply(code) != B_OK || code != B_OK) { - fServerLink->SetSenderPort(-1); - return B_ERROR; - } - - // we talk to the desktop to create our application - fServerLink->Read(&serverPort); - fServerLink->SetSenderPort(serverPort); + status_t status + = create_desktop_connection(fServerLink, "aStartMessage(AS_CREATE_APP); - fServerLink->Attach(clientPort); + fServerLink->Attach(fServerLink->ReceiverPort()); fServerLink->Attach(_get_looper_port_(this)); fServerLink->Attach(Team()); fServerLink->Attach(_get_object_token_(this)); fServerLink->AttachString(fAppName); area_id sharedReadOnlyArea; + port_id serverPort; + int32 code; if (fServerLink->FlushWithReply(code) == B_OK && code == B_OK) { // We don't need to contact the main app_server anymore @@ -1288,7 +1267,7 @@ BApplication::_ConnectToServer() fServerLink->SetSenderPort(serverPort); - status_t status = _SetupServerAllocator(); + status = _SetupServerAllocator(); if (status != B_OK) return status; diff --git a/src/kits/app/DesktopLink.cpp b/src/kits/app/DesktopLink.cpp index 83feea6655..8794a2bc9d 100644 --- a/src/kits/app/DesktopLink.cpp +++ b/src/kits/app/DesktopLink.cpp @@ -9,9 +9,7 @@ #include -#include -#include - +#include #include @@ -19,48 +17,21 @@ namespace BPrivate { DesktopLink::DesktopLink() - : - fReplyPort(B_ERROR) { - // get the app server port - port_id port = find_port(SERVER_PORT_NAME); - if (port < B_OK) - return; - - // create a reply port - fReplyPort = create_port(1, "desktop reply"); - if (fReplyPort < B_OK) - return; - - SetTo(port, fReplyPort); - - // We can't use AppServerLink because be_app may be NULL - StartMessage(AS_GET_DESKTOP); - Attach(fReplyPort); - Attach(getuid()); - AttachString(getenv("TARGET_SCREEN")); - Attach(AS_PROTOCOL_VERSION); - - int32 code; - if (FlushWithReply(code) != B_OK || code != B_OK) - return; - - // we now talk to the desktop - Read(&port); - SetSenderPort(port); + create_desktop_connection(this, "desktop reply", 1); } DesktopLink::~DesktopLink() { - delete_port(fReplyPort); + delete_port(fReceiver->Port()); } status_t DesktopLink::InitCheck() const { - return fReplyPort < B_OK ? fReplyPort : B_OK; + return fReceiver->Port() < B_OK ? fReceiver->Port() : B_OK; } diff --git a/src/kits/app/PortLink.cpp b/src/kits/app/PortLink.cpp index 059f3cfc65..881a475f7e 100644 --- a/src/kits/app/PortLink.cpp +++ b/src/kits/app/PortLink.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku Inc. + * Copyright 2005-2009, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -12,6 +12,7 @@ namespace BPrivate { + PortLink::PortLink(port_id send, port_id receive) { fSender = new LinkSender(send); @@ -26,11 +27,4 @@ PortLink::~PortLink() } -void -PortLink::SetTo(port_id sender, port_id receiver) -{ - fSender->SetPort(sender); - fReceiver->SetPort(receiver); -} - } // namespace BPrivate diff --git a/src/kits/app/ServerLink.cpp b/src/kits/app/ServerLink.cpp index c7a687ae9b..f2f2fd9466 100644 --- a/src/kits/app/ServerLink.cpp +++ b/src/kits/app/ServerLink.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -7,11 +7,16 @@ * Axel Dörfler, axeld@pinc-software.de */ -/** Class for low-overhead port-based messaging */ + +/*! Class for low-overhead port-based messaging */ + + +#include #include #include #include + #include #include #include @@ -21,9 +26,9 @@ #include #include -#include #include + //#define TRACE_SERVER_LINK_GRADIENTS #ifdef TRACE_SERVER_LINK_GRADIENTS # include @@ -35,6 +40,7 @@ namespace BPrivate { + ServerLink::ServerLink() { } @@ -45,8 +51,16 @@ ServerLink::~ServerLink() } +void +ServerLink::SetTo(port_id sender, port_id receiver) +{ + fSender->SetPort(sender); + fReceiver->SetPort(receiver); +} + + status_t -ServerLink::ReadRegion(BRegion *region) +ServerLink::ReadRegion(BRegion* region) { fReceiver->Read(®ion->fCount, sizeof(long)); if (region->fCount > 0) { @@ -55,28 +69,28 @@ ServerLink::ReadRegion(BRegion *region) return B_NO_MEMORY; return fReceiver->Read(region->fData, region->fCount * sizeof(clipping_rect)); - } else { - return fReceiver->Read(®ion->fBounds, sizeof(clipping_rect)); } + + return fReceiver->Read(®ion->fBounds, sizeof(clipping_rect)); } status_t -ServerLink::AttachRegion(const BRegion ®ion) +ServerLink::AttachRegion(const BRegion& region) { fSender->Attach(®ion.fCount, sizeof(long)); if (region.fCount > 0) { fSender->Attach(®ion.fBounds, sizeof(clipping_rect)); return fSender->Attach(region.fData, region.fCount * sizeof(clipping_rect)); - } else { - return fSender->Attach(®ion.fBounds, sizeof(clipping_rect)); } + + return fSender->Attach(®ion.fBounds, sizeof(clipping_rect)); } status_t -ServerLink::ReadShape(BShape *shape) +ServerLink::ReadShape(BShape* shape) { int32 opCount, ptCount; fReceiver->Read(&opCount, sizeof(int32)); @@ -96,11 +110,11 @@ ServerLink::ReadShape(BShape *shape) status_t -ServerLink::AttachShape(BShape &shape) +ServerLink::AttachShape(BShape& shape) { int32 opCount, ptCount; - uint32 *opList; - BPoint *ptList; + uint32* opList; + BPoint* ptList; shape.GetData(&opCount, &ptCount, &opList, &ptList); @@ -115,15 +129,15 @@ ServerLink::AttachShape(BShape &shape) status_t -ServerLink::ReadGradient(BGradient **gradient) +ServerLink::ReadGradient(BGradient** _gradient) { GTRACE(("ServerLink::ReadGradient\n")); - return fReceiver->ReadGradient(gradient); + return fReceiver->ReadGradient(_gradient); } status_t -ServerLink::AttachGradient(const BGradient &gradient) +ServerLink::AttachGradient(const BGradient& gradient) { GTRACE(("ServerLink::AttachGradient\n")); BGradient::Type gradientType = gradient.GetType(); @@ -196,7 +210,7 @@ ServerLink::AttachGradient(const BGradient &gradient) status_t -ServerLink::FlushWithReply(int32 &code) +ServerLink::FlushWithReply(int32& code) { status_t status = Flush(B_INFINITE_TIMEOUT, true); if (status < B_OK) @@ -205,4 +219,5 @@ ServerLink::FlushWithReply(int32 &code) return GetNextMessage(code); } + } // namespace BPrivate