aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortomaka <pierre.krieger1708@gmail.com>2014-12-31 07:49:44 +0100
committertomaka <pierre.krieger1708@gmail.com>2014-12-31 07:49:44 +0100
commit4d5e39f436a1c68475f2dd97b33acf66117ee139 (patch)
tree83dfb936f2577b136536d713414a0fc6355c3442
parentfb42768a14228eba456cc8957820c14c105b1647 (diff)
parentc956559a5158e1d92ccc5acd7c89b025c68de758 (diff)
downloadglutin-4d5e39f436a1c68475f2dd97b33acf66117ee139.tar.gz
glutin-4d5e39f436a1c68475f2dd97b33acf66117ee139.zip
Merge pull request #173 from tomaka/change-builder-attribs
Finalize window building API
-rw-r--r--src/android/mod.rs7
-rw-r--r--src/lib.rs130
-rw-r--r--src/osx/headless.rs4
-rw-r--r--src/osx/mod.rs5
-rw-r--r--src/win32/mod.rs23
-rw-r--r--src/x11/headless.rs12
-rw-r--r--src/x11/mod.rs5
-rw-r--r--src/x11/window/mod.rs6
8 files changed, 131 insertions, 61 deletions
diff --git a/src/android/mod.rs b/src/android/mod.rs
index 111d4b4..b8514f1 100644
--- a/src/android/mod.rs
+++ b/src/android/mod.rs
@@ -7,8 +7,7 @@ use events::ElementState::{Pressed, Released};
use events::Event::{MouseInput, MouseMoved};
use events::MouseButton::LeftMouseButton;
-#[cfg(feature = "headless")]
-use HeadlessRendererBuilder;
+use BuilderAttribs;
pub struct Window {
display: ffi::egl::types::EGLDisplay,
@@ -45,7 +44,7 @@ pub struct HeadlessContext(int);
#[cfg(feature = "headless")]
impl HeadlessContext {
/// See the docs in the crate root file.
- pub fn new(_builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
+ pub fn new(_builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
unimplemented!()
}
@@ -66,7 +65,7 @@ unsafe impl Send for HeadlessContext {}
unsafe impl Sync for HeadlessContext {}
impl Window {
- pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
+ pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
use std::{mem, ptr};
if builder.sharing.is_some() {
diff --git a/src/lib.rs b/src/lib.rs
index 6a736cd..6a1c23b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -70,12 +70,14 @@ pub struct MonitorID(winimpl::MonitorID);
#[deriving(Clone, Show, PartialEq, Eq)]
pub enum CreationError {
OsError(String),
+ NotSupported,
}
impl std::error::Error for CreationError {
fn description(&self) -> &str {
match self {
&CreationError::OsError(ref text) => text.as_slice(),
+ &CreationError::NotSupported => "Some of the requested attributes are not supported",
}
}
}
@@ -92,7 +94,14 @@ pub enum Api {
/// Object that allows you to build windows.
#[cfg(feature = "window")]
pub struct WindowBuilder<'a> {
- sharing: Option<&'a Window>,
+ attribs: BuilderAttribs<'a>
+}
+
+/// Attributes
+struct BuilderAttribs<'a> {
+ headless: bool,
+ strict: bool,
+ sharing: Option<&'a winimpl::Window>,
dimensions: Option<(uint, uint)>,
title: String,
monitor: Option<winimpl::MonitorID>,
@@ -101,13 +110,18 @@ pub struct WindowBuilder<'a> {
vsync: bool,
visible: bool,
multisampling: Option<u16>,
+ depth_bits: Option<u8>,
+ stencil_bits: Option<u8>,
+ color_bits: Option<u8>,
+ alpha_bits: Option<u8>,
+ stereoscopy: bool,
}
-#[cfg(feature = "window")]
-impl<'a> WindowBuilder<'a> {
- /// Initializes a new `WindowBuilder` with default values.
- pub fn new() -> WindowBuilder<'a> {
- WindowBuilder {
+impl BuilderAttribs<'static> {
+ fn new() -> BuilderAttribs<'static> {
+ BuilderAttribs {
+ headless: false,
+ strict: false,
sharing: None,
dimensions: None,
title: "glutin window".to_string(),
@@ -117,6 +131,21 @@ impl<'a> WindowBuilder<'a> {
vsync: false,
visible: true,
multisampling: None,
+ depth_bits: None,
+ stencil_bits: None,
+ color_bits: None,
+ alpha_bits: None,
+ stereoscopy: false,
+ }
+ }
+}
+
+#[cfg(feature = "window")]
+impl<'a> WindowBuilder<'a> {
+ /// Initializes a new `WindowBuilder` with default values.
+ pub fn new() -> WindowBuilder<'a> {
+ WindowBuilder {
+ attribs: BuilderAttribs::new(),
}
}
@@ -124,13 +153,13 @@ impl<'a> WindowBuilder<'a> {
///
/// Width and height are in pixels.
pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder<'a> {
- self.dimensions = Some((width, height));
+ self.attribs.dimensions = Some((width, height));
self
}
/// Requests a specific title for the window.
pub fn with_title(mut self, title: String) -> WindowBuilder<'a> {
- self.title = title;
+ self.attribs.title = title;
self
}
@@ -139,7 +168,7 @@ impl<'a> WindowBuilder<'a> {
/// If you don't specify dimensions for the window, it will match the monitor's.
pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder<'a> {
let MonitorID(monitor) = monitor;
- self.monitor = Some(monitor);
+ self.attribs.monitor = Some(monitor);
self
}
@@ -147,7 +176,7 @@ impl<'a> WindowBuilder<'a> {
///
/// There are some exceptions, like FBOs or VAOs. See the OpenGL documentation.
pub fn with_shared_lists(mut self, other: &'a Window) -> WindowBuilder<'a> {
- self.sharing = Some(other);
+ self.attribs.sharing = Some(&other.window);
self
}
@@ -156,7 +185,7 @@ impl<'a> WindowBuilder<'a> {
/// Version is a (major, minor) pair. For example to request OpenGL 3.3
/// you would pass `(3, 3)`.
pub fn with_gl_version(mut self, version: (uint, uint)) -> WindowBuilder<'a> {
- self.gl_version = Some(version);
+ self.attribs.gl_version = Some(version);
self
}
@@ -165,19 +194,19 @@ impl<'a> WindowBuilder<'a> {
/// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled
/// when you run `cargo build` and disabled when you run `cargo build --release`.
pub fn with_gl_debug_flag(mut self, flag: bool) -> WindowBuilder<'a> {
- self.gl_debug = flag;
+ self.attribs.gl_debug = flag;
self
}
/// Requests that the window has vsync enabled.
pub fn with_vsync(mut self) -> WindowBuilder<'a> {
- self.vsync = true;
+ self.attribs.vsync = true;
self
}
/// Sets whether the window will be initially hidden or visible.
pub fn with_visibility(mut self, visible: bool) -> WindowBuilder<'a> {
- self.visible = visible;
+ self.attribs.visible = visible;
self
}
@@ -189,7 +218,32 @@ impl<'a> WindowBuilder<'a> {
pub fn with_multisampling(mut self, samples: u16) -> WindowBuilder<'a> {
use std::num::UnsignedInt;
assert!(samples.is_power_of_two());
- self.multisampling = Some(samples);
+ self.attribs.multisampling = Some(samples);
+ self
+ }
+
+ /// Sets the number of bits in the depth buffer.
+ pub fn with_depth_buffer(mut self, bits: u8) -> WindowBuilder<'a> {
+ self.attribs.depth_bits = Some(bits);
+ self
+ }
+
+ /// Sets the number of bits in the stencil buffer.
+ pub fn with_stencil_buffer(mut self, bits: u8) -> WindowBuilder<'a> {
+ self.attribs.stencil_bits = Some(bits);
+ self
+ }
+
+ /// Sets the number of bits in the color buffer.
+ pub fn with_pixel_format(mut self, color_bits: u8, alpha_bits: u8) -> WindowBuilder<'a> {
+ self.attribs.color_bits = Some(color_bits);
+ self.attribs.alpha_bits = Some(alpha_bits);
+ self
+ }
+
+ /// Request the backend to be stereoscopic.
+ pub fn with_stereoscopy(mut self) -> WindowBuilder<'a> {
+ self.attribs.stereoscopy = true;
self
}
@@ -199,26 +253,33 @@ impl<'a> WindowBuilder<'a> {
/// out of memory, etc.
pub fn build(mut self) -> Result<Window, CreationError> {
// 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())
+ if self.attribs.dimensions.is_none() && self.attribs.monitor.is_some() {
+ self.attribs.dimensions = Some(self.attribs.monitor.as_ref().unwrap().get_dimensions())
}
// default dimensions
- if self.dimensions.is_none() {
- self.dimensions = Some((1024, 768));
+ if self.attribs.dimensions.is_none() {
+ self.attribs.dimensions = Some((1024, 768));
}
// building
- winimpl::Window::new(self).map(|w| Window { window: w })
+ winimpl::Window::new(self.attribs).map(|w| Window { window: w })
+ }
+
+ /// Builds the window.
+ ///
+ /// The context is build in a *strict* way. That means that if the backend couldn't give
+ /// you what you requested, an `Err` will be returned.
+ pub fn build_strict(mut self) -> Result<Window, CreationError> {
+ self.attribs.strict = true;
+ self.build()
}
}
/// Object that allows you to build headless contexts.
#[cfg(feature = "headless")]
pub struct HeadlessRendererBuilder {
- dimensions: (uint, uint),
- gl_version: Option<(uint, uint)>,
- gl_debug: bool,
+ attribs: BuilderAttribs<'static>,
}
#[cfg(feature = "headless")]
@@ -226,9 +287,11 @@ impl HeadlessRendererBuilder {
/// Initializes a new `HeadlessRendererBuilder` with default values.
pub fn new(width: uint, height: uint) -> HeadlessRendererBuilder {
HeadlessRendererBuilder {
- dimensions: (width, height),
- gl_version: None,
- gl_debug: cfg!(ndebug),
+ attribs: BuilderAttribs {
+ headless: true,
+ dimensions: Some((width, height)),
+ .. BuilderAttribs::new()
+ },
}
}
@@ -237,7 +300,7 @@ impl HeadlessRendererBuilder {
/// Version is a (major, minor) pair. For example to request OpenGL 3.3
/// you would pass `(3, 3)`.
pub fn with_gl_version(mut self, version: (uint, uint)) -> HeadlessRendererBuilder {
- self.gl_version = Some(version);
+ self.attribs.gl_version = Some(version);
self
}
@@ -246,7 +309,7 @@ impl HeadlessRendererBuilder {
/// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled
/// when you run `cargo build` and disabled when you run `cargo build --release`.
pub fn with_gl_debug_flag(mut self, flag: bool) -> HeadlessRendererBuilder {
- self.gl_debug = flag;
+ self.attribs.gl_debug = flag;
self
}
@@ -255,7 +318,16 @@ 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<HeadlessContext, CreationError> {
- winimpl::HeadlessContext::new(self).map(|w| HeadlessContext { context: w })
+ winimpl::HeadlessContext::new(self.attribs).map(|w| HeadlessContext { context: w })
+ }
+
+ /// Builds the headless context.
+ ///
+ /// The context is build in a *strict* way. That means that if the backend couldn't give
+ /// you what you requested, an `Err` will be returned.
+ pub fn build_strict(mut self) -> Result<HeadlessContext, CreationError> {
+ self.attribs.strict = true;
+ self.build()
}
}
diff --git a/src/osx/headless.rs b/src/osx/headless.rs
index 1332cf3..39c8f50 100644
--- a/src/osx/headless.rs
+++ b/src/osx/headless.rs
@@ -1,6 +1,6 @@
use CreationError;
use CreationError::OsError;
-use HeadlessRendererBuilder;
+use BuilderAttribs;
use libc;
use std::ptr;
@@ -30,7 +30,7 @@ pub struct HeadlessContext {
}
impl HeadlessContext {
- pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
+ pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
let (width, height) = builder.dimensions;
let context = unsafe {
let attributes = [
diff --git a/src/osx/mod.rs b/src/osx/mod.rs
index 92ef641..b65f67a 100644
--- a/src/osx/mod.rs
+++ b/src/osx/mod.rs
@@ -5,8 +5,7 @@ use {CreationError, Event};
use CreationError::OsError;
use libc;
-#[cfg(feature = "window")]
-use WindowBuilder;
+use BuilderAttribs;
use cocoa::base::{id, NSUInteger, nil, objc_allocateClassPair, class, objc_registerClassPair};
use cocoa::base::{selector, msg_send, class_addMethod, class_addIvar};
@@ -63,7 +62,7 @@ pub struct Window {
#[cfg(feature = "window")]
impl Window {
- pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
+ pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
if builder.sharing.is_some() {
unimplemented!()
}
diff --git a/src/win32/mod.rs b/src/win32/mod.rs
index a5f0547..e90f93f 100644
--- a/src/win32/mod.rs
+++ b/src/win32/mod.rs
@@ -3,11 +3,7 @@ use std::ptr;
use libc;
use {CreationError, Event};
-#[cfg(feature = "window")]
-use WindowBuilder;
-
-#[cfg(feature = "headless")]
-use HeadlessRendererBuilder;
+use BuilderAttribs;
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@@ -19,15 +15,13 @@ mod init;
mod monitor;
///
-#[cfg(feature = "headless")]
pub struct HeadlessContext(Window);
-#[cfg(feature = "headless")]
impl HeadlessContext {
/// See the docs in the crate root file.
- pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
- let HeadlessRendererBuilder { dimensions, gl_version, gl_debug } = builder;
- init::new_window(Some(dimensions), "".to_string(), None, gl_version, gl_debug, false, true,
+ pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
+ let BuilderAttribs { dimensions, gl_version, gl_debug, .. } = builder;
+ init::new_window(dimensions, "".to_string(), None, gl_version, gl_debug, false, true,
None, None)
.map(|w| HeadlessContext(w))
}
@@ -83,14 +77,13 @@ pub struct Window {
unsafe impl Send for Window {}
unsafe impl Sync for Window {}
-#[cfg(feature = "window")]
impl Window {
/// See the docs in the crate root file.
- pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
- let WindowBuilder { dimensions, title, monitor, gl_version,
- gl_debug, vsync, visible, sharing, multisampling } = builder;
+ pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
+ let BuilderAttribs { dimensions, title, monitor, gl_version,
+ gl_debug, vsync, visible, sharing, multisampling, .. } = builder;
init::new_window(dimensions, title, monitor, gl_version, gl_debug, vsync,
- !visible, sharing.map(|w| init::ContextHack(w.window.context)),
+ !visible, sharing.map(|w| init::ContextHack(w.context)),
multisampling)
}
}
diff --git a/src/x11/headless.rs b/src/x11/headless.rs
index d6f1023..22d0654 100644
--- a/src/x11/headless.rs
+++ b/src/x11/headless.rs
@@ -1,4 +1,4 @@
-use HeadlessRendererBuilder;
+use BuilderAttribs;
use CreationError;
use CreationError::OsError;
use libc;
@@ -13,11 +13,13 @@ pub struct HeadlessContext {
}
impl HeadlessContext {
- pub fn new(builder: HeadlessRendererBuilder) -> Result<HeadlessContext, CreationError> {
+ pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
+ let dimensions = builder.dimensions.unwrap();
+
Ok(HeadlessContext {
- width: builder.dimensions.0,
- height: builder.dimensions.1,
- buffer: Vec::from_elem(builder.dimensions.0 * builder.dimensions.1, unsafe { mem::uninitialized() }),
+ width: dimensions.0,
+ height: dimensions.1,
+ buffer: Vec::from_elem(dimensions.0 * dimensions.1, unsafe { mem::uninitialized() }),
context: unsafe {
let ctxt = ffi::OSMesaCreateContext(0x1908, ptr::null());
if ctxt.is_null() {
diff --git a/src/x11/mod.rs b/src/x11/mod.rs
index 9ce789f..22184a9 100644
--- a/src/x11/mod.rs
+++ b/src/x11/mod.rs
@@ -11,3 +11,8 @@ mod headless;
#[cfg(feature = "window")]
mod window;
+
+#[cfg(not(feature = "window"))]
+pub type Window = (); // TODO: hack to make things work
+#[cfg(not(feature = "window"))]
+pub type MonitorID = (); // TODO: hack to make things work
diff --git a/src/x11/window/mod.rs b/src/x11/window/mod.rs
index 0a8c3d5..fc622ea 100644
--- a/src/x11/window/mod.rs
+++ b/src/x11/window/mod.rs
@@ -1,4 +1,4 @@
-use {Event, WindowBuilder};
+use {Event, BuilderAttribs};
use CreationError;
use CreationError::OsError;
use libc;
@@ -89,7 +89,7 @@ pub struct Window {
}
impl Window {
- pub fn new(builder: WindowBuilder) -> Result<Window, CreationError> {
+ pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
ensure_thread_init();
let dimensions = builder.dimensions.unwrap_or((800, 600));
@@ -308,7 +308,7 @@ impl Window {
});
let share = if let Some(win) = builder.sharing {
- win.window.x.context
+ win.x.context
} else {
ptr::null()
};