This commit is contained in:
Stanislav Shwartsman 2023-10-29 23:39:46 +02:00
commit 2b439ea29e
5 changed files with 97 additions and 4 deletions

View File

@ -819,17 +819,19 @@ void bx_gui_c::userbutton_handler(void)
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) {
BX_GUI_THIS set_display_mode(DISP_MODE_CONFIG);
sr_path[0] = 0;
ret = SIM->ask_filename(sr_path, sizeof(sr_path),
int 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"))) {
void *hwnd = SIM->ml_message_box("Please wait.", "Waiting for the 'save state' to finish.\n"
"Depending on the size of your emulated disk images, this may be a little while.");
if (SIM->save_state(sr_path)) {
SIM->ml_message_box_kill(hwnd);
if (!SIM->ask_yes_no("WARNING",
"The state of cpu, memory, devices and hard drive images is saved now.\n"
"It is possible to continue, but when using the restore function in a\n"
@ -838,6 +840,7 @@ void bx_gui_c::save_restore_handler(void)
power_handler();
}
} else {
SIM->ml_message_box_kill(hwnd);
SIM->message_box("ERROR", "Failed to save state");
}
}

View File

@ -136,6 +136,10 @@ public:
virtual int ask_yes_no(const char *title, const char *prompt, bool the_default);
// simple message box
virtual void message_box(const char *title, const char *message);
// simple modeless message box
virtual void *ml_message_box(const char *title, const char *message);
// kill modeless message box
virtual void ml_message_box_kill(void *ptr);
// called at a regular interval, currently by the keyboard handler.
virtual void periodic();
virtual int create_disk_image(const char *filename, int sectors, bool overwrite);
@ -662,6 +666,27 @@ void bx_real_sim_c::message_box(const char *title, const char *message)
sim_to_ci_event(&event);
}
void *bx_real_sim_c::ml_message_box(const char *title, const char *message)
{
BxEvent event;
event.type = BX_SYNC_EVT_ML_MSG_BOX;
event.param0 = NULL;
event.u.logmsg.prefix = title;
event.u.logmsg.msg = message;
sim_to_ci_event(&event);
return event.param0;
}
void bx_real_sim_c::ml_message_box_kill(void *ptr)
{
BxEvent event;
event.type = BX_SYNC_EVT_ML_MSG_BOX_KILL;
event.param0 = ptr;
sim_to_ci_event(&event);
}
void bx_real_sim_c::periodic()
{
// give the GUI a chance to do periodic things on the bochs thread. in

View File

@ -217,6 +217,8 @@ typedef enum {
BX_SYNC_EVT_LOG_DLG, // simulator -> CI, wait for response.
BX_SYNC_EVT_GET_DBG_COMMAND, // simulator -> CI, wait for response.
BX_SYNC_EVT_MSG_BOX, // simulator -> CI, wait for response.
BX_SYNC_EVT_ML_MSG_BOX, // simulator -> CI, do not wait for response.
BX_SYNC_EVT_ML_MSG_BOX_KILL, // simulator -> CI, do not wait for response.
__ALL_EVENTS_BELOW_ARE_ASYNC__,
BX_ASYNC_EVT_KEY, // vga window -> simulator
BX_ASYNC_EVT_MOUSE, // vga window -> simulator
@ -407,6 +409,7 @@ typedef struct {
typedef struct {
BxEventType type; // what kind is this?
Bit32s retcode; // success or failure. only used for synchronous events.
void *param0; // misc parameter
union {
BxKeyEvent key;
BxMouseEvent mouse;
@ -667,6 +670,10 @@ public:
virtual int ask_yes_no(const char *title, const char *prompt, bool the_default) {return -1;}
// simple message box
virtual void message_box(const char *title, const char *message) {}
// modeless message box
virtual void *ml_message_box(const char *title, const char *message) {return NULL;}
// kill modeless message box
virtual void ml_message_box_kill(void *ptr) {}
// called at a regular interval, currently by the bx_devices_c::timer()
virtual void periodic() {}
virtual int create_disk_image(const char *filename, int sectors, bool overwrite) {return -3;}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002-2021 The Bochs Project
// Copyright (C) 2002-2023 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
@ -823,6 +823,12 @@ ask:
event->retcode = 0;
}
return event;
case BX_SYNC_EVT_ML_MSG_BOX:
fprintf(stderr, "%s\n%s\n", event->u.logmsg.prefix, event->u.logmsg.msg);
return event;
case BX_SYNC_EVT_ML_MSG_BOX_KILL:
// Nothing to do
return event;
case BX_ASYNC_EVT_REFRESH:
case BX_ASYNC_EVT_DBG_MSG:
case BX_ASYNC_EVT_LOG_MSG:

View File

@ -647,12 +647,34 @@ int MainMenuDialog(HWND hwnd, bool runtime)
(DLGPROC)MainMenuDlgProc, (LPARAM)runtime);
}
#define ML_WIN_WIDTH 400
#define ML_WIN_HEIGHT 150
// Unfortunetly, Win32 Edit Controls must have \r\n for line feeds, and Bochs uses only \n
// We must add \r to every \n to get Windows to drop to the next line in an Edit Control.
void conv_dos2unix(const char *src, char *targ, int max_len)
{
char last = 0;
while (*src && (max_len > 2)) {
if ((*src == '\n') && (last != '\r')) {
*targ++ = '\r';
max_len--;
}
*targ++ = last = *src++;
max_len--;
}
*targ = '\0';
}
BxEvent* win32_notify_callback(void *unused, BxEvent *event)
{
int opts;
int opts, x = -1, y = -1;
bx_param_c *param;
bx_param_string_c *sparam;
char pname[BX_PATHNAME_LEN];
NONCLIENTMETRICS ncm;
RECT rect;
HWND hwnd;
event->retcode = -1;
switch (event->type)
@ -663,6 +685,36 @@ BxEvent* win32_notify_callback(void *unused, BxEvent *event)
case BX_SYNC_EVT_MSG_BOX:
MessageBox(GetBochsWindow(), event->u.logmsg.msg, event->u.logmsg.prefix, MB_ICONERROR);
return event;
case BX_SYNC_EVT_ML_MSG_BOX:
// get the coordinates of the screen size
if (SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0)) {
x = (rect.right - rect.left - ML_WIN_WIDTH) / 2;
y = (rect.bottom - rect.top - ML_WIN_HEIGHT) / 2;
}
// if that failed or the screen isn't very big...
if (x < 0) x = 250;
if (y < 0) y = 250;
// create an EDIT window, with the edit control as read only
hwnd = CreateWindow("EDIT", event->u.logmsg.prefix,
WS_VISIBLE | WS_BORDER | ES_READONLY | ES_LEFT | ES_MULTILINE,
x, y, ML_WIN_WIDTH, ML_WIN_HEIGHT, GetBochsWindow(), (HMENU) NULL, NULL, (LPVOID) NULL);
// if we created the window successfully, change the font to the system font and replace the text
if (hwnd) {
ncm.cbSize = sizeof(NONCLIENTMETRICS);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
SendMessage(hwnd, WM_SETFONT, (WPARAM) CreateFontIndirect(&ncm.lfMessageFont), 0);
conv_dos2unix(event->u.logmsg.msg, pname, BX_PATHNAME_LEN);
SendMessage(hwnd, EM_SETSEL, 0, -1);
SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM) pname);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
event->param0 = hwnd;
}
return event;
case BX_SYNC_EVT_ML_MSG_BOX_KILL:
if (event->param0)
DestroyWindow((HWND) event->param0);
return event;
case BX_SYNC_EVT_ASK_PARAM:
param = event->u.param.param;
if (param->get_type() == BXT_PARAM_STRING || param->get_type() == BXT_PARAM_BYTESTRING) {