Debugger: Rework to fully use TargetHostInterface.
Application objects: - Rework and simplify to take into account that they will no longer be directly managing the team debugger list. Requests to start a new debugger are still funnelled through here however, and as such, said requests must now provide the appropriate target host to start with. Adjust StartTeamWindow and TeamsWindow accordingly. - On global init, always create an instance of the local interface. TargetHostInterface: - Convert to BLooper and implement TeamDebugger's Listener interface. TargetHostInterfaces now directly manage their TeamDebugger instances, and consequently take over the equivalent duties that the main application previously had. - Adjust signatures of Attach/CreateTeam to add const. Adjust LocalTargetHostInterface accordingly. - Add accessor to determine if a given interface is local or not. Will be needed for the TeamDebugger's file manager eventually so it knows if it needs to request remote files if no matching local file is found. - Add accessor to start a TeamDebugger instance, and corresponding options structure. TargetHostInterfaceRoster: - Minor adjustments to host interface initialization to take into account needing to start the looper. - Add accessor for number of running team debuggers, for the main app to use when deciding to quit. TeamDebugger: - Add accessor for SettingsManager. Needed for the case of a restart request, as the host interfaces do not have direct access to it. TeamsWindow: - For now, always grab the local host interface when initializing the window. Once the remote interface is implemented, this will need to be adjusted, but the appropriate UI for creating/selecting it is needed first anyways. With these changes, the main application is fully host-agnostic, and all management of actual debuggers is delegated to their parent host interfaces. There still needs to be a listener interface for the host interface and/or roster though, so that the application can be made aware of when debuggers quit, as this drives whether it's time to terminate the app or not.
This commit is contained in:
parent
52da2024d0
commit
a1afac4dca
@ -20,10 +20,8 @@
|
||||
#include <AutoLocker.h>
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include "debug_utils.h"
|
||||
|
||||
#include "CommandLineUserInterface.h"
|
||||
#include "LocalDebuggerInterface.h"
|
||||
#include "DebuggerInterface.h"
|
||||
#include "GraphicalUserInterface.h"
|
||||
#include "ImageDebugLoadingStateHandlerRoster.h"
|
||||
#include "MessageCodes.h"
|
||||
@ -31,6 +29,8 @@
|
||||
#include "SettingsManager.h"
|
||||
#include "SignalSet.h"
|
||||
#include "StartTeamWindow.h"
|
||||
#include "TargetHostInterface.h"
|
||||
#include "TargetHostInterfaceRoster.h"
|
||||
#include "TeamDebugger.h"
|
||||
#include "TeamsWindow.h"
|
||||
#include "TypeHandlerRoster.h"
|
||||
@ -101,13 +101,16 @@ struct Options {
|
||||
};
|
||||
|
||||
|
||||
struct DebuggedProgramInfo {
|
||||
team_id team;
|
||||
thread_id thread;
|
||||
int commandLineArgc;
|
||||
const char* const* commandLineArgv;
|
||||
bool stopInMain;
|
||||
};
|
||||
static void
|
||||
set_debugger_options_from_options(TeamDebuggerOptions& _debuggerOptions,
|
||||
const Options& options)
|
||||
{
|
||||
_debuggerOptions.commandLineArgc = options.commandLineArgc;
|
||||
_debuggerOptions.commandLineArgv = options.commandLineArgv;
|
||||
_debuggerOptions.team = options.team;
|
||||
_debuggerOptions.thread = options.thread;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool
|
||||
@ -219,136 +222,27 @@ global_init()
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
error = TargetHostInterfaceRoster::CreateDefault();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// for now, always create an instance of the local interface
|
||||
// by default
|
||||
TargetHostInterface* hostInterface;
|
||||
TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default();
|
||||
error = roster->CreateInterface(roster->InterfaceInfoAt(0), NULL,
|
||||
hostInterface);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds or runs the program to debug, depending on the command line options.
|
||||
* @param options The parsed command line options.
|
||||
* @param _info The info for the program to fill in. Will only be filled in
|
||||
* if successful.
|
||||
* @return \c true, if the program has been found or ran.
|
||||
*/
|
||||
static bool
|
||||
get_debugged_program(const Options& options, DebuggedProgramInfo& _info)
|
||||
{
|
||||
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 false;
|
||||
}
|
||||
|
||||
team = thread;
|
||||
// main thread ID == team ID
|
||||
stopInMain = true;
|
||||
}
|
||||
|
||||
// no parameters given, prompt the user to attach to a team
|
||||
if (team < 0 && thread < 0)
|
||||
return false;
|
||||
|
||||
// no team, but a thread -- get team
|
||||
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 \"%" B_PRId32
|
||||
"\": %s\n", thread, strerror(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
team = threadInfo.team;
|
||||
}
|
||||
printf("team: %" B_PRId32 ", thread: %" B_PRId32 "\n", team, thread);
|
||||
|
||||
_info.commandLineArgc = options.commandLineArgc;
|
||||
_info.commandLineArgv = options.commandLineArgv;
|
||||
_info.team = team;
|
||||
_info.thread = thread;
|
||||
_info.stopInMain = stopInMain;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TeamDebugger for the given team. If userInterface is given,
|
||||
* that user interface is used (the caller retains its reference), otherwise
|
||||
* a graphical user interface is created.
|
||||
*/
|
||||
static TeamDebugger*
|
||||
start_team_debugger(team_id teamID, SettingsManager* settingsManager,
|
||||
TeamDebugger::Listener* listener, thread_id threadID = -1,
|
||||
int commandLineArgc = 0, const char* const* commandLineArgv = NULL,
|
||||
bool stopInMain = false, UserInterface* userInterface = NULL,
|
||||
status_t* _result = NULL)
|
||||
{
|
||||
if (teamID < 0)
|
||||
return NULL;
|
||||
|
||||
BReference<UserInterface> userInterfaceReference;
|
||||
if (userInterface == NULL) {
|
||||
userInterface = new(std::nothrow) GraphicalUserInterface;
|
||||
if (userInterface == NULL) {
|
||||
// TODO: Notify the user!
|
||||
fprintf(stderr, "Error: Out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
userInterfaceReference.SetTo(userInterface, true);
|
||||
}
|
||||
|
||||
BReference<DebuggerInterface> interfaceReference;
|
||||
DebuggerInterface* debuggerInterface
|
||||
= new(std::nothrow) LocalDebuggerInterface(teamID);
|
||||
if (debuggerInterface == NULL)
|
||||
return NULL;
|
||||
interfaceReference.SetTo(debuggerInterface, true);
|
||||
|
||||
if (debuggerInterface->Init() != B_OK)
|
||||
return NULL;
|
||||
|
||||
status_t error = B_NO_MEMORY;
|
||||
|
||||
TeamDebugger* debugger = new(std::nothrow) TeamDebugger(listener,
|
||||
userInterface, settingsManager);
|
||||
if (debugger != NULL) {
|
||||
error = debugger->Init(debuggerInterface, threadID, commandLineArgc,
|
||||
commandLineArgv, stopInMain);
|
||||
}
|
||||
|
||||
if (error != B_OK) {
|
||||
printf("Error: debugger for team %" B_PRId32 " failed to init: %s!\n",
|
||||
teamID, strerror(error));
|
||||
delete debugger;
|
||||
debugger = NULL;
|
||||
} else
|
||||
printf("debugger for team %" B_PRId32 " created and initialized "
|
||||
"successfully!\n", teamID);
|
||||
|
||||
if (_result != NULL)
|
||||
*_result = error;
|
||||
return debugger;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Debugger application class
|
||||
|
||||
|
||||
class Debugger : public BApplication, private TeamDebugger::Listener {
|
||||
class Debugger : public BApplication {
|
||||
public:
|
||||
Debugger();
|
||||
~Debugger();
|
||||
@ -359,27 +253,15 @@ public:
|
||||
virtual void ArgvReceived(int32 argc, char** argv);
|
||||
|
||||
private:
|
||||
typedef BObjectList<TeamDebugger> TeamDebuggerList;
|
||||
|
||||
private:
|
||||
// TeamDebugger::Listener
|
||||
virtual void TeamDebuggerStarted(TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerRestartRequested(
|
||||
TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerQuit(TeamDebugger* debugger);
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void Quit();
|
||||
|
||||
TeamDebugger* _FindTeamDebugger(team_id teamID) const;
|
||||
|
||||
status_t _StartNewTeam(const char* path, const char* args);
|
||||
status_t _StartOrFindTeam(Options& options);
|
||||
private:
|
||||
status_t _StartNewTeam(TargetHostInterface* interface,
|
||||
const char* teamPath, const char* args);
|
||||
|
||||
private:
|
||||
SettingsManager fSettingsManager;
|
||||
TeamDebuggerList fTeamDebuggers;
|
||||
int32 fRunningTeamDebuggers;
|
||||
TeamsWindow* fTeamsWindow;
|
||||
StartTeamWindow* fStartTeamWindow;
|
||||
};
|
||||
@ -388,34 +270,20 @@ private:
|
||||
// #pragma mark - CliDebugger
|
||||
|
||||
|
||||
class CliDebugger : private TeamDebugger::Listener {
|
||||
class CliDebugger {
|
||||
public:
|
||||
CliDebugger();
|
||||
~CliDebugger();
|
||||
|
||||
bool Run(const Options& options);
|
||||
|
||||
private:
|
||||
// TeamDebugger::Listener
|
||||
virtual void TeamDebuggerStarted(TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerRestartRequested(
|
||||
TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerQuit(TeamDebugger* debugger);
|
||||
};
|
||||
|
||||
|
||||
class ReportDebugger : private TeamDebugger::Listener {
|
||||
class ReportDebugger {
|
||||
public:
|
||||
ReportDebugger();
|
||||
~ReportDebugger();
|
||||
bool Run(const Options& options);
|
||||
|
||||
private:
|
||||
// TeamDebugger::Listener
|
||||
virtual void TeamDebuggerStarted(TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerRestartRequested(
|
||||
TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerQuit(TeamDebugger* debugger);
|
||||
};
|
||||
|
||||
|
||||
@ -425,7 +293,6 @@ private:
|
||||
Debugger::Debugger()
|
||||
:
|
||||
BApplication(kDebuggerSignature),
|
||||
fRunningTeamDebuggers(0),
|
||||
fTeamsWindow(NULL),
|
||||
fStartTeamWindow(NULL)
|
||||
{
|
||||
@ -437,6 +304,7 @@ Debugger::~Debugger()
|
||||
ValueHandlerRoster::DeleteDefault();
|
||||
TypeHandlerRoster::DeleteDefault();
|
||||
ImageDebugLoadingStateHandlerRoster::DeleteDefault();
|
||||
TargetHostInterfaceRoster::DeleteDefault();
|
||||
}
|
||||
|
||||
|
||||
@ -480,9 +348,14 @@ Debugger::MessageReceived(BMessage* message)
|
||||
}
|
||||
case MSG_SHOW_START_TEAM_WINDOW:
|
||||
{
|
||||
TargetHostInterface* hostInterface;
|
||||
if (message->FindPointer("interface",
|
||||
reinterpret_cast<void**>(&hostInterface)) != B_OK) {
|
||||
break;
|
||||
}
|
||||
BMessenger messenger(fStartTeamWindow);
|
||||
if (!messenger.IsValid()) {
|
||||
fStartTeamWindow = StartTeamWindow::Create();
|
||||
fStartTeamWindow = StartTeamWindow::Create(hostInterface);
|
||||
if (fStartTeamWindow == NULL)
|
||||
break;
|
||||
fStartTeamWindow->Show();
|
||||
@ -497,56 +370,45 @@ Debugger::MessageReceived(BMessage* message)
|
||||
}
|
||||
case MSG_DEBUG_THIS_TEAM:
|
||||
{
|
||||
int32 teamID;
|
||||
team_id teamID;
|
||||
if (message->FindInt32("team", &teamID) != B_OK)
|
||||
break;
|
||||
|
||||
start_team_debugger(teamID, &fSettingsManager, this);
|
||||
TargetHostInterface* interface;
|
||||
if (message->FindPointer("interface", reinterpret_cast<void**>(
|
||||
&interface)) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
TeamDebuggerOptions options;
|
||||
options.settingsManager = &fSettingsManager;
|
||||
options.team = teamID;
|
||||
status_t error = interface->StartTeamDebugger(options);
|
||||
if (error != B_OK) {
|
||||
// TODO: notify user.
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MSG_START_NEW_TEAM:
|
||||
{
|
||||
TargetHostInterface* interface;
|
||||
if (message->FindPointer("interface", reinterpret_cast<void**>(
|
||||
&interface)) != B_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
const char* teamPath = NULL;
|
||||
const char* args = NULL;
|
||||
|
||||
message->FindString("path", &teamPath);
|
||||
message->FindString("arguments", &args);
|
||||
|
||||
status_t result = _StartNewTeam(teamPath, args);
|
||||
status_t result = _StartNewTeam(interface, teamPath, args);
|
||||
BMessage reply;
|
||||
reply.AddInt32("status", result);
|
||||
message->SendReply(&reply);
|
||||
break;
|
||||
}
|
||||
case MSG_TEAM_RESTART_REQUESTED:
|
||||
{
|
||||
int32 teamID;
|
||||
if (message->FindInt32("team", &teamID) != B_OK)
|
||||
break;
|
||||
TeamDebugger* debugger = _FindTeamDebugger(teamID);
|
||||
if (debugger == NULL)
|
||||
break;
|
||||
|
||||
Options options;
|
||||
options.commandLineArgc = debugger->ArgumentCount();
|
||||
options.commandLineArgv = debugger->Arguments();
|
||||
|
||||
status_t result = _StartOrFindTeam(options);
|
||||
if (result == B_OK)
|
||||
debugger->PostMessage(B_QUIT_REQUESTED);
|
||||
|
||||
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;
|
||||
@ -557,8 +419,10 @@ Debugger::MessageReceived(BMessage* message)
|
||||
void
|
||||
Debugger::ReadyToRun()
|
||||
{
|
||||
if (fRunningTeamDebuggers == 0)
|
||||
PostMessage(MSG_SHOW_TEAMS_WINDOW);
|
||||
TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default();
|
||||
AutoLocker<TargetHostInterfaceRoster> lock(roster);
|
||||
if (roster->CountRunningTeamDebuggers() == 0)
|
||||
PostMessage(MSG_SHOW_TEAMS_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
@ -571,51 +435,13 @@ Debugger::ArgvReceived(int32 argc, char** argv)
|
||||
return;
|
||||
}
|
||||
|
||||
_StartOrFindTeam(options);
|
||||
TargetHostInterface* hostInterface
|
||||
= TargetHostInterfaceRoster::Default()->ActiveInterfaceAt(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Debugger::TeamDebuggerStarted(TeamDebugger* debugger)
|
||||
{
|
||||
printf("debugger for team %" B_PRId32 " started...\n", debugger->TeamID());
|
||||
|
||||
// Note: see TeamDebuggerQuit() note about locking
|
||||
AutoLocker<Debugger> 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 %" B_PRId32 " quit.\n", debugger->TeamID());
|
||||
|
||||
AutoLocker<Debugger> locker(this);
|
||||
fTeamDebuggers.RemoveItem(debugger);
|
||||
locker.Unlock();
|
||||
|
||||
if (debugger->Thread() >= 0) {
|
||||
BMessage message(MSG_TEAM_DEBUGGER_QUIT);
|
||||
message.AddInt32("thread", debugger->Thread());
|
||||
PostMessage(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Debugger::TeamDebuggerRestartRequested(TeamDebugger* debugger)
|
||||
{
|
||||
BMessage message(MSG_TEAM_RESTART_REQUESTED);
|
||||
message.AddInt32("team", debugger->TeamID());
|
||||
PostMessage(&message);
|
||||
TeamDebuggerOptions debuggerOptions;
|
||||
set_debugger_options_from_options(debuggerOptions, options);
|
||||
debuggerOptions.settingsManager = &fSettingsManager;
|
||||
hostInterface->StartTeamDebugger(debuggerOptions);
|
||||
}
|
||||
|
||||
|
||||
@ -639,27 +465,17 @@ Debugger::QuitRequested()
|
||||
void
|
||||
Debugger::Quit()
|
||||
{
|
||||
TargetHostInterfaceRoster* roster = TargetHostInterfaceRoster::Default();
|
||||
AutoLocker<TargetHostInterfaceRoster> lock(roster);
|
||||
// don't quit before all team debuggers have been quit
|
||||
if (fRunningTeamDebuggers <= 0 && fTeamsWindow == NULL)
|
||||
if (roster->CountRunningTeamDebuggers() == 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;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Debugger::_StartNewTeam(const char* path, const char* args)
|
||||
Debugger::_StartNewTeam(TargetHostInterface* interface, const char* path,
|
||||
const char* args)
|
||||
{
|
||||
if (path == NULL)
|
||||
return B_BAD_VALUE;
|
||||
@ -672,7 +488,8 @@ Debugger::_StartNewTeam(const char* path, const char* args)
|
||||
ArgumentVector argVector;
|
||||
argVector.Parse(data.String());
|
||||
|
||||
Options options;
|
||||
TeamDebuggerOptions options;
|
||||
options.settingsManager = &fSettingsManager;
|
||||
options.commandLineArgc = argVector.ArgumentCount();
|
||||
if (options.commandLineArgc <= 0)
|
||||
return B_BAD_VALUE;
|
||||
@ -682,31 +499,11 @@ Debugger::_StartNewTeam(const char* path, const char* args)
|
||||
options.commandLineArgv = argv;
|
||||
MemoryDeleter deleter(argv);
|
||||
|
||||
return _StartOrFindTeam(options);
|
||||
}
|
||||
status_t error = interface->StartTeamDebugger(options);
|
||||
if (error == B_OK)
|
||||
deleter.Detach();
|
||||
|
||||
|
||||
status_t
|
||||
Debugger::_StartOrFindTeam(Options& options)
|
||||
{
|
||||
DebuggedProgramInfo programInfo;
|
||||
if (!get_debugged_program(options, programInfo))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
TeamDebugger* debugger = _FindTeamDebugger(programInfo.team);
|
||||
if (debugger != NULL) {
|
||||
printf("There's already a debugger for team: %" B_PRId32 "\n",
|
||||
programInfo.team);
|
||||
debugger->Activate();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t result;
|
||||
start_team_debugger(programInfo.team, &fSettingsManager, this,
|
||||
programInfo.thread, programInfo.commandLineArgc,
|
||||
programInfo.commandLineArgv, programInfo.stopInMain, NULL, &result);
|
||||
|
||||
return result;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@ -756,18 +553,20 @@ CliDebugger::Run(const Options& options)
|
||||
}
|
||||
BReference<UserInterface> userInterfaceReference(userInterface, true);
|
||||
|
||||
// get/run the program to be debugged and start the team debugger
|
||||
DebuggedProgramInfo programInfo;
|
||||
if (!get_debugged_program(options, programInfo))
|
||||
return false;
|
||||
|
||||
TeamDebugger* teamDebugger = start_team_debugger(programInfo.team,
|
||||
&settingsManager, this, programInfo.thread,
|
||||
programInfo.commandLineArgc, programInfo.commandLineArgv,
|
||||
programInfo.stopInMain, userInterface);
|
||||
if (teamDebugger == NULL)
|
||||
// TODO: once we support specifying a remote interface via command line
|
||||
// args, this needs to be adjusted. For now, always assume actions
|
||||
// are being taken via the local interface.
|
||||
TargetHostInterface* hostInterface
|
||||
= TargetHostInterfaceRoster::Default()->ActiveInterfaceAt(0);
|
||||
|
||||
TeamDebuggerOptions debuggerOptions;
|
||||
set_debugger_options_from_options(debuggerOptions, options);
|
||||
debuggerOptions.userInterface = userInterface;
|
||||
error = hostInterface->StartTeamDebugger(debuggerOptions);
|
||||
if (error != B_OK)
|
||||
return false;
|
||||
|
||||
TeamDebugger* teamDebugger = hostInterface->TeamDebuggerAt(0);
|
||||
thread_id teamDebuggerThread = teamDebugger->Thread();
|
||||
|
||||
// run the input loop
|
||||
@ -780,25 +579,6 @@ CliDebugger::Run(const Options& options)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CliDebugger::TeamDebuggerStarted(TeamDebugger* debugger)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CliDebugger::TeamDebuggerRestartRequested(TeamDebugger* debugger)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CliDebugger::TeamDebuggerQuit(TeamDebugger* debugger)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ReportDebugger
|
||||
|
||||
|
||||
@ -840,18 +620,17 @@ ReportDebugger::Run(const Options& options)
|
||||
}
|
||||
BReference<UserInterface> userInterfaceReference(userInterface, true);
|
||||
|
||||
// get/run the program to be debugged and start the team debugger
|
||||
DebuggedProgramInfo programInfo;
|
||||
if (!get_debugged_program(options, programInfo))
|
||||
return false;
|
||||
|
||||
TeamDebugger* teamDebugger = start_team_debugger(programInfo.team,
|
||||
&settingsManager, this, programInfo.thread,
|
||||
programInfo.commandLineArgc, programInfo.commandLineArgv,
|
||||
programInfo.stopInMain, userInterface);
|
||||
if (teamDebugger == NULL)
|
||||
TargetHostInterface* hostInterface
|
||||
= TargetHostInterfaceRoster::Default()->ActiveInterfaceAt(0);
|
||||
|
||||
TeamDebuggerOptions debuggerOptions;
|
||||
set_debugger_options_from_options(debuggerOptions, options);
|
||||
debuggerOptions.userInterface = userInterface;
|
||||
error = hostInterface->StartTeamDebugger(debuggerOptions);
|
||||
if (error != B_OK)
|
||||
return false;
|
||||
|
||||
TeamDebugger* teamDebugger = hostInterface->TeamDebuggerAt(0);
|
||||
thread_id teamDebuggerThread = teamDebugger->Thread();
|
||||
|
||||
// run the input loop
|
||||
@ -864,24 +643,6 @@ ReportDebugger::Run(const Options& options)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ReportDebugger::TeamDebuggerStarted(TeamDebugger* debugger)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ReportDebugger::TeamDebuggerRestartRequested(TeamDebugger* debugger)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ReportDebugger::TeamDebuggerQuit(TeamDebugger* debugger)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
@ -55,6 +55,8 @@ public:
|
||||
{ return fCommandLineArgc; }
|
||||
const char** Arguments() const
|
||||
{ return fCommandLineArgv; }
|
||||
SettingsManager* GetSettingsManager() const
|
||||
{ return fSettingsManager; }
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
|
@ -5,12 +5,37 @@
|
||||
|
||||
#include "TargetHostInterface.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "DebuggerInterface.h"
|
||||
#include "GraphicalUserInterface.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "TeamDebugger.h"
|
||||
|
||||
|
||||
// #pragma mark - TeamDebuggerOptions
|
||||
|
||||
|
||||
TeamDebuggerOptions::TeamDebuggerOptions()
|
||||
:
|
||||
commandLineArgc(0),
|
||||
commandLineArgv(NULL),
|
||||
team(-1),
|
||||
thread(-1),
|
||||
settingsManager(NULL),
|
||||
userInterface(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - TargetHostInterface
|
||||
|
||||
|
||||
TargetHostInterface::TargetHostInterface()
|
||||
:
|
||||
BReferenceable(),
|
||||
BLooper(),
|
||||
fTeamDebuggers(20, false)
|
||||
{
|
||||
}
|
||||
@ -21,10 +46,40 @@ TargetHostInterface::~TargetHostInterface()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::SetName(const BString& name)
|
||||
status_t
|
||||
TargetHostInterface::StartTeamDebugger(const TeamDebuggerOptions& options)
|
||||
{
|
||||
fName = name;
|
||||
// we only want to stop in main for teams we're responsible for
|
||||
// creating ourselves.
|
||||
bool stopInMain = options.commandLineArgv != NULL;
|
||||
team_id team = options.team;
|
||||
thread_id thread = options.thread;
|
||||
|
||||
AutoLocker<TargetHostInterface> interfaceLocker(this);
|
||||
if (options.commandLineArgc > 0) {
|
||||
status_t error = CreateTeam(options.commandLineArgc,
|
||||
options.commandLineArgv, team);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
thread = team;
|
||||
}
|
||||
|
||||
if (team < 0 && thread < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (team < 0) {
|
||||
status_t error = FindTeamByThread(thread, team);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
TeamDebugger* debugger = FindTeamDebugger(team);
|
||||
if (debugger != NULL) {
|
||||
debugger->Activate();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return _StartTeamDebugger(team, options, stopInMain);
|
||||
}
|
||||
|
||||
|
||||
@ -69,6 +124,133 @@ TargetHostInterface::RemoveTeamDebugger(TeamDebugger* debugger)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::Quit()
|
||||
{
|
||||
if (fTeamDebuggers.CountItems() == 0)
|
||||
BLooper::Quit();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_TEAM_DEBUGGER_QUIT:
|
||||
{
|
||||
thread_id thread;
|
||||
if (message->FindInt32("thread", &thread) == B_OK)
|
||||
wait_for_thread(thread, NULL);
|
||||
break;
|
||||
}
|
||||
case MSG_TEAM_RESTART_REQUESTED:
|
||||
{
|
||||
int32 teamID;
|
||||
if (message->FindInt32("team", &teamID) != B_OK)
|
||||
break;
|
||||
|
||||
TeamDebugger* debugger = FindTeamDebugger(teamID);
|
||||
|
||||
TeamDebuggerOptions options;
|
||||
options.commandLineArgc = debugger->ArgumentCount();
|
||||
options.commandLineArgv = debugger->Arguments();
|
||||
options.settingsManager = debugger->GetSettingsManager();
|
||||
status_t result = StartTeamDebugger(options);
|
||||
if (result == B_OK)
|
||||
debugger->PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BLooper::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::TeamDebuggerStarted(TeamDebugger* debugger)
|
||||
{
|
||||
AutoLocker<TargetHostInterface> locker(this);
|
||||
AddTeamDebugger(debugger);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::TeamDebuggerRestartRequested(TeamDebugger* debugger)
|
||||
{
|
||||
BMessage message(MSG_TEAM_RESTART_REQUESTED);
|
||||
message.AddInt32("team", debugger->TeamID());
|
||||
PostMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TargetHostInterface::TeamDebuggerQuit(TeamDebugger* debugger)
|
||||
{
|
||||
AutoLocker<TargetHostInterface> interfaceLocker(this);
|
||||
RemoveTeamDebugger(debugger);
|
||||
interfaceLocker.Unlock();
|
||||
|
||||
if (debugger->Thread() >= 0) {
|
||||
BMessage message(MSG_TEAM_DEBUGGER_QUIT);
|
||||
message.AddInt32("thread", debugger->Thread());
|
||||
PostMessage(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TargetHostInterface::_StartTeamDebugger(team_id teamID,
|
||||
const TeamDebuggerOptions& options, bool stopInMain)
|
||||
{
|
||||
BReference<UserInterface> userInterfaceReference;
|
||||
UserInterface* userInterface = options.userInterface;
|
||||
if (userInterface == NULL) {
|
||||
userInterface = new(std::nothrow) GraphicalUserInterface;
|
||||
if (userInterface == NULL) {
|
||||
fprintf(stderr, "Error: Out of memory!\n");
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
userInterfaceReference.SetTo(userInterface, true);
|
||||
}
|
||||
|
||||
thread_id threadID = options.thread;
|
||||
if (options.commandLineArgv != NULL)
|
||||
threadID = teamID;
|
||||
|
||||
DebuggerInterface* interface = NULL;
|
||||
TeamDebugger* debugger = NULL;
|
||||
status_t error = Attach(teamID, options.thread, interface);
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "Error: Failed to attach to team %" B_PRId32 ": %s!\n",
|
||||
teamID, strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
BReference<DebuggerInterface> debuggerInterfaceReference(interface,
|
||||
true);
|
||||
debugger = new(std::nothrow) TeamDebugger(this, userInterface,
|
||||
options.settingsManager);
|
||||
if (debugger != NULL) {
|
||||
error = debugger->Init(interface, threadID,
|
||||
options.commandLineArgc, options.commandLineArgv, stopInMain);
|
||||
}
|
||||
|
||||
if (error != B_OK) {
|
||||
printf("Error: debugger for team %" B_PRId32 " on interface %s failed"
|
||||
" to init: %s!\n", interface->TeamID(), Name(), strerror(error));
|
||||
delete debugger;
|
||||
debugger = NULL;
|
||||
} else {
|
||||
printf("debugger for team %" B_PRId32 " on interface %s created and"
|
||||
" initialized successfully!\n", interface->TeamID(), Name());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ int
|
||||
TargetHostInterface::_CompareDebuggers(const TeamDebugger* a,
|
||||
const TeamDebugger* b)
|
||||
|
@ -6,26 +6,28 @@
|
||||
#define TARGET_HOST_INTERFACE_H
|
||||
|
||||
#include <OS.h>
|
||||
#include <String.h>
|
||||
#include <Looper.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
|
||||
#include "TeamDebugger.h"
|
||||
|
||||
|
||||
class DebuggerInterface;
|
||||
class Settings;
|
||||
class SettingsManager;
|
||||
class TargetHost;
|
||||
class TeamDebugger;
|
||||
struct TeamDebuggerOptions;
|
||||
class UserInterface;
|
||||
|
||||
|
||||
class TargetHostInterface : public BReferenceable {
|
||||
class TargetHostInterface : public BLooper, private TeamDebugger::Listener {
|
||||
public:
|
||||
TargetHostInterface();
|
||||
virtual ~TargetHostInterface();
|
||||
|
||||
const BString& Name() const { return fName; }
|
||||
void SetName(const BString& name);
|
||||
|
||||
status_t StartTeamDebugger(const TeamDebuggerOptions& options);
|
||||
|
||||
int32 CountTeamDebuggers() const;
|
||||
TeamDebugger* TeamDebuggerAt(int32 index) const;
|
||||
@ -36,18 +38,35 @@ public:
|
||||
virtual status_t Init(Settings* settings) = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
virtual bool IsLocal() const = 0;
|
||||
virtual bool Connected() const = 0;
|
||||
|
||||
virtual TargetHost* GetTargetHost() = 0;
|
||||
|
||||
virtual status_t Attach(team_id id, thread_id threadID,
|
||||
DebuggerInterface*& _interface) = 0;
|
||||
DebuggerInterface*& _interface) const = 0;
|
||||
|
||||
virtual status_t CreateTeam(int commandLineArgc,
|
||||
const char* const* arguments,
|
||||
DebuggerInterface*& _interface) = 0;
|
||||
team_id& _teamID) const = 0;
|
||||
virtual status_t FindTeamByThread(thread_id thread,
|
||||
team_id& _teamID) const = 0;
|
||||
|
||||
// BLooper
|
||||
virtual void Quit();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
// TeamDebugger::Listener
|
||||
virtual void TeamDebuggerStarted(TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerRestartRequested(
|
||||
TeamDebugger* debugger);
|
||||
virtual void TeamDebuggerQuit(TeamDebugger* debugger);
|
||||
|
||||
private:
|
||||
status_t _StartTeamDebugger(team_id teamID,
|
||||
const TeamDebuggerOptions& options,
|
||||
bool stopInMain);
|
||||
static int _CompareDebuggers(const TeamDebugger* a,
|
||||
const TeamDebugger* b);
|
||||
static int _FindDebuggerByKey(const team_id* team,
|
||||
@ -56,9 +75,19 @@ private:
|
||||
typedef BObjectList<TeamDebugger> TeamDebuggerList;
|
||||
|
||||
private:
|
||||
BString fName;
|
||||
TeamDebuggerList fTeamDebuggers;
|
||||
};
|
||||
|
||||
|
||||
struct TeamDebuggerOptions {
|
||||
TeamDebuggerOptions();
|
||||
int commandLineArgc;
|
||||
const char* const* commandLineArgv;
|
||||
team_id team;
|
||||
thread_id thread;
|
||||
SettingsManager* settingsManager;
|
||||
UserInterface* userInterface;
|
||||
};
|
||||
|
||||
|
||||
#endif // TARGET_HOST_INTERFACE_H
|
||||
|
@ -130,12 +130,13 @@ TargetHostInterfaceRoster::CreateInterface(TargetHostInterfaceInfo* info,
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
BReference<TargetHostInterface> interfaceReference(interface, true);
|
||||
if (!fActiveInterfaces.AddItem(interface))
|
||||
error = interface->Run();
|
||||
if (error < B_OK || !fActiveInterfaces.AddItem(interface)) {
|
||||
delete interface;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
_interface = interface;
|
||||
interfaceReference.Detach();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -153,3 +154,15 @@ TargetHostInterfaceRoster::ActiveInterfaceAt(int32 index) const
|
||||
return fActiveInterfaces.ItemAt(index);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
TargetHostInterfaceRoster::CountRunningTeamDebuggers() const
|
||||
{
|
||||
int32 total = 0;
|
||||
for (int32 i = 0; TargetHostInterface* interface = ActiveInterfaceAt(i);
|
||||
i++) {
|
||||
total += interface->CountTeamDebuggers();
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ public:
|
||||
int32 CountActiveInterfaces() const;
|
||||
TargetHostInterface* ActiveInterfaceAt(int32 index) const;
|
||||
|
||||
int32 CountRunningTeamDebuggers() const;
|
||||
|
||||
private:
|
||||
typedef BObjectList<TargetHostInterfaceInfo> InfoList;
|
||||
typedef BObjectList<TargetHostInterface> InterfaceList;
|
||||
|
@ -112,6 +112,13 @@ LocalTargetHostInterface::Close()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LocalTargetHostInterface::IsLocal() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LocalTargetHostInterface::Connected() const
|
||||
{
|
||||
@ -128,7 +135,7 @@ LocalTargetHostInterface::GetTargetHost()
|
||||
|
||||
status_t
|
||||
LocalTargetHostInterface::Attach(team_id teamID, thread_id threadID,
|
||||
DebuggerInterface*& _interface)
|
||||
DebuggerInterface*& _interface) const
|
||||
{
|
||||
if (teamID < 0 && threadID < 0)
|
||||
return B_BAD_VALUE;
|
||||
@ -161,13 +168,29 @@ LocalTargetHostInterface::Attach(team_id teamID, thread_id threadID,
|
||||
|
||||
status_t
|
||||
LocalTargetHostInterface::CreateTeam(int commandLineArgc,
|
||||
const char* const* arguments, DebuggerInterface*& _interface)
|
||||
const char* const* arguments, team_id& _teamID) const
|
||||
{
|
||||
thread_id thread = load_program(arguments, commandLineArgc, false);
|
||||
if (thread < 0)
|
||||
return thread;
|
||||
|
||||
return Attach(-1, thread, _interface);
|
||||
// main thread ID == team ID.
|
||||
_teamID = thread;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
LocalTargetHostInterface::FindTeamByThread(thread_id thread,
|
||||
team_id& _teamID) const
|
||||
{
|
||||
thread_info info;
|
||||
status_t error = get_thread_info(thread, &info);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
_teamID = info.team;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,16 +16,20 @@ public:
|
||||
virtual status_t Init(Settings* settings);
|
||||
virtual void Close();
|
||||
|
||||
virtual bool IsLocal() const;
|
||||
virtual bool Connected() const;
|
||||
|
||||
virtual TargetHost* GetTargetHost();
|
||||
|
||||
virtual status_t Attach(team_id id, thread_id threadID,
|
||||
DebuggerInterface*& _interface);
|
||||
DebuggerInterface*& _interface) const;
|
||||
|
||||
virtual status_t CreateTeam(int commandLineArgc,
|
||||
const char* const* arguments,
|
||||
DebuggerInterface*& _interface);
|
||||
team_id& _teamID) const;
|
||||
virtual status_t FindTeamByThread(thread_id thread,
|
||||
team_id& _teamID) const;
|
||||
|
||||
|
||||
private:
|
||||
static status_t _PortLoop(void* arg);
|
||||
|
@ -59,14 +59,13 @@ LocalTargetHostInterfaceInfo::CreateInterface(Settings* settings,
|
||||
if (interface == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
BReference<LocalTargetHostInterface> interfaceReference(interface, true);
|
||||
status_t error = interface->Init(settings);
|
||||
if (error != B_OK)
|
||||
if (error != B_OK) {
|
||||
delete interface;
|
||||
return error;
|
||||
}
|
||||
|
||||
_interface = interface;
|
||||
interfaceReference.Detach();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,6 @@ TeamsListView::TeamsListView(const char* name, team_id currentTeam,
|
||||
fCurrentTeam(currentTeam),
|
||||
fInterface(interface)
|
||||
{
|
||||
fInterface->AcquireReference();
|
||||
AddColumn(new TeamsColumn("Name", 400, 100, 600,
|
||||
B_TRUNCATE_BEGINNING), kNameColumn);
|
||||
AddColumn(new TeamsColumn("ID", 80, 40, 100,
|
||||
@ -290,7 +289,6 @@ TeamsListView::TeamsListView(const char* name, team_id currentTeam,
|
||||
|
||||
TeamsListView::~TeamsListView()
|
||||
{
|
||||
fInterface->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
#include "MessageCodes.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "LocalTargetHostInterface.h"
|
||||
#include "TargetHostInterface.h"
|
||||
#include "TargetHostInterfaceRoster.h"
|
||||
#include "TeamsListView.h"
|
||||
|
||||
|
||||
@ -51,8 +52,6 @@ TeamsWindow::TeamsWindow(SettingsManager* settingsManager)
|
||||
|
||||
TeamsWindow::~TeamsWindow()
|
||||
{
|
||||
if (fTargetHostInterface != NULL)
|
||||
fTargetHostInterface->ReleaseReference();
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +99,7 @@ TeamsWindow::MessageReceived(BMessage* message)
|
||||
if (row != NULL) {
|
||||
BMessage message(MSG_DEBUG_THIS_TEAM);
|
||||
message.AddInt32("team", row->TeamID());
|
||||
message.AddPointer("interface", fTargetHostInterface);
|
||||
be_app_messenger.SendMessage(&message);
|
||||
}
|
||||
break;
|
||||
@ -120,6 +120,14 @@ TeamsWindow::MessageReceived(BMessage* message)
|
||||
break;
|
||||
}
|
||||
|
||||
case MSG_SHOW_START_TEAM_WINDOW:
|
||||
{
|
||||
BMessage startMessage(*message);
|
||||
startMessage.AddPointer("interface", fTargetHostInterface);
|
||||
be_app_messenger.SendMessage(&startMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
@ -146,10 +154,8 @@ TeamsWindow::_Init()
|
||||
BMessage settings;
|
||||
_LoadSettings(settings);
|
||||
|
||||
fTargetHostInterface = new LocalTargetHostInterface();
|
||||
|
||||
if (fTargetHostInterface->Init(NULL) != B_OK)
|
||||
throw std::bad_alloc();
|
||||
fTargetHostInterface = TargetHostInterfaceRoster::Default()
|
||||
->ActiveInterfaceAt(0);
|
||||
|
||||
BRect frame;
|
||||
if (settings.FindRect("teams window frame", &frame) == B_OK) {
|
||||
@ -175,7 +181,7 @@ TeamsWindow::_Init()
|
||||
MSG_TEAM_SELECTION_CHANGED));
|
||||
|
||||
fAttachTeamButton->SetEnabled(false);
|
||||
fCreateTeamButton->SetTarget(be_app);
|
||||
fCreateTeamButton->SetTarget(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2013-2016, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include "StartTeamWindow.h"
|
||||
@ -24,7 +24,7 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
StartTeamWindow::StartTeamWindow()
|
||||
StartTeamWindow::StartTeamWindow(TargetHostInterface* hostInterface)
|
||||
:
|
||||
BWindow(BRect(), "Start new team", B_TITLED_WINDOW,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
||||
@ -34,7 +34,8 @@ StartTeamWindow::StartTeamWindow()
|
||||
fBrowseTeamButton(NULL),
|
||||
fBrowseTeamPanel(NULL),
|
||||
fStartButton(NULL),
|
||||
fCancelButton(NULL)
|
||||
fCancelButton(NULL),
|
||||
fTargetHostInterface(hostInterface)
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,9 +47,9 @@ StartTeamWindow::~StartTeamWindow()
|
||||
|
||||
|
||||
StartTeamWindow*
|
||||
StartTeamWindow::Create()
|
||||
StartTeamWindow::Create(TargetHostInterface* hostInterface)
|
||||
{
|
||||
StartTeamWindow* self = new StartTeamWindow;
|
||||
StartTeamWindow* self = new StartTeamWindow(hostInterface);
|
||||
|
||||
try {
|
||||
self->_Init();
|
||||
@ -141,6 +142,7 @@ StartTeamWindow::MessageReceived(BMessage* message)
|
||||
appMessage.AddString("path", fTeamTextControl->TextView()->Text());
|
||||
appMessage.AddString("arguments", fArgumentsTextControl->TextView()
|
||||
->Text());
|
||||
appMessage.AddPointer("interface", fTargetHostInterface);
|
||||
BMessage reply;
|
||||
be_app_messenger.SendMessage(&appMessage, &reply);
|
||||
status_t error = reply.FindInt32("status");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2013-2016, Rene Gollent, rene@gollent.com.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef START_TEAM_WINDOW_H
|
||||
@ -13,16 +13,18 @@ class BButton;
|
||||
class BFilePanel;
|
||||
class BStringView;
|
||||
class BTextControl;
|
||||
class TargetHostInterface;
|
||||
|
||||
|
||||
class StartTeamWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
StartTeamWindow();
|
||||
StartTeamWindow(
|
||||
TargetHostInterface* hostInterface);
|
||||
|
||||
~StartTeamWindow();
|
||||
|
||||
static StartTeamWindow* Create();
|
||||
static StartTeamWindow* Create(TargetHostInterface* hostInterface);
|
||||
// throws
|
||||
|
||||
|
||||
@ -42,6 +44,7 @@ private:
|
||||
BFilePanel* fBrowseTeamPanel;
|
||||
BButton* fStartButton;
|
||||
BButton* fCancelButton;
|
||||
TargetHostInterface* fTargetHostInterface;
|
||||
};
|
||||
|
||||
#endif // START_TEAM_WINDOW_H
|
||||
|
Loading…
Reference in New Issue
Block a user