diff options
| author | Federico Angelilli <code@fedang.net> | 2024-07-09 17:02:42 +0200 |
|---|---|---|
| committer | Federico Angelilli <code@fedang.net> | 2024-07-09 17:02:42 +0200 |
| commit | 0c567c67933cc48ac57f08167d88a57ce0504524 (patch) | |
| tree | da7c5ccc0935093cf5ecc661371db324ea0005cb /src/event.c | |
| parent | 28adc6b395d2fb7545189636cec3651b9c2a5f73 (diff) | |
Add event handling
Diffstat (limited to 'src/event.c')
| -rw-r--r-- | src/event.c | 136 |
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); + } +} |
