X11: Fix get_current_monitor (#515)
* X11: Fix get_current_monitor Fixes #64 * impl Debug for MonitorId on all platforms
This commit is contained in:
parent
15a4fec3d9
commit
d86f53a02c
15 changed files with 417 additions and 145 deletions
|
|
@ -1,5 +1,40 @@
|
|||
use std::cmp;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Rect {
|
||||
left: i64,
|
||||
right: i64,
|
||||
top: i64,
|
||||
bottom: i64,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
pub fn new((x, y): (i32, i32), (width, height): (u32, u32)) -> Self {
|
||||
let (x, y) = (x as i64, y as i64);
|
||||
let (width, height) = (width as i64, height as i64);
|
||||
Rect {
|
||||
left: x,
|
||||
right: x + width,
|
||||
top: y,
|
||||
bottom: y + height,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_overlapping_area(&self, other: &Self) -> i64 {
|
||||
let x_overlap = cmp::max(
|
||||
0,
|
||||
cmp::min(self.right, other.right) - cmp::max(self.left, other.left),
|
||||
);
|
||||
let y_overlap = cmp::max(
|
||||
0,
|
||||
cmp::min(self.bottom, other.bottom) - cmp::max(self.top, other.top),
|
||||
);
|
||||
x_overlap * y_overlap
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TranslatedCoords {
|
||||
pub x_rel_root: c_int,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ mod geometry;
|
|||
mod hint;
|
||||
mod icon;
|
||||
mod input;
|
||||
mod randr;
|
||||
mod window_property;
|
||||
mod wm;
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ pub use self::geometry::*;
|
|||
pub use self::hint::*;
|
||||
pub use self::icon::*;
|
||||
pub use self::input::*;
|
||||
pub use self::randr::*;
|
||||
pub use self::window_property::*;
|
||||
pub use self::wm::*;
|
||||
|
||||
|
|
|
|||
84
src/platform/linux/x11/util/randr.rs
Normal file
84
src/platform/linux/x11/util/randr.rs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
use std::slice;
|
||||
|
||||
use super::*;
|
||||
use super::ffi::{
|
||||
RROutput,
|
||||
XRRCrtcInfo,
|
||||
XRRMonitorInfo,
|
||||
XRRScreenResources,
|
||||
};
|
||||
|
||||
pub enum MonitorRepr {
|
||||
Monitor(*mut XRRMonitorInfo),
|
||||
Crtc(*mut XRRCrtcInfo),
|
||||
}
|
||||
|
||||
impl MonitorRepr {
|
||||
pub unsafe fn get_output(&self) -> RROutput {
|
||||
match *self {
|
||||
// Same member names, but different locations within the struct...
|
||||
MonitorRepr::Monitor(monitor) => *((*monitor).outputs.offset(0)),
|
||||
MonitorRepr::Crtc(crtc) => *((*crtc).outputs.offset(0)),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_dimensions(&self) -> (u32, u32) {
|
||||
match *self {
|
||||
MonitorRepr::Monitor(monitor) => ((*monitor).width as u32, (*monitor).height as u32),
|
||||
MonitorRepr::Crtc(crtc) => ((*crtc).width as u32, (*crtc).height as u32),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_position(&self) -> (i32, i32) {
|
||||
match *self {
|
||||
MonitorRepr::Monitor(monitor) => ((*monitor).x as i32, (*monitor).y as i32),
|
||||
MonitorRepr::Crtc(crtc) => ((*crtc).x as i32, (*crtc).y as i32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<*mut XRRMonitorInfo> for MonitorRepr {
|
||||
fn from(monitor: *mut XRRMonitorInfo) -> Self {
|
||||
MonitorRepr::Monitor(monitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<*mut XRRCrtcInfo> for MonitorRepr {
|
||||
fn from(crtc: *mut XRRCrtcInfo) -> Self {
|
||||
MonitorRepr::Crtc(crtc)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calc_dpi_factor(
|
||||
(width_px, height_px): (u32, u32),
|
||||
(width_mm, height_mm): (u64, u64),
|
||||
) -> f64 {
|
||||
let ppmm = (
|
||||
(width_px as f64 * height_px as f64) / (width_mm as f64 * height_mm as f64)
|
||||
).sqrt();
|
||||
// Quantize 1/12 step size
|
||||
((ppmm * (12.0 * 25.4 / 96.0)).round() / 12.0).max(1.0)
|
||||
}
|
||||
|
||||
pub unsafe fn get_output_info(
|
||||
xconn: &Arc<XConnection>,
|
||||
resources: *mut XRRScreenResources,
|
||||
repr: &MonitorRepr,
|
||||
) -> (String, f32) {
|
||||
let output_info = (xconn.xrandr.XRRGetOutputInfo)(
|
||||
xconn.display,
|
||||
resources,
|
||||
repr.get_output(),
|
||||
);
|
||||
let name_slice = slice::from_raw_parts(
|
||||
(*output_info).name as *mut u8,
|
||||
(*output_info).nameLen as usize,
|
||||
);
|
||||
let name = String::from_utf8_lossy(name_slice).into();
|
||||
let hidpi_factor = calc_dpi_factor(
|
||||
repr.get_dimensions(),
|
||||
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
||||
) as f32;
|
||||
(xconn.xrandr.XRRFreeOutputInfo)(output_info);
|
||||
(name, hidpi_factor)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue