mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 14:51:30 +11:00
Switch X11 and wayland to the new design
This commit is contained in:
parent
b5d0a3eb67
commit
5182023fd6
|
@ -13,14 +13,16 @@ use api::dlopen;
|
||||||
use api::egl;
|
use api::egl;
|
||||||
use api::egl::Context as EglContext;
|
use api::egl::Context as EglContext;
|
||||||
|
|
||||||
use BuilderAttribs;
|
|
||||||
use ContextError;
|
use ContextError;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use Event;
|
use Event;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use MouseCursor;
|
use MouseCursor;
|
||||||
|
use GlAttributes;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
|
use PixelFormatRequirements;
|
||||||
|
use WindowAttributes;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
@ -241,7 +243,9 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
|
pub fn new(window: &WindowAttributes, pf_reqs: &PixelFormatRequirements,
|
||||||
|
opengl: &GlAttributes<&Window>) -> Result<Window, CreationError>
|
||||||
|
{
|
||||||
use self::wayland::internals::FFI;
|
use self::wayland::internals::FFI;
|
||||||
|
|
||||||
let wayland_context = match *WAYLAND_CONTEXT {
|
let wayland_context = match *WAYLAND_CONTEXT {
|
||||||
|
@ -251,7 +255,7 @@ impl Window {
|
||||||
|
|
||||||
if !is_egl_available() { return Err(CreationError::NotSupported) }
|
if !is_egl_available() { return Err(CreationError::NotSupported) }
|
||||||
|
|
||||||
let (w, h) = builder.window.dimensions.unwrap_or((800, 600));
|
let (w, h) = window.dimensions.unwrap_or((800, 600));
|
||||||
|
|
||||||
let surface = EGLSurface::new(
|
let surface = EGLSurface::new(
|
||||||
wayland_context.compositor.create_surface(),
|
wayland_context.compositor.create_surface(),
|
||||||
|
@ -259,12 +263,12 @@ impl Window {
|
||||||
h as i32
|
h as i32
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut shell_window = if let Some(PlatformMonitorID::Wayland(ref monitor)) = builder.window.monitor {
|
let mut shell_window = if let Some(PlatformMonitorID::Wayland(ref monitor)) = window.monitor {
|
||||||
let shell_surface = wayland_context.shell.get_shell_surface(surface);
|
let shell_surface = wayland_context.shell.get_shell_surface(surface);
|
||||||
shell_surface.set_fullscreen(ShellFullscreenMethod::Default, Some(&monitor.output));
|
shell_surface.set_fullscreen(ShellFullscreenMethod::Default, Some(&monitor.output));
|
||||||
ShellWindow::Plain(shell_surface)
|
ShellWindow::Plain(shell_surface)
|
||||||
} else {
|
} else {
|
||||||
if builder.window.decorations {
|
if window.decorations {
|
||||||
ShellWindow::Decorated(match DecoratedSurface::new(
|
ShellWindow::Decorated(match DecoratedSurface::new(
|
||||||
surface,
|
surface,
|
||||||
w as i32,
|
w as i32,
|
||||||
|
@ -291,7 +295,7 @@ impl Window {
|
||||||
});
|
});
|
||||||
try!(EglContext::new(
|
try!(EglContext::new(
|
||||||
egl,
|
egl,
|
||||||
&builder.pf_reqs, &builder.opengl.clone().map_sharing(|_| unimplemented!()), // TODO:
|
pf_reqs, &opengl.clone().map_sharing(|_| unimplemented!()), // TODO:
|
||||||
egl::NativeDisplay::Wayland(Some(wayland_context.display.ptr() as *const _)))
|
egl::NativeDisplay::Wayland(Some(wayland_context.display.ptr() as *const _)))
|
||||||
.and_then(|p| p.finish((**shell_window.get_shell()).ptr() as *const _))
|
.and_then(|p| p.finish((**shell_window.get_shell()).ptr() as *const _))
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use {Event, BuilderAttribs, MouseCursor};
|
use {Event, MouseCursor};
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use CreationError::OsError;
|
use CreationError::OsError;
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -12,9 +12,12 @@ use std::sync::{Arc, Mutex};
|
||||||
use Api;
|
use Api;
|
||||||
use ContextError;
|
use ContextError;
|
||||||
use CursorState;
|
use CursorState;
|
||||||
|
use GlAttributes;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use PixelFormatRequirements;
|
||||||
|
use WindowAttributes;
|
||||||
|
|
||||||
use api::glx::Context as GlxContext;
|
use api::glx::Context as GlxContext;
|
||||||
use api::egl;
|
use api::egl;
|
||||||
|
@ -295,10 +298,13 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(display: &Arc<XConnection>, builder: BuilderAttribs) -> Result<Window, CreationError> {
|
pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes,
|
||||||
let dimensions = builder.window.dimensions.unwrap_or((800, 600));
|
pf_reqs: &PixelFormatRequirements, opengl: &GlAttributes<&Window>)
|
||||||
|
-> Result<Window, CreationError>
|
||||||
|
{
|
||||||
|
let dimensions = window_attrs.dimensions.unwrap_or((800, 600));
|
||||||
|
|
||||||
let screen_id = match builder.window.monitor {
|
let screen_id = match window_attrs.monitor {
|
||||||
Some(PlatformMonitorID::X(MonitorID(_, monitor))) => monitor as i32,
|
Some(PlatformMonitorID::X(MonitorID(_, monitor))) => monitor as i32,
|
||||||
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) },
|
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) },
|
||||||
};
|
};
|
||||||
|
@ -316,7 +322,7 @@ impl Window {
|
||||||
// FIXME: `XF86VidModeModeInfo` is missing its `hskew` field. Therefore we point to
|
// FIXME: `XF86VidModeModeInfo` is missing its `hskew` field. Therefore we point to
|
||||||
// `vsyncstart` instead of `vdisplay` as a temporary hack.
|
// `vsyncstart` instead of `vdisplay` as a temporary hack.
|
||||||
|
|
||||||
let mode_to_switch_to = if builder.window.monitor.is_some() {
|
let mode_to_switch_to = if window_attrs.monitor.is_some() {
|
||||||
let matching_mode = (0 .. mode_num).map(|i| {
|
let matching_mode = (0 .. mode_num).map(|i| {
|
||||||
let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m
|
let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m
|
||||||
}).find(|m| m.hdisplay == dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16);
|
}).find(|m| m.hdisplay == dimensions.0 as u16 && m.vsyncstart == dimensions.1 as u16);
|
||||||
|
@ -348,24 +354,23 @@ impl Window {
|
||||||
Glx(::api::glx::ContextPrototype<'a>),
|
Glx(::api::glx::ContextPrototype<'a>),
|
||||||
Egl(::api::egl::ContextPrototype<'a>),
|
Egl(::api::egl::ContextPrototype<'a>),
|
||||||
}
|
}
|
||||||
let builder_clone = builder.clone();
|
let builder_clone_opengl_glx = opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
|
||||||
let builder_clone_opengl_glx = builder_clone.opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
|
let builder_clone_opengl_egl = opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
|
||||||
let builder_clone_opengl_egl = builder_clone.opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
|
let context = match opengl.version {
|
||||||
let context = match builder.opengl.version {
|
|
||||||
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
|
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
|
||||||
// GLX should be preferred over EGL, otherwise crashes may occur
|
// GLX should be preferred over EGL, otherwise crashes may occur
|
||||||
// on X11 – issue #314
|
// on X11 – issue #314
|
||||||
if let Some(ref glx) = display.glx {
|
if let Some(ref glx) = display.glx {
|
||||||
Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, &builder_clone.pf_reqs, &builder_clone_opengl_glx, display.display)))
|
Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, pf_reqs, &builder_clone_opengl_glx, display.display)))
|
||||||
} else if let Some(ref egl) = display.egl {
|
} else if let Some(ref egl) = display.egl {
|
||||||
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
|
Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
|
||||||
} else {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GlRequest::Specific(Api::OpenGlEs, _) => {
|
GlRequest::Specific(Api::OpenGlEs, _) => {
|
||||||
if let Some(ref egl) = display.egl {
|
if let Some(ref egl) = display.egl {
|
||||||
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
|
Prototype::Egl(try!(EglContext::new(egl.clone(), pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
|
||||||
} else {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
|
@ -417,7 +422,7 @@ impl Window {
|
||||||
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
||||||
ffi::ButtonReleaseMask | ffi::KeymapStateMask;
|
ffi::ButtonReleaseMask | ffi::KeymapStateMask;
|
||||||
swa.border_pixel = 0;
|
swa.border_pixel = 0;
|
||||||
if builder.window.transparent {
|
if window_attrs.transparent {
|
||||||
swa.background_pixel = 0;
|
swa.background_pixel = 0;
|
||||||
}
|
}
|
||||||
swa.override_redirect = 0;
|
swa.override_redirect = 0;
|
||||||
|
@ -426,7 +431,7 @@ impl Window {
|
||||||
|
|
||||||
let mut window_attributes = ffi::CWBorderPixel | ffi::CWColormap | ffi::CWEventMask;
|
let mut window_attributes = ffi::CWBorderPixel | ffi::CWColormap | ffi::CWEventMask;
|
||||||
|
|
||||||
if builder.window.transparent {
|
if window_attrs.transparent {
|
||||||
window_attributes |= ffi::CWBackPixel;
|
window_attributes |= ffi::CWBackPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +455,7 @@ impl Window {
|
||||||
};
|
};
|
||||||
|
|
||||||
// set visibility
|
// set visibility
|
||||||
if builder.window.visible {
|
if window_attrs.visible {
|
||||||
unsafe {
|
unsafe {
|
||||||
(display.xlib.XMapRaised)(display.display, window);
|
(display.xlib.XMapRaised)(display.display, window);
|
||||||
(display.xlib.XFlush)(display.display);
|
(display.xlib.XFlush)(display.display);
|
||||||
|
@ -463,7 +468,7 @@ impl Window {
|
||||||
(display.xlib.XInternAtom)(display.display, delete_window, 0)
|
(display.xlib.XInternAtom)(display.display, delete_window, 0)
|
||||||
);
|
);
|
||||||
(display.xlib.XSetWMProtocols)(display.display, window, &mut wm_delete_window, 1);
|
(display.xlib.XSetWMProtocols)(display.display, window, &mut wm_delete_window, 1);
|
||||||
with_c_str(&*builder.window.title, |title| {;
|
with_c_str(&*window_attrs.title, |title| {;
|
||||||
(display.xlib.XStoreName)(display.display, window, title);
|
(display.xlib.XStoreName)(display.display, window, title);
|
||||||
});
|
});
|
||||||
(display.xlib.XFlush)(display.display);
|
(display.xlib.XFlush)(display.display);
|
||||||
|
@ -511,7 +516,7 @@ impl Window {
|
||||||
|
|
||||||
// Set ICCCM WM_CLASS property based on initial window title
|
// Set ICCCM WM_CLASS property based on initial window title
|
||||||
unsafe {
|
unsafe {
|
||||||
with_c_str(&*builder.window.title, |c_name| {
|
with_c_str(&*window_attrs.title, |c_name| {
|
||||||
let hint = (display.xlib.XAllocClassHint)();
|
let hint = (display.xlib.XAllocClassHint)();
|
||||||
(*hint).res_name = c_name as *mut libc::c_char;
|
(*hint).res_name = c_name as *mut libc::c_char;
|
||||||
(*hint).res_class = c_name as *mut libc::c_char;
|
(*hint).res_class = c_name as *mut libc::c_char;
|
||||||
|
@ -520,7 +525,7 @@ impl Window {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_fullscreen = builder.window.monitor.is_some();
|
let is_fullscreen = window_attrs.monitor.is_some();
|
||||||
|
|
||||||
// finish creating the OpenGL context
|
// finish creating the OpenGL context
|
||||||
let context = match context {
|
let context = match context {
|
||||||
|
|
|
@ -162,9 +162,29 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
|
pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> {
|
||||||
|
let window = builder.window;
|
||||||
|
let pf_reqs = builder.pf_reqs;
|
||||||
|
let opengl = builder.opengl;
|
||||||
|
|
||||||
match *BACKEND {
|
match *BACKEND {
|
||||||
Backend::Wayland => wayland::Window::new(builder).map(Window::Wayland),
|
Backend::Wayland => {
|
||||||
Backend::X(ref connec) => x11::Window::new(connec, builder).map(Window::X),
|
let opengl = opengl.map_sharing(|w| match w {
|
||||||
|
&Window::Wayland(ref w) => w,
|
||||||
|
_ => panic!() // TODO: return an error
|
||||||
|
});
|
||||||
|
|
||||||
|
wayland::Window::new(&window, &pf_reqs, &opengl).map(Window::Wayland)
|
||||||
|
},
|
||||||
|
|
||||||
|
Backend::X(ref connec) => {
|
||||||
|
let opengl = opengl.map_sharing(|w| match w {
|
||||||
|
&Window::X(ref w) => w,
|
||||||
|
_ => panic!() // TODO: return an error
|
||||||
|
});
|
||||||
|
|
||||||
|
x11::Window::new(connec, &window, &pf_reqs, &opengl).map(Window::X)
|
||||||
|
},
|
||||||
|
|
||||||
Backend::Error(ref error) => Err(CreationError::NoBackendAvailable(Box::new(error.clone())))
|
Backend::Error(ref error) => Err(CreationError::NoBackendAvailable(Box::new(error.clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue