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
M seat.c
M seat.h
+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