Skip to content

Commit

Permalink
Merge pull request #1165 from OlegOAndreev/display-orientation
Browse files Browse the repository at this point in the history
Added display orientation support
  • Loading branch information
Cobrand authored Nov 12, 2021
2 parents 8bddddb + 33cbec8 commit fe411c6
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 4 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
121 changes: 117 additions & 4 deletions src/sdl2/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -516,6 +579,11 @@ pub enum Event {
timestamp: u32,
},

Display {
timestamp: u32,
display_index: i32,
display_event: DisplayEvent,
},
Window {
timestamp: u32,
window_id: u32,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 { .. })
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2496,7 +2598,7 @@ impl crate::EventPump {
/// for event in event_pump.poll_iter() {
/// use sdl2::event::Event;
/// match event {
/// Event::KeyDown {..} => { /*...*/ },
/// Event::KeyDown {..} => { /*...*/ }
/// _ => ()
/// }
/// }
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand Down
52 changes: 52 additions & 0 deletions src/sdl2/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 can’t 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)
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit fe411c6

Please sign in to comment.