diff options
Diffstat (limited to 'src/common/events.c')
| -rw-r--r-- | src/common/events.c | 196 |
1 files changed, 99 insertions, 97 deletions
diff --git a/src/common/events.c b/src/common/events.c index a9bbcaf..ba78d77 100644 --- a/src/common/events.c +++ b/src/common/events.c @@ -6,15 +6,15 @@ #include <string.h> struct event_node { - struct yasl_event event; + struct yasl_private_event event; uint64_t queue_id; char *text; void (*release)(void *); struct event_node *next; }; -struct yasl_event_state { - yasl_mutex mutex; +struct yasl_private_event_state { + yasl_private_mutex mutex; struct event_node *head, *tail, *last; uint64_t sequence, identity, request; int error; @@ -37,67 +37,67 @@ static void dispose_list(struct event_node *nodes) } } -bool yasl_events_open(struct yasl_display *d) +bool yasl_private_events_open(struct yasl_private_display *d) { - struct yasl_event_state *state = calloc(1, sizeof(*state)); + struct yasl_private_event_state *state = calloc(1, sizeof(*state)); if (!state) { errno = ENOMEM; return false; } - int error = yasl_mutex_init(&state->mutex); + int error = yasl_private_mutex_init(&state->mutex); if (error) { free(state); errno = error; return false; } d->events = state; return true; } -void yasl_events_close(struct yasl_display *d) +void yasl_private_events_close(struct yasl_private_display *d) { - struct yasl_event_state *state = d->events; + struct yasl_private_event_state *state = d->events; if (!state) return; /* Producers must already have stopped. Detach before callbacks so cleanup * can make harmless failed posts without touching a dying queue. */ d->events = NULL; dispose_list(state->head); dispose(state->last); - yasl_mutex_destroy(&state->mutex); + yasl_private_mutex_destroy(&state->mutex); free(state); } -int yasl_events_error(struct yasl_display *d) +int yasl_private_events_error(struct yasl_private_display *d) { if (!d->events) return 0; - yasl_mutex_lock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); int error = d->events->error; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); return error; } -bool yasl_events_pending(struct yasl_display *d) +bool yasl_private_events_pending(struct yasl_private_display *d) { if (!d->events) return false; - yasl_mutex_lock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); bool pending = d->events->head != NULL; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); return pending; } -struct yasl_surface *yasl_events_find(struct yasl_display *d, uint64_t id) +struct yasl_surface *yasl_private_events_find(struct yasl_private_display *d, uint64_t id) { for (struct yasl_surface *s = d->surfaces; s; s = s->event_next) if (s->id == id) return s; return NULL; } -static bool publish_input(const struct yasl_event *event, void *ud) +static bool publish_input(const struct yasl_private_event *event, void *ud) { struct yasl_surface *owner = ud; - return yasl_events_push(owner->display, owner, event); + return yasl_private_events_push(owner->display, owner, event); } -bool yasl_events_register(struct yasl_surface *s) +bool yasl_private_events_register(struct yasl_surface *s) { - struct yasl_display *d = s->display; + struct yasl_private_display *d = s->display; if (!d->events) return true; /* Internal test doubles need no queue. */ - yasl_mutex_lock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); if (d->events->identity == UINT64_MAX) { - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); errno = EOVERFLOW; return false; } @@ -105,26 +105,26 @@ bool yasl_events_register(struct yasl_surface *s) s->id = ++d->events->identity; s->event_next = d->surfaces; d->surfaces = s; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); struct input_queue *q = d->ops->surface_input_queue ? d->ops->surface_input_queue(s) : &s->input; if (q) { /* Preserve input generated during native creation. */ - struct yasl_event event; + struct yasl_private_event event; while (input_queue_pop(q, &event)) - yasl_events_push(d, s, &event); + yasl_private_events_push(d, s, &event); q->publish = publish_input; q->publish_ud = s; } return true; } -void yasl_events_unregister(struct yasl_surface *s) +void yasl_private_events_unregister(struct yasl_surface *s) { - struct yasl_display *d = s->display; + struct yasl_private_display *d = s->display; if (!d->events) return; struct event_node *discarded = NULL; - yasl_mutex_lock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); struct yasl_surface **surface = &d->surfaces; while (*surface && *surface != s) surface = &(*surface)->event_next; if (*surface) *surface = s->event_next; @@ -142,30 +142,30 @@ void yasl_events_unregister(struct yasl_surface *s) } } s->event_next = NULL; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); dispose_list(discarded); } -static bool append(struct yasl_display *d, struct event_node *node) +static bool append(struct yasl_private_display *d, struct event_node *node) { - struct yasl_event_state *state = d->events; + struct yasl_private_event_state *state = d->events; if (state->sequence == UINT64_MAX) { errno = EOVERFLOW; return false; } node->event.sequence = ++state->sequence; - if (!node->event.time_ns) node->event.time_ns = yasl_loop_now_ns(); + if (!node->event.time_ns) node->event.time_ns = yasl_private_loop_now_ns(); if (state->tail) state->tail->next = node; else state->head = node; state->tail = node; return true; } -static bool string_event(enum yasl_event_type type) +static bool string_event(enum yasl_private_event_type type) { - return type == YASL_EVENT_TEXT || type == YASL_EVENT_PASTE || - type == YASL_EVENT_DROP || type == YASL_EVENT_COMPOSITION; + return type == YASL_PRIVATE_EVENT_TEXT || type == YASL_PRIVATE_EVENT_PASTE || + type == YASL_PRIVATE_EVENT_DROP || type == YASL_PRIVATE_EVENT_COMPOSITION || type == YASL_PRIVATE_EVENT_TEXT_EDIT; } -bool yasl_events_push(struct yasl_display *d, struct yasl_surface *queue_owner, - const struct yasl_event *event) +bool yasl_private_events_push(struct yasl_private_display *d, struct yasl_surface *queue_owner, + const struct yasl_private_event *event) { if (!d || !d->events || (event->surface && !event->surface->id)) return true; struct event_node *node = calloc(1, sizeof(*node)); @@ -182,56 +182,57 @@ bool yasl_events_push(struct yasl_display *d, struct yasl_surface *queue_owner, if (!node->text) { free(node); goto failed; } if (event->text.len) memcpy(node->text, event->text.data, event->text.len); node->text[event->text.len] = '\0'; - if (event->type == YASL_EVENT_PASTE) node->event.paste.data = node->text; - else if (event->type == YASL_EVENT_COMPOSITION) node->event.composition.data = node->text; + if (event->type == YASL_PRIVATE_EVENT_PASTE) node->event.paste.data = node->text; + else if (event->type == YASL_PRIVATE_EVENT_TEXT_EDIT) node->event.text_edit.data = node->text; + else if (event->type == YASL_PRIVATE_EVENT_COMPOSITION) node->event.composition.data = node->text; else node->event.text.data = node->text; } - yasl_mutex_lock(&d->events->mutex); - if ((node->event.surface_id && !yasl_events_find(d, node->event.surface_id)) || - (node->queue_id && !yasl_events_find(d, node->queue_id))) { - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); + if ((node->event.surface_id && !yasl_private_events_find(d, node->event.surface_id)) || + (node->queue_id && !yasl_private_events_find(d, node->queue_id))) { + yasl_private_mutex_unlock(&d->events->mutex); dispose(node); return true; /* A native teardown notification for a canceled recipient. */ } bool ok = append(d, node); if (!ok) d->events->error = errno; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); if (!ok) dispose(node); return ok; failed: - yasl_mutex_lock(&d->events->mutex); + yasl_private_mutex_lock(&d->events->mutex); d->events->error = ENOMEM; - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); errno = ENOMEM; return false; } -bool yasl_display_post(struct yasl_display *d, const struct yasl_message *message) +bool yasl_private_display_post(struct yasl_private_display *d, const struct yasl_private_message *message) { if (!d || !d->events || !message) { errno = EINVAL; return false; } struct event_node *node = calloc(1, sizeof(*node)); if (!node) { errno = ENOMEM; return false; } - node->event = (struct yasl_event){ - .type = YASL_EVENT_USER, .surface_id = message->target_id, + node->event = (struct yasl_private_event){ + .type = YASL_PRIVATE_EVENT_USER, .surface_id = message->target_id, .user = {.code = message->code, .payload = message->payload, .size = message->size}, }; node->queue_id = message->target_id; node->release = message->release; - yasl_mutex_lock(&d->events->mutex); - bool ok = !message->target_id || yasl_events_find(d, message->target_id); + yasl_private_mutex_lock(&d->events->mutex); + bool ok = !message->target_id || yasl_private_events_find(d, message->target_id); if (!ok) errno = ENOENT; else ok = append(d, node); - yasl_mutex_unlock(&d->events->mutex); + yasl_private_mutex_unlock(&d->events->mutex); if (!ok) { free(node); return false; } - if (d->loop) yasl_loop_kick(d->loop); + if (d->loop) yasl_private_loop_kick(d->loop); return true; } -static bool poll_event(struct yasl_display *d, uint64_t queue_id, struct yasl_event *event) +static bool poll_event(struct yasl_private_display *d, uint64_t queue_id, struct yasl_private_event *event) { if (!d || !d->events || !event) return false; - struct yasl_event_state *state = d->events; - yasl_mutex_lock(&state->mutex); + struct yasl_private_event_state *state = d->events; + yasl_private_mutex_lock(&state->mutex); struct event_node *discarded = NULL; struct event_node **entry = &state->head; struct event_node *previous = NULL; @@ -241,8 +242,8 @@ static bool poll_event(struct yasl_display *d, uint64_t queue_id, struct yasl_ev * Mixing this adapter with display polling is deliberately unsupported. */ while (*entry) { struct event_node *candidate = *entry; - if (candidate->event.type < YASL_EVENT_KEY || - candidate->event.type > YASL_EVENT_INPUT_RESET) { + if (candidate->event.type < YASL_PRIVATE_EVENT_KEY || + candidate->event.type > YASL_PRIVATE_EVENT_INPUT_RESET) { *entry = candidate->next; if (state->tail == candidate) state->tail = previous; candidate->next = discarded; @@ -261,7 +262,7 @@ static bool poll_event(struct yasl_display *d, uint64_t queue_id, struct yasl_ev } struct event_node *node = *entry; if (!node) { - yasl_mutex_unlock(&state->mutex); + yasl_private_mutex_unlock(&state->mutex); dispose_list(discarded); return false; } @@ -269,104 +270,105 @@ static bool poll_event(struct yasl_display *d, uint64_t queue_id, struct yasl_ev if (state->tail == node) state->tail = previous; node->next = NULL; if (node->event.surface_id) - node->event.surface = yasl_events_find(d, node->event.surface_id); + node->event.surface = yasl_private_events_find(d, node->event.surface_id); struct event_node *last = state->last; state->last = node; *event = node->event; - yasl_mutex_unlock(&state->mutex); + yasl_private_mutex_unlock(&state->mutex); dispose(last); dispose_list(discarded); return true; } -bool yasl_display_poll_event(struct yasl_display *d, struct yasl_event *event) +bool yasl_private_display_poll_event(struct yasl_private_display *d, struct yasl_private_event *event) { return poll_event(d, 0, event); } -bool yasl_events_poll_surface(struct yasl_surface *s, struct yasl_event *event) +bool yasl_private_events_poll_surface(struct yasl_surface *s, struct yasl_private_event *event) { return s && s->id ? poll_event(s->display, s->id, event) : false; } -uint64_t yasl_events_request_id(struct yasl_display *d) +uint64_t yasl_private_events_request_id(struct yasl_private_display *d) { if (!d->events || d->events->request == UINT64_MAX) { errno = EOVERFLOW; return 0; } return ++d->events->request; } -uint64_t yasl_surface_id(const struct yasl_surface *s) { return s ? s->id : 0; } -void yasl_surface_set_userdata(struct yasl_surface *s, void *ud) { if (s) s->userdata = ud; } -void *yasl_surface_userdata(const struct yasl_surface *s) { return s ? s->userdata : NULL; } +uint64_t yasl_private_surface_id(const struct yasl_surface *s) { return s ? s->id : 0; } +void yasl_private_surface_set_userdata(struct yasl_surface *s, void *ud) { if (s) s->userdata = ud; } +void *yasl_private_surface_userdata(const struct yasl_surface *s) { return s ? s->userdata : NULL; } -void yasl_surface_notify_configure(struct yasl_surface *s, struct yasl_geometry geometry) +void yasl_private_surface_notify_configure(struct yasl_surface *s, struct yasl_private_geometry geometry) { uint32_t previous_scale = s->reported_scale; s->reported_scale = geometry.scale_120; s->size = geometry.size; s->scale_120 = geometry.scale_120; - struct yasl_event event = {.type = YASL_EVENT_WINDOW_RESIZE, .surface = s, + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_WINDOW_RESIZE, .surface = s, .resize = {.geometry = geometry, .scale_changed = previous_scale != geometry.scale_120}}; - yasl_events_push(s->display, s, &event); - if (s->display) yasl_surface_request_frame(s); + yasl_private_events_push(s->display, s, &event); + if (s->display) yasl_private_surface_request_frame(s); if (s->callbacks.configure) s->callbacks.configure(s, geometry, s->ud); } -void yasl_surface_notify_close(struct yasl_surface *s) +void yasl_private_surface_notify_close(struct yasl_surface *s) { - struct yasl_event event = {.type = YASL_EVENT_WINDOW_CLOSE, .surface = s}; - yasl_events_push(s->display, s, &event); + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_WINDOW_CLOSE, .surface = s}; + yasl_private_events_push(s->display, s, &event); if (s->callbacks.close) s->callbacks.close(s, s->ud); } -void yasl_surface_notify_state(struct yasl_surface *s, uint32_t flags) +void yasl_private_surface_notify_state(struct yasl_surface *s, uint32_t flags) { s->state = flags; - struct yasl_event event = {.type = YASL_EVENT_WINDOW_STATE, .surface = s, .state.flags = flags}; - yasl_events_push(s->display, s, &event); + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_WINDOW_STATE, .surface = s, .state.flags = flags}; + yasl_private_events_push(s->display, s, &event); if (s->callbacks.state) s->callbacks.state(s, flags, s->ud); } -void yasl_surface_notify_drag(struct yasl_surface *s, enum yasl_drag_event action, struct yasl_vector2i pos) +void yasl_private_surface_notify_drag(struct yasl_surface *s, enum yasl_private_drag_event action, struct yasl_private_vector2i pos) { - struct yasl_event event = {.type = YASL_EVENT_DRAG, .surface = s, .drag = {action, pos}}; - yasl_events_push(s->display, s, &event); + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_DRAG, .surface = s, .drag = {action, pos}}; + yasl_private_events_push(s->display, s, &event); if (s->callbacks.drag) s->callbacks.drag(s, action, pos, s->ud); } -void yasl_surface_notify_drop(struct yasl_surface *s, enum yasl_drop_event action, struct yasl_vector2i pos) +void yasl_private_surface_notify_drop(struct yasl_surface *s, enum yasl_private_drop_event action, struct yasl_private_vector2i pos) { - struct yasl_event event = {.type = YASL_EVENT_DROP_HOVER, .surface = s, .drop = {action, pos}}; - yasl_events_push(s->display, s, &event); + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_DROP_HOVER, .surface = s, .drop = {action, pos}}; + yasl_private_events_push(s->display, s, &event); if (s->callbacks.drop) s->callbacks.drop(s, action, pos, s->ud); } -void yasl_surface_notify_composition(struct yasl_surface *s, const char *text, int begin, int end) +void yasl_private_surface_notify_composition(struct yasl_surface *s, const char *text, int begin, int end) { - struct yasl_event event = {.type = YASL_EVENT_COMPOSITION, .surface = s, + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_COMPOSITION, .surface = s, .composition = {.data = text ? text : "", .len = text ? strlen(text) : 0, - .begin = begin, .end = end, .active = text && text[0]}}; - yasl_events_push(s->display, s, &event); + .begin = begin, .end = end, .active = text && text[0], + .revision = s->text_revision, .generation = s->text_generation}}; + yasl_private_events_push(s->display, s, &event); } -void yasl_surface_complete_paste(struct yasl_surface *s, uint64_t id, - enum yasl_transfer_status status, const char *text, size_t len) +void yasl_private_surface_complete_paste(struct yasl_surface *s, uint64_t id, + enum yasl_private_transfer_status status, const char *text, size_t len) { - struct yasl_event event = {.type = YASL_EVENT_PASTE, .surface = s, + struct yasl_private_event event = {.type = YASL_PRIVATE_EVENT_PASTE, .surface = s, .paste = {.data = text ? text : "", .len = text ? len : 0, .request_id = id, .status = status}}; if (!s->display->events) { struct input_queue *q = s->display->ops->surface_input_queue ? s->display->ops->surface_input_queue(s) : &s->input; input_queue_push(q, &event); - } else yasl_events_push(s->display, s, &event); + } else yasl_private_events_push(s->display, s, &event); } -void yasl_display_notify_event(struct yasl_display *d, enum yasl_event_type type) +void yasl_private_display_notify_event(struct yasl_private_display *d, enum yasl_private_event_type type) { - struct yasl_event event = {.type = type}; - yasl_events_push(d, NULL, &event); - void (*callback)(void *) = type == YASL_EVENT_DISPLAY_QUIT ? d->callbacks.quit - : type == YASL_EVENT_DISPLAY_REOPEN ? d->callbacks.reopen - : type == YASL_EVENT_DISPLAY_LOST ? d->callbacks.lost : NULL; + struct yasl_private_event event = {.type = type}; + yasl_private_events_push(d, NULL, &event); + void (*callback)(void *) = type == YASL_PRIVATE_EVENT_DISPLAY_QUIT ? d->callbacks.quit + : type == YASL_PRIVATE_EVENT_DISPLAY_REOPEN ? d->callbacks.reopen + : type == YASL_PRIVATE_EVENT_DISPLAY_LOST ? d->callbacks.lost : NULL; if (callback) callback(d->callback_ud); } |
