Compare commits
No commits in common. "master" and "f821d87ba3184ffe4e5e4f22f23055ea5e39da63" have entirely different histories.
master
...
f821d87ba3
|
@ -40,15 +40,5 @@ And the following facts:
|
||||||
Work](https://www.x.org/wiki/Development/Documentation/HowVideoCardsWork/)... [TK]
|
Work](https://www.x.org/wiki/Development/Documentation/HowVideoCardsWork/)... [TK]
|
||||||
- An output can have multiple CRTCs... but usually has only one.
|
- An output can have multiple CRTCs... but usually has only one.
|
||||||
|
|
||||||
Unresolved questions ...
|
|
||||||
|
|
||||||
- If the output encapsulates the _whole_ of screen (and the root window), when
|
|
||||||
we rotate the output who does coordinate remapping? I believe that's the
|
|
||||||
responsibility of the window manager. But if that's true, then what are the
|
|
||||||
implications for image viewers?
|
|
||||||
|
|
||||||
- If the output encapsulates only a subwindow of the whole, what is the
|
|
||||||
responsibility of the window manager when the new dimensions fit easily within
|
|
||||||
the screen as a whole?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,20 +33,9 @@ void display_one_output(xcb_connection_t* connection, xcb_randr_get_output_info_
|
||||||
xcb_timestamp_t timestamp) {
|
xcb_timestamp_t timestamp) {
|
||||||
xcb_randr_get_crtc_info_reply_t* crtc = xcb_randr_get_crtc_info_reply(
|
xcb_randr_get_crtc_info_reply_t* crtc = xcb_randr_get_crtc_info_reply(
|
||||||
connection, xcb_randr_get_crtc_info(connection, output->crtc, timestamp), NULL);
|
connection, xcb_randr_get_crtc_info(connection, output->crtc, timestamp), NULL);
|
||||||
|
|
||||||
// Note: This is part of the output structure natively; it's just not
|
|
||||||
// automagically exposed. (Opaque structures suck.) But it's both accessible
|
|
||||||
// and null-terminated, so it's relatively safe to use this way, and it does
|
|
||||||
// not require free() at the end.
|
|
||||||
auto name = xcb_randr_get_output_info_name(output);
|
|
||||||
if (name) {
|
|
||||||
std::cout << "DISPLAY: " << name << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!crtc) {
|
if (!crtc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
display_one_crtc(crtc);
|
display_one_crtc(crtc);
|
||||||
free(crtc);
|
free(crtc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Cargo.lock
|
|
||||||
**/*.rs.bk
|
|
||||||
target
|
|
|
@ -1,10 +0,0 @@
|
||||||
[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"] }
|
|
|
@ -1,112 +0,0 @@
|
||||||
use xcb::Xid;
|
|
||||||
|
|
||||||
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,
|
|
||||||
cookie: xcb::randr::GetOutputInfoCookie,
|
|
||||||
timestamp: xcb::x::Timestamp,
|
|
||||||
) {
|
|
||||||
let output = conn.wait_for_reply(cookie).unwrap();
|
|
||||||
if !(output.connection() == xcb::randr::Connection::Connected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Display: {}", std::str::from_utf8(output.name()).unwrap());
|
|
||||||
if output.crtc().resource_id() == 0 {
|
|
||||||
println!("(no monitor found)\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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: {}\n",
|
|
||||||
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,
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
for cookie in output_cookies {
|
|
||||||
display_one_output(conn, cookie, 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