Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added display orientation support #1165

Merged
merged 2 commits into from
Nov 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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