diff --git a/bochs/config.cc b/bochs/config.cc index 861758747..497e651b4 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -3776,10 +3776,10 @@ int bx_write_configuration(const char *rc, int overwrite) bx_write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_KEYBOARD), NULL, 0); bx_write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_MOUSE), NULL, 0); bx_write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_SOUNDLOW),"sound", 0); + SIM->save_addon_options(fp); #if BX_USB_DEBUGGER bx_write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_USB_DEBUG), "usb_debug", 0); #endif - SIM->save_addon_options(fp); fclose(fp); return 0; } diff --git a/bochs/configure b/bochs/configure index 1327ead88..cc8666d2c 100755 --- a/bochs/configure +++ b/bochs/configure @@ -26034,7 +26034,7 @@ fi GUI_CXXFLAGS="$GUI_CXXFLAGS \$(X_CFLAGS)" GUI_LINK_OPTS="$GUI_LINK_OPTS \$(GUI_LINK_OPTS_X)" # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then needs_gtk2=1 fi use_gui_console=1 @@ -26060,8 +26060,10 @@ if test "$with_sdl" = yes; then NONPLUGIN_GUI_LINK_OPTS="`sdl-config --libs`" fi # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi if test "$with_win32" != yes -a "$with_wx" != yes; then case $target in @@ -26096,8 +26098,10 @@ if test "$with_sdl2" = yes; then NONPLUGIN_GUI_LINK_OPTS="`sdl2-config --libs`" fi # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi if test "$with_win32" != yes -a "$with_wx" != yes; then case $target in @@ -26329,8 +26333,10 @@ if test "$with_wx" = yes; then ;; esac # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi fi @@ -26659,13 +26665,17 @@ fi USB_DBG_OBJS="" if test "$usb_debugger" = 1; then - if test "$DEFAULT_GUI" = win32 -o "$with_win32" = yes; then + if test "$bx_have_gtk_version" -ge 2; then + USB_DBG_OBJS="usb_debug.o gtk_usb_debug.o" + printf "%s\n" "#define BX_USB_DEBUGGER 1" >>confdefs.h + + elif test "$DEFAULT_GUI" = win32 -o "$with_win32" = yes; then USB_DBG_OBJS="usb_debug.o win32usb.o" printf "%s\n" "#define BX_USB_DEBUGGER 1" >>confdefs.h else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: The USB debugger supported only for Win32 cannot be compiled here, disabling it" >&5 -printf "%s\n" "$as_me: WARNING: The USB debugger supported only for Win32 cannot be compiled here, disabling it" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: The USB debugger cannot be compiled here, disabling it" >&5 +printf "%s\n" "$as_me: WARNING: The USB debugger cannot be compiled here, disabling it" >&2;} printf "%s\n" "#define BX_USB_DEBUGGER 0" >>confdefs.h fi diff --git a/bochs/configure.ac b/bochs/configure.ac index 11663b4b3..1a8dbf513 100644 --- a/bochs/configure.ac +++ b/bochs/configure.ac @@ -2535,7 +2535,7 @@ if test "$with_x11" = yes; then GUI_CXXFLAGS="$GUI_CXXFLAGS \$(X_CFLAGS)" GUI_LINK_OPTS="$GUI_LINK_OPTS \$(GUI_LINK_OPTS_X)" # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then needs_gtk2=1 fi use_gui_console=1 @@ -2560,8 +2560,10 @@ if test "$with_sdl" = yes; then NONPLUGIN_GUI_LINK_OPTS="`sdl-config --libs`" fi # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi if test "$with_win32" != yes -a "$with_wx" != yes; then case $target in @@ -2595,8 +2597,10 @@ if test "$with_sdl2" = yes; then NONPLUGIN_GUI_LINK_OPTS="`sdl2-config --libs`" fi # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi if test "$with_win32" != yes -a "$with_wx" != yes; then case $target in @@ -2771,8 +2775,10 @@ if test "$with_wx" = yes; then ;; esac # The enhanced X debugger depends on GTK2 - if test "$gui_debugger" = 1 -a "$DEFAULT_GUI" != win32; then - needs_gtk2=1 + if test "$DEFAULT_GUI" != win32; then + if test "$gui_debugger" = 1 -o "$usb_debugger" = 1; then + needs_gtk2=1 + fi fi fi @@ -3019,11 +3025,14 @@ AC_SUBST(ENH_DBG_OBJS) USB_DBG_OBJS="" if test "$usb_debugger" = 1; then - if test "$DEFAULT_GUI" = win32 -o "$with_win32" = yes; then + if test "$bx_have_gtk_version" -ge 2; then + USB_DBG_OBJS="usb_debug.o gtk_usb_debug.o" + AC_DEFINE(BX_USB_DEBUGGER, 1) + elif test "$DEFAULT_GUI" = win32 -o "$with_win32" = yes; then USB_DBG_OBJS="usb_debug.o win32usb.o" AC_DEFINE(BX_USB_DEBUGGER, 1) else - AC_MSG_WARN([The USB debugger supported only for Win32 cannot be compiled here, disabling it]) + AC_MSG_WARN([The USB debugger cannot be compiled here, disabling it]) AC_DEFINE(BX_USB_DEBUGGER, 0) fi fi diff --git a/bochs/gui/gtk_usb_debug.cc b/bochs/gui/gtk_usb_debug.cc new file mode 100644 index 000000000..3313685eb --- /dev/null +++ b/bochs/gui/gtk_usb_debug.cc @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2023 Benjamin David Lunt +// Copyright (C) 2003-2024 The Bochs Project +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +#include "bochs.h" +#include "siminterface.h" + +#if BX_USB_DEBUGGER + +#if BX_HAVE_GTK_VERSION == 2 +#define GTK_DISABLE_DEPRECATED +#endif + +#include +#include + +// multithreading using pure posix threads -- not glib threads +void * EventLp(void *data) +{ + gtk_main(); + return NULL; +} + +void MakeGTKthreads() +{ + pthread_t hThread; + pthread_create(&hThread, NULL, EventLp, NULL); +} + +int usb_debug_dialog(int type, int param1, int param2) +{ + static bool first_call = true; + int argc = 1; + char *argv[2], **argvp, buffer[80]; + + + if (first_call) { + if (!SIM->is_wx_selected() && !SIM->has_debug_gui()) { + // you MUST call gtk_init, even with faked arguments, because it inits GDK and Glib + *buffer = 0; // gtk flames out if you pass in a NULL -- sheesh + argv[0] = buffer; // so I really do have to fake up an "argv" list + argv[1] = NULL; + argvp = argv; + if (gtk_init_check(&argc, &argvp) == false) { + fprintf(stderr, "gtk init failed, can not access display?\n"); + return -1; + } + MakeGTKthreads(); + } + first_call = false; + } + GtkWidget* error = gtk_message_dialog_new( + NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, + "GTK version of USB debugger dialog not implemented yet"); + gtk_window_set_title(GTK_WINDOW(error), "WARNING"); + int ret = gtk_dialog_run(GTK_DIALOG(error)); + gtk_widget_destroy(error); + return (ret == GTK_RESPONSE_OK) ? 0 : -1; +} + +#endif diff --git a/bochs/gui/sdl2.cc b/bochs/gui/sdl2.cc index 7cbc105d7..f9fc100bb 100644 --- a/bochs/gui/sdl2.cc +++ b/bochs/gui/sdl2.cc @@ -513,6 +513,10 @@ void bx_sdl2_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y) #endif if (gui_ci) { dialog_caps = BX_GUI_DLG_ALL; +#if BX_USB_DEBUGGER + } else { + dialog_caps |= BX_GUI_DLG_USB; +#endif } sdl_init_done = 1; } diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 09e5f1d80..f31a4b990 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -181,8 +181,8 @@ public: virtual int configuration_interface(const char* name, ci_command_t command); #if BX_USB_DEBUGGER virtual void register_usb_debug_type(int type); - virtual void usb_debug_trigger(int type, int trigger, int wParam, int lParam); - virtual int usb_debug_interface(int type, int wParam, int lParam); + virtual void usb_debug_trigger(int type, int trigger, int param1, int param2); + virtual int usb_debug_interface(int type, int param1, int param2); #endif virtual int begin_simulation(int argc, char *argv[]); virtual int register_runtime_config_handler(void *dev, rt_conf_handler_t handler); @@ -946,18 +946,18 @@ void bx_real_sim_c::register_usb_debug_type(int type) usb_dbg_register_type(type); } -void bx_real_sim_c::usb_debug_trigger(int type, int trigger, int wParam, int lParam) +void bx_real_sim_c::usb_debug_trigger(int type, int trigger, int param1, int param2) { - usb_dbg_trigger(type, trigger, wParam, lParam); + usb_dbg_trigger(type, trigger, param1, param2); } -int bx_real_sim_c::usb_debug_interface(int type, int wParam, int lParam) +int bx_real_sim_c::usb_debug_interface(int type, int param1, int param2) { int retval = -1; if (type != USB_DEBUG_NONE) { set_display_mode(DISP_MODE_CONFIG); - retval = usb_dbg_interface(type, wParam, lParam); + retval = usb_dbg_interface(type, param1, param2); set_display_mode(DISP_MODE_SIM); } return retval; diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 6bdb008ae..7834b5918 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -742,8 +742,8 @@ public: virtual int configuration_interface(const char* name, ci_command_t command) {return -1; } #if BX_USB_DEBUGGER virtual void register_usb_debug_type(int type) {} - virtual void usb_debug_trigger(int type, int trigger, int wParam, int lParam) {} - virtual int usb_debug_interface(int type, int wParam, int lParam) { return -1; } + virtual void usb_debug_trigger(int type, int trigger, int param1, int param2) {} + virtual int usb_debug_interface(int type, int param1, int param2) { return -1; } #endif virtual int begin_simulation(int argc, char *argv[]) {return -1;} virtual int register_runtime_config_handler(void *dev, rt_conf_handler_t handler) {return 0;} diff --git a/bochs/gui/usb_debug.cc b/bochs/gui/usb_debug.cc index 53f939958..0ad307d25 100644 --- a/bochs/gui/usb_debug.cc +++ b/bochs/gui/usb_debug.cc @@ -45,29 +45,27 @@ void usb_dbg_register_type(int type) } } -int usb_dbg_interface(int type, int wParam, int lParam) +int usb_dbg_interface(int type, int param1, int param2) { - if (!bx_gui->has_gui_console()) { - if (SIM->get_param_enum(BXPN_USB_DEBUG_TYPE)->get() > 0) { - // if "start_frame" is 0, do the debug_window - // if "start_frame" is 1, wait for the trigger from the HC - // (set the value to 2, then return, allowing the trigger to envoke it) - // if "start_frame" is 2, the HC triggered the debug - if (SIM->get_param_num(BXPN_USB_DEBUG_START_FRAME)->get() == BX_USB_DEBUG_SOF_SET) { - SIM->get_param_num(BXPN_USB_DEBUG_START_FRAME)->set(BX_USB_DEBUG_SOF_TRIGGER); - bx_gui->set_usbdbg_bitmap(1); - } else { - bx_gui->set_usbdbg_bitmap(0); - if (win32_usb_start(GetForegroundWindow(), type, wParam, lParam) < 0) { - bx_user_quit = 1; + if (SIM->get_param_enum(BXPN_USB_DEBUG_TYPE)->get() > 0) { + // if "start_frame" is 0, do the debug_window + // if "start_frame" is 1, wait for the trigger from the HC + // (set the value to 2, then return, allowing the trigger to envoke it) + // if "start_frame" is 2, the HC triggered the debug + if (SIM->get_param_num(BXPN_USB_DEBUG_START_FRAME)->get() == BX_USB_DEBUG_SOF_SET) { + SIM->get_param_num(BXPN_USB_DEBUG_START_FRAME)->set(BX_USB_DEBUG_SOF_TRIGGER); + bx_gui->set_usbdbg_bitmap(1); + } else { + bx_gui->set_usbdbg_bitmap(0); + if (usb_debug_dialog(type, param1, param2) < 0) { + bx_user_quit = 1; #if !BX_DEBUGGER - bx_atexit(); - SIM->quit_sim(1); + bx_atexit(); + SIM->quit_sim(1); #else - bx_dbg_exit(1); + bx_dbg_exit(1); #endif - return -1; - } + return -1; } } } @@ -75,7 +73,7 @@ int usb_dbg_interface(int type, int wParam, int lParam) } // one of the controllers has triggered a debug item. -void usb_dbg_trigger(int type, int trigger, int wParam, int lParam) +void usb_dbg_trigger(int type, int trigger, int param1, int param2) { if ((usb_debug_type == USB_DEBUG_NONE) || (type != usb_debug_type)) return; @@ -86,7 +84,7 @@ void usb_dbg_trigger(int type, int trigger, int wParam, int lParam) case USB_DEBUG_FRAME: num_trigger = SIM->get_param_num(BXPN_USB_DEBUG_START_FRAME); if (num_trigger && (num_trigger->get() == BX_USB_DEBUG_SOF_TRIGGER)) { - SIM->usb_debug_interface(USB_DEBUG_FRAME, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_FRAME, param1, param2); num_trigger->set(BX_USB_DEBUG_SOF_SET); } break; @@ -94,31 +92,31 @@ void usb_dbg_trigger(int type, int trigger, int wParam, int lParam) case USB_DEBUG_COMMAND: bool_trigger = SIM->get_param_bool(BXPN_USB_DEBUG_DOORBELL); if (bool_trigger && bool_trigger->get()) - SIM->usb_debug_interface(USB_DEBUG_COMMAND, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_COMMAND, param1, param2); break; case USB_DEBUG_EVENT: bool_trigger = SIM->get_param_bool(BXPN_USB_DEBUG_EVENT); if (bool_trigger && bool_trigger->get()) - SIM->usb_debug_interface(USB_DEBUG_EVENT, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_EVENT, param1, param2); break; case USB_DEBUG_NONEXIST: bool_trigger = SIM->get_param_bool(BXPN_USB_DEBUG_NON_EXIST); if (bool_trigger && bool_trigger->get()) - SIM->usb_debug_interface(USB_DEBUG_NONEXIST, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_NONEXIST, param1, param2); break; case USB_DEBUG_RESET: bool_trigger = SIM->get_param_bool(BXPN_USB_DEBUG_RESET); if (bool_trigger && bool_trigger->get()) - SIM->usb_debug_interface(USB_DEBUG_RESET, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_RESET, param1, param2); break; case USB_DEBUG_ENABLE: bool_trigger = SIM->get_param_bool(BXPN_USB_DEBUG_ENABLE); if (bool_trigger && bool_trigger->get()) - SIM->usb_debug_interface(USB_DEBUG_ENABLE, wParam, lParam); + SIM->usb_debug_interface(USB_DEBUG_ENABLE, param1, param2); break; } } diff --git a/bochs/gui/usb_debug.h b/bochs/gui/usb_debug.h index 906ef34b8..01025c502 100644 --- a/bochs/gui/usb_debug.h +++ b/bochs/gui/usb_debug.h @@ -28,11 +28,11 @@ extern int usb_debug_type; void usb_dbg_register_type(int type); -int usb_dbg_interface(int type, int wParam, int lParam); +int usb_dbg_interface(int type, int param1, int param2); -void usb_dbg_trigger(int type, int trigger, int wParam, int lParam); +void usb_dbg_trigger(int type, int trigger, int param1, int param2); -int win32_usb_start(HWND hwnd, int break_type, int wParam, int lParam); +int usb_debug_dialog(int break_type, int param1, int param2); #endif // BX_USB_DEBUGGER #endif // BX_USB_DEBUG_H diff --git a/bochs/gui/win32usb.cc b/bochs/gui/win32usb.cc index 4cb2da828..6662898e0 100644 --- a/bochs/gui/win32usb.cc +++ b/bochs/gui/win32usb.cc @@ -70,9 +70,14 @@ HFONT hTreeViewFont; // Common to all HC types // +HWND getBochsWindow() +{ + return GetForegroundWindow(); // FIXME +} + // return 0 to continue with emulation // return -1 to quit emulation -int win32_usb_start(HWND hwnd, int break_type, int wParam, int lParam) +int usb_debug_dialog(int break_type, int param1, int param2) { char str[COMMON_STR_SIZE]; int ret; @@ -84,7 +89,7 @@ int win32_usb_start(HWND hwnd, int break_type, int wParam, int lParam) host_param = SIM->get_param(hc_param_str[usb_debug_type]); if ((host_param == NULL) || !SIM->get_param_bool("enabled", host_param)->get()) { sprintf(str, "Selected USB HC not enabled: %s", debug_type->get_choice(usb_debug_type)); - MessageBox(hwnd, str, NULL, MB_ICONINFORMATION); + MessageBox(getBochsWindow(), str, NULL, MB_ICONINFORMATION); return 0; } @@ -103,7 +108,7 @@ int win32_usb_start(HWND hwnd, int break_type, int wParam, int lParam) DEFAULT_PITCH | FF_DONTCARE, TEXT("Courier New")); } if (hTreeViewFont == NULL) { - MessageBox(hwnd, "Could not create a font for the Tree View Control", NULL, MB_ICONINFORMATION); + MessageBox(getBochsWindow(), "Could not create a font for the Tree View Control", NULL, MB_ICONINFORMATION); return 0; } @@ -116,9 +121,9 @@ int win32_usb_start(HWND hwnd, int break_type, int wParam, int lParam) // create the dialog and wait for it to return g_params.type = usb_debug_type; g_params.break_type = break_type; - g_params.wParam = wParam; - g_params.lParam = lParam; - ret = (int) DialogBoxParam(NULL, MAKEINTRESOURCE(dlg_resource[usb_debug_type]), hwnd, + g_params.wParam = param1; + g_params.lParam = param2; + ret = (int) DialogBoxParam(NULL, MAKEINTRESOURCE(dlg_resource[usb_debug_type]), getBochsWindow(), usb_debug_callbacks[usb_debug_type], (LPARAM) 0); // destroy the font DeleteObject(hTreeViewFont); diff --git a/bochs/gui/x.cc b/bochs/gui/x.cc index 4b17ba129..7024b4ec9 100644 --- a/bochs/gui/x.cc +++ b/bochs/gui/x.cc @@ -606,7 +606,7 @@ void bx_x_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y) progname = argv[0]; console.present = 1; -#if (BX_DEBUGGER && BX_DEBUGGER_GUI) || BX_SUPPORT_SOUNDLOW || BX_SUPPORT_VOODOO +#if (BX_DEBUGGER && BX_DEBUGGER_GUI) || BX_SUPPORT_SOUNDLOW || BX_SUPPORT_VOODOO || BX_USB_DEBUGGER // This is only necessary when GTK+ and Xlib are sharing the same // connection. XInitThreads() must finish before any calls to GTK+ // or Xlib are made. @@ -927,6 +927,9 @@ void bx_x_gui_c::specific_init(int argc, char **argv, unsigned headerbar_y) new_gfx_api = 1; new_text_api = 1; dialog_caps |= (BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT | BX_GUI_DLG_CDROM); +#if BX_USB_DEBUGGER + dialog_caps |= BX_GUI_DLG_USB; +#endif } void bx_x_gui_c::handle_events(void)