From 2af367b55caf948ec254c0ffabda8c6263d01690 Mon Sep 17 00:00:00 2001 From: Tomaka17 Date: Fri, 12 Sep 2014 15:51:43 +0200 Subject: [PATCH] Use the gl_generator macro to generate the bindings for WGL --- Cargo.toml | 2 +- src/lib.rs | 1 + src/win32/ffi.rs | 35 ++++++++---------------- src/win32/init.rs | 68 ++++++++++++++++++++++------------------------- src/win32/mod.rs | 13 ++++----- 5 files changed, 52 insertions(+), 67 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c81a97dd..5c592336 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,5 @@ git = "https://github.com/huonw/compile_msg" [dependencies.android_glue] git = "https://github.com/tomaka/android-rs-glue" -[dev-dependencies.gl_generator] +[dependencies.gl_generator] git = "https://github.com/bjz/gl-rs" diff --git a/src/lib.rs b/src/lib.rs index 97001a86..8db5f403 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ //! will look and behave. #[phase(plugin)] extern crate compile_msg; +#[phase(plugin)] extern crate gl_generator; extern crate libc; pub use events::*; diff --git a/src/win32/ffi.rs b/src/win32/ffi.rs index 6bf0e2df..6eb65634 100644 --- a/src/win32/ffi.rs +++ b/src/win32/ffi.rs @@ -5,6 +5,16 @@ use libc; +/// WGL bindings +pub mod wgl { + generate_gl_bindings!("wgl", "core", "1.0", "static") +} + +/// Functions that are not necessarly always available +pub mod wgl_extra { + generate_gl_bindings!("wgl", "core", "1.0", "struct", [ "WGL_ARB_create_context" ]) +} + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx // we don't define the T types to ensure that A/W functions are used pub type ATOM = WORD; @@ -32,7 +42,7 @@ pub type LPSTR = *mut libc::c_char; pub type LPVOID = *mut libc::c_void; pub type LPWSTR = *mut WCHAR; pub type LRESULT = LONG_PTR; -pub type PVOID = *mut libc::c_void; +pub type PVOID = *const libc::c_void; pub type UINT = libc::c_uint; pub type UINT_PTR = int; pub type WCHAR = libc::wchar_t; @@ -385,17 +395,6 @@ pub static VK_NONAME: WPARAM = 0xFC; pub static VK_PA1: WPARAM = 0xFD; pub static VK_OEM_CLEAR: WPARAM = 0xFE; -// ? -pub static WGL_CONTEXT_DEBUG_BIT_ARB: libc::c_int = 0x00000001; -pub static WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB: libc::c_int = 0x00000002; -pub static WGL_CONTEXT_MAJOR_VERSION_ARB: libc::c_int = 0x2091; -pub static WGL_CONTEXT_MINOR_VERSION_ARB: libc::c_int = 0x2092; -pub static WGL_CONTEXT_LAYER_PLANE_ARB: libc::c_int = 0x2093; -pub static WGL_CONTEXT_FLAGS_ARB: libc::c_int = 0x2094; -pub static WGL_CONTEXT_PROFILE_MASK_ARB: libc::c_int = 0x9126; -pub static WGL_CONTEXT_CORE_PROFILE_BIT_ARB: libc::c_int = 0x00000001; -pub static WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: libc::c_int = 0x00000002; - // messages pub static WM_LBUTTONDOWN: UINT = 0x0201; pub static WM_LBUTTONUP: UINT = 0x0202; @@ -766,16 +765,4 @@ extern "system" { // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644956(v=vs.85).aspx pub fn WaitMessage() -> BOOL; - - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd374379(v=vs.85).aspx - pub fn wglCreateContext(hdc: HDC) -> HGLRC; - - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd374381(v=vs.85).aspx - pub fn wglDeleteContext(hglrc: HGLRC); - - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd374386(v=vs.85).aspx - pub fn wglGetProcAddress(lpszProc: LPCSTR) -> *const libc::c_void; - - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd374387(v=vs.85).aspx - pub fn wglMakeCurrent(hdc: HDC, hglrc: HGLRC); } diff --git a/src/win32/init.rs b/src/win32/init.rs index 365bcb84..0da916b9 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -40,12 +40,12 @@ pub fn new_window(builder: WindowBuilder) -> Result { cbClsExtra: 0, cbWndExtra: 0, hInstance: unsafe { ffi::GetModuleHandleW(ptr::null()) }, - hIcon: ptr::mut_null(), - hCursor: ptr::mut_null(), - hbrBackground: ptr::mut_null(), + hIcon: ptr::null(), + hCursor: ptr::null(), + hbrBackground: ptr::null(), lpszMenuName: ptr::null(), lpszClassName: class_name.as_ptr(), - hIconSm: ptr::mut_null(), + hIconSm: ptr::null(), }; // We ignore errors because registering the same window class twice would trigger @@ -87,7 +87,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { screen_settings.dmFields = ffi::DM_BITSPERPEL | ffi::DM_PELSWIDTH | ffi::DM_PELSHEIGHT; let result = unsafe { ffi::ChangeDisplaySettingsExW(monitor.get_system_name().as_ptr(), - &mut screen_settings, ptr::mut_null(), ffi::CDS_FULLSCREEN, ptr::mut_null()) }; + &mut screen_settings, ptr::null(), ffi::CDS_FULLSCREEN, ptr::mut_null()) }; if result != ffi::DISP_CHANGE_SUCCESSFUL { tx.send(Err(format!("ChangeDisplaySettings failed: {}", result))); @@ -106,9 +106,9 @@ pub fn new_window(builder: WindowBuilder) -> Result { // adjusting the window coordinates using the style unsafe { ffi::AdjustWindowRectEx(&mut rect, style, 0, ex_style) }; - // getting the address of wglCreateContextAttribs and the pixel format + // getting the address of wglCreateContextAttribsARB and the pixel format // that we will use - let (create_context_attribs, pixel_format) = { + let (extra_functions, pixel_format) = { // creating a dummy invisible window for GL initialization let dummy_window = unsafe { let handle = ffi::CreateWindowExW(ex_style, class_name.as_ptr(), @@ -116,7 +116,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { style | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN, ffi::CW_USEDEFAULT, ffi::CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, - ptr::mut_null(), ptr::mut_null(), ffi::GetModuleHandleW(ptr::null()), + ptr::null(), ptr::null(), ffi::GetModuleHandleW(ptr::null()), ptr::mut_null()); if handle.is_null() { @@ -191,7 +191,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { // creating the dummy OpenGL context let dummy_context = { - let ctxt = unsafe { ffi::wglCreateContext(dummy_hdc) }; + let ctxt = unsafe { ffi::wgl::CreateContext(dummy_hdc) }; if ctxt.is_null() { tx.send(Err(format!("wglCreateContext function failed: {}", os::error_string(os::errno() as uint)))); @@ -202,33 +202,27 @@ pub fn new_window(builder: WindowBuilder) -> Result { }; // making context current - unsafe { ffi::wglMakeCurrent(dummy_hdc, dummy_context); } + unsafe { ffi::wgl::MakeCurrent(dummy_hdc, dummy_context); } - // getting the pointer to wglCreateContextAttribs - let mut addr = unsafe { ffi::wglGetProcAddress(b"wglCreateContextAttribs".as_ptr() - as *const i8) } as *const (); - - if addr.is_null() { - addr = unsafe { ffi::wglGetProcAddress(b"wglCreateContextAttribsARB".as_ptr() - as *const i8) } as *const (); - } + // loading the extra WGL functions + let extra_functions = ffi::wgl_extra::Wgl::load_with(|addr| { + unsafe { + addr.with_c_str(|s| { + use libc; + ffi::wgl::GetProcAddress(s) as *const libc::c_void + }) + } + }); // removing current context - unsafe { ffi::wglMakeCurrent(ptr::mut_null(), ptr::mut_null()); } + unsafe { ffi::wgl::MakeCurrent(ptr::null(), ptr::null()); } // destroying the context and the window - unsafe { ffi::wglDeleteContext(dummy_context); } + unsafe { ffi::wgl::DeleteContext(dummy_context); } unsafe { ffi::DestroyWindow(dummy_window); } // returning the address - if addr.is_null() { - (None, pixel_format) - } else { - use libc; - let addr: extern "system" fn(ffi::HDC, ffi::HGLRC, *const libc::c_int) -> ffi::HGLRC - = unsafe { mem::transmute(addr) }; - (Some(addr), pixel_format) - } + (extra_functions, pixel_format) }; // creating the real window this time @@ -245,7 +239,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { if builder.monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT }, if builder.monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT }, width.unwrap_or(ffi::CW_USEDEFAULT), height.unwrap_or(ffi::CW_USEDEFAULT), - ptr::mut_null(), ptr::mut_null(), ffi::GetModuleHandleW(ptr::null()), + ptr::null(), ptr::null(), ffi::GetModuleHandleW(ptr::null()), ptr::mut_null()); if handle.is_null() { @@ -288,18 +282,20 @@ pub fn new_window(builder: WindowBuilder) -> Result { if builder.gl_version.is_some() { let version = builder.gl_version.as_ref().unwrap(); - attributes.push(ffi::WGL_CONTEXT_MAJOR_VERSION_ARB); + attributes.push(ffi::wgl_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int); attributes.push(version.val0() as libc::c_int); - attributes.push(ffi::WGL_CONTEXT_MINOR_VERSION_ARB); + attributes.push(ffi::wgl_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int); attributes.push(version.val1() as libc::c_int); } attributes.push(0); let ctxt = unsafe { - match create_context_attribs { - None => ffi::wglCreateContext(hdc), - Some(ptr) => ptr(hdc, ptr::mut_null(), attributes.as_slice().as_ptr()) + if extra_functions.CreateContextAttribsARB.is_loaded() { + extra_functions.CreateContextAttribsARB(hdc, ptr::null(), + attributes.as_slice().as_ptr()) + } else { + ffi::wgl::CreateContext(hdc) } }; @@ -332,7 +328,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { if lib.is_null() { tx.send(Err(format!("LoadLibrary function failed: {}", os::error_string(os::errno() as uint)))); - unsafe { ffi::wglDeleteContext(context); } + unsafe { ffi::wgl::DeleteContext(context); } unsafe { ffi::DestroyWindow(real_window); } return; } @@ -357,7 +353,7 @@ pub fn new_window(builder: WindowBuilder) -> Result { loop { let mut msg = unsafe { mem::uninitialized() }; - if unsafe { ffi::GetMessageW(&mut msg, ptr::mut_null(), 0, 0) } == 0 { + if unsafe { ffi::GetMessageW(&mut msg, ptr::null(), 0, 0) } == 0 { break; } diff --git a/src/win32/mod.rs b/src/win32/mod.rs index cf889cb4..faff3747 100644 --- a/src/win32/mod.rs +++ b/src/win32/mod.rs @@ -75,7 +75,7 @@ impl Window { use libc; unsafe { - ffi::SetWindowPos(self.window, ptr::mut_null(), x as libc::c_int, y as libc::c_int, + ffi::SetWindowPos(self.window, ptr::null(), x as libc::c_int, y as libc::c_int, 0, 0, ffi::SWP_NOZORDER | ffi::SWP_NOSIZE); ffi::UpdateWindow(self.window); } @@ -116,7 +116,7 @@ impl Window { use libc; unsafe { - ffi::SetWindowPos(self.window, ptr::mut_null(), 0, 0, x as libc::c_int, + ffi::SetWindowPos(self.window, ptr::null(), 0, 0, x as libc::c_int, y as libc::c_int, ffi::SWP_NOZORDER | ffi::SWP_NOREPOSITION); ffi::UpdateWindow(self.window); } @@ -172,7 +172,8 @@ impl Window { /// See the docs in the crate root file. pub unsafe fn make_current(&self) { - ffi::wglMakeCurrent(self.hdc, self.context) + // TODO: check return value + ffi::wgl::MakeCurrent(self.hdc, self.context); } /// See the docs in the crate root file. @@ -181,7 +182,7 @@ impl Window { unsafe { addr.with_c_str(|s| { - let p = ffi::wglGetProcAddress(s) as *const (); + let p = ffi::wgl::GetProcAddress(s) as *const (); if !p.is_null() { return p; } ffi::GetProcAddress(self.gl_library, s) as *const () }) @@ -203,8 +204,8 @@ impl Window { impl Drop for Window { fn drop(&mut self) { use std::ptr; - unsafe { ffi::wglMakeCurrent(ptr::mut_null(), ptr::mut_null()); } - unsafe { ffi::wglDeleteContext(self.context); } + unsafe { ffi::wgl::MakeCurrent(ptr::null(), ptr::null()); } + unsafe { ffi::wgl::DeleteContext(self.context); } unsafe { ffi::DestroyWindow(self.window); } } }