mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
Merge pull request #173 from tomaka/change-builder-attribs
Finalize window building API
This commit is contained in:
commit
4d5e39f436
|
@ -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() {
|
||||
|
|
130
src/lib.rs
130
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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!()
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue