X11: Check if XRRGetOutputInfo returned NULL ()

* X11: Check if XRRGetOutputInfo returned NULL

Fixes 

* Change X11 error logging to actually use log
This commit is contained in:
Francesca Plebani 2018-11-17 15:51:39 -05:00 committed by GitHub
parent 3ba808e3c6
commit 3c59283b3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 11 deletions
CHANGELOG.md
src/platform/linux

View file

@ -5,6 +5,7 @@
- On Windows, catch panics in event loop child thread and forward them to the parent thread. This prevents an invocation of undefined behavior due to unwinding into foreign code. - On Windows, catch panics in event loop child thread and forward them to the parent thread. This prevents an invocation of undefined behavior due to unwinding into foreign code.
- On Windows, fix issue where resizing or moving window combined with grabbing the cursor would freeze program. - On Windows, fix issue where resizing or moving window combined with grabbing the cursor would freeze program.
- On Windows, fix issue where resizing or moving window would eat `Awakened` events. - On Windows, fix issue where resizing or moving window would eat `Awakened` events.
- On X11, fixed a segfault when using virtual monitors with XRandR.
# Version 0.18.0 (2018-11-07) # Version 0.18.0 (2018-11-07)

View file

@ -382,7 +382,7 @@ unsafe extern "C" fn x_error_callback(
minor_code: (*event).minor_code, minor_code: (*event).minor_code,
}; };
eprintln!("[winit X11 error] {:#?}", error); error!("X11 error: {:#?}", error);
*xconn.latest_error.lock() = Some(error); *xconn.latest_error.lock() = Some(error);
} }

View file

@ -65,11 +65,11 @@ impl MonitorId {
id: u32, id: u32,
repr: util::MonitorRepr, repr: util::MonitorRepr,
primary: bool, primary: bool,
) -> Self { ) -> Option<Self> {
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr) }; let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) }; let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) };
let rect = util::AaRect::new(position, dimensions); let rect = util::AaRect::new(position, dimensions);
MonitorId { Some(MonitorId {
id, id,
name, name,
hidpi_factor, hidpi_factor,
@ -77,7 +77,7 @@ impl MonitorId {
position, position,
primary, primary,
rect, rect,
} })
} }
pub fn get_name(&self) -> Option<String> { pub fn get_name(&self) -> Option<String> {
@ -153,13 +153,13 @@ impl XConnection {
let monitor = monitors.offset(monitor_index as isize); let monitor = monitors.offset(monitor_index as isize);
let is_primary = (*monitor).primary != 0; let is_primary = (*monitor).primary != 0;
has_primary |= is_primary; has_primary |= is_primary;
available.push(MonitorId::from_repr( MonitorId::from_repr(
self, self,
resources, resources,
monitor_index as u32, monitor_index as u32,
monitor.into(), monitor.into(),
is_primary, is_primary,
)); ).map(|monitor_id| available.push(monitor_id));
} }
(xrandr_1_5.XRRFreeMonitors)(monitors); (xrandr_1_5.XRRFreeMonitors)(monitors);
} else { } else {
@ -176,13 +176,13 @@ impl XConnection {
let crtc = util::MonitorRepr::from(crtc); let crtc = util::MonitorRepr::from(crtc);
let is_primary = crtc.get_output() == primary; let is_primary = crtc.get_output() == primary;
has_primary |= is_primary; has_primary |= is_primary;
available.push(MonitorId::from_repr( MonitorId::from_repr(
self, self,
resources, resources,
crtc_id as u32, crtc_id as u32,
crtc, crtc,
is_primary, is_primary,
)); ).map(|monitor_id| available.push(monitor_id));
} }
(self.xrandr.XRRFreeCrtcInfo)(crtc); (self.xrandr.XRRFreeCrtcInfo)(crtc);
} }

View file

@ -79,12 +79,23 @@ impl From<*mut ffi::XRRCrtcInfo> for MonitorRepr {
} }
impl XConnection { impl XConnection {
pub unsafe fn get_output_info(&self, resources: *mut ffi::XRRScreenResources, repr: &MonitorRepr) -> (String, f64) { pub unsafe fn get_output_info(
&self,
resources: *mut ffi::XRRScreenResources,
repr: &MonitorRepr,
) -> Option<(String, f64)> {
let output_info = (self.xrandr.XRRGetOutputInfo)( let output_info = (self.xrandr.XRRGetOutputInfo)(
self.display, self.display,
resources, resources,
repr.get_output(), repr.get_output(),
); );
if output_info.is_null() {
// When calling `XRRGetOutputInfo` on a virtual monitor (versus a physical display)
// it's possible for it to return null.
// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=816596
let _ = self.check_errors(); // discard `BadRROutput` error
return None;
}
let name_slice = slice::from_raw_parts( let name_slice = slice::from_raw_parts(
(*output_info).name as *mut u8, (*output_info).name as *mut u8,
(*output_info).nameLen as usize, (*output_info).nameLen as usize,
@ -95,6 +106,6 @@ impl XConnection {
((*output_info).mm_width as u64, (*output_info).mm_height as u64), ((*output_info).mm_width as u64, (*output_info).mm_height as u64),
); );
(self.xrandr.XRRFreeOutputInfo)(output_info); (self.xrandr.XRRFreeOutputInfo)(output_info);
(name, hidpi_factor) Some((name, hidpi_factor))
} }
} }