commit 610fc7f

Michael Forney  ·  2013-11-26 02:02:13 +0000 UTC
parent 166eccd
Move seat-related stuff out of compositor.c
9 files changed,  +189, -209
+14, -29
  1@@ -3,13 +3,17 @@
  2 #include "compositor_surface.h"
  3 #include "cursor_surface.h"
  4 #include "data_device_manager.h"
  5+#include "internal.h"
  6 #include "output.h"
  7+#include "pointer.h"
  8 #include "region.h"
  9+#include "seat.h"
 10 #include "surface.h"
 11 #include "util.h"
 12 
 13 #include <stdlib.h>
 14 #include <stdio.h>
 15+#include <xkbcommon/xkbcommon-keysyms.h>
 16 
 17 static const char default_seat[] = "seat0";
 18 
 19@@ -144,14 +148,11 @@ static void perform_update(void * data)
 20 
 21 static void handle_focus(struct swc_pointer * pointer)
 22 {
 23-    struct swc_seat * seat;
 24-    struct swc_compositor * compositor;
 25+    /* XXX: Temporary hack */
 26+    struct swc_compositor * compositor = swc.compositor;
 27     struct swc_surface * surface;
 28     int32_t x, y;
 29 
 30-    seat = CONTAINER_OF(pointer, typeof(*seat), pointer);
 31-    compositor = CONTAINER_OF(seat, typeof(*compositor), seat);
 32-
 33     wl_list_for_each(surface, &compositor->surfaces, link)
 34     {
 35         pixman_region32_t region;
 36@@ -306,7 +307,7 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 37     struct wl_list * outputs;
 38     struct swc_output * output;
 39     pixman_region32_t pointer_region;
 40-    xkb_keysym_t keysym;
 41+    uint32_t keysym;
 42 
 43     compositor->display = display;
 44     compositor->drm_listener.notify = &handle_drm_event;
 45@@ -321,23 +322,11 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 46         .motion = &handle_motion
 47     };
 48 
 49-    /* TODO: configurable seat */
 50-    if (!swc_seat_initialize(&compositor->seat, default_seat))
 51-    {
 52-        printf("could not initialize seat\n");
 53-        goto error_base;
 54-    }
 55-
 56-    swc_seat_add_event_sources(&compositor->seat, event_loop);
 57-    compositor->seat.pointer.handler = &compositor->pointer_handler;
 58-    wl_signal_add(&compositor->seat.pointer.event_signal,
 59-                  &compositor->pointer_listener);
 60-
 61     /* TODO: configurable seat */
 62     if (!swc_drm_initialize(&compositor->drm, default_seat))
 63     {
 64         printf("could not initialize drm\n");
 65-        goto error_seat;
 66+        goto error0;
 67     }
 68 
 69     wl_signal_add(&compositor->drm.event_signal, &compositor->drm_listener);
 70@@ -346,7 +335,7 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 71     if (!swc_renderer_initialize(&compositor->renderer, &compositor->drm))
 72     {
 73         printf("could not initialize renderer\n");
 74-        goto error_drm;
 75+        goto error1;
 76     }
 77 
 78     outputs = swc_drm_create_outputs(&compositor->drm);
 79@@ -360,7 +349,7 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 80     else
 81     {
 82         printf("could not create outputs\n");
 83-        goto error_renderer;
 84+        goto error2;
 85     }
 86 
 87     /* Calculate pointer region */
 88@@ -374,7 +363,7 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 89                                    output->geometry.height);
 90     }
 91 
 92-    swc_pointer_set_region(&compositor->seat.pointer, &pointer_region);
 93+    swc_pointer_set_region(swc.seat->pointer, &pointer_region);
 94     pixman_region32_fini(&pointer_region);
 95 
 96     pixman_region32_init(&compositor->damage);
 97@@ -396,13 +385,11 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 98 
 99     return true;
