Rewrite of the optional plugin control feature.
- Now that we know about all available plugins at startup, the bx_list_c object "plugin_ctrl" contains a fixed number of bx_param_bool_c objects representing the requested status (1 = load). It is verified at simulation startup. - The config interface creates two text lists (textconfig) or list boxes (win32, wx) from it to show the remaining available and the loaded plugins. Loading and unloading is performed immediately and plugins may install / uninstall options in other menus / dialogs. - Modified the "non-plugin" code to make the optional plugin control work very similar in this mode.
This commit is contained in:
parent
9e95491fb5
commit
e5c68dd4ac
@ -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", "");
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user