diff options
| -rw-r--r-- | src/win32/init.rs | 169 | 
1 files changed, 84 insertions, 85 deletions
| diff --git a/src/win32/init.rs b/src/win32/init.rs index 260b0ab..13da111 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -40,34 +40,36 @@ pub fn new_window(builder: BuilderAttribs<'static>, builder_sharelists: Option<C      //  so we create a new thread dedicated to this window.      // This is the only safe method. Using `nosend` wouldn't work for non-native runtime.      ::std::thread::Thread::spawn(move || { -        // sending -        match init(title, builder, builder_sharelists) { -            Ok(w) => tx.send(Ok(w)).ok(), -            Err(e) => { -                tx.send(Err(e)).ok(); -                return; +        unsafe { +            // sending +            match init(title, builder, builder_sharelists) { +                Ok(w) => tx.send(Ok(w)).ok(), +                Err(e) => { +                    tx.send(Err(e)).ok(); +                    return; +                } +            }; + +            // now that the `Window` struct is initialized, the main `Window::new()` function will +            //  return and this events loop will run in parallel +            loop { +                let mut msg = mem::uninitialized(); + +                if user32::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) == 0 { +                    break; +                } + +                user32::TranslateMessage(&msg); +                user32::DispatchMessageW(&msg);     // calls `callback` (see below)              } -        }; - -        // now that the `Window` struct is initialized, the main `Window::new()` function will -        //  return and this events loop will run in parallel -        loop { -            let mut msg = unsafe { mem::uninitialized() }; - -            if unsafe { user32::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) } == 0 { -                break; -            } - -            unsafe { user32::TranslateMessage(&msg) }; -            unsafe { user32::DispatchMessageW(&msg) };     // calls `callback` (see below)          }      });      rx.recv().unwrap()  } -fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: Option<ContextHack>) -        -> Result<Window, CreationError> +unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, +               builder_sharelists: Option<ContextHack>) -> Result<Window, CreationError>  {      let builder_sharelists = builder_sharelists.map(|s| s.0); @@ -85,7 +87,7 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      //  and change the monitor's resolution if necessary      if builder.monitor.is_some() {          let monitor = builder.monitor.as_ref().unwrap(); -        switch_to_fullscreen(&mut rect, monitor); +        try!(switch_to_fullscreen(&mut rect, monitor));      }      // computing the style and extended style of the window @@ -97,12 +99,12 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      };      // adjusting the window coordinates using the style -    unsafe { user32::AdjustWindowRectEx(&mut rect, style, 0, ex_style) }; +    user32::AdjustWindowRectEx(&mut rect, style, 0, ex_style);      // getting the address of wglCreateContextAttribsARB      let extra_functions = {          // creating a dummy invisible window for GL initialization -        let dummy_window = unsafe { +        let dummy_window = {              let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(),                  title.as_ptr() as winapi::LPCWSTR,                  style | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN, @@ -121,11 +123,11 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O          // getting the HDC of the dummy window          let dummy_hdc = { -            let hdc = unsafe { user32::GetDC(dummy_window) }; +            let hdc = user32::GetDC(dummy_window);              if hdc.is_null() {                  let err = Err(OsError(format!("GetDC function failed: {}",                      os::error_string(os::errno())))); -                unsafe { user32::DestroyWindow(dummy_window); } +                user32::DestroyWindow(dummy_window);                  return err;              }              hdc @@ -142,7 +144,8 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O          let dummy_context = try!(create_context(None, dummy_hdc, None));          // making context current -        unsafe { gl::wgl::MakeCurrent(dummy_hdc as *const libc::c_void, dummy_context as *const libc::c_void); } +        gl::wgl::MakeCurrent(dummy_hdc as *const libc::c_void, +                             dummy_context as *const libc::c_void);          // loading the extra WGL functions          let extra_functions = gl::wgl_extra::Wgl::load_with(|addr| { @@ -151,24 +154,22 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O              let addr = CString::from_slice(addr.as_bytes());              let addr = addr.as_ptr(); -            unsafe { -                gl::wgl::GetProcAddress(addr) as *const libc::c_void -            } +            gl::wgl::GetProcAddress(addr) as *const libc::c_void          });          // removing current context -        unsafe { gl::wgl::MakeCurrent(ptr::null(), ptr::null()); } +        gl::wgl::MakeCurrent(ptr::null(), ptr::null());          // destroying the context and the window -        unsafe { gl::wgl::DeleteContext(dummy_context as *const libc::c_void); } -        unsafe { user32::DestroyWindow(dummy_window); } +        gl::wgl::DeleteContext(dummy_context as *const libc::c_void); +        user32::DestroyWindow(dummy_window);          // returning the address          extra_functions      };      // creating the real window this time -    let real_window = unsafe { +    let real_window = {          let (width, height) = if builder.monitor.is_some() || builder.dimensions.is_some() {              (Some(rect.right - rect.left), Some(rect.bottom - rect.top))          } else { @@ -192,7 +193,7 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O          if handle.is_null() {              return Err(OsError(format!("CreateWindowEx function failed: {}", -                os::error_string(os::errno())))); +                                       os::error_string(os::errno()))));          }          handle @@ -200,11 +201,11 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      // getting the HDC of the window      let hdc = { -        let hdc = unsafe { user32::GetDC(real_window) }; +        let hdc = user32::GetDC(real_window);          if hdc.is_null() {              let err = Err(OsError(format!("GetDC function failed: {}", -                os::error_string(os::errno())))); -            unsafe { user32::DestroyWindow(real_window); } +                                          os::error_string(os::errno())))); +            user32::DestroyWindow(real_window);              return err;          }          hdc @@ -227,7 +228,7 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      // calling SetForegroundWindow if fullscreen      if builder.monitor.is_some() { -        unsafe { user32::SetForegroundWindow(real_window) }; +        user32::SetForegroundWindow(real_window);      }      // filling the WINDOW task-local storage @@ -246,16 +247,16 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      // handling vsync      if builder.vsync {          if extra_functions.SwapIntervalEXT.is_loaded() { -            unsafe { gl::wgl::MakeCurrent(hdc as *const libc::c_void, context as *const libc::c_void) }; -            if unsafe { extra_functions.SwapIntervalEXT(1) } == 0 { -                unsafe { gl::wgl::DeleteContext(context as *const libc::c_void); } -                unsafe { user32::DestroyWindow(real_window); } +            gl::wgl::MakeCurrent(hdc as *const libc::c_void, context as *const libc::c_void); +            if extra_functions.SwapIntervalEXT(1) == 0 { +                gl::wgl::DeleteContext(context as *const libc::c_void); +                user32::DestroyWindow(real_window);                  return Err(OsError(format!("wglSwapIntervalEXT failed")));              }              // it is important to remove the current context, otherwise you get very weird              // errors -            unsafe { gl::wgl::MakeCurrent(ptr::null(), ptr::null()); } +            gl::wgl::MakeCurrent(ptr::null(), ptr::null());          }      } @@ -270,7 +271,7 @@ fn init(title: Vec<u16>, builder: BuilderAttribs<'static>, builder_sharelists: O      })  } -fn register_window_class() -> Vec<u16> { +unsafe fn register_window_class() -> Vec<u16> {      let class_name: Vec<u16> = "Window Class".utf16_units().chain(Some(0).into_iter())                                               .collect::<Vec<u16>>(); @@ -280,7 +281,7 @@ fn register_window_class() -> Vec<u16> {          lpfnWndProc: Some(callback::callback),          cbClsExtra: 0,          cbWndExtra: 0, -        hInstance: unsafe { kernel32::GetModuleHandleW(ptr::null()) }, +        hInstance: kernel32::GetModuleHandleW(ptr::null()),          hIcon: ptr::null_mut(),          hCursor: ptr::null_mut(),          hbrBackground: ptr::null_mut(), @@ -293,12 +294,14 @@ fn register_window_class() -> Vec<u16> {      //  an error, and because errors here are detected during CreateWindowEx anyway.      // Also since there is no weird element in the struct, there is no reason for this      //  call to fail. -    unsafe { user32::RegisterClassExW(&class) }; +    user32::RegisterClassExW(&class);      class_name  } -fn switch_to_fullscreen(rect: &mut winapi::RECT, monitor: &MonitorID) -> Result<(), CreationError> { +unsafe fn switch_to_fullscreen(rect: &mut winapi::RECT, monitor: &MonitorID) +                               -> Result<(), CreationError> +{      // adjusting the rect      {          let pos = monitor.get_position(); @@ -309,15 +312,16 @@ fn switch_to_fullscreen(rect: &mut winapi::RECT, monitor: &MonitorID) -> Result<      }      // changing device settings -    let mut screen_settings: winapi::DEVMODEW = unsafe { mem::zeroed() }; +    let mut screen_settings: winapi::DEVMODEW = mem::zeroed();      screen_settings.dmSize = mem::size_of::<winapi::DEVMODEW>() as winapi::WORD;      screen_settings.dmPelsWidth = (rect.right - rect.left) as winapi::DWORD;      screen_settings.dmPelsHeight = (rect.bottom - rect.top) as winapi::DWORD;      screen_settings.dmBitsPerPel = 32;      // TODO: ?      screen_settings.dmFields = winapi::DM_BITSPERPEL | winapi::DM_PELSWIDTH | winapi::DM_PELSHEIGHT; -    let result = unsafe { user32::ChangeDisplaySettingsExW(monitor.get_system_name().as_ptr(), -        &mut screen_settings, ptr::null_mut(), winapi::CDS_FULLSCREEN, ptr::null_mut()) }; +    let result = user32::ChangeDisplaySettingsExW(monitor.get_system_name().as_ptr(), +                                                  &mut screen_settings, ptr::null_mut(), +                                                  winapi::CDS_FULLSCREEN, ptr::null_mut());      if result != winapi::DISP_CHANGE_SUCCESSFUL {          return Err(OsError(format!("ChangeDisplaySettings failed: {}", result))); @@ -326,9 +330,9 @@ fn switch_to_fullscreen(rect: &mut winapi::RECT, monitor: &MonitorID) -> Result<      Ok(())  } -fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>, -                  hdc: winapi::HDC, share: Option<winapi::HGLRC>) -                  -> Result<winapi::HGLRC, CreationError> +unsafe fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>, +                         hdc: winapi::HDC, share: Option<winapi::HGLRC>) +                         -> Result<winapi::HGLRC, CreationError>  {      let share = share.unwrap_or(ptr::null_mut()); @@ -360,11 +364,10 @@ fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>              attributes.push(0); -            Some(unsafe { -                extra_functions.CreateContextAttribsARB(hdc as *const libc::c_void, -                                                        share as *const libc::c_void, -                                                        attributes.as_slice().as_ptr()) -            }) +            Some(extra_functions.CreateContextAttribsARB(hdc as *const libc::c_void, +                                                         share as *const libc::c_void, +                                                         attributes.as_slice().as_ptr())) +          } else {              None          } @@ -375,13 +378,11 @@ fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>      let ctxt = match ctxt {          Some(ctxt) => ctxt,          None => { -            unsafe { -                let ctxt = gl::wgl::CreateContext(hdc as *const libc::c_void); -                if !ctxt.is_null() && !share.is_null() { -                    gl::wgl::ShareLists(share as *const libc::c_void, ctxt); -                }; -                ctxt -            } +            let ctxt = gl::wgl::CreateContext(hdc as *const libc::c_void); +            if !ctxt.is_null() && !share.is_null() { +                gl::wgl::ShareLists(share as *const libc::c_void, ctxt); +            }; +            ctxt          }      }; @@ -393,18 +394,16 @@ fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'static>)>      Ok(ctxt as winapi::HGLRC)  } -fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c_int)> { +unsafe fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c_int)> {      let size_of_pxfmtdescr = mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as u32; -    let num = unsafe { gdi32::DescribePixelFormat(hdc, 1, size_of_pxfmtdescr, ptr::null_mut()) }; +    let num = gdi32::DescribePixelFormat(hdc, 1, size_of_pxfmtdescr, ptr::null_mut());      let mut result = Vec::new();      for index in (0 .. num) { -        let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() }; +        let mut output: winapi::PIXELFORMATDESCRIPTOR = mem::zeroed(); -        if unsafe { gdi32::DescribePixelFormat(hdc, index, size_of_pxfmtdescr, -                                               &mut output) } == 0 -        { +        if gdi32::DescribePixelFormat(hdc, index, size_of_pxfmtdescr, &mut output) == 0 {              continue;          } @@ -438,14 +437,14 @@ fn enumerate_native_pixel_formats(hdc: winapi::HDC) -> Vec<(PixelFormat, libc::c      result  } -fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC) -                               -> Vec<(PixelFormat, libc::c_int)> +unsafe fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC) +                                      -> Vec<(PixelFormat, libc::c_int)>  {      let get_info = |index: u32, attrib: u32| { -        let mut value = unsafe { mem::uninitialized() }; -        unsafe { extra.GetPixelFormatAttribivARB(hdc as *const libc::c_void, index as libc::c_int, -                                                 0, 1, [attrib as libc::c_int].as_ptr(), -                                                 &mut value) }; +        let mut value = mem::uninitialized(); +        extra.GetPixelFormatAttribivARB(hdc as *const libc::c_void, index as libc::c_int, +                                        0, 1, [attrib as libc::c_int].as_ptr(), +                                        &mut value);          value as u32      }; @@ -489,17 +488,17 @@ fn enumerate_arb_pixel_formats(extra: &gl::wgl_extra::Wgl, hdc: winapi::HDC)      result  } -fn set_pixel_format(hdc: winapi::HDC, id: libc::c_int) -> Result<(), CreationError> { -    let mut output: winapi::PIXELFORMATDESCRIPTOR = unsafe { mem::zeroed() }; +unsafe fn set_pixel_format(hdc: winapi::HDC, id: libc::c_int) -> Result<(), CreationError> { +    let mut output: winapi::PIXELFORMATDESCRIPTOR = mem::zeroed(); -    if unsafe { gdi32::DescribePixelFormat(hdc, id, -        mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0 +    if gdi32::DescribePixelFormat(hdc, id, mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() +                                  as winapi::UINT, &mut output) == 0      {          return Err(OsError(format!("DescribePixelFormat function failed: {}",                                     os::error_string(os::errno()))));      } -    if unsafe { gdi32::SetPixelFormat(hdc, id, &output) } == 0 { +    if gdi32::SetPixelFormat(hdc, id, &output) == 0 {          return Err(OsError(format!("SetPixelFormat function failed: {}",                                     os::error_string(os::errno()))));      } @@ -507,11 +506,11 @@ fn set_pixel_format(hdc: winapi::HDC, id: libc::c_int) -> Result<(), CreationErr      Ok(())  } -fn load_opengl32_dll() -> Result<winapi::HMODULE, CreationError> { +unsafe fn load_opengl32_dll() -> Result<winapi::HMODULE, CreationError> {      let name = "opengl32.dll".utf16_units().chain(Some(0).into_iter())                               .collect::<Vec<u16>>().as_ptr(); -    let lib = unsafe { kernel32::LoadLibraryW(name) }; +    let lib = kernel32::LoadLibraryW(name);      if lib.is_null() {          return Err(OsError(format!("LoadLibrary function failed: {}", | 
