#include #include #include #include #include #include #include #include static uint16_t mod_key = XCB_MOD_MASK_4; static const uint16_t SHIFT = XCB_MOD_MASK_SHIFT; void wm_set_mod_key(uint16_t mod) { mod_key = mod; } uint16_t wm_get_mod_key(bool with_shift) { if (with_shift) { return mod_key | SHIFT; } return mod_key; } /* * Array of (internal) event handlers. They cast the event pointer to * the proper type and call the custom handlers defined in Scheme. */ typedef void (*generic_event_handler_t)(xcb_generic_event_t *); static generic_event_handler_t events[XCB_NO_OPERATION]; /* * NOTE: * Don't do the thing below. Create hooks for relevant stuff the user * might care about, call them at the appropriate places. Design should be: * - Event handlers: the WMs job * - Hooks: user customization * * Current sketch is too complex and we don't need to customize * behavior that much anyway. */ // XCB_CONFIGURE_REQUEST static void ev_configure_request(xcb_generic_event_t *); typedef void (*configure_request_handler_t)(); static configure_request_handler_t configure_request_handler = NULL; void wm_set_configure_request_handler(configure_request_handler_t handler) { configure_request_handler = handler; } static void ev_configure_request(xcb_generic_event_t *generic_ev) { if (configure_request_handler) { xcb_configure_request_event_t *ev = (xcb_configure_request_event_t *) generic_ev; configure_request_handler(); } } // XCB_DESTROY_NOTIFY static void ev_destroy_notify(xcb_generic_event_t *); typedef void (*destroy_notify_handler_t)(); static destroy_notify_handler_t destroy_notify_handler = NULL; void wm_set_destroy_notify_handler(destroy_notify_handler_t handler) { destroy_notify_handler = handler; } static void ev_destroy_notify(xcb_generic_event_t *generic_ev) { if (destroy_notify_handler) { xcb_destroy_notify_event_t *ev = (xcb_destroy_notify_event_t *) generic_ev; destroy_notify_handler(); } } // XCB_ENTER_NOTIFY static void ev_enter_notify(xcb_generic_event_t *); typedef void (*enter_notify_handler_t)(); static enter_notify_handler_t enter_notify_handler = NULL; void wm_set_enter_notify_handler(enter_notify_handler_t handler) { enter_notify_handler = handler; } static void ev_enter_notify(xcb_generic_event_t *generic_ev) { if (enter_notify_handler) { xcb_enter_notify_event_t *ev = (xcb_enter_notify_event_t *) generic_ev; enter_notify_handler(); } } // XCB_KEY_PRESS static void ev_key_press(xcb_generic_event_t *); typedef void (*key_press_handler_t)(); static key_press_handler_t key_press_handler = NULL; void wm_set_key_press_handler(key_press_handler_t handler) { key_press_handler = handler; } static void ev_key_press(xcb_generic_event_t *generic_ev) { if (key_press_handler) { xcb_key_press_event_t *ev = (xcb_key_press_event_t *) generic_ev; key_press_handler(); } } // XCB_MAP_REQUEST static void ev_map_request(xcb_generic_event_t *); typedef void (*map_request_handler_t)(); static map_request_handler_t map_request_handler = NULL; void wm_set_map_request_handler(map_request_handler_t handler) { map_request_handler = handler; } static void ev_map_request(xcb_generic_event_t *generic_ev) { if (map_request_handler) { xcb_map_request_event_t *ev = (xcb_map_request_event_t *) generic_ev; map_request_handler(); } } // XCB_UNMAP_NOTIFY static void ev_unmap_notify(xcb_generic_event_t *); typedef void (*unmap_notify_handler_t)(); static unmap_notify_handler_t unmap_notify_handler = NULL; void wm_set_unmap_notify_handler(unmap_notify_handler_t handler) { unmap_notify_handler = handler; } static void ev_unmap_notify(xcb_generic_event_t *generic_ev) { if (unmap_notify_handler) { xcb_unmap_notify_event_t *ev = (xcb_unmap_notify_event_t *) generic_ev; unmap_notify_handler(); } } // XCB_MAPPING_NOTIFY static void ev_mapping_notify(xcb_generic_event_t *); typedef void (*mapping_notify_handler_t)(); static mapping_notify_handler_t mapping_notify_handler = NULL; void wm_set_mapping_notify_handler(mapping_notify_handler_t handler) { mapping_notify_handler = handler; } static void ev_mapping_notify(xcb_generic_event_t *generic_ev) { if (mapping_notify_handler) { xcb_mapping_notify_event_t *ev = (xcb_mapping_notify_event_t *) generic_ev; mapping_notify_handler(); } } // XCB_CONFIGURE_NOTIFY static void ev_configure_notify(xcb_generic_event_t *); typedef void (*configure_notify_handler_t)(int16_t, int16_t, uint16_t, uint16_t); static configure_notify_handler_t configure_notify_handler = NULL; void wm_set_configure_notify_handler(configure_notify_handler_t handler) { configure_notify_handler = handler; } static void ev_configure_notify(xcb_generic_event_t *generic_ev) { if (configure_notify_handler) { xcb_configure_notify_event_t *ev = (xcb_configure_notify_event_t *) generic_ev; configure_notify_handler(ev->x, ev->y, ev->width, ev->height); } } // XCB_CIRCULATE_REQUEST static void ev_circulate_request(xcb_generic_event_t *); typedef void (*circulate_request_handler_t)(); static circulate_request_handler_t circulate_request_handler = NULL; void wm_set_circulate_request_handler(circulate_request_handler_t handler) { circulate_request_handler = handler; } static void ev_circulate_request(xcb_generic_event_t *generic_ev) { if (circulate_request_handler) { xcb_circulate_request_event_t *ev = (xcb_circulate_request_event_t *) generic_ev; circulate_request_handler(); } } // XCB_BUTTON_PRESS static void ev_button_press(xcb_generic_event_t *); typedef void (*button_press_handler_t)(); static button_press_handler_t button_press_handler = NULL; void wm_set_button_press_handler(button_press_handler_t handler) { button_press_handler = handler; } static void ev_button_press(xcb_generic_event_t *generic_ev) { if (button_press_handler) { xcb_button_press_event_t *ev = (xcb_button_press_event_t *) generic_ev; button_press_handler(); } } // XCB_CLIENT_MESSAGE static void ev_client_message(xcb_generic_event_t *); typedef void (*client_message_handler_t)(); static client_message_handler_t client_message_handler = NULL; void wm_set_client_message_handler(client_message_handler_t handler) { client_message_handler = handler; } static void ev_client_message(xcb_generic_event_t *generic_ev) { if (client_message_handler) { xcb_client_message_event_t *ev = (xcb_client_message_event_t *) generic_ev; client_message_handler(); } } bool wm_init() { memset(events, 0, sizeof(events)); events[XCB_CONFIGURE_REQUEST] = ev_configure_request; events[XCB_DESTROY_NOTIFY] = ev_destroy_notify; events[XCB_ENTER_NOTIFY] = ev_enter_notify; events[XCB_KEY_PRESS] = ev_key_press; events[XCB_MAP_REQUEST] = ev_map_request; events[XCB_UNMAP_NOTIFY] = ev_unmap_notify; events[XCB_MAPPING_NOTIFY] = ev_mapping_notify; events[XCB_CONFIGURE_NOTIFY] = ev_configure_notify; events[XCB_CIRCULATE_REQUEST] = ev_circulate_request; events[XCB_BUTTON_PRESS] = ev_button_press; events[XCB_CLIENT_MESSAGE] = ev_client_message; return true; } void wm_destroy(); void wm_run() { /* while (wm.is_running) { xcb_generic_event_t *ev = xcb_wait_for_event(display_server.conn); int ev_type = ev->response_type & 0x80; generic_event_handler_t handler = wm.events[ev_type]; if (handler) { handler(ev); } free(ev); } wm_destroy(); */ } void wm_quit() { if (configure_notify_handler) { // xcb_configure_notify_event_t ev; // ev.x = 0; // ev.y = 1; // ev.width = 2; // ev.height = 3; configure_notify_handler(0, 1, 2, 3); } }