From 584bb3e7df751d55aad189eacd85b1cd6c5aa5c5 Mon Sep 17 00:00:00 2001 From: Tomaka17 Date: Wed, 5 Nov 2014 16:42:18 +0100 Subject: Use a proper error type for window creation --- src/android/mod.rs | 18 +++++++++--------- src/lib.rs | 20 +++++++++++++++++--- src/osx/mod.rs | 16 ++++++++-------- src/win32/init.rs | 52 +++++++++++++++++++++++++-------------------------- src/win32/mod.rs | 6 +++--- src/x11/headless.rs | 3 ++- src/x11/window/mod.rs | 21 +++++++++++---------- 7 files changed, 76 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/android/mod.rs b/src/android/mod.rs index 7198553..4b1c7eb 100644 --- a/src/android/mod.rs +++ b/src/android/mod.rs @@ -2,7 +2,7 @@ extern crate android_glue; extern crate native; use libc; -use {Event, WindowBuilder}; +use {CreationError, OsError, Event, WindowBuilder}; pub struct Window { display: ffi::egl::types::EGLDisplay, @@ -35,18 +35,18 @@ impl MonitorID { } impl Window { - pub fn new(_builder: WindowBuilder) -> Result { + pub fn new(_builder: WindowBuilder) -> Result { use std::{mem, ptr}; let native_window = unsafe { android_glue::get_native_window() }; if native_window.is_null() { - return Err(format!("Android's native window is null")); + return Err(OsError(format!("Android's native window is null"))); } let display = unsafe { let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY)); if display.is_null() { - return Err("No EGL display connection available".to_string()); + return Err(OsError("No EGL display connection available".to_string())); } display }; @@ -58,7 +58,7 @@ impl Window { let mut minor: ffi::egl::types::EGLint = mem::uninitialized(); if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 { - return Err(format!("eglInitialize failed")) + return Err(OsError(format!("eglInitialize failed"))) } (major, minor) @@ -79,11 +79,11 @@ impl Window { if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1, &mut num_config) == 0 { - return Err(format!("eglChooseConfig failed")) + return Err(OsError(format!("eglChooseConfig failed"))) } if num_config <= 0 { - return Err(format!("eglChooseConfig returned no available config")) + return Err(OsError(format!("eglChooseConfig returned no available config"))) } config @@ -94,7 +94,7 @@ impl Window { let context = unsafe { let context = ffi::egl::CreateContext(display, config, ptr::null(), ptr::null()); if context.is_null() { - return Err(format!("eglCreateContext failed")) + return Err(OsError(format!("eglCreateContext failed"))) } context }; @@ -104,7 +104,7 @@ impl Window { let surface = unsafe { let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null()); if surface.is_null() { - return Err(format!("eglCreateWindowSurface failed")) + return Err(OsError(format!("eglCreateWindowSurface failed"))) } surface }; diff --git a/src/lib.rs b/src/lib.rs index a976da5..3c8b939 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,6 +70,20 @@ compile_error!("Only the `windows`, `linux` and `macos` platforms are supported" #[cfg(feature = "window")] pub struct MonitorID(winimpl::MonitorID); +/// Error that can happen while creating a window or a headless renderer. +#[deriving(Clone, Show, PartialEq, Eq)] +pub enum CreationError { + OsError(String), +} + +impl std::error::Error for CreationError { + fn description(&self) -> &str { + match self { + &OsError(ref text) => text.as_slice(), + } + } +} + /// Object that allows you to build windows. #[cfg(feature = "window")] pub struct WindowBuilder { @@ -143,7 +157,7 @@ impl WindowBuilder { /// /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. - pub fn build(mut self) -> Result { + pub fn build(mut self) -> Result { // resizing the window to the dimensions of the monitor when fullscreen if self.dimensions.is_none() && self.monitor.is_some() { self.dimensions = Some(self.monitor.as_ref().unwrap().get_dimensions()) @@ -189,7 +203,7 @@ impl HeadlessRendererBuilder { /// /// Error should be very rare and only occur in case of permission denied, incompatible system, /// out of memory, etc. - pub fn build(self) -> Result { + pub fn build(self) -> Result { winimpl::HeadlessContext::new(self).map(|w| HeadlessContext { context: w }) } } @@ -238,7 +252,7 @@ impl Window { /// out of memory, etc. #[inline] #[cfg(feature = "window")] - pub fn new() -> Result { + pub fn new() -> Result { let builder = WindowBuilder::new(); builder.build() } diff --git a/src/osx/mod.rs b/src/osx/mod.rs index 3dda56a..3d1df8b 100644 --- a/src/osx/mod.rs +++ b/src/osx/mod.rs @@ -1,4 +1,4 @@ -use Event; +use {CreationError, OsError, Event}; use libc; use std::sync::atomic::AtomicBool; @@ -48,37 +48,37 @@ impl Deref for HeadlessContext { #[cfg(feature = "window")] impl Window { - pub fn new(builder: WindowBuilder) -> Result { + pub fn new(builder: WindowBuilder) -> Result { Window::new_impl(builder.dimensions, builder.title.as_slice(), true) } } #[cfg(feature = "headless")] impl HeadlessContext { - pub fn new(builder: HeadlessRendererBuilder) -> Result { + pub fn new(builder: HeadlessRendererBuilder) -> Result { Window::new_impl(Some(builder.dimensions), "", false) .map(|w| HeadlessContext(w)) } } impl Window { - fn new_impl(dimensions: Option<(uint, uint)>, title: &str, visible: bool) -> Result { + fn new_impl(dimensions: Option<(uint, uint)>, title: &str, visible: bool) -> Result { let app = match Window::create_app() { Some(app) => app, - None => { return Err(format!("Couldn't create NSApplication")); }, + None => { return Err(OsError(format!("Couldn't create NSApplication"))); }, }; let window = match Window::create_window(dimensions.unwrap_or((800, 600)), title) { Some(window) => window, - None => { return Err(format!("Couldn't create NSWindow")); }, + None => { return Err(OsError(format!("Couldn't create NSWindow"))); }, }; let view = match Window::create_view(window) { Some(view) => view, - None => { return Err(format!("Couldn't create NSView")); }, + None => { return Err(OsError(format!("Couldn't create NSView"))); }, }; let context = match Window::create_context(view) { Some(context) => context, - None => { return Err(format!("Couldn't create OpenGL context")); }, + None => { return Err(OsError(format!("Couldn't create OpenGL context"))); }, }; unsafe { diff --git a/src/win32/init.rs b/src/win32/init.rs index 73a6a6a..beef44b 100644 --- a/src/win32/init.rs +++ b/src/win32/init.rs @@ -6,7 +6,7 @@ use std::sync::atomic::AtomicBool; use std::ptr; use super::{event, ffi}; use super::Window; -use Event; +use {CreationError, OsError, Event}; /// Stores the current window and its events dispatcher. /// @@ -17,7 +17,7 @@ local_data_key!(WINDOW: (ffi::HWND, Sender)) pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: String, builder_monitor: Option, builder_gl_version: Option<(uint, uint)>, builder_vsync: bool, - builder_hidden: bool) -> Result + builder_hidden: bool) -> Result { use std::mem; use std::os; @@ -94,7 +94,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin &mut screen_settings, ptr::null(), ffi::CDS_FULLSCREEN, ptr::null_mut()) }; if result != ffi::DISP_CHANGE_SUCCESSFUL { - tx.send(Err(format!("ChangeDisplaySettings failed: {}", result))); + tx.send(Err(OsError(format!("ChangeDisplaySettings failed: {}", result)))); return; } } @@ -125,8 +125,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin if handle.is_null() { use std::os; - tx.send(Err(format!("CreateWindowEx function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("CreateWindowEx function failed: {}", + os::error_string(os::errno() as uint))))); return; } @@ -137,8 +137,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin let dummy_hdc = { let hdc = unsafe { ffi::GetDC(dummy_window) }; if hdc.is_null() { - tx.send(Err(format!("GetDC function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("GetDC function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(dummy_window); } return; } @@ -165,8 +165,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin let pf_index = unsafe { ffi::ChoosePixelFormat(dummy_hdc, &output) }; if pf_index == 0 { - tx.send(Err(format!("ChoosePixelFormat function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("ChoosePixelFormat function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(dummy_window); } return; } @@ -174,8 +174,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin if unsafe { ffi::DescribePixelFormat(dummy_hdc, pf_index, mem::size_of::() as ffi::UINT, &mut output) } == 0 { - tx.send(Err(format!("DescribePixelFormat function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("DescribePixelFormat function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(dummy_window); } return; } @@ -186,8 +186,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin // calling SetPixelFormat unsafe { if ffi::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 { - tx.send(Err(format!("SetPixelFormat function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("SetPixelFormat function failed: {}", + os::error_string(os::errno() as uint))))); ffi::DestroyWindow(dummy_window); return; } @@ -197,8 +197,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin let dummy_context = { 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)))); + tx.send(Err(OsError(format!("wglCreateContext function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(dummy_window); } return; } @@ -254,8 +254,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin if handle.is_null() { use std::os; - tx.send(Err(format!("CreateWindowEx function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("CreateWindowEx function failed: {}", + os::error_string(os::errno() as uint))))); return; } @@ -266,8 +266,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin let hdc = { let hdc = unsafe { ffi::GetDC(real_window) }; if hdc.is_null() { - tx.send(Err(format!("GetDC function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("GetDC function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(real_window); } return; } @@ -277,8 +277,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin // calling SetPixelFormat unsafe { if ffi::SetPixelFormat(hdc, 1, &pixel_format) == 0 { - tx.send(Err(format!("SetPixelFormat function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("SetPixelFormat function failed: {}", + os::error_string(os::errno() as uint))))); ffi::DestroyWindow(real_window); return; } @@ -310,8 +310,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin }; if ctxt.is_null() { - tx.send(Err(format!("OpenGL context creation failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("OpenGL context creation failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::DestroyWindow(real_window); } return; } @@ -337,8 +337,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin .collect::>().as_ptr(); let lib = unsafe { ffi::LoadLibraryW(name) }; if lib.is_null() { - tx.send(Err(format!("LoadLibrary function failed: {}", - os::error_string(os::errno() as uint)))); + tx.send(Err(OsError(format!("LoadLibrary function failed: {}", + os::error_string(os::errno() as uint))))); unsafe { ffi::wgl::DeleteContext(context); } unsafe { ffi::DestroyWindow(real_window); } return; @@ -351,7 +351,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin if extra_functions.SwapIntervalEXT.is_loaded() { unsafe { ffi::wgl::MakeCurrent(hdc, context) }; if unsafe { extra_functions.SwapIntervalEXT(1) } == 0 { - tx.send(Err(format!("wglSwapIntervalEXT failed"))); + tx.send(Err(OsError(format!("wglSwapIntervalEXT failed")))); unsafe { ffi::wgl::DeleteContext(context); } unsafe { ffi::DestroyWindow(real_window); } return; diff --git a/src/win32/mod.rs b/src/win32/mod.rs index facfb6d..282b0bb 100644 --- a/src/win32/mod.rs +++ b/src/win32/mod.rs @@ -1,7 +1,7 @@ use std::sync::atomic::AtomicBool; use std::ptr; use libc; -use Event; +use {CreationError, Event}; #[cfg(feature = "window")] use WindowBuilder; @@ -23,7 +23,7 @@ pub struct HeadlessContext(Window); #[cfg(feature = "headless")] impl HeadlessContext { /// See the docs in the crate root file. - pub fn new(builder: HeadlessRendererBuilder) -> Result { + pub fn new(builder: HeadlessRendererBuilder) -> Result { let HeadlessRendererBuilder { dimensions, gl_version } = builder; init::new_window(Some(dimensions), "".to_string(), None, gl_version, false, true) .map(|w| HeadlessContext(w)) @@ -67,7 +67,7 @@ pub struct Window { #[cfg(feature = "window")] impl Window { /// See the docs in the crate root file. - pub fn new(builder: WindowBuilder) -> Result { + pub fn new(builder: WindowBuilder) -> Result { let WindowBuilder { dimensions, title, monitor, gl_version, vsync, visible } = builder; init::new_window(dimensions, title, monitor, gl_version, vsync, !visible) } diff --git a/src/x11/headless.rs b/src/x11/headless.rs index 4f4eb16..71232e5 100644 --- a/src/x11/headless.rs +++ b/src/x11/headless.rs @@ -1,4 +1,5 @@ use HeadlessRendererBuilder; +use CreationError; use libc; use std::{mem, ptr}; use super::ffi; @@ -11,7 +12,7 @@ pub struct HeadlessContext { } impl HeadlessContext { - pub fn new(builder: HeadlessRendererBuilder) -> Result { + pub fn new(builder: HeadlessRendererBuilder) -> Result { Ok(HeadlessContext { width: builder.dimensions.0, height: builder.dimensions.1, diff --git a/src/x11/window/mod.rs b/src/x11/window/mod.rs index 2d26cbd..f7f62b0 100644 --- a/src/x11/window/mod.rs +++ b/src/x11/window/mod.rs @@ -1,4 +1,5 @@ use {Event, WindowBuilder, KeyModifiers}; +use {CreationError, OsError}; use libc; use std::{mem, ptr}; use std::cell::Cell; @@ -37,7 +38,7 @@ pub struct Window { } impl Window { - pub fn new(builder: WindowBuilder) -> Result { + pub fn new(builder: WindowBuilder) -> Result { ensure_thread_init(); let dimensions = builder.dimensions.unwrap_or((800, 600)); @@ -45,7 +46,7 @@ impl Window { let display = unsafe { let display = ffi::XOpenDisplay(ptr::null()); if display.is_null() { - return Err(format!("XOpenDisplay failed")); + return Err(OsError(format!("XOpenDisplay failed"))); } display }; @@ -77,7 +78,7 @@ impl Window { let fb = ffi::glx::ChooseFBConfig(display, ffi::XDefaultScreen(display), VISUAL_ATTRIBUTES.as_ptr(), &mut num_fb); if fb.is_null() { - return Err(format!("glx::ChooseFBConfig failed")); + return Err(OsError(format!("glx::ChooseFBConfig failed"))); } let preferred_fb = *fb; // TODO: choose more wisely ffi::XFree(fb as *const libc::c_void); @@ -89,7 +90,7 @@ impl Window { let mut mode_num: libc::c_int = mem::uninitialized(); let mut modes: *mut *mut ffi::XF86VidModeModeInfo = mem::uninitialized(); if ffi::XF86VidModeGetAllModeLines(display, screen_id, &mut mode_num, &mut modes) == 0 { - return Err(format!("Could not query the video modes")); + return Err(OsError(format!("Could not query the video modes"))); } for i in range(0, mode_num) { @@ -99,7 +100,7 @@ impl Window { } }; if best_mode == -1 && builder.monitor.is_some() { - return Err(format!("Could not find a suitable graphics mode")); + return Err(OsError(format!("Could not find a suitable graphics mode"))); } modes @@ -113,7 +114,7 @@ impl Window { let mut visual_infos = unsafe { let vi = ffi::glx::GetVisualFromFBConfig(display, fb_config); if vi.is_null() { - return Err(format!("glx::ChooseVisual failed")); + return Err(OsError(format!("glx::ChooseVisual failed"))); } let vi_copy = *vi; ffi::XFree(vi as *const libc::c_void); @@ -182,7 +183,7 @@ impl Window { let im = unsafe { let im = ffi::XOpenIM(display, ptr::null(), ptr::null_mut(), ptr::null_mut()); if im.is_null() { - return Err(format!("XOpenIM failed")); + return Err(OsError(format!("XOpenIM failed"))); } im }; @@ -197,7 +198,7 @@ impl Window { ffi::XIMPreeditNothing | ffi::XIMStatusNothing, client_window.as_ptr(), window, ptr::null()); if ic.is_null() { - return Err(format!("XCreateIC failed")); + return Err(OsError(format!("XCreateIC failed"))); } ffi::XSetICFocus(ic); ic @@ -208,7 +209,7 @@ impl Window { let mut supported_ptr = false; ffi::XkbSetDetectableAutoRepeat(display, true, &mut supported_ptr); if !supported_ptr { - return Err(format!("XkbSetDetectableAutoRepeat failed")); + return Err(OsError(format!("XkbSetDetectableAutoRepeat failed"))); } } @@ -243,7 +244,7 @@ impl Window { }; if context.is_null() { - return Err(format!("GL context creation failed")); + return Err(OsError(format!("GL context creation failed"))); } context -- cgit v1.2.3