diff options
| author | Tomaka17 <pierre.krieger1708@gmail.com> | 2014-07-27 21:21:50 +0200 | 
|---|---|---|
| committer | Tomaka17 <pierre.krieger1708@gmail.com> | 2014-07-27 21:21:50 +0200 | 
| commit | 0d122cec47799e5c5198d3d4068c9ed43ce9b83c (patch) | |
| tree | 39984df9dcb34b028755a1b2f61e7de5d0c0e730 /src/win32 | |
| parent | d824fb94db2f33e56dd641df18b1327d361cae88 (diff) | |
| download | glutin-0d122cec47799e5c5198d3d4068c9ed43ce9b83c.tar.gz glutin-0d122cec47799e5c5198d3d4068c9ed43ce9b83c.zip | |
Implement fullscreen for win32
Diffstat (limited to 'src/win32')
| -rw-r--r-- | src/win32/ffi.rs | 95 | ||||
| -rw-r--r-- | src/win32/mod.rs | 49 | 
2 files changed, 138 insertions, 6 deletions
| diff --git a/src/win32/ffi.rs b/src/win32/ffi.rs index 8ff7c43..4a3ce7e 100644 --- a/src/win32/ffi.rs +++ b/src/win32/ffi.rs @@ -96,6 +96,17 @@ pub static BS_USERBUTTON: DWORD = 8;  pub static BS_VCENTER: DWORD =  0xc00;  pub static BS_FLAT: DWORD = 0x8000; +// ? +pub static CDS_UPDATEREGISTRY: DWORD = 0x1; +pub static CDS_TEST: DWORD = 0x2; +pub static CDS_FULLSCREEN: DWORD = 0x4; +pub static CDS_GLOBAL: DWORD = 0x8; +pub static CDS_SET_PRIMARY: DWORD = 0x10; +pub static CDS_VIDEOPARAMETERS: DWORD = 0x20; +pub static CDS_NORESET: DWORD = 0x10000000; +pub static CDS_SETRECT: DWORD = 0x20000000; +pub static CDS_RESET: DWORD = 0x40000000; +  // http://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspx  pub static CS_BYTEALIGNCLIENT: DWORD = 0x1000;  pub static CS_BYTEALIGNWINDOW: DWORD = 0x2000; @@ -114,6 +125,48 @@ pub static CS_VREDRAW: DWORD = 0x0001;  #[allow(type_overflow)]  pub static CW_USEDEFAULT: libc::c_int = 0x80000000; +// ? +pub static DISP_CHANGE_SUCCESSFUL: LONG = 0; +pub static DISP_CHANGE_RESTART: LONG = 1; +pub static DISP_CHANGE_FAILED: LONG = -1; +pub static DISP_CHANGE_BADMODE: LONG = -2; +pub static DISP_CHANGE_NOTUPDATED: LONG = -3; +pub static DISP_CHANGE_BADFLAGS: LONG = -4; +pub static DISP_CHANGE_BADPARAM: LONG = -5; +pub static DISP_CHANGE_BADDUALVIEW: LONG = -6; + +// ? +pub static DM_ORIENTATION: DWORD = 0x00000001; +pub static DM_PAPERSIZE: DWORD = 0x00000002; +pub static DM_PAPERLENGTH: DWORD = 0x00000004; +pub static DM_PAPERWIDTH: DWORD = 0x00000008; +pub static DM_SCALE: DWORD = 0x00000010; +pub static DM_POSITION: DWORD = 0x00000020; +pub static DM_NUP: DWORD = 0x00000040; +pub static DM_DISPLAYORIENTATION: DWORD = 0x00000080; +pub static DM_COPIES: DWORD = 0x00000100; +pub static DM_DEFAULTSOURCE: DWORD = 0x00000200; +pub static DM_PRINTQUALITY: DWORD = 0x00000400; +pub static DM_COLOR: DWORD = 0x00000800; +pub static DM_DUPLEX: DWORD = 0x00001000; +pub static DM_YRESOLUTION: DWORD = 0x00002000; +pub static DM_TTOPTION: DWORD = 0x00004000; +pub static DM_COLLATE: DWORD = 0x00008000; +pub static DM_FORMNAME: DWORD = 0x00010000; +pub static DM_LOGPIXELS: DWORD = 0x00020000; +pub static DM_BITSPERPEL: DWORD = 0x00040000; +pub static DM_PELSWIDTH: DWORD = 0x00080000; +pub static DM_PELSHEIGHT: DWORD = 0x00100000; +pub static DM_DISPLAYFLAGS: DWORD = 0x00200000; +pub static DM_DISPLAYFREQUENCY: DWORD = 0x00400000; +pub static DM_ICMMETHOD: DWORD = 0x00800000; +pub static DM_ICMINTENT: DWORD = 0x01000000; +pub static DM_MEDIATYPE: DWORD = 0x02000000; +pub static DM_DITHERTYPE: DWORD = 0x04000000; +pub static DM_PANNINGWIDTH: DWORD = 0x08000000; +pub static DM_PANNINGHEIGHT: DWORD = 0x10000000; +pub static DM_DISPLAYFIXEDOUTPUT: DWORD = 0x20000000; +  // 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_ARGUMENT_ARRAY: DWORD = 0x00002000; @@ -467,6 +520,38 @@ pub struct PIXELFORMATDESCRIPTOR {      pub dwDamageMask: DWORD,  } +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx +#[repr(C)] +pub struct DEVMODE { +    pub dmDeviceName: [WCHAR, ..32], +    pub dmSpecVersion: WORD, +    pub dmDriverVersion: WORD, +    pub dmSize: WORD, +    pub dmDriverExtra: WORD, +    pub dmFields: DWORD, +    union1: [u8, ..16], +    pub dmColor: libc::c_short, +    pub dmDuplex: libc::c_short, +    pub dmYResolution: libc::c_short, +    pub dmTTOption: libc::c_short, +    pub dmCollate: libc::c_short, +    pub dmFormName: [WCHAR, ..32], +    pub dmLogPixels: WORD, +    pub dmBitsPerPel: DWORD, +    pub dmPelsWidth: DWORD, +    pub dmPelsHeight: DWORD, +    pub dmDisplayFlags: DWORD, +    pub dmDisplayFrequency: DWORD, +    pub dmICMMethod: DWORD, +    pub dmICMIntent: DWORD, +    pub dmMediaType: DWORD, +    pub dmDitherType: DWORD, +    dmReserved1: DWORD, +    dmReserved2: DWORD, +    pub dmPanningWidth: DWORD, +    pub dmPanningHeight: DWORD, +} +  pub type LPMSG = *mut MSG;  #[link(name = "advapi32")] @@ -484,9 +569,16 @@ pub type LPMSG = *mut MSG;  #[link(name = "uuid")]  #[link(name = "winspool")]  extern "system" { +    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632667(v=vs.85).aspx +    pub fn AdjustWindowRectEx(lpRect: *mut RECT, dwStyle: DWORD, bMenu: BOOL, +        dwExStyle: DWORD) -> BOOL; +      // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183362(v=vs.85).aspx      pub fn BeginPaint(hwnd: HWND, lpPaint: *mut PAINTSTRUCT) -> HDC; +    // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183411(v=vs.85).aspx +    pub fn ChangeDisplaySettingsW(lpDevMode: *mut DEVMODE, dwFlags: DWORD) -> LONG; +      // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680(v=vs.85).aspx      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, @@ -542,6 +634,9 @@ extern "system" {      // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633586(v=vs.85).aspx      pub fn RegisterClassExW(lpWndClass: *const WNDCLASSEX) -> ATOM; +    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx +    pub fn SetForegroundWindow(hWnd: HWND) -> BOOL; +      // http://msdn.microsoft.com/en-us/library/windows/desktop/dd369049(v=vs.85).aspx      pub fn SetPixelFormat(hdc: HDC, iPixelFormat: libc::c_int,          ppfd: *const PIXELFORMATDESCRIPTOR) -> BOOL; diff --git a/src/win32/mod.rs b/src/win32/mod.rs index 03c262f..7230ee4 100644 --- a/src/win32/mod.rs +++ b/src/win32/mod.rs @@ -23,7 +23,7 @@ local_data_key!(pub WINDOWS_LIST: Mutex<Vec<(ffi::HWND, Sender<Event>)>>)  impl Window {      pub fn new(dimensions: Option<(uint, uint)>, title: &str, -        _hints: &Hints, _monitor: Option<MonitorID>) +        _hints: &Hints, monitor: Option<MonitorID>)          -> Result<Window, String>      {          use std::mem; @@ -60,16 +60,48 @@ impl Window {                  os::error_string(os::errno() as uint)))          } +        // building a RECT object with coordinates +        let mut rect = ffi::RECT { +            left: 0, right: dimensions.map(|(w, _)| w as ffi::LONG).unwrap_or(1024), +            top: 0, bottom: dimensions.map(|(_, h)| h as ffi::LONG).unwrap_or(768), +        }; + +        // switching to fullscreen +        if monitor.is_some() { +            let mut screen_settings: ffi::DEVMODE = unsafe { mem::zeroed() }; +            screen_settings.dmSize = mem::size_of::<ffi::DEVMODE>() as ffi::WORD; +            screen_settings.dmPelsWidth = 1024; +            screen_settings.dmPelsHeight = 768; +            screen_settings.dmBitsPerPel = 32; +            screen_settings.dmFields = ffi::DM_BITSPERPEL | ffi::DM_PELSWIDTH | ffi::DM_PELSHEIGHT; + +            let result = unsafe { ffi::ChangeDisplaySettingsW(&mut screen_settings, ffi::CDS_FULLSCREEN) }; +            if result != ffi::DISP_CHANGE_SUCCESSFUL { +                return Err(format!("ChangeDisplaySettings failed: {}", result)) +            } +        } + +        // computing the style and extended style +        let (ex_style, style) = if monitor.is_some() { +            (ffi::WS_EX_APPWINDOW, ffi::WS_POPUP | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN) +        } else { +            (ffi::WS_EX_APPWINDOW | ffi::WS_EX_WINDOWEDGE, +                ffi::WS_OVERLAPPEDWINDOW | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN) +        }; + +        // adjusting +        unsafe { ffi::AdjustWindowRectEx(&mut rect, style, 0, ex_style) }; +          // creating the window          let handle = unsafe {              use libc; -            let handle = ffi::CreateWindowExW(0, class_name.as_ptr(), +            let handle = ffi::CreateWindowExW(ex_style, class_name.as_ptr(),                  title.utf16_units().collect::<Vec<u16>>().append_one(0).as_ptr() as ffi::LPCWSTR, -                ffi::WS_OVERLAPPEDWINDOW | ffi::WS_VISIBLE, -                dimensions.map(|(x, _)| x as libc::c_int).unwrap_or(ffi::CW_USEDEFAULT), -                dimensions.map(|(_, y)| y as libc::c_int).unwrap_or(ffi::CW_USEDEFAULT), -                ffi::CW_USEDEFAULT, ffi::CW_USEDEFAULT, +                style | ffi::WS_VISIBLE | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN, +                if monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT}, +                if monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT}, +                rect.right - rect.left, rect.bottom - rect.top,                  ptr::mut_null(), ptr::mut_null(), ffi::GetModuleHandleW(ptr::null()),                  ptr::mut_null()); @@ -82,6 +114,11 @@ impl Window {              handle          }; +        // calling SetForegroundWindow if fullscreen +        if monitor.is_some() { +            unsafe { ffi::SetForegroundWindow(handle) }; +        } +          // adding it to WINDOWS_LIST          let events_receiver = {              let (tx, rx) = channel(); | 
