* 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
This commit is contained in:
Axel Dörfler
2006-06-09 21:46:40 +00:00
parent e4f35acf7c
commit 82584ab9c2
11 changed files with 193 additions and 58 deletions
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
*/
#ifndef _DESKTOP_LINK_H
#define _DESKTOP_LINK_H
#include <PortLink.h>
namespace BPrivate {
class DesktopLink : public PortLink {
public:
DesktopLink();
virtual ~DesktopLink();
status_t InitCheck() const;
private:
port_id fReplyPort;
};
} // namespace BPrivate
#endif /* _DESKTOP_LINK_H */
+4
View File
@@ -70,6 +70,10 @@ class BRoster::Private {
void SaveRecentLists(const char *file) const void SaveRecentLists(const char *file) const
{ fRoster->_SaveRecentLists(file); } { fRoster->_SaveRecentLists(file); }
// needed by the debug server
void ApplicationCrashed(team_id team) const
{ fRoster->_ApplicationCrashed(team); }
static void InitBeRoster(); static void InitBeRoster();
static void DeleteBeRoster(); static void DeleteBeRoster();
+1 -2
View File
@@ -44,8 +44,7 @@ enum {
AS_DELETE_APP, AS_DELETE_APP,
AS_QUIT_APP, AS_QUIT_APP,
AS_ACTIVATE_APP, AS_ACTIVATE_APP,
AS_APP_CRASHED,
AS_SET_SERVER_PORT,
AS_CREATE_WINDOW, AS_CREATE_WINDOW,
AS_CREATE_OFFSCREEN_WINDOW, AS_CREATE_OFFSCREEN_WINDOW,
+1 -1
View File
@@ -22,7 +22,7 @@
*/ */
ScreenSaverWindow::ScreenSaverWindow(BRect frame) ScreenSaverWindow::ScreenSaverWindow(BRect frame)
: BDirectWindow(frame, "ScreenSaver Window", : BDirectWindow(frame, "ScreenSaver Window",
B_NO_BORDER_WINDOW_LOOK, kWindowScreenFeel, B_NOT_RESIZABLE | B_NOT_ZOOMABLE), B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE),
fSaver(NULL) fSaver(NULL)
{ {
frame.OffsetTo(0, 0); frame.OffsetTo(0, 0);
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright 2006, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Axel Dörfler, [email protected]
*/
#include <DesktopLink.h>
#include <ServerProtocol.h>
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<port_id>(fReplyPort);
Attach<int32>(getuid());
int32 code;
if (FlushWithReply(code) != B_OK || code != B_OK)
return;
// we now talk to the desktop
Read<port_id>(&port);
SetSenderPort(port);
}
DesktopLink::~DesktopLink()
{
delete_port(fReplyPort);
}
status_t
DesktopLink::InitCheck() const
{
return fReplyPort < B_OK ? fReplyPort : B_OK;
}
} // namespace BPrivate
+1
View File
@@ -31,6 +31,7 @@ MergeObject <libbe>app_kit.o :
Cursor.cpp Cursor.cpp
Clipboard.cpp Clipboard.cpp
dano_message.cpp dano_message.cpp
DesktopLink.cpp
Handler.cpp Handler.cpp
InitTerminateLibBe.cpp InitTerminateLibBe.cpp
Invoker.cpp Invoker.cpp
+27 -44
View File
@@ -14,7 +14,6 @@
#include <AppFileInfo.h> #include <AppFileInfo.h>
#include <Application.h> #include <Application.h>
#include <AppMisc.h>
#include <Directory.h> #include <Directory.h>
#include <File.h> #include <File.h>
#include <FindDirectory.h> #include <FindDirectory.h>
@@ -22,21 +21,24 @@
#include <fs_info.h> #include <fs_info.h>
#include <image.h> #include <image.h>
#include <List.h> #include <List.h>
#include <MessengerPrivate.h>
#include <Mime.h> #include <Mime.h>
#include <Node.h> #include <Node.h>
#include <NodeInfo.h> #include <NodeInfo.h>
#include <OS.h> #include <OS.h>
#include <Path.h> #include <Path.h>
#include <PortLink.h>
#include <Query.h> #include <Query.h>
#include <RegistrarDefs.h> #include <RegistrarDefs.h>
#include <Roster.h> #include <Roster.h>
#include <RosterPrivate.h>
#include <ServerProtocol.h>
#include <Volume.h> #include <Volume.h>
#include <VolumeRoster.h> #include <VolumeRoster.h>
#include <AppMisc.h>
#include <DesktopLink.h>
#include <MessengerPrivate.h>
#include <PortLink.h>
#include <RosterPrivate.h>
#include <ServerProtocol.h>
#include <ctype.h> #include <ctype.h>
#include <new> #include <new>
#include <stdio.h> #include <stdio.h>
@@ -770,52 +772,18 @@ BRoster::StopWatching(BMessenger target) const
status_t status_t
BRoster::ActivateApp(team_id team) const BRoster::ActivateApp(team_id team) const
{ {
// get the app server port BPrivate::DesktopLink link;
port_id port = find_port(SERVER_PORT_NAME);
if (port < B_OK)
return port;
// create a reply port status_t status = link.InitCheck();
struct ReplyPort { if (status < B_OK)
ReplyPort() return status;
: 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<port_id>(replyPort.port);
link.Attach<int32>(getuid());
int32 code;
if (link.FlushWithReply(code) != B_OK || code != B_OK)
return B_ERROR;
// we now talk to the desktop
link.Read<port_id>(&port);
link.SetSenderPort(port);
// prepare the message // prepare the message
status_t error = link.StartMessage(AS_ACTIVATE_APP); status_t error = link.StartMessage(AS_ACTIVATE_APP);
if (error != B_OK) if (error != B_OK)
return error; return error;
error = link.Attach(replyPort.port); error = link.Attach(link.ReceiverPort());
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -824,6 +792,7 @@ BRoster::ActivateApp(team_id team) const
return error; return error;
// send it // send it
status_t code;
error = link.FlushWithReply(code); error = link.FlushWithReply(code);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1724,6 +1693,20 @@ BRoster::_RemoveApp(team_id team) const
return error; 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 // _LaunchApp
/*! \brief Launches the application associated with the supplied MIME type or /*! \brief Launches the application associated with the supplied MIME type or
the entry referred to by the supplied entry_ref. the entry referred to by the supplied entry_ref.
+17
View File
@@ -542,6 +542,23 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
break; 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: case B_QUIT_REQUESTED:
// We've been asked to quit, so (for now) broadcast to all // We've been asked to quit, so (for now) broadcast to all
// test apps to quit. This situation will occur only when the server // test apps to quit. This situation will occur only when the server
+17
View File
@@ -51,6 +51,7 @@
#include <FontPrivate.h> #include <FontPrivate.h>
#include <MessengerPrivate.h> #include <MessengerPrivate.h>
#include <ServerProtocol.h> #include <ServerProtocol.h>
#include <WindowPrivate.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -432,6 +433,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
break; 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_WINDOW:
case AS_CREATE_OFFSCREEN_WINDOW: case AS_CREATE_OFFSCREEN_WINDOW:
{ {
+11 -2
View File
@@ -1011,12 +1011,21 @@ fDesktop->LockSingleWindow();
} }
case AS_DIRECT_WINDOW_SET_FULLSCREEN: case AS_DIRECT_WINDOW_SET_FULLSCREEN:
{ {
// TODO: maybe there is more to do than this?
bool enable; bool enable;
link.Read<bool>(&enable); link.Read<bool>(&enable);
fLink.StartMessage(B_ERROR); status_t status = B_OK;
fLink.Flush(); 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; break;
} }
+17 -1
View File
@@ -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. * Distributed under the terms of the MIT License.
*/ */
@@ -18,6 +18,8 @@
#include <debug_support.h> #include <debug_support.h>
#include <Entry.h> #include <Entry.h>
#include <Invoker.h> #include <Invoker.h>
#include <RosterPrivate.h>
#include <Server.h> #include <Server.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
@@ -112,6 +114,7 @@ private:
void _LookupSymbolAddress(debug_symbol_lookup_context *lookupContext, void _LookupSymbolAddress(debug_symbol_lookup_context *lookupContext,
const void *address, char *buffer, int32 bufferSize); const void *address, char *buffer, int32 bufferSize);
void _PrintStackTrace(thread_id thread); void _PrintStackTrace(thread_id thread);
void _NotifyAppServer(team_id team);
status_t _InitGUI(); status_t _InitGUI();
@@ -567,6 +570,9 @@ TeamDebugHandler::_HandleMessage(DebugMessage *message)
} else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) { } else if (USE_GUI && _AreGUIServersAlive() && _InitGUI() == B_OK) {
// normal app // normal app
_NotifyAppServer(fTeam);
char buffer[1024]; char buffer[1024];
snprintf(buffer, sizeof(buffer), "The application:\n\n %s\n\n" snprintf(buffer, sizeof(buffer), "The application:\n\n %s\n\n"
"has encountered an error which prevents it from continuing. Haiku " "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 // _InitGUI
status_t status_t
TeamDebugHandler::_InitGUI() TeamDebugHandler::_InitGUI()