From 4b55dc8caeddce64f35c5d3386f4f03c0f350b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Sat, 3 May 2025 01:41:18 +0200 Subject: [PATCH 01/15] plat: use size_t for global dir path buffer length --- src/include/86box/plat.h | 4 ++-- src/qt/qt_platform.cpp | 12 ++++++------ src/unix/unix.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index bbc673dcf..de0a9f30c 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -143,8 +143,8 @@ extern int plat_getcwd(char *bufp, int max); extern int plat_chdir(char *path); extern void plat_tempfile(char *bufp, char *prefix, char *suffix); extern void plat_get_exe_name(char *s, int size); -extern void plat_get_global_config_dir(char *outbuf, uint8_t len); -extern void plat_get_global_data_dir(char *outbuf, uint8_t len); +extern void plat_get_global_config_dir(char *outbuf, size_t len); +extern void plat_get_global_data_dir(char *outbuf, size_t len); extern void plat_get_temp_dir(char *outbuf, uint8_t len); extern void plat_init_rom_paths(void); extern int plat_dir_check(char *path); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index be40452fd..3bdbdf569 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -595,14 +595,14 @@ ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[STRING_MOUSE_CAPTURE] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); - + char mouseCaptureKeyseq[100]; sprintf(mouseCaptureKeyseq, qPrintable(QCoreApplication::translate("", "Press %s to release mouse")), acc_keys[FindAccelerator("release_mouse")].seq); translatedstrings[STRING_MOUSE_RELEASE] = QString(mouseCaptureKeyseq).toStdWString(); - + sprintf(mouseCaptureKeyseq, qPrintable(QCoreApplication::translate("", "Press %s or middle button to release mouse")), acc_keys[FindAccelerator("release_mouse")].seq); - translatedstrings[STRING_MOUSE_RELEASE_MMB] = QString(mouseCaptureKeyseq).toStdWString(); - + translatedstrings[STRING_MOUSE_RELEASE_MMB] = QString(mouseCaptureKeyseq).toStdWString(); + translatedstrings[STRING_INVALID_CONFIG] = QCoreApplication::translate("", "Invalid configuration").toStdWString(); translatedstrings[STRING_NO_ST506_ESDI_CDROM] = QCoreApplication::translate("", "MFM/RLL or ESDI CD-ROM drives never existed").toStdWString(); translatedstrings[STRING_PCAP_ERROR_NO_DEVICES] = QCoreApplication::translate("", "No PCap devices found").toStdWString(); @@ -639,7 +639,7 @@ plat_chdir(char *path) } void -plat_get_global_config_dir(char *outbuf, const uint8_t len) +plat_get_global_config_dir(char *outbuf, const size_t len) { const auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation)[0]); if (!dir.exists()) { @@ -651,7 +651,7 @@ plat_get_global_config_dir(char *outbuf, const uint8_t len) } void -plat_get_global_data_dir(char *outbuf, const uint8_t len) +plat_get_global_data_dir(char *outbuf, const size_t len) { const auto dir = QDir(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0]); if (!dir.exists()) { diff --git a/src/unix/unix.c b/src/unix/unix.c index 2e92a90d3..bdee9006b 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -844,7 +844,7 @@ plat_init_rom_paths(void) } void -plat_get_global_config_dir(char *outbuf, const uint8_t len) +plat_get_global_config_dir(char *outbuf, const size_t len) { char *prefPath = SDL_GetPrefPath(NULL, "86Box"); strncpy(outbuf, prefPath, len); @@ -853,7 +853,7 @@ plat_get_global_config_dir(char *outbuf, const uint8_t len) } void -plat_get_global_data_dir(char *outbuf, const uint8_t len) +plat_get_global_data_dir(char *outbuf, const size_t len) { char *prefPath = SDL_GetPrefPath(NULL, "86Box"); strncpy(outbuf, prefPath, len); From fac052a50f398564769c300e35937ae38b29e492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Sat, 3 May 2025 01:45:21 +0200 Subject: [PATCH 02/15] config: move some settings to a global config --- src/86box.c | 65 +++++++++----- src/config.c | 178 ++++++++++++++++++++++---------------- src/include/86box/86box.h | 1 + 3 files changed, 146 insertions(+), 98 deletions(-) diff --git a/src/86box.c b/src/86box.c index 1d7a73060..4131e7ecc 100644 --- a/src/86box.c +++ b/src/86box.c @@ -160,7 +160,7 @@ int window_remember; int vid_resize; /* (C) allow resizing */ int invert_display = 0; /* (C) invert the display */ int suppress_overscan = 0; /* (C) suppress overscans */ -int lang_id = 0; /* (C) language id */ +int lang_id = 0; /* (G) language id */ int scale = 0; /* (C) screen scale factor */ int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */ @@ -168,7 +168,7 @@ int vid_api = 0; /* (C) video r int vid_cga_contrast = 0; /* (C) video */ int video_fullscreen = 0; /* (C) video */ int video_fullscreen_scale = 0; /* (C) video */ -int video_fullscreen_first = 0; /* (C) video */ +int video_fullscreen_first = 0; /* (G) video */ int enable_overscan = 0; /* (C) video */ int force_43 = 0; /* (C) video */ int video_filter_method = 1; /* (C) video */ @@ -199,13 +199,13 @@ int cpu = 0; /* (C) cpu typ int fpu_type = 0; /* (C) fpu type */ int fpu_softfloat = 0; /* (C) fpu uses softfloat */ int time_sync = 0; /* (C) enable time sync */ -int confirm_reset = 1; /* (C) enable reset confirmation */ -int confirm_exit = 1; /* (C) enable exit confirmation */ -int confirm_save = 1; /* (C) enable save confirmation */ +int confirm_reset = 1; /* (G) enable reset confirmation */ +int confirm_exit = 1; /* (G) enable exit confirmation */ +int confirm_save = 1; /* (G) enable save confirmation */ int enable_discord = 0; /* (C) enable Discord integration */ int pit_mode = -1; /* (C) force setting PIT mode */ int fm_driver = 0; /* (C) select FM sound driver */ -int open_dir_usr_path = 0; /* (C) default file open dialog directory +int open_dir_usr_path = 0; /* (G) default file open dialog directory of usr_path */ int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */ @@ -215,7 +215,7 @@ int hook_enabled = 1; /* (C) Keyboar int test_mode = 0; /* (C) Test mode */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int sound_muted = 0; /* (C) Is sound muted? */ -int inhibit_multimedia_keys; /* (C) Inhibit multimedia keys on Windows. */ +int inhibit_multimedia_keys; /* (G) Inhibit multimedia keys on Windows. */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are present */ @@ -229,27 +229,27 @@ struct accelKey acc_keys[NUM_ACCELS]; struct accelKey def_acc_keys[NUM_ACCELS] = { { .name="send_ctrl_alt_del", .desc="Send Control+Alt+Del", .seq="Ctrl+F12" }, - - { .name="send_ctrl_alt_esc", .desc="Send Control+Alt+Escape", + + { .name="send_ctrl_alt_esc", .desc="Send Control+Alt+Escape", .seq="Ctrl+F10" }, - - { .name="fullscreen", .desc="Toggle fullscreen", + + { .name="fullscreen", .desc="Toggle fullscreen", .seq="Ctrl+Alt+PgUp" }, - - { .name="screenshot", .desc="Screenshot", + + { .name="screenshot", .desc="Screenshot", .seq="Ctrl+F11" }, - - { .name="release_mouse", .desc="Release mouse pointer", + + { .name="release_mouse", .desc="Release mouse pointer", .seq="Ctrl+End" }, - - { .name="hard_reset", .desc="Hard reset", + + { .name="hard_reset", .desc="Hard reset", .seq="Ctrl+Alt+F12" }, - - { .name="pause", .desc="Toggle pause", + + { .name="pause", .desc="Toggle pause", .seq="Ctrl+Alt+F1" }, - - { .name="mute", .desc="Toggle mute", - .seq="Ctrl+Alt+M" } + + { .name="mute", .desc="Toggle mute", + .seq="Ctrl+Alt+M" } }; @@ -271,6 +271,7 @@ extern double exp_pow_table[0x800]; char exe_path[2048]; /* path (dir) of executable */ char usr_path[1024]; /* path (dir) of user data */ char cfg_path[1024]; /* full path of config file */ +char global_cfg_path[1024]; /* full path of config file */ FILE *stdlog = NULL; /* file to log output to */ #if 0 int scrnsz_x = SCREEN_RES_X; /* current screen size, X */ @@ -308,7 +309,7 @@ static int suppr_seen = 1; void pclog_ensure_stdlog_open(void); #endif -/* +/* Ensures STDLOG is open for pclog_ex and pclog_ex_cyclic */ void pclog_ensure_stdlog_open(void) @@ -616,6 +617,7 @@ pc_show_usage(char *s) "-M or --missing\t\t- dump missing machines and video cards\n" "-N or --noconfirm\t\t- do not ask for confirmation on quit\n" "-P or --vmpath path\t\t- set 'path' to be root for vm\n" + "-O or --global path\t\t- set 'path' to be global config file\n" "-R or --rompath path\t\t- set 'path' to be ROM path\n" #ifndef USE_SDL_UI "-S or --settings\t\t\t- show only the settings dialog\n" @@ -655,6 +657,7 @@ pc_init(int argc, char *argv[]) char *ppath = NULL; char *rpath = NULL; char *cfg = NULL; + char *global = NULL; char *p; char temp[2048]; char *fn[FDD_NUM] = { NULL }; @@ -769,6 +772,11 @@ usage: #ifdef DEPRECATE_USAGE deprecated = 0; #endif + } else if (!strcasecmp(argv[c], "--global") || !strcasecmp(argv[c], "-O")) { + if ((c + 1) == argc || plat_dir_check(argv[c + 1])) + goto usage; + + global = argv[++c]; } else if (!strcasecmp(argv[c], "--image") || !strcasecmp(argv[c], "-I")) { if ((c + 1) == argc) goto usage; @@ -996,6 +1004,14 @@ usage: /* At this point, we can safely create the full path name. */ path_append_filename(cfg_path, usr_path, p); + /* Build the global configuration file path. */ + if (global == NULL) { + plat_get_global_config_dir(global_cfg_path, sizeof(global_cfg_path)); + path_append_filename(global_cfg_path, global_cfg_path, CONFIG_FILE); + } else { + strncpy(global_cfg_path, global, sizeof(global_cfg_path) - 1); + } + /* * Get the current directory's name * @@ -1025,7 +1041,8 @@ usage: pclog("# ROM path: %s\n", rom_path->path); } - pclog("# Configuration file: %s\n#\n\n", cfg_path); + pclog("# Global configuration file: %s\n", global_cfg_path); + pclog("# VM configuration file: %s\n#\n\n", cfg_path); /* * We are about to read the configuration file, which MAY * put data into global variables (the hard- and floppy diff --git a/src/config.c b/src/config.c index 52a80763a..f3d771e30 100644 --- a/src/config.c +++ b/src/config.c @@ -88,6 +88,7 @@ static int cy; static int cw; static int ch; static ini_t config; +static ini_t global; #ifdef ENABLE_CONFIG_LOG int config_do_log = ENABLE_CONFIG_LOG; @@ -107,6 +108,35 @@ config_log(const char *fmt, ...) # define config_log(fmt, ...) #endif +/* Load global configuration */ +static void +load_global(void) +{ + ini_section_t cat = ini_find_section(global, ""); + char *p; + + p = ini_section_get_string(cat, "language", NULL); + if (p != NULL) + lang_id = plat_language_code(p); + else + lang_id = plat_language_code(DEFAULT_LANGUAGE); + + open_dir_usr_path = ini_section_get_int(cat, "open_dir_usr_path", 0); + + confirm_reset = ini_section_get_int(cat, "confirm_reset", 1); + confirm_exit = ini_section_get_int(cat, "confirm_exit", 1); + confirm_save = ini_section_get_int(cat, "confirm_save", 1); + + video_fullscreen_first = ini_section_get_int(cat, "video_fullscreen_first", 1); + + inhibit_multimedia_keys = ini_section_get_int(cat, "inhibit_multimedia_keys", 0); + + mouse_sensitivity = ini_section_get_double(cat, "mouse_sensitivity", 1.0); + if (mouse_sensitivity < 0.1) + mouse_sensitivity = 0.1; + else if (mouse_sensitivity > 2.0) + mouse_sensitivity = 2.0; +} /* Load "General" section. */ static void @@ -128,12 +158,8 @@ load_general(void) video_fullscreen_scale = ini_section_get_int(cat, "video_fullscreen_scale", 1); - video_fullscreen_first = ini_section_get_int(cat, "video_fullscreen_first", 1); - video_filter_method = ini_section_get_int(cat, "video_filter_method", 1); - inhibit_multimedia_keys = ini_section_get_int(cat, "inhibit_multimedia_keys", 0); - force_43 = !!ini_section_get_int(cat, "force_43", 0); scale = ini_section_get_int(cat, "scale", 1); if (scale > 9) @@ -179,26 +205,8 @@ load_general(void) hide_tool_bar = ini_section_get_int(cat, "hide_tool_bar", 0); sound_muted = ini_section_get_int(cat, "sound_muted", 0); - confirm_reset = ini_section_get_int(cat, "confirm_reset", 1); - confirm_exit = ini_section_get_int(cat, "confirm_exit", 1); - confirm_save = ini_section_get_int(cat, "confirm_save", 1); - - p = ini_section_get_string(cat, "language", NULL); - if (p != NULL) - lang_id = plat_language_code(p); - else - lang_id = plat_language_code(DEFAULT_LANGUAGE); - - mouse_sensitivity = ini_section_get_double(cat, "mouse_sensitivity", 1.0); - if (mouse_sensitivity < 0.1) - mouse_sensitivity = 0.1; - else if (mouse_sensitivity > 2.0) - mouse_sensitivity = 2.0; - enable_discord = !!ini_section_get_int(cat, "enable_discord", 0); - open_dir_usr_path = ini_section_get_int(cat, "open_dir_usr_path", 0); - video_framerate = ini_section_get_int(cat, "video_gl_framerate", -1); video_vsync = ini_section_get_int(cat, "video_gl_vsync", 0); @@ -1800,7 +1808,21 @@ config_load(void) int i; ini_section_t c; - config_log("Loading config file '%s'..\n", cfg_path); + config_log("Loading global config file '%s'...\n", global_cfg_path); + + global = ini_read(global_cfg_path); + + if (global == NULL) { + global = ini_new(); + + lang_id = plat_language_code(DEFAULT_LANGUAGE); + + config_log("Global config file not present or invalid!\n"); + } else { + load_global(); + } + + config_log("Loading VM config file '%s'...\n", cfg_path); memset(hdd, 0, sizeof(hard_disk_t)); memset(cdrom, 0, sizeof(cdrom_t) * CDROM_NUM); @@ -1812,8 +1834,7 @@ config_load(void) config = ini_read(cfg_path); if (config == NULL) { - config = ini_new(); - config_changed = 1; + config = ini_new(); cpu_f = (cpu_family_t *) &cpu_families[0]; cpu = 0; @@ -1873,9 +1894,7 @@ config_load(void) cassette_pcm = 0; cassette_ui_writeprot = 0; - lang_id = plat_language_code(DEFAULT_LANGUAGE); - - config_log("Config file not present or invalid!\n"); + config_log("VM config file not present or invalid!\n"); } else { load_general(); /* General */ for (i = 0; i < MONITORS_NUM; i++) @@ -1913,29 +1932,74 @@ config_load(void) if (c != NULL) ini_rename_section(c, "3Dfx Voodoo Banshee"); - /* Mark the configuration as changed. */ - config_changed = 1; - - config_log("Config loaded.\n\n"); + config_log("VM config loaded.\n\n"); } + /* Mark the configuration as changed. */ + config_changed = 1; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; } +/* Save global configuration */ +static void +save_global(void) +{ + ini_section_t cat = ini_find_or_create_section(global, ""); + char buffer[512] = { 0 }; + + if (lang_id == plat_language_code(DEFAULT_LANGUAGE)) + ini_section_delete_var(cat, "language"); + else { + plat_language_code_r(lang_id, buffer, 511); + ini_section_set_string(cat, "language", buffer); + } + + if (open_dir_usr_path) + ini_section_set_int(cat, "open_dir_usr_path", open_dir_usr_path); + else + ini_section_delete_var(cat, "open_dir_usr_path"); + + if (confirm_reset != 1) + ini_section_set_int(cat, "confirm_reset", confirm_reset); + else + ini_section_delete_var(cat, "confirm_reset"); + + if (confirm_exit != 1) + ini_section_set_int(cat, "confirm_exit", confirm_exit); + else + ini_section_delete_var(cat, "confirm_exit"); + + if (confirm_save != 1) + ini_section_set_int(cat, "confirm_save", confirm_save); + else + ini_section_delete_var(cat, "confirm_save"); + + if (video_fullscreen_first == 1) + ini_section_delete_var(cat, "video_fullscreen_first"); + else + ini_section_set_int(cat, "video_fullscreen_first", video_fullscreen_first); + + if (inhibit_multimedia_keys == 1) + ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys); + else + ini_section_delete_var(cat, "inhibit_multimedia_keys"); + + if (mouse_sensitivity != 1.0) + ini_section_set_double(cat, "mouse_sensitivity", mouse_sensitivity); + else + ini_section_delete_var(cat, "mouse_sensitivity"); +} + /* Save "General" section. */ static void save_general(void) { ini_section_t cat = ini_find_or_create_section(config, "General"); char temp[512]; - char buffer[512] = { 0 }; const char *va_name; - ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys); - if (inhibit_multimedia_keys == 0) - ini_section_delete_var(cat, "inhibit_multimedia_keys"); - ini_section_set_int(cat, "sound_muted", sound_muted); if (sound_muted == 0) ini_section_delete_var(cat, "sound_muted"); @@ -1955,11 +2019,6 @@ save_general(void) else ini_section_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); - if (video_fullscreen_first == 1) - ini_section_delete_var(cat, "video_fullscreen_first"); - else - ini_section_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - if (video_filter_method == 1) ini_section_delete_var(cat, "video_filter_method"); else @@ -2041,43 +2100,11 @@ save_general(void) else ini_section_delete_var(cat, "hide_tool_bar"); - if (confirm_reset != 1) - ini_section_set_int(cat, "confirm_reset", confirm_reset); - else - ini_section_delete_var(cat, "confirm_reset"); - - if (confirm_exit != 1) - ini_section_set_int(cat, "confirm_exit", confirm_exit); - else - ini_section_delete_var(cat, "confirm_exit"); - - if (confirm_save != 1) - ini_section_set_int(cat, "confirm_save", confirm_save); - else - ini_section_delete_var(cat, "confirm_save"); - - if (mouse_sensitivity != 1.0) - ini_section_set_double(cat, "mouse_sensitivity", mouse_sensitivity); - else - ini_section_delete_var(cat, "mouse_sensitivity"); - - if (lang_id == plat_language_code(DEFAULT_LANGUAGE)) - ini_section_delete_var(cat, "language"); - else { - plat_language_code_r(lang_id, buffer, 511); - ini_section_set_string(cat, "language", buffer); - } - if (enable_discord) ini_section_set_int(cat, "enable_discord", enable_discord); else ini_section_delete_var(cat, "enable_discord"); - if (open_dir_usr_path) - ini_section_set_int(cat, "open_dir_usr_path", open_dir_usr_path); - else - ini_section_delete_var(cat, "open_dir_usr_path"); - if (video_framerate != -1) ini_section_set_int(cat, "video_gl_framerate", video_framerate); else @@ -3133,6 +3160,9 @@ save_other_removable_devices(void) void config_save(void) { + save_global(); /* Global */ + ini_write(global, global_cfg_path); + save_general(); /* General */ for (uint8_t i = 0; i < MONITORS_NUM; i++) save_monitor(i); /* Monitors */ diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index e19665535..c4ebb80e0 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -175,6 +175,7 @@ extern int hook_enabled; /* (C) Keyboard hook is enabled */ extern char exe_path[2048]; /* path (dir) of executable */ extern char usr_path[1024]; /* path (dir) of user data */ extern char cfg_path[1024]; /* full path of config file */ +extern char global_cfg_path[1024]; /* full path of global config file */ extern int open_dir_usr_path; /* default file open dialog directory of usr_path */ extern char uuid[MAX_UUID_LEN]; /* UUID or machine identifier */ #ifndef USE_NEW_DYNAREC From 7b5a861005e06caf28e8a60c1b251aefa7493468 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 8 Aug 2025 00:51:46 +0500 Subject: [PATCH 03/15] Manager: Temporarily disable the system location option in the new machine wizard --- src/qt/qt_vmmanager_addmachine.cpp | 32 +++++++++++++++++++++++++++++- src/qt/qt_vmmanager_addmachine.hpp | 6 ++++++ src/qt/qt_vmmanager_main.cpp | 4 ++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_vmmanager_addmachine.cpp b/src/qt/qt_vmmanager_addmachine.cpp index 55ff7274b..719f9be43 100644 --- a/src/qt/qt_vmmanager_addmachine.cpp +++ b/src/qt/qt_vmmanager_addmachine.cpp @@ -223,6 +223,7 @@ WithExistingConfigPage::isComplete() const NameAndLocationPage:: NameAndLocationPage(QWidget *parent) { +#ifdef CUSTOM_SYSTEM_LOCATION setTitle(tr("System name and location")); #if defined(_WIN32) @@ -234,6 +235,10 @@ NameAndLocationPage(QWidget *parent) #endif const auto topLabel = new QLabel(tr("Enter the name of the system and choose the location")); +#else + setTitle(tr("System name")); + const auto topLabel = new QLabel(tr("Enter the name of the system")); +#endif topLabel->setWordWrap(true); const auto chooseDirectoryButton = new QPushButton(); @@ -246,6 +251,7 @@ NameAndLocationPage(QWidget *parent) registerField("systemName*", systemName); systemNameValidation = new QLabel(); +#ifdef CUSTOM_SYSTEM_LOCATION const auto systemLocationLabel = new QLabel(tr("System Location")); systemLocation = new QLineEdit(); // TODO: FIXME: This is using the CLI arg and needs to instead use a proper variable @@ -253,6 +259,7 @@ NameAndLocationPage(QWidget *parent) registerField("systemLocation*", systemLocation); systemLocationValidation = new QLabel(); systemLocationValidation->setWordWrap(true); +#endif const auto layout = new QGridLayout(); layout->addWidget(topLabel, 0, 0, 1, -1); @@ -265,6 +272,7 @@ NameAndLocationPage(QWidget *parent) // Set height on validation because it may not always be present layout->setRowMinimumHeight(3, 20); +#ifdef CUSTOM_SYSTEM_LOCATION // Another spacer layout->setRowMinimumHeight(4, 20); layout->addWidget(systemLocationLabel, 5, 0); @@ -273,11 +281,13 @@ NameAndLocationPage(QWidget *parent) // Validation text layout->addWidget(systemLocationValidation, 6, 0, 1, -1); layout->setRowMinimumHeight(6, 20); +#endif setLayout(layout); - +#ifdef CUSTOM_SYSTEM_LOCATION connect(chooseDirectoryButton, &QPushButton::clicked, this, &NameAndLocationPage::chooseDirectoryLocation); +#endif } int @@ -286,6 +296,7 @@ NameAndLocationPage::nextId() const return VMManagerAddMachine::Page_Conclusion; } +#ifdef CUSTOM_SYSTEM_LOCATION void NameAndLocationPage::chooseDirectoryLocation() { @@ -294,23 +305,31 @@ NameAndLocationPage::chooseDirectoryLocation() systemLocation->setText(QDir::toNativeSeparators(directory)); emit completeChanged(); } +#endif bool NameAndLocationPage::isComplete() const { bool nameValid = false; +#ifdef CUSTOM_SYSTEM_LOCATION bool locationValid = false; +#endif // return true if complete if (systemName->text().isEmpty()) { systemNameValidation->setText(tr("Please enter a system name")); +#ifdef CUSTOM_SYSTEM_LOCATION } else if (!systemName->text().contains(dirValidate)) { systemNameValidation->setText(tr("System name cannot contain certain characters")); } else if (const QDir newDir = QDir::cleanPath(systemLocation->text() + "/" + systemName->text()); newDir.exists()) { +#else + } else if (const QDir newDir = QDir::cleanPath(QString(vmm_path) + "/" + systemName->text()); newDir.exists()) { +#endif systemNameValidation->setText(tr("System name already exists")); } else { systemNameValidation->clear(); nameValid = true; } +#ifdef CUSTOM_SYSTEM_LOCATION if (systemLocation->text().isEmpty()) { systemLocationValidation->setText(tr("Please enter a directory for the system")); } else if (const auto dir = QDir(systemLocation->text()); !dir.exists()) { @@ -321,6 +340,9 @@ NameAndLocationPage::isComplete() const } return nameValid && locationValid; +#else + return nameValid; +#endif } bool NameAndLocationPage::eventFilter(QObject *watched, QEvent *event) @@ -354,17 +376,21 @@ ConclusionPage(QWidget *parent) const auto systemNameLabel = new QLabel(tr("System name:")); systemNameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); systemName = new QLabel(); +#ifdef CUSTOM_SYSTEM_LOCATION const auto systemLocationLabel = new QLabel(tr("System location:")); systemLocationLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); systemLocation = new QLabel(); +#endif const auto layout = new QGridLayout(); layout->addWidget(topLabel, 0, 0, 1, -1); layout->setRowMinimumHeight(1, 20); layout->addWidget(systemNameLabel, 2, 0); layout->addWidget(systemName, 2, 1); +#ifdef CUSTOM_SYSTEM_LOCATION layout->addWidget(systemLocationLabel, 3, 0); layout->addWidget(systemLocation, 3, 1); +#endif setLayout(layout); } @@ -373,10 +399,14 @@ ConclusionPage(QWidget *parent) void ConclusionPage::initializePage() { +#ifdef CUSTOM_SYSTEM_LOCATION const auto finalPath = QDir::cleanPath(field("systemLocation").toString() + "/" + field("systemName").toString()); const auto nativePath = QDir::toNativeSeparators(finalPath); +#endif const auto systemNameDisplay = field("systemName").toString(); systemName->setText(systemNameDisplay); +#ifdef CUSTOM_SYSTEM_LOCATION systemLocation->setText(nativePath); +#endif } diff --git a/src/qt/qt_vmmanager_addmachine.hpp b/src/qt/qt_vmmanager_addmachine.hpp index 6ba1a53ce..6e573d905 100644 --- a/src/qt/qt_vmmanager_addmachine.hpp +++ b/src/qt/qt_vmmanager_addmachine.hpp @@ -90,12 +90,16 @@ public: [[nodiscard]] int nextId() const override; private: QLineEdit *systemName; +#ifdef CUSTOM_SYSTEM_LOCATION QLineEdit *systemLocation; +#endif QLabel *systemNameValidation; +#ifdef CUSTOM_SYSTEM_LOCATION QLabel *systemLocationValidation; QRegularExpression dirValidate; private slots: void chooseDirectoryLocation(); +#endif protected: [[nodiscard]] bool isComplete() const override; bool eventFilter(QObject *watched, QEvent *event) override; @@ -109,7 +113,9 @@ public: private: QLabel *topLabel; QLabel *systemName; +#ifdef CUSTOM_SYSTEM_LOCATION QLabel *systemLocation; +#endif protected: void initializePage() override; }; diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 38a3d7340..73f54c69c 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -349,7 +349,11 @@ VMManagerMain::newMachineWizard() const auto wizard = new VMManagerAddMachine(this); if (wizard->exec() == QDialog::Accepted) { const auto newName = wizard->field("systemName").toString(); +#ifdef CUSTOM_SYSTEM_LOCATION const auto systemDir = wizard->field("systemLocation").toString(); +#else + const auto systemDir = QDir(vmm_path).path(); +#endif const auto existingConfiguration = wizard->field("existingConfiguration").toString(); addNewSystem(newName, systemDir, existingConfiguration); } From fcf85d40a60be6e34f0cb2d91e94c4250f049aa4 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 8 Aug 2025 00:52:16 +0500 Subject: [PATCH 04/15] Manager: Add display name to new machine wizard --- src/qt/qt_vmmanager_addmachine.cpp | 24 ++++++++++++++++++++++++ src/qt/qt_vmmanager_addmachine.hpp | 3 +++ src/qt/qt_vmmanager_main.cpp | 7 +++++-- src/qt/qt_vmmanager_main.hpp | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_vmmanager_addmachine.cpp b/src/qt/qt_vmmanager_addmachine.cpp index 719f9be43..12b736fb3 100644 --- a/src/qt/qt_vmmanager_addmachine.cpp +++ b/src/qt/qt_vmmanager_addmachine.cpp @@ -261,6 +261,12 @@ NameAndLocationPage(QWidget *parent) systemLocationValidation->setWordWrap(true); #endif + const auto displayNameLabel = new QLabel(tr("Display Name (optional)")); + displayName = new QLineEdit(); + // Special event filter to override enter key + displayName->installEventFilter(this); + registerField("displayName*", displayName); + const auto layout = new QGridLayout(); layout->addWidget(topLabel, 0, 0, 1, -1); // Spacer row @@ -283,6 +289,11 @@ NameAndLocationPage(QWidget *parent) layout->setRowMinimumHeight(6, 20); #endif + // Another spacer + layout->setRowMinimumHeight(7, 20); + layout->addWidget(displayNameLabel, 8, 0); + layout->addWidget(displayName, 8, 1); + setLayout(layout); #ifdef CUSTOM_SYSTEM_LOCATION @@ -382,6 +393,10 @@ ConclusionPage(QWidget *parent) systemLocation = new QLabel(); #endif + displayNameLabel = new QLabel(tr("Display name:")); + displayNameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + displayName = new QLabel(); + const auto layout = new QGridLayout(); layout->addWidget(topLabel, 0, 0, 1, -1); layout->setRowMinimumHeight(1, 20); @@ -391,6 +406,8 @@ ConclusionPage(QWidget *parent) layout->addWidget(systemLocationLabel, 3, 0); layout->addWidget(systemLocation, 3, 1); #endif + layout->addWidget(displayNameLabel, 4, 0); + layout->addWidget(displayName, 4, 1); setLayout(layout); } @@ -404,9 +421,16 @@ ConclusionPage::initializePage() const auto nativePath = QDir::toNativeSeparators(finalPath); #endif const auto systemNameDisplay = field("systemName").toString(); + const auto displayNameDisplay = field("displayName").toString(); systemName->setText(systemNameDisplay); #ifdef CUSTOM_SYSTEM_LOCATION systemLocation->setText(nativePath); #endif + if (!displayNameDisplay.isEmpty()) + displayName->setText(displayNameDisplay); + else { + displayNameLabel->setVisible(false); + displayName->setVisible(false); + } } diff --git a/src/qt/qt_vmmanager_addmachine.hpp b/src/qt/qt_vmmanager_addmachine.hpp index 6e573d905..92a12398a 100644 --- a/src/qt/qt_vmmanager_addmachine.hpp +++ b/src/qt/qt_vmmanager_addmachine.hpp @@ -93,6 +93,7 @@ private: #ifdef CUSTOM_SYSTEM_LOCATION QLineEdit *systemLocation; #endif + QLineEdit *displayName; QLabel *systemNameValidation; #ifdef CUSTOM_SYSTEM_LOCATION QLabel *systemLocationValidation; @@ -116,6 +117,8 @@ private: #ifdef CUSTOM_SYSTEM_LOCATION QLabel *systemLocation; #endif + QLabel *displayNameLabel; + QLabel *displayName; protected: void initializePage() override; }; diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 73f54c69c..bf22e367e 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -355,12 +355,13 @@ VMManagerMain::newMachineWizard() const auto systemDir = QDir(vmm_path).path(); #endif const auto existingConfiguration = wizard->field("existingConfiguration").toString(); - addNewSystem(newName, systemDir, existingConfiguration); + const auto displayName = wizard->field("displayName").toString(); + addNewSystem(newName, systemDir, displayName, existingConfiguration); } } void -VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QString &configFile) +VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QString &displayName, const QString &configFile) { const auto newSytemDirectory = QDir(QDir::cleanPath(dir + "/" + name)); @@ -423,6 +424,8 @@ VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QStri delete new_system; return; } + auto added_system = vm_model->getConfigObjectForIndex(created_object); + added_system->setDisplayName(displayName); // Get the index of the newly-created system and select it const QModelIndex mapped_index = proxy_model->mapFromSource(created_object); ui->listView->setCurrentIndex(mapped_index); diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index fc21d577f..d41d57938 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -70,7 +70,7 @@ public slots: void shutdownForceButtonPressed() const; void searchSystems(const QString &text) const; void newMachineWizard(); - void addNewSystem(const QString &name, const QString &dir, const QString &configFile = {}); + void addNewSystem(const QString &name, const QString &dir, const QString &displayName = QString(), const QString &configFile = {}); #if __GNUC__ >= 11 [[nodiscard]] QStringList getSearchCompletionList() const; #else From d10d77481a3438d4656a4e07b5aad8a9b79841e1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Aug 2025 23:53:40 +0500 Subject: [PATCH 05/15] Manager: Use UTF-8 when reading/writing INI files --- src/qt/qt_vmmanager_config.cpp | 1 + src/qt/qt_vmmanager_system.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/qt/qt_vmmanager_config.cpp b/src/qt/qt_vmmanager_config.cpp index 08bf4e7c4..2997bdcb1 100644 --- a/src/qt/qt_vmmanager_config.cpp +++ b/src/qt/qt_vmmanager_config.cpp @@ -33,6 +33,7 @@ VMManagerConfig::VMManagerConfig(const ConfigType type, const QString& section) config_type = type; settings = new QSettings(configFile, QSettings::IniFormat, this); + settings->setIniCodec("UTF-8"); settings->setFallbacksEnabled(false); if(type == ConfigType::System && !section.isEmpty()) { settings->beginGroup(section); diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index fadc5aa61..189c482dd 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -234,6 +234,7 @@ VMManagerSystem::loadSettings() } // qInfo() << "Loaded "<< config_file.filePath() << "status:" << settings.status(); + settings.setIniCodec("UTF-8"); // Clear out the config hash in case the config is reloaded for (const auto &outer_key : config_hash.keys()) { config_hash[outer_key].clear(); From 74501db7fcf0bdaaa5c1659a88470de92a8128de Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 7 Aug 2025 13:36:46 +0500 Subject: [PATCH 06/15] Manager: Add machine deletion --- src/qt/qt_vmmanager_main.cpp | 26 ++++++++++++++++++++++++++ src/qt/qt_vmmanager_main.hpp | 1 + src/qt/qt_vmmanager_model.cpp | 14 +++++++++++++- src/qt/qt_vmmanager_model.hpp | 1 + 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index bf22e367e..484696954 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -107,6 +107,13 @@ VMManagerMain::VMManagerMain(QWidget *parent) : }); killIcon.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + QAction deleteAction(tr("&Delete")); + contextMenu.addAction(&deleteAction); + connect(&deleteAction, &QAction::triggered, [this, parent] { + deleteSystem(selected_sysconfig); + }); + deleteAction.setEnabled(selected_sysconfig->process->state() == QProcess::NotRunning); + contextMenu.addSeparator(); QAction showRawConfigFile(tr("Show &config file")); @@ -433,6 +440,25 @@ VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QStri }); } + +void +VMManagerMain::deleteSystem(VMManagerSystem *sysconfig) +{ + QMessageBox msgbox(QMessageBox::Icon::Warning, tr("Warning"), tr("Do you really want to delete the virtual machine \"%1\" and all its files? This action cannot be undone!").arg(sysconfig->displayName), QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No, qobject_cast(this->parent())); + msgbox.exec(); + if (msgbox.result() == QMessageBox::Yes) { + auto qrmdir = new QDir(sysconfig->config_dir); + if (const bool rmdirResult = qrmdir->removeRecursively(); !rmdirResult) { + QMessageBox::critical(this, tr("Remove directory failed"), tr("Some files in the machine's directory were unable to be deleted. Please delete them manually.")); + return; + } + auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + config->remove(sysconfig->uuid); + vm_model->removeConfigFromModel(sysconfig); + delete sysconfig; + } +} + QStringList VMManagerMain::getSearchCompletionList() const { diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index d41d57938..9b9401d0f 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -70,6 +70,7 @@ public slots: void shutdownForceButtonPressed() const; void searchSystems(const QString &text) const; void newMachineWizard(); + void deleteSystem(VMManagerSystem *sysconfig); void addNewSystem(const QString &name, const QString &dir, const QString &displayName = QString(), const QString &configFile = {}); #if __GNUC__ >= 11 [[nodiscard]] QStringList getSearchCompletionList() const; diff --git a/src/qt/qt_vmmanager_model.cpp b/src/qt/qt_vmmanager_model.cpp index 76fcbffd6..3f6bdc4f9 100644 --- a/src/qt/qt_vmmanager_model.cpp +++ b/src/qt/qt_vmmanager_model.cpp @@ -140,6 +140,18 @@ VMManagerModel::addConfigToModel(VMManagerSystem *system_config) connect(system_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged); endInsertRows(); } + +void +VMManagerModel::removeConfigFromModel(VMManagerSystem *system_config) +{ + const QModelIndex index = getIndexForConfigFile(system_config->config_file); + disconnect(system_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged); + beginRemoveRows(QModelIndex(), index.row(), index.row()); + machines.remove(index.row()); + endRemoveRows(); + emit systemDataChanged(); +} + void VMManagerModel::modelDataChanged() { @@ -177,4 +189,4 @@ VMManagerModel::getActiveMachineCount() running++; } return running; -} \ No newline at end of file +} diff --git a/src/qt/qt_vmmanager_model.hpp b/src/qt/qt_vmmanager_model.hpp index 9fed1ca8c..4205e8098 100644 --- a/src/qt/qt_vmmanager_model.hpp +++ b/src/qt/qt_vmmanager_model.hpp @@ -51,6 +51,7 @@ public: [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role) const override; void addConfigToModel(VMManagerSystem *system_config); + void removeConfigFromModel(VMManagerSystem *system_config); [[nodiscard]] VMManagerSystem * getConfigObjectForIndex(const QModelIndex &index) const; QModelIndex getIndexForConfigFile(const QFileInfo& config_file); From 6ee2e66b56ed6463dc8142f8729bef0f9a07a18f Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 8 Aug 2025 01:36:24 +0500 Subject: [PATCH 07/15] Fix the details screen after deleting every machine --- src/qt/qt_vmmanager_main.cpp | 20 ++++++++++++++++++-- src/qt/qt_vmmanager_system.hpp | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 484696954..b55e2be2a 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -188,11 +188,19 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, return; } - disconnect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + /* hack to prevent strange segfaults when adding a machine after + removing all machines previously */ + if (selected_sysconfig->config_signal_connected == true) { + disconnect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + selected_sysconfig->config_signal_connected = false; + } const auto mapped_index = proxy_model->mapToSource(current); selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); vm_details->updateData(selected_sysconfig); - connect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + if (selected_sysconfig->config_signal_connected == false) { + connect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); + selected_sysconfig->config_signal_connected = true; + } // Emit that the selection changed, include with the process state emit selectionChanged(current, selected_sysconfig->process->state()); @@ -456,6 +464,14 @@ VMManagerMain::deleteSystem(VMManagerSystem *sysconfig) config->remove(sysconfig->uuid); vm_model->removeConfigFromModel(sysconfig); delete sysconfig; + + if (vm_model->rowCount(QModelIndex()) <= 0) { + /* no machines left - get rid of the last machine's leftovers */ + ui->detailsArea->layout()->removeWidget(vm_details); + delete vm_details; + vm_details = new VMManagerDetails(); + ui->detailsArea->layout()->addWidget(vm_details); + } } } diff --git a/src/qt/qt_vmmanager_system.hpp b/src/qt/qt_vmmanager_system.hpp index 27b9fda57..5914e46cb 100644 --- a/src/qt/qt_vmmanager_system.hpp +++ b/src/qt/qt_vmmanager_system.hpp @@ -136,6 +136,7 @@ public: QProcess *process = new QProcess(); bool window_obscured; + bool config_signal_connected = false; QString getDisplayValue(VMManager::Display::Name key); QFileInfoList getScreenshots(); From 91bac20d576451e65c7a42cfe357a3ec154a0895 Mon Sep 17 00:00:00 2001 From: flama12333 <143599905+flama12333@users.noreply.github.com> Date: Thu, 7 Aug 2025 15:45:23 -0500 Subject: [PATCH 08/15] Change flags to DEVICE_ISA16 for Oki vga/h-2 and spaced. vid_jega.c has isa 16 slot. src: https://x.com/konekodensetsu/status/1804920614794440854 --- src/video/vid_jega.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_jega.c b/src/video/vid_jega.c index eafdceb9c..d3c806708 100644 --- a/src/video/vid_jega.c +++ b/src/video/vid_jega.c @@ -912,9 +912,9 @@ const device_t jega_device = { }; const device_t jvga_device = { - .name = "OKIVGA/H-2 (JVGA/H)", + .name = "OKI VGA/H-2 (JVGA/H)", .internal_name = "jvga", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA16, .local = 0, .init = jvga_standalone_init, .close = jega_close, From c11272cee96b82d300fe362449e1388682768201 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 8 Aug 2025 01:52:05 +0500 Subject: [PATCH 09/15] Github Actions: Add Linux Qt 6 builds --- .github/workflows/cmake_linux.yml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 012db79b7..5dc0387d8 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -54,10 +54,12 @@ jobs: ui: - name: SDL GUI qt: off + qt6: off static: on - - name: Qt GUI + - name: Qt 5 GUI qt: on - slug: -Qt + qt6: off + slug: -Qt5 packages: >- qtbase5-dev qtbase5-private-dev @@ -65,6 +67,20 @@ jobs: qttranslations5-l10n libevdev-dev libxkbcommon-x11-dev + - name: Qt 6 GUI + qt: on + qt6: on + slug: -Qt6 + packages: >- + qt6-base-dev + qt6-base-private-dev + qt6-tools-dev + qt6-tools-dev-tools + qt6-l10n-tools + qt6-translations-l10n + libevdev-dev + libxkbcommon-x11-dev + libvulkan-dev environment: - arch: x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake @@ -110,6 +126,7 @@ jobs: -D NEW_DYNAREC=${{ matrix.dynarec.new }} -D CMAKE_INSTALL_PREFIX=./build/artifacts -D QT=${{ matrix.ui.qt }} + -D USE_QT6=${{ matrix.ui.qt6 }} - name: Build run: | From 4d198a9b718deb9456dd3379431ed4cc2e33eada Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Fri, 8 Aug 2025 02:52:07 +0500 Subject: [PATCH 10/15] Fix build failures with Qt 6 --- src/qt/qt_vmmanager_config.cpp | 2 ++ src/qt/qt_vmmanager_system.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/qt/qt_vmmanager_config.cpp b/src/qt/qt_vmmanager_config.cpp index 2997bdcb1..41075799b 100644 --- a/src/qt/qt_vmmanager_config.cpp +++ b/src/qt/qt_vmmanager_config.cpp @@ -33,7 +33,9 @@ VMManagerConfig::VMManagerConfig(const ConfigType type, const QString& section) config_type = type; settings = new QSettings(configFile, QSettings::IniFormat, this); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) settings->setIniCodec("UTF-8"); +#endif settings->setFallbacksEnabled(false); if(type == ConfigType::System && !section.isEmpty()) { settings->beginGroup(section); diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index 189c482dd..5130ac50c 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -234,7 +234,9 @@ VMManagerSystem::loadSettings() } // qInfo() << "Loaded "<< config_file.filePath() << "status:" << settings.status(); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) settings.setIniCodec("UTF-8"); +#endif // Clear out the config hash in case the config is reloaded for (const auto &outer_key : config_hash.keys()) { config_hash[outer_key].clear(); From 6017b5605f83868480a0824b01155b912bcbfca5 Mon Sep 17 00:00:00 2001 From: Nelson Kerber Hennemann Filho <87081197+nelsonhef@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:06:09 -0300 Subject: [PATCH 11/15] Update 86box.c Minor typo --- src/86box.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index 2f8c77c9f..e8cba9fc8 100644 --- a/src/86box.c +++ b/src/86box.c @@ -618,7 +618,7 @@ pc_show_usage(char *s) #ifdef USE_INSTRUMENT "-J or --instrument name\t- set 'name' to be the profiling instrument\n" #endif - "-L or --logfile pat\t\t- set 'path' to be the logfile\n" + "-L or --logfile path\t\t- set 'path' to be the logfile\n" "-M or --missing\t\t- dump missing machines and video cards\n" "-N or --noconfirm\t\t- do not ask for confirmation on quit\n" "-P or --vmpath path\t\t- set 'path' to be root for vm\n" From 1ebd8f4f430278c713ca68a187d8d1b897fde8a8 Mon Sep 17 00:00:00 2001 From: Nelson Kerber Hennemann Filho <87081197+nelsonhef@users.noreply.github.com> Date: Thu, 7 Aug 2025 19:09:42 -0300 Subject: [PATCH 12/15] Update qt_vmmanager_addmachine.cpp Minor typo --- src/qt/qt_vmmanager_addmachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_vmmanager_addmachine.cpp b/src/qt/qt_vmmanager_addmachine.cpp index 12b736fb3..b73afb022 100644 --- a/src/qt/qt_vmmanager_addmachine.cpp +++ b/src/qt/qt_vmmanager_addmachine.cpp @@ -110,7 +110,7 @@ IntroPage(QWidget *parent) newConfigRadioButton = new QRadioButton(tr("New configuration")); // auto newDescription = new QLabel(tr("Choose this option to start with a fresh configuration.")); - existingConfigRadioButton = new QRadioButton(tr("Use existing configuraion")); + existingConfigRadioButton = new QRadioButton(tr("Use existing configuration")); // auto existingDescription = new QLabel(tr("Use this option if you'd like to paste in the configuration file from an existing system.")); newConfigRadioButton->setChecked(true); From ce9c40e058e36337a0ef3874e1d8a17766593f60 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Aug 2025 18:06:37 +0200 Subject: [PATCH 13/15] =?UTF-8?q?ATAPI=20CD-ROM:=20Add=20512=20=C2=B5s=20t?= =?UTF-8?q?o=20the=20access=20time=20of=20non-medium-access=20commands=20t?= =?UTF-8?q?o=20avoid=20them=20being=20too=20quick,=20fixes=20too=20slow=20?= =?UTF-8?q?waiting=20times=20on=20the=20two=20AMI=207=20STPC=20Acrossers.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scsi/scsi_cdrom.c | 60 ++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index afafa00ba..03dcb59ef 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -645,19 +645,16 @@ scsi_cdrom_bus_speed(scsi_cdrom_t *dev) { double ret = -1.0; - if (dev && dev->drv && (dev->drv->bus_type == CDROM_BUS_SCSI)) { - dev->callback = -1.0; /* Speed depends on SCSI controller */ - return 0.0; - } else { - if (dev && dev->drv) - ret = ide_atapi_get_period(dev->drv->ide_channel); - if (ret == -1.0) { - if (dev) - dev->callback = -1.0; - return 0.0; - } else - return 1000000.0 / ret; + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + + if (ret == -1.0) { + if (dev) + dev->callback = -1.0; + ret = 0.0; } + + return ret; } static void @@ -671,7 +668,12 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) double bytes_per_second; double period; - if (dev->was_cached != -1) { + if (dev->was_cached == -1) { + if (dev->drv->bus_type == CDROM_BUS_SCSI) + dev->callback = -1.0; /* Speed depends on SCSI controller */ + else + dev->callback = 512.0 + (scsi_cdrom_bus_speed(dev) * (double) (dev->packet_len)); + } else { if (dev->was_cached) { dev->callback += 512.0; scsi_cdrom_set_callback(dev); @@ -686,27 +688,21 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; - } else { - bytes_per_second = scsi_cdrom_bus_speed(dev); - if (bytes_per_second == 0.0) { - dev->callback = -1; /* Speed depends on SCSI controller */ - return; + + period = 1000000.0 / bytes_per_second; + scsi_cdrom_log(dev->log, "Byte transfer period: %lf us\n", period); + if (dev->was_cached == -1) + period *= (double) dev->packet_len; + else { + const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) || + (dev->block_len == 0)) ? dev->sectors_num : + ((scsi_cdrom_current_mode(dev) == 2) ? 1 : dev->sectors_num); + + period *= ((double) num) * 2352.0; } + scsi_cdrom_log(dev->log, "Sector transfer period: %lf us\n", period); + dev->callback += period; } - - period = 1000000.0 / bytes_per_second; - scsi_cdrom_log(dev->log, "Byte transfer period: %lf us\n", period); - if (dev->was_cached == -1) - period *= (double) dev->packet_len; - else { - const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) || - (dev->block_len == 0)) ? dev->sectors_num : - ((scsi_cdrom_current_mode(dev) == 2) ? 1 : dev->sectors_num); - - period *= ((double) num) * 2352.0; - } - scsi_cdrom_log(dev->log, "Sector transfer period: %lf us\n", period); - dev->callback += period; } scsi_cdrom_set_callback(dev); } From d4bce724b1298d254dcf9608aab1c82846a45c7d Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Aug 2025 18:10:47 +0200 Subject: [PATCH 14/15] QT CMakeLists.txt - define HAS_VDE when VDE is present, fixes VDE not being present in the menu anymore. --- src/qt/CMakeLists.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index 1b69635b2..fc35123cd 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -62,6 +62,26 @@ if(APPLE AND USE_QT6) find_package(Qt6Gui/Qt6QICNSPlugin REQUIRED) endif() +if (UNIX) + find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) + if(HAS_VDE) + find_library(VDE_LIB vdeplug) + if (NOT VDE_LIB) + message(WARNING "Could not find VDE. The library will not be bundled and any related features will be disabled.") + else() + add_compile_definitions(HAS_VDE) + endif() + endif() +endif() +if (UNIX AND NOT APPLE) # Support for TAP on Linux and BSD, supposedly. + find_path(HAS_TAP "linux/if_tun.h" PATHS ${TAP_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) + if(HAS_TAP) + add_compile_definitions(HAS_TAP) + else() + message(WARNING "TAP support not available. Are you on some BSD?") + endif() +endif() + add_library(plat STATIC qt.c qt_main.cpp From a1b0d535e13d7fbc69f73b5d81d41ded0d08f2d9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Aug 2025 19:55:53 +0200 Subject: [PATCH 15/15] Windows CD-ROM IOCTL: Do not pass to big maximum size values to the READ TOC IOCTL's, fixes #5900. --- src/qt/win_cdrom_ioctl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index cd558c2ec..6bc2df27c 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -49,6 +49,13 @@ typedef struct ioctl_t { WCHAR path[256]; } ioctl_t; +typedef struct _CDROM_FULL_TOC { + UCHAR Length[2]; + UCHAR FirstCompleteSession; + UCHAR LastCompleteSession; + CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[MAXIMUM_NUMBER_TRACKS + 2]; +} CDROM_FULL_TOC; + static int ioctl_read_dvd_structure(const void *local, uint8_t layer, uint8_t format, uint8_t *buffer, uint32_t *info); @@ -124,7 +131,7 @@ ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf, int32_t *tracks_num) const int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &cur_read_toc_ex, sizeof(CDROM_READ_TOC_EX), - cur_full_toc, 65535, + cur_full_toc, sizeof(CDROM_TOC), (LPDWORD) &size, NULL); ioctl_log(ioctl->log, "temp = %i\n", temp); @@ -179,7 +186,7 @@ ioctl_read_raw_toc(ioctl_t *ioctl) if (!ioctl->is_dvd) { status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &cur_read_toc_ex, sizeof(CDROM_READ_TOC_EX), - cur_full_toc, 65535, + cur_full_toc, sizeof(CDROM_FULL_TOC), (LPDWORD) &size, NULL); ioctl_log(ioctl->log, "status = %i\n", status); }