summaryrefslogtreecommitdiff
path: root/schewm.c
diff options
context:
space:
mode:
Diffstat (limited to 'schewm.c')
-rw-r--r--schewm.c241
1 files changed, 239 insertions, 2 deletions
diff --git a/schewm.c b/schewm.c
index 72f89bf..53919bd 100644
--- a/schewm.c
+++ b/schewm.c
@@ -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);
+ }
}