From 82584ab9c2996ff4dec740d64eb78c7c0b74c900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 9 Jun 2006 21:46:40 +0000 Subject: [PATCH] * Implemented AS_DIRECT_WINDOW_SET_FULLSCREEN so that it sets kWindowScreenFeel when enabled, and B_NORMAL_WINDOW_FEEL when disabled. IOW when enabled, no other windows can interfere. * Therefore, it's no longer necessary to have the screen_blanker window use kWindowScreenFeel - it will set its window to full screen as long as the blanker runs. * Added a AS_APP_CRASHED notification in the app_server that will remove all kWindowScreenFeels from the windows of the crashed app. * This is now used by the debugger to ensure that the debugger alert will be visible. * Factored out a DesktopLink class out of the BRoster::_ActivateApp() method. This class is now also used in the new BRoster::_ApplicationCrashed() method as used in the debug_server (via BRoster::Private). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17785 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/app/DesktopLink.h | 30 +++++++++ headers/private/app/RosterPrivate.h | 4 ++ headers/private/app/ServerProtocol.h | 3 +- src/bin/screen_blanker/ScreenSaverWindow.cpp | 18 ++--- src/kits/app/DesktopLink.cpp | 59 ++++++++++++++++ src/kits/app/Jamfile | 1 + src/kits/app/Roster.cpp | 71 ++++++++------------ src/servers/app/Desktop.cpp | 17 +++++ src/servers/app/ServerApp.cpp | 17 +++++ src/servers/app/ServerWindow.cpp | 13 +++- src/servers/debug/DebugServer.cpp | 18 ++++- 11 files changed, 193 insertions(+), 58 deletions(-) create mode 100644 headers/private/app/DesktopLink.h create mode 100644 src/kits/app/DesktopLink.cpp diff --git a/headers/private/app/DesktopLink.h b/headers/private/app/DesktopLink.h new file mode 100644 index 0000000000..2d896373c3 --- /dev/null +++ b/headers/private/app/DesktopLink.h @@ -0,0 +1,30 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef _DESKTOP_LINK_H +#define _DESKTOP_LINK_H + + +#include + + +namespace BPrivate { + +class DesktopLink : public PortLink { + public: + DesktopLink(); + virtual ~DesktopLink(); + + status_t InitCheck() const; + + private: + port_id fReplyPort; +}; + +} // namespace BPrivate + +#endif /* _DESKTOP_LINK_H */ diff --git a/headers/private/app/RosterPrivate.h b/headers/private/app/RosterPrivate.h index 5c59a24b63..18b196bcb9 100644 --- a/headers/private/app/RosterPrivate.h +++ b/headers/private/app/RosterPrivate.h @@ -70,6 +70,10 @@ class BRoster::Private { void SaveRecentLists(const char *file) const { fRoster->_SaveRecentLists(file); } + // needed by the debug server + void ApplicationCrashed(team_id team) const + { fRoster->_ApplicationCrashed(team); } + static void InitBeRoster(); static void DeleteBeRoster(); diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index b716fa24bb..2b2d6e99d8 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -44,8 +44,7 @@ enum { AS_DELETE_APP, AS_QUIT_APP, AS_ACTIVATE_APP, - - AS_SET_SERVER_PORT, + AS_APP_CRASHED, AS_CREATE_WINDOW, AS_CREATE_OFFSCREEN_WINDOW, diff --git a/src/bin/screen_blanker/ScreenSaverWindow.cpp b/src/bin/screen_blanker/ScreenSaverWindow.cpp index b44e7cd765..df630cc0f8 100644 --- a/src/bin/screen_blanker/ScreenSaverWindow.cpp +++ b/src/bin/screen_blanker/ScreenSaverWindow.cpp @@ -20,10 +20,10 @@ This is the BDirectWindow subclass that rendering occurs in. A view is added to it so that BView based screensavers will work. */ -ScreenSaverWindow::ScreenSaverWindow(BRect frame) - : BDirectWindow(frame, "ScreenSaver Window", - B_NO_BORDER_WINDOW_LOOK, kWindowScreenFeel, B_NOT_RESIZABLE | B_NOT_ZOOMABLE), - fSaver(NULL) +ScreenSaverWindow::ScreenSaverWindow(BRect frame) + : BDirectWindow(frame, "ScreenSaver Window", + B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE), + fSaver(NULL) { frame.OffsetTo(0, 0); fTopView = new BView(frame, "ScreenSaver View", B_FOLLOW_ALL, B_WILL_DRAW); @@ -32,7 +32,7 @@ ScreenSaverWindow::ScreenSaverWindow(BRect frame) } -ScreenSaverWindow::~ScreenSaverWindow() +ScreenSaverWindow::~ScreenSaverWindow() { Hide(); } @@ -45,16 +45,16 @@ ScreenSaverWindow::SetSaver(BScreenSaver *saver) } -bool -ScreenSaverWindow::QuitRequested() +bool +ScreenSaverWindow::QuitRequested() { be_app->PostMessage(B_QUIT_REQUESTED); return true; } -void -ScreenSaverWindow::DirectConnected(direct_buffer_info *info) +void +ScreenSaverWindow::DirectConnected(direct_buffer_info *info) { if (fSaver) fSaver->DirectConnected(info); diff --git a/src/kits/app/DesktopLink.cpp b/src/kits/app/DesktopLink.cpp new file mode 100644 index 0000000000..f828cafefe --- /dev/null +++ b/src/kits/app/DesktopLink.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2006, Haiku Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ + + +#include +#include + + +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()); + + int32 code; + if (FlushWithReply(code) != B_OK || code != B_OK) + return; + + // we now talk to the desktop + Read(&port); + SetSenderPort(port); +} + + +DesktopLink::~DesktopLink() +{ + delete_port(fReplyPort); +} + + +status_t +DesktopLink::InitCheck() const +{ + return fReplyPort < B_OK ? fReplyPort : B_OK; +} + +} // namespace BPrivate diff --git a/src/kits/app/Jamfile b/src/kits/app/Jamfile index 940e5cc2f2..91043b2ac7 100644 --- a/src/kits/app/Jamfile +++ b/src/kits/app/Jamfile @@ -31,6 +31,7 @@ MergeObject app_kit.o : Cursor.cpp Clipboard.cpp dano_message.cpp + DesktopLink.cpp Handler.cpp InitTerminateLibBe.cpp Invoker.cpp diff --git a/src/kits/app/Roster.cpp b/src/kits/app/Roster.cpp index 0d02760197..1f75cd382f 100644 --- a/src/kits/app/Roster.cpp +++ b/src/kits/app/Roster.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -22,21 +21,24 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include -#include -#include #include #include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -770,52 +772,18 @@ BRoster::StopWatching(BMessenger target) const status_t BRoster::ActivateApp(team_id team) const { - // get the app server port - port_id port = find_port(SERVER_PORT_NAME); - if (port < B_OK) - return port; + BPrivate::DesktopLink link; - // create a reply port - struct ReplyPort { - ReplyPort() - : port(create_port(1, "activate app reply")) - { - } - - ~ReplyPort() - { - if (port >= 0) - delete_port(port); - } - - port_id port; - - } replyPort; - - if (replyPort.port < 0) - return replyPort.port; - - BPrivate::PortLink link(port, replyPort.port); - - // We can't use AppServerLink because be_app may be NULL - link.StartMessage(AS_GET_DESKTOP); - link.Attach(replyPort.port); - link.Attach(getuid()); - - int32 code; - if (link.FlushWithReply(code) != B_OK || code != B_OK) - return B_ERROR; - - // we now talk to the desktop - link.Read(&port); - link.SetSenderPort(port); + status_t status = link.InitCheck(); + if (status < B_OK) + return status; // prepare the message status_t error = link.StartMessage(AS_ACTIVATE_APP); if (error != B_OK) return error; - error = link.Attach(replyPort.port); + error = link.Attach(link.ReceiverPort()); if (error != B_OK) return error; @@ -824,6 +792,7 @@ BRoster::ActivateApp(team_id team) const return error; // send it + status_t code; error = link.FlushWithReply(code); if (error != B_OK) return error; @@ -1724,6 +1693,20 @@ BRoster::_RemoveApp(team_id team) const return error; } + +void +BRoster::_ApplicationCrashed(team_id team) +{ + BPrivate::DesktopLink link; + if (link.InitCheck() != B_OK) + return; + + if (link.StartMessage(AS_APP_CRASHED) == B_OK + && link.Attach(team) == B_OK) + link.Flush(); +} + + // _LaunchApp /*! \brief Launches the application associated with the supplied MIME type or the entry referred to by the supplied entry_ref. diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 720e2c042e..fda000f29a 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -542,6 +542,23 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) break; } + case AS_APP_CRASHED: + { + BAutolock locker(fApplicationsLock); + + team_id team; + if (link.Read(&team) != B_OK) + break; + + for (int32 i = 0; i < fApplications.CountItems(); i++) { + ServerApp* app = fApplications.ItemAt(i); + + if (app->ClientTeam() == team) + app->PostMessage(AS_APP_CRASHED); + } + break; + } + case B_QUIT_REQUESTED: // We've been asked to quit, so (for now) broadcast to all // test apps to quit. This situation will occur only when the server diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index aa03fc0445..7e4162bab4 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -432,6 +433,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } + case AS_APP_CRASHED: + // Allow the debugger to show its window: if needed, remove any + // kWindowScreenFeels from the windows of this application + if (fWindowListLock.Lock()) { + for (int32 i = fWindowList.CountItems(); i-- > 0;) { + ServerWindow* serverWindow = fWindowList.ItemAt(i); + WindowLayer* window = serverWindow->Window(); + + if (window->Feel() == kWindowScreenFeel) + fDesktop->SetWindowFeel(window, B_NORMAL_WINDOW_FEEL); + } + + fWindowListLock.Unlock(); + } + break; + case AS_CREATE_WINDOW: case AS_CREATE_OFFSCREEN_WINDOW: { diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index e41e62869f..5337abc3e4 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1011,12 +1011,21 @@ fDesktop->LockSingleWindow(); } case AS_DIRECT_WINDOW_SET_FULLSCREEN: { + // TODO: maybe there is more to do than this? bool enable; link.Read(&enable); - fLink.StartMessage(B_ERROR); - fLink.Flush(); + status_t status = B_OK; + if (!fWindowLayer->IsOffscreenWindow()) { + fDesktop->UnlockSingleWindow(); + fDesktop->SetWindowFeel(fWindowLayer, + enable ? kWindowScreenFeel : B_NORMAL_WINDOW_FEEL); + fDesktop->LockSingleWindow(); + } else + status = B_BAD_TYPE; + fLink.StartMessage(status); + fLink.Flush(); break; } diff --git a/src/servers/debug/DebugServer.cpp b/src/servers/debug/DebugServer.cpp index 06161bc0df..711517eebe 100644 --- a/src/servers/debug/DebugServer.cpp +++ b/src/servers/debug/DebugServer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. + * Copyright 2005-2006, Ingo Weinhold, bonefish@users.sf.net. * Distributed under the terms of the MIT License. */ @@ -18,6 +18,8 @@ #include #include #include + +#include #include #include @@ -112,6 +114,7 @@ private: void _LookupSymbolAddress(debug_symbol_lookup_context *lookupContext, const void *address, char *buffer, int32 bufferSize); void _PrintStackTrace(thread_id thread); + void _NotifyAppServer(team_id team); status_t _InitGUI(); @@ -567,6 +570,9 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message) } else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) { // normal app + + _NotifyAppServer(fTeam); + char buffer[1024]; snprintf(buffer, sizeof(buffer), "The application:\n\n %s\n\n" "has encountered an error which prevents it from continuing. Haiku " @@ -694,6 +700,16 @@ TeamDebugHandler::_PrintStackTrace(thread_id thread) } } + +void +TeamDebugHandler::_NotifyAppServer(team_id team) +{ + // This will remove any kWindowScreenFeels of the application, so that + // the debugger alert is visible on screen + BRoster::Private roster; + roster.ApplicationCrashed(team); +} + // _InitGUI status_t TeamDebugHandler::_InitGUI()