mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-01-11 13:31:29 +11:00
Add iterators for events and WindowBuilder
This commit is contained in:
parent
959613870c
commit
5dda167021
|
@ -5,8 +5,6 @@ extern crate gl;
|
||||||
use std::io::stdio::stdin;
|
use std::io::stdio::stdin;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use std::default::Default;
|
|
||||||
|
|
||||||
// enumerating monitors
|
// enumerating monitors
|
||||||
let monitor = {
|
let monitor = {
|
||||||
for (num, monitor) in init::get_available_monitors().enumerate() {
|
for (num, monitor) in init::get_available_monitors().enumerate() {
|
||||||
|
@ -23,8 +21,11 @@ fn main() {
|
||||||
monitor
|
monitor
|
||||||
};
|
};
|
||||||
|
|
||||||
let window = init::Window::new(None, "Hello world!", &Default::default(),
|
let window = init::WindowBuilder::new()
|
||||||
Some(monitor)).unwrap();
|
.with_title("Hello world!".to_string())
|
||||||
|
.with_monitor(monitor)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
unsafe { window.make_current() };
|
unsafe { window.make_current() };
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ fn main() {
|
||||||
gl::ClearColor(0.0, 1.0, 0.0, 1.0);
|
gl::ClearColor(0.0, 1.0, 0.0, 1.0);
|
||||||
|
|
||||||
while !window.is_closed() {
|
while !window.is_closed() {
|
||||||
println!("{}", window.wait_events());
|
println!("{}", window.wait_events().collect::<Vec<init::Event>>());
|
||||||
|
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,7 @@ extern crate libc;
|
||||||
extern crate gl;
|
extern crate gl;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use std::default::Default;
|
let window = init::Window::new().unwrap();
|
||||||
|
|
||||||
let window = init::Window::new(None, "Hello world!", &Default::default(), None).unwrap();
|
|
||||||
|
|
||||||
unsafe { window.make_current() };
|
unsafe { window.make_current() };
|
||||||
|
|
||||||
|
@ -21,7 +19,7 @@ fn main() {
|
||||||
gl::ClearColor(0.0, 1.0, 0.0, 1.0);
|
gl::ClearColor(0.0, 1.0, 0.0, 1.0);
|
||||||
|
|
||||||
while !window.is_closed() {
|
while !window.is_closed() {
|
||||||
println!("{}", window.wait_events());
|
println!("{}", window.wait_events().collect::<Vec<init::Event>>());
|
||||||
|
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
74
src/hints.rs
74
src/hints.rs
|
@ -1,74 +0,0 @@
|
||||||
use std::default::Default;
|
|
||||||
|
|
||||||
#[deriving(Clone,Show)]
|
|
||||||
#[deprecated = "Will be removed soon (it's not supported anyway)"]
|
|
||||||
pub struct Hints {
|
|
||||||
pub resizable: bool,
|
|
||||||
pub visible: bool,
|
|
||||||
pub decorated: bool,
|
|
||||||
pub red_bits: u8,
|
|
||||||
pub green_bits: u8,
|
|
||||||
pub blue_bits: u8,
|
|
||||||
pub alpha_bits: u8,
|
|
||||||
pub depth_bits: u8,
|
|
||||||
pub stencil_bits: u8,
|
|
||||||
pub accum_red_bits: u8,
|
|
||||||
pub accum_green_bits: u8,
|
|
||||||
pub accum_blue_bits: u8,
|
|
||||||
pub accum_alpha_bits: u8,
|
|
||||||
pub aux_buffers: u8,
|
|
||||||
pub samples: u8,
|
|
||||||
pub refresh_rate: u8,
|
|
||||||
pub stereo: bool,
|
|
||||||
pub srgb_capable: bool,
|
|
||||||
pub client_api: ClientAPI,
|
|
||||||
pub context_version: (u8, u8),
|
|
||||||
//pub robustness: ,
|
|
||||||
pub opengl_forward_compat: bool,
|
|
||||||
pub opengl_debug_context: bool,
|
|
||||||
pub opengl_profile: Profile,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deriving(Clone, Show)]
|
|
||||||
pub enum ClientAPI {
|
|
||||||
OpenGL,
|
|
||||||
OpenGLES,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deriving(Clone, Show)]
|
|
||||||
pub enum Profile {
|
|
||||||
AnyProfile,
|
|
||||||
CompatProfile,
|
|
||||||
CoreProfile,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Hints {
|
|
||||||
fn default() -> Hints {
|
|
||||||
Hints {
|
|
||||||
resizable: true,
|
|
||||||
visible: true,
|
|
||||||
decorated: true,
|
|
||||||
red_bits: 8,
|
|
||||||
green_bits: 8,
|
|
||||||
blue_bits: 8,
|
|
||||||
alpha_bits: 8,
|
|
||||||
depth_bits: 24,
|
|
||||||
stencil_bits: 8,
|
|
||||||
accum_red_bits: 0,
|
|
||||||
accum_green_bits: 0,
|
|
||||||
accum_blue_bits: 0,
|
|
||||||
accum_alpha_bits: 0,
|
|
||||||
aux_buffers: 0,
|
|
||||||
samples: 0,
|
|
||||||
refresh_rate: 0,
|
|
||||||
stereo: false,
|
|
||||||
srgb_capable: false,
|
|
||||||
client_api: OpenGL,
|
|
||||||
context_version: (1, 0),
|
|
||||||
//robustness: ,
|
|
||||||
opengl_forward_compat: false,
|
|
||||||
opengl_debug_context: false,
|
|
||||||
opengl_profile: AnyProfile,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
147
src/lib.rs
147
src/lib.rs
|
@ -5,7 +5,6 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
pub use events::*;
|
pub use events::*;
|
||||||
pub use hints::{Hints, ClientAPI, Profile};
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winimpl = win32;
|
use winimpl = win32;
|
||||||
|
@ -21,19 +20,63 @@ mod x11;
|
||||||
//mod egl;
|
//mod egl;
|
||||||
|
|
||||||
mod events;
|
mod events;
|
||||||
mod hints;
|
|
||||||
|
|
||||||
/// Identifier for a monitor.
|
/// Identifier for a monitor.
|
||||||
pub struct MonitorID(winimpl::MonitorID);
|
pub struct MonitorID(winimpl::MonitorID);
|
||||||
|
|
||||||
|
/// Object that allows you to build windows.
|
||||||
|
pub struct WindowBuilder {
|
||||||
|
dimensions: (uint, uint),
|
||||||
|
title: String,
|
||||||
|
monitor: Option<winimpl::MonitorID>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowBuilder {
|
||||||
|
/// Initializes a new `WindowBuilder` with default values.
|
||||||
|
pub fn new() -> WindowBuilder {
|
||||||
|
WindowBuilder {
|
||||||
|
dimensions: (1024, 768),
|
||||||
|
title: String::new(),
|
||||||
|
monitor: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder {
|
||||||
|
self.dimensions = (width, height);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_title(mut self, title: String) -> WindowBuilder {
|
||||||
|
self.title = title;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_monitor(mut self, monitor: MonitorID) -> WindowBuilder {
|
||||||
|
let MonitorID(monitor) = monitor;
|
||||||
|
self.monitor = Some(monitor);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds the window.
|
||||||
|
///
|
||||||
|
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||||
|
/// out of memory, etc.
|
||||||
|
pub fn build(self) -> Result<Window, String> {
|
||||||
|
let win = try!(winimpl::Window::new(Some(self.dimensions),
|
||||||
|
self.title.as_slice(), self.monitor));
|
||||||
|
|
||||||
|
Ok(Window{
|
||||||
|
window: win,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Represents an OpenGL context and the Window or environment around it.
|
/// Represents an OpenGL context and the Window or environment around it.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::default::Default;
|
/// let window = Window::new().unwrap();
|
||||||
///
|
|
||||||
/// let window = Window::new(None, "Hello world!", &Default::default(), None).unwrap();
|
|
||||||
///
|
///
|
||||||
/// unsafe { window.make_current() };
|
/// unsafe { window.make_current() };
|
||||||
///
|
///
|
||||||
|
@ -57,43 +100,15 @@ pub struct Window {
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
/// Creates a new OpenGL context, and a Window for platforms where this is appropriate.
|
/// Creates a new OpenGL context, and a Window for platforms where this is appropriate.
|
||||||
|
///
|
||||||
|
/// This function is equivalent to `WindowBuilder::new().build()`.
|
||||||
///
|
///
|
||||||
/// # Parameters
|
|
||||||
///
|
|
||||||
/// The `dimensions` parameter tell the library what the dimensions of the client area
|
|
||||||
/// of the window must be. If set to `None`, the library will choose or let the O/S choose.
|
|
||||||
///
|
|
||||||
/// The `title` parameter is the title that the window must have.
|
|
||||||
///
|
|
||||||
/// The `hints` parameter must be a `Hint` object which contains hints about how the context
|
|
||||||
/// must be created. This library will *try* to follow the hints, but will still success
|
|
||||||
/// even if it could not conform to all of them.
|
|
||||||
///
|
|
||||||
/// The `monitor` parameter is the identifier of the monitor that this window should fill.
|
|
||||||
/// If `None`, a windowed window will be created. If `Some(_)`, the window will be fullscreen
|
|
||||||
/// and will fill the given monitor. Note `MonitorID` does not necessarly represent a
|
|
||||||
/// *physical* monitor.
|
|
||||||
///
|
|
||||||
/// # Return value
|
|
||||||
///
|
|
||||||
/// Returns the `Window` object.
|
|
||||||
///
|
|
||||||
/// 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.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(dimensions: Option<(uint, uint)>, title: &str,
|
pub fn new() -> Result<Window, String> {
|
||||||
hints: &Hints, monitor: Option<MonitorID>)
|
let builder = WindowBuilder::new();
|
||||||
-> Result<Window, String>
|
builder.build()
|
||||||
{
|
|
||||||
// extracting the monitor ID
|
|
||||||
let monitor = monitor.map(|id| { let MonitorID(id) = id; id });
|
|
||||||
|
|
||||||
// creating the window
|
|
||||||
let win = try!(winimpl::Window::new(dimensions, title, hints, monitor));
|
|
||||||
|
|
||||||
Ok(Window{
|
|
||||||
window: win,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the window has previously been closed by the user.
|
/// Returns true if the window has previously been closed by the user.
|
||||||
|
@ -176,32 +191,22 @@ impl Window {
|
||||||
self.window.set_inner_size(x, y)
|
self.window.set_inner_size(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all the events that are currently in window's events queue.
|
/// Returns an iterator to all the events that are currently in the window's events queue.
|
||||||
///
|
///
|
||||||
/// Contrary to `wait_events`, this function never blocks.
|
/// Contrary to `wait_events`, this function never blocks.
|
||||||
#[experimental = "Will probably be changed to return an iterator instead of a Vec"]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn poll_events(&self) -> Vec<Event> {
|
pub fn poll_events(&self) -> PollEventsIterator {
|
||||||
self.window.poll_events()
|
PollEventsIterator { data: self.window.poll_events() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all the events that are currently in window's events queue.
|
/// Waits for an event, then returns an iterator to all the events that are currently
|
||||||
/// If there are no events in queue, this function will block until there is one.
|
/// in the window's events queue.
|
||||||
///
|
///
|
||||||
/// This is equivalent to:
|
/// If there are no events in queue when you call the function,
|
||||||
///
|
/// this function will block until there is one.
|
||||||
/// ```
|
|
||||||
/// loop {
|
|
||||||
/// let events = poll_events();
|
|
||||||
/// if events.len() >= 1 { return events }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ...but without the spinlock.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[experimental = "Will probably be changed to return an iterator instead of a Vec"]
|
pub fn wait_events(&self) -> WaitEventsIterator {
|
||||||
pub fn wait_events(&self) -> Vec<Event> {
|
WaitEventsIterator { data: self.window.wait_events() }
|
||||||
self.window.wait_events()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the context as the current context.
|
/// Sets the context as the current context.
|
||||||
|
@ -229,6 +234,32 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator for the `poll_events` function.
|
||||||
|
// Implementation note: we retreive the list once, then serve each element by one by one.
|
||||||
|
// This may change in the future.
|
||||||
|
pub struct PollEventsIterator<'a> {
|
||||||
|
data: Vec<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator<Event> for PollEventsIterator<'a> {
|
||||||
|
fn next(&mut self) -> Option<Event> {
|
||||||
|
self.data.remove(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An iterator for the `wait_events` function.
|
||||||
|
// Implementation note: we retreive the list once, then serve each element by one by one.
|
||||||
|
// This may change in the future.
|
||||||
|
pub struct WaitEventsIterator<'a> {
|
||||||
|
data: Vec<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator<Event> for WaitEventsIterator<'a> {
|
||||||
|
fn next(&mut self) -> Option<Event> {
|
||||||
|
self.data.remove(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An iterator for the list of available monitors.
|
/// An iterator for the list of available monitors.
|
||||||
// Implementation note: we retreive the list once, then serve each element by one by one.
|
// Implementation note: we retreive the list once, then serve each element by one by one.
|
||||||
// This may change in the future.
|
// This may change in the future.
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::sync::atomics::AtomicBool;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use super::{event, ffi};
|
use super::{event, ffi};
|
||||||
use super::{MonitorID, Window};
|
use super::{MonitorID, Window};
|
||||||
use {Event, Hints};
|
use Event;
|
||||||
|
|
||||||
/// Stores the current window and its events dispatcher.
|
/// Stores the current window and its events dispatcher.
|
||||||
///
|
///
|
||||||
|
@ -15,7 +15,7 @@ use {Event, Hints};
|
||||||
local_data_key!(WINDOW: (ffi::HWND, Sender<Event>))
|
local_data_key!(WINDOW: (ffi::HWND, Sender<Event>))
|
||||||
|
|
||||||
pub fn new_window(dimensions: Option<(uint, uint)>, title: &str,
|
pub fn new_window(dimensions: Option<(uint, uint)>, title: &str,
|
||||||
_hints: &Hints, monitor: Option<MonitorID>)
|
monitor: Option<MonitorID>)
|
||||||
-> Result<Window, String>
|
-> Result<Window, String>
|
||||||
{
|
{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::atomics::AtomicBool;
|
use std::sync::atomics::AtomicBool;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use {Event, Hints};
|
use Event;
|
||||||
|
|
||||||
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
|
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ pub struct Window {
|
||||||
impl Window {
|
impl Window {
|
||||||
/// See the docs if the crate root file.
|
/// See the docs if the crate root file.
|
||||||
pub fn new(dimensions: Option<(uint, uint)>, title: &str,
|
pub fn new(dimensions: Option<(uint, uint)>, title: &str,
|
||||||
hints: &Hints, monitor: Option<MonitorID>)
|
monitor: Option<MonitorID>)
|
||||||
-> Result<Window, String>
|
-> Result<Window, String>
|
||||||
{
|
{
|
||||||
init::new_window(dimensions, title, hints, monitor)
|
init::new_window(dimensions, title, monitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See the docs if the crate root file.
|
/// See the docs if the crate root file.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use {Event, Hints};
|
use Event;
|
||||||
use libc;
|
use libc;
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
use std::sync::atomics::AtomicBool;
|
use std::sync::atomics::AtomicBool;
|
||||||
|
@ -33,7 +33,7 @@ impl MonitorID {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(dimensions: Option<(uint, uint)>, title: &str, hints: &Hints, _: Option<MonitorID>)
|
pub fn new(dimensions: Option<(uint, uint)>, title: &str, _: Option<MonitorID>)
|
||||||
-> Result<Window, String>
|
-> Result<Window, String>
|
||||||
{
|
{
|
||||||
// calling XOpenDisplay
|
// calling XOpenDisplay
|
||||||
|
|
Loading…
Reference in a new issue