Switch to sdl3

This commit is contained in:
hodasemi 2025-03-27 12:30:14 +01:00
parent fcf246b2cb
commit 0adaffb27e
11 changed files with 117 additions and 250 deletions

View file

@ -49,7 +49,7 @@ hostname = { version = "0.4.0" }
trust-dns-resolver = { version = "0.23.2" } trust-dns-resolver = { version = "0.23.2" }
openxr = { version = "0.19.0", default-features = false, features = ["static"] } openxr = { version = "0.19.0", default-features = false, features = ["static"] }
openvr = { version = "0.7.0" } openvr = { version = "0.7.0" }
sdl2 = { version = "0.37.0" } sdl3 = { version = "0.14.19" }
syn = { version = "2.0.67", features = ["extra-traits", "full"] } syn = { version = "2.0.67", features = ["extra-traits", "full"] }
quote = "1.0.35" quote = "1.0.35"
proc-macro2 = "1.0.86" proc-macro2 = "1.0.86"

View file

@ -1,4 +1,3 @@
use crate::prelude::*;
use presentation::wsi::windowsystemintegration::WindowSystemIntegration; use presentation::wsi::windowsystemintegration::WindowSystemIntegration;
use anyhow::Result; use anyhow::Result;
@ -59,10 +58,6 @@ impl<'a> WindowConfig<'a> {
Ok(()) Ok(())
} }
pub fn displays(&self) -> &[Display] {
self.wsi.displays()
}
pub fn clipboard_content(&self) -> Result<Option<String>> { pub fn clipboard_content(&self) -> Result<Option<String>> {
self.wsi.clipboard_content() self.wsi.clipboard_content()
} }

View file

