diff options
author | Samuel Fadel <samuel@nihil.ws> | 2022-12-02 16:14:26 +0100 |
---|---|---|
committer | Samuel Fadel <samuel@nihil.ws> | 2022-12-02 16:14:26 +0100 |
commit | 21ebd4dda267d09c60d8b646782aed28138c5690 (patch) | |
tree | a07d2103c745e382160a344263790235e3ec0c68 | |
parent | 7aa66702b2b9396add0cc20849ec89a48495c7ff (diff) |
Proof-of-concept event handling. See NOTE.
-rw-r--r-- | main.scm | 6 | ||||
-rw-r--r-- | schewm.c | 241 | ||||
-rw-r--r-- | wm.scm | 30 |
3 files changed, 265 insertions, 12 deletions
@@ -1,4 +1,8 @@ (use-modules (wm)) (when (wm-init) - (wm-quit "hello")) + (wm-set-configure-notify-handler! + (lambda (x y w h) + (display (+ x y w h)) + (display "\n"))) + (wm-quit)) @@ -1,11 +1,248 @@ #include <stdio.h> #include <stdbool.h> #include <stdlib.h> +#include <string.h> + +#include <xcb/randr.h> +#include <xcb/xcb_ewmh.h> +#include <xcb/xcb_keysyms.h> +#include <X11/keysym.h> + +/* + * 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_quit(const char *m) { - printf("hello, %s\n", m); +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); + } } @@ -1,6 +1,8 @@ (define-module (wm) #:use-module (system foreign) - #:export (wm-init wm-quit)) + #:export (wm-init + wm-set-configure-notify-handler! + wm-quit)) (define libschewm (dynamic-link "libschewm")) @@ -13,12 +15,22 @@ (dynamic-func name libschewm) args)) +(define c/wm-init + (schewm-func int "wm_init" '())) + (define (wm-init) - (let ((c/wm-init - (schewm-func int "wm_init" '()))) - (int-as-bool (c/wm-init)))) - -(define (wm-quit s) - (let ((c/wm-quit - (schewm-func void "wm_quit" (list '*)))) - (c/wm-quit (string->pointer s)))) + (int-as-bool (c/wm-init))) + +(define wm-quit + (schewm-func void "wm_quit" '())) + +(define c/wm-set-configure-notify-handler + (schewm-func void + "wm_set_configure_notify_handler" + (list '*))) + +(define (wm-set-configure-notify-handler! handler) + (c/wm-set-configure-notify-handler + (procedure->pointer void + handler + (list int16 int16 uint32 uint32)))) |