mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
x11: Support XRandR versions older than 1.5 (#394)
* x11: Support XRandR versions older than 1.5 Fixes #392 Previously, initializing the member `xrandr` of `XConnection` resulted in a panic when symbols from XRandR version 1.5 were missing. There was already code to handle older versions of XRandR but it was never executed because of the panic. The member `XConnection.xrandr` now contains only functions that can safely be used with older versions. Additionally, this commit adds a new member to `XConnection` of type `Option<ffi::XRandr>` that only contains a value if version 1.5 functionality is present. * x11: Document the xrandr* members of XConnection
This commit is contained in:
parent
150d2706f9
commit
107a1e7332
|
@ -25,16 +25,13 @@ pub fn get_available_monitors(x: &Arc<XConnection>) -> Vec<MonitorId> {
|
|||
let root = (x.xlib.XDefaultRootWindow)(x.display);
|
||||
let resources = (x.xrandr.XRRGetScreenResources)(x.display, root);
|
||||
|
||||
let mut major = 0;
|
||||
let mut minor = 0;
|
||||
(x.xrandr.XRRQueryVersion)(x.display, &mut major, &mut minor);
|
||||
if ((major as u64)<<32)+(minor as u64) >= (1<<32)+5 {
|
||||
if let Some(ref xrandr_1_5) = x.xrandr_1_5 {
|
||||
// We're in XRandR >= 1.5, enumerate Monitors to handle things like MST and videowalls
|
||||
let mut nmonitors = 0;
|
||||
let monitors = (x.xrandr.XRRGetMonitors)(x.display, root, 1, &mut nmonitors);
|
||||
let monitors = (xrandr_1_5.XRRGetMonitors)(x.display, root, 1, &mut nmonitors);
|
||||
for i in 0..nmonitors {
|
||||
let monitor = *(monitors.offset(i as isize));
|
||||
let output = (x.xrandr.XRRGetOutputInfo)(x.display, resources, *(monitor.outputs.offset(0)));
|
||||
let output = (xrandr_1_5.XRRGetOutputInfo)(x.display, resources, *(monitor.outputs.offset(0)));
|
||||
let nameslice = slice::from_raw_parts((*output).name as *mut u8, (*output).nameLen as usize);
|
||||
let name = String::from_utf8_lossy(nameslice).into_owned();
|
||||
let hidpi_factor = {
|
||||
|
@ -47,7 +44,7 @@ pub fn get_available_monitors(x: &Arc<XConnection>) -> Vec<MonitorId> {
|
|||
// Quantize 1/12 step size
|
||||
((ppmm * (12.0 * 25.4 / 96.0)).round() / 12.0).max(1.0)
|
||||
};
|
||||
(x.xrandr.XRRFreeOutputInfo)(output);
|
||||
(xrandr_1_5.XRRFreeOutputInfo)(output);
|
||||
available.push(MonitorId{
|
||||
id: i as u32,
|
||||
name,
|
||||
|
@ -57,7 +54,7 @@ pub fn get_available_monitors(x: &Arc<XConnection>) -> Vec<MonitorId> {
|
|||
primary: (monitor.primary != 0),
|
||||
});
|
||||
}
|
||||
(x.xrandr.XRRFreeMonitors)(monitors);
|
||||
(xrandr_1_5.XRRFreeMonitors)(monitors);
|
||||
} else {
|
||||
// We're in XRandR < 1.5, enumerate CRTCs. Everything will work but MST and
|
||||
// videowall setups will show more monitors than the logical groups the user
|
||||
|
|
|
@ -10,7 +10,10 @@ use super::ffi;
|
|||
/// A connection to an X server.
|
||||
pub struct XConnection {
|
||||
pub xlib: ffi::Xlib,
|
||||
pub xrandr: ffi::Xrandr,
|
||||
/// Exposes XRandR functions from version < 1.5
|
||||
pub xrandr: ffi::Xrandr_2_2_0,
|
||||
/// Exposes XRandR functions from version = 1.5
|
||||
pub xrandr_1_5: Option<ffi::Xrandr>,
|
||||
pub xcursor: ffi::Xcursor,
|
||||
pub xinput2: ffi::XInput2,
|
||||
pub xlib_xcb: ffi::Xlib_xcb,
|
||||
|
@ -28,7 +31,8 @@ impl XConnection {
|
|||
// opening the libraries
|
||||
let xlib = try!(ffi::Xlib::open());
|
||||
let xcursor = try!(ffi::Xcursor::open());
|
||||
let xrandr = try!(ffi::Xrandr::open());
|
||||
let xrandr = try!(ffi::Xrandr_2_2_0::open());
|
||||
let xrandr_1_5 = ffi::Xrandr::open().ok();
|
||||
let xinput2 = try!(ffi::XInput2::open());
|
||||
let xlib_xcb = try!(ffi::Xlib_xcb::open());
|
||||
|
||||
|
@ -47,6 +51,7 @@ impl XConnection {
|
|||
Ok(XConnection {
|
||||
xlib: xlib,
|
||||
xrandr: xrandr,
|
||||
xrandr_1_5: xrandr_1_5,
|
||||
xcursor: xcursor,
|
||||
xinput2: xinput2,
|
||||
xlib_xcb: xlib_xcb,
|
||||
|
|
Loading…
Reference in a new issue