Skip to content

Commit

Permalink
Shares the XConnection between all event loops instead of just all event
Browse files Browse the repository at this point in the history
loops on the same thread.

This is needed for adding shared context support to glutin, as contexts
must be made with the same native display (and therefore the same
connection.)

Signed-off-by: Hal Gentz <[email protected]>
  • Loading branch information
goddessfreya committed Jun 17, 2018
1 parent e7a8efc commit 0f6a1fd
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- HiDPI support for Wayland.
- `EventsLoop::get_available_monitors` and `EventsLoop::get_primary_monitor` now have identical counterparts on `Window`, so this information can be acquired without an `EventsLoop` borrow.
- `AvailableMonitorsIter` now implements `Debug`.
- In X11, all events loops will now share the same XConnection.

# Version 0.15.1 (2018-06-13)

Expand Down
68 changes: 34 additions & 34 deletions src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ use self::x11::{XConnection, XError};
use self::x11::ffi::XVisualInfo;
pub use self::x11::XNotSupported;

use parking_lot::Mutex;

mod dlopen;
pub mod wayland;
pub mod x11;
Expand All @@ -50,9 +52,9 @@ pub struct PlatformSpecificWindowBuilderAttributes {
pub x11_window_type: x11::util::WindowType,
}

thread_local!(
pub static X11_BACKEND: Result<Arc<XConnection>, XNotSupported> = {
XConnection::new(Some(x_error_callback)).map(Arc::new)
lazy_static!(
pub static ref X11_BACKEND: Mutex<Result<Arc<XConnection>, XNotSupported>> = {
Mutex::new(XConnection::new(Some(x_error_callback)).map(Arc::new))
};
);

Expand Down Expand Up @@ -357,29 +359,28 @@ unsafe extern "C" fn x_error_callback(
display: *mut x11::ffi::Display,
event: *mut x11::ffi::XErrorEvent,
) -> c_int {
X11_BACKEND.with(|result| {
if let &Ok(ref xconn) = result {
let mut buf: [c_char; 1024] = mem::uninitialized();
(xconn.xlib.XGetErrorText)(
display,
(*event).error_code as c_int,
buf.as_mut_ptr(),
buf.len() as c_int,
);
let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy();

let error = XError {
description: description.into_owned(),
error_code: (*event).error_code,
request_code: (*event).request_code,
minor_code: (*event).minor_code,
};

eprintln!("[winit X11 error] {:#?}", error);

*xconn.latest_error.lock() = Some(error);
}
});
let xconn = X11_BACKEND.lock();
if let Ok(ref xconn) = *xconn {
let mut buf: [c_char; 1024] = mem::uninitialized();
(xconn.xlib.XGetErrorText)(
display,
(*event).error_code as c_int,
buf.as_mut_ptr(),
buf.len() as c_int,
);
let description = CStr::from_ptr(buf.as_ptr()).to_string_lossy();

let error = XError {
description: description.into_owned(),
error_code: (*event).error_code,
request_code: (*event).request_code,
minor_code: (*event).minor_code,
};

eprintln!("[winit X11 error] {:#?}", error);

*xconn.latest_error.lock() = Some(error);
}
// Fun fact: this return value is completely ignored.
0
}
Expand Down Expand Up @@ -441,14 +442,13 @@ r#"Failed to initialize any backend!
}

pub fn new_x11() -> Result<EventsLoop, XNotSupported> {
X11_BACKEND.with(|result| {
result
.as_ref()
.map(Arc::clone)
.map(x11::EventsLoop::new)
.map(EventsLoop::X)
.map_err(|err| err.clone())
})
let xconn = X11_BACKEND.lock();
xconn
.as_ref()
.map(Arc::clone)
.map(x11::EventsLoop::new)
.map(EventsLoop::X)
.map_err(|err| err.clone())
}

#[inline]
Expand Down

0 comments on commit 0f6a1fd

Please sign in to comment.