Added binding for SDL_GetDisplayOrientation and SDL_DISPLAYEVENT.

This commit is contained in:
Oleg Andreev
2021-11-01 17:17:02 +03:00
parent 3400b5df0d
commit c46694849e
3 changed files with 171 additions and 4 deletions
+2
View File
@@ -5,6 +5,8 @@ when upgrading from a version of rust-sdl2 to another.
[PR #1164](https://github.com/Rust-SDL2/rust-sdl2/pull/1164) Added raw-window-handle support for Android
[PR #1165](https://github.com/Rust-SDL2/rust-sdl2/pull/1165) Added binding for `SDL_GetDisplayOrientation` and `SDL_DISPLAYEVENT`
### v0.35.0
* **BREAKING CHANGE** Update `sdl2-sys/sdl_bindings.rs` to use enums instead of consts. If you were using `sdl2-sys`'s
+117 -4
View File
@@ -2,8 +2,6 @@
Event Handling
*/
use libc::c_int;
use libc::c_void;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::convert::TryFrom;
@@ -15,6 +13,9 @@ use std::mem::transmute;
use std::ptr;
use std::sync::Mutex;
use libc::c_int;
use libc::c_void;
use crate::controller;
use crate::controller::{Axis, Button};
use crate::get_error;
@@ -26,10 +27,10 @@ use crate::keyboard::Mod;
use crate::keyboard::Scancode;
use crate::mouse;
use crate::mouse::{MouseButton, MouseState, MouseWheelDirection};
use crate::sys;
use crate::sys::SDL_EventFilter;
use crate::sys::SDL_EventType;
use crate::video::Orientation;
struct CustomEventTypeMaps {
sdl_id_to_type_id: HashMap<u32, ::std::any::TypeId>,
@@ -272,6 +273,7 @@ pub enum EventType {
AppWillEnterForeground = SDL_EventType::SDL_APP_WILLENTERFOREGROUND as u32,
AppDidEnterForeground = SDL_EventType::SDL_APP_DIDENTERFOREGROUND as u32,
Display = SDL_EventType::SDL_DISPLAYEVENT as u32,
Window = SDL_EventType::SDL_WINDOWEVENT as u32,
// TODO: SysWM = sys::SDL_SYSWMEVENT as u32,
KeyDown = SDL_EventType::SDL_KEYDOWN as u32,
@@ -342,6 +344,7 @@ impl TryFrom<u32> for EventType {
SDL_APP_WILLENTERFOREGROUND => AppWillEnterForeground,
SDL_APP_DIDENTERFOREGROUND => AppDidEnterForeground,
SDL_DISPLAYEVENT => Display,
SDL_WINDOWEVENT => Window,
SDL_KEYDOWN => KeyDown,
@@ -398,6 +401,66 @@ impl TryFrom<u32> for EventType {
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
/// An enum of display events.
pub enum DisplayEvent {
None,
Orientation(Orientation),
Connected,
Disconnected,
}
impl DisplayEvent {
#[allow(clippy::match_same_arms)]
fn from_ll(id: u8, data1: i32) -> DisplayEvent {
if id > sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_DISCONNECTED as u8 {
return DisplayEvent::None;
}
match unsafe { transmute(id as u32) } {
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_NONE => DisplayEvent::None,
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_ORIENTATION => {
let orientation = if data1 as u32
> sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT_FLIPPED as u32
{
Orientation::Unknown
} else {
Orientation::from_ll(unsafe { transmute(data1 as u32) })
};
DisplayEvent::Orientation(orientation)
}
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_CONNECTED => DisplayEvent::Connected,
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_DISCONNECTED => DisplayEvent::Disconnected,
}
}
fn to_ll(&self) -> (u8, i32) {
match *self {
DisplayEvent::None => (sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_NONE as u8, 0),
DisplayEvent::Orientation(orientation) => (
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_ORIENTATION as u8,
orientation.to_ll() as i32,
),
DisplayEvent::Connected => {
(sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_CONNECTED as u8, 0)
}
DisplayEvent::Disconnected => (
sys::SDL_DisplayEventID::SDL_DISPLAYEVENT_DISCONNECTED as u8,
0,
),
}
}
pub fn is_same_kind_as(&self, other: &DisplayEvent) -> bool {
match (self, other) {
(Self::None, Self::None)
| (Self::Orientation(_), Self::Orientation(_))
| (Self::Connected, Self::Connected)
| (Self::Disconnected, Self::Disconnected) => true,
_ => false,
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
/// An enum of window events.
pub enum WindowEvent {
@@ -516,6 +579,11 @@ pub enum Event {
timestamp: u32,
},
Display {
timestamp: u32,
display_index: i32,
display_event: DisplayEvent,
},
Window {
timestamp: u32,
window_id: u32,
@@ -810,6 +878,7 @@ pub enum Event {
/// store pointers to types that are `!Send`. Dereferencing these as pointers
/// requires using `unsafe` and ensuring your own safety guarantees.
unsafe impl Send for Event {}
/// This does not auto-derive because `User`'s `data` fields can be used to
/// store pointers to types that are `!Sync`. Dereferencing these as pointers
/// requires using `unsafe` and ensuring your own safety guarantees.
@@ -880,6 +949,28 @@ impl Event {
}
}
Event::Display {
timestamp,
display_index,
display_event,
} => {
let (display_event_id, data1) = display_event.to_ll();
let event = sys::SDL_DisplayEvent {
type_: SDL_EventType::SDL_DISPLAYEVENT as u32,
timestamp,
display: display_index as u32,
event: display_event_id,
padding1: 0,
padding2: 0,
padding3: 0,
data1,
};
unsafe {
ptr::copy(&event, ret.as_mut_ptr() as *mut sys::SDL_DisplayEvent, 1);
Some(ret.assume_init())
}
}
Event::Window {
timestamp,
window_id,
@@ -1389,6 +1480,15 @@ impl Event {
}
}
EventType::Display => {
let event = raw.display;
Event::Display {
timestamp: event.timestamp,
display_index: event.display as i32,
display_event: DisplayEvent::from_ll(event.event, event.data1),
}
}
EventType::Window => {
let event = raw.window;
@@ -1885,6 +1985,7 @@ impl Event {
| (Self::AppDidEnterBackground { .. }, Self::AppDidEnterBackground { .. })
| (Self::AppWillEnterForeground { .. }, Self::AppWillEnterForeground { .. })
| (Self::AppDidEnterForeground { .. }, Self::AppDidEnterForeground { .. })
| (Self::Display { .. }, Self::Display { .. })
| (Self::Window { .. }, Self::Window { .. })
| (Self::KeyDown { .. }, Self::KeyDown { .. })
| (Self::KeyUp { .. }, Self::KeyUp { .. })
@@ -1953,6 +2054,7 @@ impl Event {
Self::AppDidEnterBackground { timestamp, .. } => timestamp,
Self::AppWillEnterForeground { timestamp, .. } => timestamp,
Self::AppDidEnterForeground { timestamp, .. } => timestamp,
Self::Display { timestamp, .. } => timestamp,
Self::Window { timestamp, .. } => timestamp,
Self::KeyDown { timestamp, .. } => timestamp,
Self::KeyUp { timestamp, .. } => timestamp,
@@ -2496,7 +2598,7 @@ impl crate::EventPump {
/// for event in event_pump.poll_iter() {
/// use sdl2::event::Event;
/// match event {
/// Event::KeyDown {..} => { /*...*/ },
/// Event::KeyDown {..} => { /*...*/ }
/// _ => ()
/// }
/// }
@@ -2608,6 +2710,8 @@ mod test {
use super::super::joystick::HatState;
use super::super::keyboard::{Keycode, Mod, Scancode};
use super::super::mouse::{MouseButton, MouseState, MouseWheelDirection};
use super::super::video::Orientation;
use super::DisplayEvent;
use super::Event;
use super::WindowEvent;
@@ -2620,6 +2724,15 @@ mod test {
let e2 = Event::from_ll(e.clone().to_ll().unwrap());
assert_eq!(e, e2);
}
{
let e = Event::Display {
timestamp: 0,
display_index: 1,
display_event: DisplayEvent::Orientation(Orientation::LandscapeFlipped),
};
let e2 = Event::from_ll(e.clone().to_ll().unwrap());
assert_eq!(e, e2);
}
{
let e = Event::Window {
timestamp: 0,
+52
View File
@@ -591,6 +591,52 @@ impl From<i32> for SwapInterval {
}
}
/// Represents orientation of a display.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
#[repr(i32)]
pub enum Orientation {
/// The display orientation cant be determined
Unknown = sys::SDL_DisplayOrientation::SDL_ORIENTATION_UNKNOWN as i32,
/// The display is in landscape mode, with the right side up, relative to portrait mode
Landscape = sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE as i32,
/// The display is in landscape mode, with the left side up, relative to portrait mode
LandscapeFlipped = sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE_FLIPPED as i32,
/// The display is in portrait mode
Portrait = sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT as i32,
/// The display is in portrait mode, upside down
PortraitFlipped = sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT_FLIPPED as i32,
}
impl Orientation {
pub fn from_ll(orientation: sys::SDL_DisplayOrientation) -> Orientation {
match orientation {
sys::SDL_DisplayOrientation::SDL_ORIENTATION_UNKNOWN => Orientation::Unknown,
sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE => Orientation::Landscape,
sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE_FLIPPED => {
Orientation::LandscapeFlipped
}
sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT => Orientation::Portrait,
sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT_FLIPPED => {
Orientation::PortraitFlipped
}
}
}
pub fn to_ll(self) -> sys::SDL_DisplayOrientation {
match self {
Orientation::Unknown => sys::SDL_DisplayOrientation::SDL_ORIENTATION_UNKNOWN,
Orientation::Landscape => sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE,
Orientation::LandscapeFlipped => {
sys::SDL_DisplayOrientation::SDL_ORIENTATION_LANDSCAPE_FLIPPED
}
Orientation::Portrait => sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT,
Orientation::PortraitFlipped => {
sys::SDL_DisplayOrientation::SDL_ORIENTATION_PORTRAIT_FLIPPED
}
}
}
}
/// Represents the "shell" of a `Window`.
///
/// You can set get and set many of the `SDL_Window` properties (i.e., border, size, `PixelFormat`, etc)
@@ -781,6 +827,12 @@ impl VideoSubsystem {
}
}
/// Return orientation of a display or Unknown if orientation could not be determined.
#[doc(alias = "SDL_GetDisplayOrientation")]
pub fn display_orientation(&self, display_index: i32) -> Orientation {
Orientation::from_ll(unsafe { sys::SDL_GetDisplayOrientation(display_index as c_int) })
}
#[doc(alias = "SDL_IsScreenSaverEnabled")]
pub fn is_screen_saver_enabled(&self) -> bool {
unsafe { sys::SDL_IsScreenSaverEnabled() == sys::SDL_bool::SDL_TRUE }