diff --git a/xcb_read_rs/.gitignore b/xcb_read_rs/.gitignore new file mode 100644 index 0000000..db94f48 --- /dev/null +++ b/xcb_read_rs/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock +**/*.rs.bk +target diff --git a/xcb_read_rs/Cargo.toml b/xcb_read_rs/Cargo.toml new file mode 100644 index 0000000..89427bb --- /dev/null +++ b/xcb_read_rs/Cargo.toml @@ -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"] } diff --git a/xcb_read_rs/src/main.rs b/xcb_read_rs/src/main.rs new file mode 100644 index 0000000..9ad2105 --- /dev/null +++ b/xcb_read_rs/src/main.rs @@ -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::>(); + + 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); +}