summaryrefslogtreecommitdiff
path: root/source/base/base_platform_linux_wayland_input.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/base/base_platform_linux_wayland_input.cpp')
-rw-r--r--source/base/base_platform_linux_wayland_input.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/source/base/base_platform_linux_wayland_input.cpp b/source/base/base_platform_linux_wayland_input.cpp
new file mode 100644
index 0000000..0d66fb4
--- /dev/null
+++ b/source/base/base_platform_linux_wayland_input.cpp
@@ -0,0 +1,159 @@
1internal void wayland_keyboard_keymap(void *data, struct wl_keyboard *keyboard, u32 format, s32 fd, u32 size) {
2 Log("<- wl_keyboard.keymap: format=%u fd=%d size=%u\n", format, fd, size);
3 close(fd);
4}
5
6internal void wayland_keyboard_enter(void *data, struct wl_keyboard *keyboard, u32 serial,
7 struct wl_surface *surface, struct wl_array *keys) {
8 WaylandState *state = (WaylandState *)data;
9 Log("<- wl_keyboard.enter\n");
10
11 // wl_array is just { size_t size; size_t alloc; void *data; }. here data is a list of u32.
12 u32 *key = (u32 *)keys->data;
13 u32 key_count = keys->size / sizeof(u32);
14 for (u32 i = 0; i < key_count; ++i) {
15 if (key[i] < sizeof(state->keys_down) / sizeof(state->keys_down[0])) {
16 state->keys_down[key[i]] = true;
17 }
18 }
19}
20
21// leave: we lost focus. after this we will NOT receive release events for keys that
22// are still held, so we release everything ourselves. otherwise keys get "stuck".
23internal void wayland_keyboard_leave(void *data, struct wl_keyboard *keyboard, u32 serial,
24 struct wl_surface *surface) {
25 WaylandState *state = (WaylandState *)data;
26 Log("<- wl_keyboard.leave\n");
27
28 MemSetZero(state->keys_down, sizeof(state->keys_down));
29}
30
31internal void wayland_keyboard_key(void *data, struct wl_keyboard *keyboard, u32 serial,
32 u32 time, u32 key, u32 key_state) {
33 WaylandState *state = (WaylandState *)data;
34 b32 pressed = (key_state == WL_KEYBOARD_KEY_STATE_PRESSED);
35
36 Log("<- wl_keyboard.key: key=%u %s\n", key, pressed ? "pressed" : "released");
37
38 if (key < sizeof(state->keys_down) / sizeof(state->keys_down[0])) {
39 state->keys_down[key] = pressed;
40 }
41
42 if (key == KEY_ESC && pressed) {
43 state->should_close = true;
44 }
45}
46
47internal void wayland_keyboard_modifiers(void *data, struct wl_keyboard *keyboard, u32 serial, u32 mods_depressed, u32 mods_latched,
48 u32 mods_locked, u32 group) {
49}
50
51internal void wayland_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard,
52 s32 rate, s32 delay) {
53 Log("<- wl_keyboard.repeat_info: rate=%d delay=%d\n", rate, delay);
54}
55
56// the listener: a struct of function pointers, one per event, in the order the events
57// are declared in wayland.xml (which is also their opcode). libwayland indexes into this
58// struct with the opcode it reads from the message header.
59global_variable const struct wl_keyboard_listener wayland_keyboard_listener = {
60 wayland_keyboard_keymap, // opcode 0
61 wayland_keyboard_enter, // opcode 1
62 wayland_keyboard_leave, // opcode 2
63 wayland_keyboard_key, // opcode 3
64 wayland_keyboard_modifiers, // opcode 4
65 wayland_keyboard_repeat_info, // opcode 5
66};
67
68//- mouse (pointer) input
69
70enum wayland_mouse_button_pressed: b32 {
71
72PRESSED,
73RELEASED,
74
75};
76
77internal void wayland_button_event(void *data, struct wl_pointer *pointer,
78 u32 serial, u32 time, u32 button, u32 state) {
79
80
81}
82
83
84internal void wayland_pointer_enter(void *data, struct wl_pointer *pointer,
85 u32 serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
86WaylandState *state = (WaylandState *)data;
87Log("<- pointer enteirng window");
88state->mouse_in_window = true;
89state->x_offset = surface_x;
90state->y_offset = surface_y;
91
92
93}
94internal void wayland_pointer_motion(void *data, struct wl_pointer *pointer, u32 time,
95 wl_fixed_t surface_x, wl_fixed_t surface_y) {
96 WaylandState *state = (WaylandState *)data;
97 state->x_offset = (f32)wl_fixed_to_double(surface_x);
98 state->y_offset = (f32)wl_fixed_to_double(surface_y);
99}
100
101internal void wayland_pointer_leave(void *data, struct wl_pointer *pointer, u32 serial, wl_surface *surface) {
102WaylandState *state = (WaylandState *)data;
103state->mouse_in_window = false;
104Log("<- pointer leaving window");
105}
106
107
108
109global_variable const struct wl_pointer_listener wayland_pointer_listener = {
110wayland_pointer_enter,
111wayland_pointer_leave,
112wayland_pointer_motion,
113 wayland_button_event,
114};
115
116
117
118
119
120//- wl_seat events
121
122// capabilities: tells us which devices this seat has, as a bitmask:
123// WL_SEAT_CAPABILITY_POINTER = 1, WL_SEAT_CAPABILITY_KEYBOARD = 2, WL_SEAT_CAPABILITY_TOUCH = 4
124// this can be sent again later (keyboard unplugged / plugged in), so we handle both directions.
125internal void wayland_seat_capabilities(void *data, struct wl_seat *seat, u32 capabilities) {
126
127 WaylandState *state = (WaylandState *)data;
128 b32 has_keyboard = (capabilities & WL_SEAT_CAPABILITY_KEYBOARD) != 0;
129
130
131 Log("<- wl_seat.capabilities: %u\n", capabilities);
132
133 if (has_keyboard && state->keyboard == NULL) {
134 // get_keyboard is a request that creates a new object (a "new_id" argument).
135 // libwayland allocates the id, sends the message, and hands us the proxy.
136 state->keyboard = wl_seat_get_keyboard(seat);
137 wl_keyboard_add_listener(state->keyboard, &wayland_keyboard_listener, state);
138 } else if (!has_keyboard && state->keyboard != NULL) {
139 // keyboard went away: tell the compositor we're done with the object, free the proxy.
140 // the `release` request only exists since wl_seat version 3; before that we can
141 // only free our side of it with destroy.
142 if (wl_keyboard_get_version(state->keyboard) >= WL_KEYBOARD_RELEASE_SINCE_VERSION) {
143 wl_keyboard_release(state->keyboard);
144 } else {
145 wl_keyboard_destroy(state->keyboard);
146 }
147 state->keyboard = NULL;
148 }
149}
150
151// name: a human readable seat name like "seat0". only useful for multi-seat setups.
152internal void wayland_seat_name(void *data, struct wl_seat *seat, const char *name) {
153 Log("<- wl_seat.name: %s\n", name);
154}
155
156global_variable const struct wl_seat_listener wayland_seat_listener = {
157 wayland_seat_capabilities, // opcode 0
158 wayland_seat_name, // opcode 1 (since version 2)
159};