mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Implement win32 initialization in a cleaner way
This commit is contained in:
parent
9884908240
commit
e9a775c6b1
27
src/lib.rs
27
src/lib.rs
|
@ -217,6 +217,33 @@ impl BuilderAttribs<'static> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> BuilderAttribs<'a> {
|
||||||
|
fn extract_non_static(mut self) -> (BuilderAttribs<'static>, Option<&'a winimpl::Window>) {
|
||||||
|
let sharing = self.sharing.take();
|
||||||
|
|
||||||
|
let new_attribs = BuilderAttribs {
|
||||||
|
headless: self.headless,
|
||||||
|
strict: self.strict,
|
||||||
|
sharing: None,
|
||||||
|
dimensions: self.dimensions,
|
||||||
|
title: self.title,
|
||||||
|
monitor: self.monitor,
|
||||||
|
gl_version: self.gl_version,
|
||||||
|
gl_debug: self.gl_debug,
|
||||||
|
vsync: self.vsync,
|
||||||
|
visible: self.visible,
|
||||||
|
multisampling: self.multisampling,
|
||||||
|
depth_bits: self.depth_bits,
|
||||||
|
stencil_bits: self.stencil_bits,
|
||||||
|
color_bits: self.color_bits,
|
||||||
|
alpha_bits: self.alpha_bits,
|
||||||
|
stereoscopy: self.stereoscopy,
|
||||||
|
};
|
||||||
|
|
||||||
|
(new_attribs, sharing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "window")]
|
#[cfg(feature = "window")]
|
||||||
impl<'a> WindowBuilder<'a> {
|
impl<'a> WindowBuilder<'a> {
|
||||||
/// Initializes a new `WindowBuilder` with default values.
|
/// Initializes a new `WindowBuilder` with default values.
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::sync::atomic::AtomicBool;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use super::event;
|
use super::event;
|
||||||
use super::Window;
|
use super::Window;
|
||||||
|
use BuilderAttribs;
|
||||||
use {CreationError, Event};
|
use {CreationError, Event};
|
||||||
use CreationError::OsError;
|
use CreationError::OsError;
|
||||||
|
|
||||||
|
@ -27,18 +28,14 @@ thread_local!(static WINDOW: Rc<RefCell<Option<(winapi::HWND, Sender<Event>)>>>
|
||||||
pub struct ContextHack(pub winapi::HGLRC);
|
pub struct ContextHack(pub winapi::HGLRC);
|
||||||
unsafe impl Send for ContextHack {}
|
unsafe impl Send for ContextHack {}
|
||||||
|
|
||||||
pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
pub fn new_window(builder: BuilderAttribs<'static>, builder_sharelists: Option<ContextHack>)
|
||||||
builder_monitor: Option<super::MonitorID>,
|
|
||||||
builder_gl_version: Option<(u32, u32)>, builder_debug: bool,
|
|
||||||
builder_vsync: bool, builder_hidden: bool,
|
|
||||||
builder_sharelists: Option<ContextHack>, builder_multisampling: Option<u16>)
|
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
// initializing variables to be sent to the task
|
// initializing variables to be sent to the task
|
||||||
let title = builder_title.as_slice().utf16_units()
|
let title = builder.title.as_slice().utf16_units()
|
||||||
.chain(Some(0).into_iter()).collect::<Vec<u16>>(); // title to utf16
|
.chain(Some(0).into_iter()).collect::<Vec<u16>>(); // title to utf16
|
||||||
//let hints = hints.clone();
|
//let hints = hints.clone();
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
@ -80,15 +77,15 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
|
|
||||||
// building a RECT object with coordinates
|
// building a RECT object with coordinates
|
||||||
let mut rect = winapi::RECT {
|
let mut rect = winapi::RECT {
|
||||||
left: 0, right: builder_dimensions.unwrap_or((1024, 768)).0 as winapi::LONG,
|
left: 0, right: builder.dimensions.unwrap_or((1024, 768)).0 as winapi::LONG,
|
||||||
top: 0, bottom: builder_dimensions.unwrap_or((1024, 768)).1 as winapi::LONG,
|
top: 0, bottom: builder.dimensions.unwrap_or((1024, 768)).1 as winapi::LONG,
|
||||||
};
|
};
|
||||||
|
|
||||||
// switching to fullscreen if necessary
|
// switching to fullscreen if necessary
|
||||||
// this means adjusting the window's position so that it overlaps the right monitor,
|
// this means adjusting the window's position so that it overlaps the right monitor,
|
||||||
// and change the monitor's resolution if necessary
|
// and change the monitor's resolution if necessary
|
||||||
if builder_monitor.is_some() {
|
if builder.monitor.is_some() {
|
||||||
let monitor = builder_monitor.as_ref().unwrap();
|
let monitor = builder.monitor.as_ref().unwrap();
|
||||||
|
|
||||||
// adjusting the rect
|
// adjusting the rect
|
||||||
{
|
{
|
||||||
|
@ -117,7 +114,7 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
// computing the style and extended style of the window
|
// 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() {
|
||||||
(winapi::WS_EX_APPWINDOW, winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN)
|
(winapi::WS_EX_APPWINDOW, winapi::WS_POPUP | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN)
|
||||||
} else {
|
} else {
|
||||||
(winapi::WS_EX_APPWINDOW | winapi::WS_EX_WINDOWEDGE,
|
(winapi::WS_EX_APPWINDOW | winapi::WS_EX_WINDOWEDGE,
|
||||||
|
@ -250,13 +247,13 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
|
|
||||||
// creating the real window this time
|
// creating the real window this time
|
||||||
let real_window = unsafe {
|
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))
|
(Some(rect.right - rect.left), Some(rect.bottom - rect.top))
|
||||||
} else {
|
} else {
|
||||||
(None, None)
|
(None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let style = if builder_hidden {
|
let style = if !builder.visible || builder.headless {
|
||||||
style
|
style
|
||||||
} else {
|
} else {
|
||||||
style | winapi::WS_VISIBLE
|
style | winapi::WS_VISIBLE
|
||||||
|
@ -265,8 +262,8 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(),
|
let handle = user32::CreateWindowExW(ex_style, class_name.as_ptr(),
|
||||||
title.as_ptr() as winapi::LPCWSTR,
|
title.as_ptr() as winapi::LPCWSTR,
|
||||||
style | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN,
|
style | winapi::WS_CLIPSIBLINGS | winapi::WS_CLIPCHILDREN,
|
||||||
if builder_monitor.is_some() { 0 } else { winapi::CW_USEDEFAULT },
|
if builder.monitor.is_some() { 0 } else { winapi::CW_USEDEFAULT },
|
||||||
if builder_monitor.is_some() { 0 } else { winapi::CW_USEDEFAULT },
|
if builder.monitor.is_some() { 0 } else { winapi::CW_USEDEFAULT },
|
||||||
width.unwrap_or(winapi::CW_USEDEFAULT), height.unwrap_or(winapi::CW_USEDEFAULT),
|
width.unwrap_or(winapi::CW_USEDEFAULT), height.unwrap_or(winapi::CW_USEDEFAULT),
|
||||||
ptr::null_mut(), ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()),
|
ptr::null_mut(), ptr::null_mut(), kernel32::GetModuleHandleW(ptr::null()),
|
||||||
ptr::null_mut());
|
ptr::null_mut());
|
||||||
|
@ -309,15 +306,15 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
|
|
||||||
let mut attributes = Vec::new();
|
let mut attributes = Vec::new();
|
||||||
|
|
||||||
if builder_gl_version.is_some() {
|
if builder.gl_version.is_some() {
|
||||||
let version = builder_gl_version.as_ref().unwrap();
|
let version = builder.gl_version.as_ref().unwrap();
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
|
attributes.push(gl::wgl_extra::CONTEXT_MAJOR_VERSION_ARB as libc::c_int);
|
||||||
attributes.push(version.0 as libc::c_int);
|
attributes.push(version.0 as libc::c_int);
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
|
attributes.push(gl::wgl_extra::CONTEXT_MINOR_VERSION_ARB as libc::c_int);
|
||||||
attributes.push(version.1 as libc::c_int);
|
attributes.push(version.1 as libc::c_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
if builder_debug {
|
if builder.gl_debug {
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
||||||
}
|
}
|
||||||
|
@ -351,7 +348,7 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
};
|
};
|
||||||
|
|
||||||
// calling SetForegroundWindow if fullscreen
|
// calling SetForegroundWindow if fullscreen
|
||||||
if builder_monitor.is_some() {
|
if builder.monitor.is_some() {
|
||||||
unsafe { user32::SetForegroundWindow(real_window) };
|
unsafe { user32::SetForegroundWindow(real_window) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +378,7 @@ pub fn new_window(builder_dimensions: Option<(u32, u32)>, builder_title: String,
|
||||||
};
|
};
|
||||||
|
|
||||||
// handling vsync
|
// handling vsync
|
||||||
if builder_vsync {
|
if builder.vsync {
|
||||||
if extra_functions.SwapIntervalEXT.is_loaded() {
|
if extra_functions.SwapIntervalEXT.is_loaded() {
|
||||||
unsafe { gl::wgl::MakeCurrent(hdc as *const libc::c_void, context) };
|
unsafe { gl::wgl::MakeCurrent(hdc as *const libc::c_void, context) };
|
||||||
if unsafe { extra_functions.SwapIntervalEXT(1) } == 0 {
|
if unsafe { extra_functions.SwapIntervalEXT(1) } == 0 {
|
||||||
|
|
|
@ -26,10 +26,8 @@ pub struct HeadlessContext(Window);
|
||||||
impl HeadlessContext {
|
impl HeadlessContext {
|
||||||
/// See the docs in the crate root file.
|
/// See the docs in the crate root file.
|
||||||
pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
|
pub fn new(builder: BuilderAttribs) -> Result<HeadlessContext, CreationError> {
|
||||||
let BuilderAttribs { dimensions, gl_version, gl_debug, .. } = builder;
|
let (builder, _) = builder.extract_non_static();
|
||||||
init::new_window(dimensions, "".to_string(), None, gl_version, gl_debug, false, true,
|
init::new_window(builder, None).map(|w| HeadlessContext(w))
|
||||||
None, None)
|
|
||||||
.map(|w| HeadlessContext(w))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See the docs in the crate root file.
|
/// See the docs in the crate root file.
|
||||||
|
@ -86,11 +84,9 @@ unsafe impl Sync for Window {}
|
||||||
impl Window {
|
impl Window {
|
||||||
/// See the docs in the crate root file.
|
/// See the docs in the crate root file.
|
||||||
pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
|
pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
|
||||||
let BuilderAttribs { dimensions, title, monitor, gl_version,
|
let (builder, sharing) = builder.extract_non_static();
|
||||||
gl_debug, vsync, visible, sharing, multisampling, .. } = builder;
|
let sharing = sharing.map(|w| init::ContextHack(w.context));
|
||||||
init::new_window(dimensions, title, monitor, gl_version, gl_debug, vsync,
|
init::new_window(builder, sharing)
|
||||||
!visible, sharing.map(|w| init::ContextHack(w.context)),
|
|
||||||
multisampling)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue