Merge pull request #106 from rerion/master

Allow creation of X11 window with specified visual and screen
This commit is contained in:
tomaka 2017-01-07 15:03:59 +01:00 committed by GitHub
commit 09e6698236
5 changed files with 66 additions and 15 deletions

View file

@ -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"]

View file

@ -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(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32, Some(id) => id,
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) }, None => match window_attrs.monitor {
Some(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32,
_ => 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

View file

@ -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
}
} }

View file

@ -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) => {

View file

@ -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;