Skip to content

Commit

Permalink
Shares the XConnection between all event loops instead of just all ev…
Browse files Browse the repository at this point in the history
…ent (#572)

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 authored and francesca64 committed Jun 18, 2018
1 parent 289fb47 commit 042f5fe
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- `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`.
- Fixed quirk on macOS where certain keys would generate characters at twice the normal rate when held down.
- On X11, all event loops now share the same `XConnection`.

# Version 0.15.1 (2018-06-13)

Expand Down
67 changes: 33 additions & 34 deletions src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::ffi::CStr;
use std::os::raw::*;
use std::sync::Arc;

use parking_lot::Mutex;
use sctk::reexports::client::ConnectError;

use {
Expand Down Expand Up @@ -50,9 +51,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 +358,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_lock = X11_BACKEND.lock();
if let Ok(ref xconn) = *xconn_lock {
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 +441,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())
})
X11_BACKEND
.lock()
.as_ref()
.map(Arc::clone)
.map(x11::EventsLoop::new)
.map(EventsLoop::X)
.map_err(|err| err.clone())
}

#[inline]
Expand Down

0 comments on commit 042f5fe

Please sign in to comment.