Merge pull request #100 from tomaka/correct-creation-error

Use a proper error type for window creation
This commit is contained in:
tomaka 2014-11-05 17:01:57 +01:00
commit 6208c59a48
7 changed files with 76 additions and 60 deletions

View file

@ -2,7 +2,7 @@ extern crate android_glue;
extern crate native; extern crate native;
use libc; use libc;
use {Event, WindowBuilder}; use {CreationError, OsError, Event, WindowBuilder};
pub struct Window { pub struct Window {
display: ffi::egl::types::EGLDisplay, display: ffi::egl::types::EGLDisplay,
@ -35,18 +35,18 @@ impl MonitorID {
} }
impl Window { impl Window {
pub fn new(_builder: WindowBuilder) -> Result<Window, String> { pub fn new(_builder: WindowBuilder) -> Result<Window, CreationError> {
use std::{mem, ptr}; use std::{mem, ptr};
let native_window = unsafe { android_glue::get_native_window() }; let native_window = unsafe { android_glue::get_native_window() };
if native_window.is_null() { 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 = unsafe {
let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY)); let display = ffi::egl::GetDisplay(mem::transmute(ffi::egl::DEFAULT_DISPLAY));
if display.is_null() { if display.is_null() {
return Err("No EGL display connection available".to_string()); return Err(OsError("No EGL display connection available".to_string()));
} }
display display
}; };
@ -58,7 +58,7 @@ impl Window {
let mut minor: ffi::egl::types::EGLint = mem::uninitialized(); let mut minor: ffi::egl::types::EGLint = mem::uninitialized();
if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 { if ffi::egl::Initialize(display, &mut major, &mut minor) == 0 {
return Err(format!("eglInitialize failed")) return Err(OsError(format!("eglInitialize failed")))
} }
(major, minor) (major, minor)
@ -79,11 +79,11 @@ impl Window {
if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1, if ffi::egl::ChooseConfig(display, attribute_list.as_ptr(), &mut config, 1,
&mut num_config) == 0 &mut num_config) == 0
{ {
return Err(format!("eglChooseConfig failed")) return Err(OsError(format!("eglChooseConfig failed")))
} }
if num_config <= 0 { if num_config <= 0 {
return Err(format!("eglChooseConfig returned no available config")) return Err(OsError(format!("eglChooseConfig returned no available config")))
} }
config config
@ -94,7 +94,7 @@ impl Window {
let context = unsafe { let context = unsafe {
let context = ffi::egl::CreateContext(display, config, ptr::null(), ptr::null()); let context = ffi::egl::CreateContext(display, config, ptr::null(), ptr::null());
if context.is_null() { if context.is_null() {
return Err(format!("eglCreateContext failed")) return Err(OsError(format!("eglCreateContext failed")))
} }
context context
}; };
@ -104,7 +104,7 @@ impl Window {
let surface = unsafe { let surface = unsafe {
let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null()); let surface = ffi::egl::CreateWindowSurface(display, config, native_window, ptr::null());
if surface.is_null() { if surface.is_null() {
return Err(format!("eglCreateWindowSurface failed")) return Err(OsError(format!("eglCreateWindowSurface failed")))
} }
surface surface
}; };

View file

@ -70,6 +70,20 @@ compile_error!("Only the `windows`, `linux` and `macos` platforms are supported"
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub struct MonitorID(winimpl::MonitorID); 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. /// Object that allows you to build windows.
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub struct WindowBuilder { pub struct WindowBuilder {
@ -143,7 +157,7 @@ impl WindowBuilder {
/// ///
/// Error should be very rare and only occur in case of permission denied, incompatible system, /// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc. /// out of memory, etc.
pub fn build(mut self) -> Result<Window, String> { pub fn build(mut self) -> Result<Window, CreationError> {
// resizing the window to the dimensions of the monitor when fullscreen // resizing the window to the dimensions of the monitor when fullscreen
if self.dimensions.is_none() && self.monitor.is_some() { if self.dimensions.is_none() && self.monitor.is_some() {
self.dimensions = Some(self.monitor.as_ref().unwrap().get_dimensions()) 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, /// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc. /// out of memory, etc.
pub fn build(self) -> Result<HeadlessContext, String> { pub fn build(self) -> Result<HeadlessContext, CreationError> {
winimpl::HeadlessContext::new(self).map(|w| HeadlessContext { context: w }) winimpl::HeadlessContext::new(self).map(|w| HeadlessContext { context: w })
} }
} }
@ -238,7 +252,7 @@ impl Window {
/// out of memory, etc. /// out of memory, etc.
#[inline] #[inline]
#[cfg(feature = "window")] #[cfg(feature = "window")]
pub fn new() -> Result<Window, String> { pub fn new() -> Result<Window, CreationError> {
let builder = WindowBuilder::new(); let builder = WindowBuilder::new();
builder.build() builder.build()
} }

View file

@ -1,4 +1,4 @@
use Event; use {CreationError, OsError, Event};
use libc; use libc;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
@ -48,37 +48,37 @@ impl Deref<Window> for HeadlessContext {
#[cfg(feature = "window")] #[cfg(feature = "window")]
impl Window { impl Window {
pub fn new(builder: WindowBuilder) -> Result<Window, String> { pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
Window::new_impl(builder.dimensions, builder.title.as_slice(), true) Window::new_impl(builder.dimensions, builder.title.as_slice(), true)
} }
} }
#[cfg(feature = "headless")] #[cfg(feature = "headless")]
impl HeadlessContext { impl HeadlessContext {
pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, String> { pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
Window::new_impl(Some(builder.dimensions), "", false) Window::new_impl(Some(builder.dimensions), "", false)
.map(|w| HeadlessContext(w)) .map(|w| HeadlessContext(w))
} }
} }
impl Window { impl Window {
fn new_impl(dimensions: Option<(uint, uint)>, title: &str, visible: bool) -> Result<Window, String> { fn new_impl(dimensions: Option<(uint, uint)>, title: &str, visible: bool) -> Result<Window, CreationError> {
let app = match Window::create_app() { let app = match Window::create_app() {
Some(app) => 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) { let window = match Window::create_window(dimensions.unwrap_or((800, 600)), title) {
Some(window) => window, 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) { let view = match Window::create_view(window) {
Some(view) => view, 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) { let context = match Window::create_context(view) {
Some(context) => context, Some(context) => context,
None => { return Err(format!("Couldn't create OpenGL context")); }, None => { return Err(OsError(format!("Couldn't create OpenGL context"))); },
}; };
unsafe { unsafe {

View file

@ -6,7 +6,7 @@ use std::sync::atomic::AtomicBool;
use std::ptr; use std::ptr;
use super::{event, ffi}; use super::{event, ffi};
use super::Window; use super::Window;
use Event; use {CreationError, OsError, Event};
/// Stores the current window and its events dispatcher. /// Stores the current window and its events dispatcher.
/// ///
@ -17,7 +17,7 @@ local_data_key!(WINDOW: (ffi::HWND, Sender<Event>))
pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: String, pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: String,
builder_monitor: Option<super::MonitorID>, builder_monitor: Option<super::MonitorID>,
builder_gl_version: Option<(uint, uint)>, builder_vsync: bool, builder_gl_version: Option<(uint, uint)>, builder_vsync: bool,
builder_hidden: bool) -> Result<Window, String> builder_hidden: bool) -> Result<Window, CreationError>
{ {
use std::mem; use std::mem;
use std::os; 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()) }; &mut screen_settings, ptr::null(), ffi::CDS_FULLSCREEN, ptr::null_mut()) };
if result != ffi::DISP_CHANGE_SUCCESSFUL { if result != ffi::DISP_CHANGE_SUCCESSFUL {
tx.send(Err(format!("ChangeDisplaySettings failed: {}", result))); tx.send(Err(OsError(format!("ChangeDisplaySettings failed: {}", result))));
return; return;
} }
} }
@ -125,8 +125,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if handle.is_null() { if handle.is_null() {
use std::os; use std::os;
tx.send(Err(format!("CreateWindowEx function failed: {}", tx.send(Err(OsError(format!("CreateWindowEx function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
return; return;
} }
@ -137,8 +137,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let dummy_hdc = { let dummy_hdc = {
let hdc = unsafe { ffi::GetDC(dummy_window) }; let hdc = unsafe { ffi::GetDC(dummy_window) };
if hdc.is_null() { if hdc.is_null() {
tx.send(Err(format!("GetDC function failed: {}", tx.send(Err(OsError(format!("GetDC function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(dummy_window); } unsafe { ffi::DestroyWindow(dummy_window); }
return; 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) }; let pf_index = unsafe { ffi::ChoosePixelFormat(dummy_hdc, &output) };
if pf_index == 0 { if pf_index == 0 {
tx.send(Err(format!("ChoosePixelFormat function failed: {}", tx.send(Err(OsError(format!("ChoosePixelFormat function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(dummy_window); } unsafe { ffi::DestroyWindow(dummy_window); }
return; 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, if unsafe { ffi::DescribePixelFormat(dummy_hdc, pf_index,
mem::size_of::<ffi::PIXELFORMATDESCRIPTOR>() as ffi::UINT, &mut output) } == 0 mem::size_of::<ffi::PIXELFORMATDESCRIPTOR>() as ffi::UINT, &mut output) } == 0
{ {
tx.send(Err(format!("DescribePixelFormat function failed: {}", tx.send(Err(OsError(format!("DescribePixelFormat function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(dummy_window); } unsafe { ffi::DestroyWindow(dummy_window); }
return; return;
} }
@ -186,8 +186,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
// calling SetPixelFormat // calling SetPixelFormat
unsafe { unsafe {
if ffi::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 { if ffi::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 {
tx.send(Err(format!("SetPixelFormat function failed: {}", tx.send(Err(OsError(format!("SetPixelFormat function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
ffi::DestroyWindow(dummy_window); ffi::DestroyWindow(dummy_window);
return; return;
} }
@ -197,8 +197,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let dummy_context = { let dummy_context = {
let ctxt = unsafe { ffi::wgl::CreateContext(dummy_hdc) }; let ctxt = unsafe { ffi::wgl::CreateContext(dummy_hdc) };
if ctxt.is_null() { if ctxt.is_null() {
tx.send(Err(format!("wglCreateContext function failed: {}", tx.send(Err(OsError(format!("wglCreateContext function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(dummy_window); } unsafe { ffi::DestroyWindow(dummy_window); }
return; return;
} }
@ -254,8 +254,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if handle.is_null() { if handle.is_null() {
use std::os; use std::os;
tx.send(Err(format!("CreateWindowEx function failed: {}", tx.send(Err(OsError(format!("CreateWindowEx function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
return; return;
} }
@ -266,8 +266,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let hdc = { let hdc = {
let hdc = unsafe { ffi::GetDC(real_window) }; let hdc = unsafe { ffi::GetDC(real_window) };
if hdc.is_null() { if hdc.is_null() {
tx.send(Err(format!("GetDC function failed: {}", tx.send(Err(OsError(format!("GetDC function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(real_window); } unsafe { ffi::DestroyWindow(real_window); }
return; return;
} }
@ -277,8 +277,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
// calling SetPixelFormat // calling SetPixelFormat
unsafe { unsafe {
if ffi::SetPixelFormat(hdc, 1, &pixel_format) == 0 { if ffi::SetPixelFormat(hdc, 1, &pixel_format) == 0 {
tx.send(Err(format!("SetPixelFormat function failed: {}", tx.send(Err(OsError(format!("SetPixelFormat function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
ffi::DestroyWindow(real_window); ffi::DestroyWindow(real_window);
return; return;
} }
@ -310,8 +310,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
}; };
if ctxt.is_null() { if ctxt.is_null() {
tx.send(Err(format!("OpenGL context creation failed: {}", tx.send(Err(OsError(format!("OpenGL context creation failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::DestroyWindow(real_window); } unsafe { ffi::DestroyWindow(real_window); }
return; return;
} }
@ -337,8 +337,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
.collect::<Vec<u16>>().as_ptr(); .collect::<Vec<u16>>().as_ptr();
let lib = unsafe { ffi::LoadLibraryW(name) }; let lib = unsafe { ffi::LoadLibraryW(name) };
if lib.is_null() { if lib.is_null() {
tx.send(Err(format!("LoadLibrary function failed: {}", tx.send(Err(OsError(format!("LoadLibrary function failed: {}",
os::error_string(os::errno() as uint)))); os::error_string(os::errno() as uint)))));
unsafe { ffi::wgl::DeleteContext(context); } unsafe { ffi::wgl::DeleteContext(context); }
unsafe { ffi::DestroyWindow(real_window); } unsafe { ffi::DestroyWindow(real_window); }
return; return;
@ -351,7 +351,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if extra_functions.SwapIntervalEXT.is_loaded() { if extra_functions.SwapIntervalEXT.is_loaded() {
unsafe { ffi::wgl::MakeCurrent(hdc, context) }; unsafe { ffi::wgl::MakeCurrent(hdc, context) };
if unsafe { extra_functions.SwapIntervalEXT(1) } == 0 { 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::wgl::DeleteContext(context); }
unsafe { ffi::DestroyWindow(real_window); } unsafe { ffi::DestroyWindow(real_window); }
return; return;

View file

@ -1,7 +1,7 @@
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::ptr; use std::ptr;
use libc; use libc;
use Event; use {CreationError, Event};
#[cfg(feature = "window")] #[cfg(feature = "window")]
use WindowBuilder; use WindowBuilder;
@ -23,7 +23,7 @@ pub struct HeadlessContext(Window);
#[cfg(feature = "headless")] #[cfg(feature = "headless")]
impl HeadlessContext { impl HeadlessContext {
/// See the docs in the crate root file. /// See the docs in the crate root file.
pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, String> { pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
let HeadlessRendererBuilder { dimensions, gl_version } = builder; let HeadlessRendererBuilder { dimensions, gl_version } = builder;
init::new_window(Some(dimensions), "".to_string(), None, gl_version, false, true) init::new_window(Some(dimensions), "".to_string(), None, gl_version, false, true)
.map(|w| HeadlessContext(w)) .map(|w| HeadlessContext(w))
@ -67,7 +67,7 @@ pub struct Window {
#[cfg(feature = "window")] #[cfg(feature = "window")]
impl Window { impl Window {
/// See the docs in the crate root file. /// See the docs in the crate root file.
pub fn new(builder: WindowBuilder) -> Result<Window, String> { pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
let WindowBuilder { dimensions, title, monitor, gl_version, vsync, visible } = builder; let WindowBuilder { dimensions, title, monitor, gl_version, vsync, visible } = builder;
init::new_window(dimensions, title, monitor, gl_version, vsync, !visible) init::new_window(dimensions, title, monitor, gl_version, vsync, !visible)
} }

View file

@ -1,4 +1,5 @@
use HeadlessRendererBuilder; use HeadlessRendererBuilder;
use CreationError;
use libc; use libc;
use std::{mem, ptr}; use std::{mem, ptr};
use super::ffi; use super::ffi;
@ -11,7 +12,7 @@ pub struct HeadlessContext {
} }
impl HeadlessContext { impl HeadlessContext {
pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, String> { pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
Ok(HeadlessContext { Ok(HeadlessContext {
width: builder.dimensions.0, width: builder.dimensions.0,
height: builder.dimensions.1, height: builder.dimensions.1,

View file

@ -1,4 +1,5 @@
use {Event, WindowBuilder, KeyModifiers}; use {Event, WindowBuilder, KeyModifiers};
use {CreationError, OsError};
use libc; use libc;
use std::{mem, ptr}; use std::{mem, ptr};
use std::cell::Cell; use std::cell::Cell;
@ -37,7 +38,7 @@ pub struct Window {
} }
impl Window { impl Window {
pub fn new(builder: WindowBuilder) -> Result<Window, String> { pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
ensure_thread_init(); ensure_thread_init();
let dimensions = builder.dimensions.unwrap_or((800, 600)); let dimensions = builder.dimensions.unwrap_or((800, 600));
@ -45,7 +46,7 @@ impl Window {
let display = unsafe { let display = unsafe {
let display = ffi::XOpenDisplay(ptr::null()); let display = ffi::XOpenDisplay(ptr::null());
if display.is_null() { if display.is_null() {
return Err(format!("XOpenDisplay failed")); return Err(OsError(format!("XOpenDisplay failed")));
} }
display display
}; };
@ -77,7 +78,7 @@ impl Window {
let fb = ffi::glx::ChooseFBConfig(display, ffi::XDefaultScreen(display), let fb = ffi::glx::ChooseFBConfig(display, ffi::XDefaultScreen(display),
VISUAL_ATTRIBUTES.as_ptr(), &mut num_fb); VISUAL_ATTRIBUTES.as_ptr(), &mut num_fb);
if fb.is_null() { 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 let preferred_fb = *fb; // TODO: choose more wisely
ffi::XFree(fb as *const libc::c_void); 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 mode_num: libc::c_int = mem::uninitialized();
let mut modes: *mut *mut ffi::XF86VidModeModeInfo = mem::uninitialized(); let mut modes: *mut *mut ffi::XF86VidModeModeInfo = mem::uninitialized();
if ffi::XF86VidModeGetAllModeLines(display, screen_id, &mut mode_num, &mut modes) == 0 { 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) { for i in range(0, mode_num) {
@ -99,7 +100,7 @@ impl Window {
} }
}; };
if best_mode == -1 && builder.monitor.is_some() { 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 modes
@ -113,7 +114,7 @@ impl Window {
let mut visual_infos = unsafe { let mut visual_infos = unsafe {
let vi = ffi::glx::GetVisualFromFBConfig(display, fb_config); let vi = ffi::glx::GetVisualFromFBConfig(display, fb_config);
if vi.is_null() { if vi.is_null() {
return Err(format!("glx::ChooseVisual failed")); return Err(OsError(format!("glx::ChooseVisual failed")));
} }
let vi_copy = *vi; let vi_copy = *vi;
ffi::XFree(vi as *const libc::c_void); ffi::XFree(vi as *const libc::c_void);
@ -182,7 +183,7 @@ impl Window {
let im = unsafe { let im = unsafe {
let im = ffi::XOpenIM(display, ptr::null(), ptr::null_mut(), ptr::null_mut()); let im = ffi::XOpenIM(display, ptr::null(), ptr::null_mut(), ptr::null_mut());
if im.is_null() { if im.is_null() {
return Err(format!("XOpenIM failed")); return Err(OsError(format!("XOpenIM failed")));
} }
im im
}; };
@ -197,7 +198,7 @@ impl Window {
ffi::XIMPreeditNothing | ffi::XIMStatusNothing, client_window.as_ptr(), ffi::XIMPreeditNothing | ffi::XIMStatusNothing, client_window.as_ptr(),
window, ptr::null()); window, ptr::null());
if ic.is_null() { if ic.is_null() {
return Err(format!("XCreateIC failed")); return Err(OsError(format!("XCreateIC failed")));
} }
ffi::XSetICFocus(ic); ffi::XSetICFocus(ic);
ic ic
@ -208,7 +209,7 @@ impl Window {
let mut supported_ptr = false; let mut supported_ptr = false;
ffi::XkbSetDetectableAutoRepeat(display, true, &mut supported_ptr); ffi::XkbSetDetectableAutoRepeat(display, true, &mut supported_ptr);
if !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() { if context.is_null() {
return Err(format!("GL context creation failed")); return Err(OsError(format!("GL context creation failed")));
} }
context context