mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Merge pull request #106 from rerion/master
Allow creation of X11 window with specified visual and screen
This commit is contained in:
commit
09e6698236
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "winit"
|
name = "winit"
|
||||||
version = "0.5.6"
|
version = "0.5.7"
|
||||||
authors = ["The winit contributors, Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
authors = ["The winit contributors, Pierre Krieger <pierre.krieger1708@gmail.com>"]
|
||||||
description = "Cross-platform window creation library."
|
description = "Cross-platform window creation library."
|
||||||
keywords = ["windowing"]
|
keywords = ["windowing"]
|
||||||
|
|
|
@ -14,6 +14,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use WindowAttributes;
|
use WindowAttributes;
|
||||||
|
use platform::PlatformSpecificWindowBuilderAttributes;
|
||||||
|
|
||||||
use platform::MonitorId as PlatformMonitorId;
|
use platform::MonitorId as PlatformMonitorId;
|
||||||
|
|
||||||
|
@ -282,7 +283,8 @@ pub struct Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes)
|
pub fn new(display: &Arc<XConnection>, window_attrs: &WindowAttributes,
|
||||||
|
pl_attribs: &PlatformSpecificWindowBuilderAttributes)
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
let dimensions = {
|
let dimensions = {
|
||||||
|
@ -303,9 +305,12 @@ impl Window {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let screen_id = match window_attrs.monitor {
|
let screen_id = match pl_attribs.screen_id {
|
||||||
|
Some(id) => id,
|
||||||
|
None => 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) },
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// finding the mode to switch to if necessary
|
// finding the mode to switch to if necessary
|
||||||
|
@ -347,7 +352,12 @@ impl Window {
|
||||||
// creating
|
// creating
|
||||||
let mut set_win_attr = {
|
let mut set_win_attr = {
|
||||||
let mut swa: ffi::XSetWindowAttributes = unsafe { mem::zeroed() };
|
let mut swa: ffi::XSetWindowAttributes = unsafe { mem::zeroed() };
|
||||||
swa.colormap = 0;
|
swa.colormap = if let Some(vi) = pl_attribs.visual_infos {
|
||||||
|
unsafe {
|
||||||
|
let visual = vi.visual;
|
||||||
|
(display.xlib.XCreateColormap)(display.display, root, visual, ffi::AllocNone)
|
||||||
|
}
|
||||||
|
} else { 0 };
|
||||||
swa.event_mask = ffi::ExposureMask | ffi::StructureNotifyMask |
|
swa.event_mask = ffi::ExposureMask | ffi::StructureNotifyMask |
|
||||||
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
ffi::VisibilityChangeMask | ffi::KeyPressMask | ffi::PointerMotionMask |
|
||||||
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
ffi::KeyReleaseMask | ffi::ButtonPressMask |
|
||||||
|
@ -369,8 +379,17 @@ impl Window {
|
||||||
// finally creating the window
|
// finally creating the window
|
||||||
let window = unsafe {
|
let window = unsafe {
|
||||||
let win = (display.xlib.XCreateWindow)(display.display, root, 0, 0, dimensions.0 as libc::c_uint,
|
let win = (display.xlib.XCreateWindow)(display.display, root, 0, 0, dimensions.0 as libc::c_uint,
|
||||||
dimensions.1 as libc::c_uint, 0, ffi::CopyFromParent, ffi::InputOutput as libc::c_uint,
|
dimensions.1 as libc::c_uint, 0,
|
||||||
ffi::CopyFromParent as *mut _, window_attributes,
|
match pl_attribs.visual_infos {
|
||||||
|
Some(vi) => vi.depth,
|
||||||
|
None => ffi::CopyFromParent
|
||||||
|
},
|
||||||
|
ffi::InputOutput as libc::c_uint,
|
||||||
|
match pl_attribs.visual_infos {
|
||||||
|
Some(vi) => vi.visual,
|
||||||
|
None => ffi::CopyFromParent as *mut _
|
||||||
|
},
|
||||||
|
window_attributes,
|
||||||
&mut set_win_attr);
|
&mut set_win_attr);
|
||||||
display.check_errors().expect("Failed to call XCreateWindow");
|
display.check_errors().expect("Failed to call XCreateWindow");
|
||||||
win
|
win
|
||||||
|
|
|
@ -1,17 +1,28 @@
|
||||||
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
|
#![cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd"))]
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::ptr;
|
||||||
use libc;
|
use libc;
|
||||||
use Window;
|
use Window;
|
||||||
use platform::Window as LinuxWindow;
|
use platform::Window as LinuxWindow;
|
||||||
|
use platform::{UnixBackend, UNIX_BACKEND};
|
||||||
use WindowBuilder;
|
use WindowBuilder;
|
||||||
use api::x11::XConnection;
|
use api::x11::XConnection;
|
||||||
|
use api::x11::ffi::XVisualInfo;
|
||||||
|
|
||||||
use wayland_client::protocol::wl_display::WlDisplay;
|
use wayland_client::protocol::wl_display::WlDisplay;
|
||||||
use wayland_client::protocol::wl_surface::WlSurface;
|
use wayland_client::protocol::wl_surface::WlSurface;
|
||||||
|
|
||||||
pub use api::x11;
|
pub use api::x11;
|
||||||
|
|
||||||
|
// TODO: do not expose XConnection
|
||||||
|
pub fn get_x11_xconnection() -> Option<Arc<XConnection>> {
|
||||||
|
match *UNIX_BACKEND {
|
||||||
|
UnixBackend::X(ref connec) => Some(connec.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Additional methods on `Window` that are specific to Unix.
|
/// Additional methods on `Window` that are specific to Unix.
|
||||||
pub trait WindowExt {
|
pub trait WindowExt {
|
||||||
/// Returns a pointer to the `Window` object of xlib that is used by this window.
|
/// Returns a pointer to the `Window` object of xlib that is used by this window.
|
||||||
|
@ -142,8 +153,22 @@ impl WindowExt for Window {
|
||||||
|
|
||||||
/// Additional methods on `WindowBuilder` that are specific to Unix.
|
/// Additional methods on `WindowBuilder` that are specific to Unix.
|
||||||
pub trait WindowBuilderExt {
|
pub trait WindowBuilderExt {
|
||||||
|
fn with_x11_visual<T>(self, visual_infos: *const T) -> WindowBuilder;
|
||||||
|
fn with_x11_screen(self, screen_id: i32) -> WindowBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowBuilderExt for WindowBuilder {
|
impl WindowBuilderExt for WindowBuilder {
|
||||||
|
#[inline]
|
||||||
|
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> WindowBuilder {
|
||||||
|
self.platform_specific.visual_infos = Some(
|
||||||
|
unsafe { ptr::read(visual_infos as *const XVisualInfo) }
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_x11_screen(mut self, screen_id: i32) -> WindowBuilder {
|
||||||
|
self.platform_specific.screen_id = Some(screen_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,22 @@ use api::x11;
|
||||||
use api::x11::XConnection;
|
use api::x11::XConnection;
|
||||||
use api::x11::XError;
|
use api::x11::XError;
|
||||||
use api::x11::XNotSupported;
|
use api::x11::XNotSupported;
|
||||||
|
use api::x11::ffi::XVisualInfo;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct PlatformSpecificWindowBuilderAttributes;
|
pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
|
pub visual_infos: Option<XVisualInfo>,
|
||||||
|
pub screen_id: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
enum Backend {
|
pub enum Backend {
|
||||||
X(Arc<XConnection>),
|
X(Arc<XConnection>),
|
||||||
Wayland(Arc<wayland::WaylandContext>),
|
Wayland(Arc<wayland::WaylandContext>),
|
||||||
Error(XNotSupported),
|
Error(XNotSupported),
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static!(
|
lazy_static!(
|
||||||
static ref BACKEND: Backend = {
|
pub static ref BACKEND: Backend = {
|
||||||
if let Some(ctxt) = wayland::WaylandContext::init() {
|
if let Some(ctxt) = wayland::WaylandContext::init() {
|
||||||
Backend::Wayland(Arc::new(ctxt))
|
Backend::Wayland(Arc::new(ctxt))
|
||||||
} else {
|
} else {
|
||||||
|
@ -36,6 +40,7 @@ lazy_static!(
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
pub enum Window {
|
pub enum Window {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
X(x11::Window),
|
X(x11::Window),
|
||||||
|
@ -165,7 +170,7 @@ impl<'a> Iterator for WaitEventsIterator<'a> {
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(window: &WindowAttributes, _: &PlatformSpecificWindowBuilderAttributes)
|
pub fn new(window: &WindowAttributes, pl_attribs: &PlatformSpecificWindowBuilderAttributes)
|
||||||
-> Result<Window, CreationError>
|
-> Result<Window, CreationError>
|
||||||
{
|
{
|
||||||
match *BACKEND {
|
match *BACKEND {
|
||||||
|
@ -174,7 +179,7 @@ impl Window {
|
||||||
},
|
},
|
||||||
|
|
||||||
Backend::X(ref connec) => {
|
Backend::X(ref connec) => {
|
||||||
x11::Window::new(connec, window).map(Window::X)
|
x11::Window::new(connec, window, pl_attribs).map(Window::X)
|
||||||
},
|
},
|
||||||
|
|
||||||
Backend::Error(ref error) => {
|
Backend::Error(ref error) => {
|
||||||
|
|
|
@ -3,5 +3,7 @@
|
||||||
pub use self::api_dispatch::{Window, WindowProxy, MonitorId, get_available_monitors, get_primary_monitor};
|
pub use self::api_dispatch::{Window, WindowProxy, MonitorId, get_available_monitors, get_primary_monitor};
|
||||||
pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator};
|
pub use self::api_dispatch::{WaitEventsIterator, PollEventsIterator};
|
||||||
pub use self::api_dispatch::PlatformSpecificWindowBuilderAttributes;
|
pub use self::api_dispatch::PlatformSpecificWindowBuilderAttributes;
|
||||||
|
pub use self::api_dispatch::Backend as UnixBackend;
|
||||||
|
pub use self::api_dispatch::BACKEND as UNIX_BACKEND;
|
||||||
|
|
||||||
mod api_dispatch;
|
mod api_dispatch;
|
||||||
|
|
Loading…
Reference in a new issue