Last active
April 19, 2020 13:32
-
-
Save sbourdeauducq/185d9b67b9826cdad522e59e6a5f073d to your computer and use it in GitHub Desktop.
Computer graphics like it's MS-DOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Small example of drawing on a Linux graphics screen, with relatively sane graphics | |
// primitives and a minimal amount of wacko libraries. | |
// See: The Unix-Haters Handbook, chapter 7 "The X-Windows Disaster" | |
extern crate xcb; | |
extern crate cairo; | |
extern crate cairo_sys; | |
use std::mem::transmute; | |
fn find_visual(conn: &xcb::Connection, visual: xcb::ffi::xcb_visualid_t) -> Option<xcb::Visualtype> { | |
let setup: xcb::Setup = conn.get_setup(); | |
for screen in setup.roots() { | |
let d_iter: xcb::DepthIterator = screen.allowed_depths(); | |
for depth in d_iter { | |
for vis in depth.visuals() { | |
if visual == vis.visual_id() { | |
return Some(vis) | |
} | |
} | |
} | |
} | |
None | |
} | |
fn main() { | |
let (conn, screen_num) = xcb::Connection::connect(None).unwrap(); | |
let setup = conn.get_setup(); | |
let screen = setup.roots().nth(screen_num as usize).unwrap(); | |
let win = conn.generate_id(); | |
xcb::create_window(&conn, | |
xcb::COPY_FROM_PARENT as u8, | |
win, | |
screen.root(), | |
0, 0, | |
1024, 768, | |
10, | |
xcb::WINDOW_CLASS_INPUT_OUTPUT as u16, | |
screen.root_visual(), &[ | |
(xcb::CW_BACK_PIXEL, screen.white_pixel()), | |
(xcb::CW_EVENT_MASK, | |
xcb::EVENT_MASK_EXPOSURE | xcb::EVENT_MASK_KEY_PRESS), | |
] | |
); | |
xcb::map_window(&conn, win); | |
conn.flush(); | |
let cairo_conn = cairo::XCBConnection(unsafe { transmute(conn.get_raw_conn()) }); | |
let cairo_win = cairo::XCBDrawable(win); | |
let visual = find_visual(&conn, screen.root_visual()); | |
let cairo_visual = cairo::XCBVisualType(unsafe { transmute(&mut visual.unwrap().base) }); | |
let surface = cairo::XCBSurface::create( | |
&cairo_conn, | |
&cairo_win, | |
&cairo_visual, | |
1024, | |
768).unwrap(); | |
loop { | |
let event = conn.wait_for_event(); | |
match event { | |
None => { break; } | |
Some(event) => { | |
let r = event.response_type() & !0x80; | |
match r { | |
xcb::EXPOSE => { | |
let cr = cairo::Context::new(&surface); | |
cr.scale(120.0, 120.0); | |
cr.set_line_width(0.1); | |
cr.set_source_rgb(0.0, 0.0, 0.0); | |
cr.rectangle(0.25, 0.25, 0.5, 0.5); | |
cr.stroke(); | |
conn.flush(); | |
}, | |
xcb::KEY_PRESS => { | |
let key_press: &xcb::KeyPressEvent = unsafe { | |
xcb::cast_event(&event) | |
}; | |
let key_code = key_press.detail(); | |
// q to exit | |
if key_code == 24 { | |
break; | |
} | |
}, | |
_ => {} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment