Introduce libinput object managing all input data
[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
31 #include "libinput.h"
32 #include "evdev.h"
33 #include "libinput-private.h"
34
35 struct libinput_source {
36         libinput_source_dispatch_t dispatch;
37         void *user_data;
38         int fd;
39         struct list link;
40 };
41
42 struct libinput_source *
43 libinput_add_fd(struct libinput *libinput,
44                 int fd,
45                 libinput_source_dispatch_t dispatch,
46                 void *user_data)
47 {
48         struct libinput_source *source;
49         struct epoll_event ep;
50
51         source = malloc(sizeof *source);
52         if (!source)
53                 return NULL;
54
55         source->dispatch = dispatch;
56         source->user_data = user_data;
57         source->fd = fd;
58
59         memset(&ep, 0, sizeof ep);
60         ep.events = EPOLLIN;
61         ep.data.ptr = source;
62
63         if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
64                 close(source->fd);
65                 free(source);
66                 return NULL;
67         }
68
69         return source;
70 }
71
72 void
73 libinput_remove_source(struct libinput *libinput,
74                        struct libinput_source *source)
75 {
76         epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
77         close(source->fd);
78         source->fd = -1;
79         list_insert(&libinput->source_destroy_list, &source->link);
80 }
81
82 LIBINPUT_EXPORT struct libinput *
83 libinput_create(void)
84 {
85         struct libinput *libinput;
86
87         libinput = zalloc(sizeof *libinput);
88         if (!libinput)
89                 return NULL;
90
91         list_init(&libinput->source_destroy_list);
92
93         libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);;
94         if (libinput->epoll_fd < 0)
95                 return NULL;
96
97         return libinput;
98 }
99
100 LIBINPUT_EXPORT void
101 libinput_destroy(struct libinput *libinput)
102 {
103         struct libinput_event *event;
104
105         while ((event = libinput_get_event(libinput)))
106                free(event);
107         free(libinput->events);
108
109         close(libinput->epoll_fd);
110         free(libinput);
111 }
112
113 LIBINPUT_EXPORT int
114 libinput_get_fd(struct libinput *libinput)
115 {
116         return libinput->epoll_fd;
117 }
118
119 LIBINPUT_EXPORT int
120 libinput_dispatch(struct libinput *libinput)
121 {
122         struct libinput_source *source, *next;
123         struct epoll_event ep[32];
124         int i, count;
125
126         count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0);
127         if (count < 0)
128                 return -1;
129
130         for (i = 0; i < count; ++i) {
131                 source = ep[i].data.ptr;
132                 if (source->fd == -1)
133                         continue;
134
135                 source->dispatch(source->user_data);
136         }
137
138         list_for_each_safe(source, next, &libinput->source_destroy_list, link)
139                 free(source);
140         list_init(&libinput->source_destroy_list);
141
142         return 0;
143 }
144
145 static void
146 init_event_base(struct libinput_event *event,
147                 enum libinput_event_type type,
148                 struct libinput_device *device)
149 {
150         event->type = type;
151         event->device = device;
152 }
153
154 static void
155 post_device_event(struct libinput_device *device,
156                   enum libinput_event_type type,
157                   struct libinput_event *event)
158 {
159         init_event_base(event, type, device);
160         libinput_post_event(device->libinput, event);
161 }
162
163 void
164 keyboard_notify_key(struct libinput_device *device,
165                     uint32_t time,
166                     uint32_t key,
167                     enum libinput_keyboard_key_state state)
168 {
169         struct libinput_event_keyboard_key *key_event;
170
171         key_event = malloc(sizeof *key_event);
172         if (!key_event)
173                 return;
174
175         *key_event = (struct libinput_event_keyboard_key) {
176                 .time = time,
177                 .key = key,
178                 .state = state,
179         };
180
181         post_device_event(device,
182                           LIBINPUT_EVENT_KEYBOARD_KEY,
183                           &key_event->base);
184 }
185
186 void
187 pointer_notify_motion(struct libinput_device *device,
188                       uint32_t time,
189                       li_fixed_t dx,
190                       li_fixed_t dy)
191 {
192         struct libinput_event_pointer_motion *motion_event;
193
194         motion_event = malloc(sizeof *motion_event);
195         if (!motion_event)
196                 return;
197
198         *motion_event = (struct libinput_event_pointer_motion) {
199                 .time = time,
200                 .dx = dx,
201                 .dy = dy,
202         };
203
204         post_device_event(device,
205                           LIBINPUT_EVENT_POINTER_MOTION,
206                           &motion_event->base);
207 }
208
209 void
210 pointer_notify_motion_absolute(struct libinput_device *device,
211                                uint32_t time,
212                                li_fixed_t x,
213                                li_fixed_t y)
214 {
215         struct libinput_event_pointer_motion_absolute *motion_absolute_event;
216
217         motion_absolute_event = malloc(sizeof *motion_absolute_event);
218         if (!motion_absolute_event)
219                 return;
220
221         *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
222                 .time = time,
223                 .x = x,
224                 .y = y,
225         };
226
227         post_device_event(device,
228                           LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
229                           &motion_absolute_event->base);
230 }
231
232 void
233 pointer_notify_button(struct libinput_device *device,
234                       uint32_t time,
235                       int32_t button,
236                       enum libinput_pointer_button_state state)
237 {
238         struct libinput_event_pointer_button *button_event;
239
240         button_event = malloc(sizeof *button_event);
241         if (!button_event)
242                 return;
243
244         *button_event = (struct libinput_event_pointer_button) {
245                 .time = time,
246                 .button = button,
247                 .state = state,
248         };
249
250         post_device_event(device,
251                           LIBINPUT_EVENT_POINTER_BUTTON,
252                           &button_event->base);
253 }
254
255 void
256 pointer_notify_axis(struct libinput_device *device,
257                     uint32_t time,
258                     enum libinput_pointer_axis axis,
259                     li_fixed_t value)
260 {
261         struct libinput_event_pointer_axis *axis_event;
262
263         axis_event = malloc(sizeof *axis_event);
264         if (!axis_event)
265                 return;
266
267         *axis_event = (struct libinput_event_pointer_axis) {
268                 .time = time,
269                 .axis = axis,
270                 .value = value,
271         };
272
273         post_device_event(device,
274                           LIBINPUT_EVENT_POINTER_AXIS,
275                           &axis_event->base);
276 }
277
278 void
279 touch_notify_touch(struct libinput_device *device,
280                    uint32_t time,
281                    int32_t slot,
282                    li_fixed_t x,
283                    li_fixed_t y,
284                    enum libinput_touch_type touch_type)
285 {
286         struct libinput_event_touch_touch *touch_event;
287
288         touch_event = malloc(sizeof *touch_event);
289         if (!touch_event)
290                 return;
291
292         *touch_event = (struct libinput_event_touch_touch) {
293                 .time = time,
294                 .slot = slot,
295                 .x = x,
296                 .y = y,
297                 .touch_type = touch_type,
298         };
299
300         post_device_event(device,
301                           LIBINPUT_EVENT_TOUCH_TOUCH,
302                           &touch_event->base);
303 }
304
305 void
306 libinput_post_event(struct libinput *libinput,
307                     struct libinput_event *event)
308 {
309         struct libinput_event **events = libinput->events;
310         size_t events_len = libinput->events_len;
311         size_t events_count = libinput->events_count;
312         size_t move_len;
313         size_t new_out;
314
315         events_count++;
316         if (events_count > events_len) {
317                 if (events_len == 0)
318                         events_len = 4;
319                 else
320                         events_len *= 2;
321                 events = realloc(events, events_len * sizeof *events);
322                 if (!events) {
323                         fprintf(stderr, "Failed to reallocate event ring "
324                                 "buffer");
325                         return;
326                 }
327
328                 if (libinput->events_count > 0 && libinput->events_in == 0) {
329                         libinput->events_in = libinput->events_len;
330                 } else if (libinput->events_count > 0 &&
331                            libinput->events_out >= libinput->events_in) {
332                         move_len = libinput->events_len - libinput->events_out;
333                         new_out = events_len - move_len;
334                         memmove(events + new_out,
335                                 libinput->events + libinput->events_out,
336                                 move_len * sizeof *events);
337                         libinput->events_out = new_out;
338                 }
339
340                 libinput->events = events;
341                 libinput->events_len = events_len;
342         }
343
344         libinput->events_count = events_count;
345         events[libinput->events_in] = event;
346         libinput->events_in = (libinput->events_in + 1) % libinput->events_len;
347 }
348
349 LIBINPUT_EXPORT struct libinput_event *
350 libinput_get_event(struct libinput *libinput)
351 {
352         struct libinput_event *event;
353
354         if (libinput->events_count == 0)
355                 return NULL;
356
357         event = libinput->events[libinput->events_out];
358         libinput->events_out =
359                 (libinput->events_out + 1) % libinput->events_len;
360         libinput->events_count--;
361
362         return event;
363 }
364
365 LIBINPUT_EXPORT void
366 libinput_device_destroy(struct libinput_device *device)
367 {
368         evdev_device_destroy((struct evdev_device *) device);
369 }
370
371 LIBINPUT_EXPORT void *
372 libinput_device_get_user_data(struct libinput_device *device)
373 {
374         return device->device_interface_data;
375 }
376
377 LIBINPUT_EXPORT void
378 libinput_device_led_update(struct libinput_device *device,
379                            enum libinput_led leds)
380 {
381         evdev_device_led_update((struct evdev_device *) device, leds);
382 }
383
384 LIBINPUT_EXPORT int
385 libinput_device_get_keys(struct libinput_device *device,
386                          char *keys, size_t size)
387 {
388         return evdev_device_get_keys((struct evdev_device *) device,
389                                      keys,
390                                      size);
391 }
392
393 LIBINPUT_EXPORT void
394 libinput_device_calibrate(struct libinput_device *device,
395                           float calibration[6])
396 {
397         evdev_device_calibrate((struct evdev_device *) device, calibration);
398 }