aboutsummaryrefslogtreecommitdiffstats
path: root/src/win32
diff options
context:
space:
mode:
authortomaka <pierre.krieger1708@gmail.com>2014-10-09 20:04:02 +0200
committertomaka <pierre.krieger1708@gmail.com>2014-10-09 20:04:02 +0200
commit093c188b114d879543b98f60b6e9a3489d9cf70f (patch)
tree4a788e43172cd968c2a2cd1bd7d3102ea6937c80 /src/win32
parentcfb0cb70013772492c1930ced62f48aa6cb372ff (diff)
parente565bfeb1372b885f8cced6a42596b731cb382b2 (diff)
downloadglutin-093c188b114d879543b98f60b6e9a3489d9cf70f.tar.gz
glutin-093c188b114d879543b98f60b6e9a3489d9cf70f.zip
Merge pull request #44 from tomaka/headless-rendering
Implement headless rendering
Diffstat (limited to 'src/win32')
-rw-r--r--src/win32/init.rs40
-rw-r--r--src/win32/mod.rs39
2 files changed, 62 insertions, 17 deletions
diff --git a/src/win32/init.rs b/src/win32/init.rs
index 7ad4dca..740bc02 100644
--- a/src/win32/init.rs
+++ b/src/win32/init.rs
@@ -6,7 +6,7 @@ use std::sync::atomics::AtomicBool;
use std::ptr;
use super::{event, ffi};
use super::Window;
-use {Event, WindowBuilder};
+use Event;
/// Stores the current window and its events dispatcher.
///
@@ -14,12 +14,16 @@ use {Event, WindowBuilder};
/// receive an event for another window.
local_data_key!(WINDOW: (ffi::HWND, Sender<Event>))
-pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
+pub fn new_window(builder_dimensions: Option<(uint, uint)>, builder_title: String,
+ builder_monitor: Option<super::MonitorID>,
+ builder_gl_version: Option<(uint, uint)>,
+ builder_headless: bool) -> Result<Window, String>
+{
use std::mem;
use std::os;
// initializing variables to be sent to the task
- let title = builder.title.as_slice().utf16_units()
+ let title = builder_title.as_slice().utf16_units()
.collect::<Vec<u16>>().append_one(0); // title to utf16
//let hints = hints.clone();
let (tx, rx) = channel();
@@ -59,15 +63,15 @@ pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
// building a RECT object with coordinates
let mut rect = ffi::RECT {
- left: 0, right: builder.dimensions.unwrap_or((1024, 768)).val0() as ffi::LONG,
- top: 0, bottom: builder.dimensions.unwrap_or((1024, 768)).val1() as ffi::LONG,
+ left: 0, right: builder_dimensions.unwrap_or((1024, 768)).val0() as ffi::LONG,
+ top: 0, bottom: builder_dimensions.unwrap_or((1024, 768)).val1() as ffi::LONG,
};
// switching to fullscreen if necessary
// this means adjusting the window's position so that it overlaps the right monitor,
// and change the monitor's resolution if necessary
- if builder.monitor.is_some() {
- let monitor = builder.monitor.as_ref().unwrap();
+ if builder_monitor.is_some() {
+ let monitor = builder_monitor.as_ref().unwrap();
// adjusting the rect
{
@@ -96,7 +100,7 @@ pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
}
// computing the style and extended style of the window
- let (ex_style, style) = if builder.monitor.is_some() {
+ let (ex_style, style) = if builder_monitor.is_some() {
(ffi::WS_EX_APPWINDOW, ffi::WS_POPUP | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN)
} else {
(ffi::WS_EX_APPWINDOW | ffi::WS_EX_WINDOWEDGE,
@@ -227,17 +231,23 @@ pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
// creating the real window this time
let real_window = unsafe {
- let (width, height) = if builder.monitor.is_some() || builder.dimensions.is_some() {
+ let (width, height) = if builder_monitor.is_some() || builder_dimensions.is_some() {
(Some(rect.right - rect.left), Some(rect.bottom - rect.top))
} else {
(None, None)
};
+ let style = if builder_headless {
+ style
+ } else {
+ style | ffi::WS_VISIBLE
+ };
+
let handle = ffi::CreateWindowExW(ex_style, class_name.as_ptr(),
title.as_ptr() as ffi::LPCWSTR,
- style | ffi::WS_VISIBLE | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN,
- if builder.monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT },
- if builder.monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT },
+ style | ffi::WS_CLIPSIBLINGS | ffi::WS_CLIPCHILDREN,
+ if builder_monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT },
+ if builder_monitor.is_some() { 0 } else { ffi::CW_USEDEFAULT },
width.unwrap_or(ffi::CW_USEDEFAULT), height.unwrap_or(ffi::CW_USEDEFAULT),
ptr::null(), ptr::null(), ffi::GetModuleHandleW(ptr::null()),
ptr::null_mut());
@@ -280,8 +290,8 @@ pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
let mut attributes = Vec::new();
- if builder.gl_version.is_some() {
- let version = builder.gl_version.as_ref().unwrap();
+ if builder_gl_version.is_some() {
+ let version = builder_gl_version.as_ref().unwrap();
attributes.push(ffi::wgl_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
attributes.push(version.val0() as libc::c_int);
attributes.push(ffi::wgl_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
@@ -310,7 +320,7 @@ pub fn new_window(builder: WindowBuilder) -> Result<Window, String> {
};
// calling SetForegroundWindow if fullscreen
- if builder.monitor.is_some() {
+ if builder_monitor.is_some() {
unsafe { ffi::SetForegroundWindow(real_window) };
}
diff --git a/src/win32/mod.rs b/src/win32/mod.rs
index faff374..af28011 100644
--- a/src/win32/mod.rs
+++ b/src/win32/mod.rs
@@ -1,6 +1,12 @@
use std::sync::atomics::AtomicBool;
use std::ptr;
-use {Event, WindowBuilder};
+use Event;
+
+#[cfg(feature = "window")]
+use WindowBuilder;
+
+#[cfg(feature = "headless")]
+use HeadlessRendererBuilder;
pub use self::monitor::{MonitorID, get_available_monitors, get_primary_monitor};
@@ -9,6 +15,30 @@ mod ffi;
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, String> {
+ let HeadlessRendererBuilder { dimensions, gl_version } = builder;
+ init::new_window(Some(dimensions), "".to_string(), None, gl_version, true)
+ .map(|w| HeadlessContext(w))
+ }
+
+ /// See the docs in the crate root file.
+ pub unsafe fn make_current(&self) {
+ self.0.make_current()
+ }
+
+ /// See the docs in the crate root file.
+ pub fn get_proc_address(&self, addr: &str) -> *const () {
+ self.0.get_proc_address(addr)
+ }
+}
+
/// The Win32 implementation of the main `Window` object.
pub struct Window {
/// Main handle for the window.
@@ -33,12 +63,16 @@ pub struct Window {
is_closed: AtomicBool,
}
+#[cfg(feature = "window")]
impl Window {
/// See the docs in the crate root file.
pub fn new(builder: WindowBuilder) -> Result<Window, String> {
- init::new_window(builder)
+ let WindowBuilder { dimensions, title, monitor, gl_version } = builder;
+ init::new_window(dimensions, title, monitor, gl_version, false)
}
+}
+impl Window {
/// See the docs in the crate root file.
pub fn is_closed(&self) -> bool {
use std::sync::atomics::Relaxed;
@@ -200,6 +234,7 @@ impl Window {
}
}
+#[cfg(feature = "window")]
#[unsafe_destructor]
impl Drop for Window {
fn drop(&mut self) {