extern crate x11rb;
use x11rb::connection::Connection;
use x11rb::cursor::Handle as CursorHandle;
use x11rb::protocol::xproto::*;
use x11rb::protocol::Event;
use x11rb::resource_manager::Database;
use x11rb::wrapper::ConnectionExt as _;
fn main() {
let (conn, screen_num) = x11rb::connect(None).unwrap();
let conn1 = std::sync::Arc::new(conn);
let conn = &*conn1;
let screen = &conn.setup().roots[screen_num];
let win_id = conn.generate_id().unwrap();
let gc_id = conn.generate_id().unwrap();
let resource_db = Database::new_from_default(conn).unwrap();
let cursor_handle = CursorHandle::new(conn, screen_num, &resource_db).unwrap();
let wm_protocols = conn.intern_atom(false, b"WM_PROTOCOLS").unwrap();
let wm_delete_window = conn.intern_atom(false, b"WM_DELETE_WINDOW").unwrap();
let net_wm_name = conn.intern_atom(false, b"_NET_WM_NAME").unwrap();
let utf8_string = conn.intern_atom(false, b"UTF8_STRING").unwrap();
let wm_protocols = wm_protocols.reply().unwrap().atom;
let wm_delete_window = wm_delete_window.reply().unwrap().atom;
let net_wm_name = net_wm_name.reply().unwrap().atom;
let utf8_string = utf8_string.reply().unwrap().atom;
let cursor_handle = cursor_handle.reply().unwrap();
let win_aux = CreateWindowAux::new()
.event_mask(EventMask::EXPOSURE | EventMask::STRUCTURE_NOTIFY | EventMask::NO_EVENT)
.background_pixel(screen.white_pixel)
.win_gravity(Gravity::NORTH_WEST)
.cursor(cursor_handle.load_cursor(conn, "wait").unwrap());
let gc_aux = CreateGCAux::new().foreground(screen.black_pixel);
let (mut width, mut height) = (100, 100);
conn.create_window(
screen.root_depth,
win_id,
screen.root,
0,
0,
width,
height,
0,
WindowClass::INPUT_OUTPUT,
0,
&win_aux,
)
.unwrap();
util::start_timeout_thread(conn1.clone(), win_id);
let title = "Simple Window";
conn.change_property8(
PropMode::REPLACE,
win_id,
AtomEnum::WM_NAME,
AtomEnum::STRING,
title.as_bytes(),
)
.unwrap();
conn.change_property8(
PropMode::REPLACE,
win_id,
net_wm_name,
utf8_string,
title.as_bytes(),
)
.unwrap();
conn.change_property32(
PropMode::REPLACE,
win_id,
wm_protocols,
AtomEnum::ATOM,
&[wm_delete_window],
)
.unwrap();
conn.change_property8(
PropMode::REPLACE,
win_id,
AtomEnum::WM_CLASS,
AtomEnum::STRING,
b"simple_window\0simple_window\0",
)
.unwrap();
conn.change_property8(
PropMode::REPLACE,
win_id,
AtomEnum::WM_CLIENT_MACHINE,
AtomEnum::STRING,
gethostname::gethostname()
.to_str()
.unwrap_or("[Invalid]")
.as_bytes(),
)
.unwrap();
let reply = conn
.get_property(false, win_id, AtomEnum::WM_NAME, AtomEnum::STRING, 0, 1024)
.unwrap();
let reply = reply.reply().unwrap();
assert_eq!(reply.value, title.as_bytes());
conn.create_gc(gc_id, win_id, &gc_aux).unwrap();
conn.map_window(win_id).unwrap();
conn.flush().unwrap();
loop {
let event = conn.wait_for_event().unwrap();
println!("{:?})", event);
match event {
Event::Expose(event) => {
if event.count == 0 {
let (width, height): (i16, i16) = (width as _, height as _);
let points = [
Point {
x: width,
y: height,
},
Point { x: -10, y: -10 },
Point {
x: -10,
y: height + 10,
},
Point {
x: width + 10,
y: -10,
},
];
conn.poly_line(CoordMode::ORIGIN, win_id, gc_id, &points)
.unwrap();
conn.flush().unwrap();
}
}
Event::ConfigureNotify(event) => {
width = event.width;
height = event.height;
}
Event::ClientMessage(event) => {
let data = event.data.as_data32();
if event.format == 32 && event.window == win_id && data[0] == wm_delete_window {
println!("Window was asked to close");
return;
}
}
Event::Error(_) => println!("Got an unexpected error"),
_ => println!("Got an unknown event"),
}
}
}
include!("integration_test_util/util.rs");