summaryrefslogtreecommitdiff
path: root/src/common/input.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-13 15:41:39 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-13 15:41:39 +0300
commit537b2d768b31deb0f95c5122e0d562e4406ae9a0 (patch)
treecc3e85cb2990672c11b4e35c6dbcfaac733d09f5 /src/common/input.c
parent98f0d51157fa2a2b8ccaae54ed4850a88d223d01 (diff)
Unify core and runner events into struct yasl_event
The core input queue and the yasl_run() runner each had their own event type, and the runner translated one into the other. Both now share struct yasl_event in <yasl/yasl.h>: yasl_surface_poll_event() returns the same events the app event callback receives, so the runner forwards them unchanged. Pointer input becomes POINTER_DOWN/UP/MOTION/SCROLL/LEAVE with a named yasl_pointer_button and a motion delta computed in the input queue. TEXT, PASTE and DROP share one text payload, scale changes fold into WINDOW_RESIZE, and every event carries a monotonic time_ns. yasl_surface_set_mouse_mode() is replaced by yasl_surface_set_pointer_mode(); no backend implements relative mode yet. The export check now only counts YASL_API declarations, so function pointer fields returning enum yasl_app_result are not mistaken for exports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/common/input.c')
-rw-r--r--src/common/input.c80
1 files changed, 43 insertions, 37 deletions
diff --git a/src/common/input.c b/src/common/input.c
index 471cd2b..0b55f1f 100644
--- a/src/common/input.c
+++ b/src/common/input.c
@@ -1,57 +1,64 @@
#include "input.h"
+#include "yasl/loop.h"
#include <stdlib.h>
#include <string.h>
-static const char *event_text(const struct yasl_input_event *ev, size_t *len)
+static bool has_text(const struct yasl_event *ev)
{
- switch (ev->kind) {
- case YASL_INPUT_TEXT: *len = ev->text.len; return ev->text.text;
- case YASL_INPUT_PASTE: *len = ev->paste.len; return ev->paste.text;
- case YASL_INPUT_DROP_FILES: *len = ev->drop_files.len; return ev->drop_files.files;
- default: *len = 0; return NULL;
- }
-}
-
-static void set_text(struct yasl_input_event *ev, const char *text)
-{
- switch (ev->kind) {
- case YASL_INPUT_TEXT: ev->text.text = text; break;
- case YASL_INPUT_PASTE: ev->paste.text = text; break;
- case YASL_INPUT_DROP_FILES: ev->drop_files.files = text; break;
- default: break;
- }
+ return ev->type == YASL_EVENT_TEXT || ev->type == YASL_EVENT_PASTE ||
+ ev->type == YASL_EVENT_DROP;
}
static void discard_pending(struct input_queue *q)
{
for (size_t i = 0; i < q->count; i++) {
- size_t len;
- free((void *)event_text(&q->events[(q->head + i) % q->capacity], &len));
+ struct yasl_event *ev = &q->events[(q->head + i) & (q->capacity - 1)];
+ if (has_text(ev)) free((void *)ev->text.data);
}
q->head = q->count = 0;
}
-bool input_queue_push(struct input_queue *q, const struct yasl_input_event *ev)
+bool input_queue_push(struct input_queue *q, const struct yasl_event *ev)
{
- struct yasl_input_event copy = *ev;
+ struct yasl_event copy = *ev;
char *owned = NULL;
- if (ev->kind == YASL_INPUT_TEXT || ev->kind == YASL_INPUT_PASTE ||
- ev->kind == YASL_INPUT_DROP_FILES) {
- size_t len;
- const char *text = event_text(ev, &len);
- if ((!text && len) || len == SIZE_MAX) goto failed;
+ if (!copy.time_ns) copy.time_ns = yasl_loop_now_ns();
+ if (has_text(ev)) {
+ size_t len = ev->text.len;
+ if ((!ev->text.data && len) || len == SIZE_MAX) goto failed;
owned = malloc(len + 1);
if (!owned) goto failed;
- if (len) memcpy(owned, text, len);
+ if (len) memcpy(owned, ev->text.data, len);
owned[len] = '\0';
- set_text(&copy, owned);
+ copy.text.data = owned;
+ }
+ switch (ev->type) {
+ case YASL_EVENT_POINTER_MOTION:
+ if (!q->relative) {
+ copy.pointer.delta = q->has_last_pos
+ ? (struct yasl_vector2d){ev->pointer.pos.x - q->last_pos.x,
+ ev->pointer.pos.y - q->last_pos.y}
+ : (struct yasl_vector2d){0, 0};
+ }
+ [[fallthrough]];
+ case YASL_EVENT_POINTER_DOWN:
+ case YASL_EVENT_POINTER_UP:
+ q->last_pos = ev->pointer.pos;
+ q->has_last_pos = true;
+ break;
+ case YASL_EVENT_POINTER_LEAVE:
+ case YASL_EVENT_INPUT_RESET:
+ q->has_last_pos = false;
+ break;
+ default:
+ break;
}
if (q->count == q->capacity) {
size_t capacity = q->capacity ? q->capacity * 2 : 32;
if (capacity < q->capacity || capacity > SIZE_MAX / sizeof(*q->events))
goto failed;
- struct yasl_input_event *events = malloc(capacity * sizeof(*events));
+ struct yasl_event *events = malloc(capacity * sizeof(*events));
if (!events) goto failed;
if (q->events && q->count > 0) {
size_t first = q->capacity - q->head;
@@ -76,10 +83,11 @@ failed:
discard_pending(q);
q->reset_surface = ev->surface;
q->reset_pending = true;
+ q->has_last_pos = false;
return false;
}
-bool input_queue_pop(struct input_queue *q, struct yasl_input_event *ev)
+bool input_queue_pop(struct input_queue *q, struct yasl_event *ev)
{
if (!ev || (!q->count && !q->reset_pending)) return false;
if (q->last_text) {
@@ -87,18 +95,16 @@ bool input_queue_pop(struct input_queue *q, struct yasl_input_event *ev)
q->last_text = NULL;
}
if (q->reset_pending) {
- *ev = (struct yasl_input_event){
- .surface = q->reset_surface, .kind = YASL_INPUT_RESET,
+ *ev = (struct yasl_event){
+ .type = YASL_EVENT_INPUT_RESET, .surface = q->reset_surface,
+ .time_ns = yasl_loop_now_ns(),
};
q->reset_pending = false;
return true;
}
*ev = q->events[q->head];
- if (ev->kind == YASL_INPUT_TEXT || ev->kind == YASL_INPUT_PASTE ||
- ev->kind == YASL_INPUT_DROP_FILES) {
- size_t len;
- q->last_text = (char *)event_text(ev, &len);
- }
+ if (has_text(ev))
+ q->last_text = (char *)ev->text.data;
q->head = (q->head + 1) & (q->capacity - 1);
q->count--;
return true;