From: Stefan Reinauer Date: Sun, 21 Jun 2026 18:39:40 +0000 (-0700) Subject: qt: restart from in-memory runtime config X-Git-Url: https://gitweb.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f7d3e708ed4d789e8673cdc22fa46ff2636cfb2e;p=francis%2Fwinuae.git qt: restart from in-memory runtime config Stop writing a temporary runtime .uae file just to reopen the Qt properties dialog. Serialize prefs to an in-memory WinUAE config snapshot, pass the displayed config path separately, and return the selected config path to the Unix bridge. --- diff --git a/od-unix/gui.cpp b/od-unix/gui.cpp index d202e080..2ef3564d 100644 --- a/od-unix/gui.cpp +++ b/od-unix/gui.cpp @@ -26,6 +26,9 @@ unsigned int gui_ledstate; static int unix_gui_argc; static TCHAR **unix_gui_argv; +#ifdef WINUAE_UNIX_WITH_INTEGRATED_QT_UI +static TCHAR unix_gui_display_config_path[MAX_DPATH]; +#endif static bool is_runtime_config_snapshot(const TCHAR *path) { @@ -43,6 +46,49 @@ static bool is_runtime_config_snapshot(const TCHAR *path) && !_tcscmp(name + len - suffix_len, suffix); } +#ifdef WINUAE_UNIX_WITH_INTEGRATED_QT_UI +static void copy_gui_config_path(TCHAR *out, size_t out_len, const TCHAR *path) +{ + if (!out || out_len == 0) { + return; + } + out[0] = 0; + if (!path || !path[0]) { + return; + } + _tcsncpy(out, path, out_len); + out[out_len - 1] = 0; +} + +static void remember_gui_display_config_path(const TCHAR *path) +{ + if (!path || !path[0] || is_runtime_config_snapshot(path)) { + return; + } + copy_gui_config_path( + unix_gui_display_config_path, + sizeof unix_gui_display_config_path / sizeof unix_gui_display_config_path[0], + path); +} + +static void get_gui_display_config_path(TCHAR *out, size_t out_len, const TCHAR *initial_config) +{ + if (!out || out_len == 0) { + return; + } + out[0] = 0; + if (unix_gui_display_config_path[0]) { + copy_gui_config_path(out, out_len, unix_gui_display_config_path); + return; + } + if (initial_config && initial_config[0] && !is_runtime_config_snapshot(initial_config)) { + copy_gui_config_path(out, out_len, initial_config); + return; + } + winUaeQtLauncherInitialConfigPath(unix_gui_argc, unix_gui_argv, out, out_len); +} +#endif + void target_main_set_args(int argc, TCHAR **argv) { unix_gui_argc = argc; @@ -62,7 +108,7 @@ int gui_init(void) /* Command-line configs are resolved by the launcher itself and win * over default.uae, like on Windows. Otherwise seed the launcher from the - * config the core just loaded, which may be a runtime restart snapshot. */ + * config the core just loaded. */ if (!winUaeQtLauncherArgumentsSpecifyConfig(unix_gui_argc, unix_gui_argv)) { if (optionsfile[0] && access(optionsfile, R_OK) == 0) { _tcscpy(initial_config, optionsfile); @@ -75,13 +121,25 @@ int gui_init(void) } } - const int action = runWinUaeQtLauncherForPrefsWithConfig( + TCHAR display_config[MAX_DPATH]; + TCHAR selected_config[MAX_DPATH]; + get_gui_display_config_path( + display_config, + sizeof display_config / sizeof display_config[0], + initial_config); + selected_config[0] = 0; + + const int action = runWinUaeQtLauncherForPrefsWithConfigPaths( unix_gui_argc, unix_gui_argv, &changed_prefs, initial_config[0] ? initial_config : nullptr, + display_config[0] ? display_config : nullptr, + selected_config, + sizeof selected_config / sizeof selected_config[0], 0, nullptr); + remember_gui_display_config_path(selected_config[0] ? selected_config : display_config); if (initial_config[0] && is_runtime_config_snapshot(initial_config)) { unlink(initial_config); } @@ -191,24 +249,6 @@ void gui_flicker_led(int led, int, int status) void gui_disk_image_change(int, const TCHAR*, bool) {} #ifdef WINUAE_UNIX_WITH_INTEGRATED_QT_UI -static bool write_runtime_config_snapshot(TCHAR *path, size_t path_len) -{ - const char *tmpdir = getenv("TMPDIR"); - if (!tmpdir || !tmpdir[0]) { - tmpdir = "/tmp"; - } - const int written = snprintf(path, path_len, "%s/winuae-runtime-%ld.uae", tmpdir, (long)getpid()); - if (written < 0 || size_t(written) >= path_len) { - write_log("Unix Qt runtime UI: temporary config path is too long\n"); - return false; - } - if (!cfgfile_save(&changed_prefs, path, 0)) { - write_log("Unix Qt runtime UI: failed to write temporary config '%s'\n", path); - return false; - } - return true; -} - static const TCHAR *runtime_shortcut_initial_path(int shortcut) { if (shortcut >= 0 && shortcut < 4) { @@ -287,26 +327,28 @@ void gui_display(int shortcut) pause_sound(); if (shortcut == -1) { - TCHAR snapshot_path[MAX_DPATH]; - snapshot_path[0] = 0; - bool have_snapshot = write_runtime_config_snapshot(snapshot_path, sizeof snapshot_path / sizeof snapshot_path[0]); + TCHAR display_config[MAX_DPATH]; + TCHAR selected_config[MAX_DPATH]; + get_gui_display_config_path( + display_config, + sizeof display_config / sizeof display_config[0], + nullptr); + selected_config[0] = 0; int exit_code = 0; - const int action = runWinUaeQtLauncherForPrefsWithConfig( + const int action = runWinUaeQtLauncherForPrefsWithConfigSnapshot( unix_gui_argc, unix_gui_argv, &changed_prefs, - have_snapshot ? snapshot_path : nullptr, + display_config[0] ? display_config : nullptr, + selected_config, + sizeof selected_config / sizeof selected_config[0], 1, &exit_code); - - if (have_snapshot && action == WINUAE_QT_LAUNCHER_RESTART - && !write_runtime_config_snapshot(snapshot_path, sizeof snapshot_path / sizeof snapshot_path[0])) { - unlink(snapshot_path); - have_snapshot = false; - } - if (have_snapshot && action != WINUAE_QT_LAUNCHER_RESTART) { - unlink(snapshot_path); + if (action == WINUAE_QT_LAUNCHER_START + || action == WINUAE_QT_LAUNCHER_RESET + || action == WINUAE_QT_LAUNCHER_RESTART) { + remember_gui_display_config_path(selected_config[0] ? selected_config : display_config); } if (action == WINUAE_QT_LAUNCHER_START || action == WINUAE_QT_LAUNCHER_RESET) { @@ -321,7 +363,9 @@ void gui_display(int shortcut) } else if (action == WINUAE_QT_LAUNCHER_QUIT) { uae_quit(); } else if (action == WINUAE_QT_LAUNCHER_RESTART) { - uae_restart(&changed_prefs, -1, have_snapshot ? snapshot_path : nullptr); + fixup_prefs(&changed_prefs, true); + copy_prefs(&changed_prefs, &currprefs); + uae_restart(&changed_prefs, -1, nullptr); } else if (action == WINUAE_QT_LAUNCHER_ERROR) { write_log("Unix Qt runtime UI exited with error code %d\n", exit_code); } diff --git a/od-unix/qt/config.cpp b/od-unix/qt/config.cpp index 8d709a3d..2bc5ecb6 100644 --- a/od-unix/qt/config.cpp +++ b/od-unix/qt/config.cpp @@ -281,11 +281,18 @@ bool WinUaeQtConfig::load(const QString &path, QString *error) return false; } + return loadFromText(QString::fromUtf8(file.readAll()), error); +} + +bool WinUaeQtConfig::loadFromText(const QString &contents, QString *) +{ Settings loaded; OrderedSettings ordered; QList lines; - while (!file.atEnd()) { - QString text = QString::fromUtf8(file.readLine()); + QString copy = contents; + QTextStream in(©, QIODevice::ReadOnly); + while (!in.atEnd()) { + QString text = in.readLine(); while (text.endsWith(QLatin1Char('\n')) || text.endsWith(QLatin1Char('\r'))) { text.chop(1); } diff --git a/od-unix/qt/config.h b/od-unix/qt/config.h index 2e55c18d..7a0bf202 100644 --- a/od-unix/qt/config.h +++ b/od-unix/qt/config.h @@ -30,6 +30,7 @@ public: void removeValue(const QString &key); bool load(const QString &path, QString *error = nullptr); + bool loadFromText(const QString &contents, QString *error = nullptr); bool save(const QString &path, QString *error = nullptr) const; QStringList commandArguments() const; diff --git a/od-unix/qt/launcher.cpp b/od-unix/qt/launcher.cpp index 316679ec..aefd5952 100644 --- a/od-unix/qt/launcher.cpp +++ b/od-unix/qt/launcher.cpp @@ -5181,7 +5181,7 @@ static bool isConfigPath(const QString &path) return path.endsWith(QStringLiteral(".uae"), Qt::CaseInsensitive); } -static QString initialConfigPathFromArguments(const QStringList &arguments) +QString winUaeQtInitialConfigPathFromArguments(const QStringList &arguments) { for (int i = 1; i < arguments.size(); i++) { const QString arg = arguments[i]; @@ -5271,6 +5271,7 @@ public: explicit WinUaeQtDialog( QWidget *parent = nullptr, const QString &initialConfigPath = QString(), + const QString &displayConfigPath = QString(), const WinUaeQtHardwareInfoProvider &hardwareInfoProvider = WinUaeQtHardwareInfoProvider()) : QDialog(parent), hardwareProvider(hardwareInfoProvider), @@ -5380,8 +5381,7 @@ public: accept(); }); connect(restart, &QPushButton::clicked, this, [this]() { - result.status = WinUaeQtLauncherStatus::RestartRequested; - accept(); + requestRestart(); }); connect(cancel, &QPushButton::clicked, this, &QDialog::reject); connect(start, &QPushButton::clicked, this, [this]() { startEmulator(); }); @@ -5413,7 +5413,9 @@ public: resetDefaults(); navigation->setCurrentItem(quickstartPage); if (!initialConfigPath.isEmpty()) { - loadConfig(initialConfigPath); + if (loadConfig(initialConfigPath)) { + setLoadedConfigDisplayPath(displayConfigPath); + } } if (hardwareProvider.pollHostWindowEvents) { QTimer *timer = new QTimer(this); @@ -5439,6 +5441,11 @@ public: activateWindow(); } + bool loadConfigSnapshot(const WinUaeQtConfig &config, const QString &displayConfigPath) + { + return loadConfigDocument(config, displayConfigPath); + } + bool exportMergedConfig(const QString &path) { WinUaeQtConfig config = mergedConfig(); @@ -16188,15 +16195,21 @@ private: } } - void loadConfig(const QString &path) + bool loadConfig(const QString &path) { const QString expandedPath = expandedPathText(path); WinUaeQtConfig config; QString error; if (!config.load(expandedPath, &error)) { QMessageBox::warning(this, windowTitle(), error); - return; + return false; } + return loadConfigDocument(config, expandedPath); + } + + bool loadConfigDocument(const WinUaeQtConfig &config, const QString &path) + { + WinUaeQtConfig loaded = config; if (mountedDrives) { mountedDrives->clear(); } @@ -16221,8 +16234,8 @@ private: quickstartSetConfig->setVisible(true); } } - moveQuickstartBeforeOverrides(config); - for (const WinUaeQtConfig::Setting &setting : config.orderedSettings()) { + moveQuickstartBeforeOverrides(loaded); + for (const WinUaeQtConfig::Setting &setting : loaded.orderedSettings()) { applySetting(setting.key, setting.value); } updateOutputControlState(); @@ -16231,14 +16244,41 @@ private: updateFpuControls(); updateCpuControlState(); updateAdvancedChipsetControlState(); - loadedConfig = config; + loadedConfig = loaded; refreshHardwareInfoPage(); + const QString expandedPath = expandedPathText(path); + configPath->setText(expandedPath); + if (!expandedPath.isEmpty()) { + configName->setCurrentText(QFileInfo(expandedPath).completeBaseName()); + } + refreshConfigList(); + status->setText(expandedPath.isEmpty() + ? QStringLiteral("Loaded running configuration") + : QStringLiteral("Loaded %1").arg(expandedPath)); + return true; + } + + void setLoadedConfigDisplayPath(const QString &path) + { + if (path.isEmpty()) { + return; + } + const QString expandedPath = expandedPathText(path); configPath->setText(expandedPath); configName->setCurrentText(QFileInfo(expandedPath).completeBaseName()); refreshConfigList(); status->setText(QStringLiteral("Loaded %1").arg(expandedPath)); } + QString currentConfigPath() const + { + if (!configPath) { + return QString(); + } + const QString path = configPath->text().trimmed(); + return path.isEmpty() ? QString() : expandedPathText(path); + } + void applySetting(const QString &key, const QString &value) { trackHardwareOrderSetting(key, value); @@ -17132,7 +17172,17 @@ private: requestStart(false); } + void requestRestart() + { + requestStart(false, WinUaeQtLauncherStatus::RestartRequested); + } + void requestStart(bool hardReset) + { + requestStart(hardReset, WinUaeQtLauncherStatus::StartRequested); + } + + void requestStart(bool hardReset, WinUaeQtLauncherStatus status) { const WinUaeQtConfig config = mergedConfig(); const QStringList validationErrors = config.validateForLaunch(); @@ -17142,9 +17192,10 @@ private: return; } - result.status = WinUaeQtLauncherStatus::StartRequested; + result.status = status; result.hardReset = hardReset; result.config = config; + result.configPath = currentConfigPath(); accept(); } }; @@ -17271,26 +17322,11 @@ static void armQtSmokeExit(QDialog &dialog, QApplication *app = nullptr) bool winUaeQtArgumentsSpecifyConfig(const QStringList &arguments) { - return !initialConfigPathFromArguments(arguments).isEmpty(); -} - -WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app) -{ - return runWinUaeQtLauncherForConfig(app, QString()); -} - -WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath) -{ - return runWinUaeQtLauncherForConfig(app, initialConfigPath, WinUaeQtHardwareInfoProvider()); + return !winUaeQtInitialConfigPathFromArguments(arguments).isEmpty(); } -WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +static WinUaeQtLauncherResult runWinUaeQtLauncherDialog(QApplication &app, WinUaeQtDialog &dialog) { - setupApplicationStyle(app); - WinUaeQtDialog dialog( - nullptr, - initialConfigPath.isEmpty() ? initialConfigPathFromArguments(app.arguments()) : initialConfigPath, - hardwareProvider); if (WinUaeQtApplication *qtApp = dynamic_cast(&app)) { qtApp->setConfigOpenHandler([&dialog](const QString &path) { dialog.openConfigFile(path); @@ -17320,6 +17356,40 @@ WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QSt return result; } +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app) +{ + return runWinUaeQtLauncherForConfig(app, QString()); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath) +{ + return runWinUaeQtLauncherForConfig(app, initialConfigPath, WinUaeQtHardwareInfoProvider()); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +{ + return runWinUaeQtLauncherForConfig(app, initialConfigPath, QString(), hardwareProvider); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +{ + setupApplicationStyle(app); + WinUaeQtDialog dialog( + nullptr, + initialConfigPath.isEmpty() ? winUaeQtInitialConfigPathFromArguments(app.arguments()) : initialConfigPath, + displayConfigPath, + hardwareProvider); + return runWinUaeQtLauncherDialog(app, dialog); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const WinUaeQtConfig &initialConfig, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +{ + setupApplicationStyle(app); + WinUaeQtDialog dialog(nullptr, QString(), QString(), hardwareProvider); + dialog.loadConfigSnapshot(initialConfig, displayConfigPath); + return runWinUaeQtLauncherDialog(app, dialog); +} + WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv) { return runWinUaeQtLauncherForConfig(argc, argv, QString()); @@ -17331,9 +17401,20 @@ WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const } WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const QString &initialConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +{ + return runWinUaeQtLauncherForConfig(argc, argv, initialConfigPath, QString(), hardwareProvider); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const QString &initialConfigPath, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) +{ + WinUaeQtApplication app(argc, argv); + return runWinUaeQtLauncherForConfig(app, initialConfigPath, displayConfigPath, hardwareProvider); +} + +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const WinUaeQtConfig &initialConfig, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider) { WinUaeQtApplication app(argc, argv); - return runWinUaeQtLauncherForConfig(app, initialConfigPath, hardwareProvider); + return runWinUaeQtLauncherForConfig(app, initialConfig, displayConfigPath, hardwareProvider); } static QString runtimeDialogDirectory(const QString &initialPath) diff --git a/od-unix/qt/launcher.h b/od-unix/qt/launcher.h index 381b304e..77ff34fc 100644 --- a/od-unix/qt/launcher.h +++ b/od-unix/qt/launcher.h @@ -19,6 +19,7 @@ struct WinUaeQtLauncherResult { bool hardReset = false; int exitCode = 0; QString error; + QString configPath; WinUaeQtConfig config; }; @@ -141,12 +142,17 @@ struct WinUaeQtHardwareInfoProvider { }; bool winUaeQtArgumentsSpecifyConfig(const QStringList &arguments); +QString winUaeQtInitialConfigPathFromArguments(const QStringList &arguments); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const QString &initialConfigPath, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(QApplication &app, const WinUaeQtConfig &initialConfig, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const QString &initialConfigPath); WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const QString &initialConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const QString &initialConfigPath, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); +WinUaeQtLauncherResult runWinUaeQtLauncherForConfig(int argc, char **argv, const WinUaeQtConfig &initialConfig, const QString &displayConfigPath, const WinUaeQtHardwareInfoProvider &hardwareProvider); WinUaeQtRuntimeFileDialogResult runWinUaeQtRuntimeFileDialog(QApplication &app, int shortcut, const QString &initialPath); WinUaeQtRuntimeFileDialogResult runWinUaeQtRuntimeFileDialog(int argc, char **argv, int shortcut, const QString &initialPath); int runWinUaeQtMessageBox(QApplication &app, int flags, const QString &message); diff --git a/od-unix/qt/launcher_bridge.cpp b/od-unix/qt/launcher_bridge.cpp index e921f423..2edb4fa3 100644 --- a/od-unix/qt/launcher_bridge.cpp +++ b/od-unix/qt/launcher_bridge.cpp @@ -531,29 +531,71 @@ static WinUaeQtHardwareInfoProvider bridgeHardwareProvider(struct uae_prefs *pre return provider; } -int winUaeQtLauncherArgumentsSpecifyConfig(int argc, char **argv) +static QStringList bridgeArguments(int argc, char **argv) { QStringList arguments; arguments.reserve(argc); for (int i = 0; i < argc; i++) { arguments.append(QString::fromLocal8Bit(argv[i])); } - return winUaeQtArgumentsSpecifyConfig(arguments) ? 1 : 0; + return arguments; } -int runWinUaeQtLauncherForPrefs(int argc, char **argv, struct uae_prefs *prefs, int *exitCode) +static bool bridgeCopyPath(const QString &path, char *out, size_t outLen) { - return runWinUaeQtLauncherForPrefsWithConfig(argc, argv, prefs, nullptr, 0, exitCode); + if (!out || outLen == 0) { + return path.isEmpty(); + } + out[0] = 0; + if (path.isEmpty()) { + return true; + } + const QByteArray bytes = path.toLocal8Bit(); + if (size_t(bytes.size()) >= outLen) { + return false; + } + memcpy(out, bytes.constData(), size_t(bytes.size()) + 1); + return true; } -int runWinUaeQtLauncherForPrefsWithConfig(int argc, char **argv, struct uae_prefs *prefs, const char *initialConfigPath, int runtimeActions, int *exitCode) +static bool bridgeConfigFromPrefs(struct uae_prefs *prefs, WinUaeQtConfig *config) +{ + if (!prefs || !config) { + return false; + } + struct zfile *file = zfile_fopen_empty(nullptr, _T("unix-qt-prefs.uae"), 0); + if (!file) { + return false; + } + cfgfile_save_options(file, prefs, CONFIG_TYPE_ALL); + size_t len = 0; + const uae_u8 *data = zfile_get_data_pointer(file, &len); + const QString text = data && len ? QString::fromLocal8Bit((const char *)data, int(len)) : QString(); + zfile_fclose(file); + + QString error; + if (!config->loadFromText(text, &error)) { + const QByteArray bytes = error.toLocal8Bit(); + fprintf(stderr, "Unix Qt UI failed to parse runtime config: %s\n", bytes.constData()); + return false; + } + return true; +} + +static int bridgeHandleLauncherResult( + const WinUaeQtLauncherResult &result, + struct uae_prefs *prefs, + char *selectedConfigPath, + size_t selectedConfigPathLen, + int *exitCode) { - const QString initialPath = initialConfigPath && initialConfigPath[0] - ? QString::fromLocal8Bit(initialConfigPath) - : QString(); - WinUaeQtLauncherResult result = runWinUaeQtLauncherForConfig(argc, argv, initialPath, bridgeHardwareProvider(prefs, runtimeActions != 0)); if (result.status == WinUaeQtLauncherStatus::StartRequested || result.status == WinUaeQtLauncherStatus::RestartRequested) { + if (selectedConfigPath + && selectedConfigPathLen > 0 + && !bridgeCopyPath(result.configPath, selectedConfigPath, selectedConfigPathLen)) { + fprintf(stderr, "Unix Qt UI warning: selected config path is too long\n"); + } if (!applyWinUaeQtConfigToPrefs(result.config, prefs)) { fprintf(stderr, "Unix Qt UI failed: no preferences target available\n"); if (exitCode) { @@ -589,6 +631,106 @@ int runWinUaeQtLauncherForPrefsWithConfig(int argc, char **argv, struct uae_pref return WINUAE_QT_LAUNCHER_EXIT; } +int winUaeQtLauncherArgumentsSpecifyConfig(int argc, char **argv) +{ + return winUaeQtArgumentsSpecifyConfig(bridgeArguments(argc, argv)) ? 1 : 0; +} + +int winUaeQtLauncherInitialConfigPath(int argc, char **argv, char *path, size_t pathLen) +{ + if (path && pathLen > 0) { + path[0] = 0; + } + const QString initialPath = winUaeQtInitialConfigPathFromArguments(bridgeArguments(argc, argv)); + if (initialPath.isEmpty()) { + return 0; + } + return bridgeCopyPath(initialPath, path, pathLen) ? 1 : -1; +} + +int runWinUaeQtLauncherForPrefs(int argc, char **argv, struct uae_prefs *prefs, int *exitCode) +{ + return runWinUaeQtLauncherForPrefsWithConfig(argc, argv, prefs, nullptr, 0, exitCode); +} + +int runWinUaeQtLauncherForPrefsWithConfig(int argc, char **argv, struct uae_prefs *prefs, const char *initialConfigPath, int runtimeActions, int *exitCode) +{ + return runWinUaeQtLauncherForPrefsWithConfigPaths( + argc, + argv, + prefs, + initialConfigPath, + nullptr, + nullptr, + 0, + runtimeActions, + exitCode); +} + +int runWinUaeQtLauncherForPrefsWithConfigPaths( + int argc, + char **argv, + struct uae_prefs *prefs, + const char *initialConfigPath, + const char *displayConfigPath, + char *selectedConfigPath, + size_t selectedConfigPathLen, + int runtimeActions, + int *exitCode) +{ + if (selectedConfigPath && selectedConfigPathLen > 0) { + selectedConfigPath[0] = 0; + } + const QString initialPath = initialConfigPath && initialConfigPath[0] + ? QString::fromLocal8Bit(initialConfigPath) + : QString(); + const QString displayPath = displayConfigPath && displayConfigPath[0] + ? QString::fromLocal8Bit(displayConfigPath) + : QString(); + WinUaeQtLauncherResult result = runWinUaeQtLauncherForConfig( + argc, + argv, + initialPath, + displayPath, + bridgeHardwareProvider(prefs, runtimeActions != 0)); + return bridgeHandleLauncherResult(result, prefs, selectedConfigPath, selectedConfigPathLen, exitCode); +} + +int runWinUaeQtLauncherForPrefsWithConfigSnapshot( + int argc, + char **argv, + struct uae_prefs *prefs, + const char *displayConfigPath, + char *selectedConfigPath, + size_t selectedConfigPathLen, + int runtimeActions, + int *exitCode) +{ + if (selectedConfigPath && selectedConfigPathLen > 0) { + selectedConfigPath[0] = 0; + } + + WinUaeQtConfig initialConfig; + if (!bridgeConfigFromPrefs(prefs, &initialConfig)) { + fprintf(stderr, "Unix Qt UI failed: could not snapshot runtime preferences\n"); + if (exitCode) { + *exitCode = 1; + } + return WINUAE_QT_LAUNCHER_ERROR; + } + + const QString displayPath = displayConfigPath && displayConfigPath[0] + ? QString::fromLocal8Bit(displayConfigPath) + : QString(); + WinUaeQtLauncherResult result = runWinUaeQtLauncherForConfig( + argc, + argv, + initialConfig, + displayPath, + bridgeHardwareProvider(prefs, runtimeActions != 0)); + return bridgeHandleLauncherResult(result, prefs, selectedConfigPath, selectedConfigPathLen, exitCode); +} + int runWinUaeQtRuntimeFileDialog(int argc, char **argv, int shortcut, const char *initialPath, char *selectedPath, size_t selectedPathLen, int *exitCode) { if (!selectedPath || selectedPathLen == 0) { diff --git a/od-unix/qt/launcher_bridge.h b/od-unix/qt/launcher_bridge.h index 2c04e9b3..d083171e 100644 --- a/od-unix/qt/launcher_bridge.h +++ b/od-unix/qt/launcher_bridge.h @@ -16,7 +16,10 @@ enum { }; int winUaeQtLauncherArgumentsSpecifyConfig(int argc, char **argv); +int winUaeQtLauncherInitialConfigPath(int argc, char **argv, char *path, size_t path_len); int runWinUaeQtLauncherForPrefs(int argc, char **argv, struct uae_prefs *prefs, int *exit_code); int runWinUaeQtLauncherForPrefsWithConfig(int argc, char **argv, struct uae_prefs *prefs, const char *initial_config_path, int runtime_actions, int *exit_code); +int runWinUaeQtLauncherForPrefsWithConfigPaths(int argc, char **argv, struct uae_prefs *prefs, const char *initial_config_path, const char *display_config_path, char *selected_config_path, size_t selected_config_path_len, int runtime_actions, int *exit_code); +int runWinUaeQtLauncherForPrefsWithConfigSnapshot(int argc, char **argv, struct uae_prefs *prefs, const char *display_config_path, char *selected_config_path, size_t selected_config_path_len, int runtime_actions, int *exit_code); int runWinUaeQtRuntimeFileDialog(int argc, char **argv, int shortcut, const char *initial_path, char *selected_path, size_t selected_path_len, int *exit_code); int runWinUaeQtMessageBox(int argc, char **argv, int flags, const char *message, int *exit_code);