diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp index 6d777028b5..bf20b9c137 100644 --- a/src/apps/debugger/Debugger.cpp +++ b/src/apps/debugger/Debugger.cpp @@ -23,6 +23,7 @@ #include "MessageCodes.h" #include "SettingsManager.h" #include "TeamDebugger.h" +#include "TeamsWindow.h" #include "TypeHandlerRoster.h" #include "ValueHandlerRoster.h" @@ -153,12 +154,16 @@ parse_arguments(int argc, const char* const* argv, bool noOutput, exclusiveParams++; if (exclusiveParams == 0) { + +/* // TODO: Support! if (noOutput) return false; fprintf(stderr, "Sorry, running without team/thread to debug not " "supported yet.\n"); exit(1); +*/ + return true; } else if (exclusiveParams != 1) { if (noOutput) return false; @@ -169,197 +174,298 @@ parse_arguments(int argc, const char* const* argv, bool noOutput, } +// #pragma mark - + class Debugger : public BApplication, private TeamDebugger::Listener { public: - Debugger() - : - BApplication(kDebuggerSignature), - fRunningTeamDebuggers(0) - { - } + Debugger(); + ~Debugger(); - ~Debugger() - { - ValueHandlerRoster::DeleteDefault(); - TypeHandlerRoster::DeleteDefault(); - } - - status_t Init() - { - status_t error = TypeHandlerRoster::CreateDefault(); - if (error != B_OK) - return error; - - error = ValueHandlerRoster::CreateDefault(); - if (error != B_OK) - return error; - - return fSettingsManager.Init(); - } - - virtual void MessageReceived(BMessage* message) - { - switch (message->what) { - case MSG_TEAM_DEBUGGER_QUIT: - { - int32 threadID; - if (message->FindInt32("thread", &threadID) == B_OK) - wait_for_thread(threadID, NULL); - - if (--fRunningTeamDebuggers == 0) - Quit(); - break; - } - default: - BApplication::MessageReceived(message); - break; - } - } - - virtual void ReadyToRun() - { - } - - virtual void ArgvReceived(int32 argc, char** argv) - { - Options options; - if (!parse_arguments(argc, argv, true, options)) -{ -printf("Debugger::ArgvReceived(): parsing args failed!\n"); - return; -} - - team_id team = options.team; - thread_id thread = options.thread; - bool stopInMain = false; - - // If command line arguments were given, start the program. - if (options.commandLineArgc > 0) { -printf("loading program: \"%s\" ...\n", options.commandLineArgv[0]); - // TODO: What about the CWD? - thread = load_program(options.commandLineArgv, - options.commandLineArgc, false); - if (thread < 0) { - // TODO: Notify the user! - fprintf(stderr, "Error: Failed to load program \"%s\": %s\n", - options.commandLineArgv[0], strerror(thread)); - return; - } - - team = thread; - // main thread ID == team ID - stopInMain = true; - } - - // If we've got - if (team < 0) { -printf("no team yet, getting thread info...\n"); - thread_info threadInfo; - status_t error = get_thread_info(thread, &threadInfo); - if (error != B_OK) { - // TODO: Notify the user! - fprintf(stderr, "Error: Failed to get info for thread \"%ld\": " - "%s\n", thread, strerror(error)); - return; - } - - team = threadInfo.team; - } -printf("team: %ld, thread: %ld\n", team, thread); - - TeamDebugger* debugger = _TeamDebuggerForTeam(team); - if (debugger != NULL) { - // TODO: Activate the respective window! -printf("There's already a debugger for team: %ld\n", team); - return; - } - - UserInterface* userInterface = new(std::nothrow) GraphicalUserInterface; - if (userInterface == NULL) { - // TODO: Notify the user! - fprintf(stderr, "Error: Out of memory!\n"); - } - Reference userInterfaceReference(userInterface, true); - - debugger = new(std::nothrow) TeamDebugger(this, userInterface, - &fSettingsManager); - if (debugger == NULL) { - // TODO: Notify the user! - fprintf(stderr, "Error: Out of memory!\n"); - } - - status_t error = debugger->Init(team, thread, stopInMain); - if (debugger->Thread()) - fRunningTeamDebuggers++; - - if (error == B_OK && fTeamDebuggers.AddItem(debugger)) { -printf("debugger for team %ld created and initialized successfully!\n", team); - } else - delete debugger; - } + status_t Init(); + virtual void MessageReceived(BMessage* message); + virtual void ReadyToRun(); + virtual void ArgvReceived(int32 argc, char** argv); private: typedef BObjectList TeamDebuggerList; private: // TeamDebugger::Listener - virtual void TeamDebuggerQuit(TeamDebugger* debugger) - { - // Note: Locking here only works, since we're never locking the other - // way around. If we even need to do that, we'll have to introduce a - // separate lock to protect the list. - AutoLocker locker(this); - fTeamDebuggers.RemoveItem(debugger); - locker.Unlock(); + virtual void TeamDebuggerStarted(TeamDebugger* debugger); + virtual void TeamDebuggerQuit(TeamDebugger* debugger); - if (debugger->Thread() >= 0) { - BMessage message(MSG_TEAM_DEBUGGER_QUIT); - message.AddInt32("thread", debugger->Thread()); - PostMessage(&message); - } - } - - virtual bool QuitRequested() - { - // NOTE: The default implementation will just ask all windows' - // QuitRequested() hooks. This in turn will ask the TeamWindows. - // For now, this is what we want. If we have more windows later, - // like the global TeamsWindow, then we want to just ask the - // TeamDebuggers, the TeamsWindow should of course not go away already - // if one or more TeamDebuggers want to stay later. There are multiple - // ways how to do this. For examaple, TeamDebugger could get a - // QuitReqested() hook or the TeamsWindow and other global windows - // could always return false in their QuitRequested(). - return BApplication::QuitRequested(); - // TODO: This is ugly. The team debuggers own the windows, not the - // other way around. - } - - virtual void Quit() - { - // don't quit before all team debuggers have been quit - if (fRunningTeamDebuggers <= 0) - BApplication::Quit(); - } - - TeamDebugger* _TeamDebuggerForTeam(team_id teamID) const - { - for (int32 i = 0; TeamDebugger* debugger = fTeamDebuggers.ItemAt(i); - i++) { - if (debugger->TeamID() == teamID) - return debugger; - } - - return NULL; - } + virtual bool QuitRequested(); + virtual void Quit(); + TeamDebugger* _FindTeamDebugger(team_id teamID) const; + TeamDebugger* _StartTeamDebugger(team_id teamID, + thread_id threadID = -1, bool stopInMain = false); private: SettingsManager fSettingsManager; TeamDebuggerList fTeamDebuggers; int32 fRunningTeamDebuggers; + TeamsWindow* fTeamsWindow; }; +Debugger::Debugger() + : + BApplication(kDebuggerSignature), + fRunningTeamDebuggers(0), + fTeamsWindow(NULL) +{ +} + + +Debugger::~Debugger() +{ + ValueHandlerRoster::DeleteDefault(); + TypeHandlerRoster::DeleteDefault(); +} + + +status_t +Debugger::Init() +{ + status_t error = TypeHandlerRoster::CreateDefault(); + if (error != B_OK) + return error; + + error = ValueHandlerRoster::CreateDefault(); + if (error != B_OK) + return error; + + return fSettingsManager.Init(); +} + + +void +Debugger::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_SHOW_TEAMS_WINDOW: + { + if (fTeamsWindow) + fTeamsWindow->Activate(true); + else { + fTeamsWindow = new TeamsWindow(); + fTeamsWindow->Show(); + } + break; + } + case MSG_TEAMS_WINDOW_CLOSED: + { + fTeamsWindow = NULL; + Quit(); + break; + } + case MSG_DEBUG_THIS_TEAM: + { + int32 teamID; + if (message->FindInt32("team", &teamID) != B_OK) + break; + + _StartTeamDebugger(teamID); + break; + } + case MSG_TEAM_DEBUGGER_QUIT: + { + int32 threadID; + if (message->FindInt32("thread", &threadID) == B_OK) + wait_for_thread(threadID, NULL); + + --fRunningTeamDebuggers; + Quit(); + break; + } + default: + BApplication::MessageReceived(message); + break; + } +} + + +void +Debugger::ReadyToRun() +{ + if (fRunningTeamDebuggers == 0) + PostMessage(MSG_SHOW_TEAMS_WINDOW); +} + + +void +Debugger::ArgvReceived(int32 argc, char** argv) +{ + Options options; + if (!parse_arguments(argc, argv, true, options)) { + printf("Debugger::ArgvReceived(): parsing args failed!\n"); + return; + } + + team_id team = options.team; + thread_id thread = options.thread; + bool stopInMain = false; + + // If command line arguments were given, start the program. + if (options.commandLineArgc > 0) { + printf("loading program: \"%s\" ...\n", options.commandLineArgv[0]); + // TODO: What about the CWD? + thread = load_program(options.commandLineArgv, + options.commandLineArgc, false); + if (thread < 0) { + // TODO: Notify the user! + fprintf(stderr, "Error: Failed to load program \"%s\": %s\n", + options.commandLineArgv[0], strerror(thread)); + return; + } + + team = thread; + // main thread ID == team ID + stopInMain = true; + } + + // If we've got + if (team < 0) { + printf("no team yet, getting thread info...\n"); + thread_info threadInfo; + status_t error = get_thread_info(thread, &threadInfo); + if (error != B_OK) { + // TODO: Notify the user! + fprintf(stderr, "Error: Failed to get info for thread \"%ld\": " + "%s\n", thread, strerror(error)); + return; + } + + team = threadInfo.team; + } + printf("team: %ld, thread: %ld\n", team, thread); + + TeamDebugger* debugger = _FindTeamDebugger(team); + if (debugger != NULL) { + printf("There's already a debugger for team: %ld\n", team); + debugger->Activate(); + return; + } + + _StartTeamDebugger(team, thread, stopInMain); +} + +// TeamDebugger::Listener + +void +Debugger::TeamDebuggerStarted(TeamDebugger* debugger) +{ + printf("debugger for team %ld started...\n", + debugger->TeamID()); + + // Note: see TeamDebuggerQuit() note about locking + AutoLocker locker(this); + fTeamDebuggers.AddItem(debugger); + fRunningTeamDebuggers++; + locker.Unlock(); +} + + +void +Debugger::TeamDebuggerQuit(TeamDebugger* debugger) +{ + // Note: Locking here only works, since we're never locking the other + // way around. If we even need to do that, we'll have to introduce a + // separate lock to protect the list. + + printf("debugger for team %ld quit.\n", + debugger->TeamID()); + + AutoLocker locker(this); + fTeamDebuggers.RemoveItem(debugger); + locker.Unlock(); + + if (debugger->Thread() >= 0) { + BMessage message(MSG_TEAM_DEBUGGER_QUIT); + message.AddInt32("thread", debugger->Thread()); + PostMessage(&message); + } +} + + +bool +Debugger::QuitRequested() +{ + // NOTE: The default implementation will just ask all windows' + // QuitRequested() hooks. This in turn will ask the TeamWindows. + // For now, this is what we want. If we have more windows later, + // like the global TeamsWindow, then we want to just ask the + // TeamDebuggers, the TeamsWindow should of course not go away already + // if one or more TeamDebuggers want to stay later. There are multiple + // ways how to do this. For example, TeamDebugger could get a + // QuitRequested() hook or the TeamsWindow and other global windows + // could always return false in their QuitRequested(). + return BApplication::QuitRequested(); + // TODO: This is ugly. The team debuggers own the windows, not the + // other way around. +} + +void +Debugger::Quit() +{ + printf("Debugger::Quit(): fRunningTeamDebuggers = %ld, fTeamsWindow = %p\n", + fRunningTeamDebuggers, fTeamsWindow); + + // don't quit before all team debuggers have been quit + if (fRunningTeamDebuggers <= 0 && fTeamsWindow == NULL) + BApplication::Quit(); +} + + +TeamDebugger* +Debugger::_FindTeamDebugger(team_id teamID) const +{ + for (int32 i = 0; TeamDebugger* debugger = fTeamDebuggers.ItemAt(i); + i++) { + if (debugger->TeamID() == teamID) + return debugger; + } + + return NULL; +} + + +TeamDebugger* +Debugger::_StartTeamDebugger(team_id teamID, thread_id threadID, bool stopInMain) +{ + if (teamID < 0) + return NULL; + + UserInterface* userInterface = new(std::nothrow) GraphicalUserInterface; + if (userInterface == NULL) { + // TODO: Notify the user! + fprintf(stderr, "Error: Out of memory!\n"); + return NULL; + } + Reference userInterfaceReference(userInterface, true); + + status_t error = B_NO_MEMORY; + + TeamDebugger* debugger = new(std::nothrow) TeamDebugger(this, userInterface, + &fSettingsManager); + if (debugger) + error = debugger->Init(teamID, threadID, stopInMain); + + if (error != B_OK) { + printf("Error: debugger for team %ld failed to init: %s!\n", + teamID, strerror(error)); + delete debugger; + return NULL; + } else + printf("debugger for team %ld created and initialized successfully!\n", + teamID); + + return debugger; +} + + +// #pragma mark - + int main(int argc, const char* const* argv) { diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 2e21538ccd..912c7023f1 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -22,6 +22,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui model ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui team_window ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui teams_window ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui util ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui value ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) util ] ; @@ -164,6 +165,10 @@ Application Debugger : VariablesViewState.cpp VariablesViewStateHistory.cpp + # user_interface/gui/teams_window + TeamsWindow.cpp + TeamsListView.cpp + # user_interface/gui/team_window BreakpointListView.cpp BreakpointsView.cpp @@ -248,4 +253,3 @@ Application Debugger : HaikuSubInclude arch x86 disasm ; HaikuSubInclude demangler ; HaikuSubInclude dwarf ; -HaikuSubInclude user_interface gui running_teams_window ; diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index bf2ddfe863..8b6915201f 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -41,7 +41,10 @@ enum { MSG_VALUE_NODE_CHILDREN_DELETED = 'vncd', MSG_VALUE_NODE_VALUE_CHANGED = 'vnvc', - MSG_TEAM_DEBUGGER_QUIT = 'dbqt' + MSG_TEAM_DEBUGGER_QUIT = 'dbqt', + MSG_SHOW_TEAMS_WINDOW = 'stsw', + MSG_TEAMS_WINDOW_CLOSED = 'tswc', + MSG_DEBUG_THIS_TEAM = 'dbtt' }; diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index 3f196431d2..e4dc4b7924 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -362,7 +362,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) return error; } - fUserInterface->Show(); + Activate(); // if requested, stop the given thread if (threadID >= 0) { @@ -380,10 +380,19 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) } } + fListener->TeamDebuggerStarted(this); + return B_OK; } +void +TeamDebugger::Activate() +{ + fUserInterface->Show(); +} + + void TeamDebugger::MessageReceived(BMessage* message) { diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 164577339a..57228c982e 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -38,6 +38,8 @@ public: status_t Init(team_id teamID, thread_id threadID, bool stopInMain); + void Activate(); + team_id TeamID() const { return fTeamID; } virtual void MessageReceived(BMessage* message); @@ -144,6 +146,7 @@ class TeamDebugger::Listener { public: virtual ~Listener(); + virtual void TeamDebuggerStarted(TeamDebugger* debugger) = 0; virtual void TeamDebuggerQuit(TeamDebugger* debugger) = 0; }; diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/Jamfile b/src/apps/debugger/user_interface/gui/running_teams_window/Jamfile deleted file mode 100644 index d3f36e386b..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -SubDir HAIKU_TOP src apps debugger user_interface gui running_teams_window ; - -CCFLAGS += -Werror ; -C++FLAGS += -Werror ; - -UsePrivateHeaders debug ; -UsePrivateSystemHeaders ; - -Application hdb : - hdb.cpp - RunningTeamsWindow.cpp - TeamsListView.cpp - TeamWindow.cpp - - : be tracker translation libdebug.so $(TARGET_LIBSUPC++) -; diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.cpp b/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.cpp deleted file mode 100644 index ef9d09794c..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "hdb.h" - -#include "RunningTeamsWindow.h" -#include "TeamsListView.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -RunningTeamsWindow::RunningTeamsWindow() - : BWindow(BRect(100, 100, 500, 250), "Running Teams", B_DOCUMENT_WINDOW, - B_ASYNCHRONOUS_CONTROLS) -{ - BMessage settings; - _LoadSettings(settings); - - BRect frame; - if (settings.FindRect("running teams window frame", &frame) == B_OK) { - MoveTo(frame.LeftTop()); - ResizeTo(frame.Width(), frame.Height()); - } - - // Add a teams list view - frame = Bounds(); - frame.right -= B_V_SCROLL_BAR_WIDTH; - - fTeamsListView = new TeamsListView(frame, "RunningTeamsList"); - fTeamsListView->SetInvocationMessage(new BMessage(kMsgDebugThisTeam)); - - BScrollView * teamsScroller = new BScrollView("RunningTeamsListScroller", - fTeamsListView, B_FOLLOW_ALL_SIDES, 0, false, true, B_NO_BORDER); - - AddChild(teamsScroller); - - // small visual tweak - if (BScrollBar* scrollBar = teamsScroller->ScrollBar(B_VERTICAL)) { - scrollBar->MoveBy(0, -1); - scrollBar->ResizeBy(0, -(B_H_SCROLL_BAR_HEIGHT - 2)); - } -} - - -RunningTeamsWindow::~RunningTeamsWindow() -{ -} - - -void -RunningTeamsWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - case kMsgDebugThisTeam: - { - TeamListItem* item = dynamic_cast(fTeamsListView->ItemAt( - fTeamsListView->CurrentSelection())); - - if (item != NULL) { - BMessage message(kMsgOpenTeamWindow); - message.AddInt32("team_id", item->TeamID()); - be_app_messenger.SendMessage(&message); - } - break; - } - - default: - BWindow::MessageReceived(message); - break; - } -} - - -bool -RunningTeamsWindow::QuitRequested() -{ - _SaveSettings(); - - be_app_messenger.SendMessage(kMsgRunningTeamsWindowClosed); - return true; -} - - -// #pragma mark -- - - -status_t -RunningTeamsWindow::_OpenSettings(BFile& file, uint32 mode) -{ - BPath path; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) - return B_ERROR; - - path.Append("Debugger settings"); - - return file.SetTo(path.Path(), mode); -} - - -status_t -RunningTeamsWindow::_LoadSettings(BMessage& settings) -{ - BFile file; - status_t status = _OpenSettings(file, B_READ_ONLY); - if (status < B_OK) - return status; - - return settings.Unflatten(&file); -} - - -status_t -RunningTeamsWindow::_SaveSettings() -{ - BFile file; - status_t status = _OpenSettings(file, - B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); - - if (status < B_OK) - return status; - - BMessage settings('hdbg'); - status = settings.AddRect("running teams window frame", Frame()); - if (status != B_OK) - return status; - - if (status == B_OK) - status = settings.Flatten(&file); - - return status; -} diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.h b/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.h deleted file mode 100644 index 658648afcd..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/RunningTeamsWindow.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#ifndef RUNNING_TEAMS_WINDOW_H -#define RUNNING_TEAMS_WINDOW_H - -#include - -class BListView; -class BFile; -class BMessage; - - -class RunningTeamsWindow : public BWindow { -public: - RunningTeamsWindow(); - virtual ~RunningTeamsWindow(); - - virtual void MessageReceived(BMessage* message); - virtual bool QuitRequested(); - -private: - - status_t _OpenSettings(BFile& file, uint32 mode); - status_t _LoadSettings(BMessage& settings); - status_t _SaveSettings(); - - BListView* fTeamsListView; - -}; - -static const uint32 kMsgDebugThisTeam = 'dbtm'; - -#endif // RUNNING_TEAMS_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.cpp deleted file mode 100644 index 3e81d2bd2a..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright 2008, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "hdb.h" -#include "TeamWindow.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -TeamWindow::TeamWindow(team_id team) - : BWindow(BRect(100, 100, 500, 250), "Running Teams", B_DOCUMENT_WINDOW, - B_ASYNCHRONOUS_CONTROLS), - fTeam(team), - fNubThread(-1), - fNubPort(-1), - fListenerThread(-1), - fListenerPort(-1) -{ - BMessage settings; - _LoadSettings(settings); - - BRect frame; - if (settings.FindRect("team window frame", &frame) == B_OK) { - MoveTo(frame.LeftTop()); - ResizeTo(frame.Width(), frame.Height()); - } - - team_info info; - get_team_info(team, &info); - - BString title; - title << "Team " << fTeam << ": " << info.args; - - SetTitle(title.String()); - - _InstallDebugger(); -} - - -TeamWindow::~TeamWindow() -{ - _RemoveDebugger(); -} - - -void -TeamWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - default: - BWindow::MessageReceived(message); - break; - } -} - - -bool -TeamWindow::QuitRequested() -{ -/* _SaveSettings(); - - BMessage update(kMsgSettingsChanged); - update.AddRect("window_frame", Frame()); - be_app_messenger.SendMessage(&update); -*/ - be_app_messenger.SendMessage(kMsgWindowClosed); - return true; -} - - -// #pragma mark -- - - -status_t -TeamWindow::_InstallDebugger() -{ - char name[32]; - status_t result; - - snprintf(name, sizeof(name), "team %ld nub listener", fTeam); - printf("Starting %s...\n", name); - - // create listener port - fListenerPort = create_port(10, name); - if (fListenerPort < 0) - return fListenerPort; - - // spawn the listener thread - fListenerThread = spawn_thread(_ListenerEntry, name, - B_NORMAL_PRIORITY, this); - if (fListenerThread < 0) - return fListenerThread; - - // register as this team debugger - printf("Installing team %ld debugger on port 0x%lx...\n", - fTeam, fListenerPort); - fNubPort = install_team_debugger(fTeam, fListenerPort); - if (fNubPort < 0) - return fNubPort; - - // init the debug context - result = init_debug_context(&fDebugContext, fTeam, fNubPort); - if (result != B_OK) { - fprintf(stderr, "Failed to init debug context for team %ld: %s\n", - fTeam, strerror(result)); - } - - // get team nub thread - team_info teamInfo; - result = get_team_info(fTeam, &teamInfo); - if (result != B_OK) { - fprintf(stderr, "Failed to get info for team %ld: %s\n", - fTeam, strerror(result)); - } - fNubThread = teamInfo.debugger_nub_thread; - - // set the team debug flags - debug_nub_set_team_flags message; - message.flags = - B_TEAM_DEBUG_SIGNALS | - // B_TEAM_DEBUG_PRE_SYSCALL | - // B_TEAM_DEBUG_POST_SYSCALL | - B_TEAM_DEBUG_TEAM_CREATION | - B_TEAM_DEBUG_THREADS | - B_TEAM_DEBUG_IMAGES | - // B_TEAM_DEBUG_STOP_NEW_THREADS | - 0; - - send_debug_message(&fDebugContext, - B_DEBUG_MESSAGE_SET_TEAM_FLAGS, &message, sizeof(message), NULL, 0); - - // resume the listener - resume_thread(fListenerThread); - - return B_OK; -} - - -status_t -TeamWindow::_RemoveDebugger() -{ - if (fListenerPort < 0) - // No debugger installed (yet?) - return B_OK; - - printf("Stopping team %ld nub listener...\n", fTeam); - - printf("Removing team %ld debugger installed on port 0x%lx...\n", - fTeam, fListenerPort); - status_t status = remove_team_debugger(fTeam); - - delete_port(fListenerPort); - if (fListenerThread >= 0 && find_thread(NULL) != fListenerThread) { - status_t result; - wait_for_thread(fListenerThread, &result); - fListenerThread = -1; - } - - destroy_debug_context(&fDebugContext); - fListenerPort = -1; - - return status; -} - - -status_t -TeamWindow::_ListenerEntry(void *data) -{ - return ((TeamWindow*) data)->_Listener(); -} - -// _Listener -status_t -TeamWindow::_Listener() -{ - printf("Team %ld nub listener on port 0x%lx started...\n", fTeam, fListenerPort); - - while (true) { - // receive the next debug message - debug_debugger_message code; - debug_debugger_message_data data; - ssize_t bytesRead; - - do { - bytesRead = read_port(fListenerPort, (int32 *) &code, &data, - sizeof(debug_debugger_message_data)); - } while (bytesRead == B_INTERRUPTED); - - if (bytesRead == B_BAD_PORT_ID) - break; - - if (bytesRead < 0) { - fprintf(stderr, "Team %ld nub listener: failed to read from " - "listener port: %s. Terminating!\n", - fTeam, strerror(bytesRead)); - break; - } - - _HandleDebugMessage(code, data); - } - - printf("Team %ld nub listener on port 0x%lx stopped.\n", fTeam, fListenerPort); - - return B_OK; -} - - -status_t -TeamWindow::_HandleDebugMessage(debug_debugger_message code, - debug_debugger_message_data & data) -{ - char dump[512]; - get_debug_message_string(code, dump, sizeof(dump)); - - printf("Team %ld nub listener: code %d from team %ld received: %s\n", - fTeam, code, data.origin.team, dump); - - switch (code) { - case B_DEBUGGER_MESSAGE_DEBUGGER_CALL: - { - // print the debugger message - char debuggerMessage[1024]; - ssize_t bytesRead = debug_read_string(&fDebugContext, - data.debugger_call.message, debuggerMessage, - sizeof(debuggerMessage)); - if (bytesRead > 0) { - printf(" Thread %ld called debugger(): %s\n", - data.origin.thread, debuggerMessage); - } else { - fprintf(stderr, " Thread %ld called debugger(), but failed" - "to get the debugger message.\n", - data.origin.thread); - } - // fall through... - } - case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED: - case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT: - case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT: - case B_DEBUGGER_MESSAGE_SINGLE_STEP: { - // ATM, just continue - debug_nub_continue_thread message; - message.thread = data.origin.thread; - message.handle_event = B_THREAD_DEBUG_HANDLE_EVENT; - message.single_step = false; // run full speed - - status_t result= send_debug_message(&fDebugContext, - B_DEBUG_MESSAGE_CONTINUE_THREAD, &message, sizeof(message), - NULL, 0); - if (result != B_OK) { - fprintf(stderr, "Failed to resume thread %ld: %s\n", - message.thread, strerror(result)); - } - break; - } - case B_DEBUGGER_MESSAGE_PRE_SYSCALL: - printf(" pre_syscall.syscall = %ld\n", data.pre_syscall.syscall); - break; - - case B_DEBUGGER_MESSAGE_POST_SYSCALL: - printf(" post_syscall.syscall = %ld\n", data.post_syscall.syscall); - break; - - case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED: - printf(" signal_received.signal = %d\n", - data.signal_received.signal); - break; - - case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED: - { - // print the exception message - char exception[1024]; - get_debug_exception_string(data.exception_occurred.exception, - exception, sizeof(exception)); - printf(" Thread %ld caused an exception: signal %d, %s\n", - data.origin.thread, data.exception_occurred.signal, exception); - break; - } - - case B_DEBUGGER_MESSAGE_TEAM_CREATED: - case B_DEBUGGER_MESSAGE_TEAM_DELETED: - break; - - case B_DEBUGGER_MESSAGE_THREAD_CREATED: - printf(" thread_created.new_thread = %ld\n", - data.thread_created.new_thread); - break; - case B_DEBUGGER_MESSAGE_THREAD_DELETED: - printf(" thread_deleted.origin.thread = %ld\n", - data.thread_deleted.origin.thread); - break; - - case B_DEBUGGER_MESSAGE_IMAGE_CREATED: - printf(" id = %ld, type = %d, name = %s\n", - data.image_created.info.id, - data.image_created.info.type, - data.image_created.info.name); - break; - - case B_DEBUGGER_MESSAGE_IMAGE_DELETED: - printf(" id = %ld, type = %d, name = %s\n", - data.image_deleted.info.id, - data.image_deleted.info.type, - data.image_deleted.info.name); - break; - - default: - // unknown message, ignore - break; - } - - return B_OK; - -} - -// ---- - -status_t -TeamWindow::_OpenSettings(BFile& file, uint32 mode) -{ - BPath path; - if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) - return B_ERROR; - - path.Append("Debugger settings"); - - return file.SetTo(path.Path(), mode); -} - - -status_t -TeamWindow::_LoadSettings(BMessage& settings) -{ - BFile file; - status_t status = _OpenSettings(file, B_READ_ONLY); - if (status < B_OK) - return status; - - return settings.Unflatten(&file); -} - - -status_t -TeamWindow::_SaveSettings() -{ - BFile file; - status_t status = _OpenSettings(file, - B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); - - if (status < B_OK) - return status; - - BMessage settings('hdbg'); - status = settings.AddRect("team window frame", Frame()); - if (status != B_OK) - return status; - - if (status == B_OK) - status = settings.Flatten(&file); - - return status; -} diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.h deleted file mode 100644 index 58d49a47ae..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/TeamWindow.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2008, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#ifndef TEAM_WINDOW_H -#define TEAM_WINDOW_H - -#include -#include - -class BFile; -class BMessage; - - -class TeamWindow : public BWindow { -public: - TeamWindow(team_id team); - virtual ~TeamWindow(); - - virtual void MessageReceived(BMessage* message); - virtual bool QuitRequested(); - - team_id Team() { return fTeam; }; - -private: - - status_t _InstallDebugger(); - status_t _RemoveDebugger(); - - static status_t _ListenerEntry(void *data); - status_t _Listener(); - status_t _HandleDebugMessage(debug_debugger_message message, - debug_debugger_message_data & data); - - status_t _OpenSettings(BFile& file, uint32 mode); - status_t _LoadSettings(BMessage& settings); - status_t _SaveSettings(); - - // ---- - - team_id fTeam; - thread_id fNubThread; - port_id fNubPort; - debug_context fDebugContext; - - thread_id fListenerThread; - port_id fListenerPort; -}; - -#endif // TEAM_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.cpp b/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.cpp deleted file mode 100644 index c23f7f580a..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "TeamsListView.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -TeamListItem::TeamListItem(team_info & info) - : BStringItem("", false), - fIcon(NULL) -{ - _SetTo(info); -} - - -TeamListItem::TeamListItem(team_id team) - : BStringItem("", false), - fIcon(NULL) -{ - team_info info; - get_team_info(team, &info); - _SetTo(info); -} - - -TeamListItem::~TeamListItem() -{ - delete fIcon; -} - -void -TeamListItem::DrawItem(BView *owner, BRect frame, bool complete) -{ - BRect rect = frame; - - if (fIcon) { - rgb_color highColor = owner->HighColor(); - rgb_color lowColor = owner->LowColor(); - - if (IsSelected() || complete) { - // Draw the background... - if (IsSelected()) - owner->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT)); - - owner->FillRect(rect, B_SOLID_LOW); - } - - BPoint point(rect.left + 2.0f, - rect.top + (rect.Height() - B_MINI_ICON) / 2.0f); - - // Draw icon - owner->SetDrawingMode(B_OP_ALPHA); - owner->DrawBitmap(fIcon, point); - owner->SetDrawingMode(B_OP_COPY); - - owner->MovePenTo(rect.left + B_MINI_ICON + 8.0f, frame.top + fBaselineOffset); - - if (!IsEnabled()) - owner->SetHighColor(tint_color(owner->HighColor(), B_LIGHTEN_2_TINT)); - else - owner->SetHighColor(0, 0, 0); - - owner->DrawString(Text()); - - owner->SetHighColor(highColor); - owner->SetLowColor(lowColor); - } else - // No icon, fallback on plain StringItem... - BStringItem::DrawItem(owner, rect, complete); -} - -void -TeamListItem::Update(BView *owner, const BFont *font) -{ - BStringItem::Update(owner, font); - - if (Height() < B_MINI_ICON + 4.0f) - SetHeight(B_MINI_ICON + 4.0f); - - font_height fontHeight; - font->GetHeight(&fontHeight); - - fBaselineOffset = fontHeight.ascent + - + (Height() - ceilf(fontHeight.ascent + fontHeight.descent)) / 2.0f; -} - - -/* static */ -int -TeamListItem::Compare(const void* a, const void* b) -{ - const BListItem *itemA = *static_cast(a); - const BListItem *itemB = *static_cast(b); - const TeamListItem *teamItemA = dynamic_cast(itemA); - const TeamListItem *teamItemB = dynamic_cast(itemB); - - if (teamItemA != NULL && teamItemB != NULL) { - return teamItemA->fTeamInfo.team - teamItemB->fTeamInfo.team; - } - - return 0; -} - - -status_t -TeamListItem::_SetTo(team_info & info) -{ - BPath systemPath; - team_info teamInfo = fTeamInfo = info; - - find_directory(B_BEOS_SYSTEM_DIRECTORY, &systemPath); - - // strip any trailing space(s)... - for (int len = strlen(teamInfo.args) - 1; - len >= 0 && teamInfo.args[len] == ' '; len--) { - teamInfo.args[len] = 0; - } - - app_info appInfo; - status_t status = be_roster->GetRunningAppInfo(teamInfo.team, &appInfo); - - if (status == B_OK || teamInfo.team == B_SYSTEM_TEAM) { - if (teamInfo.team == B_SYSTEM_TEAM) { - // Get icon and name from kernel - system_info systemInfo; - get_system_info(&systemInfo); - - BPath kernelPath(systemPath); - kernelPath.Append(systemInfo.kernel_name); - - get_ref_for_path(kernelPath.Path(), &appInfo.ref); - } - } else { - BEntry entry(teamInfo.args, true); - entry.GetRef(&appInfo.ref); - } - - SetText(teamInfo.args); - - fIcon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGBA32); - - status = BNodeInfo::GetTrackerIcon(&appInfo.ref, fIcon, B_MINI_ICON); - if (status != B_OK) { - BMimeType genericAppType(B_APP_MIME_TYPE); - status = genericAppType.GetIcon(fIcon, B_MINI_ICON); - } - - if (status != B_OK) { - delete fIcon; - fIcon = NULL; - } - - return status; -} - -// #pragma mark - - - -TeamsListView::TeamsListView(BRect frame, const char* name) - : BListView(frame, name, B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL), - fUpdateRunner(NULL) -{ - team_info tmi; - get_team_info(B_CURRENT_TEAM, &tmi); - fThisTeam = tmi.team; - -#ifdef __HAIKU__ - SetFlags(Flags() | B_SUBPIXEL_PRECISE); -#endif -} - - -TeamsListView::~TeamsListView() -{ - delete fUpdateRunner; -} - - -void -TeamsListView::AttachedToWindow() -{ - BListView::AttachedToWindow(); - - _InitList(); - - be_roster->StartWatching(this, B_REQUEST_LAUNCHED | B_REQUEST_QUIT); - - BMessage msg(kMsgUpdateTeamsList); - fUpdateRunner = new BMessageRunner(this, &msg, 100000L); // 10Hz -} - - -void -TeamsListView::DetachedFromWindow() -{ - BListView::DetachedFromWindow(); - - be_roster->StopWatching(this); - - delete fUpdateRunner; - fUpdateRunner = NULL; - - // free all items, they will be retrieved again in AttachedToWindow() - for (int32 i = CountItems(); i-- > 0;) { - delete ItemAt(i); - } - MakeEmpty(); -} - - -void -TeamsListView::MessageReceived(BMessage* message) -{ - switch (message->what) { - case kMsgUpdateTeamsList: - _UpdateList(); - break; - - case B_SOME_APP_LAUNCHED: - { - team_id team; - if (message->FindInt32("be:team", &team) != B_OK) - break; - - AddItem(new TeamListItem(team)); - SortItems(&TeamListItem::Compare); - break; - } - - case B_SOME_APP_QUIT: - { - team_id team; - if (message->FindInt32("be:team", &team) != B_OK) - break; - - TeamListItem *item = FindItem(team); - if (item != NULL) { - RemoveItem(item); - delete item; - } - break; - } - - default: - BListView::MessageReceived(message); - } -} - - -TeamListItem * -TeamsListView::FindItem(team_id teamId) -{ - for (int32 i = CountItems(); i-- > 0;) { - TeamListItem* item = dynamic_cast(ItemAt(i)); - if (item == NULL) - continue; - - if (item->TeamID() == teamId) - return item; - } - - return NULL; -} - - -void -TeamsListView::_InitList() -{ - int32 tmi_cookie = 0; - team_info tmi; - - while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) { - TeamListItem * item = new TeamListItem(tmi); - - if (tmi.team == B_SYSTEM_TEAM || - tmi.team == fThisTeam) - // We don't support debugging kernel and... ourself! - // Don't show these two teams - continue; - - AddItem(item); - } - - // SortItems(&TeamListItem::Compare); -} - - -void -TeamsListView::_UpdateList() -{ - int32 tmi_cookie = 0; - team_info tmi; - TeamListItem *item; - int32 index = 0; - - // NOTA: assuming get_next_team_info() returns team ordered by team ID... - while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) { - - if (tmi.team == B_SYSTEM_TEAM || - tmi.team == fThisTeam) - continue; // Ignore kernel and ourself teams - - item = (TeamListItem *) ItemAt(index); - - while (item && tmi.team > item->TeamID()) { - RemoveItem(item); - delete item; - item = (TeamListItem *) ItemAt(index); - } - - if (!item || tmi.team != item->TeamID()) { - // Team not found in known teams list: insert an new item - TeamListItem * item = new TeamListItem(tmi); - if (!item) - index++; // No item with team id bigger found: insert at list end - - AddItem(item, index); - } - index++; // Move list sync head. - } - - // Remove tail list items, if we don't walk list thru the end - while ((item = (TeamListItem *) ItemAt(index)) != NULL) { - RemoveItem(item); - delete item; - item = (TeamListItem *) ItemAt(++index); - } -} diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.h b/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.h deleted file mode 100644 index 80f1ad3b2d..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/TeamsListView.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#ifndef TEAMS_LIST_ITEM_H -#define TEAMS_LIST_ITEM_H - -#include -#include -#include - -class BBitmap; -class BMessageRunner; - - -class TeamListItem : public BStringItem { - public: - TeamListItem(team_info & teamInfo); - TeamListItem(team_id teamId); - - virtual ~TeamListItem(); - - public: - virtual void DrawItem(BView *owner, BRect itemRect, - bool drawEverything = false); - virtual void Update(BView *owner, const BFont *font); - - team_id TeamID() { return fTeamInfo.team; }; - - static int Compare(const void* a, const void* b); - - private: - status_t _SetTo(team_info & info); - - team_info fTeamInfo; - BBitmap * fIcon; - float fBaselineOffset; -}; - - -class TeamsListView : public BListView { - public: - TeamsListView(BRect frame, const char* name); - virtual ~TeamsListView(); - - TeamListItem* FindItem(team_id teamId); - - protected: - virtual void AttachedToWindow(); - virtual void DetachedFromWindow(); - - virtual void MessageReceived(BMessage* message); - - private: - void _InitList(); - void _UpdateList(); - - BMessageRunner* fUpdateRunner; - team_id fThisTeam; -}; - -static const uint32 kMsgUpdateTeamsList = 'uptl'; - -#endif // TEAMS_LIST_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/hdb.cpp b/src/apps/debugger/user_interface/gui/running_teams_window/hdb.cpp deleted file mode 100644 index 1ff7726234..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/hdb.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - - -#include "hdb.h" - -#include "RunningTeamsWindow.h" -#include "TeamWindow.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -const char* kSignature = "application/x-vnd.Haiku-Debugger"; - -class Debugger : public BApplication { - public: - Debugger(); - virtual ~Debugger(); - - virtual void ReadyToRun(); - - virtual void RefsReceived(BMessage *message); - virtual void ArgvReceived(int32 argc, char **argv); - virtual void MessageReceived(BMessage *message); - - virtual void AboutRequested(); - - static void ShowAbout(); - - private: - status_t Debug(team_id team); - status_t Debug(BEntry &entry); - - RunningTeamsWindow * fRunningTeamsWindow; -}; - - -Debugger::Debugger() - : BApplication(kSignature), - fRunningTeamsWindow(NULL) -{ -} - - -Debugger::~Debugger() -{ -} - - -status_t -Debugger::Debug(BEntry &entry) -{ - // Does the file really exist? - if (!entry.Exists()) - return B_ENTRY_NOT_FOUND; - - // TODO - BWindow *window = new TeamWindow(0); // team); - window->Show(); - - return B_OK; -} - - -status_t -Debugger::Debug(team_id team) -{ - // int32 teamWindows = 0; - - // Do we already have that window open? - for (int32 i = CountWindows(); i-- > 0; ) { - TeamWindow *window = dynamic_cast(WindowAt(i)); - if (window == NULL) - continue; - - if (window->Team() == team) { - window->Activate(true); - return B_OK; - } - // teamWindows++; - } - - BWindow *window = new TeamWindow(team); - window->Show(); - - return B_OK; -} - - -void -Debugger::ReadyToRun() -{ - // are there already windows open? - if (CountWindows() != 0) - return; - - // if not, open the running teams window - PostMessage(kMsgOpenRunningTeamsWindow); -} - - -void -Debugger::RefsReceived(BMessage *message) -{ - int32 index = 0; - entry_ref ref; - while (message->FindRef("refs", index++, &ref) == B_OK) { - BEntry entry; - status_t status = entry.SetTo(&ref); - - if (status == B_OK) - status = Debug(entry); - - if (status != B_OK) { - char buffer[1024]; - snprintf(buffer, sizeof(buffer), - "Could not debug \"%s\":\n" - "%s", - ref.name, strerror(status)); - - (new BAlert("Debugger request", - buffer, "OK", NULL, NULL, - B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(); - } - } -} - - -void -Debugger::ArgvReceived(int32 argc, char **argv) -{ - BMessage *message = CurrentMessage(); - - BDirectory currentDirectory; - if (message) - currentDirectory.SetTo(message->FindString("cwd")); - - BMessage refs; - - for (int i = 1 ; i < argc ; i++) { - BPath path; - if (argv[i][0] == '/') - path.SetTo(argv[i]); - else - path.SetTo(¤tDirectory, argv[i]); - - status_t status; - entry_ref ref; - BEntry entry; - - if ((status = entry.SetTo(path.Path(), false)) != B_OK - || (status = entry.GetRef(&ref)) != B_OK) { - fprintf(stderr, "Could not open file \"%s\": %s\n", path.Path(), strerror(status)); - continue; - } - - refs.AddRef("refs", &ref); - } - - RefsReceived(&refs); -} - - -void -Debugger::MessageReceived(BMessage *message) -{ - switch (message->what) { - case kMsgOpenRunningTeamsWindow: - if (fRunningTeamsWindow == NULL) { - fRunningTeamsWindow = new RunningTeamsWindow(); - fRunningTeamsWindow->Show(); - } else - fRunningTeamsWindow->Activate(true); - break; - - case kMsgRunningTeamsWindowClosed: - fRunningTeamsWindow = NULL; - // supposed to fall through - case kMsgWindowClosed: - if (CountWindows() == 1) - // Last window is being closed: quit application - PostMessage(B_QUIT_REQUESTED); - break; - - case kMsgOpenTeamWindow: - { - team_id team; - if (message->FindInt32("team_id", &team) == B_OK) - Debug(team); - break; - } - - default: - BApplication::MessageReceived(message); - break; - } -} - - -void -Debugger::AboutRequested() -{ - ShowAbout(); -} - - -/*static*/ void -Debugger::ShowAbout() -{ - BAlert *alert = new BAlert("about", "Debugger\n" - "\twritten by Philippe Houdoin\n" - "\tCopyright 2009, Haiku, Inc.\n", "OK"); - BTextView *view = alert->TextView(); - BFont font; - - view->SetStylable(true); - - view->GetFont(&font); - font.SetSize(18); - font.SetFace(B_BOLD_FACE); - view->SetFontAndColor(0, 15, &font); - - alert->Go(); -} - - -// #pragma mark - - - -int -main(int /* argc */, char ** /* argv */) -{ - Debugger app; - app.Run(); - - return 0; -} diff --git a/src/apps/debugger/user_interface/gui/running_teams_window/hdb.h b/src/apps/debugger/user_interface/gui/running_teams_window/hdb.h deleted file mode 100644 index a6bd3a0c46..0000000000 --- a/src/apps/debugger/user_interface/gui/running_teams_window/hdb.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2009, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. - * Distributed under the terms of the MIT License. - */ - -#ifndef HDB_H -#define HDB_H - -#include - -static const uint32 kMsgOpenRunningTeamsWindow = 'OpRt'; -static const uint32 kMsgRunningTeamsWindowClosed = 'ClRt'; -static const uint32 kMsgWindowClosed = 'WiCl'; - -static const uint32 kMsgOpenTeamWindow = 'OpTw'; - -#endif /* HDB_H */ diff --git a/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.cpp b/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.cpp new file mode 100644 index 0000000000..d0b34ab97d --- /dev/null +++ b/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.cpp @@ -0,0 +1,340 @@ +/* + * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TeamsListView.h" + + +TeamListItem::TeamListItem(team_info & info) + : BStringItem("", false), + fIcon(NULL) +{ + _SetTo(info); +} + + +TeamListItem::TeamListItem(team_id team) + : BStringItem("", false), + fIcon(NULL) +{ + team_info info; + get_team_info(team, &info); + _SetTo(info); +} + + +TeamListItem::~TeamListItem() +{ + delete fIcon; +} + + +void +TeamListItem::DrawItem(BView *owner, BRect frame, bool complete) +{ + BRect rect = frame; + + if (fIcon) { + rgb_color highColor = owner->HighColor(); + rgb_color lowColor = owner->LowColor(); + + if (IsSelected() || complete) { + // Draw the background... + if (IsSelected()) + owner->SetLowColor(tint_color(lowColor, B_DARKEN_2_TINT)); + + owner->FillRect(rect, B_SOLID_LOW); + } + + BPoint point(rect.left + 2.0f, + rect.top + (rect.Height() - B_MINI_ICON) / 2.0f); + + // Draw icon + owner->SetDrawingMode(B_OP_ALPHA); + owner->DrawBitmap(fIcon, point); + owner->SetDrawingMode(B_OP_COPY); + + owner->MovePenTo(rect.left + B_MINI_ICON + 8.0f, frame.top + fBaselineOffset); + + if (!IsEnabled()) + owner->SetHighColor(tint_color(owner->HighColor(), B_LIGHTEN_2_TINT)); + else + owner->SetHighColor(0, 0, 0); + + owner->DrawString(Text()); + + owner->SetHighColor(highColor); + owner->SetLowColor(lowColor); + } else + // No icon, fallback on plain StringItem... + BStringItem::DrawItem(owner, rect, complete); +} + + +void +TeamListItem::Update(BView *owner, const BFont *font) +{ + BStringItem::Update(owner, font); + + if (Height() < B_MINI_ICON + 4.0f) + SetHeight(B_MINI_ICON + 4.0f); + + font_height fontHeight; + font->GetHeight(&fontHeight); + + fBaselineOffset = fontHeight.ascent + + + (Height() - ceilf(fontHeight.ascent + fontHeight.descent)) / 2.0f; +} + + +/* static */ +int +TeamListItem::Compare(const void* a, const void* b) +{ + const BListItem *itemA = *static_cast(a); + const BListItem *itemB = *static_cast(b); + const TeamListItem *teamItemA = dynamic_cast(itemA); + const TeamListItem *teamItemB = dynamic_cast(itemB); + + if (teamItemA != NULL && teamItemB != NULL) { + return teamItemA->fTeamInfo.team - teamItemB->fTeamInfo.team; + } + + return 0; +} + + +status_t +TeamListItem::_SetTo(team_info & info) +{ + BPath systemPath; + team_info teamInfo = fTeamInfo = info; + + find_directory(B_BEOS_SYSTEM_DIRECTORY, &systemPath); + + // strip any trailing space(s)... + for (int len = strlen(teamInfo.args) - 1; + len >= 0 && teamInfo.args[len] == ' '; len--) { + teamInfo.args[len] = 0; + } + + app_info appInfo; + status_t status = be_roster->GetRunningAppInfo(teamInfo.team, &appInfo); + + if (status == B_OK || teamInfo.team == B_SYSTEM_TEAM) { + if (teamInfo.team == B_SYSTEM_TEAM) { + // Get icon and name from kernel + system_info systemInfo; + get_system_info(&systemInfo); + + BPath kernelPath(systemPath); + kernelPath.Append(systemInfo.kernel_name); + + get_ref_for_path(kernelPath.Path(), &appInfo.ref); + } + } else { + BEntry entry(teamInfo.args, true); + entry.GetRef(&appInfo.ref); + } + + SetText(teamInfo.args); + + fIcon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), B_RGBA32); + + status = BNodeInfo::GetTrackerIcon(&appInfo.ref, fIcon, B_MINI_ICON); + if (status != B_OK) { + BMimeType genericAppType(B_APP_MIME_TYPE); + status = genericAppType.GetIcon(fIcon, B_MINI_ICON); + } + + if (status != B_OK) { + delete fIcon; + fIcon = NULL; + } + + return status; +} + +// #pragma mark - + + +TeamsListView::TeamsListView(BRect frame, const char* name) + : BListView(frame, name, B_SINGLE_SELECTION_LIST, B_FOLLOW_ALL), + fUpdateRunner(NULL) +{ + team_info tmi; + get_team_info(B_CURRENT_TEAM, &tmi); + fThisTeam = tmi.team; + +#ifdef __HAIKU__ + SetFlags(Flags() | B_SUBPIXEL_PRECISE); +#endif +} + + +TeamsListView::~TeamsListView() +{ + delete fUpdateRunner; +} + + +void +TeamsListView::AttachedToWindow() +{ + BListView::AttachedToWindow(); + + _InitList(); + + be_roster->StartWatching(this, B_REQUEST_LAUNCHED | B_REQUEST_QUIT); + + BMessage msg(kMsgUpdateTeamsList); + fUpdateRunner = new BMessageRunner(this, &msg, 100000L); // 10Hz +} + + +void +TeamsListView::DetachedFromWindow() +{ + BListView::DetachedFromWindow(); + + be_roster->StopWatching(this); + + delete fUpdateRunner; + fUpdateRunner = NULL; + + // free all items, they will be retrieved again in AttachedToWindow() + for (int32 i = CountItems(); i-- > 0;) { + delete ItemAt(i); + } + MakeEmpty(); +} + + +void +TeamsListView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kMsgUpdateTeamsList: + _UpdateList(); + break; + + case B_SOME_APP_LAUNCHED: + { + team_id team; + if (message->FindInt32("be:team", &team) != B_OK) + break; + + AddItem(new TeamListItem(team)); + SortItems(&TeamListItem::Compare); + break; + } + + case B_SOME_APP_QUIT: + { + team_id team; + if (message->FindInt32("be:team", &team) != B_OK) + break; + + TeamListItem *item = FindItem(team); + if (item != NULL) { + RemoveItem(item); + delete item; + } + break; + } + + default: + BListView::MessageReceived(message); + } +} + + +TeamListItem * +TeamsListView::FindItem(team_id teamId) +{ + for (int32 i = CountItems(); i-- > 0;) { + TeamListItem* item = dynamic_cast(ItemAt(i)); + if (item == NULL) + continue; + + if (item->TeamID() == teamId) + return item; + } + + return NULL; +} + + +void +TeamsListView::_InitList() +{ + int32 tmi_cookie = 0; + team_info tmi; + + while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) { + TeamListItem * item = new TeamListItem(tmi); + + if (tmi.team == B_SYSTEM_TEAM || + tmi.team == fThisTeam) { + // We don't support debugging kernel and... ourself! + item->SetEnabled(false); + } + + AddItem(item); + } + + // SortItems(&TeamListItem::Compare); +} + + +void +TeamsListView::_UpdateList() +{ + int32 tmi_cookie = 0; + team_info tmi; + TeamListItem *item; + int32 index = 0; + + // NOTA: assuming get_next_team_info() returns team ordered by team ID... + while (get_next_team_info(&tmi_cookie, &tmi) == B_OK) { + + item = (TeamListItem *) ItemAt(index); + while (item && tmi.team > item->TeamID()) { + RemoveItem(item); + delete item; + item = (TeamListItem *) ItemAt(index); + } + + if (!item || tmi.team != item->TeamID()) { + // Team not found in known teams list: insert an new item + TeamListItem * item = new TeamListItem(tmi); + if (!item) + index++; // No item with team id bigger found: insert at list end + + AddItem(item, index); + } + index++; // Move list sync head. + } + + // Remove tail list items, if we don't walk list thru the end + while ((item = (TeamListItem *) ItemAt(index)) != NULL) { + RemoveItem(item); + delete item; + item = (TeamListItem *) ItemAt(++index); + } +} diff --git a/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.h b/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.h new file mode 100644 index 0000000000..6ad4f1f6b1 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/teams_window/TeamsListView.h @@ -0,0 +1,67 @@ +/* + * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef TEAMS_LIST_ITEM_H +#define TEAMS_LIST_ITEM_H + + +#include +#include +#include + +class BBitmap; +class BMessageRunner; + + +class TeamListItem : public BStringItem { +public: + TeamListItem(team_info & teamInfo); + TeamListItem(team_id teamId); + + virtual ~TeamListItem(); + +public: + virtual void DrawItem(BView *owner, BRect itemRect, + bool drawEverything = false); + virtual void Update(BView *owner, const BFont *font); + + team_id TeamID() { return fTeamInfo.team; }; + + static int Compare(const void* a, const void* b); + +private: + status_t _SetTo(team_info & info); + +private: + team_info fTeamInfo; + BBitmap * fIcon; + float fBaselineOffset; +}; + + +class TeamsListView : public BListView { +public: + TeamsListView(BRect frame, const char* name); + virtual ~TeamsListView(); + + TeamListItem* FindItem(team_id teamId); + +protected: + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void MessageReceived(BMessage* message); + +private: + void _InitList(); + void _UpdateList(); + +private: + BMessageRunner* fUpdateRunner; + team_id fThisTeam; +}; + +static const uint32 kMsgUpdateTeamsList = 'uptl'; + +#endif // TEAMS_LIST_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.cpp b/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.cpp new file mode 100644 index 0000000000..21720cedc7 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "MessageCodes.h" +#include "TeamsWindow.h" +#include "TeamsListView.h" + + +TeamsWindow::TeamsWindow() + : BWindow(BRect(100, 100, 500, 250), "Teams", B_DOCUMENT_WINDOW, + B_ASYNCHRONOUS_CONTROLS) +{ + BMessage settings; + _LoadSettings(settings); + + BRect frame; + if (settings.FindRect("teams window frame", &frame) == B_OK) { + MoveTo(frame.LeftTop()); + ResizeTo(frame.Width(), frame.Height()); + } + + // TODO: add button to start a team debugger + // TODO: add UI to setup arguments and environ, launch a program + // and start his team debugger + + // Add a teams list view + frame = Bounds(); + frame.right -= B_V_SCROLL_BAR_WIDTH; + + fTeamsListView = new TeamsListView(frame, "TeamsList"); + fTeamsListView->SetInvocationMessage(new BMessage(kMsgDebugThisTeam)); + + BScrollView * teamsScroller = new BScrollView("TeamsListScroller", + fTeamsListView, B_FOLLOW_ALL_SIDES, 0, false, true, B_NO_BORDER); + + AddChild(teamsScroller); + + // small visual tweak + if (BScrollBar* scrollBar = teamsScroller->ScrollBar(B_VERTICAL)) { + scrollBar->MoveBy(0, -1); + scrollBar->ResizeBy(0, -(B_H_SCROLL_BAR_HEIGHT - 2)); + } +} + + +TeamsWindow::~TeamsWindow() +{ +} + + +void +TeamsWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case kMsgDebugThisTeam: + { + TeamListItem* item = dynamic_cast(fTeamsListView->ItemAt( + fTeamsListView->CurrentSelection())); + + if (item != NULL) { + BMessage message(MSG_DEBUG_THIS_TEAM); + message.AddInt32("team", item->TeamID()); + be_app_messenger.SendMessage(&message); + } + break; + } + + default: + BWindow::MessageReceived(message); + break; + } +} + + +bool +TeamsWindow::QuitRequested() +{ + _SaveSettings(); + + be_app_messenger.SendMessage(MSG_TEAMS_WINDOW_CLOSED); + return true; +} + + +// #pragma mark -- + + +status_t +TeamsWindow::_OpenSettings(BFile& file, uint32 mode) +{ + BPath path; + if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) + return B_ERROR; + + path.Append("Debugger settings"); + + return file.SetTo(path.Path(), mode); +} + + +status_t +TeamsWindow::_LoadSettings(BMessage& settings) +{ + BFile file; + status_t status = _OpenSettings(file, B_READ_ONLY); + if (status < B_OK) + return status; + + return settings.Unflatten(&file); +} + + +status_t +TeamsWindow::_SaveSettings() +{ + BFile file; + status_t status = _OpenSettings(file, + B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); + + if (status < B_OK) + return status; + + BMessage settings('hdbg'); + status = settings.AddRect("teams window frame", Frame()); + if (status != B_OK) + return status; + + if (status == B_OK) + status = settings.Flatten(&file); + + return status; +} diff --git a/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.h b/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.h new file mode 100644 index 0000000000..787a4ea1a9 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/teams_window/TeamsWindow.h @@ -0,0 +1,37 @@ +/* + * Copyright 2009-2010, Philippe Houdoin, phoudoin@haiku-os.org. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef TEAMS_WINDOW_H +#define TEAMS_WINDOW_H + + +#include + +class BListView; +class BFile; +class BMessage; + + +class TeamsWindow : public BWindow { +public: + TeamsWindow(); + virtual ~TeamsWindow(); + + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); + +private: + + status_t _OpenSettings(BFile& file, uint32 mode); + status_t _LoadSettings(BMessage& settings); + status_t _SaveSettings(); + +private: + BListView* fTeamsListView; + +}; + +static const uint32 kMsgDebugThisTeam = 'dbtm'; + +#endif // TEAMS_WINDOW_H