2 * Copyright © 2013 Jonas Ådahl
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.
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.
29 #include <sys/epoll.h>
34 #include "libinput-private.h"
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,
44 struct libinput_source {
45 libinput_source_dispatch_t dispatch;
51 struct libinput_event {
52 enum libinput_event_type type;
53 struct libinput_device *device;
54 union libinput_event_target target;
57 struct libinput_event_added_device {
58 struct libinput_event base;
59 struct libinput_device *device;
62 struct libinput_event_removed_device {
63 struct libinput_event base;
64 struct libinput_device *device;
67 struct libinput_event_keyboard_key {
68 struct libinput_event base;
71 enum libinput_keyboard_key_state state;
74 struct libinput_event_pointer_motion {
75 struct libinput_event base;
81 struct libinput_event_pointer_motion_absolute {
82 struct libinput_event base;
88 struct libinput_event_pointer_button {
89 struct libinput_event base;
92 enum libinput_pointer_button_state state;
95 struct libinput_event_pointer_axis {
96 struct libinput_event base;
98 enum libinput_pointer_axis axis;
102 struct libinput_event_touch_touch {
103 struct libinput_event base;
108 enum libinput_touch_type touch_type;
112 libinput_post_event(struct libinput *libinput,
113 struct libinput_event *event);
115 LIBINPUT_EXPORT enum libinput_event_type
116 libinput_event_get_type(struct libinput_event *event)
121 LIBINPUT_EXPORT union libinput_event_target
122 libinput_event_get_target(struct libinput_event *event)
124 return event->target;
127 LIBINPUT_EXPORT struct libinput*
128 libinput_event_get_context(struct libinput_event *event)
130 return event->device->seat->libinput;
133 LIBINPUT_EXPORT struct libinput_device*
134 libinput_event_get_device(struct libinput_event *event)
136 return event->device;
139 LIBINPUT_EXPORT uint32_t
140 libinput_event_keyboard_key_get_time(
141 struct libinput_event_keyboard_key *event)
146 LIBINPUT_EXPORT uint32_t
147 libinput_event_keyboard_key_get_key(
148 struct libinput_event_keyboard_key *event)
153 LIBINPUT_EXPORT enum libinput_keyboard_key_state
154 libinput_event_keyboard_key_get_state(
155 struct libinput_event_keyboard_key *event)
160 LIBINPUT_EXPORT uint32_t
161 libinput_event_pointer_motion_get_time(
162 struct libinput_event_pointer_motion *event)
167 LIBINPUT_EXPORT li_fixed_t
168 libinput_event_pointer_motion_get_dx(
169 struct libinput_event_pointer_motion *event)
174 LIBINPUT_EXPORT li_fixed_t
175 libinput_event_pointer_motion_get_dy(
176 struct libinput_event_pointer_motion *event)
181 LIBINPUT_EXPORT uint32_t
182 libinput_event_pointer_motion_absolute_get_time(
183 struct libinput_event_pointer_motion_absolute *event)
188 LIBINPUT_EXPORT li_fixed_t
189 libinput_event_pointer_motion_absolute_get_x(
190 struct libinput_event_pointer_motion_absolute *event)
195 LIBINPUT_EXPORT li_fixed_t
196 libinput_event_pointer_motion_absolute_get_y(
197 struct libinput_event_pointer_motion_absolute *event)
202 LIBINPUT_EXPORT uint32_t
203 libinput_event_pointer_button_get_time(
204 struct libinput_event_pointer_button *event)
209 LIBINPUT_EXPORT uint32_t
210 libinput_event_pointer_button_get_button(
211 struct libinput_event_pointer_button *event)
213 return event->button;
216 LIBINPUT_EXPORT enum libinput_pointer_button_state
217 libinput_event_pointer_button_get_state(
218 struct libinput_event_pointer_button *event)
223 LIBINPUT_EXPORT uint32_t
224 libinput_event_pointer_axis_get_time(
225 struct libinput_event_pointer_axis *event)
230 LIBINPUT_EXPORT enum libinput_pointer_axis
231 libinput_event_pointer_axis_get_axis(
232 struct libinput_event_pointer_axis *event)
237 LIBINPUT_EXPORT li_fixed_t
238 libinput_event_pointer_axis_get_value(
239 struct libinput_event_pointer_axis *event)
244 LIBINPUT_EXPORT uint32_t
245 libinput_event_touch_touch_get_time(
246 struct libinput_event_touch_touch *event)
251 LIBINPUT_EXPORT uint32_t
252 libinput_event_touch_touch_get_slot(
253 struct libinput_event_touch_touch *event)
258 LIBINPUT_EXPORT li_fixed_t
259 libinput_event_touch_touch_get_x(
260 struct libinput_event_touch_touch *event)
265 LIBINPUT_EXPORT li_fixed_t
266 libinput_event_touch_touch_get_y(
267 struct libinput_event_touch_touch *event)
272 LIBINPUT_EXPORT enum libinput_touch_type
273 libinput_event_touch_touch_get_touch_type(
274 struct libinput_event_touch_touch *event)
276 return event->touch_type;
279 struct libinput_source *
280 libinput_add_fd(struct libinput *libinput,
282 libinput_source_dispatch_t dispatch,
285 struct libinput_source *source;
286 struct epoll_event ep;
288 source = malloc(sizeof *source);
292 source->dispatch = dispatch;
293 source->user_data = user_data;
296 memset(&ep, 0, sizeof ep);
298 ep.data.ptr = source;
300 if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
310 libinput_remove_source(struct libinput *libinput,
311 struct libinput_source *source)
313 epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
316 list_insert(&libinput->source_destroy_list, &source->link);
320 libinput_init(struct libinput *libinput,
321 const struct libinput_interface *interface,
322 const struct libinput_interface_backend *interface_backend,
325 libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC);;
326 if (libinput->epoll_fd < 0)
329 libinput->events_len = 4;
330 libinput->events = zalloc(libinput->events_len * sizeof(*libinput->events));
331 if (!libinput->events) {
332 close(libinput->epoll_fd);
336 libinput->interface = interface;
337 libinput->interface_backend = interface_backend;
338 libinput->user_data = user_data;
339 list_init(&libinput->source_destroy_list);
340 list_init(&libinput->seat_list);
346 libinput_device_destroy(struct libinput_device *device);
349 libinput_seat_destroy(struct libinput_seat *seat);
352 libinput_drop_destroyed_sources(struct libinput *libinput)
354 struct libinput_source *source, *next;
356 list_for_each_safe(source, next, &libinput->source_destroy_list, link)
358 list_init(&libinput->source_destroy_list);
362 libinput_destroy(struct libinput *libinput)
364 struct libinput_event *event;
365 struct libinput_device *device, *next_device;
366 struct libinput_seat *seat, *next_seat;
368 if (libinput == NULL)
371 libinput_suspend(libinput);
373 libinput->interface_backend->destroy(libinput);
375 while ((event = libinput_get_event(libinput)))
376 libinput_event_destroy(event);
378 libinput_drop_destroyed_sources(libinput);
380 free(libinput->events);
382 list_for_each_safe(seat, next_seat, &libinput->seat_list, link) {
383 list_for_each_safe(device, next_device,
386 libinput_device_destroy(device);
388 libinput_seat_destroy(seat);
391 close(libinput->epoll_fd);
395 static enum libinput_event_class
396 libinput_event_get_class(struct libinput_event *event)
398 switch (event->type) {
399 case LIBINPUT_EVENT_NONE:
400 return LIBINPUT_EVENT_CLASS_NONE;
402 case LIBINPUT_EVENT_ADDED_DEVICE:
403 case LIBINPUT_EVENT_REMOVED_DEVICE:
404 return LIBINPUT_EVENT_CLASS_BASE;
406 case LIBINPUT_EVENT_KEYBOARD_KEY:
407 case LIBINPUT_EVENT_POINTER_MOTION:
408 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
409 case LIBINPUT_EVENT_POINTER_BUTTON:
410 case LIBINPUT_EVENT_POINTER_AXIS:
411 case LIBINPUT_EVENT_TOUCH_TOUCH:
412 return LIBINPUT_EVENT_CLASS_DEVICE;
415 /* We should never end up here. */
420 libinput_event_destroy(struct libinput_event *event)
425 switch (libinput_event_get_class(event)) {
426 case LIBINPUT_EVENT_CLASS_NONE:
427 case LIBINPUT_EVENT_CLASS_BASE:
429 case LIBINPUT_EVENT_CLASS_SEAT:
430 libinput_seat_unref(event->target.seat);
432 case LIBINPUT_EVENT_CLASS_DEVICE:
433 libinput_device_unref(event->target.device);
441 open_restricted(struct libinput *libinput,
442 const char *path, int flags)
444 return libinput->interface->open_restricted(path,
446 libinput->user_data);
450 close_restricted(struct libinput *libinput, int fd)
452 return libinput->interface->close_restricted(fd, libinput->user_data);
456 libinput_seat_init(struct libinput_seat *seat,
457 struct libinput *libinput,
458 const char *physical_name,
459 const char *logical_name,
460 libinput_seat_destroy_func destroy)
463 seat->libinput = libinput;
464 seat->physical_name = strdup(physical_name);
465 seat->logical_name = strdup(logical_name);
466 seat->destroy = destroy;
467 list_init(&seat->devices_list);
471 libinput_seat_ref(struct libinput_seat *seat)
477 libinput_seat_destroy(struct libinput_seat *seat)
479 list_remove(&seat->link);
480 free(seat->logical_name);
481 free(seat->physical_name);
486 libinput_seat_unref(struct libinput_seat *seat)
488 assert(seat->refcount > 0);
490 if (seat->refcount == 0)
491 libinput_seat_destroy(seat);
495 libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data)
497 seat->user_data = user_data;
500 LIBINPUT_EXPORT void *
501 libinput_seat_get_user_data(struct libinput_seat *seat)
503 return seat->user_data;
506 LIBINPUT_EXPORT const char *
507 libinput_seat_get_physical_name(struct libinput_seat *seat)
509 return seat->physical_name;
512 LIBINPUT_EXPORT const char *
513 libinput_seat_get_logical_name(struct libinput_seat *seat)
515 return seat->logical_name;
519 libinput_device_init(struct libinput_device *device,
520 struct libinput_seat *seat)
523 device->refcount = 1;
527 libinput_device_ref(struct libinput_device *device)
533 libinput_device_destroy(struct libinput_device *device)
535 evdev_device_destroy((struct evdev_device *) device);
539 libinput_device_unref(struct libinput_device *device)
541 assert(device->refcount > 0);
543 if (device->refcount == 0)
544 libinput_device_destroy(device);
548 libinput_get_fd(struct libinput *libinput)
550 return libinput->epoll_fd;
554 libinput_dispatch(struct libinput *libinput)
556 struct libinput_source *source;
557 struct epoll_event ep[32];
560 count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0);
564 for (i = 0; i < count; ++i) {
565 source = ep[i].data.ptr;
566 if (source->fd == -1)
569 source->dispatch(source->user_data);
572 libinput_drop_destroyed_sources(libinput);
578 init_event_base(struct libinput_event *event,
579 struct libinput_device *device,
580 enum libinput_event_type type,
581 union libinput_event_target target)
584 event->device = device;
585 event->target = target;
589 post_base_event(struct libinput_device *device,
590 enum libinput_event_type type,
591 struct libinput_event *event)
593 struct libinput *libinput = device->seat->libinput;
594 init_event_base(event, device, type,
595 (union libinput_event_target) { .libinput = libinput });
596 libinput_post_event(libinput, event);
600 post_device_event(struct libinput_device *device,
601 enum libinput_event_type type,
602 struct libinput_event *event)
604 init_event_base(event, device, type,
605 (union libinput_event_target) { .device = device });
606 libinput_post_event(device->seat->libinput, event);
610 notify_added_device(struct libinput_device *device)
612 struct libinput_event_added_device *added_device_event;
614 added_device_event = malloc(sizeof *added_device_event);
615 if (!added_device_event)
618 *added_device_event = (struct libinput_event_added_device) {
622 post_base_event(device,
623 LIBINPUT_EVENT_ADDED_DEVICE,
624 &added_device_event->base);
628 notify_removed_device(struct libinput_device *device)
630 struct libinput_event_removed_device *removed_device_event;
632 removed_device_event = malloc(sizeof *removed_device_event);
633 if (!removed_device_event)
636 *removed_device_event = (struct libinput_event_removed_device) {
640 post_base_event(device,
641 LIBINPUT_EVENT_REMOVED_DEVICE,
642 &removed_device_event->base);
646 keyboard_notify_key(struct libinput_device *device,
649 enum libinput_keyboard_key_state state)
651 struct libinput_event_keyboard_key *key_event;
653 key_event = malloc(sizeof *key_event);
657 *key_event = (struct libinput_event_keyboard_key) {
663 post_device_event(device,
664 LIBINPUT_EVENT_KEYBOARD_KEY,
669 pointer_notify_motion(struct libinput_device *device,
674 struct libinput_event_pointer_motion *motion_event;
676 motion_event = malloc(sizeof *motion_event);
680 *motion_event = (struct libinput_event_pointer_motion) {
686 post_device_event(device,
687 LIBINPUT_EVENT_POINTER_MOTION,
688 &motion_event->base);
692 pointer_notify_motion_absolute(struct libinput_device *device,
697 struct libinput_event_pointer_motion_absolute *motion_absolute_event;
699 motion_absolute_event = malloc(sizeof *motion_absolute_event);
700 if (!motion_absolute_event)
703 *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
709 post_device_event(device,
710 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
711 &motion_absolute_event->base);
715 pointer_notify_button(struct libinput_device *device,
718 enum libinput_pointer_button_state state)
720 struct libinput_event_pointer_button *button_event;
722 button_event = malloc(sizeof *button_event);
726 *button_event = (struct libinput_event_pointer_button) {
732 post_device_event(device,
733 LIBINPUT_EVENT_POINTER_BUTTON,
734 &button_event->base);
738 pointer_notify_axis(struct libinput_device *device,
740 enum libinput_pointer_axis axis,
743 struct libinput_event_pointer_axis *axis_event;
745 axis_event = malloc(sizeof *axis_event);
749 *axis_event = (struct libinput_event_pointer_axis) {
755 post_device_event(device,
756 LIBINPUT_EVENT_POINTER_AXIS,
761 touch_notify_touch(struct libinput_device *device,
766 enum libinput_touch_type touch_type)
768 struct libinput_event_touch_touch *touch_event;
770 touch_event = malloc(sizeof *touch_event);
774 *touch_event = (struct libinput_event_touch_touch) {
779 .touch_type = touch_type,
782 post_device_event(device,
783 LIBINPUT_EVENT_TOUCH_TOUCH,
788 libinput_post_event(struct libinput *libinput,
789 struct libinput_event *event)
791 struct libinput_event **events = libinput->events;
792 size_t events_len = libinput->events_len;
793 size_t events_count = libinput->events_count;
798 if (events_count > events_len) {
800 events = realloc(events, events_len * sizeof *events);
802 fprintf(stderr, "Failed to reallocate event ring "
807 if (libinput->events_count > 0 && libinput->events_in == 0) {
808 libinput->events_in = libinput->events_len;
809 } else if (libinput->events_count > 0 &&
810 libinput->events_out >= libinput->events_in) {
811 move_len = libinput->events_len - libinput->events_out;
812 new_out = events_len - move_len;
813 memmove(events + new_out,
814 events + libinput->events_out,
815 move_len * sizeof *events);
816 libinput->events_out = new_out;
819 libinput->events = events;
820 libinput->events_len = events_len;
823 switch (libinput_event_get_class(event)) {
824 case LIBINPUT_EVENT_CLASS_NONE:
825 case LIBINPUT_EVENT_CLASS_BASE:
827 case LIBINPUT_EVENT_CLASS_SEAT:
828 libinput_seat_ref(event->target.seat);
830 case LIBINPUT_EVENT_CLASS_DEVICE:
831 libinput_device_ref(event->target.device);
835 libinput->events_count = events_count;
836 events[libinput->events_in] = event;
837 libinput->events_in = (libinput->events_in + 1) % libinput->events_len;
840 LIBINPUT_EXPORT struct libinput_event *
841 libinput_get_event(struct libinput *libinput)
843 struct libinput_event *event;
845 if (libinput->events_count == 0)
848 event = libinput->events[libinput->events_out];
849 libinput->events_out =
850 (libinput->events_out + 1) % libinput->events_len;
851 libinput->events_count--;
856 LIBINPUT_EXPORT enum libinput_event_type
857 libinput_next_event_type(struct libinput *libinput)
859 struct libinput_event *event;
861 if (libinput->events_count == 0)
862 return LIBINPUT_EVENT_NONE;
864 event = libinput->events[libinput->events_out];
868 LIBINPUT_EXPORT void *
869 libinput_get_user_data(struct libinput *libinput)
871 return libinput->user_data;
875 libinput_resume(struct libinput *libinput)
877 return libinput->interface_backend->resume(libinput);
881 libinput_suspend(struct libinput *libinput)
883 libinput->interface_backend->suspend(libinput);
887 libinput_device_set_user_data(struct libinput_device *device, void *user_data)
889 device->user_data = user_data;
892 LIBINPUT_EXPORT void *
893 libinput_device_get_user_data(struct libinput_device *device)
895 return device->user_data;
898 LIBINPUT_EXPORT const char *
899 libinput_device_get_sysname(struct libinput_device *device)
901 return evdev_device_get_sysname((struct evdev_device *) device);
904 LIBINPUT_EXPORT const char *
905 libinput_device_get_output_name(struct libinput_device *device)
907 return evdev_device_get_output((struct evdev_device *) device);
910 LIBINPUT_EXPORT struct libinput_seat *
911 libinput_device_get_seat(struct libinput_device *device)
917 libinput_device_led_update(struct libinput_device *device,
918 enum libinput_led leds)
920 evdev_device_led_update((struct evdev_device *) device, leds);
924 libinput_device_get_keys(struct libinput_device *device,
925 char *keys, size_t size)
927 return evdev_device_get_keys((struct evdev_device *) device,
933 libinput_device_calibrate(struct libinput_device *device,
934 float calibration[6])
936 evdev_device_calibrate((struct evdev_device *) device, calibration);
940 libinput_device_has_capability(struct libinput_device *device,
941 enum libinput_device_capability capability)
943 return evdev_device_has_capability((struct evdev_device *) device,