commit c52559e

Michael Forney  ·  2019-08-30 02:34:03 +0000 UTC
parent 9e5f4b8
seat: Move away from global state
6 files changed,  +122, -112
+1, -0
1@@ -73,6 +73,7 @@ handle_selection_destroy(struct wl_listener *listener, void *data)
2 bool
3 data_device_initialize(struct data_device *data_device)
4 {
5+	data_device->selection = NULL;
6 	data_device->selection_destroy_listener.notify = &handle_selection_destroy;
7 	wl_signal_init(&data_device->event_signal);
8 	wl_list_init(&data_device->resources);
+3, -1
 1@@ -41,7 +41,9 @@ create_data_source(struct wl_client *client, struct wl_resource *resource, uint3
 2 static void
 3 get_data_device(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *seat_resource)
 4 {
 5-	data_device_bind(swc.seat->data_device, client, wl_resource_get_version(resource), id);
 6+	struct swc_seat *seat = wl_resource_get_user_data(seat_resource);
 7+
 8+	data_device_bind(seat->data_device, client, wl_resource_get_version(resource), id);
 9 }
10 
11 static struct wl_data_device_manager_interface data_device_manager_implementation = {
+1, -1
1@@ -39,7 +39,7 @@ struct swc {
2 	struct wl_signal event_signal;
3 	bool active;
4 
5-	const struct swc_seat *const seat;
6+	struct swc_seat *seat;
7 	const struct swc_bindings *const bindings;
8 	struct wl_list screens;
9 	struct swc_compositor *const compositor;
+109, -101
  1@@ -46,7 +46,9 @@
  2 # include <libudev.h>
  3 #endif
  4 
  5-static struct {
  6+struct seat {
  7+	struct swc_seat base;
  8+
  9 	char *name;
 10 	uint32_t capabilities;
 11 
 12@@ -60,22 +62,19 @@ static struct {
 13 	struct wl_listener swc_listener;
 14 
 15 	struct keyboard keyboard;
 16+	struct wl_listener keyboard_focus_listener;
 17 	struct pointer pointer;
 18 	struct data_device data_device;
 19+	struct wl_listener data_device_listener;
 20 
 21 	struct wl_global *global;
 22 	struct wl_list resources;
 23-} seat;
 24-
 25-const struct swc_seat swc_seat = {
 26-	.pointer = &seat.pointer,
 27-	.keyboard = &seat.keyboard,
 28-	.data_device = &seat.data_device,
 29 };
 30 
 31 static void
 32 handle_keyboard_focus_event(struct wl_listener *listener, void *data)
 33 {
 34+	struct seat *seat = wl_container_of(listener, seat, keyboard_focus_listener);
 35 	struct event *ev = data;
 36 	struct input_focus_event_data *event_data = ev->data;
 37 
 38@@ -86,42 +85,36 @@ handle_keyboard_focus_event(struct wl_listener *listener, void *data)
 39 		struct wl_client *client = wl_resource_get_client(event_data->new->surface->resource);
 40 
 41 		/* Offer the selection to the new focus. */
 42-		data_device_offer_selection(&seat.data_device, client);
 43+		data_device_offer_selection(&seat->data_device, client);
 44 	}
 45 }
 46 
 47-static struct wl_listener keyboard_focus_listener = {
 48-	.notify = handle_keyboard_focus_event,
 49-};
 50-
 51 static void
 52 handle_data_device_event(struct wl_listener *listener, void *data)
 53 {
 54+	struct seat *seat = wl_container_of(listener, seat, data_device_listener);
 55 	struct event *ev = data;
 56 
 57 	if (ev->type != DATA_DEVICE_EVENT_SELECTION_CHANGED)
 58 		return;
 59 
 60-	if (seat.keyboard.focus.client)
 61-		data_device_offer_selection(&seat.data_device, seat.keyboard.focus.client);
 62+	if (seat->keyboard.focus.client)
 63+		data_device_offer_selection(&seat->data_device, seat->keyboard.focus.client);
 64 }
 65 
 66-static struct wl_listener data_device_listener = {
 67-	.notify = handle_data_device_event,
 68-};
 69-
 70 static void
 71 handle_swc_event(struct wl_listener *listener, void *data)
 72 {
 73+	struct seat *seat = wl_container_of(listener, seat, swc_listener);
 74 	struct event *ev = data;
 75 
 76 	switch (ev->type) {
 77 	case SWC_EVENT_DEACTIVATED:
 78-		libinput_suspend(seat.libinput);
 79-		keyboard_reset(&seat.keyboard);
 80+		libinput_suspend(seat->libinput);
 81+		keyboard_reset(&seat->keyboard);
 82 		break;
 83 	case SWC_EVENT_ACTIVATED:
 84-		if (libinput_resume(seat.libinput) != 0)
 85+		if (libinput_resume(seat->libinput) != 0)
 86 			WARNING("Failed to resume libinput context\n");
 87 		break;
 88 	}
 89@@ -131,13 +124,17 @@ handle_swc_event(struct wl_listener *listener, void *data)
 90 static void
 91 get_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id)
 92 {
 93-	pointer_bind(&seat.pointer, client, wl_resource_get_version(resource), id);
 94+	struct seat *seat = wl_resource_get_user_data(resource);
 95+
 96+	pointer_bind(&seat->pointer, client, wl_resource_get_version(resource), id);
 97 }
 98 
 99 static void
100 get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id)
101 {
102-	keyboard_bind(&seat.keyboard, client, wl_resource_get_version(resource), id);
103+	struct seat *seat = wl_resource_get_user_data(resource);
104+
105+	keyboard_bind(&seat->keyboard, client, wl_resource_get_version(resource), id);
106 }
107 
108 static void
109@@ -155,32 +152,33 @@ static struct wl_seat_interface seat_implementation = {
110 static void
111 bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
112 {
113+	struct seat *seat = data;
114 	struct wl_resource *resource;
115 
116 	if (version > 4)
117 		version = 4;
118 
119 	resource = wl_resource_create(client, &wl_seat_interface, version, id);
120-	wl_resource_set_implementation(resource, &seat_implementation, NULL, &remove_resource);
121-	wl_list_insert(&seat.resources, wl_resource_get_link(resource));
122+	wl_resource_set_implementation(resource, &seat_implementation, seat, &remove_resource);
123+	wl_list_insert(&seat->resources, wl_resource_get_link(resource));
124 
125 	if (version >= 2)
126-		wl_seat_send_name(resource, seat.name);
127+		wl_seat_send_name(resource, seat->name);
128 
129-	wl_seat_send_capabilities(resource, seat.capabilities);
130+	wl_seat_send_capabilities(resource, seat->capabilities);
131 }
132 
133 static void
134-update_capabilities(uint32_t capabilities)
135+update_capabilities(struct seat *seat, uint32_t capabilities)
136 {
137 	struct wl_resource *resource;
138 
139-	if (!(~seat.capabilities & capabilities))
140+	if (!(~seat->capabilities & capabilities))
141 		return;
142 
143-	seat.capabilities |= capabilities;
144-	wl_list_for_each(resource, &seat.resources, link)
145-		wl_seat_send_capabilities(resource, seat.capabilities);
146+	seat->capabilities |= capabilities;
147+	wl_list_for_each(resource, &seat->resources, link)
148+		wl_seat_send_capabilities(resource, seat->capabilities);
149 }
150 
151 static int
152@@ -218,7 +216,7 @@ device_capabilities(struct libinput_device *device)
153 }
154 
155 static void
156-handle_libinput_axis_event(struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
157+handle_libinput_axis_event(struct seat *seat, struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
158 {
159 	wl_fixed_t amount;
160 
161@@ -226,12 +224,13 @@ handle_libinput_axis_event(struct libinput_event_pointer *event, enum libinput_p
162 		return;
163 
164 	amount = wl_fixed_from_double(libinput_event_pointer_get_axis_value(event, axis));
165-	pointer_handle_axis(&seat.pointer, libinput_event_pointer_get_time(event), axis, amount);
166+	pointer_handle_axis(&seat->pointer, libinput_event_pointer_get_time(event), axis, amount);
167 }
168 
169 static int
170 handle_libinput_data(int fd, uint32_t mask, void *data)
171 {
172+	struct seat *seat = data;
173 	struct screen *screen;
174 	struct swc_rectangle *rect;
175 	struct libinput_event *generic_event;
176@@ -243,16 +242,16 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
177 	wl_fixed_t x, y;
178 	uint32_t time, key, state;
179 
180-	if (libinput_dispatch(seat.libinput) != 0) {
181+	if (libinput_dispatch(seat->libinput) != 0) {
182 		WARNING("libinput_dispatch failed: %s\n", strerror(errno));
183 		return 0;
184 	}
185 
186-	while ((generic_event = libinput_get_event(seat.libinput))) {
187+	while ((generic_event = libinput_get_event(seat->libinput))) {
188 		switch (libinput_event_get_type(generic_event)) {
189 		case LIBINPUT_EVENT_DEVICE_ADDED:
190 			device = libinput_event_get_device(generic_event);
191-			update_capabilities(device_capabilities(device));
192+			update_capabilities(seat, device_capabilities(device));
193 			if (swc.manager->new_device)
194 				swc.manager->new_device(device);
195 			break;
196@@ -261,14 +260,14 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
197 			time = libinput_event_keyboard_get_time(event.k);
198 			key = libinput_event_keyboard_get_key(event.k);
199 			state = libinput_event_keyboard_get_key_state(event.k);
200-			keyboard_handle_key(&seat.keyboard, time, key, state);
201+			keyboard_handle_key(&seat->keyboard, time, key, state);
202 			break;
203 		case LIBINPUT_EVENT_POINTER_MOTION:
204 			event.p = libinput_event_get_pointer_event(generic_event);
205 			time = libinput_event_pointer_get_time(event.p);
206 			x = wl_fixed_from_double(libinput_event_pointer_get_dx(event.p));
207 			y = wl_fixed_from_double(libinput_event_pointer_get_dy(event.p));
208-			pointer_handle_relative_motion(&seat.pointer, time, x, y);
209+			pointer_handle_relative_motion(&seat->pointer, time, x, y);
210 			break;
211 		case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
212 			screen = wl_container_of(swc.screens.next, screen, link);
213@@ -277,31 +276,31 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
214 			time = libinput_event_pointer_get_time(event.p);
215 			x = wl_fixed_from_double(libinput_event_pointer_get_absolute_x_transformed(event.p, rect->width));
216 			y = wl_fixed_from_double(libinput_event_pointer_get_absolute_y_transformed(event.p, rect->height));
217-			pointer_handle_absolute_motion(&seat.pointer, time, x, y);
218+			pointer_handle_absolute_motion(&seat->pointer, time, x, y);
219 			break;
220 		case LIBINPUT_EVENT_POINTER_BUTTON:
221 			event.p = libinput_event_get_pointer_event(generic_event);
222 			time = libinput_event_pointer_get_time(event.p);
223 			key = libinput_event_pointer_get_button(event.p);
224 			state = libinput_event_pointer_get_button_state(event.p);
225-			pointer_handle_button(&seat.pointer, time, key, state);
226+			pointer_handle_button(&seat->pointer, time, key, state);
227 			if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
228 		                /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so pass
229 				 * those through as axis events. */
230 				switch (key) {
231 				case BTN_GEAR_DOWN:
232-					pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
233+					pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
234 					break;
235 				case BTN_GEAR_UP:
236-					pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
237+					pointer_handle_axis(&seat->pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
238 					break;
239 				}
240 			}
241 			break;
242 		case LIBINPUT_EVENT_POINTER_AXIS:
243 			event.p = libinput_event_get_pointer_event(generic_event);
244-			handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
245-			handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
246+			handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
247+			handle_libinput_axis_event(seat, event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
248 			break;
249 		default:
250 			break;
251@@ -314,129 +313,138 @@ handle_libinput_data(int fd, uint32_t mask, void *data)
252 }
253 
254 bool
255-initialize_libinput(const char *seat_name)
256+initialize_libinput(struct seat *seat)
257 {
258 #ifdef ENABLE_LIBUDEV
259-	if (!(seat.udev = udev_new())) {
260+	if (!(seat->udev = udev_new())) {
261 		ERROR("Could not create udev context\n");
262 		goto error0;
263 	}
264 
265-	seat.libinput = libinput_udev_create_context(&libinput_interface, NULL, seat.udev);
266+	seat->libinput = libinput_udev_create_context(&libinput_interface, NULL, seat->udev);
267 #else
268-	seat.libinput = libinput_netlink_create_context(&libinput_interface, NULL);
269+	seat->libinput = libinput_netlink_create_context(&libinput_interface, NULL);
270 #endif
271 
272-	if (!seat.libinput) {
273+	if (!seat->libinput) {
274 		ERROR("Could not create libinput context\n");
275 		goto error1;
276 	}
277 
278 #ifdef ENABLE_LIBUDEV
279-	if (libinput_udev_assign_seat(seat.libinput, seat_name) != 0) {
280+	if (libinput_udev_assign_seat(seat->libinput, seat->name) != 0) {
281 		ERROR("Failed to assign seat to libinput context\n");
282 		goto error2;
283 	}
284 #else
285-	if (libinput_netlink_assign_seat(seat.libinput, seat_name) != 0) {
286+	if (libinput_netlink_assign_seat(seat->libinput, seat->name) != 0) {
287 		ERROR("Failed to assign seat to libinput context\n");
288 		goto error2;
289 	}
290 #endif
291 
292-	seat.libinput_source = wl_event_loop_add_fd
293-		(swc.event_loop, libinput_get_fd(seat.libinput), WL_EVENT_READABLE,
294-		 &handle_libinput_data, NULL);
295-
296-	if (!seat.libinput_source) {
297+	seat->libinput_source = wl_event_loop_add_fd(swc.event_loop, libinput_get_fd(seat->libinput), WL_EVENT_READABLE, &handle_libinput_data, seat);
298+	if (!seat->libinput_source) {
299 		ERROR("Could not create event source for libinput\n");
300 		goto error2;
301 	}
302 
303 	if (!swc.active)
304-		libinput_suspend(seat.libinput);
305+		libinput_suspend(seat->libinput);
306 
307 	return true;
308 
309 error2:
310-	libinput_unref(seat.libinput);
311+	libinput_unref(seat->libinput);
312 error1:
313 #ifdef ENABLE_LIBUDEV
314-	udev_unref(seat.udev);
315+	udev_unref(seat->udev);
316 error0:
317 #endif
318 	return false;
319 }
320 
321-bool
322-seat_initialize(const char *seat_name)
323+struct swc_seat *
324+seat_create(struct wl_display *display, const char *seat_name)
325 {
326-	if (!(seat.name = strdup(seat_name))) {
327-		ERROR("Could not allocate seat name string\n");
328-		goto error0;
329-	}
330-
331-	seat.global = wl_global_create(swc.display, &wl_seat_interface, 4, NULL, &bind_seat);
332+	struct seat *seat;
333 
334-	if (!seat.global)
335+	seat = malloc(sizeof(*seat));
336+	if (!seat)
337+		goto error0;
338+	seat->name = strdup(seat_name);
339+	if (!seat->name) {
340+		ERROR("Could not allocate seat name string\n");
341 		goto error1;
342+	}
343+	seat->global = wl_global_create(display, &wl_seat_interface, 4, seat, &bind_seat);
344+	if (!seat->global)
345+		goto error2;
346+	seat->capabilities = 0;
347+	wl_list_init(&seat->resources);
348 
349-	seat.capabilities = 0;
350-	wl_list_init(&seat.resources);
351-	seat.swc_listener.notify = &handle_swc_event;
352-	wl_signal_add(&swc.event_signal, &seat.swc_listener);
353+	seat->swc_listener.notify = &handle_swc_event;
354+	wl_signal_add(&swc.event_signal, &seat->swc_listener);
355 
356-	if (!data_device_initialize(&seat.data_device)) {
357+	if (!data_device_initialize(&seat->data_device)) {
358 		ERROR("Could not initialize data device\n");
359-		goto error2;
360+		goto error3;
361 	}
362+	seat->base.data_device = &seat->data_device;
363+	seat->data_device_listener.notify = &handle_data_device_event;
364+	wl_signal_add(&seat->data_device.event_signal, &seat->data_device_listener);
365 
366-	wl_signal_add(&seat.data_device.event_signal, &data_device_listener);
367-
368-	if (!keyboard_initialize(&seat.keyboard)) {
369+	if (!keyboard_initialize(&seat->keyboard)) {
370 		ERROR("Could not initialize keyboard\n");
371-		goto error3;
372+		goto error4;
373 	}
374+	seat->base.keyboard = &seat->keyboard;
375+	seat->keyboard_focus_listener.notify = handle_keyboard_focus_event;
376+	wl_signal_add(&seat->keyboard.focus.event_signal, &seat->keyboard_focus_listener);
377 
378-	wl_signal_add(&seat.keyboard.focus.event_signal, &keyboard_focus_listener);
379-
380-	if (!pointer_initialize(&seat.pointer)) {
381+	if (!pointer_initialize(&seat->pointer)) {
382 		ERROR("Could not initialize pointer\n");
383-		goto error4;
384+		goto error5;
385 	}
386+	seat->base.pointer = &seat->pointer;
387 
388-	if (!initialize_libinput(seat.name))
389-		goto error5;
390+	if (!initialize_libinput(seat))
391+		goto error6;
392 
393-	return true;
394+	return &seat->base;
395 
396+error6:
397+	pointer_finalize(&seat->pointer);
398 error5:
399-	pointer_finalize(&seat.pointer);
400+	keyboard_finalize(&seat->keyboard);
401 error4:
402-	keyboard_finalize(&seat.keyboard);
403+	data_device_finalize(&seat->data_device);
404 error3:
405-	data_device_finalize(&seat.data_device);
406+	wl_global_destroy(seat->global);
407 error2:
408-	wl_global_destroy(seat.global);
409+	free(seat->name);
410 error1:
411-	free(seat.name);
412+	free(seat);
413 error0:
414-	return false;
415+	return NULL;
416 }
417 
418 void
419-seat_finalize(void)
420+seat_destroy(struct swc_seat *seat_base)
421 {
422-	wl_event_source_remove(seat.libinput_source);
423-	libinput_unref(seat.libinput);
424+	struct seat *seat = wl_container_of(seat_base, seat, base);
425+
426+	wl_event_source_remove(seat->libinput_source);
427+	libinput_unref(seat->libinput);
428 #ifdef ENABLE_LIBUDEV
429-	udev_unref(seat.udev);
430+	udev_unref(seat->udev);
431 #endif
432 
433-	pointer_finalize(&seat.pointer);
434-	keyboard_finalize(&seat.keyboard);
435-	data_device_finalize(&seat.data_device);
436+	pointer_finalize(&seat->pointer);
437+	keyboard_finalize(&seat->keyboard);
438+	data_device_finalize(&seat->data_device);
439 
440-	wl_global_destroy(seat.global);
441-	free(seat.name);
442+	wl_global_destroy(seat->global);
443+	free(seat->name);
444+	free(seat);
445 }
+4, -4
 1@@ -1,6 +1,6 @@
 2 /* swc: libswc/seat.h
 3  *
 4- * Copyright (c) 2013 Michael Forney
 5+ * Copyright (c) 2013-2019 Michael Forney
 6  *
 7  * Permission is hereby granted, free of charge, to any person obtaining a copy
 8  * of this software and associated documentation files (the "Software"), to deal
 9@@ -24,7 +24,7 @@
10 #ifndef SWC_SEAT_H
11 #define SWC_SEAT_H
12 
13-#include <stdbool.h>
14+struct wl_display;
15 
16 struct swc_seat {
17 	struct pointer *pointer;
18@@ -32,7 +32,7 @@ struct swc_seat {
19 	struct data_device *data_device;
20 };
21 
22-bool seat_initialize(const char *seat_name);
23-void seat_finalize(void);
24+struct swc_seat *seat_create(struct wl_display *display, const char *name);
25+void seat_destroy(struct swc_seat *seat);
26 
27 #endif
+4, -5
 1@@ -42,7 +42,6 @@
 2 #include "xdg_shell.h"
 3 
 4 extern struct swc_launch swc_launch;
 5-extern const struct swc_seat swc_seat;
 6 extern const struct swc_bindings swc_bindings;
 7 extern struct swc_compositor swc_compositor;
 8 extern struct swc_drm swc_drm;
 9@@ -50,7 +49,6 @@ extern struct swc_drm swc_drm;
10 extern struct pointer_handler screens_pointer_handler;
11 
12 struct swc swc = {
13-	.seat = &swc_seat,
14 	.bindings = &swc_bindings,
15 	.compositor = &swc_compositor,
16 	.drm = &swc_drm,
17@@ -150,7 +148,8 @@ swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop, con
18 		goto error7;
19 	}
20 
21-	if (!seat_initialize(default_seat)) {
22+	swc.seat = seat_create(display, default_seat);
23+	if (!swc.seat) {
24 		ERROR("Could not initialize seat\n");
25 		goto error8;
26 	}
27@@ -179,7 +178,7 @@ error11:
28 error10:
29 	shell_finalize();
30 error9:
31-	seat_finalize();
32+	seat_destroy(swc.seat);
33 error8:
34 	wl_global_destroy(swc.data_device_manager);
35 error7:
36@@ -205,7 +204,7 @@ swc_finalize(void)
37 {
38 	panel_manager_finalize();
39 	shell_finalize();
40-	seat_finalize();
41+	seat_destroy(swc.seat);
42 	wl_global_destroy(swc.data_device_manager);
43 	compositor_finalize();
44 	screens_finalize();