@ -236,7 +236,6 @@ impl Default for ContextBuilder {
width: 800, width: 800,
height: 600, height: 600,
fullscreen: false, fullscreen: false,
requested_display: None,
}, },
// os specifics // os specifics
@ -425,14 +424,6 @@ impl ContextBuilder {
presentation.event_system_mut().enable_mouse(); presentation.event_system_mut().enable_mouse();
} }
if self.enable_keyboard {
presentation.event_system_mut().enable_keyboard();
}
if self.enable_controller {
presentation.event_system_mut().enable_controller();
}
Ok(Context { Ok(Context {
core, core,
presentation, presentation,

View file

@ -48,7 +48,6 @@ impl<'a> Default for EngineCreateInfo<'a> {
width: 1600, width: 1600,
height: 900, height: 900,
fullscreen: false, fullscreen: false,
requested_display: None,
}, },
os_specific_config: OsSpecificConfig { os_specific_config: OsSpecificConfig {
enable_game_mode: true, enable_game_mode: true,

View file

@ -7,7 +7,7 @@ edition = "2024"
[dependencies] [dependencies]
vulkan-rs = { workspace = true } vulkan-rs = { workspace = true }
ui = { workspace = true } ui = { workspace = true }
sdl2 = { workspace = true } sdl3 = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
openxr = { workspace = true, optional = true } openxr = { workspace = true, optional = true }
@ -18,5 +18,5 @@ ecs = { workspace = true }
[features] [features]
OpenXR = ["openxr"] OpenXR = ["openxr"]
OpenVR = ["openvr"] OpenVR = ["openvr"]
BundleSDL = ["sdl2/bundled", "sdl2/static-link"] BundleSDL = ["sdl3/build-from-source-static"]
sound = ["ui/audio"] sound = ["ui/audio"]

View file

@ -3,7 +3,7 @@ use ui::prelude::*;
use super::controlleraxis::ControllerAxis; use super::controlleraxis::ControllerAxis;
use sdl2::{self, GameControllerSubsystem}; use sdl3::{self, GamepadSubsystem};
#[derive(PartialEq)] #[derive(PartialEq)]
enum State { enum State {
@ -32,7 +32,7 @@ impl Default for ControllerDeadzones {
} }
pub struct Controller { pub struct Controller {
_sdl2_controller: sdl2::controller::GameController, _sdl2_controller: sdl3::gamepad::Gamepad,
name: String, name: String,
id: u32, id: u32,
@ -51,7 +51,7 @@ pub struct Controller {
impl Controller { impl Controller {
pub fn new( pub fn new(
controller_subsystem: &GameControllerSubsystem, controller_subsystem: &GamepadSubsystem,
id: u32, id: u32,
deadzones: ControllerDeadzones, deadzones: ControllerDeadzones,
) -> Result<Controller> { ) -> Result<Controller> {

View file

@ -1,30 +1,27 @@
use sdl2; use sdl3::{
use sdl2::EventPump; self, EventPump, EventSubsystem, GamepadSubsystem, JoystickSubsystem, Sdl,
use sdl2::EventSubsystem; event::{Event as SdlEvent, WindowEvent},
use sdl2::GameControllerSubsystem; gamepad::{Axis, Button},
use sdl2::JoystickSubsystem; keyboard::Keycode,
use sdl2::Sdl; mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection},
use sdl2::controller::Axis; };
use sdl2::controller::Button;
use sdl2::event::{Event as SdlEvent, EventType as SdlEventType, WindowEvent};
use sdl2::keyboard::Keycode;
use sdl2::mouse::{MouseButton as SdlMouseButton, MouseUtil, MouseWheelDirection};
use ui::prelude::*; use ui::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
use crate::Result; use crate::Result;
use anyhow::anyhow;
use super::controller::{Controller, ControllerDeadzones}; use super::controller::{Controller, ControllerDeadzones};
use super::joystick::Joystick; use super::joystick::Joystick;
fn convert_button(button: Button) -> ControllerButton { fn convert_button(button: Button) -> ControllerButton {
match button { match button {
Button::A => ControllerButton::A, Button::South => ControllerButton::A,
Button::B => ControllerButton::B, Button::East => ControllerButton::B,
Button::Y => ControllerButton::Y, Button::North => ControllerButton::Y,
Button::X => ControllerButton::X, Button::West => ControllerButton::X,
Button::Start => ControllerButton::Start, Button::Start => ControllerButton::Start,
Button::Back => ControllerButton::Select, Button::Back => ControllerButton::Select,
@ -44,10 +41,10 @@ fn convert_button(button: Button) -> ControllerButton {
Button::Misc1 => ControllerButton::Misc, Button::Misc1 => ControllerButton::Misc,
Button::Paddle1 => ControllerButton::Paddle1, Button::RightPaddle1 => ControllerButton::Paddle1,
Button::Paddle2 => ControllerButton::Paddle2, Button::RightPaddle2 => ControllerButton::Paddle2,
Button::Paddle3 => ControllerButton::Paddle3, Button::LeftPaddle1 => ControllerButton::Paddle3,
Button::Paddle4 => ControllerButton::Paddle4, Button::LeftPaddle2 => ControllerButton::Paddle4,
Button::Touchpad => ControllerButton::Touchpad, Button::Touchpad => ControllerButton::Touchpad,
} }
@ -87,7 +84,7 @@ pub enum Event<'a> {
pub struct EventSystem { pub struct EventSystem {
event_pump: EventPump, event_pump: EventPump,
mouse: MouseUtil, mouse: MouseUtil,
controller_subsystem: GameControllerSubsystem, controller_subsystem: GamepadSubsystem,
joystick_subsystem: JoystickSubsystem, joystick_subsystem: JoystickSubsystem,
event_subsystem: EventSubsystem, event_subsystem: EventSubsystem,
@ -104,9 +101,7 @@ impl EventSystem {
.event_pump() .event_pump()
.map_err(|s| anyhow::Error::msg(s))?, .map_err(|s| anyhow::Error::msg(s))?,
mouse: sdl2_context.mouse(), mouse: sdl2_context.mouse(),
controller_subsystem: sdl2_context controller_subsystem: sdl2_context.gamepad().map_err(|s| anyhow::Error::msg(s))?,
.game_controller()
.map_err(|s| anyhow::Error::msg(s))?,
joystick_subsystem: sdl2_context.joystick().map_err(|s| anyhow::Error::msg(s))?, joystick_subsystem: sdl2_context.joystick().map_err(|s| anyhow::Error::msg(s))?,
event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?, event_subsystem: sdl2_context.event().map_err(|s| anyhow::Error::msg(s))?,
@ -116,17 +111,22 @@ impl EventSystem {
connected_joysticks: HashMap::new(), connected_joysticks: HashMap::new(),
}; };
event_system.connected_joysticks = (0..event_system event_system.connected_joysticks = event_system
.joystick_subsystem .joystick_subsystem
.num_joysticks() .joysticks()
.map_err(|s| anyhow::Error::msg(s))?) .map_err(|s| anyhow::Error::msg(s))?
.into_iter() .into_iter()
.map(|i| Ok((i, Joystick::new(&event_system.joystick_subsystem, i)?))) .map(|instance| {
Ok((
instance.id,
Joystick::new(&event_system.joystick_subsystem, instance)?,
))
})
.collect::<Result<HashMap<_, _>>>()?; .collect::<Result<HashMap<_, _>>>()?;
event_system.connected_controllers = (0..event_system event_system.connected_controllers = (0..event_system
.controller_subsystem .controller_subsystem
.num_joysticks() .num_gamepads()
.map_err(|s| anyhow::Error::msg(s))?) .map_err(|s| anyhow::Error::msg(s))?)
.into_iter() .into_iter()
.filter(|i| event_system.controller_subsystem.is_game_controller(*i)) .filter(|i| event_system.controller_subsystem.is_game_controller(*i))
@ -143,56 +143,18 @@ impl EventSystem {
.collect::<Result<HashMap<_, _>>>()?; .collect::<Result<HashMap<_, _>>>()?;
event_system.disable_mouse(); event_system.disable_mouse();
event_system.disable_keyboard();
event_system.disable_controller();
Ok(event_system) Ok(event_system)
} }
pub fn enable_mouse(&mut self) { pub fn enable_mouse(&mut self) {
self.event_pump.enable_event(SdlEventType::MouseMotion);
self.event_pump.enable_event(SdlEventType::MouseButtonDown);
self.event_pump.enable_event(SdlEventType::MouseButtonUp);
self.mouse.show_cursor(true); self.mouse.show_cursor(true);
} }
pub fn disable_mouse(&mut self) { pub fn disable_mouse(&mut self) {
self.event_pump.disable_event(SdlEventType::MouseMotion);
self.event_pump.disable_event(SdlEventType::MouseButtonDown);
self.event_pump.disable_event(SdlEventType::MouseButtonUp);
self.mouse.show_cursor(false); self.mouse.show_cursor(false);
} }
pub fn enable_keyboard(&mut self) {
self.event_pump.enable_event(SdlEventType::KeyUp);
self.event_pump.enable_event(SdlEventType::KeyDown);
}
pub fn disable_keyboard(&mut self) {
self.event_pump.disable_event(SdlEventType::KeyUp);
self.event_pump.disable_event(SdlEventType::KeyDown);
}
pub fn enable_controller(&mut self) {
self.event_pump
.enable_event(SdlEventType::ControllerAxisMotion);
self.event_pump
.enable_event(SdlEventType::ControllerButtonDown);
self.event_pump
.enable_event(SdlEventType::ControllerButtonUp);
}
pub fn disable_controller(&mut self) {
self.event_pump
.disable_event(SdlEventType::ControllerAxisMotion);
self.event_pump
.disable_event(SdlEventType::ControllerButtonDown);
self.event_pump
.disable_event(SdlEventType::ControllerButtonUp);
}
pub fn set_controller_axis_enable_deadzone(&mut self, deadzone: f32) { pub fn set_controller_axis_enable_deadzone(&mut self, deadzone: f32) {
self.controller_deadzones.axis_enable_deadzone = deadzone; self.controller_deadzones.axis_enable_deadzone = deadzone;
} }
@ -224,7 +186,7 @@ impl EventSystem {
for event in self.event_pump.poll_iter() { for event in self.event_pump.poll_iter() {
match event { match event {
SdlEvent::Window { win_event, .. } => match win_event { SdlEvent::Window { win_event, .. } => match win_event {
WindowEvent::Resized(w, h) | WindowEvent::SizeChanged(w, h) => { WindowEvent::Resized(w, h) => {
resize(w as u32, h as u32)?; resize(w as u32, h as u32)?;
} }
@ -262,7 +224,7 @@ impl EventSystem {
SdlEvent::MouseWheel { SdlEvent::MouseWheel {
x, y, direction, .. x, y, direction, ..
} => { } => {
event_callback(Event::MouseWheel(x, y, direction))?; event_callback(Event::MouseWheel(x as i32, y as i32, direction))?;
} }
// ------------------- Key Events --------------------- // ------------------- Key Events ---------------------
SdlEvent::KeyDown { SdlEvent::KeyDown {
@ -370,11 +332,19 @@ impl EventSystem {
event_callback(Event::ControllerAxis(&*controller))?; event_callback(Event::ControllerAxis(&*controller))?;
} }
SdlEvent::JoyDeviceAdded { which, .. } => { SdlEvent::JoyDeviceAdded { which, .. } => {
let joystick = Joystick::new(&self.joystick_subsystem, which)?; if let Some(joystick_instance) = self
.joystick_subsystem
.joysticks()
.map_err(|_| anyhow!("failed querying joysticks"))?
.into_iter()
.find(|instance| instance.id == which)
{
let joystick = Joystick::new(&self.joystick_subsystem, joystick_instance)?;
event_callback(Event::JoystickAdded(&joystick))?; event_callback(Event::JoystickAdded(&joystick))?;
self.connected_joysticks.insert(joystick.id(), joystick); self.connected_joysticks.insert(joystick.id(), joystick);
} }
}
SdlEvent::JoyDeviceRemoved { which, .. } => { SdlEvent::JoyDeviceRemoved { which, .. } => {
if let Some(joysticks) = self.connected_joysticks.remove(&which) { if let Some(joysticks) = self.connected_joysticks.remove(&which) {
event_callback(Event::JoystickRemoved(&joysticks))?; event_callback(Event::JoystickRemoved(&joysticks))?;

View file

@ -1,25 +1,24 @@
use anyhow::Result; use anyhow::Result;
use sdl2::JoystickSubsystem; use sdl3::{JoystickSubsystem, joystick::JoystickInstance};
pub struct Joystick { pub struct Joystick {
_sdl2_joystick: sdl2::joystick::Joystick, sdl2_joystick: sdl3::joystick::Joystick,
id: u32,
name: String, name: String,
} }
impl Joystick { impl Joystick {
pub fn new(joystick_subsystem: &JoystickSubsystem, id: u32) -> Result<Self> { pub fn new(joystick_subsystem: &JoystickSubsystem, instance: JoystickInstance) -> Result<Self> {
let sdl2_joystick = joystick_subsystem.open(id)?; let sdl2_joystick = joystick_subsystem.open(instance)?;
Ok(Self { Ok(Self {
name: sdl2_joystick.name(), name: sdl2_joystick.name(),
id, sdl2_joystick,
_sdl2_joystick: sdl2_joystick,
}) })
} }
pub fn id(&self) -> u32 { pub fn id(&self) -> u32 {
self.id self.sdl2_joystick.instance_id()
} }
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
@ -30,7 +29,7 @@ impl Joystick {
impl std::fmt::Debug for Joystick { impl std::fmt::Debug for Joystick {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Joystick") f.debug_struct("Joystick")
.field("id", &self.id) .field("id", &self.id())
.field("name", &self.name) .field("name", &self.name)
.finish() .finish()
} }

View file

@ -16,7 +16,7 @@ pub use crate::input::{
// wsi // wsi
pub use crate::wsi::windowsystemintegration::{Display, WindowCreateInfo}; pub use crate::wsi::windowsystemintegration::{Display, WindowCreateInfo};
pub use sdl2::{keyboard::Keycode, mouse::MouseWheelDirection}; pub use sdl3::{keyboard::Keycode, mouse::MouseWheelDirection};
pub use vulkan_rs::prelude::*; pub use vulkan_rs::prelude::*;

View file

@ -7,7 +7,7 @@ use crate::xri::openxrintegration::OpenXRIntegration;
use crate::Result; use crate::Result;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use sdl2::Sdl; use sdl3::Sdl;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -88,8 +88,8 @@ impl PresentationCore {
window_create_info: &WindowCreateInfo, window_create_info: &WindowCreateInfo,
appl_info: ApplicationInfo, appl_info: ApplicationInfo,
) -> Result<PresentationCore> { ) -> Result<PresentationCore> {
// create sdl2 context // create sdl3 context
let context = sdl2::init().map_err(|s| anyhow::Error::msg(s))?; let context = sdl3::init().map_err(|s| anyhow::Error::msg(s))?;
Ok(PresentationCore { Ok(PresentationCore {
event_system: EventSystem::new(&context)?, event_system: EventSystem::new(&context)?,

View file

@ -1,20 +1,20 @@
// needed since RLS won't accept #[repr(C)] // needed since RLS won't accept #[repr(C)]
#![allow(improper_ctypes)] #![allow(improper_ctypes)]
use anyhow::Error; use anyhow::{Error, anyhow};
use sdl2;
use sdl2::Sdl; use sdl3::{
use sdl2::clipboard::ClipboardUtil; self, Sdl,
use sdl2::messagebox::{MessageBoxFlag, show_simple_message_box}; clipboard::ClipboardUtil,
use sdl2::mouse::Cursor; messagebox::{MessageBoxFlag, show_simple_message_box},
use sdl2::surface::Surface as SDL_Surface; mouse::Cursor,
use sdl2::sys::SDL_Window; surface::Surface as SDL_Surface,
use sdl2::video::{FullscreenType, WindowPos}; video::{FullscreenType, WindowPos},
};
use crate::Result; use crate::Result;
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
use std::mem::MaybeUninit;
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::sync::{ use std::sync::{
@ -22,30 +22,12 @@ use std::sync::{
atomic::{AtomicI32, AtomicU32, Ordering::SeqCst}, atomic::{AtomicI32, AtomicU32, Ordering::SeqCst},
}; };
const SDL_SYSWM_WINDOWS: u32 = 0x1;
const SDL_SYSWM_X11: u32 = 0x2;
const SDL_SYSWM_COCOA: u32 = 0x4;
const SDL_SYSWM_WAYLAND: u32 = 0x6;
const SDL_SYSWM_ANDROID: u32 = 0x9;
#[repr(C)]
struct SdlSysWmInfo {
version: sdl2::version::Version,
subsystem: u32,
info: [u64; 32],
}
unsafe extern "C" {
fn SDL_GetWindowWMInfo(window: *const sdl2::sys::SDL_Window, info: *mut SdlSysWmInfo) -> bool;
}
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct WindowCreateInfo { pub struct WindowCreateInfo {
pub title: String, pub title: String,
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
pub fullscreen: bool, pub fullscreen: bool,
pub requested_display: Option<String>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -57,8 +39,6 @@ pub struct Display {
pub y: i32, pub y: i32,
pub w: u32, pub w: u32,
pub h: u32, pub h: u32,
pub dpi: [f32; 3],
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
@ -70,7 +50,7 @@ struct CellRect {
} }
impl CellRect { impl CellRect {
fn update_from_window(&self, window: &sdl2::video::Window) { fn update_from_window(&self, window: &sdl3::video::Window) {
let (w, h) = window.size(); let (w, h) = window.size();
let (x, y) = window.position(); let (x, y) = window.position();
@ -80,7 +60,7 @@ impl CellRect {
self.height.store(h, SeqCst); self.height.store(h, SeqCst);
} }
fn update_to_window(&self, window: &mut sdl2::video::Window) -> Result<()> { fn update_to_window(&self, window: &mut sdl3::video::Window) -> Result<()> {
set_window_size(window, self.width.load(SeqCst), self.height.load(SeqCst))?; set_window_size(window, self.width.load(SeqCst), self.height.load(SeqCst))?;
window.set_position( window.set_position(
WindowPos::Positioned(self.x.load(SeqCst)), WindowPos::Positioned(self.x.load(SeqCst)),
@ -93,15 +73,12 @@ impl CellRect {
pub struct WindowSystemIntegration { pub struct WindowSystemIntegration {
// sdl // sdl
_video_subsystem: Mutex<sdl2::VideoSubsystem>, _video_subsystem: Mutex<sdl3::VideoSubsystem>,
window: Mutex<sdl2::video::Window>, window: Mutex<sdl3::video::Window>,
clipboard_util: ClipboardUtil, clipboard_util: ClipboardUtil,
cursor: Mutex<Option<Cursor>>, cursor: Mutex<Option<Cursor>>,
displays: Vec<Display>,
_enabled_display_index: usize,
pre_fullscreen_rect: CellRect, pre_fullscreen_rect: CellRect,
surface: Mutex<Option<Arc<Surface>>>, surface: Mutex<Option<Arc<Surface>>>,
@ -119,8 +96,8 @@ impl WindowSystemIntegration {
let video_subsystem = context.video().map_err(|s| anyhow::Error::msg(s))?; let video_subsystem = context.video().map_err(|s| anyhow::Error::msg(s))?;
// query display count // query display count
let display_count = match video_subsystem.num_video_displays() { let display_count = match video_subsystem.displays() {
Ok(num_displays) => num_displays, Ok(displays) => displays.len(),
Err(_) => 0, Err(_) => 0,
}; };
@ -128,78 +105,35 @@ impl WindowSystemIntegration {
return Err(anyhow::Error::msg("No display where detected!")); return Err(anyhow::Error::msg("No display where detected!"));
} }
// query display information // // query display information
let mut displays = Vec::with_capacity(display_count as usize); // let mut displays = Vec::with_capacity(display_count as usize);
for i in 0..display_count { // for display in video_subsystem
let rect = video_subsystem // .displays()
.display_bounds(i) // .map_err(|_| anyhow!("failed querying displays"))?
.map_err(|s| anyhow::Error::msg(s))?; // {
let name = video_subsystem // let rect = display.get_bounds().map_err(|s| anyhow::Error::msg(s))?;
.display_name(i) // let name = display.get_name().map_err(|s| anyhow::Error::msg(s))?;
.map_err(|s| anyhow::Error::msg(s))?;
let (dpi0, dpi1, dpi2) = match video_subsystem.display_dpi(i) { // let display = Display {
Ok(dpis) => dpis, // name,
Err(msg) => {
println!("failed getting dpi for display {} ({}): {}", i, name, msg);
(0.0, 0.0, 0.0)
}
};
let display = Display { // x: rect.x(),
name, // y: rect.y(),
// w: rect.width(),
// h: rect.height(),
// };
x: rect.x(), // displays.push(display);
y: rect.y(), // }
w: rect.width(),
h: rect.height(),
dpi: [dpi0, dpi1, dpi2],
};
displays.push(display);
}
// check if there is an preferred display
let mut display_index = None;
if let Some(requested_display) = &create_info.requested_display {
match displays
.iter()
.position(|display| display.name == *requested_display)
{
Some(index) => display_index = Some(index),
None => {
println!("could not find display: {}", requested_display);
println!("defaulting to display 0 ({})", displays[0].name);
}
}
}
// build window // build window
let mut window_builder = let mut window_builder =
video_subsystem.window(&create_info.title, create_info.width, create_info.height); video_subsystem.window(&create_info.title, create_info.width, create_info.height);
window_builder.resizable().vulkan(); window_builder.resizable().vulkan();
match display_index {
Some(index) => {
let display = &displays[index];
window_builder.position(
display.x + display.w as i32 / 2,
display.y + display.h as i32 / 2,
);
}
None => {
window_builder.position_centered(); window_builder.position_centered();
}
}
let window = window_builder.build()?; let window = window_builder.build()?;
display_index = Some(window.display_index().map_err(|s| anyhow::Error::msg(s))? as usize);
let rect = CellRect::default(); let rect = CellRect::default();
rect.update_from_window(&window); rect.update_from_window(&window);
@ -210,10 +144,6 @@ impl WindowSystemIntegration {
cursor: Mutex::new(None), cursor: Mutex::new(None),
displays,
_enabled_display_index: display_index.expect("display index not set"),
pre_fullscreen_rect: rect, pre_fullscreen_rect: rect,
surface: Mutex::new(None), surface: Mutex::new(None),
@ -246,20 +176,21 @@ impl WindowSystemIntegration {
self.pre_fullscreen_rect.update_from_window(&window); self.pre_fullscreen_rect.update_from_window(&window);
// set fullscreen size to fit display // set fullscreen size to fit display
let display = let display = window.get_display().map_err(|s| anyhow!(s))?;
&self.displays[window.display_index().map_err(|s| anyhow::Error::msg(s))? as usize]; let rect = display.get_bounds().map_err(|s| anyhow!(s))?;
set_window_size(&mut window, display.w, display.h)?;
set_window_size(&mut window, rect.w as u32, rect.h as u32)?;
window.set_bordered(false); window.set_bordered(false);
// change fullscreen mode // change fullscreen mode
window window
.set_fullscreen(FullscreenType::True) .set_fullscreen(true)
.map_err(|s| anyhow::Error::msg(s))?; .map_err(|s| anyhow::Error::msg(s))?;
} else { } else {
// change fullscreen mode // change fullscreen mode
window window
.set_fullscreen(FullscreenType::Off) .set_fullscreen(false)
.map_err(|s| anyhow::Error::msg(s))?; .map_err(|s| anyhow::Error::msg(s))?;
// force window borders // force window borders
@ -371,22 +302,16 @@ impl WindowSystemIntegration {
Ok(()) Ok(())
} }
fn raw_sdl2_window(&self) -> *mut SDL_Window {
self.window.lock().unwrap().raw()
}
pub fn displays(&self) -> &[Display] {
&self.displays
}
pub fn create_vulkan_surface(&self, instance: &Arc<Instance>) -> Result<()> { pub fn create_vulkan_surface(&self, instance: &Arc<Instance>) -> Result<()> {
let vk_surface = self let vk_surface = unsafe {
.window core::mem::transmute(
self.window
.lock() .lock()
.unwrap() .unwrap()
.vulkan_create_surface(instance.vk_handle().raw()) .vulkan_create_surface(core::mem::transmute(instance.vk_handle().raw()))
.map_err(|s| anyhow::Error::msg(s))? .map_err(|s| anyhow::Error::msg(s))?,
.into(); )
};
*self.surface.lock().unwrap() = Some(Surface::from_vk_surface(vk_surface, instance)); *self.surface.lock().unwrap() = Some(Surface::from_vk_surface(vk_surface, instance));
@ -401,28 +326,16 @@ impl WindowSystemIntegration {
&self, &self,
extensions: &mut InstanceExtensions, extensions: &mut InstanceExtensions,
) -> Result<()> { ) -> Result<()> {
let sys_wm_info: SdlSysWmInfo = unsafe { let driver = self._video_subsystem.lock().unwrap().current_video_driver();
let tmp = MaybeUninit::zeroed();
let mut ret: SdlSysWmInfo = tmp.assume_init();
ret.version = sdl2::version::version();
SDL_GetWindowWMInfo(self.raw_sdl2_window(), &mut ret); match driver {
"android" => extensions.android_surface = true,
"cocoa" => extensions.macos_surface = true,
"x11" => extensions.xlib_surface = true,
"wayland" => extensions.wayland_surface = true,
"windows" => extensions.win32_surface = true,
ret _ => panic!("unsupported video driver: {driver}"),
};
match sys_wm_info.subsystem {
SDL_SYSWM_ANDROID => extensions.android_surface = true,
SDL_SYSWM_COCOA => extensions.macos_surface = true,
SDL_SYSWM_WAYLAND => extensions.wayland_surface = true,
SDL_SYSWM_WINDOWS => extensions.win32_surface = true,
SDL_SYSWM_X11 => extensions.xlib_surface = true,
_ => {
return Err(anyhow::Error::msg(format!(
"Unsupported window subsystem flag {}",
sys_wm_info.subsystem
)));
}
} }
extensions.surface = true; extensions.surface = true;
@ -448,7 +361,7 @@ impl std::fmt::Debug for WindowSystemIntegration {
/// helper function to wrap SDL2 error types /// helper function to wrap SDL2 error types
#[inline] #[inline]
fn set_window_size(window: &mut sdl2::video::Window, width: u32, height: u32) -> Result<()> { fn set_window_size(window: &mut sdl3::video::Window, width: u32, height: u32) -> Result<()> {
window.set_size(width, height)?; window.set_size(width, height)?;
Ok(()) Ok(())