This is a port of the C++ version of the XCB RandR reader.
I really, *really* like the way the Rust library is built and managed. It does a really good job of emulating the XCB RandR macro found in KDE's Plasma and libkscreen. The port was straightforward and my worries about memory management were completely unfounded.
This commit is contained in:
parent
f821d87ba3
commit
f60e935ffe
|
@ -0,0 +1,3 @@
|
||||||
|
Cargo.lock
|
||||||
|
**/*.rs.bk
|
||||||
|
target
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "xcb_read_rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2.102"
|
||||||
|
xcb = { version = "1.0.0-beta", features = ["randr"] }
|
|
@ -0,0 +1,106 @@
|
||||||
|
extern crate libc;
|
||||||
|
extern crate xcb;
|
||||||
|
|
||||||
|
fn status_map(status: xcb::randr::SetConfig) -> &'static str {
|
||||||
|
match status {
|
||||||
|
xcb::randr::SetConfig::Success => "success",
|
||||||
|
xcb::randr::SetConfig::InvalidConfigTime => "invalid config time",
|
||||||
|
xcb::randr::SetConfig::InvalidTime => "invalid time",
|
||||||
|
xcb::randr::SetConfig::Failed => "failed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rotation_map(rotation: xcb::randr::Rotation) -> &'static str {
|
||||||
|
match rotation {
|
||||||
|
xcb::randr::Rotation::ROTATE_0 => "normal",
|
||||||
|
xcb::randr::Rotation::ROTATE_90 => "portrait",
|
||||||
|
xcb::randr::Rotation::ROTATE_180 => "inverted",
|
||||||
|
xcb::randr::Rotation::ROTATE_270 => "portrait inverted",
|
||||||
|
_ => "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_one_output(
|
||||||
|
conn: &xcb::Connection,
|
||||||
|
output: &xcb::randr::GetOutputInfoReply,
|
||||||
|
timestamp: xcb::x::Timestamp,
|
||||||
|
) {
|
||||||
|
let crtc = conn
|
||||||
|
.wait_for_reply(conn.send_request(&xcb::randr::GetCrtcInfo {
|
||||||
|
crtc: output.crtc(),
|
||||||
|
config_timestamp: timestamp,
|
||||||
|
}))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"x: {}, y: {}, W×H: {}×{}, status: {}, rotation: {}",
|
||||||
|
crtc.x(),
|
||||||
|
crtc.y(),
|
||||||
|
crtc.width(),
|
||||||
|
crtc.height(),
|
||||||
|
status_map(crtc.status()),
|
||||||
|
rotation_map(crtc.rotation()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_outputs(
|
||||||
|
conn: &xcb::Connection,
|
||||||
|
screen: &xcb::randr::GetScreenResourcesReply,
|
||||||
|
timestamp: xcb::x::Timestamp,
|
||||||
|
) {
|
||||||
|
let output_cookies = screen
|
||||||
|
.outputs()
|
||||||
|
.iter()
|
||||||
|
.map(|output| {
|
||||||
|
conn.send_request(&xcb::randr::GetOutputInfo {
|
||||||
|
output: *output,
|
||||||
|
config_timestamp: timestamp,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for cookie in output_cookies.into_iter() {
|
||||||
|
let reply = conn.wait_for_reply(cookie).unwrap();
|
||||||
|
if reply.connection() == xcb::randr::Connection::Connected {
|
||||||
|
display_one_output(conn, &reply, timestamp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_screen_resources(
|
||||||
|
conn: &xcb::Connection,
|
||||||
|
root: &xcb::x::Window,
|
||||||
|
) -> xcb::randr::GetScreenResourcesReply {
|
||||||
|
conn.wait_for_reply(conn.send_request(&xcb::randr::GetScreenResources { window: *root }))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn display_xrandr_version(conn: &xcb::Connection) {
|
||||||
|
let randr_version = conn
|
||||||
|
.wait_for_reply(conn.send_request(&xcb::randr::QueryVersion {
|
||||||
|
major_version: xcb::randr::MAJOR_VERSION,
|
||||||
|
minor_version: xcb::randr::MINOR_VERSION,
|
||||||
|
}))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"RandR Version {}.{}",
|
||||||
|
randr_version.major_version(),
|
||||||
|
randr_version.minor_version()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (x_connection, screen_num) = xcb::Connection::connect(None).unwrap();
|
||||||
|
let setup = x_connection.get_setup();
|
||||||
|
let screen = setup.roots().nth(screen_num as usize).unwrap();
|
||||||
|
println!(
|
||||||
|
"{} x {}",
|
||||||
|
screen.width_in_pixels(),
|
||||||
|
screen.height_in_pixels()
|
||||||
|
);
|
||||||
|
display_xrandr_version(&x_connection);
|
||||||
|
let screen_resources = get_screen_resources(&x_connection, &screen.root());
|
||||||
|
let timestamp = screen_resources.config_timestamp();
|
||||||
|
display_outputs(&x_connection, &screen_resources, timestamp);
|
||||||
|
}
|
Loading…
Reference in New Issue