Use events instead of callbacks for capability registration
[platform/upstream/libinput.git] / src / libinput.c
1 /*
2  * Copyright © 2013 Jonas Ådahl
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/epoll.h>
29 #include <unistd.h>
30 #include <assert.h>
31
32 #include "libinput.h"
33 #include "evdev.h"
34 #include "libinput-private.h"
35
36 struct libinput_source {
37         libinput_source_dispatch_t dispatch;
38         void *user_data;
39         int fd;
40         struct list link;
41 };
42
43 struct libinput_source *
44 libinput_add_fd(struct libinput *libinput,
45                 int fd,
46                 libinput_source_dispatch_t dispatch,
47                 void *user_data)
48 {
49         struct libinput_source *source;
50         struct epoll_event ep;
51
52         source = malloc(sizeof *source);
53         if (!source)
54                 return NULL;
55
56         source->dispatch = dispatch;
57         source->user_data = user_data;
58         source->fd = fd;
59
60         memset(&ep, 0, sizeof ep);
61         ep.events = EPOLLIN;
62         ep.data.ptr = source;
63
64         if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
65                 close(source->fd);
66                 free(source);
67                 return NULL;
68         }
69
70         return source;
71 }
72
73 void
74 libinput_remove_source(struct libinput *libinput,
75                        struct libinput_source *source)
76 {
77         epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
78         close(source->fd);
79         source->fd = -1;
80         list_insert(&libinput->source_destroy_list, &source->link);
81 }
82
83 LIBINPUT_EXPORT struct libinput *
84 libinput_create(void)
85 {
86         struct libinput *libinput;
87
88         libinput = zalloc(sizeof *libinput);
89         if (!libinput)
90                 return NULL;
91
92         list_init(&libinput->source_destroy_list);
93
94         libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);;
95         if (libinput->epoll_fd < 0)
96                 return NULL;
97
98         return libinput;
99 }
100
101 LIBINPUT_EXPORT void
102 libinput_destroy(struct libinput *libinput)
103 {
104         struct libinput_event *event;
105
106         while ((event = libinput_get_event(libinput)))
107                free(event);
108         free(libinput->events);
109
110         close(libinput->epoll_fd);
111         free(libinput);
112 }
113
114 LIBINPUT_EXPORT int
115 libinput_get_fd(struct libinput *libinput)
116 {
117         return libinput->epoll_fd;
118 }
119
120 LIBINPUT_EXPORT int
121 libinput_dispatch(struct libinput *libinput)
122 {
123         struct libinput_source *source, *next;
124         struct epoll_event ep[32];
125         int i, count;
126
127         count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0);
128         if (count < 0)
129                 return -1;
130
131         for (i = 0; i < count; ++i) {
132                 source = ep[i].data.ptr;
133                 if (source->fd == -1)
134                         continue;
135
136                 source->dispatch(source->user_data);
137         }
138
139         list_for_each_safe(source, next, &libinput->source_destroy_list, link)
140                 free(source);
141         list_init(&libinput->source_destroy_list);
142
143         return 0;
144 }
145
146 static void
147 init_event_base(struct libinput_event *event,
148                 enum libinput_event_type type,
149                 struct libinput_device *device)
150 {
151         event->type = type;
152         event->device = device;
153 }
154
155 static void
156 post_device_event(struct libinput_device *device,
157                   enum libinput_event_type type,
158                   struct libinput_event *event)
159 {
160         init_event_base(event, type, device);
161         libinput_post_event(device->libinput, event);
162 }
163
164 void
165 device_register_capability(struct libinput_device *device,
166                            enum libinput_device_capability capability)
167 {
168         struct libinput_event_device_register_capability *capability_event;
169
170         capability_event = malloc(sizeof *capability_event);
171
172         *capability_event = (struct libinput_event_device_register_capability) {
173                 .capability = capability,
174         };
175
176         post_device_event(device,
177                           LIBINPUT_EVENT_DEVICE_REGISTER_CAPABILITY,
178                           &capability_event->base);
179 }
180
181 void
182 device_unregister_capability(struct libinput_device *device,
183                              enum libinput_device_capability capability)
184 {
185         struct libinput_event_device_unregister_capability *capability_event;
186
187         capability_event = malloc(sizeof *capability_event);
188
189         *capability_event = (struct libinput_event_device_unregister_capability) {
190                 .capability = capability,
191         };
192
193         post_device_event(device,
194                           LIBINPUT_EVENT_DEVICE_UNREGISTER_CAPABILITY,
195                           &capability_event->base);
196 }
197
198 void
199 keyboard_notify_key(struct libinput_device *device,
200                     uint32_t time,
201                     uint32_t key,
202                     enum libinput_keyboard_key_state state)
203 {
204         struct libinput_event_keyboard_key *key_event;
205
206         key_event = malloc(sizeof *key_event);
207         if (!key_event)
208                 return;
209
210         *key_event = (struct libinput_event_keyboard_key) {
211                 .time = time,
212                 .key = key,
213                 .state = state,
214         };
215
216         post_device_event(device,
217                           LIBINPUT_EVENT_KEYBOARD_KEY,
218                           &key_event->base);
219 }
220
221 void
222 pointer_notify_motion(struct libinput_device *device,
223                       uint32_t time,
224                       li_fixed_t dx,
225                       li_fixed_t dy)
226 {
227         struct libinput_event_pointer_motion *motion_event;
228
229         motion_event = malloc(sizeof *motion_event);
230         if (!motion_event)
231                 return;
232
233         *motion_event = (struct libinput_event_pointer_motion) {
234                 .time = time,
235                 .dx = dx,
236                 .dy = dy,
237         };
238
239         post_device_event(device,
240                           LIBINPUT_EVENT_POINTER_MOTION,
241                           &motion_event->base);
242 }
243
244 void
245 pointer_notify_motion_absolute(struct libinput_device *device,
246                                uint32_t time,
247                                li_fixed_t x,
248                                li_fixed_t y)
249 {
250         struct libinput_event_pointer_motion_absolute *motion_absolute_event;
251
252         motion_absolute_event = malloc(sizeof *motion_absolute_event);
253         if (!motion_absolute_event)
254                 return;
255
256         *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
257                 .time = time,
258                 .x = x,
259                 .y = y,
260         };
261
262         post_device_event(device,
263                           LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
264                           &motion_absolute_event->base);
265 }
266
267 void
268 pointer_notify_button(struct libinput_device *device,
269                       uint32_t time,
270                       int32_t button,
271                       enum libinput_pointer_button_state state)
272 {
273         struct libinput_event_pointer_button *button_event;
274
275         button_event = malloc(sizeof *button_event);
276         if (!button_event)
277                 return;
278
279         *button_event = (struct libinput_event_pointer_button) {
280                 .time = time,
281                 .button = button,
282                 .state = state,
283         };
284
285         post_device_event(device,
286                           LIBINPUT_EVENT_POINTER_BUTTON,
287                           &button_event->base);
288 }
289
290 void
291 pointer_notify_axis(struct libinput_device *device,
292                     uint32_t time,
293                     enum libinput_pointer_axis axis,
294                     li_fixed_t value)
295 {
296         struct libinput_event_pointer_axis *axis_event;
297
298         axis_event = malloc(sizeof *axis_event);
299         if (!axis_event)
300                 return;
301
302         *axis_event = (struct libinput_event_pointer_axis) {
303                 .time = time,
304                 .axis = axis,
305                 .value = value,
306         };
307
308         post_device_event(device,
309                           LIBINPUT_EVENT_POINTER_AXIS,
310                           &axis_event->base);
311 }
312
313 void
314 touch_notify_touch(struct libinput_device *device,
315                    uint32_t time,
316                    int32_t slot,
317                    li_fixed_t x,
318                    li_fixed_t y,
319                    enum libinput_touch_type touch_type)
320 {
321         struct libinput_event_touch_touch *touch_event;
322
323         touch_event = malloc(sizeof *touch_event);
324         if (!touch_event)
325                 return;
326
327         *touch_event = (struct libinput_event_touch_touch) {
328                 .time = time,
329                 .slot = slot,
330                 .x = x,
331                 .y = y,
332                 .touch_type = touch_type,
333         };
334
335         post_device_event(device,
336                           LIBINPUT_EVENT_TOUCH_TOUCH,
337                           &touch_event->base);
338 }
339
340 void
341 libinput_post_event(struct libinput *libinput,
342                     struct libinput_event *event)
343 {
344         struct libinput_event **events = libinput->events;
345         size_t events_len = libinput->events_len;
346         size_t events_count = libinput->events_count;
347         size_t move_len;
348         size_t new_out;
349
350         events_count++;
351         if (events_count > events_len) {
352                 if (events_len == 0)
353                         events_len = 4;
354                 else
355                         events_len *= 2;
356                 events = realloc(events, events_len * sizeof *events);
357                 if (!events) {
358                         fprintf(stderr, "Failed to reallocate event ring "
359                                 "buffer");
360                         return;
361                 }
362
363                 if (libinput->events_count > 0 && libinput->events_in == 0) {
364                         libinput->events_in = libinput->events_len;
365                 } else if (libinput->events_count > 0 &&
366                            libinput->events_out >= libinput->events_in) {
367                         move_len = libinput->events_len - libinput->events_out;
368                         new_out = events_len - move_len;
369                         memmove(events + new_out,
370                                 libinput->events + libinput->events_out,
371                                 move_len * sizeof *events);
372                         libinput->events_out = new_out;
373                 }
374
375                 libinput->events = events;
376                 libinput->events_len = events_len;
377         }
378
379         libinput->events_count = events_count;
380         events[libinput->events_in] = event;
381         libinput->events_in = (libinput->events_in + 1) % libinput->events_len;
382 }
383
384 LIBINPUT_EXPORT struct libinput_event *
385 libinput_get_event(struct libinput *libinput)
386 {
387         struct libinput_event *event;
388
389         if (libinput->events_count == 0)
390                 return NULL;
391
392         event = libinput->events[libinput->events_out];
393         libinput->events_out =
394                 (libinput->events_out + 1) % libinput->events_len;
395         libinput->events_count--;
396
397         return event;
398 }
399
400 LIBINPUT_EXPORT void
401 libinput_device_terminate(struct libinput_device *device)
402 {
403         evdev_device_terminate((struct evdev_device *) device);
404         device->terminated = 1;
405 }
406
407 LIBINPUT_EXPORT void
408 libinput_device_destroy(struct libinput_device *device)
409 {
410         assert(device->terminated);
411         evdev_device_destroy((struct evdev_device *) device);
412 }
413
414 LIBINPUT_EXPORT void *
415 libinput_device_get_user_data(struct libinput_device *device)
416 {
417         return device->device_interface_data;
418 }
419
420 LIBINPUT_EXPORT void
421 libinput_device_led_update(struct libinput_device *device,
422                            enum libinput_led leds)
423 {
424         evdev_device_led_update((struct evdev_device *) device, leds);
425 }
426
427 LIBINPUT_EXPORT int
428 libinput_device_get_keys(struct libinput_device *device,
429                          char *keys, size_t size)
430 {
431         return evdev_device_get_keys((struct evdev_device *) device,
432                                      keys,
433                                      size);
434 }
435
436 LIBINPUT_EXPORT void
437 libinput_device_calibrate(struct libinput_device *device,
438                           float calibration[6])
439 {
440         evdev_device_calibrate((struct evdev_device *) device, calibration);
441 }