AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Test-owned input on the backend event loop; no product input rule changes. */3
#define _GNU_SOURCE4
#include <dlfcn.h>5
#include <inttypes.h>6
#include <stdbool.h>7
#include <stdio.h>8
#include <stdlib.h>9
#include <time.h>10
#include <unistd.h>11
#include <wayland-server-core.h>12
#include <wlr/backend/headless.h>13
#include <wlr/interfaces/wlr_pointer.h>15
struct pointer_fixture {16
struct wlr_backend *backend;17
struct wl_event_source *timer;18
struct wl_listener destroy;19
struct wlr_pointer pointer;20
bool initialized;21
};22
static const struct wlr_pointer_impl pointer_impl = {.name = "backend-input-test"};24
static int poll_input(void *data) {25
struct pointer_fixture *fixture = data;26
const char *control = getenv("SIGIL_WM_BACKEND_POINTER_CONTROL");27
if (control && unlink(control) == 0) {28
if (!fixture->initialized) {29
wlr_pointer_init(&fixture->pointer, &pointer_impl, "Backend input test");30
fixture->initialized = true;31
wl_signal_emit_mutable(&fixture->backend->events.new_input, &fixture->pointer.base);32
}33
uintptr_t tag = (uintptr_t)fixture->pointer.base.data;34
if ((tag & 1) || !(tag >> 1)) abort();35
struct timespec now;36
if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) abort();37
struct wlr_pointer_motion_event event = {38
.pointer = &fixture->pointer,39
.time_msec = (uint32_t)((uint64_t)now.tv_sec * 1000 + now.tv_nsec / 1000000),40
.delta_x = 1, .unaccel_dx = 1,41
};42
wl_signal_emit_mutable(&fixture->pointer.events.motion, &event);43
wl_signal_emit_mutable(&fixture->pointer.events.frame, NULL);44
fprintf(stderr, "BACKEND_POINTER_ACTIVITY=PASS origin=0 device=%" PRIuPTR "\n", tag >> 1);45
fflush(stderr);46
}47
return wl_event_source_timer_update(fixture->timer, 50);48
}50
static void destroy_fixture(struct wl_listener *listener, void *data) {51
(void)data;52
struct pointer_fixture *fixture = wl_container_of(listener, fixture, destroy);53
wl_list_remove(&fixture->destroy.link);54
wl_event_source_remove(fixture->timer);55
if (fixture->initialized) wlr_pointer_finish(&fixture->pointer);56
free(fixture);57
}59
struct wlr_backend *wlr_headless_backend_create(struct wl_event_loop *loop) {60
typedef struct wlr_backend *(*create_fn)(struct wl_event_loop *);61
create_fn create = (create_fn)dlsym(RTLD_NEXT, "wlr_headless_backend_create");62
if (!create) abort();63
struct wlr_backend *backend = create(loop);64
if (!backend || !getenv("SIGIL_WM_BACKEND_POINTER_CONTROL")) return backend;65
struct pointer_fixture *fixture = calloc(1, sizeof(*fixture));66
if (!fixture) abort();67
fixture->backend = backend;68
fixture->destroy.notify = destroy_fixture;69
wl_signal_add(&backend->events.destroy, &fixture->destroy);70
fixture->timer = wl_event_loop_add_timer(loop, poll_input, fixture);71
if (!fixture->timer || wl_event_source_timer_update(fixture->timer, 50) != 0) abort();72
return backend;73
}