mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 05:21:31 +11:00
Events loop backend (#269)
* Don't use UNIX_BACKEND in Window2::new * Move get_available_monitors and get_primary_monitor to EventsLoop * Remove UNIX_BACKEND * Restore choosing the Linux backend * Return a XNotSupported for new_x11() * Fix fullscreen example
This commit is contained in:
parent
e65cacbc86
commit
3d1c18ded9
|
@ -4,9 +4,11 @@ use std::io::{self, Write};
|
|||
use winit::{ControlFlow, Event, WindowEvent, FullScreenState};
|
||||
|
||||
fn main() {
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
|
||||
// enumerating monitors
|
||||
let monitor = {
|
||||
for (num, monitor) in winit::get_available_monitors().enumerate() {
|
||||
for (num, monitor) in events_loop.get_available_monitors().enumerate() {
|
||||
println!("Monitor #{}: {:?}", num, monitor.get_name());
|
||||
}
|
||||
|
||||
|
@ -16,15 +18,13 @@ fn main() {
|
|||
let mut num = String::new();
|
||||
io::stdin().read_line(&mut num).unwrap();
|
||||
let num = num.trim().parse().ok().expect("Please enter a number");
|
||||
let monitor = winit::get_available_monitors().nth(num).expect("Please enter a valid ID");
|
||||
let monitor = events_loop.get_available_monitors().nth(num).expect("Please enter a valid ID");
|
||||
|
||||
println!("Using {:?}", monitor.get_name());
|
||||
|
||||
monitor
|
||||
};
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
|
||||
let _window = winit::WindowBuilder::new()
|
||||
.with_title("Hello world!")
|
||||
.with_fullscreen(FullScreenState::Exclusive(monitor))
|
||||
|
|
|
@ -24,6 +24,16 @@ macro_rules! gen_api_transition {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> ::std::collections::VecDeque<MonitorId> {
|
||||
get_available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||
get_primary_monitor()
|
||||
}
|
||||
|
||||
pub fn poll_events<F>(&mut self, mut callback: F)
|
||||
where F: FnMut(::Event)
|
||||
{
|
||||
|
|
32
src/lib.rs
32
src/lib.rs
|
@ -116,7 +116,7 @@ extern crate x11_dl;
|
|||
extern crate wayland_client;
|
||||
|
||||
pub use events::*;
|
||||
pub use window::{AvailableMonitorsIter, MonitorId, get_available_monitors, get_primary_monitor};
|
||||
pub use window::{AvailableMonitorsIter, MonitorId};
|
||||
|
||||
#[macro_use]
|
||||
mod api_transition;
|
||||
|
@ -201,6 +201,36 @@ impl EventsLoop {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the list of all available monitors.
|
||||
///
|
||||
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||
/// > and if it fails will fallback on x11.
|
||||
/// >
|
||||
/// > If this variable is set with any other value, winit will panic.
|
||||
// Note: should be replaced with `-> impl Iterator` once stable.
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> AvailableMonitorsIter {
|
||||
let data = self.events_loop.get_available_monitors();
|
||||
AvailableMonitorsIter{ data: data.into_iter() }
|
||||
}
|
||||
|
||||
/// Returns the primary monitor of the system.
|
||||
///
|
||||
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||
/// > and if it fails will fallback on x11.
|
||||
/// >
|
||||
/// > If this variable is set with any other value, winit will panic.
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||
MonitorId { inner: self.events_loop.get_primary_monitor() }
|
||||
}
|
||||
|
||||
/// Fetches all the events that are pending, calls the callback function for each of them,
|
||||
/// and returns.
|
||||
#[inline]
|
||||
|
|
|
@ -3,21 +3,42 @@
|
|||
use std::sync::Arc;
|
||||
use std::ptr;
|
||||
use libc;
|
||||
use EventsLoop;
|
||||
use MonitorId;
|
||||
use Window;
|
||||
use platform::EventsLoop as LinuxEventsLoop;
|
||||
use platform::Window2 as LinuxWindow;
|
||||
use platform::{UnixBackend, UNIX_BACKEND};
|
||||
use WindowBuilder;
|
||||
use platform::x11::XConnection;
|
||||
use platform::x11::ffi::XVisualInfo;
|
||||
|
||||
pub use platform::x11;
|
||||
pub use platform::XNotSupported;
|
||||
|
||||
// TODO: do not expose XConnection
|
||||
pub fn get_x11_xconnection() -> Option<Arc<XConnection>> {
|
||||
match *UNIX_BACKEND {
|
||||
UnixBackend::X(ref connec) => Some(connec.clone()),
|
||||
_ => None,
|
||||
/// Additional methods on `EventsLoop` that are specific to Linux.
|
||||
pub trait EventsLoopExt {
|
||||
/// Builds a new `EventsLoop` that is forced to use X11.
|
||||
fn new_x11() -> Result<Self, XNotSupported>
|
||||
where Self: Sized;
|
||||
|
||||
/// Builds a new `EventsLoop` that is forced to use Wayland.
|
||||
fn new_wayland() -> Self
|
||||
where Self: Sized;
|
||||
}
|
||||
|
||||
impl EventsLoopExt for EventsLoop {
|
||||
#[inline]
|
||||
fn new_x11() -> Result<Self, XNotSupported> {
|
||||
LinuxEventsLoop::new_x11().map(|ev| EventsLoop { events_loop: ev })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_wayland() -> Self {
|
||||
EventsLoop {
|
||||
events_loop: match LinuxEventsLoop::new_wayland() {
|
||||
Ok(e) => e,
|
||||
Err(_) => panic!() // TODO: propagate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,10 @@ use libc;
|
|||
|
||||
use self::x11::XConnection;
|
||||
use self::x11::XError;
|
||||
use self::x11::XNotSupported;
|
||||
use self::x11::ffi::XVisualInfo;
|
||||
|
||||
pub use self::x11::XNotSupported;
|
||||
|
||||
mod dlopen;
|
||||
pub mod wayland;
|
||||
pub mod x11;
|
||||
|
@ -31,106 +32,36 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
|||
pub screen_id: Option<i32>,
|
||||
}
|
||||
|
||||
pub enum UnixBackend {
|
||||
X(Arc<XConnection>),
|
||||
Wayland(Arc<wayland::WaylandContext>),
|
||||
Error(Option<XNotSupported>, Option<String>),
|
||||
}
|
||||
|
||||
lazy_static!(
|
||||
pub static ref UNIX_BACKEND: UnixBackend = {
|
||||
#[inline]
|
||||
fn x_backend() -> Result<UnixBackend, XNotSupported> {
|
||||
match XConnection::new(Some(x_error_callback)) {
|
||||
Ok(x) => Ok(UnixBackend::X(Arc::new(x))),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn wayland_backend() -> Result<UnixBackend, ()> {
|
||||
wayland::WaylandContext::init()
|
||||
.map(|ctx| UnixBackend::Wayland(Arc::new(ctx)))
|
||||
.ok_or(())
|
||||
}
|
||||
match env::var(BACKEND_PREFERENCE_ENV_VAR) {
|
||||
Ok(s) => match s.as_str() {
|
||||
"x11" => x_backend().unwrap_or_else(|e| UnixBackend::Error(Some(e), None)),
|
||||
"wayland" => wayland_backend().unwrap_or_else(|_| {
|
||||
UnixBackend::Error(None, Some("Wayland not available".into()))
|
||||
}),
|
||||
_ => panic!("Unknown environment variable value for {}, try one of `x11`,`wayland`",
|
||||
BACKEND_PREFERENCE_ENV_VAR),
|
||||
},
|
||||
Err(_) => {
|
||||
// Try wayland, fallback to X11
|
||||
wayland_backend().unwrap_or_else(|_| {
|
||||
x_backend().unwrap_or_else(|x_err| {
|
||||
UnixBackend::Error(Some(x_err), Some("Wayland not available".into()))
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
pub static ref X11_BACKEND: Result<Arc<XConnection>, XNotSupported> = {
|
||||
XConnection::new(Some(x_error_callback)).map(Arc::new)
|
||||
};
|
||||
);
|
||||
|
||||
|
||||
pub enum Window2 {
|
||||
#[doc(hidden)]
|
||||
X(x11::Window2),
|
||||
#[doc(hidden)]
|
||||
Wayland(wayland::Window)
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum WindowId {
|
||||
#[doc(hidden)]
|
||||
X(x11::WindowId),
|
||||
#[doc(hidden)]
|
||||
Wayland(wayland::WindowId)
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum DeviceId {
|
||||
#[doc(hidden)]
|
||||
X(x11::DeviceId),
|
||||
#[doc(hidden)]
|
||||
Wayland(wayland::DeviceId)
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum MonitorId {
|
||||
#[doc(hidden)]
|
||||
X(x11::MonitorId),
|
||||
#[doc(hidden)]
|
||||
Wayland(wayland::MonitorId),
|
||||
#[doc(hidden)]
|
||||
None,
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
||||
match *UNIX_BACKEND {
|
||||
UnixBackend::Wayland(ref ctxt) => wayland::get_available_monitors(ctxt)
|
||||
.into_iter()
|
||||
.map(MonitorId::Wayland)
|
||||
.collect(),
|
||||
UnixBackend::X(ref connec) => x11::get_available_monitors(connec)
|
||||
.into_iter()
|
||||
.map(MonitorId::X)
|
||||
.collect(),
|
||||
UnixBackend::Error(..) => { let mut d = VecDeque::new(); d.push_back(MonitorId::None); d},
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor() -> MonitorId {
|
||||
match *UNIX_BACKEND {
|
||||
UnixBackend::Wayland(ref ctxt) => MonitorId::Wayland(wayland::get_primary_monitor(ctxt)),
|
||||
UnixBackend::X(ref connec) => MonitorId::X(x11::get_primary_monitor(connec)),
|
||||
UnixBackend::Error(..) => MonitorId::None,
|
||||
}
|
||||
}
|
||||
|
||||
impl MonitorId {
|
||||
#[inline]
|
||||
pub fn get_name(&self) -> Option<String> {
|
||||
|
@ -167,24 +98,14 @@ impl Window2 {
|
|||
pl_attribs: &PlatformSpecificWindowBuilderAttributes)
|
||||
-> Result<Self, CreationError>
|
||||
{
|
||||
match *UNIX_BACKEND {
|
||||
UnixBackend::Wayland(ref ctxt) => {
|
||||
if let EventsLoop::Wayland(ref evlp) = *events_loop {
|
||||
wayland::Window::new(evlp, ctxt.clone(), window).map(Window2::Wayland)
|
||||
} else {
|
||||
// It is not possible to instanciate an EventsLoop not matching its backend
|
||||
unreachable!()
|
||||
}
|
||||
match *events_loop {
|
||||
EventsLoop::Wayland(ref evlp) => {
|
||||
wayland::Window::new(evlp, window).map(Window2::Wayland)
|
||||
},
|
||||
|
||||
UnixBackend::X(_) => {
|
||||
x11::Window2::new(events_loop, window, pl_attribs).map(Window2::X)
|
||||
EventsLoop::X(ref el) => {
|
||||
x11::Window2::new(el, window, pl_attribs).map(Window2::X)
|
||||
},
|
||||
UnixBackend::Error(..) => {
|
||||
// If the Backend is Error(), it is not possible to instanciate an EventsLoop at all,
|
||||
// thus this function cannot be called!
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,7 +253,7 @@ unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x
|
|||
{
|
||||
use std::ffi::CStr;
|
||||
|
||||
if let UnixBackend::X(ref x) = *UNIX_BACKEND {
|
||||
if let Ok(ref x) = *X11_BACKEND {
|
||||
let mut buff: Vec<u8> = Vec::with_capacity(1024);
|
||||
(x.xlib.XGetErrorText)(dpy, (*event).error_code as i32, buff.as_mut_ptr() as *mut libc::c_char, buff.capacity() as i32);
|
||||
let description = CStr::from_ptr(buff.as_mut_ptr() as *const libc::c_char).to_string_lossy();
|
||||
|
@ -351,9 +272,7 @@ unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x
|
|||
}
|
||||
|
||||
pub enum EventsLoop {
|
||||
#[doc(hidden)]
|
||||
Wayland(wayland::EventsLoop),
|
||||
#[doc(hidden)]
|
||||
X(x11::EventsLoop)
|
||||
}
|
||||
|
||||
|
@ -364,19 +283,66 @@ pub enum EventsLoopProxy {
|
|||
|
||||
impl EventsLoop {
|
||||
pub fn new() -> EventsLoop {
|
||||
match *UNIX_BACKEND {
|
||||
UnixBackend::Wayland(ref ctxt) => {
|
||||
EventsLoop::Wayland(wayland::EventsLoop::new(ctxt.clone()))
|
||||
},
|
||||
|
||||
UnixBackend::X(ref ctxt) => {
|
||||
EventsLoop::X(x11::EventsLoop::new(ctxt.clone()))
|
||||
},
|
||||
|
||||
UnixBackend::Error(..) => {
|
||||
panic!("Attempted to create an EventsLoop while no backend was available.")
|
||||
if let Ok(env_var) = env::var(BACKEND_PREFERENCE_ENV_VAR) {
|
||||
match env_var.as_str() {
|
||||
"x11" => {
|
||||
return EventsLoop::new_x11().unwrap(); // TODO: propagate
|
||||
},
|
||||
"wayland" => {
|
||||
match EventsLoop::new_wayland() {
|
||||
Ok(e) => return e,
|
||||
Err(_) => panic!() // TODO: propagate
|
||||
}
|
||||
},
|
||||
_ => panic!("Unknown environment variable value for {}, try one of `x11`,`wayland`",
|
||||
BACKEND_PREFERENCE_ENV_VAR),
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(el) = EventsLoop::new_wayland() {
|
||||
return el;
|
||||
}
|
||||
|
||||
if let Ok(el) = EventsLoop::new_x11() {
|
||||
return el;
|
||||
}
|
||||
|
||||
panic!("No backend is available")
|
||||
}
|
||||
|
||||
pub fn new_wayland() -> Result<EventsLoop, ()> {
|
||||
wayland::WaylandContext::init()
|
||||
.map(|ctx| EventsLoop::Wayland(wayland::EventsLoop::new(Arc::new(ctx))))
|
||||
.ok_or(())
|
||||
}
|
||||
|
||||
pub fn new_x11() -> Result<EventsLoop, XNotSupported> {
|
||||
match *X11_BACKEND {
|
||||
Ok(ref x) => Ok(EventsLoop::X(x11::EventsLoop::new(x.clone()))),
|
||||
Err(ref err) => Err(err.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
|
||||
match *self {
|
||||
EventsLoop::Wayland(ref evlp) => wayland::get_available_monitors(evlp.context())
|
||||
.into_iter()
|
||||
.map(MonitorId::Wayland)
|
||||
.collect(),
|
||||
EventsLoop::X(ref evlp) => x11::get_available_monitors(evlp.x_connection())
|
||||
.into_iter()
|
||||
.map(MonitorId::X)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||
match *self {
|
||||
EventsLoop::Wayland(ref evlp) => MonitorId::Wayland(wayland::get_primary_monitor(evlp.context())),
|
||||
EventsLoop::X(ref evlp) => MonitorId::X(x11::get_primary_monitor(evlp.x_connection())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventsLoopProxy {
|
||||
|
|
|
@ -131,6 +131,11 @@ impl EventsLoop {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn context(&self) -> &Arc<WaylandContext> {
|
||||
&self.ctxt
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventsLoopProxy {
|
||||
EventsLoopProxy {
|
||||
ctxt: Arc::downgrade(&self.ctxt),
|
||||
|
|
|
@ -37,8 +37,9 @@ pub fn make_wid(s: &wl_surface::WlSurface) -> WindowId {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(evlp: &EventsLoop, ctxt: Arc<WaylandContext>, attributes: &WindowAttributes) -> Result<Window, CreationError>
|
||||
pub fn new(evlp: &EventsLoop, attributes: &WindowAttributes) -> Result<Window, CreationError>
|
||||
{
|
||||
let ctxt = evlp.context().clone();
|
||||
let (width, height) = attributes.dimensions.unwrap_or((800,600));
|
||||
|
||||
let (surface, decorated) = ctxt.create_window::<DecoratedHandler>(width, height);
|
||||
|
|
|
@ -120,6 +120,12 @@ impl EventsLoop {
|
|||
result
|
||||
}
|
||||
|
||||
/// Returns the `XConnection` of this events loop.
|
||||
#[inline]
|
||||
pub fn x_connection(&self) -> &Arc<XConnection> {
|
||||
&self.display
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventsLoopProxy {
|
||||
EventsLoopProxy {
|
||||
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
|
||||
|
@ -675,12 +681,11 @@ lazy_static! { // TODO: use a static mutex when that's possible, and put me
|
|||
}
|
||||
|
||||
impl Window2 {
|
||||
pub fn new(events_loop: &::platform::EventsLoop,
|
||||
pub fn new(x_events_loop: &EventsLoop,
|
||||
window: &::WindowAttributes,
|
||||
pl_attribs: &PlatformSpecificWindowBuilderAttributes)
|
||||
-> Result<Self, CreationError>
|
||||
{
|
||||
let x_events_loop = if let ::platform::EventsLoop::X(ref e) = *events_loop { e } else { unreachable!() };
|
||||
let win = ::std::sync::Arc::new(try!(Window::new(&x_events_loop, window, pl_attribs)));
|
||||
|
||||
// creating IM
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![cfg(target_os = "macos")]
|
||||
|
||||
pub use self::events_loop::{EventsLoop, Proxy as EventsLoopProxy};
|
||||
pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};
|
||||
pub use self::monitor::MonitorId;
|
||||
pub use self::window::{Id as WindowId, PlatformSpecificWindowBuilderAttributes, Window};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
use core_graphics::display;
|
||||
use std::collections::VecDeque;
|
||||
use super::EventsLoop;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MonitorId(u32);
|
||||
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
||||
let mut monitors = VecDeque::new();
|
||||
unsafe {
|
||||
let max_displays = 10u32;
|
||||
let mut active_displays = [0u32; 10];
|
||||
let mut display_count = 0;
|
||||
display::CGGetActiveDisplayList(max_displays, &mut active_displays[0], &mut display_count);
|
||||
for i in 0..display_count as usize {
|
||||
monitors.push_back(MonitorId(active_displays[i]));
|
||||
impl EventsLoop {
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
|
||||
let mut monitors = VecDeque::new();
|
||||
unsafe {
|
||||
let max_displays = 10u32;
|
||||
let mut active_displays = [0u32; 10];
|
||||
let mut display_count = 0;
|
||||
display::CGGetActiveDisplayList(max_displays, &mut active_displays[0], &mut display_count);
|
||||
for i in 0..display_count as usize {
|
||||
monitors.push_back(MonitorId(active_displays[i]));
|
||||
}
|
||||
}
|
||||
monitors
|
||||
}
|
||||
monitors
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_primary_monitor() -> MonitorId {
|
||||
let id = unsafe { MonitorId(display::CGMainDisplayID()) };
|
||||
id
|
||||
#[inline]
|
||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||
let id = unsafe { MonitorId(display::CGMainDisplayID()) };
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
impl MonitorId {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use winapi;
|
||||
|
||||
pub use self::events_loop::{EventsLoop, EventsLoopProxy};
|
||||
pub use self::monitor::{MonitorId, get_available_monitors, get_primary_monitor};
|
||||
pub use self::monitor::MonitorId;
|
||||
pub use self::window::Window;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
|
|
@ -4,6 +4,8 @@ use user32;
|
|||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
|
||||
use super::EventsLoop;
|
||||
|
||||
/// Win32 implementation of the main `MonitorId` object.
|
||||
#[derive(Clone)]
|
||||
pub struct MonitorId {
|
||||
|
@ -90,61 +92,61 @@ fn wchar_as_string(wchar: &[winapi::WCHAR]) -> String {
|
|||
.to_string()
|
||||
}
|
||||
|
||||
/// Win32 implementation of the main `get_available_monitors` function.
|
||||
pub fn get_available_monitors() -> VecDeque<MonitorId> {
|
||||
// return value
|
||||
let mut result = VecDeque::new();
|
||||
impl EventsLoop {
|
||||
pub fn get_available_monitors(&self) -> VecDeque<MonitorId> {
|
||||
// return value
|
||||
let mut result = VecDeque::new();
|
||||
|
||||
for adapter in DeviceEnumerator::adapters() {
|
||||
// getting the position
|
||||
let (position, dimensions) = unsafe {
|
||||
let mut dev: winapi::DEVMODEW = mem::zeroed();
|
||||
dev.dmSize = mem::size_of::<winapi::DEVMODEW>() as winapi::WORD;
|
||||
for adapter in DeviceEnumerator::adapters() {
|
||||
// getting the position
|
||||
let (position, dimensions) = unsafe {
|
||||
let mut dev: winapi::DEVMODEW = mem::zeroed();
|
||||
dev.dmSize = mem::size_of::<winapi::DEVMODEW>() as winapi::WORD;
|
||||
|
||||
if user32::EnumDisplaySettingsExW(adapter.DeviceName.as_ptr(),
|
||||
winapi::ENUM_CURRENT_SETTINGS,
|
||||
&mut dev, 0) == 0
|
||||
{
|
||||
continue;
|
||||
if user32::EnumDisplaySettingsExW(adapter.DeviceName.as_ptr(),
|
||||
winapi::ENUM_CURRENT_SETTINGS,
|
||||
&mut dev, 0) == 0
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let point: &winapi::POINTL = mem::transmute(&dev.union1);
|
||||
let position = (point.x as u32, point.y as u32);
|
||||
|
||||
let dimensions = (dev.dmPelsWidth as u32, dev.dmPelsHeight as u32);
|
||||
|
||||
(position, dimensions)
|
||||
};
|
||||
|
||||
for (num, monitor) in DeviceEnumerator::monitors(adapter.DeviceName.as_ptr()).enumerate() {
|
||||
// adding to the resulting list
|
||||
result.push_back(MonitorId {
|
||||
adapter_name: adapter.DeviceName,
|
||||
monitor_name: wchar_as_string(&monitor.DeviceName),
|
||||
readable_name: wchar_as_string(&monitor.DeviceString),
|
||||
flags: monitor.StateFlags,
|
||||
primary: (adapter.StateFlags & winapi::DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 &&
|
||||
num == 0,
|
||||
position: position,
|
||||
dimensions: dimensions,
|
||||
});
|
||||
}
|
||||
|
||||
let point: &winapi::POINTL = mem::transmute(&dev.union1);
|
||||
let position = (point.x as u32, point.y as u32);
|
||||
|
||||
let dimensions = (dev.dmPelsWidth as u32, dev.dmPelsHeight as u32);
|
||||
|
||||
(position, dimensions)
|
||||
};
|
||||
|
||||
for (num, monitor) in DeviceEnumerator::monitors(adapter.DeviceName.as_ptr()).enumerate() {
|
||||
// adding to the resulting list
|
||||
result.push_back(MonitorId {
|
||||
adapter_name: adapter.DeviceName,
|
||||
monitor_name: wchar_as_string(&monitor.DeviceName),
|
||||
readable_name: wchar_as_string(&monitor.DeviceString),
|
||||
flags: monitor.StateFlags,
|
||||
primary: (adapter.StateFlags & winapi::DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 &&
|
||||
num == 0,
|
||||
position: position,
|
||||
dimensions: dimensions,
|
||||
});
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Win32 implementation of the main `get_primary_monitor` function.
|
||||
pub fn get_primary_monitor() -> MonitorId {
|
||||
// we simply get all available monitors and return the one with the `PRIMARY_DEVICE` flag
|
||||
// TODO: it is possible to query the win32 API for the primary monitor, this should be done
|
||||
// instead
|
||||
for monitor in get_available_monitors().into_iter() {
|
||||
if monitor.primary {
|
||||
return monitor;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
panic!("Failed to find the primary monitor")
|
||||
pub fn get_primary_monitor(&self) -> MonitorId {
|
||||
// we simply get all available monitors and return the one with the `PRIMARY_DEVICE` flag
|
||||
// TODO: it is possible to query the win32 API for the primary monitor, this should be done
|
||||
// instead
|
||||
for monitor in self.get_available_monitors().into_iter() {
|
||||
if monitor.primary {
|
||||
return monitor;
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Failed to find the primary monitor")
|
||||
}
|
||||
}
|
||||
|
||||
impl MonitorId {
|
||||
|
|
|
@ -322,7 +322,7 @@ impl Window {
|
|||
// Implementation note: we retreive the list once, then serve each element by one by one.
|
||||
// This may change in the future.
|
||||
pub struct AvailableMonitorsIter {
|
||||
data: VecDequeIter<platform::MonitorId>,
|
||||
pub(crate) data: VecDequeIter<platform::MonitorId>,
|
||||
}
|
||||
|
||||
impl Iterator for AvailableMonitorsIter {
|
||||
|
@ -339,36 +339,6 @@ impl Iterator for AvailableMonitorsIter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the list of all available monitors.
|
||||
///
|
||||
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||
/// > and if it fails will fallback on x11.
|
||||
/// >
|
||||
/// > If this variable is set with any other value, winit will panic.
|
||||
// Note: should be replaced with `-> impl Iterator` once stable.
|
||||
#[inline]
|
||||
pub fn get_available_monitors() -> AvailableMonitorsIter {
|
||||
let data = platform::get_available_monitors();
|
||||
AvailableMonitorsIter{ data: data.into_iter() }
|
||||
}
|
||||
|
||||
/// Returns the primary monitor of the system.
|
||||
///
|
||||
/// Usage will result in display backend initialisation, this can be controlled on linux
|
||||
/// using an environment variable `WINIT_UNIX_BACKEND`.
|
||||
/// > Legal values are `x11` and `wayland`. If this variable is set only the named backend
|
||||
/// > will be tried by winit. If it is not set, winit will try to connect to a wayland connection,
|
||||
/// > and if it fails will fallback on x11.
|
||||
/// >
|
||||
/// > If this variable is set with any other value, winit will panic.
|
||||
#[inline]
|
||||
pub fn get_primary_monitor() -> MonitorId {
|
||||
MonitorId { inner: platform::get_primary_monitor() }
|
||||
}
|
||||
|
||||
/// Identifier for a monitor.
|
||||
#[derive(Clone)]
|
||||
pub struct MonitorId {
|
||||
|
|
Loading…
Reference in a new issue