aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/x11')
-rw-r--r--src/api/x11/ffi.rs2
-rw-r--r--src/api/x11/mod.rs2
-rw-r--r--src/api/x11/window.rs39
-rw-r--r--src/api/x11/xdisplay.rs53
4 files changed, 70 insertions, 26 deletions
diff --git a/src/api/x11/ffi.rs b/src/api/x11/ffi.rs
index 3d4f0ed..465aa95 100644
--- a/src/api/x11/ffi.rs
+++ b/src/api/x11/ffi.rs
@@ -5,6 +5,8 @@ pub use x11_dl::xlib::*;
pub use x11_dl::xinput::*;
pub use x11_dl::xinput2::*;
+pub use x11_dl::error::OpenError;
+
pub use self::glx::types::GLXContext;
/// GLX bindings
diff --git a/src/api/x11/mod.rs b/src/api/x11/mod.rs
index 39b99f3..a7c997b 100644
--- a/src/api/x11/mod.rs
+++ b/src/api/x11/mod.rs
@@ -2,7 +2,7 @@
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
pub use self::window::{Window, XWindow, PollEventsIterator, WaitEventsIterator, Context, WindowProxy};
-pub use self::xdisplay::XConnection;
+pub use self::xdisplay::{XConnection, XNotSupported};
pub mod ffi;
diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs
index 5bfbda9..3032bfd 100644
--- a/src/api/x11/window.rs
+++ b/src/api/x11/window.rs
@@ -1,4 +1,4 @@
-use {Event, BuilderAttribs, MouseCursor};
+use {Event, MouseCursor};
use CreationError;
use CreationError::OsError;
use libc;
@@ -12,9 +12,12 @@ use std::sync::{Arc, Mutex};
use Api;
use ContextError;
use CursorState;
+use GlAttributes;
use GlContext;
use GlRequest;
use PixelFormat;
+use PixelFormatRequirements;
+use WindowAttributes;
use api::glx::Context as GlxContext;
use api::egl;
@@ -295,10 +298,13 @@ pub struct Window {
}
impl Window {
- pub fn new(display: &Arc<XConnection>, builder: BuilderAttribs) -> Result<Window, CreationError> {
- let dimensions = builder.dimensions.unwrap_or((800, 600));
+ pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes,
+ pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>)
+ -> Result<Window, CreationError>
+ {
+ let dimensions = window_attrs.dimensions.unwrap_or((800, 600));
- let screen_id = match builder.monitor {
+ let screen_id = match window_attrs.monitor {
Some(PlatformMonitorID::X(MonitorID(_, monitor))) => monitor as i32,
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) },
};
@@ -316,7 +322,7 @@ impl Window {
// FIXME: `XF86VidModeModeInfo` is missing its `hskew` field. Therefore we point to
// `vsyncstart` instead of `vdisplay` as a temporary hack.
- let mode_to_switch_to = if builder.monitor.is_some() {
+ let mode_to_switch_to = if window_attrs.monitor.is_some() {
let matching_mode = (0 .. mode_num).map(|i| {
let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m
}).find(|m| m.hdisplay == dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16);
@@ -348,22 +354,23 @@ impl Window {
Glx(::api::glx::ContextPrototype<'a>),
Egl(::api::egl::ContextPrototype<'a>),
}
- let builder_clone = builder.clone();
- let context = match builder.gl_version {
+ let builder_clone_opengl_glx = opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
+ let builder_clone_opengl_egl = opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
+ let context = match opengl.version {
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
// GLX should be preferred over EGL, otherwise crashes may occur
// on X11 – issue #314
if let Some(ref glx) = display.glx {
- Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, &builder_clone, display.display)))
+ Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, pf_reqs, &builder_clone_opengl_glx, display.display)))
} else if let Some(ref egl) = display.egl {
- Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone, egl::NativeDisplay::X11(Some(display.display as *const _)))))
+ Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
} else {
return Err(CreationError::NotSupported);
}
},
GlRequest::Specific(Api::OpenGlEs, _) => {
if let Some(ref egl) = display.egl {
- Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone, egl::NativeDisplay::X11(Some(display.display as *const _)))))
+ Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
} else {
return Err(CreationError::NotSupported);
}
@@ -415,7 +422,7 @@ impl Window {
ffi::KeyReleaseMask | ffi::ButtonPressMask |
ffi::ButtonReleaseMask | ffi::KeymapStateMask;
swa.border_pixel = 0;
- if builder.transparent {
+ if window_attrs.transparent {
swa.background_pixel = 0;
}
swa.override_redirect = 0;
@@ -424,7 +431,7 @@ impl Window {
let mut window_attributes = ffi::CWBorderPixel | ffi::CWColormap | ffi::CWEventMask;
- if builder.transparent {
+ if window_attrs.transparent {
window_attributes |= ffi::CWBackPixel;
}
@@ -448,7 +455,7 @@ impl Window {
};
// set visibility
- if builder.visible {
+ if window_attrs.visible {
unsafe {
(display.xlib.XMapRaised)(display.display, window);
(display.xlib.XFlush)(display.display);
@@ -461,7 +468,7 @@ impl Window {
(display.xlib.XInternAtom)(display.display, delete_window, 0)
);
(display.xlib.XSetWMProtocols)(display.display, window, &mut wm_delete_window, 1);
- with_c_str(&*builder.title, |title| {;
+ with_c_str(&*window_attrs.title, |title| {;
(display.xlib.XStoreName)(display.display, window, title);
});
(display.xlib.XFlush)(display.display);
@@ -509,7 +516,7 @@ impl Window {
// Set ICCCM WM_CLASS property based on initial window title
unsafe {
- with_c_str(&*builder.title, |c_name| {
+ with_c_str(&*window_attrs.title, |c_name| {
let hint = (display.xlib.XAllocClassHint)();
(*hint).res_name = c_name as *mut libc::c_char;
(*hint).res_class = c_name as *mut libc::c_char;
@@ -518,7 +525,7 @@ impl Window {
});
}
- let is_fullscreen = builder.monitor.is_some();
+ let is_fullscreen = window_attrs.monitor.is_some();
// finish creating the OpenGL context
let context = match context {
diff --git a/src/api/x11/xdisplay.rs b/src/api/x11/xdisplay.rs
index c960c00..2aa5d95 100644
--- a/src/api/x11/xdisplay.rs
+++ b/src/api/x11/xdisplay.rs
@@ -1,4 +1,6 @@
use std::ptr;
+use std::fmt;
+use std::error::Error;
use std::ffi::CString;
use libc;
@@ -21,17 +23,13 @@ pub struct XConnection {
unsafe impl Send for XConnection {}
unsafe impl Sync for XConnection {}
-/// Error returned if this system doesn't have XLib or can't create an X connection.
-#[derive(Copy, Clone, Debug)]
-pub struct XNotSupported;
-
impl XConnection {
pub fn new() -> Result<XConnection, XNotSupported> {
// opening the libraries
- let xlib = try!(ffi::Xlib::open().map_err(|_| XNotSupported));
- let xcursor = try!(ffi::Xcursor::open().map_err(|_| XNotSupported));
- let xf86vmode = try!(ffi::Xf86vmode::open().map_err(|_| XNotSupported));
- let xinput2 = try!(ffi::XInput2::open().map_err(|_| XNotSupported));
+ let xlib = try!(ffi::Xlib::open());
+ let xcursor = try!(ffi::Xcursor::open());
+ let xf86vmode = try!(ffi::Xf86vmode::open());
+ let xinput2 = try!(ffi::XInput2::open());
unsafe extern "C" fn x_error_callback(_: *mut ffi::Display, event: *mut ffi::XErrorEvent)
-> libc::c_int
@@ -82,7 +80,7 @@ impl XConnection {
let display = unsafe {
let display = (xlib.XOpenDisplay)(ptr::null());
if display.is_null() {
- return Err(XNotSupported);
+ return Err(XNotSupported::XOpenDisplayFailed);
}
display
};
@@ -104,3 +102,40 @@ impl Drop for XConnection {
unsafe { (self.xlib.XCloseDisplay)(self.display) };
}
}
+
+/// Error returned if this system doesn't have XLib or can't create an X connection.
+#[derive(Clone, Debug)]
+pub enum XNotSupported {
+ /// Failed to load one or several shared libraries.
+ LibraryOpenError(ffi::OpenError),
+ /// Connecting to the X server with `XOpenDisplay` failed.
+ XOpenDisplayFailed, // TODO: add better message
+}
+
+impl From<ffi::OpenError> for XNotSupported {
+ fn from(err: ffi::OpenError) -> XNotSupported {
+ XNotSupported::LibraryOpenError(err)
+ }
+}
+
+impl Error for XNotSupported {
+ fn description(&self) -> &str {
+ match *self {
+ XNotSupported::LibraryOpenError(_) => "Failed to load one of xlib's shared libraries",
+ XNotSupported::XOpenDisplayFailed => "Failed to open connection to X server",
+ }
+ }
+
+ fn cause(&self) -> Option<&Error> {
+ match *self {
+ XNotSupported::LibraryOpenError(ref err) => Some(err),
+ _ => None
+ }
+ }
+}
+
+impl fmt::Display for XNotSupported {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ formatter.write_str(self.description())
+ }
+}