diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 42021137f..b8fc8edc8 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1423,7 +1423,7 @@ public: // for now... void initialize(void); void after_restore_state(void); void register_state(void); -#if BX_WITH_WX +#if BX_WITH_WX && !BX_DEBUGGER_GUI void register_wx_state(void); #endif static Bit64s param_save_handler(void *devptr, bx_param_c *param); diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index 5f7b3b633..9d30ce4b9 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -57,7 +57,7 @@ BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id) srand(time(NULL)); // initialize random generator for RDRAND/RDSEED } -#if BX_WITH_WX +#if BX_WITH_WX && !BX_DEBUGGER_GUI #define IF_SEG_REG_GET(x) \ if (!strcmp(param->get_name(), #x)) { \ @@ -227,12 +227,12 @@ void BX_CPU_C::initialize(void) init_VMCS(); #endif -#if BX_WITH_WX +#if BX_WITH_WX && !BX_DEBUGGER_GUI register_wx_state(); #endif } -#if BX_WITH_WX +#if BX_WITH_WX && !BX_DEBUGGER_GUI void BX_CPU_C::register_wx_state(void) { if (SIM->get_param(BXPN_WX_CPU_STATE) != NULL) { diff --git a/bochs/gui/enh_dbg.cc b/bochs/gui/enh_dbg.cc index e53061fee..45de704cc 100644 --- a/bochs/gui/enh_dbg.cc +++ b/bochs/gui/enh_dbg.cc @@ -3380,8 +3380,13 @@ void ActivateMenuItem (int cmd) void InitDebugDialog() { - DoAllInit(); // non-os-specific init stuff - OSInit(); + DoAllInit(); // non-os-specific init stuff + OSInit(); +} + +void CloseDebugDialog() +{ + CloseDialog(); } #endif diff --git a/bochs/gui/enh_dbg.h b/bochs/gui/enh_dbg.h index 148860626..04b82a7d9 100644 --- a/bochs/gui/enh_dbg.h +++ b/bochs/gui/enh_dbg.h @@ -66,6 +66,7 @@ int GetNextSelectedLI(int listnum, int StartPt); bx_bool OSInit(); void SpecialInit(); +void CloseDialog(); void HitBreak(); void ParseIDText(const char *x); diff --git a/bochs/gui/gtk_enh_dbg_osdep.cc b/bochs/gui/gtk_enh_dbg_osdep.cc index 6ae96b070..55cfb6386 100644 --- a/bochs/gui/gtk_enh_dbg_osdep.cc +++ b/bochs/gui/gtk_enh_dbg_osdep.cc @@ -2334,6 +2334,11 @@ bx_bool OSInit() return TRUE; } +void CloseDialog() +{ + gtk_widget_destroy(window); +} + // recurse displaying each leaf/branch of param_tree -- with values for each leaf void MakeBL(TreeParent *h_P, bx_param_c *p) { diff --git a/bochs/gui/gui.cc b/bochs/gui/gui.cc index e1cc94c05..bb6c8fabb 100644 --- a/bochs/gui/gui.cc +++ b/bochs/gui/gui.cc @@ -1015,4 +1015,10 @@ void bx_gui_c::init_debug_dialog() extern void InitDebugDialog(); InitDebugDialog(); } + +void bx_gui_c::close_debug_dialog() +{ + extern void CloseDebugDialog(); + CloseDebugDialog(); +} #endif diff --git a/bochs/gui/gui.h b/bochs/gui/gui.h index b98624732..03ee8928f 100644 --- a/bochs/gui/gui.h +++ b/bochs/gui/gui.h @@ -158,6 +158,7 @@ public: const char* get_toggle_info(void); #if BX_DEBUGGER && BX_DEBUGGER_GUI void init_debug_dialog(void); + void close_debug_dialog(void); #endif protected: diff --git a/bochs/gui/win32_enh_dbg_osdep.cc b/bochs/gui/win32_enh_dbg_osdep.cc index 033e8f1e7..a7e00c94b 100644 --- a/bochs/gui/win32_enh_dbg_osdep.cc +++ b/bochs/gui/win32_enh_dbg_osdep.cc @@ -1821,6 +1821,11 @@ bx_bool OSInit() return TRUE; } +void CloseDialog() +{ + SendMessage(hY, WM_CLOSE, 0, 0); +} + // recurse displaying each leaf/branch of param_tree -- with values for each leaf void MakeBL(HTREEITEM *h_P, bx_param_c *p) { diff --git a/bochs/gui/wx.cc b/bochs/gui/wx.cc index 139c9ac48..4fec6409c 100644 --- a/bochs/gui/wx.cc +++ b/bochs/gui/wx.cc @@ -121,6 +121,11 @@ static bx_bool wx_hide_ips = 0; #if defined (wxHAS_RAW_KEY_CODES) && defined(__WXGTK__) static Bit32u convertStringToGDKKey (const char *string); #endif +#if BX_DEBUGGER && BX_DEBUGGER_GUI +BxEvent *wx_notify_callback (void *unused, BxEvent *event); +static bxevent_handler old_callback = NULL; +static void *old_callback_arg = NULL; +#endif ////////////////////////////////////////////////////////////// @@ -922,6 +927,20 @@ bx_bool MyPanel::fillBxKeyEvent(wxKeyEvent& wxev, BxKeyEvent& bxev, bx_bool rele // fill in methods of bx_gui ////////////////////////////////////////////////////////////// +#if defined(WIN32) && BX_DEBUGGER && BX_DEBUGGER_GUI +DWORD WINAPI DebugGuiThread(LPVOID) +{ + MSG msg; + + bx_gui->init_debug_dialog(); + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return 0; +} +#endif + void bx_wx_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y) { int b,i,j; @@ -989,6 +1008,22 @@ void bx_wx_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y) } } +#if BX_DEBUGGER && BX_DEBUGGER_GUI + // redirect notify callback to wx specific code + SIM->get_notify_callback(&old_callback, &old_callback_arg); + assert(old_callback != NULL); + SIM->set_notify_callback(wx_notify_callback, NULL); +#ifdef WIN32 + // on Windows the debugger gui must run in a separate thread + DWORD threadID; + CreateThread(NULL, 0, DebugGuiThread, NULL, 0, &threadID); +#else + wxMutexGuiEnter(); + init_debug_dialog(); + wxMutexGuiLeave(); +#endif +#endif + new_gfx_api = 1; dialog_caps = BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT | BX_GUI_DLG_SAVE_RESTORE; } @@ -1640,6 +1675,10 @@ bx_wx_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id) void bx_wx_gui_c::exit(void) { clear_screen(); +#if BX_DEBUGGER && BX_DEBUGGER_GUI + SIM->set_notify_callback(old_callback, old_callback_arg); + close_debug_dialog(); +#endif } void bx_wx_gui_c::mouse_enabled_changed_specific(bx_bool val) @@ -1728,4 +1767,47 @@ static Bit32u convertStringToGDKKey (const char *string) } #endif +#if BX_DEBUGGER && BX_DEBUGGER_GUI + +#include "enh_dbg.h" + +BxEvent *wx_notify_callback(void *unused, BxEvent *event) +{ + switch (event->type) + { + case BX_SYNC_EVT_GET_DBG_COMMAND: + { + debug_cmd = new char[512]; + debug_cmd_ready = 0; + HitBreak(); + while (debug_cmd_ready == 0 && bx_user_quit == 0) + { + if (vgaw_refresh != 0) // is the GUI frontend requesting a VGAW refresh? + SIM->refresh_vga(); + vgaw_refresh = 0; +#ifdef WIN32 + Sleep(10); +#elif BX_HAVE_USLEEP + usleep(10000); +#else + sleep(1); +#endif + } + if (bx_user_quit != 0) { + bx_dbg_exit(0); + } + event->u.debugcmd.command = debug_cmd; + event->retcode = 1; + return event; + } + case BX_ASYNC_EVT_DBG_MSG: + { + ParseIDText(event->u.logmsg.msg); + return event; + } + default: + return (*old_callback)(old_callback_arg, event); + } +} +#endif /* if BX_DEBUGGER && BX_DEBUGGER_GUI */ #endif /* if BX_WITH_WX */ diff --git a/bochs/gui/wxdialog.cc b/bochs/gui/wxdialog.cc index 846051c92..7af039af8 100644 --- a/bochs/gui/wxdialog.cc +++ b/bochs/gui/wxdialog.cc @@ -400,7 +400,7 @@ void AdvancedLogOptionsDialog::ShowHelp() wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this); } -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI ////////////////////////////////////////////////////////////////////// // DebugLogDialog implementation ////////////////////////////////////////////////////////////////////// @@ -1310,6 +1310,7 @@ void ParamDialog::ShowHelp() // - col2: flexgrid // - CR* params +#if !BX_DEBUGGER_GUI // all events go to OnEvent method BEGIN_EVENT_TABLE(CpuRegistersDialog, wxDialog) EVT_BUTTON(-1, CpuRegistersDialog::OnEvent) @@ -1512,6 +1513,7 @@ void CpuRegistersDialog::OnEvent(wxCommandEvent& event) ParamDialog::OnEvent(event); } } +#endif ////////////////////////////////////////////////////////////////////// // FloppyConfigDialog implementation diff --git a/bochs/gui/wxdialog.h b/bochs/gui/wxdialog.h index 0eb8e6565..a86438244 100644 --- a/bochs/gui/wxdialog.h +++ b/bochs/gui/wxdialog.h @@ -168,7 +168,7 @@ DECLARE_EVENT_TABLE() }; -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI //////////////////////////////////////////////////////////////////////////// // DebugLogDialog //////////////////////////////////////////////////////////////////////////// @@ -430,6 +430,7 @@ public: // | [Go] [Stop] [Step] [Step N] N=[____] | // +---------------------------------------------------------+ // +#if !BX_DEBUGGER_GUI class CpuRegistersDialog : public ParamDialog { @@ -482,6 +483,7 @@ public: virtual void CopyParamToGui(); DECLARE_EVENT_TABLE() }; +#endif /************************************************************************** diff --git a/bochs/gui/wxmain.cc b/bochs/gui/wxmain.cc index 998b0e34b..ea5104626 100644 --- a/bochs/gui/wxmain.cc +++ b/bochs/gui/wxmain.cc @@ -202,6 +202,7 @@ extern "C" int libwx_LTX_plugin_init(plugin_t *plugin, plugintype_t type, wxLogDebug(wxT("installing %s as the Bochs GUI"), wxT("wxWidgets")); SIM->get_param_enum(BXPN_SEL_DISPLAY_LIBRARY)->set_enabled(0); MyPanel::OnPluginInit(); +#if !BX_DEBUGGER_GUI bx_list_c *list = new bx_list_c(SIM->get_param("."), "wxdebug", "subtree for the wx debugger" @@ -211,6 +212,7 @@ extern "C" int libwx_LTX_plugin_init(plugin_t *plugin, plugintype_t type, "CPU State" ); cpu->set_options(bx_list_c::USE_TAB_WINDOW); +#endif return 0; // success } @@ -344,9 +346,11 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(ID_Edit_Other, MyFrame::OnEditOther) EVT_MENU(ID_Log_Prefs, MyFrame::OnLogPrefs) EVT_MENU(ID_Log_PrefsDevice, MyFrame::OnLogPrefsDevice) +#if !BX_DEBUGGER_GUI EVT_MENU(ID_Debug_ShowCpu, MyFrame::OnShowCpu) #if BX_DEBUGGER EVT_MENU(ID_Debug_Console, MyFrame::OnDebugLog) +#endif #endif // toolbar events EVT_TOOL(ID_Edit_FD_0, MyFrame::OnToolbarClick) @@ -423,9 +427,11 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, // init variables sim_thread = NULL; start_bochs_times = 0; +#if !BX_DEBUGGER_GUI showCpu = NULL; debugCommand = NULL; debugCommandEvent = NULL; +#endif // set up the gui menuConfiguration = new wxMenu; @@ -466,10 +472,12 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, menuSimulate->Enable(ID_Simulate_PauseResume, FALSE); menuSimulate->Enable(ID_Simulate_Stop, FALSE); +#if !BX_DEBUGGER_GUI menuDebug = new wxMenu; menuDebug->Append(ID_Debug_ShowCpu, wxT("Show &CPU")); #if BX_DEBUGGER menuDebug->Append(ID_Debug_Console, wxT("Debug Console")); +#endif #endif menuLog = new wxMenu; @@ -484,7 +492,9 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, menuBar->Append(menuConfiguration, wxT("&File")); menuBar->Append(menuEdit, wxT("&Edit")); menuBar->Append(menuSimulate, wxT("&Simulate")); +#if !BX_DEBUGGER_GUI menuBar->Append(menuDebug, wxT("&Debug")); +#endif menuBar->Append(menuLog, wxT("&Log")); menuBar->Append(menuHelp, wxT("&Help")); SetMenuBar(menuBar); @@ -539,7 +549,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, SetAutoLayout(TRUE); SetSizer(sz); -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI // create the debug log dialog box immediately so that we can write output // to it. showDebugLog = new DebugLogDialog(this, -1); @@ -810,6 +820,7 @@ void MyFrame::OnLogPrefsDevice(wxCommandEvent& WXUNUSED(event)) // interrupt the simulation, you want to force an update. If you manually // change a parameter, you would force an update. // When simulation is free running, #1 or #2 might make sense. Try #2. +#if !BX_DEBUGGER_GUI void MyFrame::OnShowCpu(wxCommandEvent& WXUNUSED(event)) { if (SIM->get_param(BXPN_WX_CPU0_STATE) == NULL) { @@ -888,6 +899,7 @@ void MyFrame::DebugCommand(const char *cmd) } } #endif +#endif void MyFrame::OnQuit(wxCommandEvent& event) { @@ -931,7 +943,7 @@ void MyFrame::simStatusChanged(StatusChange change, bx_bool popupNotify) { menuSimulate->Enable(ID_Simulate_PauseResume, FALSE); menuSimulate->Enable(ID_Simulate_Stop, FALSE); menuSimulate->SetLabel(ID_Simulate_PauseResume, wxT("&Pause")); -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI showDebugLog->Show(FALSE); #endif // This should only be used if the simulation stops due to error. @@ -1055,7 +1067,7 @@ void MyFrame::OnKillSim(wxCommandEvent& WXUNUSED(event)) // OnSimThreadExit, which also tries to lock sim_thread_lock. // If we grab the lock at this level, deadlock results. wxLogDebug(wxT("OnKillSim()")); -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI // the sim_thread may be waiting for a debugger command. If so, send // it a "quit" DebugCommand("quit"); @@ -1180,9 +1192,11 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event) // all cases should return. sync event handlers MUST send back a // response. async event handlers MUST delete the event. switch (be->type) { +#if !BX_DEBUGGER_GUI case BX_ASYNC_EVT_REFRESH: RefreshDialogs(); break; +#endif case BX_SYNC_EVT_ASK_PARAM: wxLogDebug(wxT("before HandleAskParam")); be->retcode = HandleAskParam(be); @@ -1191,7 +1205,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event) sim_thread->SendSyncResponse(be); wxLogDebug(wxT("after SendSyncResponse")); break; -#if BX_DEBUGGER +#if BX_DEBUGGER && !BX_DEBUGGER_GUI case BX_ASYNC_EVT_DBG_MSG: showDebugLog->AppendText(wxString(be->u.logmsg.msg, wxConvUTF8)); break; @@ -1200,6 +1214,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event) case BX_ASYNC_EVT_LOG_MSG: OnLogMsg(be); break; +#if !BX_DEBUGGER_GUI case BX_SYNC_EVT_GET_DBG_COMMAND: wxLogDebug(wxT("BX_SYNC_EVT_GET_DBG_COMMAND received")); if (debugCommand == NULL) { @@ -1223,6 +1238,7 @@ void MyFrame::OnSim2CIEvent(wxCommandEvent& event) sim_thread->SendSyncResponse(be); } break; +#endif case BX_ASYNC_EVT_QUIT_SIM: wxMessageBox(wxT("Bochs simulation has stopped."), wxT("Bochs Stopped"), wxOK | wxICON_INFORMATION, this); @@ -1352,6 +1368,7 @@ void MyFrame::OnToolbarClick(wxCommandEvent& event) } // warning: This can be called from the simulator thread!!! +#if !BX_DEBUGGER_GUI bool MyFrame::WantRefresh() { bool anyShowing = false; @@ -1363,6 +1380,7 @@ void MyFrame::RefreshDialogs() { if (showCpu!=NULL && showCpu->IsShowing()) showCpu->CopyParamToGui(); } +#endif ////////////////////////////////////////////////////////////////////// // Simulation Thread @@ -1466,11 +1484,13 @@ BxEvent *SimThread::SiminterfaceCallback2(BxEvent *event) return event; } +#if !BX_DEBUGGER_GUI // prune refresh events if the frame is going to ignore them anyway if (event->type == BX_ASYNC_EVT_REFRESH && !theFrame->WantRefresh()) { delete event; return NULL; } +#endif //encapsulate the bxevent in a wxwidgets event wxCommandEvent wxevent(wxEVT_COMMAND_MENU_SELECTED, ID_Sim2CI_Event); diff --git a/bochs/gui/wxmain.h b/bochs/gui/wxmain.h index 44628ad15..2387e4973 100644 --- a/bochs/gui/wxmain.h +++ b/bochs/gui/wxmain.h @@ -58,8 +58,10 @@ enum ID_Simulate_Start, ID_Simulate_PauseResume, ID_Simulate_Stop, +#if !BX_DEBUGGER_GUI ID_Debug_ShowCpu, ID_Debug_Console, +#endif ID_Log_View, ID_Log_Prefs, ID_Log_PrefsDevice, @@ -189,12 +191,14 @@ public: void OnLogPrefs(wxCommandEvent& event); void OnLogPrefsDevice(wxCommandEvent& event); void OnEditATA(wxCommandEvent& event); +#if !BX_DEBUGGER_GUI void OnShowCpu(wxCommandEvent& event); #if BX_DEBUGGER void OnDebugLog(wxCommandEvent& event); void DebugBreak(); void DebugCommand(wxString string); void DebugCommand(const char *cmd); +#endif #endif void editFloppyConfig(int drive); void editFirstCdrom(); @@ -217,6 +221,7 @@ private: wxMenu *menuLog; wxMenu *menuHelp; wxToolBar *bxToolBar; +#if !BX_DEBUGGER_GUI ParamDialog *showCpu; #if BX_DEBUGGER DebugLogDialog *showDebugLog; @@ -224,8 +229,11 @@ private: void RefreshDialogs(); char *debugCommand; // maybe need lock on this BxEvent *debugCommandEvent; // maybe need lock on this +#endif public: +#if !BX_DEBUGGER_GUI bool WantRefresh(); +#endif DECLARE_EVENT_TABLE() }; diff --git a/bochs/wxbochs.rc b/bochs/wxbochs.rc index a5336db8d..5854e16cd 100644 --- a/bochs/wxbochs.rc +++ b/bochs/wxbochs.rc @@ -1,7 +1,7 @@ #include "config.h" icon_bochs ICON build\win32\nsis\bochs.ico #include "wx/msw/wx.rc" -#if BX_WITH_WIN32 +#if BX_WITH_WIN32 || BX_DEBUGGER_GUI #include "win32res.rc" #else #include "bxversion.rc"