commit 441ff74
Michael Forney
·
2013-06-14 11:05:39 +0000 UTC
parent f60ae11
Pass stuff from evdev up through events
4 files changed,
+270,
-140
+51,
-23
1@@ -1,6 +1,7 @@
2 #include "evdev_device.h"
3
4 #include "seat.h"
5+#include "event.h"
6
7 #include <stdlib.h>
8 #include <stdio.h>
9@@ -18,49 +19,57 @@ static inline uint32_t timeval_to_msec(struct timeval * time)
10 }
11
12 static void handle_key_event(struct swc_evdev_device * device,
13- struct input_event * event)
14+ struct input_event * input_event)
15 {
16- uint32_t time = timeval_to_msec(&event->time);
17+ struct swc_event event;
18+ struct swc_evdev_device_event_data data;
19
20- if ((event->code >= BTN_MISC && event->code <= BTN_GEAR_UP)
21- || event->code >= BTN_TRIGGER_HAPPY)
22+ event.data = &data;
23+ data.time = timeval_to_msec(&input_event->time);
24+
25+ if ((input_event->code >= BTN_MISC && input_event->code <= BTN_GEAR_UP)
26+ || input_event->code >= BTN_TRIGGER_HAPPY)
27 {
28- swc_seat_handle_button(device->seat, time, event->value,
29- event->value ? WL_POINTER_BUTTON_STATE_PRESSED
30- : WL_POINTER_BUTTON_STATE_RELEASED);
31+ event.type = SWC_EVDEV_DEVICE_EVENT_BUTTON;
32+ data.button.button = input_event->code;
33+ data.button.state = input_event->value ? WL_POINTER_BUTTON_STATE_PRESSED
34+ : WL_POINTER_BUTTON_STATE_RELEASED;
35 }
36 else
37 {
38- swc_seat_handle_key(device->seat, time, event->code,
39- event->value ? WL_KEYBOARD_KEY_STATE_PRESSED
40- : WL_KEYBOARD_KEY_STATE_RELEASED);
41+ event.type = SWC_EVDEV_DEVICE_EVENT_KEY;
42+ data.key.key = input_event->code;
43+ data.key.state = input_event->value ? WL_KEYBOARD_KEY_STATE_PRESSED
44+ : WL_KEYBOARD_KEY_STATE_RELEASED;
45 }
46+
47+ wl_signal_emit(&device->event_signal, &event);
48 }
49
50 static void handle_rel_event(struct swc_evdev_device * device,
51- struct input_event * event)
52+ struct input_event * input_event)
53 {
54- //printf("rel event\n");
55-
56- switch (event->code)
57+ switch (input_event->code)
58 {
59 case REL_X:
60- //printf("rel_x: %d\n", event->value);
61+ device->motion.rel.dx += input_event->value;
62+ device->motion.rel.pending = true;
63 break;
64 case REL_Y:
65- //printf("rel_y: %d\n", event->value);
66+ device->motion.rel.dy += input_event->value;
67+ device->motion.rel.pending = true;
68 break;
69 }
70 }
71
72 static void handle_abs_event(struct swc_evdev_device * device,
73- struct input_event * event)
74+ struct input_event * input_event)
75 {
76 printf("abs event\n");
77 }
78
79 static void (* event_handlers[])(struct swc_evdev_device * device,
80- struct input_event * event) = {
81+ struct input_event * input_event) = {
82 [EV_KEY] = &handle_key_event,
83 [EV_REL] = &handle_rel_event,
84 [EV_ABS] = &handle_abs_event
85@@ -75,6 +84,24 @@ static bool is_motion_event(struct input_event * event)
86 static void handle_motion_events(struct swc_evdev_device * device,
87 uint32_t time)
88 {
89+ struct swc_event event;
90+ struct swc_evdev_device_event_data data;
91+
92+ event.data = &data;
93+ data.time = time;
94+
95+ if (device->motion.rel.pending)
96+ {
97+ event.type = SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION;
98+ data.relative_motion.dx = wl_fixed_from_int(device->motion.rel.dx);
99+ data.relative_motion.dy = wl_fixed_from_int(device->motion.rel.dy);
100+
101+ wl_signal_emit(&device->event_signal, &event);
102+
103+ device->motion.rel.pending = false;
104+ device->motion.rel.dx = 0;
105+ device->motion.rel.dy = 0;
106+ }
107 }
108
109 static void process_events(struct swc_evdev_device * device,
110@@ -121,7 +148,6 @@ static int handle_data(int fd, uint32_t mask, void * data)
111 }
112
113 bool swc_evdev_device_initialize(struct swc_evdev_device * device,
114- struct swc_seat * seat,
115 struct udev_device * udev_device)
116 {
117 const char * path, * model, * vendor;
118@@ -134,10 +160,12 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
119 vendor = udev_device_get_property_value(udev_device, "ID_VENDOR")
120 ?: "unknown";
121
122- device->seat = seat;
123 device->model = strdup(model);
124 device->vendor = strdup(vendor);
125 device->fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
126+ memset(&device->motion, 0, sizeof device->motion);
127+
128+ wl_signal_init(&device->event_signal);
129
130 if (device->fd == -1)
131 {
132@@ -150,7 +178,7 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
133 ioctl(device->fd, EVIOCGBIT(0, sizeof ev_bits), &ev_bits);
134
135 device->capabilities = 0;
136- /* Currently, I don't care about touch devices. */
137+ /* XXX: touch devices */
138
139 if (udev_device_get_property_value(udev_device, "ID_INPUT_KEYBOARD"))
140 {
141@@ -187,9 +215,9 @@ bool swc_evdev_device_initialize(struct swc_evdev_device * device,
142 ioctl(device->fd, EVIOCGBIT(EV_ABS, sizeof abs_bits), &abs_bits);
143
144 if (TEST_BIT(abs_bits, ABS_X))
145- ioctl(device->fd, EVIOCGABS(ABS_X), &device->abs.info.x);
146+ ioctl(device->fd, EVIOCGABS(ABS_X), &device->motion.abs.info.x);
147 if (TEST_BIT(abs_bits, ABS_Y))
148- ioctl(device->fd, EVIOCGABS(ABS_X), &device->abs.info.y);
149+ ioctl(device->fd, EVIOCGABS(ABS_X), &device->motion.abs.info.y);
150 }
151 }
152
+46,
-12
1@@ -6,10 +6,40 @@
2 #include <linux/input.h>
3 #include <wayland-server.h>
4
5-struct swc_evdev_device
6+enum swc_evdev_device_event_type
7 {
8- struct swc_seat * seat;
9+ SWC_EVDEV_DEVICE_EVENT_KEY,
10+ SWC_EVDEV_DEVICE_EVENT_BUTTON,
11+ SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION,
12+ SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION
13+};
14+
15+struct swc_evdev_device_event_data
16+{
17+ uint32_t time;
18+ union
19+ {
20+ struct
21+ {
22+ wl_fixed_t dx, dy;
23+ } relative_motion;
24+
25+ struct
26+ {
27+ uint32_t key;
28+ enum wl_keyboard_key_state state;
29+ } key;
30
31+ struct
32+ {
33+ uint32_t button;
34+ enum wl_pointer_button_state state;
35+ } button;
36+ };
37+};
38+
39+struct swc_evdev_device
40+{
41 int fd;
42 char * model, * vendor;
43
44@@ -17,26 +47,30 @@ struct swc_evdev_device
45 {
46 struct
47 {
48- struct input_absinfo x, y;
49- } info;
50+ struct
51+ {
52+ struct input_absinfo x, y;
53+ } info;
54
55- int32_t x, y;
56- bool pending;
57- } abs;
58+ int32_t x, y;
59+ bool pending;
60+ } abs;
61
62- struct
63- {
64- bool pending;
65- } rel;
66+ struct
67+ {
68+ int32_t dx, dy;
69+ bool pending;
70+ } rel;
71+ } motion;
72
73 uint32_t capabilities;
74
75 struct wl_event_source * source;
76+ struct wl_signal event_signal;
77 struct wl_list link;
78 };
79
80 bool swc_evdev_device_initialize(struct swc_evdev_device * device,
81- struct swc_seat * seat,
82 struct udev_device * udev_device);
83
84 void swc_evdev_device_finish(struct swc_evdev_device * device);
M
seat.c
+173,
-99
1@@ -3,17 +3,164 @@
2 #include "evdev_device.h"
3 #include "util.h"
4 #include "binding.h"
5+#include "event.h"
6
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10
11+struct evdev_device_entry
12+{
13+ struct swc_evdev_device device;
14+ struct wl_listener event_listener;
15+ struct swc_seat * seat;
16+ struct wl_list link;
17+};
18+
19 struct wl_seat_interface swc_seat_interface = {
20 .get_pointer = &swc_seat_get_pointer,
21 .get_keyboard = &swc_seat_get_keyboard,
22 .get_touch = &swc_seat_get_touch
23 };
24
25+static void handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
26+ uint32_t state)
27+{
28+ uint32_t * pressed_key;
29+ struct swc_keyboard * keyboard = &seat->keyboard;
30+ struct swc_xkb * xkb = &seat->xkb;
31+ struct wl_display * display;
32+ uint32_t serial;
33+ enum xkb_key_direction direction;
34+
35+ if (keyboard->focus.resource)
36+ {
37+ struct wl_client * focus_client
38+ = wl_resource_get_client(keyboard->focus.resource);
39+ display = wl_client_get_display(focus_client);
40+ }
41+
42+ /* Update keyboard state state */
43+ wl_array_for_each(pressed_key, &keyboard->keys)
44+ {
45+ if (*pressed_key == key)
46+ {
47+ /* Ignore repeat evdev events. */
48+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
49+ return;
50+ else
51+ {
52+ /* Remove the key from the array */
53+ uint32_t bytes_to_copy = keyboard->keys.size + 1
54+ - (((void *) pressed_key) - keyboard->keys.data);
55+
56+ if (bytes_to_copy > 0)
57+ memmove(pressed_key, pressed_key + 1, bytes_to_copy);
58+
59+ keyboard->keys.size -= sizeof key;
60+
61+ break;
62+ }
63+ }
64+ }
65+
66+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
67+ {
68+ //keyboard->grab_key = key;
69+ //keyboard->grab_time = time;
70+ pressed_key = wl_array_add(&keyboard->keys, sizeof key);
71+ *pressed_key = key;
72+ }
73+
74+ /* See if the key press is not handled by the compositor */
75+ if (!(keyboard->handler && keyboard->handler->key)
76+ || !keyboard->handler->key(keyboard, time, key, state))
77+ {
78+ if (keyboard->focus.resource)
79+ {
80+ serial = wl_display_next_serial(display);
81+ wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
82+
83+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
84+ printf("\t-> sent to client\n");
85+ }
86+ }
87+
88+ /* Update XKB state. Apparently the keycodes are offset by 8 in XKB. */
89+ direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN
90+ : XKB_KEY_UP;
91+ xkb_state_update_key(xkb->state, key + 8, direction);
92+
93+ {
94+ uint32_t mods_depressed, mods_latched, mods_locked, mods_active;
95+ uint32_t group;
96+
97+ mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED);
98+ mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED);
99+ mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED);
100+ mods_active = mods_depressed | mods_latched;
101+
102+ group = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE);
103+
104+ if (mods_depressed != keyboard->modifiers.mods_depressed
105+ || mods_latched != keyboard->modifiers.mods_latched
106+ || mods_locked != keyboard->modifiers.mods_locked
107+ || group != keyboard->modifiers.group)
108+ {
109+ if (keyboard->focus.resource)
110+ {
111+ serial = wl_display_next_serial(display);
112+ wl_keyboard_send_modifiers(keyboard->focus.resource, serial,
113+ mods_depressed, mods_latched,
114+ mods_locked, group);
115+ }
116+ }
117+
118+ keyboard->modifiers.mods_depressed = mods_depressed;
119+ keyboard->modifiers.mods_latched = mods_latched;
120+ keyboard->modifiers.mods_locked = mods_locked;
121+ keyboard->modifiers.group = group;
122+ }
123+}
124+
125+static void handle_button(struct swc_seat * seat, uint32_t time,
126+ uint32_t button, uint32_t state)
127+{
128+}
129+
130+static void handle_relative_motion(struct swc_seat * seat, uint32_t time,
131+ wl_fixed_t dx, wl_fixed_t dy)
132+{
133+}
134+
135+static void handle_evdev_event(struct wl_listener * listener, void * data)
136+{
137+ struct evdev_device_entry * entry;
138+ struct swc_event * event = data;
139+ struct swc_evdev_device_event_data * evdev_data = event->data;
140+
141+ entry = wl_container_of(listener, entry, event_listener);
142+
143+ switch (event->type)
144+ {
145+ case SWC_EVDEV_DEVICE_EVENT_KEY:
146+ handle_key(entry->seat, evdev_data->time, evdev_data->key.key,
147+ evdev_data->key.state);
148+ break;
149+ case SWC_EVDEV_DEVICE_EVENT_BUTTON:
150+ handle_button(entry->seat, evdev_data->time,
151+ evdev_data->button.button, evdev_data->button.state);
152+ break;
153+ case SWC_EVDEV_DEVICE_EVENT_RELATIVE_MOTION:
154+ handle_relative_motion(entry->seat, evdev_data->time,
155+ evdev_data->relative_motion.dx,
156+ evdev_data->relative_motion.dy);
157+ break;
158+ case SWC_EVDEV_DEVICE_EVENT_ABSOLUTE_MOTION:
159+ break;
160+ }
161+}
162+
163 static void bind_seat(struct wl_client * client, void * data, uint32_t version,
164 uint32_t id)
165 {
166@@ -40,7 +187,7 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
167 {
168 const char * device_seat;
169 const char * device_path;
170- struct swc_evdev_device * evdev_device;
171+ struct evdev_device_entry * entry;
172
173 device_seat = udev_device_get_property_value(udev_device, "ID_SEAT");
174
175@@ -51,16 +198,27 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
176 if (strcmp(device_seat, seat->name) != 0)
177 return;
178
179- evdev_device = malloc(sizeof *evdev_device);
180+ entry = malloc(sizeof *entry);
181
182- if (!swc_evdev_device_initialize(evdev_device, seat, udev_device))
183+ if (!entry)
184 {
185- free(evdev_device);
186+ printf("could not allocate evdev device\n");
187 return;
188 }
189
190+ entry->seat = seat;
191+ entry->event_listener.notify = &handle_evdev_event;
192+
193+ if (!swc_evdev_device_initialize(&entry->device, udev_device))
194+ {
195+ free(entry);
196+ return;
197+ }
198+
199+ wl_signal_add(&entry->device.event_signal, &entry->event_listener);
200+
201 if (!(seat->capabilities & WL_SEAT_CAPABILITY_POINTER)
202- && evdev_device->capabilities & WL_SEAT_CAPABILITY_POINTER)
203+ && entry->device.capabilities & WL_SEAT_CAPABILITY_POINTER)
204 {
205 printf("initializing pointer\n");
206 swc_pointer_initialize(&seat->pointer);
207@@ -69,7 +227,7 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
208 }
209
210 if (!(seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
211- && evdev_device->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
212+ && entry->device.capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
213 {
214 printf("initializing keyboard\n");
215 swc_keyboard_initialize(&seat->keyboard);
216@@ -77,9 +235,9 @@ static void add_device(struct swc_seat * seat, struct udev_device * udev_device)
217 update_capabilities(seat);
218 }
219
220- seat->capabilities |= evdev_device->capabilities;
221+ seat->capabilities |= entry->device.capabilities;
222
223- wl_list_insert(&seat->devices, &evdev_device->link);
224+ wl_list_insert(&seat->devices, &entry->link);
225 }
226
227 bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev,
228@@ -109,7 +267,7 @@ bool swc_seat_initialize(struct swc_seat * seat, struct udev * udev,
229
230 void swc_seat_finish(struct swc_seat * seat)
231 {
232- struct swc_evdev_device * device, * tmp;
233+ struct evdev_device_entry * entry, * tmp;
234
235 wl_signal_emit(&seat->destroy_signal, seat);
236
237@@ -122,10 +280,10 @@ void swc_seat_finish(struct swc_seat * seat)
238 free(seat->name);
239 swc_xkb_finish(&seat->xkb);
240
241- wl_list_for_each_safe(device, tmp, &seat->devices, link)
242+ wl_list_for_each_safe(entry, tmp, &seat->devices, link)
243 {
244- swc_evdev_device_finish(device);
245- free(device);
246+ swc_evdev_device_finish(&entry->device);
247+ free(entry);
248 }
249 }
250
251@@ -137,11 +295,11 @@ void swc_seat_add_globals(struct swc_seat * seat, struct wl_display * display)
252 void swc_seat_add_event_sources(struct swc_seat * seat,
253 struct wl_event_loop * event_loop)
254 {
255- struct swc_evdev_device * device;
256+ struct evdev_device_entry * entry;
257
258- wl_list_for_each(device, &seat->devices, link)
259+ wl_list_for_each(entry, &seat->devices, link)
260 {
261- swc_evdev_device_add_event_sources(device, event_loop);
262+ swc_evdev_device_add_event_sources(&entry->device, event_loop);
263 }
264 }
265
266@@ -169,90 +327,6 @@ void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev)
267 udev_enumerate_unref(enumerate);
268 }
269
270-void swc_seat_handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
271- uint32_t state)
272-{
273- uint32_t * pressed_key;
274- struct swc_keyboard * keyboard = &seat->keyboard;
275- struct swc_xkb * xkb = &seat->xkb;
276- struct wl_display * display;
277- uint32_t serial;
278- enum xkb_key_direction direction;
279-
280- /* Update XKB state */
281- direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN
282- : XKB_KEY_UP;
283-
284- /* Apparently these are offset by 8 in X. */
285- xkb_state_update_key(xkb->state, key + 8, direction);
286-
287- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
288- {
289- //keyboard->grab_key = key;
290- //keyboard->grab_time = time;
291- pressed_key = wl_array_add(&keyboard->keys, sizeof key);
292- *pressed_key = key;
293- }
294- else
295- {
296- wl_array_for_each(pressed_key, &keyboard->keys)
297- {
298- if (*pressed_key == key)
299- {
300- /* Remove the key from the array */
301- uint32_t bytes_to_copy = keyboard->keys.size + 1
302- - (((void *) pressed_key) - keyboard->keys.data);
303- memmove(pressed_key, pressed_key + 1, bytes_to_copy);
304- --keyboard->keys.size;
305- break;
306- }
307- }
308- }
309-
310- /* See if the key press is not handled by the compositor */
311- if (!(keyboard->handler && keyboard->handler->key)
312- || !keyboard->handler->key(keyboard, time, key, state))
313- {
314- if (keyboard->focus.resource)
315- {
316- serial = wl_display_next_serial(display);
317- wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
318-
319- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
320- printf("\t-> sent to client\n");
321- }
322- }
323-
324- {
325- uint32_t mods_depressed, mods_latched, mods_locked, mods_active;
326- uint32_t layout;
327-
328- mods_depressed = xkb_state_serialize_mods(xkb->state, XKB_STATE_DEPRESSED);
329- mods_latched = xkb_state_serialize_mods(xkb->state, XKB_STATE_LATCHED);
330- mods_locked = xkb_state_serialize_mods(xkb->state, XKB_STATE_LOCKED);
331- mods_active = mods_depressed | mods_latched;
332-
333- layout = xkb_state_serialize_layout(xkb->state, XKB_STATE_LAYOUT_EFFECTIVE);
334-
335- if (mods_depressed != keyboard->modifiers.mods_depressed
336- || mods_latched != keyboard->modifiers.mods_latched
337- || mods_locked != keyboard->modifiers.mods_locked
338- || layout != keyboard->modifiers.group)
339- {
340- }
341-
342- keyboard->modifiers.mods_depressed = mods_depressed;
343- keyboard->modifiers.mods_latched = mods_latched;
344- keyboard->modifiers.mods_locked = mods_locked;
345- keyboard->modifiers.group = layout;
346- }
347-}
348-
349-void swc_seat_handle_button(struct swc_seat * seat, uint32_t time,
350- uint32_t button, uint32_t state)
351-{
352-}
353-
354 /* Wayland Seat Interface */
355 void swc_seat_get_pointer(struct wl_client * client,
356 struct wl_resource * resource, uint32_t id)
M
seat.h
+0,
-6
1@@ -38,12 +38,6 @@ void swc_seat_add_event_sources(struct swc_seat * seat,
2
3 void swc_seat_add_devices(struct swc_seat * seat, struct udev * udev);
4
5-void swc_seat_handle_key(struct swc_seat * seat, uint32_t time, uint32_t key,
6- uint32_t state);
7-
8-void swc_seat_handle_button(struct swc_seat * seat, uint32_t time,
9- uint32_t button, uint32_t state);
10-
11 /* Wayland Seat Interface */
12 extern struct wl_seat_interface swc_seat_interface;
13