From 32d01b288e5ee8f900b4672216e7d1fa912e5bcb Mon Sep 17 00:00:00 2001 From: Nicolas Koch Date: Sat, 30 Jul 2016 23:58:28 +0200 Subject: [PATCH] Add support for xcb Due to XCB and Xlib compability, we can take a shortcut and use X11's underlying xcb_connection. This way, a complete XCB backend implementation can be avoided. --- Cargo.toml | 2 +- src/api/x11/ffi.rs | 1 + src/api/x11/window.rs | 6 ++++++ src/api/x11/xdisplay.rs | 3 +++ src/os/unix.rs | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f83b2653..54094f25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,4 +39,4 @@ dwmapi-sys = "0.1" wayland-client = { version = "0.5.4", features = ["dlopen"] } wayland-kbd = "0.3.3" wayland-window = "0.2.2" -x11-dl = "~2.4" +x11-dl = "2.8" diff --git a/src/api/x11/ffi.rs b/src/api/x11/ffi.rs index 2b970997..e04e4ad2 100644 --- a/src/api/x11/ffi.rs +++ b/src/api/x11/ffi.rs @@ -4,4 +4,5 @@ pub use x11_dl::xf86vmode::*; pub use x11_dl::xlib::*; pub use x11_dl::xinput::*; pub use x11_dl::xinput2::*; +pub use x11_dl::xlib_xcb::*; pub use x11_dl::error::OpenError; diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs index ea327eb4..005fe6d2 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -694,6 +694,12 @@ impl Window { self.x.window as *mut libc::c_void } + pub fn get_xcb_connection(&self) -> *mut libc::c_void { + unsafe { + (self.x.display.xlib_xcb.XGetXCBConnection)(self.get_xlib_display() as *mut _) as *mut _ + } + } + #[inline] pub fn set_window_resize_callback(&mut self, _: Option) { } diff --git a/src/api/x11/xdisplay.rs b/src/api/x11/xdisplay.rs index 4c5a8bf0..95cc187a 100644 --- a/src/api/x11/xdisplay.rs +++ b/src/api/x11/xdisplay.rs @@ -15,6 +15,7 @@ pub struct XConnection { pub xf86vmode: ffi::Xf86vmode, pub xcursor: ffi::Xcursor, pub xinput2: ffi::XInput2, + pub xlib_xcb: ffi::Xlib_xcb, pub display: *mut ffi::Display, pub latest_error: Mutex>, } @@ -31,6 +32,7 @@ impl XConnection { let xcursor = try!(ffi::Xcursor::open()); let xf86vmode = try!(ffi::Xf86vmode::open()); let xinput2 = try!(ffi::XInput2::open()); + let xlib_xcb = try!(ffi::Xlib_xcb::open()); unsafe { (xlib.XInitThreads)() }; unsafe { (xlib.XSetErrorHandler)(error_handler) }; @@ -49,6 +51,7 @@ impl XConnection { xf86vmode: xf86vmode, xcursor: xcursor, xinput2: xinput2, + xlib_xcb: xlib_xcb, display: display, latest_error: Mutex::new(None), }) diff --git a/src/os/unix.rs b/src/os/unix.rs index 195da77a..c4dfac90 100644 --- a/src/os/unix.rs +++ b/src/os/unix.rs @@ -20,6 +20,14 @@ pub trait WindowExt { /// /// The pointer will become invalid when the glutin `Window` is destroyed. fn get_xlib_display(&self) -> Option<*mut libc::c_void>; + + /// + /// This function returns the underlying `xcb_connection_t` of an xlib `Display`. + /// + /// Returns `None` if the window doesn't use xlib (if it uses wayland for example). + /// + /// The pointer will become invalid when the glutin `Window` is destroyed. + fn get_xcb_connection(&self) -> Option<*mut libc::c_void>; /// Returns a pointer to the `wl_surface` object of wayland that is used by this window. /// @@ -53,6 +61,13 @@ impl WindowExt for Window { } } + fn get_xcb_connection(&self) -> Option<*mut libc::c_void> { + match self.window { + LinuxWindow::X(ref w) => Some(w.get_xcb_connection()), + _ => None + } + } + #[inline] fn get_wayland_surface(&self) -> Option<*mut libc::c_void> { match self.window {