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();