diff --git a/Cargo.lock b/Cargo.lock
index 20ec92d0c..eb90a635b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1594,6 +1594,7 @@ dependencies = [
"thiserror 2.0.3",
"uuid",
"windows-sys 0.59.0",
+ "winit",
"winres",
"x86-64",
"xdg",
diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt
index 4e20e16e3..25b893fb4 100644
--- a/gui/CMakeLists.txt
+++ b/gui/CMakeLists.txt
@@ -5,8 +5,7 @@ find_package(Threads REQUIRED)
# Setup GUI.
add_executable(obliteration WIN32 MACOSX_BUNDLE
main.cpp
- main_window.cpp
- resources.qrc)
+ main_window.cpp)
set_target_properties(obliteration PROPERTIES AUTOMOC ON AUTORCC ON)
diff --git a/gui/Cargo.toml b/gui/Cargo.toml
index 45d1a0572..3a5ee9dc0 100644
--- a/gui/Cargo.toml
+++ b/gui/Cargo.toml
@@ -24,6 +24,7 @@ redb = "2.2.0"
serde = { version = "1.0.209", features = ["derive"] }
thiserror = "2.0.3"
uuid = { version = "1.11.0", features = ["serde", "v4"] }
+winit = "0.30.5"
[dependencies.obfw]
git = "https://github.com/obhq/firmware-dumper.git"
diff --git a/gui/main.cpp b/gui/main.cpp
index 2f4d2ef30..44d1821ff 100644
--- a/gui/main.cpp
+++ b/gui/main.cpp
@@ -25,8 +25,6 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
- QGuiApplication::setWindowIcon(QIcon(":/resources/obliteration-icon.png"));
-
// Setup main window.
MainWindow win;
diff --git a/gui/resources.qrc b/gui/resources.qrc
deleted file mode 100644
index fc410c5d5..000000000
--- a/gui/resources.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- resources/obliteration-icon.png
-
-
diff --git a/gui/resources/obliteration-icon.png b/gui/resources/obliteration-icon.png
deleted file mode 100644
index 2af4030af..000000000
Binary files a/gui/resources/obliteration-icon.png and /dev/null differ
diff --git a/gui/src/hv/mod.rs b/gui/src/hv/mod.rs
index 1cd1d8960..d25fa506e 100644
--- a/gui/src/hv/mod.rs
+++ b/gui/src/hv/mod.rs
@@ -60,7 +60,7 @@ pub trait Cpu {
type Exit<'a>: CpuExit
where
Self: 'a;
- type TranslateErr: Error + Send + 'static;
+ type TranslateErr: Error + Send + Sync + 'static;
fn id(&self) -> usize;
diff --git a/gui/src/main.rs b/gui/src/main.rs
index 4b66c827a..0c3b7b9c4 100644
--- a/gui/src/main.rs
+++ b/gui/src/main.rs
@@ -1,16 +1,13 @@
#![windows_subsystem = "windows"]
use self::data::{DataError, DataMgr};
-use self::debug::DebugClient;
use self::graphics::{Graphics, GraphicsError, PhysicalDevice, Screen};
use self::profile::Profile;
use self::setup::{run_setup, SetupError};
use self::ui::{ErrorWindow, MainWindow, ProfileModel, ResolutionModel};
-use self::vmm::{Vmm, VmmError};
+use self::vmm::{Vmm, VmmArgs, VmmError, VmmEvent};
use clap::{Parser, ValueEnum};
use debug::DebugServer;
-use gdbstub::stub::MultiThreadStopReason;
-use obconf::ConsoleType;
use slint::{ComponentHandle, ModelRc, SharedString, VecModel};
use std::cell::Cell;
use std::error::Error;
@@ -20,6 +17,8 @@ use std::process::ExitCode;
use std::rc::Rc;
use std::sync::Arc;
use thiserror::Error;
+use winit::error::EventLoopError;
+use winit::event_loop::EventLoop;
mod data;
mod debug;
@@ -39,7 +38,7 @@ fn main() -> ExitCode {
use std::fmt::Write;
// Check program mode.
- let args = CliArgs::parse();
+ let args = ProgramArgs::parse();
let r = match &args.mode {
Some(ProgramMode::PanicHandler) => self::panic::run_handler(),
None => run_vmm(&args),
@@ -75,23 +74,23 @@ fn main() -> ExitCode {
ExitCode::FAILURE
}
-fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
+fn run_vmm(args: &ProgramArgs) -> Result<(), ProgramError> {
// Spawn panic handler.
let exe = std::env::current_exe()
.and_then(std::fs::canonicalize)
- .map_err(ApplicationError::GetCurrentExePath)?;
+ .map_err(ProgramError::GetCurrentExePath)?;
self::panic::spawn_handler(&exe)?;
#[cfg(unix)]
- rlim::set_rlimit_nofile().map_err(ApplicationError::FdLimit)?;
+ rlim::set_rlimit_nofile().map_err(ProgramError::FdLimit)?;
// Initialize graphics engine.
- let mut graphics = graphics::new().map_err(ApplicationError::InitGraphics)?;
+ let mut graphics = graphics::new().map_err(ProgramError::InitGraphics)?;
// Run setup wizard. This will simply return the data manager if the user already has required
// settings.
- let data = match run_setup().map_err(ApplicationError::Setup)? {
+ let data = match run_setup().map_err(ProgramError::Setup)? {
Some(v) => Arc::new(v),
None => return Ok(()),
};
@@ -123,9 +122,9 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
// Load profiles.
let mut profiles = Vec::new();
- for l in data.prof().list().map_err(ApplicationError::ListProfile)? {
- let l = l.map_err(ApplicationError::ListProfile)?;
- let p = Profile::load(&l).map_err(ApplicationError::LoadProfile)?;
+ for l in data.prof().list().map_err(ProgramError::ListProfile)? {
+ let l = l.map_err(ProgramError::ListProfile)?;
+ let p = Profile::load(&l).map_err(ProgramError::LoadProfile)?;
profiles.push(p);
}
@@ -137,11 +136,11 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
let l = data.prof().data(p.id());
if let Err(e) = std::fs::create_dir(&l) {
- return Err(ApplicationError::CreateDirectory(l, e));
+ return Err(ProgramError::CreateDirectory(l, e));
}
// Save.
- p.save(&l).map_err(ApplicationError::SaveDefaultProfile)?;
+ p.save(&l).map_err(ProgramError::SaveDefaultProfile)?;
profiles.push(p);
}
@@ -165,11 +164,11 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
// Wait for debugger.
let debugger = if let Some(listen) = debug {
let debug_server =
- DebugServer::new(listen).map_err(|e| ApplicationError::StartDebugServer(e, listen))?;
+ DebugServer::new(listen).map_err(|e| ProgramError::StartDebugServer(e, listen))?;
let debugger = debug_server
.accept()
- .map_err(ApplicationError::CreateDebugClient)?;
+ .map_err(ProgramError::CreateDebugClient)?;
Some(debugger)
} else {
@@ -177,27 +176,31 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
};
// Setup VMM screen.
+ let mut el = EventLoop::::with_user_event();
+
let screen = graphics
.create_screen(&profile)
- .map_err(|e| ApplicationError::CreateScreen(Box::new(e)))?;
+ .map_err(|e| ProgramError::CreateScreen(Box::new(e)))?;
// Start VMM.
+ let el = el.build().map_err(ProgramError::CreateVmmEventLoop)?;
+
std::thread::scope(|scope| {
let vmm = Vmm::new(
VmmArgs {
profile: &profile,
kernel,
debugger,
+ el: el.create_proxy(),
},
- VmmHandler {},
scope,
)
- .map_err(ApplicationError::StartVmm)?;
+ .map_err(ProgramError::StartVmm)?;
// Run the screen.
screen
.run()
- .map_err(|e| ApplicationError::RunScreen(Box::new(e)))?;
+ .map_err(|e| ProgramError::RunScreen(Box::new(e)))?;
Ok(())
})
@@ -207,9 +210,9 @@ fn run_launcher(
graphics: &impl Graphics,
data: &Arc,
profiles: Vec,
-) -> Result