Some more cleanup:

- replaced fMsgSender/Receiver with a BPortLink fLink
- moved message loop into non-static method _MessageLooper()
- renamed Zoom()/Minimize()/Quit()/ScreenModeChanged() to Notify*(), and
  Quit() to NotfiyQuitRequested() to make more clear what they do (they
  don't operate on ServerWindow, they just notify its client)
- less insane way to init a window: there is no longer the constructor
  and a separate method Init(); now there is the constructor (which
  fully sets up the window), InitCheck(), and Run() which runs the
  window's message loop
- moved the quitting stuff into a separate method Quit() and made
  it callable from other threads.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13247 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-06-23 22:43:11 +00:00
parent 4801a9a97d
commit ce1639b2bf
4 changed files with 289 additions and 221 deletions
+27 -25
View File
@@ -192,15 +192,10 @@ ServerApp::Run()
// Unlike a BApplication, a ServerApp is *supposed* to return immediately // Unlike a BApplication, a ServerApp is *supposed* to return immediately
// when its Run() function is called. // when its Run() function is called.
fThread = spawn_thread(_message_thread, fSignature.String(), B_NORMAL_PRIORITY, this); fThread = spawn_thread(_message_thread, Signature(), B_NORMAL_PRIORITY, this);
if (fThread < B_OK) if (fThread < B_OK)
return false; return false;
// Let's tell the client how to talk with us
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(fMessagePort);
fLink.Flush();
if (resume_thread(fThread) != B_OK) { if (resume_thread(fThread) != B_OK) {
fQuitting = true; fQuitting = true;
kill_thread(fThread); kill_thread(fThread);
@@ -208,6 +203,11 @@ ServerApp::Run()
return false; return false;
} }
// Let's tell the client how to talk with us
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(fMessagePort);
fLink.Flush();
return true; return true;
} }
@@ -230,10 +230,7 @@ ServerApp::Quit()
// execute application deletion in the message looper thread // execute application deletion in the message looper thread
fQuitting = true; fQuitting = true;
PostMessage(kMsgAppQuit);
BPrivate::LinkSender link(fMessagePort);
link.StartMessage(kMsgAppQuit);
link.Flush();
send_data(fThread, 'QUIT', NULL, 0); send_data(fThread, 'QUIT', NULL, 0);
} }
@@ -390,7 +387,7 @@ ServerApp::_MessageLooper()
uint32 flags; uint32 flags;
uint32 workspaces; uint32 workspaces;
int32 token = B_NULL_TOKEN; int32 token = B_NULL_TOKEN;
port_id sendPort = -1; port_id clientReplyPort = -1;
port_id looperPort = -1; port_id looperPort = -1;
char *title = NULL; char *title = NULL;
@@ -400,27 +397,32 @@ ServerApp::_MessageLooper()
receiver.Read<uint32>(&flags); receiver.Read<uint32>(&flags);
receiver.Read<uint32>(&workspaces); receiver.Read<uint32>(&workspaces);
receiver.Read<int32>(&token); receiver.Read<int32>(&token);
receiver.Read<port_id>(&sendPort); receiver.Read<port_id>(&clientReplyPort);
receiver.Read<port_id>(&looperPort); receiver.Read<port_id>(&looperPort);
if (receiver.ReadString(&title) != B_OK) if (receiver.ReadString(&title) != B_OK)
break; break;
STRACE(("ServerApp %s: Got 'New Window' message, trying to do smething...\n",
Signature()));
// ServerWindow constructor will reply with port_id of a newly created port // ServerWindow constructor will reply with port_id of a newly created port
ServerWindow *window = new ServerWindow(title, this, sendPort, looperPort, ServerWindow *window = new ServerWindow(title, this, clientReplyPort,
token); looperPort, token, frame, look, feel, flags, workspaces);
window->Init(frame, look, feel, flags, workspaces);
if (fWindowListLock.Lock()) {
fWindowList.AddItem(window);
fWindowListLock.Unlock();
}
STRACE(("\nServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n", STRACE(("\nServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n",
app->fSignature.String(), title, frame.left, frame.top, fSignature(), title, frame.left, frame.top, frame.right, frame.bottom));
frame.right, frame.bottom));
if (window->InitCheck() == B_OK && window->Run()) {
// add the window to the list
if (fWindowListLock.Lock()) {
fWindowList.AddItem(window);
fWindowListLock.Unlock();
}
} else {
delete window;
// window creation failed, we need to notify the client
BPrivate::LinkSender reply(clientReplyPort);
reply.StartMessage(SERVER_FALSE);
reply.Flush();
}
// We don't have to free the title, as it's owned by the ServerWindow now // We don't have to free the title, as it's owned by the ServerWindow now
break; break;
+228 -166
View File
@@ -60,6 +60,9 @@
#endif #endif
static const uint32 kMsgWindowQuit = 'winQ';
/*! /*!
\brief Constructor \brief Constructor
@@ -67,72 +70,127 @@
monitor thread. monitor thread.
*/ */
ServerWindow::ServerWindow(const char *title, ServerApp *app, ServerWindow::ServerWindow(const char *title, ServerApp *app,
port_id clientPort, port_id looperPort, int32 handlerID) port_id clientPort, port_id looperPort, int32 handlerID,
: BLocker(*title ? title : "Unnamed Window"), BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
: BLocker(title && *title ? title : "Unnamed Window"),
fTitle(title), fTitle(title),
fServerApp(app), fServerApp(app),
fWinBorder(NULL),
fClientTeam(app->ClientTeam()),
fMessagePort(-1),
fClientReplyPort(clientPort), fClientReplyPort(clientPort),
fClientLooperPort(looperPort), fClientLooperPort(looperPort),
fClientViewsWithInvalidCoords(B_VIEW_RESIZED), fClientViewsWithInvalidCoords(B_VIEW_RESIZED),
fHandlerToken(handlerID) fHandlerToken(handlerID),
fCurrentLayer(NULL)
{ {
STRACE(("ServerWindow(%s)::ServerWindow()\n", title)); STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
if (fTitle == NULL) if (fTitle == NULL)
fTitle = strdup("Unnamed Window"); fTitle = strdup("Unnamed Window");
if (fTitle == NULL)
fClientTeam = app->ClientTeam(); return;
fWinBorder = NULL;
fCurrentLayer = NULL;
// fMessagePort is the port to which the app sends messages for the server // fMessagePort is the port to which the app sends messages for the server
fMessagePort = create_port(30, fTitle); fMessagePort = create_port(100, fTitle);
if (fMessagePort < B_OK)
return;
fMsgSender = new BPrivate::LinkSender(fClientReplyPort); fLink.SetSenderPort(fClientReplyPort);
fMsgReceiver = new BPrivate::LinkReceiver(fMessagePort); fLink.SetReceiverPort(fMessagePort);
// Send a reply to our window - it is expecting fMessagePort port. char name[60];
fMsgSender->StartMessage(SERVER_TRUE); snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
fMsgSender->Attach<port_id>(fMessagePort);
fMsgSender->Flush(); fWinBorder = new WinBorder(frame, name, look, feel, flags,
workspace, this, gDesktop->GetDisplayDriver());
STRACE(("ServerWindow %s Created\n", fTitle)); STRACE(("ServerWindow %s Created\n", fTitle));
} }
void
ServerWindow::Init(BRect frame, uint32 wlook,
uint32 wfeel, uint32 wflags, uint32 wwksindex)
{
char name[60];
snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
fWinBorder = new WinBorder(frame, name, wlook, wfeel, wflags,
wwksindex, this, gDesktop->GetDisplayDriver());
// Spawn our message-monitoring thread
fThread = spawn_thread(MonitorWin, fTitle, B_NORMAL_PRIORITY, this);
if (fThread >= B_OK)
resume_thread(fThread);
}
//!Tears down all connections the main app_server objects, and deletes some internals. //!Tears down all connections the main app_server objects, and deletes some internals.
ServerWindow::~ServerWindow(void) ServerWindow::~ServerWindow()
{ {
STRACE(("*ServerWindow (%s):~ServerWindow()\n", fTitle)); STRACE(("*ServerWindow (%s):~ServerWindow()\n", fTitle));
delete fWinBorder; delete fWinBorder;
delete fMsgSender;
delete fMsgReceiver;
free(const_cast<char *>(fTitle)); free(const_cast<char *>(fTitle));
STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle)); STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle));
} }
status_t
ServerWindow::InitCheck()
{
if (fTitle == NULL || fWinBorder == NULL)
return B_NO_MEMORY;
if (fMessagePort < B_OK)
return fMessagePort;
return B_OK;
}
bool
ServerWindow::Run()
{
// Spawn our message-monitoring thread
fThread = spawn_thread(_message_thread, fTitle, B_NORMAL_PRIORITY, this);
if (fThread < B_OK)
return false;
if (resume_thread(fThread) != B_OK) {
kill_thread(fThread);
fThread = -1;
return false;
}
// Send a reply to our window - it is expecting fMessagePort port.
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<port_id>(fMessagePort);
fLink.Flush();
return true;
}
void
ServerWindow::Quit()
{
if (fThread < B_OK) {
delete this;
return;
}
if (fThread == find_thread(NULL)) {
App()->RemoveWindow(this);
delete this;
exit_thread(0);
} else
PostMessage(kMsgWindowQuit);
}
/*!
\brief Send a message to the ServerWindow with no attachments
\param code ID code of the message to post
*/
void
ServerWindow::PostMessage(int32 code)
{
BPrivate::LinkSender link(fMessagePort);
link.StartMessage(code);
link.Flush();
}
//! Forces the window border to update its decorator //! Forces the window border to update its decorator
void void
ServerWindow::ReplaceDecorator(void) ServerWindow::ReplaceDecorator()
{ {
if (!IsLocked()) if (!IsLocked())
debugger("you must lock a ServerWindow object before calling ::ReplaceDecorator()\n"); debugger("you must lock a ServerWindow object before calling ::ReplaceDecorator()\n");
@@ -141,20 +199,9 @@ ServerWindow::ReplaceDecorator(void)
fWinBorder->UpdateDecorator(); fWinBorder->UpdateDecorator();
} }
//! Requests that the ServerWindow's BWindow quit
void
ServerWindow::Quit(void)
{
// NOTE: if you do something else, other than sending a port message, PLEASE lock
STRACE(("ServerWindow %s: Quit\n", fTitle));
BMessage msg(B_QUIT_REQUESTED);
SendMessageToClient(&msg);
}
//! Shows the window's WinBorder //! Shows the window's WinBorder
void void
ServerWindow::Show(void) ServerWindow::Show()
{ {
// NOTE: if you do something else, other than sending a port message, PLEASE lock // NOTE: if you do something else, other than sending a port message, PLEASE lock
STRACE(("ServerWindow %s: Show\n", Title())); STRACE(("ServerWindow %s: Show\n", Title()));
@@ -167,7 +214,7 @@ ServerWindow::Show(void)
//! Hides the window's WinBorder //! Hides the window's WinBorder
void void
ServerWindow::Hide(void) ServerWindow::Hide()
{ {
// NOTE: if you do something else, other than sending a port message, PLEASE lock // NOTE: if you do something else, other than sending a port message, PLEASE lock
STRACE(("ServerWindow %s: Hide\n", Title())); STRACE(("ServerWindow %s: Hide\n", Title()));
@@ -179,8 +226,20 @@ ServerWindow::Hide(void)
} }
//! Requests that the ServerWindow's BWindow quit
void void
ServerWindow::Minimize(bool status) ServerWindow::NotifyQuitRequested()
{
// NOTE: if you do something else, other than sending a port message, PLEASE lock
STRACE(("ServerWindow %s: Quit\n", fTitle));
BMessage msg(B_QUIT_REQUESTED);
SendMessageToClient(&msg);
}
void
ServerWindow::NotifyMinimize(bool minimize)
{ {
// NOTE: if you do something else, other than sending a port message, PLEASE lock // NOTE: if you do something else, other than sending a port message, PLEASE lock
// This function doesn't need much -- check to make sure that we should and // This function doesn't need much -- check to make sure that we should and
@@ -188,7 +247,7 @@ ServerWindow::Minimize(bool status)
// does all the heavy lifting for us. :) // does all the heavy lifting for us. :)
bool sendMessages = false; bool sendMessages = false;
if (status) { if (minimize) {
if (!fWinBorder->IsHidden()) { if (!fWinBorder->IsHidden()) {
Hide(); Hide();
sendMessages = true; sendMessages = true;
@@ -201,10 +260,9 @@ ServerWindow::Minimize(bool status)
} }
if (sendMessages) { if (sendMessages) {
BMessage msg; BMessage msg(B_MINIMIZE);
msg.what = B_MINIMIZE;
msg.AddInt64("when", real_time_clock_usecs()); msg.AddInt64("when", real_time_clock_usecs());
msg.AddBool("minimize", status); msg.AddBool("minimize", minimize);
SendMessageToClient(&msg); SendMessageToClient(&msg);
} }
@@ -212,7 +270,7 @@ ServerWindow::Minimize(bool status)
//! Sends a message to the client to perform a Zoom //! Sends a message to the client to perform a Zoom
void void
ServerWindow::Zoom() ServerWindow::NotifyZoom()
{ {
// NOTE: if you do something else, other than sending a port message, PLEASE lock // NOTE: if you do something else, other than sending a port message, PLEASE lock
BMessage msg(B_ZOOM); BMessage msg(B_ZOOM);
@@ -225,7 +283,7 @@ ServerWindow::Zoom()
\param color_space Color space of the new screen mode \param color_space Color space of the new screen mode
*/ */
void void
ServerWindow::ScreenModeChanged(const BRect frame, const color_space colorSpace) ServerWindow::NotifyScreenModeChanged(const BRect frame, const color_space colorSpace)
{ {
STRACE(("ServerWindow %s: ScreenModeChanged\n", fTitle)); STRACE(("ServerWindow %s: ScreenModeChanged\n", fTitle));
@@ -318,7 +376,7 @@ ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
void void
ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
if (fCurrentLayer == NULL && code != AS_LAYER_CREATE_ROOT && code != AS_LAYER_CREATE) { if (fCurrentLayer == NULL && code != AS_LAYER_CREATE_ROOT && code != AS_LAYER_CREATE) {
printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n", Title(), code - SERVER_TRUE); printf("ServerWindow %s received unexpected code - message offset %ld before top_view attached.\n", Title(), code - SERVER_TRUE);
@@ -430,7 +488,6 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
if (parent != NULL) if (parent != NULL)
parent->AddChild(newLayer, this); parent->AddChild(newLayer, this);
//printf("Adi: create %s\n", fTitle);
if (!newLayer->IsHidden()) if (!newLayer->IsHidden())
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
myRootLayer->GoInvalidate(newLayer, newLayer->fFull); myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
@@ -494,16 +551,16 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: Layer name: %s\n", fTitle, fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: Layer name: %s\n", fTitle, fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
// attach state data // attach state data
fCurrentLayer->fLayerData->WriteToLink(*fMsgSender); fCurrentLayer->fLayerData->WriteToLink(fLink.Sender());
fMsgSender->Attach<float>(fCurrentLayer->fFrame.left); fLink.Attach<float>(fCurrentLayer->fFrame.left);
fMsgSender->Attach<float>(fCurrentLayer->fFrame.top); fLink.Attach<float>(fCurrentLayer->fFrame.top);
fMsgSender->Attach<BRect>(fCurrentLayer->fFrame.OffsetToCopy(fCurrentLayer->BoundsOrigin())); fLink.Attach<BRect>(fCurrentLayer->fFrame.OffsetToCopy(fCurrentLayer->BoundsOrigin()));
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
case AS_LAYER_SET_MOUSE_EVENT_MASK: case AS_LAYER_SET_MOUSE_EVENT_MASK:
@@ -552,13 +609,13 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_COORD: case AS_LAYER_GET_COORD:
{ {
STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: Layer: %s\n", Title(), fCurrentLayer->Name())); STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
// our offset in the parent -> will be originX and originY in BView // our offset in the parent -> will be originX and originY in BView
fMsgSender->Attach<float>(fCurrentLayer->fFrame.left); fLink.Attach<float>(fCurrentLayer->fFrame.left);
fMsgSender->Attach<float>(fCurrentLayer->fFrame.top); fLink.Attach<float>(fCurrentLayer->fFrame.top);
// convert frame to bounds // convert frame to bounds
fMsgSender->Attach<BRect>(fCurrentLayer->fFrame.OffsetToCopy(fCurrentLayer->BoundsOrigin())); fLink.Attach<BRect>(fCurrentLayer->fFrame.OffsetToCopy(fCurrentLayer->BoundsOrigin()));
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
case AS_LAYER_SET_ORIGIN: case AS_LAYER_SET_ORIGIN:
@@ -575,9 +632,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_ORIGIN: case AS_LAYER_GET_ORIGIN:
{ {
STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: Layer: %s\n", Title(), fCurrentLayer->Name())); STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<BPoint>(fCurrentLayer->fLayerData->Origin()); fLink.Attach<BPoint>(fCurrentLayer->fLayerData->Origin());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
case AS_LAYER_RESIZE_MODE: case AS_LAYER_RESIZE_MODE:
@@ -638,11 +695,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_LINE_MODE: case AS_LAYER_GET_LINE_MODE:
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<int8>((int8)(fCurrentLayer->fLayerData->LineCapMode())); fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->LineCapMode()));
fMsgSender->Attach<int8>((int8)(fCurrentLayer->fLayerData->LineJoinMode())); fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->LineJoinMode()));
fMsgSender->Attach<float>(fCurrentLayer->fLayerData->MiterLimit()); fLink.Attach<float>(fCurrentLayer->fLayerData->MiterLimit());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -690,9 +747,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
while ((ld = ld->prevState)) while ((ld = ld->prevState))
scale *= ld->Scale(); scale *= ld->Scale();
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<float>(scale); fLink.Attach<float>(scale);
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -711,9 +768,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_PEN_LOC: case AS_LAYER_GET_PEN_LOC:
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<BPoint>(fCurrentLayer->fLayerData->PenLocation()); fLink.Attach<BPoint>(fCurrentLayer->fLayerData->PenLocation());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -729,9 +786,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_PEN_SIZE: case AS_LAYER_GET_PEN_SIZE:
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<float>(fCurrentLayer->fLayerData->PenSize()); fLink.Attach<float>(fCurrentLayer->fLayerData->PenSize());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -759,11 +816,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
lowColor = fCurrentLayer->fLayerData->LowColor().GetColor32(); lowColor = fCurrentLayer->fLayerData->LowColor().GetColor32();
viewColor = fCurrentLayer->ViewColor().GetColor32(); viewColor = fCurrentLayer->ViewColor().GetColor32();
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach(&highColor, sizeof(rgb_color)); fLink.Attach(&highColor, sizeof(rgb_color));
fMsgSender->Attach(&lowColor, sizeof(rgb_color)); fLink.Attach(&lowColor, sizeof(rgb_color));
fMsgSender->Attach(&viewColor, sizeof(rgb_color)); fLink.Attach(&viewColor, sizeof(rgb_color));
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -783,10 +840,10 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_BLEND_MODE: case AS_LAYER_GET_BLEND_MODE:
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaSrcMode())); fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaSrcMode()));
fMsgSender->Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaFncMode())); fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->AlphaFncMode()));
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -804,9 +861,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_LAYER_GET_DRAW_MODE: case AS_LAYER_GET_DRAW_MODE:
{ {
DTRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: Layer: %s\n", Title(), fCurrentLayer->Name())); DTRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: Layer: %s\n", Title(), fCurrentLayer->Name()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<int8>((int8)(fCurrentLayer->fLayerData->GetDrawingMode())); fLink.Attach<int8>((int8)(fCurrentLayer->fLayerData->GetDrawingMode()));
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -868,9 +925,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// if this Layer is hidden, it is clear that its visible region is void. // if this Layer is hidden, it is clear that its visible region is void.
if (fCurrentLayer->IsHidden()) if (fCurrentLayer->IsHidden())
{ {
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<int32>(0L); fLink.Attach<int32>(0L);
fMsgSender->Flush(); fLink.Flush();
} }
else else
{ {
@@ -896,11 +953,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
} }
noOfRects = reg.CountRects(); noOfRects = reg.CountRects();
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<int32>(noOfRects); fLink.Attach<int32>(noOfRects);
for(int i = 0; i < noOfRects; i++) for(int i = 0; i < noOfRects; i++)
fMsgSender->Attach<BRect>(reg.RectAt(i)); fLink.Attach<BRect>(reg.RectAt(i));
} }
break; break;
} }
@@ -915,8 +972,7 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<int32>(&noOfRects); link.Read<int32>(&noOfRects);
BRegion region; BRegion region;
for(int i = 0; i < noOfRects; i++) for (int i = 0; i < noOfRects; i++) {
{
link.Read<BRect>(&r); link.Read<BRect>(&r);
region.Include(r); region.Include(r);
} }
@@ -1055,8 +1111,8 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID); wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID);
if (wb) { if (wb) {
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Flush(); fLink.Flush();
// ToDo: this is a pretty expensive and complicated way to send a message... // ToDo: this is a pretty expensive and complicated way to send a message...
BPrivate::PortLink msg(-1, -1); BPrivate::PortLink msg(-1, -1);
@@ -1065,8 +1121,8 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
msg.Attach<WinBorder*>(wb); msg.Attach<WinBorder*>(wb);
fWinBorder->GetRootLayer()->EnqueueMessage(msg); fWinBorder->GetRootLayer()->EnqueueMessage(msg);
} else { } else {
fMsgSender->StartMessage(SERVER_FALSE); fLink.StartMessage(SERVER_FALSE);
fMsgSender->Flush(); fLink.Flush();
} }
break; break;
} }
@@ -1082,8 +1138,8 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID); wb = gDesktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID);
if (wb) { if (wb) {
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Flush(); fLink.Flush();
BPrivate::PortLink msg(-1, -1); BPrivate::PortLink msg(-1, -1);
msg.StartMessage(AS_ROOTLAYER_REMOVE_FROM_SUBSET); msg.StartMessage(AS_ROOTLAYER_REMOVE_FROM_SUBSET);
@@ -1091,8 +1147,8 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
msg.Attach<WinBorder*>(wb); msg.Attach<WinBorder*>(wb);
fWinBorder->GetRootLayer()->EnqueueMessage(msg); fWinBorder->GetRootLayer()->EnqueueMessage(msg);
} else { } else {
fMsgSender->StartMessage(SERVER_FALSE); fLink.StartMessage(SERVER_FALSE);
fMsgSender->Flush(); fLink.Flush();
} }
break; break;
} }
@@ -1131,9 +1187,9 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
case AS_GET_WORKSPACES: case AS_GET_WORKSPACES:
{ {
STRACE(("ServerWindow %s: Message Get_Workspaces unimplemented\n", Title())); STRACE(("ServerWindow %s: Message Get_Workspaces unimplemented\n", Title()));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<uint32>(fWinBorder->Workspaces()); fLink.Attach<uint32>(fWinBorder->Workspaces());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
case AS_SET_WORKSPACES: case AS_SET_WORKSPACES:
@@ -1202,13 +1258,13 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// and now, sync the client to the limits that we were able to enforce // and now, sync the client to the limits that we were able to enforce
fWinBorder->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); fWinBorder->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Attach<float>(minWidth); fLink.Attach<float>(minWidth);
fMsgSender->Attach<float>(maxWidth); fLink.Attach<float>(maxWidth);
fMsgSender->Attach<float>(minHeight); fLink.Attach<float>(minHeight);
fMsgSender->Attach<float>(maxHeight); fLink.Attach<float>(maxHeight);
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
@@ -1325,24 +1381,23 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Part sanity check, part get base pointer :) // Part sanity check, part get base pointer :)
if(get_area_info(area,&ai)!=B_OK) if(get_area_info(area,&ai)!=B_OK)
break; break;
msgpointer=(int8*)ai.address + offset; msgpointer = (int8*)ai.address + offset;
RAMLinkMsgReader mlink(msgpointer); RAMLinkMsgReader mlink(msgpointer);
DispatchMessage(mlink.Code(),mlink); _DispatchMessage(mlink.Code(), mlink);
// This is a very special case in the sense that when ServerMemIO is used for this // This is a very special case in the sense that when ServerMemIO is used for this
// purpose, it will be set to NOT automatically free the memory which it had // purpose, it will be set to NOT automatically free the memory which it had
// requested. This is the server's job once the message has been dispatched. // requested. This is the server's job once the message has been dispatched.
fServerApp->AppAreaPool()->ReleaseBuffer(msgpointer); fServerApp->AppAreaPool()->ReleaseBuffer(msgpointer);
break; break;
} }
case AS_SYNC: case AS_SYNC:
{ {
// TODO: AS_SYNC is a no-op for now, just to get things working // TODO: AS_SYNC is a no-op for now, just to get things working
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
case AS_LAYER_DRAG_IMAGE: case AS_LAYER_DRAG_IMAGE:
@@ -1363,21 +1418,21 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
DTRACE(("ServerWindow %s: Message AS_GET_MOUSE_COORDS\n", fTitle)); DTRACE(("ServerWindow %s: Message AS_GET_MOUSE_COORDS\n", fTitle));
fMsgSender->StartMessage(SERVER_TRUE); fLink.StartMessage(SERVER_TRUE);
// Returns // Returns
// 1) BPoint mouse location // 1) BPoint mouse location
// 2) int32 button state // 2) int32 button state
fMsgSender->Attach<BPoint>(gDesktop->GetDisplayDriver()->GetCursorPosition()); fLink.Attach<BPoint>(gDesktop->GetDisplayDriver()->GetCursorPosition());
fMsgSender->Attach<int32>(gDesktop->ActiveRootLayer()->Buttons()); fLink.Attach<int32>(gDesktop->ActiveRootLayer()->Buttons());
fMsgSender->Flush(); fLink.Flush();
break; break;
} }
default: default:
DispatchGraphicsMessage(code, link); _DispatchGraphicsMessage(code, link);
break; break;
} }
} }
@@ -1386,7 +1441,7 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
inline inline
void void
ServerWindow::DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link) ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
fWinBorder->GetRootLayer()->Lock(); fWinBorder->GetRootLayer()->Lock();
BRegion rreg BRegion rreg
@@ -1907,17 +1962,28 @@ ServerWindow::DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
} }
/*! /*!
\brief Message-dispatching loop for the ServerWindow \brief Message-dispatching loop starter
MonitorWin() watches the ServerWindow's message port and dispatches as necessary
\param data The thread's ServerWindow \param data The thread's ServerWindow
\return Throwaway code. Always 0.
*/ */
int32 int32
ServerWindow::MonitorWin(void *data) ServerWindow::_message_thread(void *_window)
{ {
ServerWindow *win = (ServerWindow *)data; ServerWindow *window = (ServerWindow *)_window;
BPrivate::LinkReceiver *ses = win->fMsgReceiver;
window->_MessageLooper();
return 0;
}
/*!
\brief Message-dispatching loop for the ServerWindow
Watches the ServerWindow's message port and dispatches as necessary
*/
void
ServerWindow::_MessageLooper()
{
BPrivate::LinkReceiver& receiver = fLink.Receiver();
bool quitting = false; bool quitting = false;
int32 code; int32 code;
@@ -1925,21 +1991,26 @@ ServerWindow::MonitorWin(void *data)
while (!quitting) { while (!quitting) {
STRACE(("info: ServerWindow::MonitorWin listening on port %ld.\n", STRACE(("info: ServerWindow::MonitorWin listening on port %ld.\n",
win->fMessagePort)); fMessagePort));
err = ses->GetNextMessage(code); err = receiver.GetNextMessage(code);
if (err < B_OK) if (err < B_OK) {
return err; // that shouldn't happen, it's our port
// ToDo: do something about it, anyway!
return;
}
win->Lock(); Lock();
switch (code) { switch (code) {
case AS_DELETE_WINDOW: case AS_DELETE_WINDOW:
case kMsgWindowQuit:
{ {
// this means the client has been killed // this means the client has been killed
STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n", STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n",
win->Title())); Title()));
// ToDo: what's this?
//RootLayer *rootLayer = fWinBorder->GetRootLayer(); //RootLayer *rootLayer = fWinBorder->GetRootLayer();
// we are preparing to delete a ServerWindow, RootLayer should be aware // we are preparing to delete a ServerWindow, RootLayer should be aware
@@ -1954,32 +2025,25 @@ ServerWindow::MonitorWin(void *data)
//} //}
// ServerWindow's destructor takes care of pulling this object off the desktop. // ServerWindow's destructor takes care of pulling this object off the desktop.
if (!win->fWinBorder->IsHidden()) if (!fWinBorder->IsHidden())
CRITICAL("ServerWindow: a window must be hidden before it's deleted\n"); CRITICAL("ServerWindow: a window must be hidden before it's deleted\n");
win->App()->RemoveWindow(win); Quit();
delete win; // does not return
//rootLayer->Unlock();
exit_thread(0);
break; break;
} }
case B_QUIT_REQUESTED: case B_QUIT_REQUESTED:
{ STRACE(("ServerWindow %s received quit request\n", Title()));
STRACE(("ServerWindow %s received Quit request\n", win->Title())); NotifyQuitRequested();
win->Quit();
break; break;
}
default: default:
{ _DispatchMessage(code, receiver);
win->DispatchMessage(code, *ses);
break; break;
}
} }
win->Unlock(); Unlock();
} }
return err;
} }
// _CopyBits // _CopyBits
@@ -2041,8 +2105,6 @@ ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePre
char* buffer = new char[size]; char* buffer = new char[size];
if (msg->Flatten(buffer, size) == B_OK) { if (msg->Flatten(buffer, size) == B_OK) {
// BMessage::Private::SendFlattenedMessage(buffer, size,
// fClientLooperPort, target, usePreferred, B_INFINITE_TIMEOUT);
status_t ret = BMessage::Private::SendFlattenedMessage(buffer, size, status_t ret = BMessage::Private::SendFlattenedMessage(buffer, size,
fClientLooperPort, target, usePreferred, 100000); fClientLooperPort, target, usePreferred, 100000);
if (ret < B_OK) if (ret < B_OK)
+28 -26
View File
@@ -12,9 +12,9 @@
#ifndef _SERVERWIN_H_ #ifndef _SERVERWIN_H_
#define _SERVERWIN_H_ #define _SERVERWIN_H_
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <LinkMsgReader.h> #include <PortLink.h>
#include <LinkMsgSender.h>
#include <Locker.h> #include <Locker.h>
#include <Message.h> #include <Message.h>
#include <OS.h> #include <OS.h>
@@ -29,9 +29,9 @@ class BString;
class BMessenger; class BMessenger;
class BPoint; class BPoint;
class BMessage; class BMessage;
class ServerApp; class ServerApp;
class Decorator; class Decorator;
class BPortLink;
class WinBorder; class WinBorder;
class Workspace; class Workspace;
class RootLayer; class RootLayer;
@@ -53,26 +53,28 @@ class ServerPicture;
*/ */
class ServerWindow : public BLocker { class ServerWindow : public BLocker {
public: public:
ServerWindow( const char *string, ServerWindow(const char *title, ServerApp *app,
ServerApp *winapp, port_id clientPort, port_id looperPort,
port_id winport, int32 handlerID, BRect frame, uint32 look,
port_id looperPort, uint32 feel, uint32 flags, uint32 workspace);
int32 handlerID); virtual ~ServerWindow();
virtual ~ServerWindow(void);
void Init( BRect frame, status_t InitCheck();
uint32 wlook, uint32 wfeel, uint32 wflags, bool Run();
uint32 wwksindex); void Quit();
void ReplaceDecorator(void); void ReplaceDecorator();
void Show(void); void Show();
void Hide(void); void Hide();
void PostMessage(int32 code);
// methods for sending various messages to client. // methods for sending various messages to client.
void Quit(void); void NotifyQuitRequested();
void Minimize(bool status); void NotifyMinimize(bool minimize);
void Zoom(void); void NotifyZoom();
void ScreenModeChanged(const BRect frame, const color_space cspace); void NotifyScreenModeChanged(const BRect frame,
const color_space cspace);
// util methods. // util methods.
void SendMessageToClient(const BMessage* msg, void SendMessageToClient(const BMessage* msg,
@@ -103,12 +105,13 @@ private:
Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent); Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent);
void SetLayerState(Layer *layer, BPrivate::LinkReceiver &link); void SetLayerState(Layer *layer, BPrivate::LinkReceiver &link);
void SetLayerFontState(Layer *layer, BPrivate::LinkReceiver &link); void SetLayerFontState(Layer *layer, BPrivate::LinkReceiver &link);
void ClientDied(bool crashed);
// message handle methods. // message handling methods.
void DispatchMessage(int32 code, BPrivate::LinkReceiver &link); void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
void DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link); void _DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link);
static int32 MonitorWin(void *data); void _MessageLooper();
static int32 _message_thread(void *_window);
// used by CopyBits and Scrolling // used by CopyBits and Scrolling
void _CopyBits(RootLayer* rootLayer, void _CopyBits(RootLayer* rootLayer,
@@ -137,8 +140,7 @@ private:
port_id fClientReplyPort; port_id fClientReplyPort;
port_id fClientLooperPort; port_id fClientLooperPort;
BPrivate::LinkReceiver* fMsgReceiver; BPrivate::PortLink fLink;
BPrivate::LinkSender* fMsgSender;
BMessage fClientViewsWithInvalidCoords; BMessage fClientViewsWithInvalidCoords;
+6 -4
View File
@@ -6,6 +6,8 @@
* Adi Oanca <adioanca@cotty.iren.ro> * Adi Oanca <adioanca@cotty.iren.ro>
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
*/ */
#include <Locker.h> #include <Locker.h>
#include <Region.h> #include <Region.h>
#include <String.h> #include <String.h>
@@ -476,21 +478,21 @@ WinBorder::MouseUp(const PointerEvent& event)
fIsZooming = false; fIsZooming = false;
fDecorator->SetZoom(false); fDecorator->SetZoom(false);
if (action == DEC_ZOOM) if (action == DEC_ZOOM)
Window()->Zoom(); Window()->NotifyZoom();
return; return;
} }
if (fIsClosing) { if (fIsClosing) {
fIsClosing = false; fIsClosing = false;
fDecorator->SetClose(false); fDecorator->SetClose(false);
if (action == DEC_CLOSE) if (action == DEC_CLOSE)
Window()->Quit(); Window()->NotifyQuitRequested();
return; return;
} }
if (fIsMinimizing) { if (fIsMinimizing) {
fIsMinimizing = false; fIsMinimizing = false;
fDecorator->SetMinimize(false); fDecorator->SetMinimize(false);
if (action == DEC_MINIMIZE) if (action == DEC_MINIMIZE)
Window()->Minimize(true); Window()->NotifyMinimize(true);
return; return;
} }
} }
@@ -696,4 +698,4 @@ void WinBorder::get_user_regions(BRegion &reg)
reg.Include(&fDecRegion); reg.Include(&fDecRegion);
} }
#endif #endif