1 #include <assert.h>
2 #include <errno.h>
3 #include <cairo/cairo.h>
4 #include <getopt.h>
5 #include <libinput.h>
6 #include <libudev.h>
7 #include <poll.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/mman.h>
13 #include <time.h>
14 #include <unistd.h>
15 #include <wayland-client.h>
16 #include <xkbcommon/xkbcommon.h>
17 #include "devmgr.h"
18 #include "shm.h"
19 #include "pango.h"
20 #include "wlr-layer-shell-unstable-v1-client-protocol.h"
21 #include "xdg-output-unstable-v1-client-protocol.h"
22 
23 struct wsk_keypress {
24 	xkb_keysym_t sym;
25 	char name[128];
26 	char utf8[128];
27 	struct wsk_keypress *next;
28 };
29 
30 struct wsk_output {
31 	struct wl_output *output;
32 	int scale;
33 	enum wl_output_subpixel subpixel;
34 	struct wsk_output *next;
35 };
36 
37 struct wsk_state {
38 	int devmgr;
39 	pid_t devmgr_pid;
40 	struct udev *udev;
41 	struct libinput *libinput;
42 
43 	uint32_t foreground, background, specialfg;
44 	const char *font;
45 	int timeout;
46 
47 	struct wl_display *display;
48 	struct wl_registry *registry;
49 	struct wl_compositor *compositor;
50 	struct wl_shm *shm;
51 	struct wl_seat *seat;
52 	struct wl_keyboard *keyboard;
53 	struct zxdg_output_manager_v1 *output_mgr;
54 	struct zwlr_layer_shell_v1 *layer_shell;
55 
56 	struct wl_surface *surface;
57 	struct zwlr_layer_surface_v1 *layer_surface;
58 	uint32_t width, height;
59 	bool frame_scheduled, dirty;
60 	struct pool_buffer buffers[2];
61 	struct pool_buffer *current_buffer;
62 	struct wsk_output *output, *outputs;
63 
64 	struct xkb_state *xkb_state;
65 	struct xkb_context *xkb_context;
66 	struct xkb_keymap *xkb_keymap;
67 
68 	struct wsk_keypress *keys;
69 	struct timespec last_key;
70 
71 	bool run;
72 };
73 
cairo_set_source_u32(cairo_t * cairo,uint32_t color)74 static void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
75 	cairo_set_source_rgba(cairo,
76 			(color >> (3*8) & 0xFF) / 255.0,
77 			(color >> (2*8) & 0xFF) / 255.0,
78 			(color >> (1*8) & 0xFF) / 255.0,
79 			(color >> (0*8) & 0xFF) / 255.0);
80 }
81 
to_cairo_subpixel_order(enum wl_output_subpixel subpixel)82 static cairo_subpixel_order_t to_cairo_subpixel_order(
83 		enum wl_output_subpixel subpixel) {
84 	switch (subpixel) {
85 	case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
86 		return CAIRO_SUBPIXEL_ORDER_RGB;
87 	case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
88 		return CAIRO_SUBPIXEL_ORDER_BGR;
89 	case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
90 		return CAIRO_SUBPIXEL_ORDER_VRGB;
91 	case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
92 		return CAIRO_SUBPIXEL_ORDER_VBGR;
93 	default:
94 		return CAIRO_SUBPIXEL_ORDER_DEFAULT;
95 	}
96 	return CAIRO_SUBPIXEL_ORDER_DEFAULT;
97 }
98 
render_to_cairo(cairo_t * cairo,struct wsk_state * state,int scale,uint32_t * width,uint32_t * height)99 static void render_to_cairo(cairo_t *cairo, struct wsk_state *state,
100 		int scale, uint32_t *width, uint32_t *height) {
101 	cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
102 	cairo_set_source_u32(cairo, state->background);
103 	cairo_paint(cairo);
104 
105 	struct wsk_keypress *key = state->keys;
106 	while (key) {
107 		bool special = false;
108 		const char *name = key->utf8;
109 		if (!name[0]) {
110 			special = true;
111 			cairo_set_source_u32(cairo, state->specialfg);
112 			name = key->name;
113 		} else {
114 			cairo_set_source_u32(cairo, state->foreground);
115 		}
116 
117 		cairo_move_to(cairo, *width, 0);
118 
119 		int w, h;
120 		if (special) {
121 			get_text_size(cairo, state->font, &w, &h, NULL, scale, "%s+", name);
122 			pango_printf(cairo, state->font, scale,  "%s+", name);
123 		} else {
124 			get_text_size(cairo, state->font, &w, &h, NULL, scale, "%s", name);
125 			pango_printf(cairo, state->font, scale,  "%s", name);
126 		}
127 
128 		*width = *width + w;
129 		if ((int)*height < h) {
130 			*height = h;
131 		}
132 		key = key->next;
133 	}
134 }
135 
render_frame(struct wsk_state * state)136 static void render_frame(struct wsk_state *state) {
137 	cairo_surface_t *recorder = cairo_recording_surface_create(
138 			CAIRO_CONTENT_COLOR_ALPHA, NULL);
139 	cairo_t *cairo = cairo_create(recorder);
140 	cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
141 	cairo_font_options_t *fo = cairo_font_options_create();
142 	cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
143 	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
144 	if (state->output) {
145 		cairo_font_options_set_subpixel_order(
146 				fo, to_cairo_subpixel_order(state->output->subpixel));
147 	}
148 	cairo_set_font_options(cairo, fo);
149 	cairo_font_options_destroy(fo);
150 	cairo_save(cairo);
151 	cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
152 	cairo_paint(cairo);
153 	cairo_restore(cairo);
154 
155 	int scale = state->output ? state->output->scale : 1;
156 	uint32_t width = 0, height = 0;
157 	render_to_cairo(cairo, state, scale, &width, &height);
158 	if (height / scale != state->height
159 			|| width / scale != state->width
160 			|| state->width == 0) {
161 		// Reconfigure surface
162 		if (width == 0 || height == 0) {
163 			wl_surface_attach(state->surface, NULL, 0, 0);
164 		} else {
165 			zwlr_layer_surface_v1_set_size(
166 					state->layer_surface, width / scale, height / scale);
167 		}
168 
169 		// TODO: this could infinite loop if the compositor assigns us a
170 		// different height than what we asked for
171 		wl_surface_commit(state->surface);
172 	} else if (height > 0) {
173 		// Replay recording into shm and send it off
174 		state->current_buffer = get_next_buffer(state->shm,
175 				state->buffers, state->width * scale, state->height * scale);
176 		if (!state->current_buffer) {
177 			cairo_surface_destroy(recorder);
178 			cairo_destroy(cairo);
179 			return;
180 		}
181 		cairo_t *shm = state->current_buffer->cairo;
182 
183 		cairo_save(shm);
184 		cairo_set_operator(shm, CAIRO_OPERATOR_CLEAR);
185 		cairo_paint(shm);
186 		cairo_restore(shm);
187 
188 		cairo_set_source_surface(shm, recorder, 0.0, 0.0);
189 		cairo_paint(shm);
190 
191 		wl_surface_set_buffer_scale(state->surface, scale);
192 		wl_surface_attach(state->surface,
193 				state->current_buffer->buffer, 0, 0);
194 		wl_surface_damage_buffer(state->surface, 0, 0,
195 				state->width, state->height);
196 		wl_surface_commit(state->surface);
197 	}
198 }
199 
set_dirty(struct wsk_state * state)200 static void set_dirty(struct wsk_state *state) {
201 	if (state->frame_scheduled) {
202 		state->dirty = true;
203 	} else if (state->surface) {
204 		render_frame(state);
205 	}
206 }
207 
layer_surface_configure(void * data,struct zwlr_layer_surface_v1 * zwlr_layer_surface_v1,uint32_t serial,uint32_t width,uint32_t height)208 static void layer_surface_configure(void *data,
209 			struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
210 			uint32_t serial, uint32_t width, uint32_t height) {
211 	struct wsk_state *state = data;
212 	state->width = width;
213 	state->height = height;
214 	zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial);
215 	set_dirty(state);
216 }
217 
layer_surface_closed(void * data,struct zwlr_layer_surface_v1 * zwlr_layer_surface_v1)218 static void layer_surface_closed(void *data,
219 		struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1) {
220 	struct wsk_state *state = data;
221 	state->run = false;
222 }
223 
224 static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
225 	.configure = layer_surface_configure,
226 	.closed = layer_surface_closed,
227 };
228 
surface_enter(void * data,struct wl_surface * wl_surface,struct wl_output * output)229 static void surface_enter(void *data,
230 		struct wl_surface *wl_surface, struct wl_output *output) {
231 	struct wsk_state *state = data;
232 	struct wsk_output *wsk_output = state->outputs;
233 	while (wsk_output->output != output) {
234 		wsk_output = wsk_output->next;
235 	}
236 	state->output = wsk_output;
237 }
238 
surface_leave(void * data,struct wl_surface * wl_surface,struct wl_output * output)239 static void surface_leave(void *data,
240 		struct wl_surface *wl_surface, struct wl_output *output) {
241 	// Who cares (not really possible with layer shell)
242 }
243 
244 static const struct wl_surface_listener wl_surface_listener = {
245 	.enter = surface_enter,
246 	.leave = surface_leave,
247 };
248 
keyboard_keymap(void * data,struct wl_keyboard * wl_keyboard,uint32_t format,int32_t fd,uint32_t size)249 static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
250 		uint32_t format, int32_t fd, uint32_t size) {
251 	struct wsk_state *state = data;
252 	char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
253 	if (map_shm == MAP_FAILED) {
254 		close(fd);
255 		fprintf(stderr, "Unable to mmap keymap: %s", strerror(errno));
256 		return;
257 	}
258 	if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
259 		munmap(map_shm, size);
260 		close(fd);
261 		return;
262 	}
263 
264 	struct xkb_keymap *keymap = xkb_keymap_new_from_string(
265 			state->xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
266 			XKB_KEYMAP_COMPILE_NO_FLAGS);
267 	munmap(map_shm, size);
268 	close(fd);
269 
270 	struct xkb_state *xkb_state = xkb_state_new(keymap);
271 	xkb_keymap_unref(state->xkb_keymap);
272 	xkb_state_unref(state->xkb_state);
273 	state->xkb_keymap = keymap;
274 	state->xkb_state = xkb_state;
275 }
276 
keyboard_enter(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)277 static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
278 		uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
279 	// Who cares
280 }
281 
keyboard_leave(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface)282 static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
283 		uint32_t serial, struct wl_surface *surface) {
284 	// Who cares
285 }
286 
keyboard_key(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)287 static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
288 		uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
289 	// Who cares
290 }
291 
keyboard_modifiers(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)292 static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
293 		uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
294 		uint32_t mods_locked, uint32_t group) {
295 	// Who cares
296 }
297 
keyboard_repeat_info(void * data,struct wl_keyboard * wl_keyboard,int32_t rate,int32_t delay)298 static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
299 		int32_t rate, int32_t delay) {
300 	// TODO
301 }
302 
303 static const struct wl_keyboard_listener wl_keyboard_listener = {
304 	.keymap = keyboard_keymap,
305 	.enter = keyboard_enter,
306 	.leave = keyboard_leave,
307 	.key = keyboard_key,
308 	.modifiers = keyboard_modifiers,
309 	.repeat_info = keyboard_repeat_info,
310 };
311 
seat_capabilities(void * data,struct wl_seat * wl_seat,uint32_t capabilities)312 static void seat_capabilities(
313 		void *data, struct wl_seat *wl_seat, uint32_t capabilities) {
314 	struct wsk_state *state = data;
315 	if (state->keyboard) {
316 		// TODO: support multiple seats
317 		return;
318 	}
319 
320 	if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) {
321 		fprintf(stderr, "wl_seat does not support keyboard");
322 		state->run = false;
323 		return;
324 	}
325 
326 	state->keyboard = wl_seat_get_keyboard(wl_seat);
327 	wl_keyboard_add_listener(state->keyboard, &wl_keyboard_listener, state);
328 }
329 
seat_name(void * data,struct wl_seat * wl_seat,const char * name)330 static void seat_name(void *data, struct wl_seat *wl_seat, const char *name) {
331 	struct wsk_state *state = data;
332 	/* TODO: support multiple seats */
333 	if (libinput_udev_assign_seat(state->libinput, "seat0") != 0) {
334 		fprintf(stderr, "Failed to assign libinput seat\n");
335 		state->run = false;
336 		return;
337 	}
338 }
339 
340 static const struct wl_seat_listener wl_seat_listener = {
341 	.capabilities = seat_capabilities,
342 	.name = seat_name,
343 };
344 
output_geometry(void * data,struct wl_output * wl_output,int32_t x,int32_t y,int32_t physical_width,int32_t physical_height,int32_t subpixel,const char * make,const char * model,int32_t transform)345 static void output_geometry(void *data, struct wl_output *wl_output,
346 		int32_t x, int32_t y, int32_t physical_width, int32_t physical_height,
347 		int32_t subpixel, const char *make, const char *model,
348 		int32_t transform) {
349 	struct wsk_output *output = data;
350 	output->subpixel = subpixel;
351 }
352 
output_mode(void * data,struct wl_output * wl_output,uint32_t flags,int32_t width,int32_t height,int32_t refresh)353 static void output_mode(void *data, struct wl_output *wl_output,
354 		uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
355 	// Who cares
356 }
357 
output_done(void * data,struct wl_output * wl_output)358 static void output_done(void *data, struct wl_output *wl_output) {
359 	// Who cares
360 }
361 
output_scale(void * data,struct wl_output * wl_output,int32_t factor)362 static void output_scale(void *data,
363 		struct wl_output *wl_output, int32_t factor) {
364 	struct wsk_output *output = data;
365 	output->scale = factor;
366 }
367 
368 static const struct wl_output_listener wl_output_listener = {
369 	.geometry = output_geometry,
370 	.mode = output_mode,
371 	.done = output_done,
372 	.scale = output_scale,
373 };
374 
registry_global(void * data,struct wl_registry * wl_registry,uint32_t name,const char * interface,uint32_t version)375 static void registry_global(void *data, struct wl_registry *wl_registry,
376 		uint32_t name, const char *interface, uint32_t version) {
377 	struct wsk_state *state = data;
378 	if (strcmp(interface, wl_compositor_interface.name) == 0) {
379 		state->compositor = wl_registry_bind(wl_registry,
380 				name, &wl_compositor_interface, 4);
381 	} else if (strcmp(interface, wl_shm_interface.name) == 0) {
382 		state->shm = wl_registry_bind(wl_registry, name, &wl_shm_interface, 1);
383 	} else if (strcmp(interface, wl_seat_interface.name) == 0) {
384 		state->seat = wl_registry_bind(wl_registry,
385 				name, &wl_seat_interface, 5);
386 	} else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) {
387 		state->output_mgr = wl_registry_bind(wl_registry,
388 				name, &zxdg_output_manager_v1_interface, 1);
389 	} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
390 		state->layer_shell = wl_registry_bind(wl_registry,
391 				name, &zwlr_layer_shell_v1_interface, 1);
392 	} else if (strcmp(interface, wl_output_interface.name) == 0) {
393 		struct wsk_output *output = calloc(1, sizeof(struct wsk_output));
394 		output->output = wl_registry_bind(wl_registry,
395 				name, &wl_output_interface, 3);
396 		output->scale = 1;
397 		struct wsk_output **link = &state->outputs;
398 		while (*link) {
399 			link = &(*link)->next;
400 		}
401 		*link = output;
402 		wl_output_add_listener(output->output, &wl_output_listener, output);
403 	}
404 }
405 
registry_global_remove(void * data,struct wl_registry * wl_registry,uint32_t name)406 static void registry_global_remove(void *data,
407 		struct wl_registry *wl_registry, uint32_t name) {
408 	/* This space deliberately left blank */
409 }
410 
411 static const struct wl_registry_listener registry_listener = {
412 	.global = registry_global,
413 	.global_remove = registry_global_remove,
414 };
415 
handle_libinput_event(struct wsk_state * state,struct libinput_event * event)416 static void handle_libinput_event(struct wsk_state *state,
417 		struct libinput_event *event) {
418 	if (!state->xkb_state) {
419 		return;
420 	}
421 
422 	enum libinput_event_type event_type = libinput_event_get_type(event);
423 	if (event_type != LIBINPUT_EVENT_KEYBOARD_KEY) {
424 		return;
425 	}
426 
427 	struct libinput_event_keyboard *kbevent =
428 		libinput_event_get_keyboard_event(event);
429 
430 	uint32_t keycode = libinput_event_keyboard_get_key(kbevent) + 8;
431 	enum libinput_key_state key_state =
432 		libinput_event_keyboard_get_key_state(kbevent);
433 	xkb_state_update_key(state->xkb_state, keycode,
434 			key_state == LIBINPUT_KEY_STATE_RELEASED ?
435 				XKB_KEY_UP : XKB_KEY_DOWN);
436 
437 	xkb_keysym_t keysym = xkb_state_key_get_one_sym(state->xkb_state, keycode);
438 
439 	struct wsk_keypress *keypress;
440 	switch (key_state) {
441 	case LIBINPUT_KEY_STATE_RELEASED:
442 		/* Who cares */
443 		break;
444 	case LIBINPUT_KEY_STATE_PRESSED:
445 		keypress = calloc(1, sizeof(struct wsk_keypress));
446 		assert(keypress);
447 		keypress->sym = keysym;
448 		xkb_keysym_get_name(keypress->sym, keypress->name,
449 				sizeof(keypress->name));
450 		if (xkb_state_key_get_utf8(state->xkb_state, keycode,
451 				keypress->utf8, sizeof(keypress->utf8)) <= 0 ||
452 				keypress->utf8[0] <= ' ') {
453 			keypress->utf8[0] = '\0';
454 		}
455 
456 		struct wsk_keypress **link = &state->keys;
457 		while (*link) {
458 			link = &(*link)->next;
459 		}
460 		*link = keypress;
461 		break;
462 	}
463 
464 	clock_gettime(CLOCK_MONOTONIC, &state->last_key);
465 	set_dirty(state);
466 }
467 
libinput_open_restricted(const char * path,int flags,void * data)468 static int libinput_open_restricted(const char *path,
469 		int flags, void *data) {
470 	int *fd = data;
471 	return devmgr_open(*fd, path);
472 }
473 
libinput_close_restricted(int fd,void * data)474 static void libinput_close_restricted(int fd, void *data) {
475 	close(fd);
476 }
477 
478 static const struct libinput_interface libinput_impl = {
479 	.open_restricted = libinput_open_restricted,
480 	.close_restricted = libinput_close_restricted,
481 };
482 
parse_color(const char * color)483 static uint32_t parse_color(const char *color) {
484 	if (color[0] == '#') {
485 		++color;
486 	}
487 
488 	int len = strlen(color);
489 	if (len != 6 && len != 8) {
490 		fprintf(stderr, "Invalid color %s, defaulting to color "
491 				"0xFFFFFFFF\n", color);
492 		return 0xFFFFFFFF;
493 	}
494 	uint32_t res = (uint32_t)strtoul(color, NULL, 16);
495 	if (strlen(color) == 6) {
496 		res = (res << 8) | 0xFF;
497 	}
498 	return res;
499 }
500 
main(int argc,char * argv[])501 int main(int argc, char *argv[]) {
502 	/* NOTICE: This code runs as root */
503 	struct wsk_state state = { 0 };
504 	if (devmgr_start(&state.devmgr, &state.devmgr_pid, INPUTDEVPATH) > 0) {
505 		return 1;
506 	}
507 
508 	/* Begin normal user code: */
509 	int ret = 0;
510 
511 	unsigned int anchor = 0;
512 	int margin = 32;
513 	state.background = 0x000000CC;
514 	state.specialfg = 0xAAAAAAFF;
515 	state.foreground = 0xFFFFFFFF;
516 	state.font = "monospace 24";
517 	state.timeout = 1;
518 
519 	int c;
520 	while ((c = getopt(argc, argv, "hb:f:s:F:t:a:m:o:")) != -1) {
521 		switch (c) {
522 		case 'b':
523 			state.background = parse_color(optarg);
524 			break;
525 		case 'f':
526 			state.foreground = parse_color(optarg);
527 			break;
528 		case 's':
529 			state.specialfg = parse_color(optarg);
530 			break;
531 		case 'F':
532 			state.font = optarg;
533 			break;
534 		case 't':
535 			state.timeout = atoi(optarg);
536 			break;
537 		case 'a':
538 			if (strcmp(optarg, "top") == 0) {
539 				anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
540 			} else if (strcmp(optarg, "left") == 0) {
541 				anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
542 			} else if (strcmp(optarg, "right") == 0) {
543 				anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
544 			} else if (strcmp(optarg, "bottom") == 0) {
545 				anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
546 			}
547 			break;
548 		case 'm':
549 			margin = atoi(optarg);
550 			break;
551 		case 'o':
552 			fprintf(stderr, "-o is unimplemented\n");
553 			return 0;
554 		default:
555 			fprintf(stderr, "usage: wshowkeys [-b|-f|-s #RRGGBB[AA]] [-F font] "
556 					"[-t timeout]\n\t[-a top|left|right|bottom] [-m margin] "
557 					"[-o output]\n");
558 			return 1;
559 		}
560 	}
561 
562 	state.udev = udev_new();
563 	if (!state.udev) {
564 		fprintf(stderr, "udev_create: %s\n", strerror(errno));
565 		ret = 1;
566 		goto exit;
567 	}
568 
569 	state.libinput = libinput_udev_create_context(
570 			&libinput_impl, &state.devmgr, state.udev);
571 	udev_unref(state.udev);
572 	if (!state.libinput) {
573 		fprintf(stderr, "libinput_udev_create_context: %s\n", strerror(errno));
574 		ret = 1;
575 		goto exit;
576 	}
577 
578 	state.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
579 	if (!state.xkb_context) {
580 		fprintf(stderr, "xkb_context_new: %s\n", strerror(errno));
581 		ret = 1;
582 		goto exit;
583 	}
584 
585 	state.display = wl_display_connect(NULL);
586 	if (!state.display) {
587 		fprintf(stderr, "wl_display_connect: %s\n", strerror(errno));
588 		ret = 1;
589 		goto exit;
590 	}
591 
592 	state.registry = wl_display_get_registry(state.display);
593 	assert(state.registry);
594 	wl_registry_add_listener(state.registry, &registry_listener, &state);
595 	wl_display_roundtrip(state.display);
596 
597 	struct {
598 		const char *name;
599 		void *ptr;
600 	} need_globals[] = {
601 		"wl_compositor", &state.compositor,
602 		"wl_shm", &state.shm,
603 		"wl_seat", &state.seat,
604 		"wlr_layer_shell", &state.layer_shell,
605 	};
606 	for (size_t i = 0; i < sizeof(need_globals) / sizeof(need_globals[0]); ++i) {
607 		if (!need_globals[i].ptr) {
608 			fprintf(stderr, "Error: required Wayland interface '%s' "
609 					"is not present\n", need_globals[i].name);
610 			ret = 1;
611 			goto exit;
612 		}
613 	}
614 
615 	// TODO: Listener for xdg output
616 
617 	wl_seat_add_listener(state.seat, &wl_seat_listener, &state);
618 	wl_display_roundtrip(state.display);
619 
620 	state.surface = wl_compositor_create_surface(state.compositor);
621 	assert(state.surface);
622 	wl_surface_add_listener(state.surface, &wl_surface_listener, &state);
623 
624 	state.layer_surface = zwlr_layer_shell_v1_get_layer_surface(
625 			state.layer_shell, state.surface, NULL,
626 			ZWLR_LAYER_SHELL_V1_LAYER_TOP, "showkeys");
627 	assert(state.layer_surface);
628 	zwlr_layer_surface_v1_add_listener(
629 			state.layer_surface, &layer_surface_listener, &state);
630 	zwlr_layer_surface_v1_set_size(state.layer_surface, 1, 1);
631 	zwlr_layer_surface_v1_set_anchor(state.layer_surface, anchor);
632 	zwlr_layer_surface_v1_set_margin(state.layer_surface,
633 			margin, margin, margin, margin);
634 	zwlr_layer_surface_v1_set_exclusive_zone(state.layer_surface, -1);
635 	wl_surface_commit(state.surface);
636 
637 	struct pollfd pollfds[] = {
638 		{ .fd = libinput_get_fd(state.libinput), .events = POLLIN, },
639 		{ .fd = wl_display_get_fd(state.display), .events = POLLIN, },
640 	};
641 
642 	state.run = true;
643 	while (state.run) {
644 		errno = 0;
645 		do {
646 			if (wl_display_flush(state.display) == -1 && errno != EAGAIN) {
647 				fprintf(stderr, "wl_display_flush: %s\n", strerror(errno));
648 				break;
649 			}
650 		} while (errno == EAGAIN);
651 
652 		int timeout = -1;
653 		if (state.keys) {
654 			timeout = 100;
655 		}
656 
657 		if (poll(pollfds, sizeof(pollfds) / sizeof(pollfds[0]), timeout) < 0) {
658 			fprintf(stderr, "poll: %s\n", strerror(errno));
659 			break;
660 		}
661 
662 		/* Clear out old keys */
663 		struct timespec now;
664 		clock_gettime(CLOCK_MONOTONIC, &now);
665 		if (now.tv_sec >= state.last_key.tv_sec + state.timeout &&
666 				now.tv_nsec >= state.last_key.tv_nsec) {
667 			struct wsk_keypress *key = state.keys;
668 			while (key) {
669 				struct wsk_keypress *next = key->next;
670 				free(key);
671 				key = next;
672 			}
673 			state.keys = NULL;
674 			set_dirty(&state);
675 		}
676 
677 		if ((pollfds[0].revents & POLLIN)) {
678 			if (libinput_dispatch(state.libinput) != 0) {
679 				fprintf(stderr, "libinput_dispatch: %s\n", strerror(errno));
680 				break;
681 			}
682 			struct libinput_event *event;
683 			while ((event = libinput_get_event(state.libinput))) {
684 				handle_libinput_event(&state, event);
685 				libinput_event_destroy(event);
686 			}
687 		}
688 
689 		if ((pollfds[1].revents & POLLIN)
690 				&& wl_display_dispatch(state.display) == -1) {
691 			fprintf(stderr, "wl_display_dispatch: %s\n", strerror(errno));
692 			break;
693 		}
694 	}
695 
696 exit:
697 	wl_display_disconnect(state.display);
698 	libinput_unref(state.libinput);
699 	devmgr_finish(state.devmgr, state.devmgr_pid);
700 	return ret;
701 }
702