mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
Add monitor support for win32
This commit is contained in:
parent
db8955a9d8
commit
d9d293667a
|
@ -14,8 +14,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
print!("Please write the number of the monitor to use: ");
|
print!("Please write the number of the monitor to use: ");
|
||||||
let num = from_str(stdin().read_line().unwrap().as_slice()).unwrap();
|
let num = from_str(stdin().read_line().unwrap().as_slice().trim())
|
||||||
let monitor = init::get_available_monitors().nth(num).unwrap();
|
.expect("Plase enter a number");
|
||||||
|
let monitor = init::get_available_monitors().nth(num).expect("Please enter a valid ID");
|
||||||
|
|
||||||
println!("Using {}", monitor.get_name());
|
println!("Using {}", monitor.get_name());
|
||||||
|
|
||||||
|
|
|
@ -258,6 +258,7 @@ pub fn get_primary_monitor() -> MonitorID {
|
||||||
impl MonitorID {
|
impl MonitorID {
|
||||||
/// Returns a human-readable name of the monitor.
|
/// Returns a human-readable name of the monitor.
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn get_name(&self) -> Option<String> {
|
||||||
Some("<Unknown>".to_string())
|
let &MonitorID(ref id) = self;
|
||||||
|
id.get_name()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(non_snake_case_functions)]
|
#![allow(non_snake_case_functions)]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
#![allow(uppercase_variables)]
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
|
@ -135,6 +136,13 @@ pub static DISP_CHANGE_BADFLAGS: LONG = -4;
|
||||||
pub static DISP_CHANGE_BADPARAM: LONG = -5;
|
pub static DISP_CHANGE_BADPARAM: LONG = -5;
|
||||||
pub static DISP_CHANGE_BADDUALVIEW: LONG = -6;
|
pub static DISP_CHANGE_BADDUALVIEW: LONG = -6;
|
||||||
|
|
||||||
|
// ?
|
||||||
|
pub static DISPLAY_DEVICE_ACTIVE: DWORD = 0x00000001;
|
||||||
|
pub static DISPLAY_DEVICE_MULTI_DRIVER: DWORD = 0x00000002;
|
||||||
|
pub static DISPLAY_DEVICE_PRIMARY_DEVICE: DWORD = 0x00000004;
|
||||||
|
pub static DISPLAY_DEVICE_MIRRORING_DRIVER: DWORD = 0x00000008;
|
||||||
|
pub static DISPLAY_DEVICE_VGA_COMPATIBLE: DWORD = 0x00000010;
|
||||||
|
|
||||||
// ?
|
// ?
|
||||||
pub static DM_ORIENTATION: DWORD = 0x00000001;
|
pub static DM_ORIENTATION: DWORD = 0x00000001;
|
||||||
pub static DM_PAPERSIZE: DWORD = 0x00000002;
|
pub static DM_PAPERSIZE: DWORD = 0x00000002;
|
||||||
|
@ -167,6 +175,13 @@ pub static DM_PANNINGWIDTH: DWORD = 0x08000000;
|
||||||
pub static DM_PANNINGHEIGHT: DWORD = 0x10000000;
|
pub static DM_PANNINGHEIGHT: DWORD = 0x10000000;
|
||||||
pub static DM_DISPLAYFIXEDOUTPUT: DWORD = 0x20000000;
|
pub static DM_DISPLAYFIXEDOUTPUT: DWORD = 0x20000000;
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162609(v=vs.85).aspx
|
||||||
|
pub static EDD_GET_DEVICE_INTERFACE_NAME: DWORD = 0x00000001;
|
||||||
|
|
||||||
|
// ?
|
||||||
|
pub static ENUM_CURRENT_SETTINGS: DWORD = -1;
|
||||||
|
pub static ENUM_REGISTRY_SETTINGS: DWORD = -2;
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
|
||||||
pub static FORMAT_MESSAGE_ALLOCATE_BUFFER: DWORD = 0x00000100;
|
pub static FORMAT_MESSAGE_ALLOCATE_BUFFER: DWORD = 0x00000100;
|
||||||
pub static FORMAT_MESSAGE_ARGUMENT_ARRAY: DWORD = 0x00002000;
|
pub static FORMAT_MESSAGE_ARGUMENT_ARRAY: DWORD = 0x00002000;
|
||||||
|
@ -520,6 +535,13 @@ pub struct PIXELFORMATDESCRIPTOR {
|
||||||
pub dwDamageMask: DWORD,
|
pub dwDamageMask: DWORD,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/dd162807(v=vs.85).aspx
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct POINTL {
|
||||||
|
pub x: LONG,
|
||||||
|
pub y: LONG,
|
||||||
|
}
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct DEVMODE {
|
pub struct DEVMODE {
|
||||||
|
@ -529,7 +551,7 @@ pub struct DEVMODE {
|
||||||
pub dmSize: WORD,
|
pub dmSize: WORD,
|
||||||
pub dmDriverExtra: WORD,
|
pub dmDriverExtra: WORD,
|
||||||
pub dmFields: DWORD,
|
pub dmFields: DWORD,
|
||||||
union1: [u8, ..16],
|
pub union1: [u8, ..16],
|
||||||
pub dmColor: libc::c_short,
|
pub dmColor: libc::c_short,
|
||||||
pub dmDuplex: libc::c_short,
|
pub dmDuplex: libc::c_short,
|
||||||
pub dmYResolution: libc::c_short,
|
pub dmYResolution: libc::c_short,
|
||||||
|
@ -563,6 +585,17 @@ pub struct WINDOWPLACEMENT {
|
||||||
pub rcNormalPosition: RECT,
|
pub rcNormalPosition: RECT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183569(v=vs.85).aspx
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct DISPLAY_DEVICEW {
|
||||||
|
pub cb: DWORD,
|
||||||
|
pub DeviceName: [WCHAR, ..32],
|
||||||
|
pub DeviceString: [WCHAR, ..128],
|
||||||
|
pub StateFlags: DWORD,
|
||||||
|
pub DeviceID: [WCHAR, ..128],
|
||||||
|
pub DeviceKey: [WCHAR, ..128],
|
||||||
|
}
|
||||||
|
|
||||||
pub type LPMSG = *mut MSG;
|
pub type LPMSG = *mut MSG;
|
||||||
|
|
||||||
#[link(name = "advapi32")]
|
#[link(name = "advapi32")]
|
||||||
|
@ -590,6 +623,10 @@ extern "system" {
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183411(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183411(v=vs.85).aspx
|
||||||
pub fn ChangeDisplaySettingsW(lpDevMode: *mut DEVMODE, dwFlags: DWORD) -> LONG;
|
pub fn ChangeDisplaySettingsW(lpDevMode: *mut DEVMODE, dwFlags: DWORD) -> LONG;
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183413(v=vs.85).aspx
|
||||||
|
pub fn ChangeDisplaySettingsExW(lpszDeviceName: LPCWSTR, lpDevMode: *mut DEVMODE, hwnd: HWND,
|
||||||
|
dwFlags: DWORD, lParam: LPVOID) -> LONG;
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx
|
||||||
pub fn CreateWindowExW(dwExStyle: DWORD, lpClassName: LPCWSTR, lpWindowName: LPCWSTR,
|
pub fn CreateWindowExW(dwExStyle: DWORD, lpClassName: LPCWSTR, lpWindowName: LPCWSTR,
|
||||||
dwStyle: DWORD, x: libc::c_int, y: libc::c_int, nWidth: libc::c_int, nHeight: libc::c_int,
|
dwStyle: DWORD, x: libc::c_int, y: libc::c_int, nWidth: libc::c_int, nHeight: libc::c_int,
|
||||||
|
@ -611,6 +648,14 @@ extern "system" {
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162598(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162598(v=vs.85).aspx
|
||||||
pub fn EndPaint(hWnd: HWND, lpPaint: *const PAINTSTRUCT) -> BOOL;
|
pub fn EndPaint(hWnd: HWND, lpPaint: *const PAINTSTRUCT) -> BOOL;
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162609(v=vs.85).aspx
|
||||||
|
pub fn EnumDisplayDevicesW(lpDevice: LPCWSTR, iDevNum: DWORD,
|
||||||
|
lpDisplayDevice: *mut DISPLAY_DEVICEW, dwFlags: DWORD) -> BOOL;
|
||||||
|
|
||||||
|
// http://msdn.microsoft.com/en-us/library/dd162612(v=vs.85).aspx
|
||||||
|
pub fn EnumDisplaySettingsExW(lpszDeviceName: LPCWSTR, iModeNum: DWORD,
|
||||||
|
lpDevMode: *mut DEVMODE, dwFlags: DWORD) -> BOOL;
|
||||||
|
|
||||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162719(v=vs.85).aspx
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162719(v=vs.85).aspx
|
||||||
pub fn FillRect(hDC: HDC, lprc: *const RECT, hbr: HBRUSH) -> libc::c_int;
|
pub fn FillRect(hDC: HDC, lprc: *const RECT, hbr: HBRUSH) -> libc::c_int;
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@ use std::sync::atomics::AtomicBool;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use {Event, Hints};
|
use {Event, Hints};
|
||||||
|
|
||||||
|
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
|
||||||
|
|
||||||
mod event;
|
mod event;
|
||||||
mod ffi;
|
mod ffi;
|
||||||
|
mod monitor;
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
window: ffi::HWND,
|
window: ffi::HWND,
|
||||||
|
@ -17,16 +20,6 @@ pub struct Window {
|
||||||
nosend: NoSend,
|
nosend: NoSend,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MonitorID(uint);
|
|
||||||
|
|
||||||
pub fn get_available_monitors() -> Vec<MonitorID> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_primary_monitor() -> MonitorID {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stores the list of all the windows.
|
/// Stores the list of all the windows.
|
||||||
/// Only available on callback thread.
|
/// Only available on callback thread.
|
||||||
local_data_key!(pub WINDOWS_LIST: Mutex<Vec<(ffi::HWND, Sender<Event>)>>)
|
local_data_key!(pub WINDOWS_LIST: Mutex<Vec<(ffi::HWND, Sender<Event>)>>)
|
||||||
|
@ -78,6 +71,18 @@ impl Window {
|
||||||
|
|
||||||
// switching to fullscreen
|
// switching to fullscreen
|
||||||
if monitor.is_some() {
|
if monitor.is_some() {
|
||||||
|
let monitor = monitor.as_ref().unwrap();
|
||||||
|
|
||||||
|
// adjusting the rect
|
||||||
|
{
|
||||||
|
let pos = monitor.get_position();
|
||||||
|
rect.left += pos.val0() as ffi::LONG;
|
||||||
|
rect.right += pos.val0() as ffi::LONG;
|
||||||
|
rect.top += pos.val1() as ffi::LONG;
|
||||||
|
rect.bottom += pos.val1() as ffi::LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// changing device settings
|
||||||
let mut screen_settings: ffi::DEVMODE = unsafe { mem::zeroed() };
|
let mut screen_settings: ffi::DEVMODE = unsafe { mem::zeroed() };
|
||||||
screen_settings.dmSize = mem::size_of::<ffi::DEVMODE>() as ffi::WORD;
|
screen_settings.dmSize = mem::size_of::<ffi::DEVMODE>() as ffi::WORD;
|
||||||
screen_settings.dmPelsWidth = 1024;
|
screen_settings.dmPelsWidth = 1024;
|
||||||
|
@ -85,7 +90,8 @@ impl Window {
|
||||||
screen_settings.dmBitsPerPel = 32;
|
screen_settings.dmBitsPerPel = 32;
|
||||||
screen_settings.dmFields = ffi::DM_BITSPERPEL | ffi::DM_PELSWIDTH | ffi::DM_PELSHEIGHT;
|
screen_settings.dmFields = ffi::DM_BITSPERPEL | ffi::DM_PELSWIDTH | ffi::DM_PELSHEIGHT;
|
||||||
|
|
||||||
let result = unsafe { ffi::ChangeDisplaySettingsW(&mut screen_settings, ffi::CDS_FULLSCREEN) };
|
let result = unsafe { ffi::ChangeDisplaySettingsExW(monitor.get_system_name().as_ptr(),
|
||||||
|
&mut screen_settings, ptr::mut_null(), ffi::CDS_FULLSCREEN, ptr::mut_null()) };
|
||||||
if result != ffi::DISP_CHANGE_SUCCESSFUL {
|
if result != ffi::DISP_CHANGE_SUCCESSFUL {
|
||||||
return Err(format!("ChangeDisplaySettings failed: {}", result))
|
return Err(format!("ChangeDisplaySettings failed: {}", result))
|
||||||
}
|
}
|
||||||
|
|
79
src/win32/monitor.rs
Normal file
79
src/win32/monitor.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
use super::ffi;
|
||||||
|
|
||||||
|
pub struct MonitorID {
|
||||||
|
name: [ffi::WCHAR, ..32],
|
||||||
|
readable_name: String,
|
||||||
|
flags: ffi::DWORD,
|
||||||
|
position: (uint, uint),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_available_monitors() -> Vec<MonitorID> {
|
||||||
|
use std::{iter, mem, ptr};
|
||||||
|
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
for id in iter::count(0u, 1) {
|
||||||
|
let mut output: ffi::DISPLAY_DEVICEW = unsafe { mem::zeroed() };
|
||||||
|
output.cb = mem::size_of::<ffi::DISPLAY_DEVICEW>() as ffi::DWORD;
|
||||||
|
|
||||||
|
if unsafe { ffi::EnumDisplayDevicesW(ptr::null(), id as ffi::DWORD, &mut output, 0) } == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.StateFlags & ffi::DISPLAY_DEVICE_ACTIVE) == 0 ||
|
||||||
|
(output.StateFlags & ffi::DISPLAY_DEVICE_MIRRORING_DRIVER) != 0
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let readable_name = String::from_utf16_lossy(output.DeviceString.as_slice());
|
||||||
|
let readable_name = readable_name.as_slice().trim_right_chars(0 as char).to_string();
|
||||||
|
|
||||||
|
let position = unsafe {
|
||||||
|
let mut dev: ffi::DEVMODE = mem::zeroed();
|
||||||
|
dev.dmSize = mem::size_of::<ffi::DEVMODE>() as ffi::WORD;
|
||||||
|
|
||||||
|
if ffi::EnumDisplaySettingsExW(output.DeviceName.as_ptr(), ffi::ENUM_CURRENT_SETTINGS,
|
||||||
|
&mut dev, 0) == 0
|
||||||
|
{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let point: &ffi::POINTL = mem::transmute(&dev.union1);
|
||||||
|
(point.x as uint, point.y as uint)
|
||||||
|
};
|
||||||
|
|
||||||
|
result.push(MonitorID {
|
||||||
|
name: output.DeviceName,
|
||||||
|
readable_name: readable_name,
|
||||||
|
flags: output.StateFlags,
|
||||||
|
position: position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_primary_monitor() -> MonitorID {
|
||||||
|
for monitor in get_available_monitors().move_iter() {
|
||||||
|
if (monitor.flags & ffi::DISPLAY_DEVICE_PRIMARY_DEVICE) != 0 {
|
||||||
|
return monitor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail!("Failed to find the primary monitor")
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MonitorID {
|
||||||
|
pub fn get_name(&self) -> Option<String> {
|
||||||
|
Some(self.readable_name.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_system_name(&self) -> &[ffi::WCHAR] {
|
||||||
|
self.name.as_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_position(&self) -> (uint, uint) {
|
||||||
|
self.position
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,12 @@ pub fn get_primary_monitor() -> MonitorID {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MonitorID {
|
||||||
|
pub fn get_name(&self) -> Option<String> {
|
||||||
|
Some("<Unknown>".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(dimensions: Option<(uint, uint)>, title: &str, hints: &Hints, _: Option<MonitorID>)
|
pub fn new(dimensions: Option<(uint, uint)>, title: &str, hints: &Hints, _: Option<MonitorID>)
|
||||||
-> Result<Window, String>
|
-> Result<Window, String>
|
||||||
|
|
Loading…
Reference in a new issue