#include #include #include #include #include #include const int ESC_BUTTON = 9; typedef struct xhorse { xcb_connection_t *conn; xcb_screen_t *scr; xcb_window_t win; } xhorse_t; bool xh_connect(xhorse_t *xh) { xh->conn = xcb_connect(NULL, NULL); if (!xh->conn || xcb_connection_has_error(xh->conn)) { return false; } return true; } void xh_disconnect(xhorse_t *xh) { xcb_unmap_window(xh->conn, xh->win); xcb_flush(xh->conn); xcb_disconnect(xh->conn); } void xh_setup(xhorse_t *xh) { const xcb_setup_t *set = xcb_get_setup(xh->conn); xh->scr = xcb_setup_roots_iterator(set).data; uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; uint32_t vals[] = { xh->scr->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS }; xh->win = xcb_generate_id(xh->conn); xcb_void_cookie_t cookie = xcb_create_window(xh->conn, /* depth */ XCB_COPY_FROM_PARENT, xh->win, xh->scr->root, /* x */ 0, /* y */ 0, /* w */ 150, /* h */ 75, /* border width*/ 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, xh->scr->root_visual, mask, vals); xcb_map_window(xh->conn, xh->win); } void xh_handle_expose(xhorse_t *xh, xcb_generic_event_t *generic_ev) { // TODO } bool xh_handle_esc(xhorse_t *xh, xcb_generic_event_t *generic_ev) { xcb_key_press_event_t *press_ev = (xcb_key_press_event_t *)generic_ev; return ESC_BUTTON == press_ev->detail; } void xh_event_loop(xhorse_t *xh) { xcb_generic_event_t *generic_ev; while ((generic_ev = xcb_wait_for_event(xh->conn))) { uint8_t response_type = generic_ev->response_type & ~0x80; switch (response_type) { case XCB_EXPOSE: xh_handle_expose(xh, generic_ev); break; case XCB_KEY_PRESS: if (true == xh_handle_esc(xh, generic_ev)) return; break; } free(generic_ev); } } int main(void) { xhorse_t *xh = malloc(sizeof(xhorse_t)); if (false == xh_connect(xh)) { puts("can't connect to X"); return EXIT_FAILURE; } xh_setup(xh); xcb_flush(xh->conn); xh_event_loop(xh); xh_disconnect(xh); free(xh); return EXIT_SUCCESS; }