100 
101-  error_renderer:
102+  error2:
103     swc_renderer_finalize(&compositor->renderer);
104-  error_drm:
105+  error1:
106     swc_drm_finish(&compositor->drm);
107-  error_seat:
108-    swc_seat_finish(&compositor->seat);
109-  error_base:
110+  error0:
111     return false;
112 }
113 
114@@ -419,7 +406,6 @@ void swc_compositor_finish(struct swc_compositor * compositor)
115     }
116 
117     swc_drm_finish(&compositor->drm);
118-    swc_seat_finish(&compositor->seat);
119 }
120 
121 void swc_compositor_add_globals(struct swc_compositor * compositor,
122@@ -431,7 +417,6 @@ void swc_compositor_add_globals(struct swc_compositor * compositor,
123                      &bind_compositor);
124 
125     swc_data_device_manager_add_globals(display);
126-    swc_seat_add_globals(&compositor->seat, display);
127     swc_drm_add_globals(&compositor->drm, display);
128 
129     wl_list_for_each(output, &compositor->outputs, link)
+0, -2
 1@@ -3,7 +3,6 @@
 2 
 3 #include "drm.h"
 4 #include "pointer.h"
 5-#include "seat.h"
 6 #include "renderer.h"
 7 
 8 #include <wayland-server.h>
 9@@ -12,7 +11,6 @@ struct swc_compositor
10 {
11     struct wl_display * display;
12 
13-    struct swc_seat seat;
14     struct swc_drm drm;
15     struct swc_renderer renderer;
16 
+1, -0
1@@ -23,6 +23,7 @@
2 
3 #include "compositor_surface.h"
4 #include "compositor.h"
5+#include "event.h"
6 #include "util.h"
7 
8 #include <stdio.h>
+2, -5
 1@@ -24,6 +24,7 @@
 2 #include "data_device_manager.h"
 3 #include "data.h"
 4 #include "data_device.h"
 5+#include "internal.h"
 6 #include "seat.h"
 7 
 8 static void create_data_source(struct wl_client * client,
 9@@ -41,11 +42,7 @@ static void get_data_device(struct wl_client * client,
10                             struct wl_resource * resource, uint32_t id,
11                             struct wl_resource * seat_resource)
12 {
13-    struct swc_seat * seat = wl_resource_get_user_data(seat_resource);
14-
15-    printf("data_device_manager.get_data_device\n");
16-
17-    swc_data_device_bind(&seat->data_device, client, id);
18+    swc_data_device_bind(swc.seat->data_device, client, id);
19 }
20 
21 static struct wl_data_device_manager_interface
+1, -0
1@@ -32,6 +32,7 @@ struct swc
2 
3     struct udev * udev;
4 
5+    const struct swc_seat_global * const seat;
6     const struct swc_bindings_global * const bindings;
7     struct swc_compositor * compositor;
8 };
+114, -126
  1@@ -1,7 +1,10 @@
  2 #include "seat.h"
  3+#include "data_device.h"
  4 #include "evdev_device.h"
  5 #include "event.h"
  6 #include "internal.h"
  7+#include "keyboard.h"
  8+#include "pointer.h"
  9 #include "util.h"
 10 
 11 #include <stdlib.h>
 12@@ -9,48 +12,63 @@
 13 #include <string.h>
 14 #include <libudev.h>
 15 
 16+#define SEAT_NAME "seat0"
 17+
 18+static struct
 19+{
 20+    char * name;
 21+    uint32_t capabilities;
 22+
 23+    struct swc_keyboard keyboard;
 24+    struct swc_pointer pointer;
 25+    struct swc_data_device data_device;
 26+
 27+    struct wl_global * global;
 28+    struct wl_list resources;
 29+    struct wl_list devices;
 30+} seat;
 31+
 32+const struct swc_seat_global swc_seat_global = {
 33+    .pointer = &seat.pointer,
 34+    .keyboard = &seat.keyboard,
 35+    .data_device = &seat.data_device
 36+};
 37+
 38 static void handle_key(const struct swc_evdev_device_handler * handler,
 39                        uint32_t time, uint32_t key, uint32_t state)
 40 {
 41-    struct swc_seat * seat = CONTAINER_OF(handler, typeof(*seat),
 42-                                          evdev_handler);
 43-
 44-    swc_keyboard_handle_key(&seat->keyboard, time, key, state);
 45+    swc_keyboard_handle_key(&seat.keyboard, time, key, state);
 46 }
 47 
 48 static void handle_button(const struct swc_evdev_device_handler * handler,
 49                           uint32_t time, uint32_t button, uint32_t state)
 50 {
 51-    struct swc_seat * seat = CONTAINER_OF(handler, typeof(*seat),
 52-                                          evdev_handler);
 53-
 54-    swc_pointer_handle_button(&seat->pointer, time, button, state);
 55+    swc_pointer_handle_button(&seat.pointer, time, button, state);
 56 }
 57 
 58 static void handle_axis(const struct swc_evdev_device_handler * handler,
 59                         uint32_t time, uint32_t axis, wl_fixed_t amount)
 60 {
 61-    struct swc_seat * seat = CONTAINER_OF(handler, typeof(*seat),
 62-                                          evdev_handler);
 63-
 64-    swc_pointer_handle_axis(&seat->pointer, time, axis, amount);
 65+    swc_pointer_handle_axis(&seat.pointer, time, axis, amount);
 66 }
 67 
 68 static void handle_relative_motion
 69     (const struct swc_evdev_device_handler * handler,
 70      uint32_t time, wl_fixed_t dx, wl_fixed_t dy)
 71 {
 72-    struct swc_seat * seat = CONTAINER_OF(handler, typeof(*seat),
 73-                                          evdev_handler);
 74-
 75-    swc_pointer_handle_relative_motion(&seat->pointer, time, dx, dy);
 76+    swc_pointer_handle_relative_motion(&seat.pointer, time, dx, dy);
 77 }
 78 
 79+const static struct swc_evdev_device_handler evdev_handler = {
 80+    .key = &handle_key,
 81+    .button = &handle_button,
 82+    .axis = &handle_axis,
 83+    .relative_motion = &handle_relative_motion
 84+};
 85+
 86 static void handle_keyboard_focus_event(struct wl_listener * listener,
 87                                         void * data)
 88 {
 89-    struct swc_seat * seat = CONTAINER_OF(listener, typeof(*seat),
 90-                                          keyboard_focus_listener);
 91     struct swc_event * event = data;
 92     struct swc_input_focus_event_data * event_data = event->data;
 93 
 94@@ -63,48 +81,48 @@ static void handle_keyboard_focus_event(struct wl_listener * listener,
 95                     = wl_resource_get_client(event_data->new->resource);
 96 
 97                 /* Offer the selection to the new focus. */
 98-                swc_data_device_offer_selection(&seat->data_device, client);
 99+                swc_data_device_offer_selection(&seat.data_device, client);
100             }
101             break;
102     }
103 }
104 
105+static struct wl_listener keyboard_focus_listener = {
106+    .notify = &handle_keyboard_focus_event
107+};
108+
109 static void handle_data_device_event(struct wl_listener * listener, void * data)
110 {
111-    struct swc_seat * seat = CONTAINER_OF(listener, typeof(*seat),
112-                                          data_device_listener);
113     struct swc_event * event = data;
114 
115     switch (event->type)
116     {
117         case SWC_DATA_DEVICE_EVENT_SELECTION_CHANGED:
118-            if (seat->keyboard.focus.resource)
119+            if (seat.keyboard.focus.resource)
120             {
121                 struct wl_client * client
122-                    = wl_resource_get_client(seat->keyboard.focus.resource);
123-                swc_data_device_offer_selection(&seat->data_device, client);
124+                    = wl_resource_get_client(seat.keyboard.focus.resource);
125+                swc_data_device_offer_selection(&seat.data_device, client);
126             }
127             break;
128     }
129 }
130 
131+static struct wl_listener data_device_listener = {
132+    .notify = &handle_data_device_event
133+};
134+
135 /* Wayland Seat Interface */
136 static void get_pointer(struct wl_client * client, struct wl_resource * resource,
137                         uint32_t id)
138 {
139-    struct swc_seat * seat = wl_resource_get_user_data(resource);
140-    struct swc_pointer * pointer = &seat->pointer;
141-
142-    swc_pointer_bind(pointer, client, id);
143+    swc_pointer_bind(&seat.pointer, client, id);
144 }
145 
146 static void get_keyboard(struct wl_client * client, struct wl_resource * resource,
147                          uint32_t id)
148 {
149-    struct swc_seat * seat = wl_resource_get_user_data(resource);
150-    struct swc_keyboard * keyboard = &seat->keyboard;
151-
152-    swc_keyboard_bind(keyboard, client, id);
153+    swc_keyboard_bind(&seat.keyboard, client, id);
154 }
155 
156 static void get_touch(struct wl_client * client, struct wl_resource * resource,
157@@ -122,32 +140,23 @@ static struct wl_seat_interface seat_implementation = {
158 static void bind_seat(struct wl_client * client, void * data, uint32_t version,
159                       uint32_t id)
160 {
161-    struct swc_seat * seat = data;
162     struct wl_resource * resource;
163 
164     if (version >= 2)
165         version = 2;
166 
167     resource = wl_resource_create(client, &wl_seat_interface, version, id);
168-    wl_resource_set_implementation(resource, &seat_implementation, seat,
169+    wl_resource_set_implementation(resource, &seat_implementation, NULL,
170                                    &swc_remove_resource);
171-    wl_list_insert(&seat->resources, wl_resource_get_link(resource));
172+    wl_list_insert(&seat.resources, wl_resource_get_link(resource));
173 
174     if (version >= 2)
175-        wl_seat_send_name(resource, seat->name);
176-
177-    wl_seat_send_capabilities(resource, seat->capabilities);
178-}
179-
180-static void update_capabilities(struct swc_seat * seat)
181-{
182-    struct wl_resource * resource;
183+        wl_seat_send_name(resource, seat.name);
184 
185-    wl_list_for_each(resource, &seat->resources, link)
186-        wl_seat_send_capabilities(resource, seat->capabilities);
187+    wl_seat_send_capabilities(resource, seat.capabilities);
188 }
189 
190-static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
191+static void add_device(struct udev_device * udev_device)
192 {
193     const char * device_seat;
194     const char * device_path;
195@@ -159,11 +168,11 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
196     if (!device_seat)
197         device_seat = "seat0";
198 
199-    if (strcmp(device_seat, seat->name) != 0)
200+    if (strcmp(device_seat, seat.name) != 0)
201         return;
202 
203     device_path = udev_device_get_devnode(udev_device);
204-    device = swc_evdev_device_new(device_path, &seat->evdev_handler);
205+    device = swc_evdev_device_new(device_path, &evdev_handler);
206 
207     if (!device)
208     {
209@@ -171,123 +180,102 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
210         return;
211     }
212 
213-    if (~seat->capabilities & device->capabilities)
214+    if (~seat.capabilities & device->capabilities)
215     {
216-        seat->capabilities |= device->capabilities;
217-        update_capabilities(seat);
218+        struct wl_resource * resource;
219+
220+        seat.capabilities |= device->capabilities;
221+        wl_list_for_each(resource, &seat.resources, link)
222+            wl_seat_send_capabilities(resource, seat.capabilities);
223     }
224 
225-    wl_list_insert(&seat->devices, &device->link);
226+    wl_list_insert(&seat.devices, &device->link);
227+    swc_evdev_device_add_event_sources(device, swc.event_loop);
228 }
229 
230-bool swc_seat_initialize(struct swc_seat * seat, const char * seat_name)
231+static void add_devices()
232 {
233-    seat->name = strdup(seat_name);
234-    seat->capabilities = 0;
235-    seat->keyboard_focus_listener.notify = &handle_keyboard_focus_event;
236-    seat->data_device_listener.notify = &handle_data_device_event;
237-    seat->evdev_handler.key = &handle_key;
238-    seat->evdev_handler.button = &handle_button;
239-    seat->evdev_handler.axis = &handle_axis;
240-    seat->evdev_handler.relative_motion = &handle_relative_motion;
241-
242-    if (!seat->name)
243+    struct udev_enumerate * enumerate;
244+    struct udev_list_entry * entry;
245+    const char * path;
246+    struct udev_device * device;
247+
248+    enumerate = udev_enumerate_new(swc.udev);
249+    udev_enumerate_add_match_subsystem(enumerate, "input");
250+    udev_enumerate_add_match_sysname(enumerate, "event[0-9]*");
251+
252+    udev_enumerate_scan_devices(enumerate);
253+
254+    udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(enumerate))
255+    {
256+        path = udev_list_entry_get_name(entry);
257+        device = udev_device_new_from_syspath(swc.udev, path);
258+        add_device(device);
259+        udev_device_unref(device);
260+    }
261+
262+    udev_enumerate_unref(enumerate);
263+}
264+
265+bool swc_seat_initialize()
266+{
267+    seat.name = SEAT_NAME;
268+    seat.capabilities = 0;
269+    wl_list_init(&seat.resources);
270+    wl_list_init(&seat.devices);
271+
272+    seat.global = wl_global_create(swc.display, &wl_seat_interface, 2,
273+                                       NULL, &bind_seat);
274+
275+    if (!seat.global)
276         goto error0;
277 
278-    if (!swc_data_device_initialize(&seat->data_device))
279+    if (!swc_data_device_initialize(&seat.data_device))
280     {
281         printf("could not initialize data device\n");
282         goto error1;
283     }
284 
285-    if (!swc_keyboard_initialize(&seat->keyboard))
286+    wl_signal_add(&seat.data_device.event_signal, &data_device_listener);
287+
288+    if (!swc_keyboard_initialize(&seat.keyboard))
289     {
290         printf("could not initialize keyboard\n");
291         goto error2;
292     }
293 
294-    wl_signal_add(&seat->keyboard.focus.event_signal,
295-                  &seat->keyboard_focus_listener);
296+    wl_signal_add(&seat.keyboard.focus.event_signal, &keyboard_focus_listener);
297 
298-    if (!swc_pointer_initialize(&seat->pointer))
299+    if (!swc_pointer_initialize(&seat.pointer))
300     {
301         printf("could not initialize pointer\n");
302         goto error3;
303     }
304 
305-    wl_signal_add(&seat->data_device.event_signal, &seat->data_device_listener);
306-
307-    wl_list_init(&seat->resources);
308-    wl_signal_init(&seat->destroy_signal);
309-    wl_list_init(&seat->devices);
310-    swc_seat_add_devices(seat);
311+    add_devices();
312 
313     return true;
314 
315   error3:
316-    swc_keyboard_finish(&seat->keyboard);
317+    swc_keyboard_finish(&seat.keyboard);
318   error2:
319-    swc_data_device_finish(&seat->data_device);
320+    swc_data_device_finish(&seat.data_device);
321   error1:
322-    free(seat->name);
323+    wl_global_destroy(seat.global);
324   error0:
325     return false;
326 }
327 
328-void swc_seat_finish(struct swc_seat * seat)
329+void swc_seat_finalize()
330 {
331     struct swc_evdev_device * device, * tmp;
332 
333-    wl_signal_emit(&seat->destroy_signal, seat);
334+    swc_pointer_finish(&seat.pointer);
335+    swc_keyboard_finish(&seat.keyboard);
336 
337-    swc_pointer_finish(&seat->pointer);
338-    swc_keyboard_finish(&seat->keyboard);
339-
340-    free(seat->name);
341-
342-    wl_list_for_each_safe(device, tmp, &seat->devices, link)
343-    {
344+    wl_list_for_each_safe(device, tmp, &seat.devices, link)
345         swc_evdev_device_destroy(device);
346-    }
347-}
348-
349-void swc_seat_add_globals(struct swc_seat * seat, struct wl_display * display)
350-{
351-    wl_global_create(display, &wl_seat_interface, 2, seat, &bind_seat);
352-}
353-
354-void swc_seat_add_event_sources(struct swc_seat * seat,
355-                                struct wl_event_loop * event_loop)
356-{
357-    struct swc_evdev_device * device;
358-
359-    wl_list_for_each(device, &seat->devices, link)
360-    {
361-        swc_evdev_device_add_event_sources(device, event_loop);
362-    }
363-}
364 
365-void swc_seat_add_devices(struct swc_seat * seat)
366-{
367-    struct udev_enumerate * enumerate;
368-    struct udev_list_entry * entry;
369-    const char * path;
370-    struct udev_device * device;
371-
372-    enumerate = udev_enumerate_new(swc.udev);
373-    udev_enumerate_add_match_subsystem(enumerate, "input");
374-    udev_enumerate_add_match_sysname(enumerate, "event[0-9]*");
375-
376-    udev_enumerate_scan_devices(enumerate);
377-
378-    udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(enumerate))
379-    {
380-        path = udev_list_entry_get_name(entry);
381-        device = udev_device_new_from_syspath(swc.udev, path);
382-        add_device(seat, device);
383-        udev_device_unref(device);
384-    }
385-
386-    udev_enumerate_unref(enumerate);
387+    wl_global_destroy(seat.global);
388 }
389 
+29, -38
 1@@ -1,49 +1,40 @@
 2+/* swc: libswc/seat.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25 #ifndef SWC_SEAT_H
26 #define SWC_SEAT_H
27 
28-#include "xkb.h"
29-#include "data_device.h"
30-#include "keyboard.h"
31-#include "pointer.h"
32-#include "evdev_device.h"
33-
34-#include <stdint.h>
35 #include <stdbool.h>
36-#include <wayland-util.h>
37-
38-struct wl_display;
39-struct wl_event_loop;
40 
41-struct swc_seat
42+struct swc_seat_global
43 {
44-    char * name;
45-    uint32_t capabilities;
46-
47-    struct wl_list resources;
48-    struct wl_signal destroy_signal;
49-
50-    struct swc_data_device data_device;
51-    struct wl_listener data_device_listener;
52-
53-    struct swc_keyboard keyboard;
54-    struct wl_listener keyboard_focus_listener;
55-
56-    struct swc_pointer pointer;
57-
58-    struct wl_list devices;
59-    struct swc_evdev_device_handler evdev_handler;
60+    struct swc_pointer * pointer;
61+    struct swc_keyboard * keyboard;
62+    struct swc_data_device * data_device;
63 };
64 
65-bool swc_seat_initialize(struct swc_seat * seat, const char * seat_name);
66-
67-void swc_seat_finish(struct swc_seat * seat);
68-
69-void swc_seat_add_globals(struct swc_seat * seat, struct wl_display * display);
70-
71-void swc_seat_add_event_sources(struct swc_seat * seat,
72-                                struct wl_event_loop * event_loop);
73-
74-void swc_seat_add_devices(struct swc_seat * seat);
75+bool swc_seat_initialize();
76+void swc_seat_finalize();
77 
78 #endif
79 
+24, -7
 1@@ -25,24 +25,32 @@
 2 #include "bindings.h"
 3 #include "compositor.h"
 4 #include "internal.h"
 5+#include "keyboard.h"
 6+#include "pointer.h"
 7+#include "seat.h"
 8 #include "shell.h"
 9 #include "window.h"
10 
11 #include <libudev.h>
12 
13+extern const struct swc_seat_global swc_seat_global;
14 extern const struct swc_bindings_global swc_bindings_global;
15 static struct swc_compositor compositor;
16 
17 struct swc swc = {
18+    .seat = &swc_seat_global,
19     .bindings = &swc_bindings_global,
20     .compositor = &compositor
21 };
22 
23 static void setup_compositor()
24 {
25-    compositor.seat.keyboard.handler = swc.bindings->keyboard_handler;
26-    wl_signal_add(&compositor.seat.pointer.focus.event_signal,
27+    swc.seat->keyboard->handler = swc.bindings->keyboard_handler;
28+    swc.seat->pointer->handler = &compositor.pointer_handler;
29+    wl_signal_add(&swc.seat->pointer->focus.event_signal,
30                   swc_window_enter_listener);
31+    wl_signal_add(&swc.seat->pointer->event_signal,
32+                  &compositor.pointer_listener);
33 }
34 
35 EXPORT
36@@ -60,16 +68,22 @@ bool swc_initialize(struct wl_display * display,
37         goto error0;
38     }
39 
40+    if (!swc_seat_initialize())
41+    {
42+        fprintf(stderr, "Could not initialize seat\n");
43+        goto error1;
44+    }
45+
46     if (!swc_bindings_initialize())
47     {
48         fprintf(stderr, "Could not initialize bindings\n");
49-        goto error1;
50+        goto error2;
51     }
52 
53     if (!swc_compositor_initialize(&compositor, display, swc.event_loop))
54     {
55         fprintf(stderr, "Could not initialize compositor\n");
56-        goto error2;
57+        goto error3;
58     }
59 
60     swc_compositor_add_globals(&compositor, display);
61@@ -77,17 +91,19 @@ bool swc_initialize(struct wl_display * display,
62     if (!swc_shell_initialize())
63     {
64         fprintf(stderr, "Could not initialize shell\n");
65-        goto error3;
66+        goto error4;
67     }
68 
69     setup_compositor();
70 
71     return true;
72 
73-  error3:
74+  error4:
75     swc_compositor_finish(&compositor);
76-  error2:
77+  error3:
78     swc_bindings_finalize();
79+  error2:
80+    swc_seat_finalize();
81   error1:
82     udev_unref(swc.udev);
83   error0:
84@@ -100,6 +116,7 @@ void swc_finalize()
85     swc_shell_finalize();
86     swc_compositor_finish(&compositor);
87     swc_bindings_finalize();
88+    swc_seat_finalize();
89     udev_unref(swc.udev);
90 }
91 
+4, -2
 1@@ -24,7 +24,10 @@
 2 #include "window.h"
 3 #include "compositor.h"
 4 #include "compositor_surface.h"
 5+#include "event.h"
 6 #include "internal.h"
 7+#include "keyboard.h"
 8+#include "seat.h"
 9 #include "swc.h"
10 
11 #include <stdlib.h>
12@@ -70,8 +73,7 @@ void swc_window_focus(struct swc_window * window)
13     if (INTERNAL(window)->impl->focus)
14         INTERNAL(window)->impl->focus(window);
15 
16-    swc_keyboard_set_focus(&swc.compositor->seat.keyboard,
17-                           INTERNAL(window)->surface);
18+    swc_keyboard_set_focus(swc.seat->keyboard, INTERNAL(window)->surface);
19 }
20 
21 EXPORT