#[path = "util/cancel.rs"]
mod cancel;
#[cfg(feature = "std")]
use breadx::{
display::DisplayConnection,
prelude::*,
protocol::{xproto, Event},
};
#[cfg(feature = "std")]
fn main() -> breadx::Result<()> {
tracing_subscriber::fmt::init();
cancel::spawn_kill_thread();
let mut connection = DisplayConnection::connect(None)?;
let events = xproto::EventMask::EXPOSURE | xproto::EventMask::BUTTON_PRESS;
let background = connection.default_screen().white_pixel;
let parent = connection.default_screen().root;
let wid = connection.generate_xid()?;
connection.create_window(
0, wid,
parent,
0, 0, 600, 400, 0, xproto::WindowClass::COPY_FROM_PARENT,
0, xproto::CreateWindowAux::new()
.event_mask(events)
.background_pixel(background),
)?;
connection.map_window_checked(wid)?;
let title = "Hello, world!";
connection.change_property_checked(
xproto::PropMode::REPLACE,
wid,
xproto::AtomEnum::WM_NAME.into(),
xproto::AtomEnum::STRING.into(),
8,
title.len() as u32,
title,
)?;
let gc = connection.generate_xid()?;
connection.create_gc_checked(
gc,
wid,
xproto::CreateGCAux::new()
.foreground(connection.default_screen().black_pixel)
.graphics_exposures(0)
.line_width(10),
)?;
let cmap = connection.default_screen().default_colormap;
let red_color = connection.alloc_color(cmap, u16::MAX, 0, 0)?;
let green_color = connection.alloc_color(cmap, 0, u16::MAX, 0)?;
let blue_color = connection.alloc_color(cmap, 0, 0, u16::MAX)?;
connection.flush()?;
let red_pixel = connection.wait_for_reply(red_color)?.pixel;
let green_pixel = connection.wait_for_reply(green_color)?.pixel;
let blue_pixel = connection.wait_for_reply(blue_color)?.pixel;
let wm_protocols = connection.intern_atom(false, "WM_PROTOCOLS")?;
let wm_delete_window = connection.intern_atom(false, "WM_DELETE_WINDOW")?;
connection.flush()?;
let wm_protocols = connection.wait_for_reply(wm_protocols)?.atom;
let wm_delete_window = connection.wait_for_reply(wm_delete_window)?.atom;
connection.change_property(
xproto::PropMode::REPLACE,
wid,
wm_protocols,
xproto::AtomEnum::ATOM.into(),
32,
1,
&wm_delete_window,
)?;
cancel::spawn_close_thread(wid);
loop {
let event = connection.wait_for_event()?;
match event {
Event::Expose(_) => {
connection.change_gc(gc, xproto::ChangeGCAux::new().foreground(red_pixel))?;
connection.poly_segment(
wid,
gc,
&[
xproto::Segment {
x1: 10,
y1: 10,
x2: 150,
y2: 150,
},
xproto::Segment {
x1: 150,
y1: 10,
x2: 10,
y2: 150,
},
],
)?;
connection.change_gc(gc, xproto::ChangeGCAux::new().foreground(green_pixel))?;
connection.poly_fill_arc(
wid,
gc,
&[xproto::Arc {
x: 200,
y: 10,
width: 150,
height: 150,
angle1: 0,
angle2: 360 * 64,
}],
)?;
connection.change_gc(gc, xproto::ChangeGCAux::new().foreground(blue_pixel))?;
connection.poly_fill_arc(
wid,
gc,
&[xproto::Arc {
x: 200,
y: 10,
width: 150,
height: 150,
angle1: 0,
angle2: 270 * 64,
}],
)?;
connection.change_gc(
gc,
xproto::ChangeGCAux::new().foreground(connection.default_screen().black_pixel),
)?;
connection.poly_arc(
wid,
gc,
&[xproto::Arc {
x: 200,
y: 10,
width: 150,
height: 150,
angle1: 0,
angle2: 360 * 64,
}],
)?;
connection.flush()?;
}
Event::ButtonPress(bp) => {
println!("Detected click at ({}, {})", bp.event_x, bp.event_y);
}
Event::ClientMessage(cme) => {
if cme.data.as_data32()[0] == wm_delete_window {
break;
}
}
_ => {}
}
}
Ok(())
}
#[cfg(not(feature = "std"))]
fn main() {
println!("Feature `std` is necessary to run this example.");
}