Add libinput_event_get_context()
[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 <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/epoll.h>
30 #include <unistd.h>
31 #include <assert.h>
32
33 #include "libinput.h"
34 #include "libinput-private.h"
35 #include "evdev.h"
36
37 enum libinput_event_class {
38         LIBINPUT_EVENT_CLASS_NONE,
39         LIBINPUT_EVENT_CLASS_BASE,
40         LIBINPUT_EVENT_CLASS_SEAT,
41         LIBINPUT_EVENT_CLASS_DEVICE,
42 };
43
44 struct libinput_source {
45         libinput_source_dispatch_t dispatch;
46         void *user_data;
47         int fd;
48         struct list link;
49 };
50
51 struct libinput_event {
52         enum libinput_event_type type;
53         struct libinput *libinput;
54         union libinput_event_target target;
55 };
56
57 struct libinput_event_added_seat {
58         struct libinput_event base;
59         struct libinput_seat *seat;
60 };
61
62 struct libinput_event_removed_seat {
63         struct libinput_event base;
64         struct libinput_seat *seat;
65 };
66
67 struct libinput_event_added_device {
68         struct libinput_event base;
69         struct libinput_device *device;
70 };
71
72 struct libinput_event_removed_device {
73         struct libinput_event base;
74         struct libinput_device *device;
75 };
76
77 struct libinput_event_keyboard_key {
78         struct libinput_event base;
79         uint32_t time;
80         uint32_t key;
81         enum libinput_keyboard_key_state state;
82 };
83
84 struct libinput_event_pointer_motion {
85         struct libinput_event base;
86         uint32_t time;
87         li_fixed_t dx;
88         li_fixed_t dy;
89 };
90
91 struct libinput_event_pointer_motion_absolute {
92         struct libinput_event base;
93         uint32_t time;
94         li_fixed_t x;
95         li_fixed_t y;
96 };
97
98 struct libinput_event_pointer_button {
99         struct libinput_event base;
100         uint32_t time;
101         uint32_t button;
102         enum libinput_pointer_button_state state;
103 };
104
105 struct libinput_event_pointer_axis {
106         struct libinput_event base;
107         uint32_t time;
108         enum libinput_pointer_axis axis;
109         li_fixed_t value;
110 };
111
112 struct libinput_event_touch_touch {
113         struct libinput_event base;
114         uint32_t time;
115         uint32_t slot;
116         li_fixed_t x;
117         li_fixed_t y;
118         enum libinput_touch_type touch_type;
119 };
120
121 static void
122 libinput_post_event(struct libinput *libinput,
123                     struct libinput_event *event);
124
125 LIBINPUT_EXPORT enum libinput_event_type
126 libinput_event_get_type(struct libinput_event *event)
127 {
128         return event->type;
129 }
130
131 LIBINPUT_EXPORT union libinput_event_target
132 libinput_event_get_target(struct libinput_event *event)
133 {
134         return event->target;
135 }
136
137 LIBINPUT_EXPORT struct libinput*
138 libinput_event_get_context(struct libinput_event *event)
139 {
140         return event->libinput;
141 }
142
143 LIBINPUT_EXPORT struct libinput_seat *
144 libinput_event_added_seat_get_seat(struct libinput_event_added_seat *event)
145 {
146         return event->seat;
147 }
148
149 LIBINPUT_EXPORT struct libinput_seat *
150 libinput_event_removed_seat_get_seat(struct libinput_event_removed_seat *event)
151 {
152         return event->seat;
153 }
154
155 LIBINPUT_EXPORT struct libinput_device *
156 libinput_event_added_device_get_device(
157         struct libinput_event_added_device *event)
158 {
159         return event->device;
160 }
161
162 LIBINPUT_EXPORT struct libinput_device *
163 libinput_event_removed_device_get_device(
164         struct libinput_event_removed_device *event)
165 {
166         return event->device;
167 }
168
169 LIBINPUT_EXPORT uint32_t
170 libinput_event_keyboard_key_get_time(
171         struct libinput_event_keyboard_key *event)
172 {
173         return event->time;
174 }
175
176 LIBINPUT_EXPORT uint32_t
177 libinput_event_keyboard_key_get_key(
178         struct libinput_event_keyboard_key *event)
179 {
180         return event->key;
181 }
182
183 LIBINPUT_EXPORT enum libinput_keyboard_key_state
184 libinput_event_keyboard_key_get_state(
185         struct libinput_event_keyboard_key *event)
186 {
187         return event->state;
188 }
189
190 LIBINPUT_EXPORT uint32_t
191 libinput_event_pointer_motion_get_time(
192         struct libinput_event_pointer_motion *event)
193 {
194         return event->time;
195 }
196
197 LIBINPUT_EXPORT li_fixed_t
198 libinput_event_pointer_motion_get_dx(
199         struct libinput_event_pointer_motion *event)
200 {
201         return event->dx;
202 }
203
204 LIBINPUT_EXPORT li_fixed_t
205 libinput_event_pointer_motion_get_dy(
206         struct libinput_event_pointer_motion *event)
207 {
208         return event->dy;
209 }
210
211 LIBINPUT_EXPORT uint32_t
212 libinput_event_pointer_motion_absolute_get_time(
213         struct libinput_event_pointer_motion_absolute *event)
214 {
215         return event->time;
216 }
217
218 LIBINPUT_EXPORT li_fixed_t
219 libinput_event_pointer_motion_absolute_get_x(
220         struct libinput_event_pointer_motion_absolute *event)
221 {
222         return event->x;
223 }
224
225 LIBINPUT_EXPORT li_fixed_t
226 libinput_event_pointer_motion_absolute_get_y(
227         struct libinput_event_pointer_motion_absolute *event)
228 {
229         return event->y;
230 }
231
232 LIBINPUT_EXPORT uint32_t
233 libinput_event_pointer_button_get_time(
234         struct libinput_event_pointer_button *event)
235 {
236         return event->time;
237 }
238
239 LIBINPUT_EXPORT uint32_t
240 libinput_event_pointer_button_get_button(
241         struct libinput_event_pointer_button *event)
242 {
243         return event->button;
244 }
245
246 LIBINPUT_EXPORT enum libinput_pointer_button_state
247 libinput_event_pointer_button_get_state(
248         struct libinput_event_pointer_button *event)
249 {
250         return event->state;
251 }
252
253 LIBINPUT_EXPORT uint32_t
254 libinput_event_pointer_axis_get_time(
255         struct libinput_event_pointer_axis *event)
256 {
257         return event->time;
258 }
259
260 LIBINPUT_EXPORT enum libinput_pointer_axis
261 libinput_event_pointer_axis_get_axis(
262         struct libinput_event_pointer_axis *event)
263 {
264         return event->axis;
265 }
266
267 LIBINPUT_EXPORT li_fixed_t
268 libinput_event_pointer_axis_get_value(
269         struct libinput_event_pointer_axis *event)
270 {
271         return event->value;
272 }
273
274 LIBINPUT_EXPORT uint32_t
275 libinput_event_touch_touch_get_time(
276         struct libinput_event_touch_touch *event)
277 {
278         return event->time;
279 }
280
281 LIBINPUT_EXPORT uint32_t
282 libinput_event_touch_touch_get_slot(
283         struct libinput_event_touch_touch *event)
284 {
285         return event->slot;
286 }
287
288 LIBINPUT_EXPORT li_fixed_t
289 libinput_event_touch_touch_get_x(
290         struct libinput_event_touch_touch *event)
291 {
292         return event->x;
293 }
294
295 LIBINPUT_EXPORT li_fixed_t
296 libinput_event_touch_touch_get_y(
297         struct libinput_event_touch_touch *event)
298 {
299         return event->y;
300 }
301
302 LIBINPUT_EXPORT enum libinput_touch_type
303 libinput_event_touch_touch_get_touch_type(
304         struct libinput_event_touch_touch *event)
305 {
306         return event->touch_type;
307 }
308
309 struct libinput_source *
310 libinput_add_fd(struct libinput *libinput,
311                 int fd,
312                 libinput_source_dispatch_t dispatch,
313                 void *user_data)
314 {
315         struct libinput_source *source;
316         struct epoll_event ep;
317
318         source = malloc(sizeof *source);
319         if (!source)
320                 return NULL;
321
322         source->dispatch = dispatch;
323         source->user_data = user_data;
324         source->fd = fd;
325
326         memset(&ep, 0, sizeof ep);
327         ep.events = EPOLLIN;
328         ep.data.ptr = source;
329
330         if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
331                 close(source->fd);
332                 free(source);
333                 return NULL;
334         }
335
336         return source;
337 }
338
339 void
340 libinput_remove_source(struct libinput *libinput,
341                        struct libinput_source *source)
342 {
343         epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
344         close(source->fd);
345         source->fd = -1;
346         list_insert(&libinput->source_destroy_list, &source->link);
347 }
348
349 int
350 libinput_init(struct libinput *libinput,
351               const struct libinput_interface *interface,
352               const struct libinput_interface_backend *interface_backend,
353               void *user_data)
354 {
355         libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);;
356         if (libinput->epoll_fd < 0)
357                 return -1;
358
359         libinput->events_len = 4;
360         libinput->events = zalloc(libinput->events_len * sizeof(*libinput->events));
361         if (!libinput->events) {
362                 close(libinput->epoll_fd);
363                 return -1;
364         }
365
366         libinput->interface = interface;
367         libinput->interface_backend = interface_backend;
368         libinput->user_data = user_data;
369         list_init(&libinput->source_destroy_list);
370         list_init(&libinput->seat_list);
371
372         return 0;
373 }
374
375 static void
376 libinput_device_destroy(struct libinput_device *device);
377
378 static void
379 libinput_seat_destroy(struct libinput_seat *seat);
380
381 static void
382 libinput_drop_destroyed_sources(struct libinput *libinput)
383 {
384         struct libinput_source *source, *next;
385
386         list_for_each_safe(source, next, &libinput->source_destroy_list, link)
387                 free(source);
388         list_init(&libinput->source_destroy_list);
389 }
390
391 LIBINPUT_EXPORT void
392 libinput_destroy(struct libinput *libinput)
393 {
394         struct libinput_event *event;
395         struct libinput_device *device, *next_device;
396         struct libinput_seat *seat, *next_seat;
397
398         if (libinput == NULL)
399                 return;
400
401         libinput_suspend(libinput);
402
403         libinput->interface_backend->destroy(libinput);
404
405         while ((event = libinput_get_event(libinput)))
406                libinput_event_destroy(event);
407
408         libinput_drop_destroyed_sources(libinput);
409
410         free(libinput->events);
411
412         list_for_each_safe(seat, next_seat, &libinput->seat_list, link) {
413                 list_for_each_safe(device, next_device,
414                                    &seat->devices_list,
415                                    link)
416                         libinput_device_destroy(device);
417
418                 libinput_seat_destroy(seat);
419         }
420
421         close(libinput->epoll_fd);
422         free(libinput);
423 }
424
425 static enum libinput_event_class
426 libinput_event_get_class(struct libinput_event *event)
427 {
428         switch (event->type) {
429         case LIBINPUT_EVENT_NONE:
430                 return LIBINPUT_EVENT_CLASS_NONE;
431
432         case LIBINPUT_EVENT_ADDED_SEAT:
433         case LIBINPUT_EVENT_REMOVED_SEAT:
434         case LIBINPUT_EVENT_ADDED_DEVICE:
435         case LIBINPUT_EVENT_REMOVED_DEVICE:
436                 return LIBINPUT_EVENT_CLASS_BASE;
437
438         case LIBINPUT_EVENT_KEYBOARD_KEY:
439         case LIBINPUT_EVENT_POINTER_MOTION:
440         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
441         case LIBINPUT_EVENT_POINTER_BUTTON:
442         case LIBINPUT_EVENT_POINTER_AXIS:
443         case LIBINPUT_EVENT_TOUCH_TOUCH:
444                 return LIBINPUT_EVENT_CLASS_DEVICE;
445         }
446
447         /* We should never end up here. */
448         abort();
449 }
450
451 LIBINPUT_EXPORT void
452 libinput_event_destroy(struct libinput_event *event)
453 {
454         if (event == NULL)
455                 return;
456
457         switch (libinput_event_get_class(event)) {
458         case LIBINPUT_EVENT_CLASS_NONE:
459         case LIBINPUT_EVENT_CLASS_BASE:
460                 break;
461         case LIBINPUT_EVENT_CLASS_SEAT:
462                 libinput_seat_unref(event->target.seat);
463                 break;
464         case LIBINPUT_EVENT_CLASS_DEVICE:
465                 libinput_device_unref(event->target.device);
466                 break;
467         }
468
469         if (libinput_event_get_type(event) == LIBINPUT_EVENT_ADDED_SEAT ||
470             libinput_event_get_type(event) == LIBINPUT_EVENT_REMOVED_SEAT)
471                 libinput_seat_unref(((struct libinput_event_added_seat*)event)->seat);
472
473         free(event);
474 }
475
476 int
477 open_restricted(struct libinput *libinput,
478                 const char *path, int flags)
479 {
480         return libinput->interface->open_restricted(path,
481                                                     flags,
482                                                     libinput->user_data);
483 }
484
485 void
486 close_restricted(struct libinput *libinput, int fd)
487 {
488         return libinput->interface->close_restricted(fd, libinput->user_data);
489 }
490
491 void
492 libinput_seat_init(struct libinput_seat *seat,
493                    struct libinput *libinput,
494                    const char *name,
495                    libinput_seat_destroy_func destroy)
496 {
497         seat->refcount = 1;
498         seat->libinput = libinput;
499         seat->name = strdup(name);
500         seat->destroy = destroy;
501         list_init(&seat->devices_list);
502 }
503
504 LIBINPUT_EXPORT void
505 libinput_seat_ref(struct libinput_seat *seat)
506 {
507         seat->refcount++;
508 }
509
510 static void
511 libinput_seat_destroy(struct libinput_seat *seat)
512 {
513         list_remove(&seat->link);
514         free(seat->name);
515         seat->destroy(seat);
516 }
517
518 LIBINPUT_EXPORT void
519 libinput_seat_unref(struct libinput_seat *seat)
520 {
521         assert(seat->refcount > 0);
522         seat->refcount--;
523         if (seat->refcount == 0)
524                 libinput_seat_destroy(seat);
525 }
526
527 LIBINPUT_EXPORT void
528 libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data)
529 {
530         seat->user_data = user_data;
531 }
532
533 LIBINPUT_EXPORT void *
534 libinput_seat_get_user_data(struct libinput_seat *seat)
535 {
536         return seat->user_data;
537 }
538
539 LIBINPUT_EXPORT const char *
540 libinput_seat_get_name(struct libinput_seat *seat)
541 {
542         return seat->name;
543 }
544
545 void
546 libinput_device_init(struct libinput_device *device,
547                      struct libinput_seat *seat)
548 {
549         device->seat = seat;
550         device->refcount = 1;
551 }
552
553 LIBINPUT_EXPORT void
554 libinput_device_ref(struct libinput_device *device)
555 {
556         device->refcount++;
557 }
558
559 static void
560 libinput_device_destroy(struct libinput_device *device)
561 {
562         evdev_device_destroy((struct evdev_device *) device);
563 }
564
565 LIBINPUT_EXPORT void
566 libinput_device_unref(struct libinput_device *device)
567 {
568         assert(device->refcount > 0);
569         device->refcount--;
570         if (device->refcount == 0)
571                 libinput_device_destroy(device);
572 }
573
574 LIBINPUT_EXPORT int
575 libinput_get_fd(struct libinput *libinput)
576 {
577         return libinput->epoll_fd;
578 }
579
580 LIBINPUT_EXPORT int
581 libinput_dispatch(struct libinput *libinput)
582 {
583         struct libinput_source *source;
584         struct epoll_event ep[32];
585         int i, count;
586
587         count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0);
588         if (count < 0)
589                 return -errno;
590
591         for (i = 0; i < count; ++i) {
592                 source = ep[i].data.ptr;
593                 if (source->fd == -1)
594                         continue;
595
596                 source->dispatch(source->user_data);
597         }
598
599         libinput_drop_destroyed_sources(libinput);
600
601         return 0;
602 }
603
604 static void
605 init_event_base(struct libinput_event *event,
606                 struct libinput *libinput,
607                 enum libinput_event_type type,
608                 union libinput_event_target target)
609 {
610         event->type = type;
611         event->libinput = libinput;
612         event->target = target;
613 }
614
615 static void
616 post_base_event(struct libinput *libinput,
617                 enum libinput_event_type type,
618                 struct libinput_event *event)
619 {
620         init_event_base(event, libinput, type,
621                         (union libinput_event_target) { .libinput = libinput });
622         libinput_post_event(libinput, event);
623 }
624
625 static void
626 post_device_event(struct libinput_device *device,
627                   enum libinput_event_type type,
628                   struct libinput_event *event)
629 {
630         init_event_base(event, device->seat->libinput, type,
631                         (union libinput_event_target) { .device = device });
632         libinput_post_event(device->seat->libinput, event);
633 }
634
635 void
636 notify_added_seat(struct libinput_seat *seat)
637 {
638         struct libinput_event_added_seat *added_seat_event;
639
640         added_seat_event = malloc(sizeof *added_seat_event);
641         if (!added_seat_event)
642                 return;
643
644         libinput_seat_ref(seat);
645
646         *added_seat_event = (struct libinput_event_added_seat) {
647                 .seat = seat,
648         };
649
650         post_base_event(seat->libinput,
651                         LIBINPUT_EVENT_ADDED_SEAT,
652                         &added_seat_event->base);
653 }
654
655 void
656 notify_removed_seat(struct libinput_seat *seat)
657 {
658         struct libinput_event_removed_seat *removed_seat_event;
659
660         removed_seat_event = malloc(sizeof *removed_seat_event);
661         if (!removed_seat_event)
662                 return;
663
664         libinput_seat_ref(seat);
665
666         *removed_seat_event = (struct libinput_event_removed_seat) {
667                 .seat = seat,
668         };
669
670         post_base_event(seat->libinput,
671                         LIBINPUT_EVENT_REMOVED_SEAT,
672                         &removed_seat_event->base);
673 }
674
675 void
676 notify_added_device(struct libinput_device *device)
677 {
678         struct libinput_event_added_device *added_device_event;
679
680         added_device_event = malloc(sizeof *added_device_event);
681         if (!added_device_event)
682                 return;
683
684         *added_device_event = (struct libinput_event_added_device) {
685                 .device = device,
686         };
687
688         post_base_event(device->seat->libinput,
689                         LIBINPUT_EVENT_ADDED_DEVICE,
690                         &added_device_event->base);
691 }
692
693 void
694 notify_removed_device(struct libinput_device *device)
695 {
696         struct libinput_event_removed_device *removed_device_event;
697
698         removed_device_event = malloc(sizeof *removed_device_event);
699         if (!removed_device_event)
700                 return;
701
702         *removed_device_event = (struct libinput_event_removed_device) {
703                 .device = device,
704         };
705
706         post_base_event(device->seat->libinput,
707                         LIBINPUT_EVENT_REMOVED_DEVICE,
708                         &removed_device_event->base);
709 }
710
711 void
712 keyboard_notify_key(struct libinput_device *device,
713                     uint32_t time,
714                     uint32_t key,
715                     enum libinput_keyboard_key_state state)
716 {
717         struct libinput_event_keyboard_key *key_event;
718
719         key_event = malloc(sizeof *key_event);
720         if (!key_event)
721                 return;
722
723         *key_event = (struct libinput_event_keyboard_key) {
724                 .time = time,
725                 .key = key,
726                 .state = state,
727         };
728
729         post_device_event(device,
730                           LIBINPUT_EVENT_KEYBOARD_KEY,
731                           &key_event->base);
732 }
733
734 void
735 pointer_notify_motion(struct libinput_device *device,
736                       uint32_t time,
737                       li_fixed_t dx,
738                       li_fixed_t dy)
739 {
740         struct libinput_event_pointer_motion *motion_event;
741
742         motion_event = malloc(sizeof *motion_event);
743         if (!motion_event)
744                 return;
745
746         *motion_event = (struct libinput_event_pointer_motion) {
747                 .time = time,
748                 .dx = dx,
749                 .dy = dy,
750         };
751
752         post_device_event(device,
753                           LIBINPUT_EVENT_POINTER_MOTION,
754                           &motion_event->base);
755 }
756
757 void
758 pointer_notify_motion_absolute(struct libinput_device *device,
759                                uint32_t time,
760                                li_fixed_t x,
761                                li_fixed_t y)
762 {
763         struct libinput_event_pointer_motion_absolute *motion_absolute_event;
764
765         motion_absolute_event = malloc(sizeof *motion_absolute_event);
766         if (!motion_absolute_event)
767                 return;
768
769         *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
770                 .time = time,
771                 .x = x,
772                 .y = y,
773         };
774
775         post_device_event(device,
776                           LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
777                           &motion_absolute_event->base);
778 }
779
780 void
781 pointer_notify_button(struct libinput_device *device,
782                       uint32_t time,
783                       int32_t button,
784                       enum libinput_pointer_button_state state)
785 {
786         struct libinput_event_pointer_button *button_event;
787
788         button_event = malloc(sizeof *button_event);
789         if (!button_event)
790                 return;
791
792         *button_event = (struct libinput_event_pointer_button) {
793                 .time = time,
794                 .button = button,
795                 .state = state,
796         };
797
798         post_device_event(device,
799                           LIBINPUT_EVENT_POINTER_BUTTON,
800                           &button_event->base);
801 }
802
803 void
804 pointer_notify_axis(struct libinput_device *device,
805                     uint32_t time,
806                     enum libinput_pointer_axis axis,
807                     li_fixed_t value)
808 {
809         struct libinput_event_pointer_axis *axis_event;
810
811         axis_event = malloc(sizeof *axis_event);
812         if (!axis_event)
813                 return;
814
815         *axis_event = (struct libinput_event_pointer_axis) {
816                 .time = time,
817                 .axis = axis,
818                 .value = value,
819         };
820
821         post_device_event(device,
822                           LIBINPUT_EVENT_POINTER_AXIS,
823                           &axis_event->base);
824 }
825
826 void
827 touch_notify_touch(struct libinput_device *device,
828                    uint32_t time,
829                    int32_t slot,
830                    li_fixed_t x,
831                    li_fixed_t y,
832                    enum libinput_touch_type touch_type)
833 {
834         struct libinput_event_touch_touch *touch_event;
835
836         touch_event = malloc(sizeof *touch_event);
837         if (!touch_event)
838                 return;
839
840         *touch_event = (struct libinput_event_touch_touch) {
841                 .time = time,
842                 .slot = slot,
843                 .x = x,
844                 .y = y,
845                 .touch_type = touch_type,
846         };
847
848         post_device_event(device,
849                           LIBINPUT_EVENT_TOUCH_TOUCH,
850                           &touch_event->base);
851 }
852
853 static void
854 libinput_post_event(struct libinput *libinput,
855                     struct libinput_event *event)
856 {
857         struct libinput_event **events = libinput->events;
858         size_t events_len = libinput->events_len;
859         size_t events_count = libinput->events_count;
860         size_t move_len;
861         size_t new_out;
862
863         events_count++;
864         if (events_count > events_len) {
865                 events_len *= 2;
866                 events = realloc(events, events_len * sizeof *events);
867                 if (!events) {
868                         fprintf(stderr, "Failed to reallocate event ring "
869                                 "buffer");
870                         return;
871                 }
872
873                 if (libinput->events_count > 0 && libinput->events_in == 0) {
874                         libinput->events_in = libinput->events_len;
875                 } else if (libinput->events_count > 0 &&
876                            libinput->events_out >= libinput->events_in) {
877                         move_len = libinput->events_len - libinput->events_out;
878                         new_out = events_len - move_len;
879                         memmove(events + new_out,
880                                 events + libinput->events_out,
881                                 move_len * sizeof *events);
882                         libinput->events_out = new_out;
883                 }
884
885                 libinput->events = events;
886                 libinput->events_len = events_len;
887         }
888
889         switch (libinput_event_get_class(event)) {
890         case LIBINPUT_EVENT_CLASS_NONE:
891         case LIBINPUT_EVENT_CLASS_BASE:
892                 break;
893         case LIBINPUT_EVENT_CLASS_SEAT:
894                 libinput_seat_ref(event->target.seat);
895                 break;
896         case LIBINPUT_EVENT_CLASS_DEVICE:
897                 libinput_device_ref(event->target.device);
898                 break;
899         }
900
901         libinput->events_count = events_count;
902         events[libinput->events_in] = event;
903         libinput->events_in = (libinput->events_in + 1) % libinput->events_len;
904 }
905
906 LIBINPUT_EXPORT struct libinput_event *
907 libinput_get_event(struct libinput *libinput)
908 {
909         struct libinput_event *event;
910
911         if (libinput->events_count == 0)
912                 return NULL;
913
914         event = libinput->events[libinput->events_out];
915         libinput->events_out =
916                 (libinput->events_out + 1) % libinput->events_len;
917         libinput->events_count--;
918
919         return event;
920 }
921
922 LIBINPUT_EXPORT enum libinput_event_type
923 libinput_next_event_type(struct libinput *libinput)
924 {
925         struct libinput_event *event;
926
927         if (libinput->events_count == 0)
928                 return LIBINPUT_EVENT_NONE;
929
930         event = libinput->events[libinput->events_out];
931         return event->type;
932 }
933
934 LIBINPUT_EXPORT void *
935 libinput_get_user_data(struct libinput *libinput)
936 {
937         return libinput->user_data;
938 }
939
940 LIBINPUT_EXPORT int
941 libinput_resume(struct libinput *libinput)
942 {
943         return libinput->interface_backend->resume(libinput);
944 }
945
946 LIBINPUT_EXPORT void
947 libinput_suspend(struct libinput *libinput)
948 {
949         libinput->interface_backend->suspend(libinput);
950 }
951
952 LIBINPUT_EXPORT void
953 libinput_device_set_user_data(struct libinput_device *device, void *user_data)
954 {
955         device->user_data = user_data;
956 }
957
958 LIBINPUT_EXPORT void *
959 libinput_device_get_user_data(struct libinput_device *device)
960 {
961         return device->user_data;
962 }
963
964 LIBINPUT_EXPORT const char *
965 libinput_device_get_sysname(struct libinput_device *device)
966 {
967         return evdev_device_get_sysname((struct evdev_device *) device);
968 }
969
970 LIBINPUT_EXPORT const char *
971 libinput_device_get_output_name(struct libinput_device *device)
972 {
973         return evdev_device_get_output((struct evdev_device *) device);
974 }
975
976 LIBINPUT_EXPORT struct libinput_seat *
977 libinput_device_get_seat(struct libinput_device *device)
978 {
979         return device->seat;
980 }
981
982 LIBINPUT_EXPORT void
983 libinput_device_led_update(struct libinput_device *device,
984                            enum libinput_led leds)
985 {
986         evdev_device_led_update((struct evdev_device *) device, leds);
987 }
988
989 LIBINPUT_EXPORT int
990 libinput_device_get_keys(struct libinput_device *device,
991                          char *keys, size_t size)
992 {
993         return evdev_device_get_keys((struct evdev_device *) device,
994                                      keys,
995                                      size);
996 }
997
998 LIBINPUT_EXPORT void
999 libinput_device_calibrate(struct libinput_device *device,
1000                           float calibration[6])
1001 {
1002         evdev_device_calibrate((struct evdev_device *) device, calibration);
1003 }
1004
1005 LIBINPUT_EXPORT int
1006 libinput_device_has_capability(struct libinput_device *device,
1007                                enum libinput_device_capability capability)
1008 {
1009         return evdev_device_has_capability((struct evdev_device *) device,
1010                                            capability);
1011 }