aboutsummaryrefslogtreecommitdiffstats
path: root/src/win32
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32')
-rw-r--r--src/win32/init.rs64
-rw-r--r--src/win32/mod.rs104
-rw-r--r--src/win32/monitor.rs28
3 files changed, 108 insertions, 88 deletions
diff --git a/src/win32/init.rs b/src/win32/init.rs
index 3cdf8d5..7317c42 100644
--- a/src/win32/init.rs
+++ b/src/win32/init.rs
@@ -6,7 +6,9 @@ use {CreationError, Event};
use CreationError::OsError;
use std::cell::RefCell;
+use std::ffi::CString;
use std::rc::Rc;
+use std::sync::mpsc::{Sender, Receiver, channel};
use libc;
use super::gl;
@@ -18,11 +20,15 @@ use winapi;
/// receive an event for another window.
thread_local!(static WINDOW: Rc<RefCell<Option<(winapi::HWND, Sender<Event>)>>> = Rc::new(RefCell::new(None)));
-pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: String,
+/// Work-around the fact that HGLRC doesn't implement Send
+pub struct ContextHack(pub winapi::HGLRC);
+unsafe impl Send for ContextHack {}
+
+pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
builder_monitor: Option<super::MonitorID>,
- builder_gl_version: Option<(uint, uint)>, builder_debug: bool,
+ builder_gl_version: Option<(u32, u32)>, builder_debug: bool,
builder_vsync: bool, builder_hidden: bool,
- builder_sharelists: Option<winapi::HGLRC>, builder_multisampling: Option<u16>)
+ builder_sharelists: Option<ContextHack>, builder_multisampling: Option<u16>)
-> Result<Window, CreationError>
{
use std::mem;
@@ -38,6 +44,8 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
// so we create a new thread dedicated to this window.
// This is the only safe method. Using `nosend` wouldn't work for non-native runtime.
::std::thread::Thread::spawn(move || {
+ let builder_sharelists = builder_sharelists.map(|s| s.0);
+
// registering the window class
let class_name = {
let class_name: Vec<u16> = "Window Class".utf16_units().chain(Some(0).into_iter())
@@ -132,7 +140,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if handle.is_null() {
use std::os;
tx.send(Err(OsError(format!("CreateWindowEx function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
return;
}
@@ -144,7 +152,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let hdc = unsafe { winapi::GetDC(dummy_window) };
if hdc.is_null() {
tx.send(Err(OsError(format!("GetDC function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(dummy_window); }
return;
}
@@ -172,7 +180,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if pf_index == 0 {
tx.send(Err(OsError(format!("ChoosePixelFormat function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(dummy_window); }
return;
}
@@ -181,7 +189,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
mem::size_of::<winapi::PIXELFORMATDESCRIPTOR>() as winapi::UINT, &mut output) } == 0
{
tx.send(Err(OsError(format!("DescribePixelFormat function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(dummy_window); }
return;
}
@@ -193,7 +201,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
unsafe {
if winapi::SetPixelFormat(dummy_hdc, 1, &pixel_format) == 0 {
tx.send(Err(OsError(format!("SetPixelFormat function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
winapi::DestroyWindow(dummy_window);
return;
}
@@ -204,7 +212,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let ctxt = unsafe { gl::wgl::CreateContext(dummy_hdc as *const libc::c_void) };
if ctxt.is_null() {
tx.send(Err(OsError(format!("wglCreateContext function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(dummy_window); }
return;
}
@@ -216,11 +224,13 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
// loading the extra WGL functions
let extra_functions = gl::wgl_extra::Wgl::load_with(|addr| {
+ use libc;
+
+ let addr = CString::from_slice(addr.as_bytes());
+ let addr = addr.as_slice_with_nul().as_ptr();
+
unsafe {
- addr.with_c_str(|s| {
- use libc;
- gl::wgl::GetProcAddress(s) as *const libc::c_void
- })
+ gl::wgl::GetProcAddress(addr) as *const libc::c_void
}
});
@@ -261,7 +271,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if handle.is_null() {
use std::os;
tx.send(Err(OsError(format!("CreateWindowEx function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
return;
}
@@ -273,7 +283,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let hdc = unsafe { winapi::GetDC(real_window) };
if hdc.is_null() {
tx.send(Err(OsError(format!("GetDC function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(real_window); }
return;
}
@@ -284,7 +294,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
unsafe {
if winapi::SetPixelFormat(hdc, 1, &pixel_format) == 0 {
tx.send(Err(OsError(format!("SetPixelFormat function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
winapi::DestroyWindow(real_window);
return;
}
@@ -329,7 +339,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
if ctxt.is_null() {
tx.send(Err(OsError(format!("OpenGL context creation failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { winapi::DestroyWindow(real_window); }
return;
}
@@ -359,7 +369,7 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
let lib = unsafe { winapi::LoadLibraryW(name) };
if lib.is_null() {
tx.send(Err(OsError(format!("LoadLibrary function failed: {}",
- os::error_string(os::errno() as uint)))));
+ os::error_string(os::errno() as usize)))));
unsafe { gl::wgl::DeleteContext(context); }
unsafe { winapi::DestroyWindow(real_window); }
return;
@@ -409,9 +419,9 @@ pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: Strin
unsafe { winapi::TranslateMessage(&msg) };
unsafe { winapi::DispatchMessageW(&msg) }; // calls `callback` (see below)
}
- }).detach();
+ });
- rx.recv()
+ rx.recv().unwrap()
}
/// Checks that the window is the good one, and if so send the event to it.
@@ -429,7 +439,7 @@ fn send_event(input_window: winapi::HWND, event: Event) {
return;
}
- sender.send_opt(event).ok(); // ignoring if closed
+ sender.send(event).ok(); // ignoring if closed
});
}
@@ -465,16 +475,16 @@ extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
winapi::WM_SIZE => {
use events::Event::Resized;
- let w = winapi::LOWORD(lparam as winapi::DWORD) as uint;
- let h = winapi::HIWORD(lparam as winapi::DWORD) as uint;
+ let w = winapi::LOWORD(lparam as winapi::DWORD) as u32;
+ let h = winapi::HIWORD(lparam as winapi::DWORD) as u32;
send_event(window, Resized(w, h));
0
},
winapi::WM_MOVE => {
use events::Event::Moved;
- let x = winapi::LOWORD(lparam as winapi::DWORD) as i16 as int;
- let y = winapi::HIWORD(lparam as winapi::DWORD) as i16 as int;
+ let x = winapi::LOWORD(lparam as winapi::DWORD) as i32;
+ let y = winapi::HIWORD(lparam as winapi::DWORD) as i32;
send_event(window, Moved(x, y));
0
},
@@ -490,8 +500,8 @@ extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT,
winapi::WM_MOUSEMOVE => {
use events::Event::MouseMoved;
- let x = winapi::GET_X_LPARAM(lparam) as int;
- let y = winapi::GET_Y_LPARAM(lparam) as int;
+ let x = winapi::GET_X_LPARAM(lparam) as i32;
+ let y = winapi::GET_Y_LPARAM(lparam) as i32;
send_event(window, MouseMoved((x, y)));
diff --git a/src/win32/mod.rs b/src/win32/mod.rs
index dba08e5..e6964b4 100644
--- a/src/win32/mod.rs
+++ b/src/win32/mod.rs
@@ -1,13 +1,12 @@
use std::sync::atomic::AtomicBool;
use std::ptr;
+use std::ffi::CString;
+use std::collections::RingBuf;
+use std::sync::mpsc::Receiver;
use libc;
-use {CreationError, Event};
+use {CreationError, Event, MouseCursor};
-#[cfg(feature = "window")]
-use WindowBuilder;
-
-#[cfg(feature = "headless")]
-use HeadlessRendererBuilder;
+use BuilderAttribs;
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@@ -18,16 +17,14 @@ mod gl;
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))
}
@@ -47,10 +44,15 @@ impl HeadlessContext {
::Api::OpenGl
}
- pub fn set_window_resize_callback(&mut self, _: Option<fn(uint, uint)>) {
+ pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
}
}
+#[cfg(feature = "headless")]
+unsafe impl Send for HeadlessContext {}
+#[cfg(feature = "headless")]
+unsafe impl Sync for HeadlessContext {}
+
/// The Win32 implementation of the main `Window` object.
pub struct Window {
/// Main handle for the window.
@@ -75,18 +77,21 @@ pub struct Window {
is_closed: AtomicBool,
}
-#[cfg(feature = "window")]
+unsafe impl Send for Window {}
+unsafe impl Sync for 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| w.window.context), multisampling)
+ !visible, sharing.map(|w| init::ContextHack(w.context)),
+ multisampling)
}
}
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct WindowProxy;
impl WindowProxy {
@@ -98,12 +103,12 @@ impl WindowProxy {
impl Window {
/// See the docs in the crate root file.
pub fn is_closed(&self) -> bool {
- use std::sync::atomic::Relaxed;
+ use std::sync::atomic::Ordering::Relaxed;
self.is_closed.load(Relaxed)
}
/// See the docs in the crate root file.
- ///
+ ///
/// Calls SetWindowText on the HWND.
pub fn set_title(&self, text: &str) {
unsafe {
@@ -126,7 +131,7 @@ impl Window {
}
/// See the docs in the crate root file.
- pub fn get_position(&self) -> Option<(int, int)> {
+ pub fn get_position(&self) -> Option<(i32, i32)> {
use std::mem;
let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() };
@@ -137,11 +142,11 @@ impl Window {
}
let ref rect = placement.rcNormalPosition;
- Some((rect.left as int, rect.top as int))
+ Some((rect.left as i32, rect.top as i32))
}
/// See the docs in the crate root file.
- pub fn set_position(&self, x: int, y: int) {
+ pub fn set_position(&self, x: i32, y: i32) {
use libc;
unsafe {
@@ -152,7 +157,7 @@ impl Window {
}
/// See the docs in the crate root file.
- pub fn get_inner_size(&self) -> Option<(uint, uint)> {
+ pub fn get_inner_size(&self) -> Option<(u32, u32)> {
use std::mem;
let mut rect: winapi::RECT = unsafe { mem::uninitialized() };
@@ -161,13 +166,13 @@ impl Window {
}
Some((
- (rect.right - rect.left) as uint,
- (rect.bottom - rect.top) as uint
+ (rect.right - rect.left) as u32,
+ (rect.bottom - rect.top) as u32
))
}
/// See the docs in the crate root file.
- pub fn get_outer_size(&self) -> Option<(uint, uint)> {
+ pub fn get_outer_size(&self) -> Option<(u32, u32)> {
use std::mem;
let mut rect: winapi::RECT = unsafe { mem::uninitialized() };
@@ -176,13 +181,13 @@ impl Window {
}
Some((
- (rect.right - rect.left) as uint,
- (rect.bottom - rect.top) as uint
+ (rect.right - rect.left) as u32,
+ (rect.bottom - rect.top) as u32
))
}
/// See the docs in the crate root file.
- pub fn set_inner_size(&self, x: uint, y: uint) {
+ pub fn set_inner_size(&self, x: u32, y: u32) {
use libc;
unsafe {
@@ -198,33 +203,33 @@ impl Window {
/// See the docs in the crate root file.
// TODO: return iterator
- pub fn poll_events(&self) -> Vec<Event> {
- let mut events = Vec::new();
+ pub fn poll_events(&self) -> RingBuf<Event> {
+ let mut events = RingBuf::new();
loop {
match self.events_receiver.try_recv() {
- Ok(ev) => events.push(ev),
+ Ok(ev) => events.push_back(ev),
Err(_) => break
}
}
// if one of the received events is `Closed`, setting `is_closed` to true
if events.iter().any(|e| match e { &::events::Event::Closed => true, _ => false }) {
- use std::sync::atomic::Relaxed;
+ use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
}
-
+
events
}
/// See the docs in the crate root file.
// TODO: return iterator
- pub fn wait_events(&self) -> Vec<Event> {
- match self.events_receiver.recv_opt() {
+ pub fn wait_events(&self) -> RingBuf<Event> {
+ match self.events_receiver.recv() {
Ok(ev) => {
// if the received event is `Closed`, setting `is_closed` to true
match ev {
::events::Event::Closed => {
- use std::sync::atomic::Relaxed;
+ use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
},
_ => ()
@@ -237,9 +242,9 @@ impl Window {
},
Err(_) => {
- use std::sync::atomic::Relaxed;
+ use std::sync::atomic::Ordering::Relaxed;
self.is_closed.store(true, Relaxed);
- vec![]
+ RingBuf::new()
}
}
}
@@ -252,14 +257,13 @@ impl Window {
/// See the docs in the crate root file.
pub fn get_proc_address(&self, addr: &str) -> *const () {
- use std::c_str::ToCStr;
+ let addr = CString::from_slice(addr.as_bytes());
+ let addr = addr.as_slice_with_nul().as_ptr();
unsafe {
- addr.with_c_str(|s| {
- let p = gl::wgl::GetProcAddress(s) as *const ();
- if !p.is_null() { return p; }
- winapi::GetProcAddress(self.gl_library, s) as *const ()
- })
+ let p = gl::wgl::GetProcAddress(addr) as *const ();
+ if !p.is_null() { return p; }
+ winapi::GetProcAddress(self.gl_library, addr) as *const ()
}
}
@@ -279,7 +283,11 @@ impl Window {
::Api::OpenGl
}
- pub fn set_window_resize_callback(&mut self, _: Option<fn(uint, uint)>) {
+ pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
+ }
+
+ pub fn set_cursor(&self, cursor: MouseCursor) {
+ unimplemented!()
}
}
diff --git a/src/win32/monitor.rs b/src/win32/monitor.rs
index f841f1e..2078a52 100644
--- a/src/win32/monitor.rs
+++ b/src/win32/monitor.rs
@@ -1,9 +1,11 @@
use winapi;
+use std::collections::RingBuf;
+
/// Win32 implementation of the main `MonitorID` object.
pub struct MonitorID {
/// The system name of the monitor.
- name: [winapi::WCHAR, ..32],
+ name: [winapi::WCHAR; 32],
/// Name to give to the user.
readable_name: String,
@@ -15,22 +17,22 @@ pub struct MonitorID {
/// The position of the monitor in pixels on the desktop.
///
/// A window that is positionned at these coordinates will overlap the monitor.
- position: (uint, uint),
+ position: (u32, u32),
/// The current resolution in pixels on the monitor.
- dimensions: (uint, uint),
+ dimensions: (u32, u32),
}
/// Win32 implementation of the main `get_available_monitors` function.
-pub fn get_available_monitors() -> Vec<MonitorID> {
+pub fn get_available_monitors() -> RingBuf<MonitorID> {
use std::{iter, mem, ptr};
// return value
- let mut result = Vec::new();
+ let mut result = RingBuf::new();
// enumerating the devices is done by querying device 0, then device 1, then device 2, etc.
// until the query function returns null
- for id in iter::count(0u, 1) {
+ for id in iter::count(0u32, 1) {
// getting the DISPLAY_DEVICEW object of the current device
let output = {
let mut output: winapi::DISPLAY_DEVICEW = unsafe { mem::zeroed() };
@@ -56,7 +58,7 @@ pub fn get_available_monitors() -> Vec<MonitorID> {
// computing the human-friendly name
let readable_name = String::from_utf16_lossy(output.DeviceString.as_slice());
- let readable_name = readable_name.as_slice().trim_right_chars(0 as char).to_string();
+ let readable_name = readable_name.as_slice().trim_right_matches(0 as char).to_string();
// getting the position
let (position, dimensions) = unsafe {
@@ -70,15 +72,15 @@ pub fn get_available_monitors() -> Vec<MonitorID> {
}
let point: &winapi::POINTL = mem::transmute(&dev.union1);
- let position = (point.x as uint, point.y as uint);
+ let position = (point.x as u32, point.y as u32);
- let dimensions = (dev.dmPelsWidth as uint, dev.dmPelsHeight as uint);
+ let dimensions = (dev.dmPelsWidth as u32, dev.dmPelsHeight as u32);
(position, dimensions)
};
// adding to the resulting list
- result.push(MonitorID {
+ result.push_back(MonitorID {
name: output.DeviceName,
readable_name: readable_name,
flags: output.StateFlags,
@@ -111,7 +113,7 @@ impl MonitorID {
}
/// See the docs if the crate root file.
- pub fn get_dimensions(&self) -> (uint, uint) {
+ pub fn get_dimensions(&self) -> (u32, u32) {
// TODO: retreive the dimensions every time this is called
self.dimensions
}
@@ -123,9 +125,9 @@ impl MonitorID {
}
/// This is a Win32-only function for `MonitorID` that returns the position of the
- /// monitor on the desktop.
+ /// monitor on the desktop.
/// A window that is positionned at these coordinates will overlap the monitor.
- pub fn get_position(&self) -> (uint, uint) {
+ pub fn get_position(&self) -> (u32, u32) {
self.position
}
}