aboutsummaryrefslogtreecommitdiff
path: root/src/event.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-07-09 17:02:42 +0200
committerFederico Angelilli <code@fedang.net>2024-07-09 17:02:42 +0200
commit0c567c67933cc48ac57f08167d88a57ce0504524 (patch)
treeda7c5ccc0935093cf5ecc661371db324ea0005cb /src/event.c
parent28adc6b395d2fb7545189636cec3651b9c2a5f73 (diff)
Add event handling
Diffstat (limited to 'src/event.c')
-rw-r--r--src/event.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..1c16c49
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,136 @@
+#include "util.h"
+#include "layout.h"
+#include "event.h"
+#include "any_log.h"
+
+bool event_dispatch_block(layout_t *layout, event_t event)
+{
+ int width = layout->width - 2 * layout->x_padding;
+ int height = layout->height - 2 * layout->y_padding;
+
+ if (!in_capsule(event.x, event.y, layout->x, layout->y, width, height))
+ return false;
+
+ for (int i = 0; i < layout->n_children; i++) {
+ if (event_dispatch_block(layout->children[i], event))
+ return true;
+ }
+
+ log_value_debug("Dispatching event to block",
+ "i:event_x", event.x,
+ "i:event_y", event.y,
+ "i:x", layout->x,
+ "i:y", layout->y,
+ "i:width", layout->width,
+ "i:height", layout->height);
+
+ if (layout->block->event_cb != NULL) {
+ layout->block->event_cb(layout->block, event);
+ log_debug("Called event callback");
+ }
+
+ return true;
+}
+
+void event_dispatch(display_t *display, layout_t *layout)
+{
+ xcb_generic_event_t *xevent;
+
+ while ((xevent = xcb_poll_for_event(display->connection)) != NULL) {
+ int type = xevent->response_type & ~0x80;
+ switch (type) {
+ case 0: {
+ xcb_generic_error_t *error = (xcb_generic_error_t *)xevent;
+
+ const char *extension;
+ const char *name = xcb_errors_get_name_for_error(display->errors, error->error_code, &extension);
+ const char *major = xcb_errors_get_name_for_major_code(display->errors, error->major_code);
+ const char *minor = xcb_errors_get_name_for_minor_code(display->errors, error->major_code, error->minor_code);
+
+ log_value_error("Xcb error",
+ "s:name", name,
+ "s:extension", extension ? extension : "none",
+ "s:major", major,
+ "s:minor", minor ? minor : "none"
+ "u:resource", (unsigned int)error->resource_id,
+ "u:sequence", (unsigned int)error->sequence);
+
+ // TODO: Handle errors instead of aborting
+ abort();
+ break;
+ }
+
+ case XCB_EXPOSE: {
+ xcb_expose_event_t *expose = (xcb_expose_event_t *)xevent;
+ log_trace("Processing 'Expose' event");
+
+ // Redraw
+ break;
+ }
+
+ case XCB_CREATE_NOTIFY: {
+ xcb_create_notify_event_t *create = (xcb_create_notify_event_t *)xevent;
+ log_trace("Processing 'CreateNotify' event");
+
+ // TODO: Circulate top the window if override_redirect == 0
+ break;
+ }
+
+ case XCB_BUTTON_RELEASE: {
+ xcb_button_release_event_t *button = (xcb_button_release_event_t *)xevent;
+ log_trace("Processing 'ButtonRelease' event");
+
+ event_t event = {
+ .x = button->event_x,
+ .y = button->event_y,
+ };
+
+ switch (button->detail) {
+ case XCB_BUTTON_INDEX_1:
+ event.type = EVENT_RIGHT_CLICK;
+ event_dispatch_block(layout, event);
+ break;
+
+ case XCB_BUTTON_INDEX_2:
+ event.type = EVENT_LEFT_CLICK;
+ event_dispatch_block(layout, event);
+ break;
+
+ case XCB_BUTTON_INDEX_3:
+ event.type = EVENT_MIDDLE_CLICK;
+ event_dispatch_block(layout, event);
+ break;
+
+ default:
+ log_debug("Ignoring button release", button->detail);
+ break;
+ }
+ break;
+ }
+
+ case XCB_PROPERTY_NOTIFY: {
+ xcb_property_notify_event_t *property = (xcb_property_notify_event_t *)xevent;
+ log_trace("Processing 'PropertyNotify' event");
+
+ if (property->atom == XCB_ATOM_RESOURCE_MANAGER) {
+ display_update_xrm(display);
+ display_update_scale(display);
+ // Redraw
+ }
+ break;
+ }
+
+ default: {
+ const char *extension;
+ const char *name = xcb_errors_get_name_for_xcb_event(display->errors, xevent, &extension);
+
+ log_value_debug("Ignoring Xcb event",
+ "s:name", name,
+ "u:type", xevent->response_type & 0x7f,
+ "s:extension", extension ? extension : "none");
+ break;
+ }
+ }
+ free(xevent);
+ }
+}