diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-04-02 23:14:37 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-04-04 18:47:48 -0400 |
commit | 1008d4cc9105e18074f8152ec5d6679aef8ebc5f (patch) | |
tree | 7ea62bc43f58f50477f0ee3edb44076944f19d02 /swaylock | |
parent | Set up an XKB context for the keyboard (diff) | |
download | sway-1008d4cc9105e18074f8152ec5d6679aef8ebc5f.tar.gz sway-1008d4cc9105e18074f8152ec5d6679aef8ebc5f.tar.zst sway-1008d4cc9105e18074f8152ec5d6679aef8ebc5f.zip |
Split seat code into its own file
Diffstat (limited to 'swaylock')
-rw-r--r-- | swaylock/main.c | 246 | ||||
-rw-r--r-- | swaylock/meson.build | 6 | ||||
-rw-r--r-- | swaylock/seat.c | 187 |
3 files changed, 194 insertions, 245 deletions
diff --git a/swaylock/main.c b/swaylock/main.c index 555b1d64..7602e47e 100644 --- a/swaylock/main.c +++ b/swaylock/main.c | |||
@@ -8,101 +8,19 @@ | |||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include <sys/mman.h> | ||
12 | #include <sys/stat.h> | 11 | #include <sys/stat.h> |
13 | #include <time.h> | 12 | #include <time.h> |
14 | #include <unistd.h> | 13 | #include <unistd.h> |
15 | #include <wayland-client.h> | 14 | #include <wayland-client.h> |
16 | #include <wlr/util/log.h> | 15 | #include <wlr/util/log.h> |
17 | #include <xkbcommon/xkbcommon.h> | 16 | #include "swaylock/seat.h" |
17 | #include "swaylock/swaylock.h" | ||
18 | #include "background-image.h" | 18 | #include "background-image.h" |
19 | #include "pool-buffer.h" | 19 | #include "pool-buffer.h" |
20 | #include "cairo.h" | 20 | #include "cairo.h" |
21 | #include "util.h" | 21 | #include "util.h" |
22 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 22 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
23 | 23 | ||
24 | struct swaylock_args { | ||
25 | uint32_t color; | ||
26 | enum background_mode mode; | ||
27 | bool show_indicator; | ||
28 | }; | ||
29 | |||
30 | enum mod_bit { | ||
31 | MOD_SHIFT = 1<<0, | ||
32 | MOD_CAPS = 1<<1, | ||
33 | MOD_CTRL = 1<<2, | ||
34 | MOD_ALT = 1<<3, | ||
35 | MOD_MOD2 = 1<<4, | ||
36 | MOD_MOD3 = 1<<5, | ||
37 | MOD_LOGO = 1<<6, | ||
38 | MOD_MOD5 = 1<<7, | ||
39 | }; | ||
40 | |||
41 | enum mask { | ||
42 | MASK_SHIFT, | ||
43 | MASK_CAPS, | ||
44 | MASK_CTRL, | ||
45 | MASK_ALT, | ||
46 | MASK_MOD2, | ||
47 | MASK_MOD3, | ||
48 | MASK_LOGO, | ||
49 | MASK_MOD5, | ||
50 | MASK_LAST | ||
51 | }; | ||
52 | |||
53 | const char *XKB_MASK_NAMES[MASK_LAST] = { | ||
54 | XKB_MOD_NAME_SHIFT, | ||
55 | XKB_MOD_NAME_CAPS, | ||
56 | XKB_MOD_NAME_CTRL, | ||
57 | XKB_MOD_NAME_ALT, | ||
58 | "Mod2", | ||
59 | "Mod3", | ||
60 | XKB_MOD_NAME_LOGO, | ||
61 | "Mod5", | ||
62 | }; | ||
63 | |||
64 | const enum mod_bit XKB_MODS[MASK_LAST] = { | ||
65 | MOD_SHIFT, | ||
66 | MOD_CAPS, | ||
67 | MOD_CTRL, | ||
68 | MOD_ALT, | ||
69 | MOD_MOD2, | ||
70 | MOD_MOD3, | ||
71 | MOD_LOGO, | ||
72 | MOD_MOD5 | ||
73 | }; | ||
74 | |||
75 | struct swaylock_xkb { | ||
76 | uint32_t modifiers; | ||
77 | struct xkb_state *state; | ||
78 | struct xkb_context *context; | ||
79 | struct xkb_keymap *keymap; | ||
80 | xkb_mod_mask_t masks[MASK_LAST]; | ||
81 | }; | ||
82 | |||
83 | struct swaylock_state { | ||
84 | struct wl_display *display; | ||
85 | struct wl_compositor *compositor; | ||
86 | struct zwlr_layer_shell_v1 *layer_shell; | ||
87 | struct wl_shm *shm; | ||
88 | struct wl_list contexts; | ||
89 | struct swaylock_args args; | ||
90 | struct swaylock_xkb xkb; | ||
91 | bool run_display; | ||
92 | }; | ||
93 | |||
94 | struct swaylock_context { | ||
95 | cairo_surface_t *image; | ||
96 | struct swaylock_state *state; | ||
97 | struct wl_output *output; | ||
98 | struct wl_surface *surface; | ||
99 | struct zwlr_layer_surface_v1 *layer_surface; | ||
100 | struct pool_buffer buffers[2]; | ||
101 | struct pool_buffer *current_buffer; | ||
102 | uint32_t width, height; | ||
103 | struct wl_list link; | ||
104 | }; | ||
105 | |||
106 | static void daemonize() { | 24 | static void daemonize() { |
107 | if (fork() == 0) { | 25 | if (fork() == 0) { |
108 | int devnull = open("/dev/null", O_RDWR); | 26 | int devnull = open("/dev/null", O_RDWR); |
@@ -149,169 +67,11 @@ static void layer_surface_closed(void *data, | |||
149 | context->state->run_display = false; | 67 | context->state->run_display = false; |
150 | } | 68 | } |
151 | 69 | ||
152 | static struct zwlr_layer_surface_v1_listener layer_surface_listener = { | 70 | static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { |
153 | .configure = layer_surface_configure, | 71 | .configure = layer_surface_configure, |
154 | .closed = layer_surface_closed, | 72 | .closed = layer_surface_closed, |
155 | }; | 73 | }; |
156 | 74 | ||
157 | static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, | ||
158 | uint32_t format, int32_t fd, uint32_t size) { | ||
159 | struct swaylock_state *state = data; | ||
160 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | ||
161 | close(fd); | ||
162 | wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); | ||
163 | exit(1); | ||
164 | } | ||
165 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||
166 | if (map_shm == MAP_FAILED) { | ||
167 | close(fd); | ||
168 | wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); | ||
169 | exit(1); | ||
170 | } | ||
171 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( | ||
172 | state->xkb.context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, 0); | ||
173 | munmap(map_shm, size); | ||
174 | close(fd); | ||
175 | assert(keymap); | ||
176 | struct xkb_state *xkb_state = xkb_state_new(keymap); | ||
177 | assert(xkb_state); | ||
178 | xkb_keymap_unref(state->xkb.keymap); | ||
179 | xkb_state_unref(state->xkb.state); | ||
180 | state->xkb.keymap = keymap; | ||
181 | state->xkb.state = xkb_state; | ||
182 | } | ||
183 | |||
184 | static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, | ||
185 | uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { | ||
186 | // Who cares | ||
187 | } | ||
188 | |||
189 | static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, | ||
190 | uint32_t serial, struct wl_surface *surface) { | ||
191 | // Who cares | ||
192 | } | ||
193 | |||
194 | static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, | ||
195 | uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) { | ||
196 | struct swaylock_state *state = data; | ||
197 | enum wl_keyboard_key_state key_state = _key_state; | ||
198 | xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb.state, key + 8); | ||
199 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? | ||
200 | key + 8 : 0; | ||
201 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); | ||
202 | wlr_log(L_DEBUG, "%c %d", codepoint, sym); | ||
203 | } | ||
204 | |||
205 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, | ||
206 | uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, | ||
207 | uint32_t mods_locked, uint32_t group) { | ||
208 | struct swaylock_state *state = data; | ||
209 | xkb_state_update_mask(state->xkb.state, | ||
210 | mods_depressed, mods_latched, mods_locked, 0, 0, group); | ||
211 | xkb_mod_mask_t mask = xkb_state_serialize_mods(state->xkb.state, | ||
212 | XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); | ||
213 | state->xkb.modifiers = 0; | ||
214 | for (uint32_t i = 0; i < MASK_LAST; ++i) { | ||
215 | if (mask & state->xkb.masks[i]) { | ||
216 | state->xkb.modifiers |= XKB_MODS[i]; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, | ||
222 | int32_t rate, int32_t delay) { | ||
223 | // TODO | ||
224 | } | ||
225 | |||
226 | static struct wl_keyboard_listener keyboard_listener = { | ||
227 | .keymap = keyboard_keymap, | ||
228 | .enter = keyboard_enter, | ||
229 | .leave = keyboard_leave, | ||
230 | .key = keyboard_key, | ||
231 | .modifiers = keyboard_modifiers, | ||
232 | .repeat_info = keyboard_repeat_info, | ||
233 | }; | ||
234 | |||
235 | static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, | ||
236 | uint32_t serial, struct wl_surface *surface, | ||
237 | wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
238 | wl_pointer_set_cursor(wl_pointer, serial, NULL, 0, 0); | ||
239 | } | ||
240 | |||
241 | static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, | ||
242 | uint32_t serial, struct wl_surface *surface) { | ||
243 | // Who cares | ||
244 | } | ||
245 | |||
246 | static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, | ||
247 | uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
248 | // Who cares | ||
249 | } | ||
250 | |||
251 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | ||
252 | uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { | ||
253 | // Who cares | ||
254 | } | ||
255 | |||
256 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | ||
257 | uint32_t time, uint32_t axis, wl_fixed_t value) { | ||
258 | // Who cares | ||
259 | } | ||
260 | |||
261 | static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { | ||
262 | // Who cares | ||
263 | } | ||
264 | |||
265 | static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, | ||
266 | uint32_t axis_source) { | ||
267 | // Who cares | ||
268 | } | ||
269 | |||
270 | static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, | ||
271 | uint32_t time, uint32_t axis) { | ||
272 | // Who cares | ||
273 | } | ||
274 | |||
275 | static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, | ||
276 | uint32_t axis, int32_t discrete) { | ||
277 | // Who cares | ||
278 | } | ||
279 | |||
280 | static struct wl_pointer_listener pointer_listener = { | ||
281 | .enter = wl_pointer_enter, | ||
282 | .leave = wl_pointer_leave, | ||
283 | .motion = wl_pointer_motion, | ||
284 | .button = wl_pointer_button, | ||
285 | .axis = wl_pointer_axis, | ||
286 | .frame = wl_pointer_frame, | ||
287 | .axis_source = wl_pointer_axis_source, | ||
288 | .axis_stop = wl_pointer_axis_stop, | ||
289 | .axis_discrete = wl_pointer_axis_discrete, | ||
290 | }; | ||
291 | |||
292 | static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||
293 | enum wl_seat_capability caps) { | ||
294 | struct swaylock_state *state = data; | ||
295 | if ((caps & WL_SEAT_CAPABILITY_POINTER)) { | ||
296 | struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); | ||
297 | wl_pointer_add_listener(pointer, &pointer_listener, NULL); | ||
298 | } | ||
299 | if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { | ||
300 | struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); | ||
301 | wl_keyboard_add_listener(keyboard, &keyboard_listener, state); | ||
302 | } | ||
303 | } | ||
304 | |||
305 | static void seat_handle_name(void *data, struct wl_seat *wl_seat, | ||
306 | const char *name) { | ||
307 | // Who cares | ||
308 | } | ||
309 | |||
310 | const struct wl_seat_listener seat_listener = { | ||
311 | .capabilities = seat_handle_capabilities, | ||
312 | .name = seat_handle_name, | ||
313 | }; | ||
314 | |||
315 | static void handle_global(void *data, struct wl_registry *registry, | 75 | static void handle_global(void *data, struct wl_registry *registry, |
316 | uint32_t name, const char *interface, uint32_t version) { | 76 | uint32_t name, const char *interface, uint32_t version) { |
317 | struct swaylock_state *state = data; | 77 | struct swaylock_state *state = data; |
diff --git a/swaylock/meson.build b/swaylock/meson.build index 5b886ded..2f2733f8 100644 --- a/swaylock/meson.build +++ b/swaylock/meson.build | |||
@@ -1,6 +1,8 @@ | |||
1 | executable( | 1 | executable( |
2 | 'swaylock', | 2 | 'swaylock', [ |
3 | 'main.c', | 3 | 'main.c', |
4 | 'seat.c' | ||
5 | ], | ||
4 | include_directories: [sway_inc], | 6 | include_directories: [sway_inc], |
5 | dependencies: [ | 7 | dependencies: [ |
6 | cairo, | 8 | cairo, |
diff --git a/swaylock/seat.c b/swaylock/seat.c new file mode 100644 index 00000000..522200f2 --- /dev/null +++ b/swaylock/seat.c | |||
@@ -0,0 +1,187 @@ | |||
1 | #include <assert.h> | ||
2 | #include <sys/mman.h> | ||
3 | #include <unistd.h> | ||
4 | #include <wlr/util/log.h> | ||
5 | #include <xkbcommon/xkbcommon.h> | ||
6 | #include "swaylock/swaylock.h" | ||
7 | #include "swaylock/seat.h" | ||
8 | |||
9 | const char *XKB_MASK_NAMES[MASK_LAST] = { | ||
10 | XKB_MOD_NAME_SHIFT, | ||
11 | XKB_MOD_NAME_CAPS, | ||
12 | XKB_MOD_NAME_CTRL, | ||
13 | XKB_MOD_NAME_ALT, | ||
14 | "Mod2", | ||
15 | "Mod3", | ||
16 | XKB_MOD_NAME_LOGO, | ||
17 | "Mod5", | ||
18 | }; | ||
19 | |||
20 | const enum mod_bit XKB_MODS[MASK_LAST] = { | ||
21 | MOD_SHIFT, | ||
22 | MOD_CAPS, | ||
23 | MOD_CTRL, | ||
24 | MOD_ALT, | ||
25 | MOD_MOD2, | ||
26 | MOD_MOD3, | ||
27 | MOD_LOGO, | ||
28 | MOD_MOD5 | ||
29 | }; | ||
30 | |||
31 | static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, | ||
32 | uint32_t format, int32_t fd, uint32_t size) { | ||
33 | struct swaylock_state *state = data; | ||
34 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | ||
35 | close(fd); | ||
36 | wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); | ||
37 | exit(1); | ||
38 | } | ||
39 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||
40 | if (map_shm == MAP_FAILED) { | ||
41 | close(fd); | ||
42 | wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); | ||
43 | exit(1); | ||
44 | } | ||
45 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( | ||
46 | state->xkb.context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, 0); | ||
47 | munmap(map_shm, size); | ||
48 | close(fd); | ||
49 | assert(keymap); | ||
50 | struct xkb_state *xkb_state = xkb_state_new(keymap); | ||
51 | assert(xkb_state); | ||
52 | xkb_keymap_unref(state->xkb.keymap); | ||
53 | xkb_state_unref(state->xkb.state); | ||
54 | state->xkb.keymap = keymap; | ||
55 | state->xkb.state = xkb_state; | ||
56 | } | ||
57 | |||
58 | static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, | ||
59 | uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { | ||
60 | // Who cares | ||
61 | } | ||
62 | |||
63 | static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, | ||
64 | uint32_t serial, struct wl_surface *surface) { | ||
65 | // Who cares | ||
66 | } | ||
67 | |||
68 | static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, | ||
69 | uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) { | ||
70 | struct swaylock_state *state = data; | ||
71 | enum wl_keyboard_key_state key_state = _key_state; | ||
72 | xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb.state, key + 8); | ||
73 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? | ||
74 | key + 8 : 0; | ||
75 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); | ||
76 | wlr_log(L_DEBUG, "%c %d", codepoint, sym); | ||
77 | } | ||
78 | |||
79 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, | ||
80 | uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, | ||
81 | uint32_t mods_locked, uint32_t group) { | ||
82 | struct swaylock_state *state = data; | ||
83 | xkb_state_update_mask(state->xkb.state, | ||
84 | mods_depressed, mods_latched, mods_locked, 0, 0, group); | ||
85 | xkb_mod_mask_t mask = xkb_state_serialize_mods(state->xkb.state, | ||
86 | XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); | ||
87 | state->xkb.modifiers = 0; | ||
88 | for (uint32_t i = 0; i < MASK_LAST; ++i) { | ||
89 | if (mask & state->xkb.masks[i]) { | ||
90 | state->xkb.modifiers |= XKB_MODS[i]; | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, | ||
96 | int32_t rate, int32_t delay) { | ||
97 | // TODO | ||
98 | } | ||
99 | |||
100 | static const struct wl_keyboard_listener keyboard_listener = { | ||
101 | .keymap = keyboard_keymap, | ||
102 | .enter = keyboard_enter, | ||
103 | .leave = keyboard_leave, | ||
104 | .key = keyboard_key, | ||
105 | .modifiers = keyboard_modifiers, | ||
106 | .repeat_info = keyboard_repeat_info, | ||
107 | }; | ||
108 | |||
109 | static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, | ||
110 | uint32_t serial, struct wl_surface *surface, | ||
111 | wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
112 | wl_pointer_set_cursor(wl_pointer, serial, NULL, 0, 0); | ||
113 | } | ||
114 | |||
115 | static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, | ||
116 | uint32_t serial, struct wl_surface *surface) { | ||
117 | // Who cares | ||
118 | } | ||
119 | |||
120 | static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, | ||
121 | uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
122 | // Who cares | ||
123 | } | ||
124 | |||
125 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | ||
126 | uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { | ||
127 | // Who cares | ||
128 | } | ||
129 | |||
130 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | ||
131 | uint32_t time, uint32_t axis, wl_fixed_t value) { | ||
132 | // Who cares | ||
133 | } | ||
134 | |||
135 | static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { | ||
136 | // Who cares | ||
137 | } | ||
138 | |||
139 | static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, | ||
140 | uint32_t axis_source) { | ||
141 | // Who cares | ||
142 | } | ||
143 | |||
144 | static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, | ||
145 | uint32_t time, uint32_t axis) { | ||
146 | // Who cares | ||
147 | } | ||
148 | |||
149 | static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, | ||
150 | uint32_t axis, int32_t discrete) { | ||
151 | // Who cares | ||
152 | } | ||
153 | |||
154 | static const struct wl_pointer_listener pointer_listener = { | ||
155 | .enter = wl_pointer_enter, | ||
156 | .leave = wl_pointer_leave, | ||
157 | .motion = wl_pointer_motion, | ||
158 | .button = wl_pointer_button, | ||
159 | .axis = wl_pointer_axis, | ||
160 | .frame = wl_pointer_frame, | ||
161 | .axis_source = wl_pointer_axis_source, | ||
162 | .axis_stop = wl_pointer_axis_stop, | ||
163 | .axis_discrete = wl_pointer_axis_discrete, | ||
164 | }; | ||
165 | |||
166 | static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||
167 | enum wl_seat_capability caps) { | ||
168 | struct swaylock_state *state = data; | ||
169 | if ((caps & WL_SEAT_CAPABILITY_POINTER)) { | ||
170 | struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); | ||
171 | wl_pointer_add_listener(pointer, &pointer_listener, NULL); | ||
172 | } | ||
173 | if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { | ||
174 | struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); | ||
175 | wl_keyboard_add_listener(keyboard, &keyboard_listener, state); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void seat_handle_name(void *data, struct wl_seat *wl_seat, | ||
180 | const char *name) { | ||
181 | // Who cares | ||
182 | } | ||
183 | |||
184 | const struct wl_seat_listener seat_listener = { | ||
185 | .capabilities = seat_handle_capabilities, | ||
186 | .name = seat_handle_name, | ||
187 | }; | ||