From c23fa96fd0ffe0e4c88d0c67d9baa6f4c75489dc Mon Sep 17 00:00:00 2001 From: Putta Khunchalee Date: Sun, 1 Dec 2024 23:52:51 +0700 Subject: [PATCH] Initializes firmware installation (#1155) --- Cargo.lock | 7 +++++ gui/CMakeLists.txt | 1 - gui/Cargo.toml | 1 + gui/main.cpp | 4 +-- gui/main_window.cpp | 12 -------- gui/main_window.hpp | 4 --- gui/screen.cpp | 23 --------------- gui/screen.hpp | 14 --------- gui/src/setup/mod.rs | 20 +++++++++++++ gui/ui/error.slint | 29 +++++++++++++++++-- gui/ui/setup.slint | 57 +++++++++++++++++++++++++++++++------ gui/ui/setup/firmware.slint | 8 +++++- 12 files changed, 112 insertions(+), 68 deletions(-) delete mode 100644 gui/screen.cpp delete mode 100644 gui/screen.hpp diff --git a/Cargo.lock b/Cargo.lock index cbcc4e11e..03181b7a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1121,6 +1121,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erdp" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a235af404df0c0ceef5b773e9d641731dccea25f02e4e2714b4841df10f6c1c" + [[package]] name = "errno" version = "0.3.9" @@ -1567,6 +1573,7 @@ dependencies = [ "ciborium", "clap", "core-graphics-types 0.1.3", + "erdp", "gdbstub", "gdbstub_arch", "humansize", diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index bc0177baa..8975d4319 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -18,7 +18,6 @@ add_executable(obliteration WIN32 MACOSX_BUNDLE progress_dialog.cpp resources.cpp resources.qrc - screen.cpp settings.cpp system.cpp) diff --git a/gui/Cargo.toml b/gui/Cargo.toml index fce8cdd82..f5fee10ad 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -11,6 +11,7 @@ path = "src/main.rs" bitfield-struct = "0.9.2" ciborium = "0.2.2" clap = { version = "4.5.21", features = ["derive"] } +erdp = "0.1.1" gdbstub = "0.7.3" gdbstub_arch = "0.3.1" humansize = "2.1.3" diff --git a/gui/main.cpp b/gui/main.cpp index 9a0f37f25..fb90c43bc 100644 --- a/gui/main.cpp +++ b/gui/main.cpp @@ -38,8 +38,6 @@ int main(int argc, char *argv[]) // Parse arguments. QCommandLineParser args; - args.setApplicationDescription("Virtualization stack for Obliteration"); - args.addHelpOption(); args.addOption(Args::debug); args.addOption(Args::kernel); args.process(app); @@ -165,7 +163,7 @@ int main(int argc, char *argv[]) #ifdef __APPLE__ MainWindow win(args); #else - MainWindow win(args, &vulkan, std::move(vkDevices)); + MainWindow win(args, std::move(vkDevices)); #endif win.restoreGeometry(); diff --git a/gui/main_window.cpp b/gui/main_window.cpp index 37666237c..a8560e1f4 100644 --- a/gui/main_window.cpp +++ b/gui/main_window.cpp @@ -1,7 +1,6 @@ #include "main_window.hpp" #include "launch_settings.hpp" #include "resources.hpp" -#include "screen.hpp" #include "settings.hpp" #include @@ -41,13 +40,11 @@ MainWindow::MainWindow(const QCommandLineParser &args) : #else MainWindow::MainWindow( const QCommandLineParser &args, - QVulkanInstance *vulkan, QList &&vkDevices) : #endif m_args(args), m_main(nullptr), m_launch(nullptr), - m_screen(nullptr), m_debugNoti(nullptr) { setWindowTitle("Obliteration"); @@ -92,15 +89,6 @@ MainWindow::MainWindow( #endif m_main->addWidget(m_launch); - - // Screen. - m_screen = new Screen(); - -#ifndef __APPLE__ - m_screen->setVulkanInstance(vulkan); -#endif - - m_main->addWidget(createWindowContainer(m_screen)); } MainWindow::~MainWindow() diff --git a/gui/main_window.hpp b/gui/main_window.hpp index ddad9879d..fa0855114 100644 --- a/gui/main_window.hpp +++ b/gui/main_window.hpp @@ -7,12 +7,10 @@ #endif class LaunchSettings; -class ProfileList; class QCommandLineOption; class QCommandLineParser; class QSocketNotifier; class QStackedWidget; -class Screen; class MainWindow final : public QMainWindow { public: @@ -21,7 +19,6 @@ class MainWindow final : public QMainWindow { #else MainWindow( const QCommandLineParser &args, - QVulkanInstance *vulkan, QList &&vkDevices); #endif ~MainWindow() override; @@ -42,7 +39,6 @@ private slots: const QCommandLineParser &m_args; QStackedWidget *m_main; LaunchSettings *m_launch; - Screen *m_screen; QSocketNotifier *m_debugNoti; }; diff --git a/gui/screen.cpp b/gui/screen.cpp deleted file mode 100644 index b04dcf0e9..000000000 --- a/gui/screen.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "screen.hpp" - -Screen::Screen() -{ -#ifdef __APPLE__ - setSurfaceType(QSurface::MetalSurface); -#else - setSurfaceType(QSurface::VulkanSurface); -#endif -} - -Screen::~Screen() -{ -} - -bool Screen::event(QEvent *ev) -{ - if (ev->type() == QEvent::UpdateRequest) { - emit updateRequestReceived(); - } - - return QWindow::event(ev); -} diff --git a/gui/screen.hpp b/gui/screen.hpp deleted file mode 100644 index c0628f7e1..000000000 --- a/gui/screen.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -class Screen final : public QWindow { - Q_OBJECT -public: - Screen(); - ~Screen() override; -signals: - void updateRequestReceived(); -protected: - bool event(QEvent *ev) override; -}; diff --git a/gui/src/setup/mod.rs b/gui/src/setup/mod.rs index 85601cae3..aeccd6511 100644 --- a/gui/src/setup/mod.rs +++ b/gui/src/setup/mod.rs @@ -1,7 +1,9 @@ use crate::dialogs::{open_file, FileType}; use crate::ui::SetupWizard; +use erdp::ErrorDisplay; use slint::{ComponentHandle, PlatformError}; use std::cell::Cell; +use std::fs::File; use std::rc::Rc; use thiserror::Error; @@ -24,6 +26,12 @@ pub fn run_setup() -> Result { } }); + win.on_install_firmware({ + let win = win.as_weak(); + + move || install_firmware(win.unwrap()) + }); + win.on_finish({ let win = win.as_weak(); let finish = finish.clone(); @@ -56,6 +64,18 @@ async fn browse_firmware(win: SetupWizard) { win.set_firmware_dump(path.into_os_string().into_string().unwrap().into()); } +fn install_firmware(win: SetupWizard) { + // Open firmware dump. + let dump = win.get_firmware_dump(); + let dump = match File::open(dump.as_str()) { + Ok(v) => v, + Err(e) => { + win.set_error_message(format!("Failed to open {}: {}.", dump, e.display()).into()); + return; + } + }; +} + /// Represents an error when [`run_setup()`] fails. #[derive(Debug, Error)] pub enum SetupError { diff --git a/gui/ui/error.slint b/gui/ui/error.slint index 11aafde2e..a1ace8075 100644 --- a/gui/ui/error.slint +++ b/gui/ui/error.slint @@ -1,8 +1,10 @@ import { Palette, HorizontalBox, StandardButton, VerticalBox } from "std-widgets.slint"; -component Content { +component Content inherits Rectangle { in property message; + background: Palette.background; + HorizontalBox { VerticalLayout { alignment: start; @@ -23,7 +25,7 @@ component Content { } component ActionBar inherits Rectangle { - pure callback close(); + callback close(); background: Palette.alternate-background; @@ -39,6 +41,29 @@ component ActionBar inherits Rectangle { } } +export component ErrorPopup inherits PopupWindow { + in property message; + + callback close-clicked <=> ab.close; + + close-on-click: false; + + Rectangle { + border-color: Palette.border; + border-width: 1px; + clip: true; + + VerticalLayout { + Content { + message: message; + vertical-stretch: 1; + } + + ab := ActionBar { } + } + } +} + export component ErrorWindow inherits Window { in property message; diff --git a/gui/ui/setup.slint b/gui/ui/setup.slint index 50133c104..2ad6a66d5 100644 --- a/gui/ui/setup.slint +++ b/gui/ui/setup.slint @@ -3,6 +3,7 @@ import { Firmware, InstallFirmware } from "setup/firmware.slint"; import { Conclusion } from "setup/conclusion.slint"; import { NavBar } from "setup/nav.slint"; import { Palette } from "std-widgets.slint"; +import { ErrorPopup } from "error.slint"; // https://github.com/slint-ui/slint/issues/6880 enum WizardPage { @@ -11,18 +12,28 @@ enum WizardPage { Conclusion } -export component SetupWizard inherits Window { - title: "Setup Obliteration"; - icon: @image-url("icon.png"); - width: 500px; // PopupWindow does not resize with the window somehow. - height: 400px; // Same here. +export enum FirmwareInstaller { + Stopped, + Running +} +export component SetupWizard inherits Window { in-out property firmware-dump; + in-out property firmware-installer; + in property firmware-status; + in property firmware-progress; + in-out property error-message; pure callback cancel <=> nav.cancel; pure callback browse-firmware(); + pure callback install-firmware(); pure callback finish(); + title: "Setup Obliteration"; + icon: @image-url("icon.png"); + width: 500px; // PopupWindow does not resize with the window somehow. + height: 400px; // Same here. + private property page: WizardPage.Intro; states [ @@ -37,12 +48,16 @@ export component SetupWizard inherits Window { } if page == WizardPage.Firmware: Firmware { - firmware-dump: root.firmware-dump; + firmware-dump: firmware-dump; vertical-stretch: 1; browse => { browse-firmware(); } + + changed firmware-dump => { + firmware-dump = self.firmware-dump; + } } if page == WizardPage.Conclusion: Conclusion { @@ -62,7 +77,7 @@ export component SetupWizard inherits Window { if root.page == WizardPage.Intro { root.page = WizardPage.Firmware; } else if root.page == WizardPage.Firmware { - install-firmware.show(); + install-firmware(); } else if root.page == WizardPage.Conclusion { finish(); } @@ -70,10 +85,36 @@ export component SetupWizard inherits Window { } } - install-firmware := InstallFirmware { + firmware-popup := InstallFirmware { x: 10px; y: 150px; width: parent.width - 20px; height: parent.height - 300px; + status: firmware-status; + progress: firmware-progress; + } + + error-popup := ErrorPopup { + x: 10px; + y: (parent.height / 2) - 50px; + width: parent.width - 20px; + message: error-message; + close-clicked => { + error-message = ""; + } + } + + changed firmware-installer => { + if firmware-installer == FirmwareInstaller.Running { + firmware-popup.show(); + } + } + + changed error-message => { + if error-message == "" { + error-popup.close(); + } else { + error-popup.show(); + } } } diff --git a/gui/ui/setup/firmware.slint b/gui/ui/setup/firmware.slint index 9749fb12e..33b26c89d 100644 --- a/gui/ui/setup/firmware.slint +++ b/gui/ui/setup/firmware.slint @@ -35,6 +35,9 @@ export component Firmware { } export component InstallFirmware inherits PopupWindow { + in property status; + in property progress; + close-on-click: false; Rectangle { @@ -50,9 +53,12 @@ export component InstallFirmware inherits PopupWindow { horizontal-alignment: center; } - ProgressIndicator { } + ProgressIndicator { + progress: progress; + } Text { + text: status; horizontal-alignment: center; } }