mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31: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 root = (x.xlib.XDefaultRootWindow)(x.display);
|
||||||
let resources = (x.xrandr.XRRGetScreenResources)(x.display, root);
|
let resources = (x.xrandr.XRRGetScreenResources)(x.display, root);
|
||||||
|
|
||||||
let mut major = 0;
|
if let Some(ref xrandr_1_5) = x.xrandr_1_5 {
|
||||||
let mut minor = 0;
|
|
||||||
(x.xrandr.XRRQueryVersion)(x.display, &mut major, &mut minor);
|
|
||||||
if ((major as u64)<<32)+(minor as u64) >= (1<<32)+5 {
|
|
||||||
// We're in XRandR >= 1.5, enumerate Monitors to handle things like MST and videowalls
|
// We're in XRandR >= 1.5, enumerate Monitors to handle things like MST and videowalls
|
||||||
let mut nmonitors = 0;
|
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 {
|
for i in 0..nmonitors {
|
||||||
let monitor = *(monitors.offset(i as isize));
|
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 nameslice = slice::from_raw_parts((*output).name as *mut u8, (*output).nameLen as usize);
|
||||||
let name = String::from_utf8_lossy(nameslice).into_owned();
|
let name = String::from_utf8_lossy(nameslice).into_owned();
|
||||||
let hidpi_factor = {
|
let hidpi_factor = {
|
||||||
|
@ -47,7 +44,7 @@ pub fn get_available_monitors(x: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
// Quantize 1/12 step size
|
// Quantize 1/12 step size
|
||||||
((ppmm * (12.0 * 25.4 / 96.0)).round() / 12.0).max(1.0)
|
((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{
|
available.push(MonitorId{
|
||||||
id: i as u32,
|
id: i as u32,
|
||||||
name,
|
name,
|
||||||
|
@ -57,7 +54,7 @@ pub fn get_available_monitors(x: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
primary: (monitor.primary != 0),
|
primary: (monitor.primary != 0),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(x.xrandr.XRRFreeMonitors)(monitors);
|
(xrandr_1_5.XRRFreeMonitors)(monitors);
|
||||||
} else {
|
} else {
|
||||||
// We're in XRandR < 1.5, enumerate CRTCs. Everything will work but MST and
|
// 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
|
// 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.
|
/// A connection to an X server.
|
||||||
pub struct XConnection {
|
pub struct XConnection {
|
||||||
pub xlib: ffi::Xlib,
|
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 xcursor: ffi::Xcursor,
|
||||||
pub xinput2: ffi::XInput2,
|
pub xinput2: ffi::XInput2,
|
||||||
pub xlib_xcb: ffi::Xlib_xcb,
|
pub xlib_xcb: ffi::Xlib_xcb,
|
||||||
|
@ -28,7 +31,8 @@ impl XConnection {
|
||||||
// opening the libraries
|
// opening the libraries
|
||||||
let xlib = try!(ffi::Xlib::open());
|
let xlib = try!(ffi::Xlib::open());
|
||||||
let xcursor = try!(ffi::Xcursor::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 xinput2 = try!(ffi::XInput2::open());
|
||||||
let xlib_xcb = try!(ffi::Xlib_xcb::open());
|
let xlib_xcb = try!(ffi::Xlib_xcb::open());
|
||||||
|
|
||||||
|
@ -47,6 +51,7 @@ impl XConnection {
|
||||||
Ok(XConnection {
|
Ok(XConnection {
|
||||||
xlib: xlib,
|
xlib: xlib,
|
||||||
xrandr: xrandr,
|
xrandr: xrandr,
|
||||||
|
xrandr_1_5: xrandr_1_5,
|
||||||
xcursor: xcursor,
|
xcursor: xcursor,
|
||||||
xinput2: xinput2,
|
xinput2: xinput2,
|
||||||
xlib_xcb: xlib_xcb,
|
xlib_xcb: xlib_xcb,
|
||||||
|
|
Loading…
Reference in a new issue