diff --git a/bochs/config.cc b/bochs/config.cc index 7bc01989e..43b06ac39 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -250,6 +250,27 @@ void bx_init_usb_options(const char *usb_name, const char *pname, int maxports) enabled->set_dependent_list(deplist); } +void bx_plugin_ctrl_init() +{ + bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL); +#if !BX_PLUGINS + int i = 0; + while (strcmp(bx_builtin_plugins[i].name, "NULL")) { + if (bx_builtin_plugins[i].type == PLUGTYPE_OPTIONAL) { + new bx_param_bool_c(base, bx_builtin_plugins[i].name, "", "", 0); + } + i++; + } +#else + const char *name; + int count = bx_get_plugins_count(PLUGTYPE_OPTIONAL); + for (int i = 0; i < count; i++) { + name = bx_get_plugin_name(PLUGTYPE_OPTIONAL, i); + new bx_param_bool_c(base, name, "", "", 0); + } +#endif +} + void bx_plugin_ctrl_reset(bx_bool init_done) { bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL); @@ -259,18 +280,18 @@ void bx_plugin_ctrl_reset(bx_bool init_done) } SIM->opt_plugin_ctrl("*", 0); } - // add the default set of plugins to the list - new bx_param_bool_c(base, "unmapped", "", "", 1); - new bx_param_bool_c(base, "biosdev", "", "", 1); - new bx_param_bool_c(base, "speaker", "", "", 1); - new bx_param_bool_c(base, "extfpuirq", "", "", 1); - new bx_param_bool_c(base, "parallel", "", "", 1); - new bx_param_bool_c(base, "serial", "", "", 1); + // enable the default set of plugins to be loaded + SIM->get_param_bool("unmapped", base)->set(1); + SIM->get_param_bool("biosdev", base)->set(1); + SIM->get_param_bool("speaker", base)->set(1); + SIM->get_param_bool("extfpuirq", base)->set(1); + SIM->get_param_bool("parallel", base)->set(1); + SIM->get_param_bool("serial", base)->set(1); #if BX_SUPPORT_GAMEPORT - new bx_param_bool_c(base, "gameport", "", "", 1); + SIM->get_param_bool("gameport", base)->set(1); #endif #if BX_SUPPORT_IODEBUG && BX_DEBUGGER - new bx_param_bool_c(base, "iodebug", "", "", 1); + SIM->get_param_bool("iodebug", base)->set(1); #endif SIM->opt_plugin_ctrl("*", 1); } @@ -364,6 +385,7 @@ void bx_init_options() // optional plugin control new bx_list_c(menu, "plugin_ctrl", "Optional Plugin Control"); + bx_plugin_ctrl_init(); // subtree for special menus bx_list_c *special_menus = new bx_list_c(root_param, "menu", ""); diff --git a/bochs/extplugin.h b/bochs/extplugin.h index 113a8d7a7..4c48484b7 100644 --- a/bochs/extplugin.h +++ b/bochs/extplugin.h @@ -46,21 +46,25 @@ typedef void (CDECL *plugin_fini_t)(void); typedef struct _plugin_t { - plugintype_t type; - bx_bool loaded; - bx_bool initialized; #if BX_PLUGINS + char *name; #if defined(WIN32) HINSTANCE handle; #else lt_dlhandle handle; #endif +#else + const char *name; #endif - char *name; + plugintype_t type; plugin_init_t plugin_init; plugin_fini_t plugin_fini; + bool initialized; +#if BX_PLUGINS + bool loaded; struct _plugin_t *next; +#endif } plugin_t; diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 549087b21..582fb95c7 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -1452,31 +1452,33 @@ bool bx_real_sim_c::opt_plugin_ctrl(const char *plugname, bx_bool load) bx_param_bool_c *plugin = (bx_param_bool_c*)plugin_ctrl->get(i); if (load == (bx_bool)plugin->get()) { opt_plugin_ctrl(plugin->get_name(), load); - if (load) i++; - } else { - i++; } + i++; } return 1; } + if (plugin_ctrl->get_by_name(plugname) == NULL) { + BX_PANIC(("Plugin '%s' not found", plugname)); + return 0; + } if (load != PLUG_device_present(plugname)) { if (load) { if (PLUG_load_opt_plugin(plugname)) { - if (plugin_ctrl->get_by_name(plugname) == NULL) { - new bx_param_bool_c(plugin_ctrl, plugname, "", "", 1); - } + SIM->get_param_bool(plugname, plugin_ctrl)->set(1); return 1; } else { // plugin load code panics in this case return 0; } } else { - PLUG_unload_opt_plugin(plugname); - plugin_ctrl->remove(plugname); - return 1; + if (PLUG_unload_opt_plugin(plugname)) { + SIM->get_param_bool(plugname, plugin_ctrl)->set(0); + return 1; + } else { + // plugin load code panics in this case + return 0; + } } - } else if (!load && !PLUG_device_present(plugname)) { - plugin_ctrl->remove(plugname); } return 0; } diff --git a/bochs/gui/textconfig.cc b/bochs/gui/textconfig.cc index 2cf2e64d7..25e48a6fe 100644 --- a/bochs/gui/textconfig.cc +++ b/bochs/gui/textconfig.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 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 @@ -665,7 +665,8 @@ void bx_plugin_ctrl() { Bit32u choice; bx_list_c *plugin_ctrl; - int count; + bx_param_bool_c *plugin; + int i, count; char plugname[512]; while (1) { @@ -679,24 +680,38 @@ void bx_plugin_ctrl() bx_printf("\nNo optional plugins loaded\n"); } else { bx_printf("\nCurrently loaded plugins:"); - for (int i = 0; i < count; i++) { - if (i > 0) bx_printf(","); - bx_printf(" %s", plugin_ctrl->get(i)->get_name()); + for (i = 0; i < count; i++) { + plugin = (bx_param_bool_c*)plugin_ctrl->get(i); + if (plugin->get()) { + if (i > 0) bx_printf(","); + bx_printf(" %s", plugin->get_name()); + } } bx_printf("\n"); + if (choice == 1) { + bx_printf("\nAdditionally available plugins:"); + for (i = 0; i < count; i++) { + plugin = (bx_param_bool_c*)plugin_ctrl->get(i); + if (!plugin->get()) { + if (i > 0) bx_printf(","); + bx_printf(" %s", plugin->get_name()); + } + } + bx_printf("\n"); + } } if (choice == 1) { ask_string("\nEnter the name of the plugin to load.\nTo cancel, type 'none'. [%s] ", "none", plugname); if (strcmp(plugname, "none")) { - if (!SIM->opt_plugin_ctrl(plugname, 1)) { - bx_printf("\nPlugin already loaded.\n"); + if (SIM->opt_plugin_ctrl(plugname, 1)) { + bx_printf("\nLoaded plugin '%s'.\n", plugname); } } } else { ask_string("\nEnter the name of the plugin to unload.\nTo cancel, type 'none'. [%s] ", "none", plugname); if (strcmp(plugname, "none")) { - if (!SIM->opt_plugin_ctrl(plugname, 0)) { - bx_printf("\nNo plugin unloaded.\n"); + if (SIM->opt_plugin_ctrl(plugname, 0)) { + bx_printf("\nUnloaded plugin '%s'.\n", plugname); } } } diff --git a/bochs/gui/win32dialog.cc b/bochs/gui/win32dialog.cc index 5faa3e668..45002398b 100644 --- a/bochs/gui/win32dialog.cc +++ b/bochs/gui/win32dialog.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2003-2020 The Bochs Project +// Copyright (C) 2003-2021 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 @@ -358,6 +358,7 @@ static BOOL CALLBACK PluginCtrlDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARA int count, i; long code; bx_list_c *plugin_ctrl; + bx_param_bool_c *plugin; char plugname[20], message[80]; switch (msg) { @@ -365,7 +366,12 @@ static BOOL CALLBACK PluginCtrlDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARA plugin_ctrl = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL); count = plugin_ctrl->get_size(); for (i = 0; i < count; i++) { - SendMessage(GetDlgItem(hDlg, IDPLUGLIST), LB_ADDSTRING, 0, (LPARAM)plugin_ctrl->get(i)->get_name()); + plugin = (bx_param_bool_c*)plugin_ctrl->get(i); + if (plugin->get()) { + SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_ADDSTRING, 0, (LPARAM)plugin->get_name()); + } else { + SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_ADDSTRING, 0, (LPARAM)plugin->get_name()); + } } EnableWindow(GetDlgItem(hDlg, IDLOAD), FALSE); EnableWindow(GetDlgItem(hDlg, IDUNLOAD), FALSE); @@ -376,32 +382,39 @@ static BOOL CALLBACK PluginCtrlDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARA case WM_COMMAND: code = HIWORD(wParam); switch (LOWORD(wParam)) { - case IDPLUGLIST: + case IDPLUGLIST1: if (code == LBN_SELCHANGE) { + SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_SETCURSEL, -1, 0); + EnableWindow(GetDlgItem(hDlg, IDLOAD), TRUE); + EnableWindow(GetDlgItem(hDlg, IDUNLOAD), FALSE); + } + break; + case IDPLUGLIST2: + if (code == LBN_SELCHANGE) { + SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_SETCURSEL, -1, 0); + EnableWindow(GetDlgItem(hDlg, IDLOAD), FALSE); EnableWindow(GetDlgItem(hDlg, IDUNLOAD), TRUE); } break; - case IDEDIT: - if (code == EN_CHANGE) { - i = GetWindowTextLength(GetDlgItem(hDlg, IDEDIT)); - EnableWindow(GetDlgItem(hDlg, IDLOAD), i > 0); - } - break; case IDLOAD: - GetDlgItemText(hDlg, IDEDIT, plugname, 18); + i = SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_GETCURSEL, 0, 0); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_GETTEXT, i, (LPARAM)plugname); if (SIM->opt_plugin_ctrl(plugname, 1)) { wsprintf(message, "Plugin '%s' loaded", plugname); MessageBox(hDlg, message, "Plugin Control", MB_ICONINFORMATION); - SendMessage(GetDlgItem(hDlg, IDPLUGLIST), LB_ADDSTRING, 0, (LPARAM)plugname); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_DELETESTRING, i, 0); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_ADDSTRING, 0, (LPARAM)plugname); + EnableWindow(GetDlgItem(hDlg, IDLOAD), FALSE); } break; case IDUNLOAD: - i = SendMessage(GetDlgItem(hDlg, IDPLUGLIST), LB_GETCURSEL, 0, 0); - SendMessage(GetDlgItem(hDlg, IDPLUGLIST), LB_GETTEXT, i, (LPARAM)plugname); + i = SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_GETCURSEL, 0, 0); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_GETTEXT, i, (LPARAM)plugname); if (SIM->opt_plugin_ctrl(plugname, 0)) { wsprintf(message, "Plugin '%s' unloaded", plugname); MessageBox(hDlg, message, "Plugin Control", MB_ICONINFORMATION); - SendMessage(GetDlgItem(hDlg, IDPLUGLIST), LB_DELETESTRING, i, 0); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST1), LB_ADDSTRING, 0, (LPARAM)plugname); + SendMessage(GetDlgItem(hDlg, IDPLUGLIST2), LB_DELETESTRING, i, 0); EnableWindow(GetDlgItem(hDlg, IDUNLOAD), FALSE); } break; diff --git a/bochs/gui/win32res.h b/bochs/gui/win32res.h index 20186a996..23e115135 100644 --- a/bochs/gui/win32res.h +++ b/bochs/gui/win32res.h @@ -27,8 +27,10 @@ #define IDADVLOGOPT 1240 #define IDAPPLY 1250 #define PLUGIN_CTRL_DLG 1300 -#define IDPLUGLIST 1310 -#define IDEDIT 1320 +#define IDPLUGTXT1 1305 +#define IDPLUGLIST1 1310 +#define IDPLUGTXT2 1315 +#define IDPLUGLIST2 1320 #define IDLOAD 1330 #define IDUNLOAD 1340 #define ASK_DLG 2000 diff --git a/bochs/gui/wxdialog.cc b/bochs/gui/wxdialog.cc index 4aa79e254..74200d531 100644 --- a/bochs/gui/wxdialog.cc +++ b/bochs/gui/wxdialog.cc @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 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 @@ -450,23 +450,30 @@ PluginControlDialog::PluginControlDialog( SetTitle(wxT("Optional Plugin Control")); vertSizer = new wxBoxSizer(wxVERTICAL); horzSizer = new wxBoxSizer(wxHORIZONTAL); - listSizer = new wxBoxSizer(wxVERTICAL); - editSizer = new wxBoxSizer(wxVERTICAL); + leftSizer = new wxBoxSizer(wxVERTICAL); + centerSizer = new wxBoxSizer(wxVERTICAL); + rightSizer = new wxBoxSizer(wxVERTICAL); buttonSizer = new wxBoxSizer(wxHORIZONTAL); - horzSizer->Add(listSizer, 0, wxALIGN_LEFT); - horzSizer->Add(editSizer, 0, wxALIGN_RIGHT); - vertSizer->Add(horzSizer, 0, wxALIGN_LEFT); + horzSizer->Add(leftSizer, 0, wxALIGN_LEFT); + horzSizer->Add(centerSizer, 0, wxALIGN_CENTER); + horzSizer->Add(rightSizer, 0, wxALIGN_RIGHT); + vertSizer->Add(horzSizer, 0, wxALIGN_CENTER); vertSizer->Add(buttonSizer, 0, wxALIGN_CENTER); - // listSizer contents - pluglist = new wxListBox(this, ID_PluginList); - listSizer->Add(pluglist, 0, wxALL, 10); - // editSizer contents - plugname = new wxTextCtrl(this, ID_PluginName, wxT(""), wxDefaultPosition, wxSize(120, -1)); - editSizer->Add(plugname, 0, wxALL, 10); - btn_load = new wxButton(this, ID_Load, wxT("Load")); - editSizer->Add(btn_load, 0, wxALL | wxALIGN_RIGHT, 5); - btn_unload = new wxButton(this, ID_Unload, wxT("Unload")); - editSizer->Add(btn_unload, 0, wxALL | wxALIGN_RIGHT, 5); + // leftSizer contents + plugtxt1 = new wxStaticText(this, -1, wxT("Available")); + pluglist1 = new wxListBox(this, ID_PluginList1, wxDefaultPosition, wxSize(120, 200)); + leftSizer->Add(plugtxt1, 0, wxALL | wxALIGN_CENTER, 10); + leftSizer->Add(pluglist1, 0, wxALL, 10); + // rightSizer contents + plugtxt2 = new wxStaticText(this, -1, wxT("Loaded")); + pluglist2 = new wxListBox(this, ID_PluginList2, wxDefaultPosition, wxSize(120, 200)); + rightSizer->Add(plugtxt2, 0, wxALL | wxALIGN_CENTER, 10); + rightSizer->Add(pluglist2, 0, wxALL, 10); + // centerSizer contents + btn_load = new wxButton(this, ID_Load, wxT(">> Load >>")); + centerSizer->Add(btn_load, 0, wxALL | wxALIGN_RIGHT, 5); + btn_unload = new wxButton(this, ID_Unload, wxT("<< Unload <<")); + centerSizer->Add(btn_unload, 0, wxALL | wxALIGN_RIGHT, 5); // buttonSizer contents wxButton *btn = new wxButton(this, wxID_HELP, BTNLABEL_HELP); buttonSizer->Add(btn, 0, wxALL, 5); @@ -475,9 +482,14 @@ PluginControlDialog::PluginControlDialog( // make sure all plugins are loaded and add them to the listbox SIM->opt_plugin_ctrl("*", 1); bx_list_c *plugin_ctrl = (bx_list_c*) SIM->get_param(BXPN_PLUGIN_CTRL); + int a = 0, b = 0; for (int i = 0; i < plugin_ctrl->get_size(); i++) { bx_param_bool_c *plugin = (bx_param_bool_c*)plugin_ctrl->get(i); - pluglist->Insert(wxString(plugin->get_name(), wxConvUTF8), i); + if (plugin->get()) { + pluglist2->Insert(wxString(plugin->get_name(), wxConvUTF8), a++); + } else { + pluglist1->Insert(wxString(plugin->get_name(), wxConvUTF8), b++); + } } btn_load->Enable(0); btn_unload->Enable(0); @@ -496,41 +508,52 @@ void PluginControlDialog::Init() void PluginControlDialog::OnEvent(wxCommandEvent& event) { char buf[1024]; + int i; int id = event.GetId(); switch (id) { - case ID_PluginList: + case ID_PluginList1: if (event.GetEventType() == wxEVT_COMMAND_LISTBOX_SELECTED) { - btn_unload->Enable(1); + pluglist2->SetSelection(-1); + btn_load->Enable(1); + btn_unload->Enable(0); } break; - case ID_PluginName: - if (event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED) { - btn_load->Enable(!plugname->IsEmpty()); + case ID_PluginList2: + if (event.GetEventType() == wxEVT_COMMAND_LISTBOX_SELECTED) { + pluglist1->SetSelection(-1); + btn_load->Enable(0); + btn_unload->Enable(1); } break; case ID_Load: { - wxString tmpname(plugname->GetValue()); + i = pluglist1->GetSelection(); + wxString tmpname = pluglist1->GetString(i); strncpy(buf, tmpname.mb_str(wxConvUTF8), sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; if (SIM->opt_plugin_ctrl(buf, 1)) { tmpname.Printf(wxT("Plugin '%s' loaded"), buf); wxMessageBox(tmpname, wxT("Plugin Control"), wxOK | wxICON_INFORMATION, this); - pluglist->Insert(wxString(buf, wxConvUTF8), pluglist->GetCount()); + pluglist1->Delete(i); + pluglist2->Insert(wxString(buf, wxConvUTF8), pluglist2->GetCount()); + pluglist1->SetSelection(-1); + btn_load->Enable(0); } } break; case ID_Unload: { - int i = pluglist->GetSelection(); - wxString tmpname = pluglist->GetString(i); + i = pluglist2->GetSelection(); + wxString tmpname = pluglist2->GetString(i); strncpy(buf, tmpname.mb_str(wxConvUTF8), sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; if (SIM->opt_plugin_ctrl(buf, 0)) { tmpname.Printf(wxT("Plugin '%s' unloaded"), buf); wxMessageBox(tmpname, wxT("Plugin Control"), wxOK | wxICON_INFORMATION, this); - pluglist->Delete(i); + pluglist1->Insert(wxString(buf, wxConvUTF8), pluglist1->GetCount()); + pluglist2->Delete(i); + pluglist2->SetSelection(-1); btn_unload->Enable(0); } } diff --git a/bochs/gui/wxdialog.h b/bochs/gui/wxdialog.h index 8886159c9..b12787f63 100644 --- a/bochs/gui/wxdialog.h +++ b/bochs/gui/wxdialog.h @@ -2,7 +2,7 @@ // $Id$ //////////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2016 The Bochs Project +// Copyright (C) 2002-2021 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 @@ -187,9 +187,10 @@ class PluginControlDialog: public wxDialog private: void Init(); // called automatically by ShowModal() void ShowHelp(); - wxBoxSizer *vertSizer, *horzSizer, *listSizer, *editSizer, *buttonSizer; - wxTextCtrl *plugname; - wxListBox *pluglist; + wxBoxSizer *vertSizer, *horzSizer, *buttonSizer; + wxBoxSizer *leftSizer, *centerSizer, *rightSizer; + wxStaticText *plugtxt1, *plugtxt2; + wxListBox *pluglist1, *pluglist2; wxButton *btn_load, *btn_unload; public: PluginControlDialog(wxWindow* parent, wxWindowID id); diff --git a/bochs/gui/wxmain.h b/bochs/gui/wxmain.h index 1df124530..60f5f6558 100644 --- a/bochs/gui/wxmain.h +++ b/bochs/gui/wxmain.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////// // -// Copyright (C) 2002-2020 The Bochs Project +// Copyright (C) 2002-2021 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 @@ -108,8 +108,8 @@ enum // advanced log options ID_ApplyDefault, // dialog box: PluginControlDialog - ID_PluginList, - ID_PluginName, + ID_PluginList1, + ID_PluginList2, ID_Load, ID_Unload, // that's all diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index 4c22355dd..5b5db98c7 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -225,7 +225,7 @@ void bx_devices_c::init(BX_MEM_C *newmem) (chipset == BX_PCI_CHIPSET_I440BX)) { // UHCI is a part of the PIIX3/PIIX4, so load / enable it if (!PLUG_device_present("usb_uhci")) { - PLUG_load_plugin(usb_uhci, PLUGTYPE_OPTIONAL); + SIM->opt_plugin_ctrl("usb_uhci", 1); } SIM->get_param_bool(BXPN_UHCI_ENABLED)->set(1); } @@ -265,7 +265,7 @@ void bx_devices_c::init(BX_MEM_C *newmem) #if BX_SUPPORT_BUSMOUSE if ((mouse_type == BX_MOUSE_TYPE_INPORT) || (mouse_type == BX_MOUSE_TYPE_BUS)) { - PLUG_load_plugin(busmouse, PLUGTYPE_OPTIONAL); + SIM->opt_plugin_ctrl("busmouse", 1); } #endif if (is_harddrv_enabled()) { diff --git a/bochs/plugin.cc b/bochs/plugin.cc index a47c779bf..dc66828f3 100644 --- a/bochs/plugin.cc +++ b/bochs/plugin.cc @@ -368,6 +368,25 @@ void plugins_search(void) delete [] pgn_path; } +bool plugin_is_optional_device(plugin_t *plugin) +{ + const char *core_plugins[] = {"cmos", "dma", "floppy", "pci", "pci2isa", + "pic", "pit", "svga_cirrus", "vga", NULL}; + const char *std_plugins[] = {"acpi", "harddrv", "hpet", "ioapic", "keyboard", + "pci_ide", NULL}; + int i = 0; + while (core_plugins[i] != NULL) { + if (!strcmp(plugin->name, core_plugins[i])) return 0; + i++; + } + i = 0; + while (std_plugins[i] != NULL) { + if (!strcmp(plugin->name, std_plugins[i])) return 0; + i++; + } + return 1; +} + Bit8u bx_get_plugins_count(plugintype_t type) { plugin_t *temp; @@ -377,7 +396,9 @@ Bit8u bx_get_plugins_count(plugintype_t type) temp = plugins; while (temp != NULL) { - if (type == temp->type) + if ((type == temp->type) || + ((type == PLUGTYPE_OPTIONAL) && (temp->type == PLUGTYPE_DEV) && + plugin_is_optional_device(temp))) count++; temp = temp->next; } @@ -394,7 +415,9 @@ const char* bx_get_plugin_name(plugintype_t type, Bit8u index) temp = plugins; while (temp != NULL) { - if (type == temp->type) { + if ((type == temp->type) || + ((type == PLUGTYPE_OPTIONAL) && (temp->type == PLUGTYPE_DEV) && + plugin_is_optional_device(temp))) { if (count == index) return temp->name; count++; @@ -423,7 +446,7 @@ bool plugin_init_one(plugin_t *plugin) } -void plugin_unload(plugin_t *plugin) +bool plugin_unload(plugin_t *plugin) { if (plugin->loaded) { if (plugin->initialized) @@ -437,6 +460,9 @@ void plugin_unload(plugin_t *plugin) plugin->type = PLUGTYPE_DEV; } plugin->loaded = 0; + return 1; + } else { + return 0; } } @@ -770,19 +796,22 @@ bool bx_load_plugin(const char *name, plugintype_t type) } } -void bx_unload_plugin(const char *name, bx_bool devflag) +bool bx_unload_plugin(const char *name, bx_bool devflag) { plugin_t *plugin; + bool ret = 0; for (plugin = plugins; plugin; plugin = plugin->next) { if (!strcmp(plugin->name, name)) { + BX_INFO(("bx_unload_plugin(): name = %s", plugin->name)); if (devflag) { pluginUnregisterDeviceDevmodel(plugin->name); } - plugin_unload(plugin); + ret = plugin_unload(plugin); break; } } + return ret; } void bx_unload_plugin_type(const char *name, plugintype_t type) @@ -968,14 +997,6 @@ void bx_plugins_after_restore_state() // Special code for loading gui, optional and sound plugins when plugin support // is turned off. -typedef struct { - const char* name; - plugintype_t type; - plugin_init_t plugin_init; - plugin_fini_t plugin_fini; - bx_bool status; -} builtin_plugin_t; - #define BUILTIN_GUI_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_GUI, lib##mod##_gui_plugin_init, lib##mod##_gui_plugin_fini, 0} #define BUILTIN_OPT_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_OPTIONAL, lib##mod##_LTX_plugin_init, lib##mod##_LTX_plugin_fini, 0} #define BUILTIN_SND_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_SND, lib##mod##_sound_plugin_init, lib##mod##_sound_plugin_fini, 0} @@ -984,7 +1005,7 @@ typedef struct { #define BUILTIN_VGA_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_VGA, lib##mod##_LTX_plugin_init, lib##mod##_LTX_plugin_fini, 0} #define BUILTIN_IMG_PLUGIN_ENTRY(mod) {#mod, PLUGTYPE_IMG, lib##mod##_img_plugin_init, lib##mod##_img_plugin_fini, 0} -static builtin_plugin_t builtin_plugins[] = { +plugin_t bx_builtin_plugins[] = { #if BX_WITH_AMIGAOS BUILTIN_GUI_PLUGIN_ENTRY(amigaos), #endif @@ -1132,40 +1153,40 @@ static builtin_plugin_t builtin_plugins[] = { {"NULL", PLUGTYPE_GUI, NULL, NULL, 0} }; -int bx_load_plugin2(const char *name, plugintype_t type) +int bx_load_plugin_np(const char *name, plugintype_t type) { int i = 0; - while (strcmp(builtin_plugins[i].name, "NULL")) { - if ((!strcmp(name, builtin_plugins[i].name)) && - (type == builtin_plugins[i].type)) { - if (builtin_plugins[i].status == 0) { - builtin_plugins[i].plugin_init(NULL, type); - builtin_plugins[i].status = 1; + while (strcmp(bx_builtin_plugins[i].name, "NULL")) { + if ((!strcmp(name, bx_builtin_plugins[i].name)) && + (type == bx_builtin_plugins[i].type)) { + if (bx_builtin_plugins[i].initialized == 0) { + bx_builtin_plugins[i].plugin_init(NULL, type); + bx_builtin_plugins[i].initialized = 1; } return 1; } i++; - }; + } return 0; } int bx_unload_opt_plugin(const char *name, bx_bool devflag) { int i = 0; - while (strcmp(builtin_plugins[i].name, "NULL")) { - if ((!strcmp(name, builtin_plugins[i].name)) && - (builtin_plugins[i].type == PLUGTYPE_OPTIONAL)) { - if (builtin_plugins[i].status == 1) { + while (strcmp(bx_builtin_plugins[i].name, "NULL")) { + if ((!strcmp(name, bx_builtin_plugins[i].name)) && + (bx_builtin_plugins[i].type == PLUGTYPE_OPTIONAL)) { + if (bx_builtin_plugins[i].initialized == 1) { if (devflag) { - pluginUnregisterDeviceDevmodel(builtin_plugins[i].name); + pluginUnregisterDeviceDevmodel(bx_builtin_plugins[i].name); } - builtin_plugins[i].plugin_fini(); - builtin_plugins[i].status = 0; + bx_builtin_plugins[i].plugin_fini(); + bx_builtin_plugins[i].initialized = 0; } return 1; } i++; - }; + } return 0; } diff --git a/bochs/plugin.h b/bochs/plugin.h index fd8aa991b..786ee3a79 100644 --- a/bochs/plugin.h +++ b/bochs/plugin.h @@ -114,11 +114,11 @@ extern "C" { // When plugins are off, PLUG_load_plugin will call the plugin_init function // directly. #define PLUG_load_plugin(name,type) {lib##name##_LTX_plugin_init(NULL,type);} -#define PLUG_load_gui_plugin(name) bx_load_plugin2(name,PLUGTYPE_GUI) -#define PLUG_load_opt_plugin(name) bx_load_plugin2(name,PLUGTYPE_OPTIONAL) -#define PLUG_load_vga_plugin(name) bx_load_plugin2(name,PLUGTYPE_VGA) +#define PLUG_load_gui_plugin(name) bx_load_plugin_np(name,PLUGTYPE_GUI) +#define PLUG_load_opt_plugin(name) bx_load_plugin_np(name,PLUGTYPE_OPTIONAL) +#define PLUG_load_vga_plugin(name) bx_load_plugin_np(name,PLUGTYPE_VGA) #define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();} -#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1); +#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1) #define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f) #define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f) @@ -339,7 +339,7 @@ Bit8u bx_get_plugins_count(plugintype_t type); const char* bx_get_plugin_name(plugintype_t type, Bit8u index); #endif bool bx_load_plugin(const char *name, plugintype_t type); -extern void bx_unload_plugin(const char *name, bx_bool devflag); +bool bx_unload_plugin(const char *name, bx_bool devflag); extern void bx_unload_plugin_type(const char *name, plugintype_t type); extern void bx_init_plugins(void); extern void bx_reset_plugins(unsigned); @@ -349,7 +349,9 @@ extern void bx_plugins_register_state(void); extern void bx_plugins_after_restore_state(void); #if !BX_PLUGINS -int bx_load_plugin2(const char *name, plugintype_t type); +extern plugin_t bx_builtin_plugins[]; + +int bx_load_plugin_np(const char *name, plugintype_t type); int bx_unload_opt_plugin(const char *name, bx_bool devflag); #endif diff --git a/bochs/win32res.rc b/bochs/win32res.rc index 1257d55b0..fb1e1058d 100644 --- a/bochs/win32res.rc +++ b/bochs/win32res.rc @@ -76,16 +76,18 @@ BEGIN PUSHBUTTON "Apply", IDAPPLY, 155, 155, 50, 14 END -PLUGIN_CTRL_DLG DIALOG 100, 120, 180, 135 +PLUGIN_CTRL_DLG DIALOG 100, 120, 280, 140 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Optional Plugin Control" FONT 8, "Helv" BEGIN - LISTBOX IDPLUGLIST, 15, 15, 85, 100, WS_VSCROLL | WS_TABSTOP - EDITTEXT IDEDIT, 110, 15, 60, 14 - PUSHBUTTON "Load", IDLOAD, 110, 35, 50, 14 - PUSHBUTTON "Unload", IDUNLOAD, 110, 55, 50, 14 - DEFPUSHBUTTON "OK", IDOK, 65, 115, 50, 14 + LTEXT "Available", IDPLUGTXT1, 40, 10, 55, 14 + LISTBOX IDPLUGLIST1, 15, 20, 85, 100, WS_VSCROLL | WS_TABSTOP + LTEXT "Loaded", IDPLUGTXT2, 200, 10, 55, 14 + LISTBOX IDPLUGLIST2, 175, 20, 85, 100, WS_VSCROLL | WS_TABSTOP + PUSHBUTTON ">> Load >>", IDLOAD, 110, 40, 50, 14 + PUSHBUTTON "<< Unload <<", IDUNLOAD, 110, 60, 50, 14 + DEFPUSHBUTTON "OK", IDOK, 115, 120, 50, 14 END PARAM_DLG DIALOG 30, 30, 200, 65