- fixed and improved save state dialog handling

* generic save state dialog code moved to the save_restore_handler() in gui.cc
  * the suspend button in the wxWidgets port now works and uses the new code
  * old wxWidgets save state code removed (not thread-safe)
- wxWidgets HandleAskParamString() method fixed for wxGTK (now using a temporary
  string array instead of a pointer)
This commit is contained in:
Volker Ruppert 2006-08-29 20:10:27 +00:00
parent 25f6299550
commit c9b4d06ff4
9 changed files with 95 additions and 150 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: gui.cc,v 1.97 2006-06-07 19:40:14 vruppert Exp $
// $Id: gui.cc,v 1.98 2006-08-29 20:10:26 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -601,8 +601,25 @@ void bx_gui_c::userbutton_handler(void)
#if BX_SUPPORT_SAVE_RESTORE
void bx_gui_c::save_restore_handler(void)
{
int ret;
char sr_path[BX_PATHNAME_LEN];
if (BX_GUI_THIS dialog_caps & BX_GUI_DLG_SAVE_RESTORE) {
SIM->configuration_interface(NULL, CI_SAVE_RESTORE);
sr_path[0] = 0;
ret = SIM->ask_filename(sr_path, sizeof(sr_path),
"Save Bochs state to folder...", "none",
bx_param_string_c::SELECT_FOLDER_DLG);
if ((ret >= 0) && (strcmp(sr_path, "none"))) {
if (SIM->save_state(sr_path)) {
if (!SIM->ask_yes_no("WARNING",
"The save function currently doesn't handle the state of hard drive images,\n"
"so we don't recommend to continue, unless you are running a read-only\n"
"guest system (e.g. Live-CD).\n\n"
"Do you want to continue?", 0)) {
power_handler();
}
}
}
}
}
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: siminterface.h,v 1.199 2006-06-21 20:42:26 sshwarts Exp $
// $Id: siminterface.h,v 1.200 2006-08-29 20:10:26 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Intro to siminterface by Bryce Denney:
@ -849,7 +849,8 @@ public:
IS_FILENAME = 2, // 1=yes it's a filename, 0=not a filename.
// Some guis have a file browser. This
// bit suggests that they use it.
SAVE_FILE_DIALOG = 4 // Use save dialog opposed to open file dialog
SAVE_FILE_DIALOG = 4, // Use save dialog opposed to open file dialog
SELECT_FOLDER_DLG = 8 // Use folder selection dialog
} bx_string_opt_bits;
bx_param_string_c(bx_param_c *parent,
const char *name,
@ -1087,7 +1088,7 @@ BOCHSAPI extern int clock_sync_n_names;
#include <setjmp.h>
enum ci_command_t { CI_START, CI_RUNTIME_CONFIG, CI_SAVE_RESTORE, CI_SHUTDOWN };
enum ci_command_t { CI_START, CI_RUNTIME_CONFIG, CI_SHUTDOWN };
enum ci_return_t {
CI_OK, // normal return value
CI_ERR_NO_TEXT_CONSOLE // err: can't work because there's no text console

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: textconfig.cc,v 1.61 2006-07-29 09:58:24 vruppert Exp $
// $Id: textconfig.cc,v 1.62 2006-08-29 20:10:26 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// This is code for a text-mode configuration interface. Note that this file
@ -546,34 +546,6 @@ int bx_config_interface(int menu)
}
}
break;
#if BX_SUPPORT_SAVE_RESTORE
case BX_CI_SAVE_RESTORE:
{
Bit32u cont = 1;
#ifdef WIN32
cont = win32SaveState();
#else
if (ask_string(save_state_prompt, "none", sr_path) >= 0) {
if (strcmp(sr_path, "none")) {
if (SIM->save_state(sr_path)) {
cont = 0;
ask_yn("\nThe save function currently doesn't handle the state of hard drive images,\n"
"so we don't recommend to continue, unless you are running a read-only\n"
"guest system (e.g. Live-CD).\n\n"
"Do you want to continue? [no]", "", 0, &cont);
}
}
}
#endif
if (!cont) {
bx_user_quit = 1;
SIM->quit_sim(1);
return -1;
} else {
return 0;
}
}
#endif
default:
fprintf(stderr, "Unknown config interface menu type.\n");
assert(menu >=0 && menu < BX_CI_N_MENUS);
@ -956,10 +928,15 @@ bx_param_string_c::text_ask(FILE *fpin, FILE *fpout)
int status;
const char *prompt = get_ask_format();
if (prompt == NULL) {
// default prompt, if they didn't set an ask format string
text_print(fpout);
fprintf(fpout, "\n");
prompt = "Enter a new value, '?' for help, or press return for no change.\n";
if (options->get() & SELECT_FOLDER_DLG) {
fprintf(fpout, "%s\n\n", get_label());
prompt = "Enter a path to an existing folder or press enter to cancel\n";
} else {
// default prompt, if they didn't set an ask format string
text_print(fpout);
fprintf(fpout, "\n");
prompt = "Enter a new value, '?' for help, or press return for no change.\n";
}
}
while (1) {
char buffer[1024];
@ -1058,11 +1035,6 @@ static int ci_callback(void *userdata, ci_command_t command)
case CI_RUNTIME_CONFIG:
bx_config_interface(BX_CI_RUNTIME);
break;
case CI_SAVE_RESTORE:
#if BX_SUPPORT_SAVE_RESTORE
bx_config_interface(BX_CI_SAVE_RESTORE);
#endif
break;
case CI_SHUTDOWN:
break;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: textconfig.h,v 1.6 2006-06-07 19:40:15 vruppert Exp $
// $Id: textconfig.h,v 1.7 2006-08-29 20:10:26 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
@ -18,9 +18,6 @@ enum {
BX_CI_START_OPTS_MISC,
BX_CI_START_SIMULATION,
BX_CI_RUNTIME,
#if BX_SUPPORT_SAVE_RESTORE
BX_CI_SAVE_RESTORE,
#endif
BX_CI_N_MENUS
};

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: win32dialog.cc,v 1.48 2006-06-08 17:02:51 vruppert Exp $
// $Id: win32dialog.cc,v 1.49 2006-08-29 20:10:26 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
#include "config.h"
@ -78,7 +78,7 @@ int BrowseDir(const char *Title, char *result)
{
BROWSEINFO browseInfo;
LPITEMIDLIST ItemIDList;
int r = 0;
int r = -1;
memset(&browseInfo,0,sizeof(BROWSEINFO));
browseInfo.hwndOwner = GetActiveWindow();
@ -90,7 +90,7 @@ int BrowseDir(const char *Title, char *result)
if (ItemIDList != NULL) {
*result = 0;
if (SHGetPathFromIDList(ItemIDList, result)) {
if (result[0]) r = 1;
if (result[0]) r = 0;
}
// free memory used
IMalloc * imalloc = 0;
@ -891,28 +891,6 @@ int RuntimeOptionsDialog()
return retcode;
}
#if BX_SUPPORT_SAVE_RESTORE
bx_bool win32SaveState()
{
char sr_path[MAX_PATH];
int ret;
sr_path[0] = 0;
if (BrowseDir("Select folder for save/restore data", sr_path)) {
if (SIM->save_state(sr_path)) {
ret = MessageBox(GetBochsWindow(), "The save function currently doesn't handle the state of hard drive images,\n"
"so we don't recommend to continue, unless you are running a read-only\n"
"guest system (e.g. Live-CD).\n\nDo you want to continue?",
"WARNING", MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2);
if (ret == IDNO) {
return 0;
}
}
}
return 1;
}
#endif
BxEvent* win32_notify_callback(void *unused, BxEvent *event)
{
int opts;
@ -931,7 +909,9 @@ BxEvent* win32_notify_callback(void *unused, BxEvent *event)
sparam = (bx_param_string_c *)param;
opts = sparam->get_options()->get();
if (opts & sparam->IS_FILENAME) {
if (param->get_parent() == NULL) {
if (opts & sparam->SELECT_FOLDER_DLG) {
event->retcode = BrowseDir(sparam->get_label(), sparam->getptr());
} else if (param->get_parent() == NULL) {
event->retcode = AskFilename(GetBochsWindow(), (bx_param_filename_c *)sparam, "txt");
} else {
event->retcode = FloppyDialog((bx_param_filename_c *)sparam);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: win32dialog.h,v 1.9 2006-06-08 17:02:51 vruppert Exp $
// $Id: win32dialog.h,v 1.10 2006-08-29 20:10:27 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
#include "config.h"
@ -7,9 +7,6 @@
#if BX_USE_TEXTCONFIG && defined(WIN32)
int RuntimeOptionsDialog();
#if BX_SUPPORT_SAVE_RESTORE
bx_bool win32SaveState();
#endif
void win32_init_notify_callback();
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wx.cc,v 1.84 2006-05-07 09:49:16 vruppert Exp $
// $Id: wx.cc,v 1.85 2006-08-29 20:10:27 vruppert Exp $
/////////////////////////////////////////////////////////////////
//
// wxWidgets VGA display for Bochs. wx.cc implements a custom
@ -917,7 +917,7 @@ bx_wx_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned t
#endif
new_gfx_api = 1;
dialog_caps = BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT;
dialog_caps = BX_GUI_DLG_USER | BX_GUI_DLG_SNAPSHOT | BX_GUI_DLG_SAVE_RESTORE;
}
// ::HANDLE_EVENTS()
@ -934,17 +934,20 @@ void bx_wx_gui_c::handle_events(void)
switch(event_queue[i].type) {
case BX_ASYNC_EVT_TOOLBAR:
switch (event_queue[i].u.toolbar.button) {
case BX_TOOLBAR_FLOPPYA: floppyA_handler (); break;
case BX_TOOLBAR_FLOPPYB: floppyB_handler (); break;
case BX_TOOLBAR_CDROMD: cdromD_handler (); break;
case BX_TOOLBAR_RESET: reset_handler (); break;
case BX_TOOLBAR_POWER: power_handler (); break;
case BX_TOOLBAR_COPY: copy_handler (); break;
case BX_TOOLBAR_PASTE: paste_handler (); break;
case BX_TOOLBAR_SNAPSHOT: snapshot_handler (); break;
case BX_TOOLBAR_CONFIG: config_handler (); break;
case BX_TOOLBAR_MOUSE_EN: thePanel->ToggleMouse (true); break;
case BX_TOOLBAR_USER: userbutton_handler (); break;
case BX_TOOLBAR_FLOPPYA: floppyA_handler(); break;
case BX_TOOLBAR_FLOPPYB: floppyB_handler(); break;
case BX_TOOLBAR_CDROMD: cdromD_handler(); break;
case BX_TOOLBAR_RESET: reset_handler(); break;
case BX_TOOLBAR_POWER: power_handler(); break;
#if BX_SUPPORT_SAVE_RESTORE
case BX_TOOLBAR_SAVE_RESTORE: save_restore_handler(); break;
#endif
case BX_TOOLBAR_COPY: copy_handler(); break;
case BX_TOOLBAR_PASTE: paste_handler(); break;
case BX_TOOLBAR_SNAPSHOT: snapshot_handler(); break;
case BX_TOOLBAR_CONFIG: config_handler(); break;
case BX_TOOLBAR_MOUSE_EN: thePanel->ToggleMouse(true); break;
case BX_TOOLBAR_USER: userbutton_handler(); break;
default:
wxLogDebug (wxT ("unknown toolbar id %d"), event_queue[i].u.toolbar.button);
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.142 2006-06-07 19:40:15 vruppert Exp $
// $Id: wxmain.cc,v 1.143 2006-08-29 20:10:27 vruppert Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWidgets frame, toolbar, menus, and dialogs.
@ -186,9 +186,6 @@ static int ci_callback(void *userdata, ci_command_t command)
case CI_RUNTIME_CONFIG:
fprintf(stderr, "wxmain.cc: runtime config not implemented\n");
break;
case CI_SAVE_RESTORE:
fprintf(stderr, "wxmain.cc: save state not implemented\n");
break;
case CI_SHUTDOWN:
fprintf(stderr, "wxmain.cc: shutdown not implemented\n");
break;
@ -322,7 +319,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Config_New, MyFrame::OnConfigNew)
EVT_MENU(ID_Config_Read, MyFrame::OnConfigRead)
EVT_MENU(ID_Config_Save, MyFrame::OnConfigSave)
EVT_MENU(ID_State_Save, MyFrame::OnStateSave)
EVT_MENU(ID_State_Restore, MyFrame::OnStateRestore)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_Help_About, MyFrame::OnAbout)
@ -358,6 +354,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_TOOL(ID_Edit_Cdrom, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Reset, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Power, MyFrame::OnToolbarClick)
#if BX_SUPPORT_SAVE_RESTORE
EVT_TOOL(ID_Toolbar_SaveRestore, MyFrame::OnToolbarClick)
#endif
EVT_TOOL(ID_Toolbar_Copy, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Paste, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Toolbar_Snapshot, MyFrame::OnToolbarClick)
@ -438,7 +437,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuConfiguration->Append(ID_Config_Read, wxT("&Read Configuration"));
menuConfiguration->Append(ID_Config_Save, wxT("&Save Configuration"));
menuConfiguration->AppendSeparator();
menuConfiguration->Append(ID_State_Save, wxT("&Save State"));
menuConfiguration->Append(ID_State_Restore, wxT("&Restore State"));
menuConfiguration->AppendSeparator();
menuConfiguration->Append(ID_Quit, wxT("&Quit"));
@ -503,7 +501,6 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
menuEdit->Enable(ID_Edit_ATA2, BX_MAX_ATA_CHANNEL > 2);
menuEdit->Enable(ID_Edit_ATA3, BX_MAX_ATA_CHANNEL > 3);
// enable restore state if present
menuConfiguration->Enable(ID_State_Save, FALSE);
menuConfiguration->Enable(ID_State_Restore, BX_SUPPORT_SAVE_RESTORE);
CreateStatusBar();
@ -596,30 +593,6 @@ void MyFrame::OnConfigSave(wxCommandEvent& WXUNUSED(event))
delete fdialog;
}
void MyFrame::OnStateSave(wxCommandEvent& event)
{
#if BX_SUPPORT_SAVE_RESTORE
char sr_path[512];
// pass some initial dir to wxDirDialog
wxString dirSaveRestore;
wxGetHomeDir(&dirSaveRestore);
wxDirDialog ddialog(this, wxT("Select folder with save/restore data"), dirSaveRestore, wxDD_DEFAULT_STYLE);
if (ddialog.ShowModal() == wxID_OK) {
strncpy(sr_path, ddialog.GetPath().mb_str(wxConvUTF8), sizeof(sr_path));
if (SIM->save_state(sr_path)) {
if (wxMessageBox(wxT("The save function currently doesn't handle the state of hard\n"
"drive images, so we don't recommend to continue, unless you\n"
"are running a read-only guest system (e.g. Live-CD).\n\nDo you want to continue?"),
wxT("WARNING"), wxYES_NO, this) == wxNO) {
OnKillSim(event);
}
}
}
#endif
}
void MyFrame::OnStateRestore(wxCommandEvent& WXUNUSED(event))
{
#if BX_SUPPORT_SAVE_RESTORE
@ -992,7 +965,6 @@ void MyFrame::simStatusChanged(StatusChange change, bx_bool popupNotify) {
menuConfiguration->Enable(ID_Config_New, canConfigure);
menuConfiguration->Enable(ID_Config_Read, canConfigure);
#if BX_SUPPORT_SAVE_RESTORE
menuConfiguration->Enable(ID_State_Save, (change == Pause));
menuConfiguration->Enable(ID_State_Restore, canConfigure);
#endif
// only enabled ATA channels with a cdrom connected are available at runtime
@ -1121,36 +1093,41 @@ MyFrame::HandleAskParamString(bx_param_string_c *param)
if ((msg == NULL) || (strlen(msg) == 0)) {
msg = param->get_name();
}
const char *newval = NULL;
char newval[512];
newval[0] = 0;
wxDialog *dialog = NULL;
if (n_opt & param->IS_FILENAME) {
if (n_opt & param->SELECT_FOLDER_DLG) {
// pass some initial dir to wxDirDialog
wxString homeDir;
wxGetHomeDir(&homeDir);
wxDirDialog *ddialog = new wxDirDialog(this, wxString(msg, wxConvUTF8), homeDir, wxDD_DEFAULT_STYLE);
if (ddialog->ShowModal() == wxID_OK)
strncpy(newval, ddialog->GetPath().mb_str(wxConvUTF8), sizeof(newval));
dialog = ddialog; // so I can delete it
} else if (n_opt & param->IS_FILENAME) {
// use file open dialog
long style =
(n_opt & param->SAVE_FILE_DIALOG) ? wxSAVE|wxOVERWRITE_PROMPT : wxOPEN;
wxLogDebug(wxT("HandleAskParamString: create dialog"));
wxFileDialog *fdialog = new wxFileDialog(this, wxString(msg, wxConvUTF8), wxT(""), wxString(param->getptr(), wxConvUTF8), wxT("*.*"), style);
wxLogDebug(wxT("HandleAskParamString: before showmodal"));
if (fdialog->ShowModal() == wxID_OK)
newval = fdialog->GetPath().mb_str(wxConvUTF8);
wxLogDebug(wxT("HandleAskParamString: after showmodal"));
dialog = fdialog; // so I can delete it
long style =
(n_opt & param->SAVE_FILE_DIALOG) ? wxSAVE|wxOVERWRITE_PROMPT : wxOPEN;
wxFileDialog *fdialog = new wxFileDialog(this, wxString(msg, wxConvUTF8), wxT(""), wxString(param->getptr(), wxConvUTF8), wxT("*.*"), style);
if (fdialog->ShowModal() == wxID_OK)
strncpy(newval, fdialog->GetPath().mb_str(wxConvUTF8), sizeof(newval));
dialog = fdialog; // so I can delete it
} else {
// use simple string dialog
long style = wxOK|wxCANCEL;
wxTextEntryDialog *tdialog = new wxTextEntryDialog(this, wxString(msg, wxConvUTF8), wxT("Enter new value"), wxString(param->getptr(), wxConvUTF8), style);
if (tdialog->ShowModal() == wxID_OK)
newval = tdialog->GetValue().mb_str(wxConvUTF8);
dialog = tdialog; // so I can delete it
long style = wxOK|wxCANCEL;
wxTextEntryDialog *tdialog = new wxTextEntryDialog(this, wxString(msg, wxConvUTF8), wxT("Enter new value"), wxString(param->getptr(), wxConvUTF8), style);
if (tdialog->ShowModal() == wxID_OK)
strncpy(newval, tdialog->GetValue().mb_str(wxConvUTF8), sizeof(newval));
dialog = tdialog; // so I can delete it
}
// newval points to memory inside the dialog. As soon as dialog is deleted,
// newval points to junk. So be sure to copy the text out before deleting
// it!
if (newval && strlen(newval)>0) {
// change floppy path to this value.
wxLogDebug(wxT("Setting param %s to '%s'"), param->get_name(), newval);
param->set(newval);
delete dialog;
return 1;
if (strlen(newval) > 0) {
// change floppy path to this value.
wxLogDebug(wxT("Setting param %s to '%s'"), param->get_name(), newval);
param->set(newval);
delete dialog;
return 1;
}
delete dialog;
return -1;
@ -1404,6 +1381,9 @@ void MyFrame::OnToolbarClick(wxCommandEvent& event)
switch (id) {
case ID_Toolbar_Power:which = BX_TOOLBAR_POWER; break;
case ID_Toolbar_Reset: which = BX_TOOLBAR_RESET; break;
#if BX_SUPPORT_SAVE_RESTORE
case ID_Toolbar_SaveRestore: which = BX_TOOLBAR_SAVE_RESTORE; break;
#endif
case ID_Edit_FD_0:
// floppy config dialog box
editFloppyConfig(0);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.h,v 1.56 2006-06-06 22:11:09 sshwarts Exp $
// $Id: wxmain.h,v 1.57 2006-08-29 20:10:27 vruppert Exp $
/////////////////////////////////////////////////////////////////
// This file defines variables and classes that the wxWidgets .cc files
// share. It should be included only by wx.cc and wxmain.cc.
@ -32,7 +32,6 @@ enum
ID_Config_New,
ID_Config_Read,
ID_Config_Save,
ID_State_Save,
ID_State_Restore,
ID_Edit_FD_0,
ID_Edit_FD_1,
@ -169,7 +168,6 @@ public:
void OnConfigNew(wxCommandEvent& event);
void OnConfigRead(wxCommandEvent& event);
void OnConfigSave(wxCommandEvent& event);
void OnStateSave(wxCommandEvent& event);
void OnStateRestore(wxCommandEvent& event);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);