use cairo::XCBSurface;
use cairo::prelude::SurfaceExt;
use pango::LayoutExt;
use std::mem;
use xcb::ffi::*;
// this should in no way be hard-coded, but hey guess what it is
// right now deal with it
const WIDTH: i32 = 1920;
const HEIGHT: i32 = 38;
fn find_visual(conn: *mut xcb_connection_t, visual: xcb_visualid_t) -> *mut xcb_visualtype_t {
unsafe {
let screen_iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
while screen_iter.rem > 0 {
let depth_iter = xcb_screen_allowed_depths_iterator(screen_iter.data);
while depth_iter.rem > 0 {
let visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
while visual_iter.rem > 0 {
if visual == (*visual_iter.data).visual_id {
return visual_iter.data;
}
xcb_visualtype_next(&visual_iter as *const xcb_visualtype_iterator_t as *mut xcb_visualtype_iterator_t);
}
xcb_depth_next(&depth_iter as *const xcb_depth_iterator_t as *mut xcb_depth_iterator_t);
}
xcb_screen_next(&screen_iter as *const xcb_screen_iterator_t as *mut xcb_screen_iterator_t);
}
std::ptr::null_mut()
}
}
fn mk_connection() -> *mut xcb_connection_t {
unsafe {
xcb_connect(std::ptr::null_mut(), std::ptr::null_mut())
}
}
fn mk_window(conn: *mut xcb_connection_t) -> (*mut xcb_screen_t, xcb_window_t) {
unsafe {
let screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
let window = xcb_generate_id(conn);
let mask = [1, XCB_EVENT_MASK_EXPOSURE];
xcb_create_window(conn, XCB_COPY_FROM_PARENT as u8, window, (*screen).root,
0, 0, WIDTH as u16, HEIGHT as u16, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT as u16,
(*screen).root_visual,
XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
mask.as_ptr());
xcb_map_window(conn, window);
(screen, window)
}
}
fn main () {
let conn = mk_connection();
let (screen, window) = mk_window(conn);
let visual = find_visual(conn, unsafe { (*screen).root_visual });
let s = unsafe {
<cairo::Surface as XCBSurface>::create(
&cairo::XCBConnection::from_raw_none(mem::transmute::<*mut xcb_connection_t, *mut cairo_sys::xcb_connection_t>(conn)),
&cairo::XCBDrawable(window),
&cairo::XCBVisualType::from_raw_none(mem::transmute::<*mut xcb_visualtype_t, *mut cairo_sys::xcb_visualtype_t>(visual)),
WIDTH,
HEIGHT,
)
};
let ctx = cairo::Context::new(&s);
unsafe { xcb_flush(conn); }
loop {
let event = unsafe { xcb_wait_for_event(conn) };
if let Some(e) = unsafe { event.as_ref() } {
if (e.response_type & !0x80) == XCB_EXPOSE {
ctx.set_source_rgb(0.2, 0.2, 0.2);
ctx.paint();
ctx.set_source_rgb(1.0, 1.0, 1.0);
let layout = pangocairo::functions::create_layout(&ctx).unwrap();
layout.set_width(1920 * 1024);
let font = pango::FontDescription::from_string("Fira Mono 18");
layout.set_font_description(&font);
ctx.move_to(6.0, 4.0);
layout.set_text("The quick brown fox jumps over the lazy dog.");
pangocairo::functions::show_layout(&ctx, &layout);
<&cairo::Surface as SurfaceExt>::flush(&&s);
}
} else {
break;
}
unsafe { xcb_flush(conn); }
}
unsafe { xcb_disconnect(conn); }
}