Extracts handle and xdg_toplevel methods from WinitWindow into DesktopWindow (#1263)

This commit is contained in:
Putta Khunchalee
2025-01-26 14:54:08 +01:00
committed by GitHub
parent 5c2624d7e2
commit b062760f2f
20 changed files with 116 additions and 112 deletions
+1
View File
@@ -0,0 +1 @@
*.svg binary
+5 -1
View File
@@ -6,6 +6,8 @@
Obliteration is a free and open-source PlayStation 4 kernel rewritten in Rust. Our goal is not running on the PlayStation 4 but to run the dumped PlayStation 4 system software on Windows, Linux and macOS using a custom made virtualization stack optimized specifically for Obliteration.
<p align="center"><img alt="Architecture" src="architecture.svg"></p>
This project started as a hard-fork from [Kyty](https://github.com/InoriRus/Kyty). Then we decided to rewrite the whole project from scratch by using Kyty and [Uplift](https://github.com/idc/uplift) as a reference to help us getting started with the project.
Our ultimate goal is to become a permissive free and open-source operating system optimized for gaming that can run on a variety of hardware. The reason we want to built this because:
@@ -21,7 +23,9 @@ The project logo and icon was designed by [VocalFan](https://github.com/VocalFan
## Status
Currently we cannot run any games yet. The reason it take so long is because we try to implement things without stubbing as much as possible.
Currently we cannot run any games yet. What we have is a working [64-bit](https://en.wikipedia.org/wiki/Long_mode) kernel and the VMM to run it. The kernel has been successfully setup [GDT](https://en.wikipedia.org/wiki/Global_Descriptor_Table), [TSS](https://en.wikipedia.org/wiki/Task_state_segment), [IDT](https://en.wikipedia.org/wiki/Interrupt_descriptor_table) and [syscall](https://en.wikipedia.org/wiki/System_call) instruction. Right now we are working on [UMA](https://man.freebsd.org/cgi/man.cgi?query=uma) system. Once this finished we will start migrating code from our [legacy user-mode kernel](https://github.com/obhq/obliteration/tree/main/legacy/src) then execute `mini-syscore.elf`.
The reason it take so long is because we try to implement the kernel without stubbing as much as possible.
## Key features
+4
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 130 KiB

+4 -4
View File
@@ -1,5 +1,6 @@
use super::Metal;
use crate::rt::{Hook, WindowHandler, WinitWindow};
use crate::ui::DesktopWindow;
use metal::{CAMetalLayer, MetalLayer};
use objc::runtime::{Object, NO, YES};
use objc::{msg_send, sel, sel_impl};
@@ -56,11 +57,10 @@ impl WinitWindow for MetalWindow {
fn id(&self) -> WindowId {
self.window.id()
}
}
fn handle(&self) -> impl HasWindowHandle + '_
where
Self: Sized,
{
impl DesktopWindow for MetalWindow {
fn handle(&self) -> impl HasWindowHandle + '_ {
&self.window
}
}
+4 -4
View File
@@ -1,6 +1,7 @@
use super::engine::Vulkan;
use super::GraphicsError;
use crate::rt::{Hook, WindowHandler, WinitWindow};
use crate::ui::DesktopWindow;
use ash::vk::SurfaceKHR;
use raw_window_handle::HasWindowHandle;
use std::error::Error;
@@ -50,11 +51,10 @@ impl WinitWindow for VulkanWindow {
fn id(&self) -> WindowId {
self.window.id()
}
}
fn handle(&self) -> impl HasWindowHandle + '_
where
Self: Sized,
{
impl DesktopWindow for VulkanWindow {
fn handle(&self) -> impl HasWindowHandle + '_ {
&self.window
}
+1 -1
View File
@@ -8,7 +8,7 @@ use self::log::LogWriter;
use self::profile::{DisplayResolution, Profile};
use self::setup::{run_setup, SetupError};
use self::ui::{
DesktopWindow, MainWindow, ProfileModel, ResolutionModel, RuntimeExt, SlintBackend,
DesktopExt, MainWindow, ProfileModel, ResolutionModel, RuntimeExt, SlintBackend,
WaitForDebugger,
};
use self::vmm::{CpuError, Vmm, VmmError, VmmEvent};
-6
View File
@@ -1,4 +1,3 @@
use raw_window_handle::HasWindowHandle;
use std::error::Error;
use winit::dpi::{PhysicalPosition, PhysicalSize};
use winit::event::{DeviceId, ElementState, InnerSizeWriter, MouseButton};
@@ -34,9 +33,4 @@ pub trait WindowHandler: WinitWindow {
/// Provides method to return winit properties.
pub trait WinitWindow {
fn id(&self) -> WindowId;
fn handle(&self) -> impl HasWindowHandle + '_
where
Self: Sized;
#[cfg(target_os = "linux")]
fn xdg_toplevel(&self) -> *mut std::ffi::c_void;
}
+2 -2
View File
@@ -4,8 +4,8 @@ use self::data::{read_data_root, write_data_root};
use crate::data::{DataError, DataMgr};
use crate::rt::yield_now;
use crate::ui::{
error, open_dir, open_file, spawn_handler, DesktopWindow, FileType, InstallFirmware,
RuntimeExt, SetupWizard,
error, open_dir, open_file, spawn_handler, DesktopExt, FileType, InstallFirmware, RuntimeExt,
SetupWizard,
};
use crate::vfs::{FsType, FS_TYPE};
use erdp::ErrorDisplay;
+4 -14
View File
@@ -57,6 +57,10 @@ impl Window {
.unwrap()
}
pub fn winit(&self) -> &winit::window::Window {
&self.winit
}
pub fn hidden(&self) -> &Signal<()> {
&self.hidden
}
@@ -66,20 +70,6 @@ impl WinitWindow for Window {
fn id(&self) -> WindowId {
self.winit.id()
}
fn handle(&self) -> impl HasWindowHandle + '_
where
Self: Sized,
{
&self.winit
}
#[cfg(target_os = "linux")]
fn xdg_toplevel(&self) -> *mut std::ffi::c_void {
use winit::platform::wayland::WindowExtWayland;
self.winit.xdg_toplevel()
}
}
impl WindowHandler for Window {
+5 -5
View File
@@ -1,5 +1,5 @@
use crate::rt::{global, WinitWindow};
use crate::ui::{FileType, SlintBackend};
use crate::rt::global;
use crate::ui::{DesktopWindow, FileType, SlintBackend};
use ashpd::desktop::file_chooser::{FileFilter, SelectedFiles};
use ashpd::desktop::ResponseError;
use ashpd::WindowIdentifier;
@@ -11,7 +11,7 @@ use wayland_client::protocol::wl_surface::WlSurface;
use wayland_client::Proxy;
use wayland_protocols::xdg::foreign::zv2::client::zxdg_exported_v2::ZxdgExportedV2;
pub async fn open_file<T: WinitWindow>(
pub async fn open_file<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
ty: FileType,
@@ -46,7 +46,7 @@ pub async fn open_file<T: WinitWindow>(
Some(resp.uris().first().unwrap().to_file_path().unwrap())
}
pub async fn open_dir<T: WinitWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
// Send the request
let parent = get_parent_id(parent);
let req = SelectedFiles::open_file()
@@ -74,7 +74,7 @@ pub async fn open_dir<T: WinitWindow>(parent: &T, title: impl AsRef<str>) -> Opt
fn get_parent_id<P>(parent: &P) -> Parent
where
P: WinitWindow,
P: DesktopWindow,
{
// Check window type.
let parent = parent.handle();
+6 -6
View File
@@ -1,8 +1,8 @@
pub use self::dialogs::*;
use self::modal::Modal;
use super::{DesktopWindow, SlintBackend};
use crate::rt::{global, WinitWindow};
use super::{DesktopExt, DesktopWindow, SlintBackend};
use crate::rt::global;
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use thiserror::Error;
@@ -10,11 +10,11 @@ mod dialogs;
mod modal;
mod wayland;
impl<T: WinitWindow> DesktopWindow for T {
impl<T: DesktopWindow> DesktopExt for T {
type Modal<'a, P>
= Modal<'a, Self, P>
where
P: WinitWindow + 'a;
P: DesktopWindow + 'a;
fn set_center(&self) -> Result<(), PlatformError> {
let win = self.handle();
@@ -33,7 +33,7 @@ impl<T: WinitWindow> DesktopWindow for T {
fn set_modal<P>(self, parent: &P) -> Result<Modal<Self, P>, PlatformError>
where
P: WinitWindow,
P: DesktopWindow,
Self: Sized,
{
let back = global::<SlintBackend>().unwrap();
@@ -49,7 +49,7 @@ impl<T: WinitWindow> DesktopWindow for T {
}
}
/// Linux-specific error for [`PlatformExt`].
/// Linux-specific error for [`DesktopExt`].
#[derive(Debug, Error)]
pub enum PlatformError {
#[error("couldn't create xdg_dialog_v1")]
+6 -5
View File
@@ -1,18 +1,19 @@
use crate::rt::{block, Blocker, WinitWindow};
use crate::rt::{block, Blocker};
use crate::ui::DesktopWindow;
use std::ops::Deref;
use wayland_protocols::xdg::dialog::v1::client::xdg_dialog_v1::XdgDialogV1;
/// Encapsulates a modal window and its parent.
///
/// This struct forces the modal window to be dropped before its parent.
pub struct Modal<'a, W, P: WinitWindow> {
pub struct Modal<'a, W, P: DesktopWindow> {
window: W,
wayland: Option<XdgDialogV1>,
#[allow(dead_code)]
blocker: Blocker<'a, P>,
}
impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Modal<'a, W, P> {
pub fn new(window: W, parent: &'a P, wayland: Option<XdgDialogV1>) -> Self {
Self {
window,
@@ -22,7 +23,7 @@ impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
}
}
impl<'a, W, P: WinitWindow> Drop for Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Drop for Modal<'a, W, P> {
fn drop(&mut self) {
if let Some(v) = self.wayland.take() {
v.destroy();
@@ -30,7 +31,7 @@ impl<'a, W, P: WinitWindow> Drop for Modal<'a, W, P> {
}
}
impl<'a, W, P: WinitWindow> Deref for Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Deref for Modal<'a, W, P> {
type Target = W;
fn deref(&self) -> &Self::Target {
+4 -5
View File
@@ -1,6 +1,5 @@
use super::PlatformError;
use crate::rt::WinitWindow;
use crate::ui::Wayland;
use crate::ui::{DesktopWindow, Wayland};
use wayland_backend::sys::client::ObjectId;
use wayland_client::Proxy;
use wayland_protocols::xdg::dialog::v1::client::xdg_dialog_v1::XdgDialogV1;
@@ -10,8 +9,8 @@ use wayland_protocols::xdg::shell::client::xdg_toplevel::XdgToplevel;
/// `parent` must outlive `target`.
pub unsafe fn set_modal(
wayland: &Wayland,
target: &impl WinitWindow,
parent: &impl WinitWindow,
target: &impl DesktopWindow,
parent: &impl DesktopWindow,
) -> Result<XdgDialogV1, PlatformError> {
// Get xdg_toplevel for parent.
let mut queue = wayland.queue().borrow_mut();
@@ -40,7 +39,7 @@ pub unsafe fn set_modal(
/// # Safety
/// `win` must outlive the returned [`XdgToplevel`].
unsafe fn get_xdg_toplevel(wayland: &Wayland, win: &impl WinitWindow) -> XdgToplevel {
unsafe fn get_xdg_toplevel(wayland: &Wayland, win: &impl DesktopWindow) -> XdgToplevel {
let obj = win.xdg_toplevel();
let obj = ObjectId::from_ptr(XdgToplevel::interface(), obj.cast()).unwrap();
+3 -4
View File
@@ -1,8 +1,7 @@
use crate::rt::WinitWindow;
use crate::ui::FileType;
use crate::ui::{DesktopWindow, FileType};
use std::path::PathBuf;
pub async fn open_file<T: WinitWindow>(
pub async fn open_file<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
ty: FileType,
@@ -10,6 +9,6 @@ pub async fn open_file<T: WinitWindow>(
todo!();
}
pub async fn open_dir<T: WinitWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
todo!()
}
+5 -6
View File
@@ -2,8 +2,7 @@ pub use self::dialogs::*;
use self::modal::Modal;
use self::view::with_window;
use super::DesktopWindow;
use crate::rt::WinitWindow;
use super::{DesktopExt, DesktopWindow};
use block::ConcreteBlock;
use objc::{msg_send, sel, sel_impl};
use std::ffi::c_long;
@@ -14,11 +13,11 @@ mod dialogs;
mod modal;
mod view;
impl<T: WinitWindow> DesktopWindow for T {
impl<T: DesktopWindow> DesktopExt for T {
type Modal<'a, P>
= Modal<'a, Self, P>
where
P: WinitWindow + 'a;
P: DesktopWindow + 'a;
fn set_center(&self) -> Result<(), PlatformError> {
with_window::<()>(self.handle(), |win| unsafe { msg_send![win, center] });
@@ -28,7 +27,7 @@ impl<T: WinitWindow> DesktopWindow for T {
fn set_modal<P>(self, parent: &P) -> Result<Modal<Self, P>, PlatformError>
where
P: WinitWindow,
P: DesktopWindow,
Self: Sized,
{
// Setup completionHandler.
@@ -45,6 +44,6 @@ impl<T: WinitWindow> DesktopWindow for T {
}
}
/// macOS-specific error for [`DesktopWindow`].
/// macOS-specific error for [`DesktopExt`].
#[derive(Debug, Error)]
pub enum PlatformError {}
+5 -4
View File
@@ -1,16 +1,17 @@
use crate::rt::{block, Blocker, WinitWindow};
use crate::rt::{block, Blocker};
use crate::ui::DesktopWindow;
use std::ops::Deref;
/// Encapsulates a modal window and its parent.
///
/// This struct forces the modal window to be dropped before its parent.
pub struct Modal<'a, W, P: WinitWindow> {
pub struct Modal<'a, W, P: DesktopWindow> {
window: W,
#[allow(dead_code)]
blocker: Blocker<'a, P>,
}
impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Modal<'a, W, P> {
pub(super) fn new(window: W, parent: &'a P) -> Self {
Self {
window,
@@ -19,7 +20,7 @@ impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
}
}
impl<'a, W, P: WinitWindow> Deref for Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Deref for Modal<'a, W, P> {
type Target = W;
fn deref(&self) -> &Self::Target {
+20 -7
View File
@@ -31,7 +31,7 @@ where
spawn_blocker(w, f);
}
pub async fn error<P: WinitWindow>(parent: Option<&P>, msg: impl Into<SharedString>) {
pub async fn error<P: DesktopWindow>(parent: Option<&P>, msg: impl Into<SharedString>) {
let win = ErrorWindow::new().unwrap();
win.set_message(msg.into());
@@ -55,27 +55,40 @@ pub async fn error<P: WinitWindow>(parent: Option<&P>, msg: impl Into<SharedStri
impl<T: ComponentHandle> WinitWindow for T {
fn id(&self) -> WindowId {
let win = WindowInner::from_pub(self.window()).window_adapter();
let win = Window::from_adapter(win.as_ref());
Window::from_adapter(win.as_ref()).id()
win.id()
}
}
impl<T: ComponentHandle> DesktopWindow for T {
fn handle(&self) -> impl HasWindowHandle + '_ {
self.window().window_handle()
}
#[cfg(target_os = "linux")]
fn xdg_toplevel(&self) -> *mut std::ffi::c_void {
let win = WindowInner::from_pub(self.window()).window_adapter();
use winit::platform::wayland::WindowExtWayland;
Window::from_adapter(win.as_ref()).xdg_toplevel()
let win = WindowInner::from_pub(self.window()).window_adapter();
let win = Window::from_adapter(win.as_ref());
win.winit().xdg_toplevel()
}
}
/// Provides methods to operate on a desktop window.
/// Provides methods to return platform-specific handle for a desktop window.
pub trait DesktopWindow: WinitWindow {
fn handle(&self) -> impl HasWindowHandle + '_;
#[cfg(target_os = "linux")]
fn xdg_toplevel(&self) -> *mut std::ffi::c_void;
}
/// Provides methods to operate on a [`DesktopWindow`].
pub trait DesktopExt: DesktopWindow {
type Modal<'a, P>: Deref<Target = Self>
where
P: WinitWindow + 'a;
P: DesktopWindow + 'a;
/// Center window on the screen.
///
@@ -84,7 +97,7 @@ pub trait DesktopWindow: WinitWindow {
fn set_center(&self) -> Result<(), PlatformError>;
fn set_modal<P>(self, parent: &P) -> Result<Self::Modal<'_, P>, PlatformError>
where
P: WinitWindow,
P: DesktopWindow,
Self: Sized;
}
+27 -28
View File
@@ -1,5 +1,4 @@
use crate::rt::WinitWindow;
use crate::ui::FileType;
use crate::ui::{DesktopWindow, FileType};
use futures::channel::oneshot;
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use std::future::Future;
@@ -11,31 +10,7 @@ use windows_sys::Win32::UI::Shell::{
SHBrowseForFolderW, SHGetPathFromIDListW, BIF_NEWDIALOGSTYLE, BIF_RETURNONLYFSDIRS, BROWSEINFOW,
};
fn get_hwnd<T: WinitWindow>(parent: &T) -> NonZero<isize> {
let parent = parent.handle();
let parent = parent.window_handle().unwrap();
let RawWindowHandle::Win32(win) = parent.as_ref() else {
unreachable!();
};
win.hwnd
}
fn spawn_dialog<F>(dialog_fn: F) -> impl Future<Output = Option<PathBuf>>
where
F: Send + 'static + FnOnce() -> Option<PathBuf>,
{
let (tx, rx) = oneshot::channel();
std::thread::spawn(move || {
let res = dialog_fn();
tx.send(res).unwrap();
});
async move { rx.await.unwrap_or(None) }
}
pub async fn open_file<T: WinitWindow>(
pub async fn open_file<T: DesktopWindow>(
parent: &T,
title: impl AsRef<str>,
ty: FileType,
@@ -43,7 +18,7 @@ pub async fn open_file<T: WinitWindow>(
todo!()
}
pub async fn open_dir<T: WinitWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
pub async fn open_dir<T: DesktopWindow>(parent: &T, title: impl AsRef<str>) -> Option<PathBuf> {
let hwnd = get_hwnd(parent);
let title_wide: Vec<u16> = title
@@ -81,3 +56,27 @@ pub async fn open_dir<T: WinitWindow>(parent: &T, title: impl AsRef<str>) -> Opt
})
.await
}
fn get_hwnd<T: DesktopWindow>(parent: &T) -> NonZero<isize> {
let parent = parent.handle();
let parent = parent.window_handle().unwrap();
let RawWindowHandle::Win32(win) = parent.as_ref() else {
unreachable!();
};
win.hwnd
}
fn spawn_dialog<F>(dialog_fn: F) -> impl Future<Output = Option<PathBuf>>
where
F: Send + 'static + FnOnce() -> Option<PathBuf>,
{
let (tx, rx) = oneshot::channel();
std::thread::spawn(move || {
let res = dialog_fn();
tx.send(res).unwrap();
});
async move { rx.await.unwrap_or(None) }
}
+5 -6
View File
@@ -1,8 +1,7 @@
pub use self::dialogs::*;
use self::modal::Modal;
use super::DesktopWindow;
use crate::rt::WinitWindow;
use super::{DesktopExt, DesktopWindow};
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use std::io::Error;
use std::mem::zeroed;
@@ -16,11 +15,11 @@ use windows_sys::Win32::UI::WindowsAndMessaging::{
mod dialogs;
mod modal;
impl<T: WinitWindow> DesktopWindow for T {
impl<T: DesktopWindow> DesktopExt for T {
type Modal<'a, P>
= Modal<'a, Self, P>
where
P: WinitWindow + 'a;
P: DesktopWindow + 'a;
fn set_center(&self) -> Result<(), PlatformError> {
// Get HWND.
@@ -69,14 +68,14 @@ impl<T: WinitWindow> DesktopWindow for T {
fn set_modal<P>(self, parent: &P) -> Result<Modal<Self, P>, PlatformError>
where
P: WinitWindow,
P: DesktopWindow,
Self: Sized,
{
todo!()
}
}
/// Windows-specific error for [`DesktopWindow`].
/// Windows-specific error for [`DesktopExt`].
#[derive(Debug, Error)]
pub enum PlatformError {
#[error("couldn't get window rectangle")]
+5 -4
View File
@@ -1,16 +1,17 @@
use crate::rt::{block, Blocker, WinitWindow};
use crate::rt::{block, Blocker};
use crate::ui::DesktopWindow;
use std::ops::Deref;
/// Encapsulates a modal window and its parent.
///
/// This struct forces the modal window to be dropped before its parent.
pub struct Modal<'a, W, P: WinitWindow> {
pub struct Modal<'a, W, P: DesktopWindow> {
window: W,
#[allow(dead_code)]
blocker: Blocker<'a, P>,
}
impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Modal<'a, W, P> {
pub(super) fn new(window: W, parent: &'a P) -> Self {
Self {
window,
@@ -19,7 +20,7 @@ impl<'a, W, P: WinitWindow> Modal<'a, W, P> {
}
}
impl<'a, W, P: WinitWindow> Deref for Modal<'a, W, P> {
impl<'a, W, P: DesktopWindow> Deref for Modal<'a, W, P> {
type Target = W;
fn deref(&self) -> &Self::Target {