13 static const struct ds_backend_interface libinput_backend_interface;
14 static void libinput_backend_handle_display_destroy(
15 struct wl_listener *listener, void *data);
17 WL_EXPORT struct ds_backend *
18 ds_libinput_backend_create(struct wl_display *display)
20 struct ds_libinput_backend *libinput_backend;
22 libinput_backend = calloc(1, sizeof *libinput_backend);
23 if (!libinput_backend) {
24 ds_log_errno(DS_ERR, "Could not allocate memory");
28 ds_backend_init(&libinput_backend->base, &libinput_backend_interface);
30 libinput_backend->display = display;
31 wl_list_init(&libinput_backend->devices);
33 libinput_backend->display_destroy.notify =
34 libinput_backend_handle_display_destroy;
35 wl_display_add_destroy_listener(display,
36 &libinput_backend->display_destroy);
38 ds_inf("Libinput backend(%p) created",
41 return &libinput_backend->base;
44 WL_EXPORT struct ds_libinput_backend *
45 libinput_backend_from_backend(struct ds_backend *backend)
47 assert(backend->iface == &libinput_backend_interface);
48 return (struct ds_libinput_backend *)backend;
52 destroy_libinput_input_device(struct ds_libinput_input_device *dev)
54 ds_input_device_destroy(&dev->base);
55 libinput_device_unref(dev->handle);
56 wl_list_remove(&dev->link);
61 libinput_backend_destroy(struct ds_libinput_backend *backend)
63 struct ds_libinput_input_device *dev, *tmp_dev;
65 wl_list_for_each_safe(dev, tmp_dev, &backend->devices, link)
66 destroy_libinput_input_device(dev);
68 ds_backend_finish(&backend->base);
69 wl_list_remove(&backend->display_destroy.link);
70 wl_event_source_remove(backend->server_event_source);
71 udev_unref(backend->udev);
72 libinput_unref(backend->libinput_context);
78 libinput_open_restricted(const char *path, int flags, void *_backend)
83 fd = open(path, flags | O_CLOEXEC);
85 if (fd < 0 || (fstat(fd, &s) == -1)) {
86 ds_log(DS_ERR, "Could not open device");
94 libinput_close_restricted(int fd, void *_backend)
96 if (fd >= 0) close(fd);
99 static const struct libinput_interface libinput_impl = {
100 .open_restricted = libinput_open_restricted,
101 .close_restricted = libinput_close_restricted
105 handle_libinput_readable(int fd, uint32_t mask, void *_backend)
107 struct ds_libinput_backend *backend = _backend;
108 struct libinput_event *event;
111 ret = libinput_dispatch(backend->libinput_context);
113 ds_log(DS_ERR, "Failed to dispatch libinput: %s", strerror(-ret));
114 wl_display_terminate(backend->display);
118 while ((event = libinput_get_event(backend->libinput_context))) {
119 handle_libinput_event(backend, event);
120 libinput_event_destroy(event);
126 log_libinput(struct libinput *libinput_context,
127 enum libinput_log_priority priority, const char *fmt, va_list args)
129 char buf[1024] = {0,};
131 vsnprintf(buf, 1024, fmt, args);
133 case LIBINPUT_LOG_PRIORITY_DEBUG:
134 ds_log(DS_DBG,"%s", buf);
136 case LIBINPUT_LOG_PRIORITY_INFO:
137 ds_log(DS_INF, "%s", buf);
139 case LIBINPUT_LOG_PRIORITY_ERROR:
140 ds_log(DS_ERR, "%s", buf);
148 libinput_backend_iface_start(struct ds_backend *ds_backend)
150 struct ds_libinput_backend *backend;
151 struct wl_event_loop *event_loop;
154 backend = libinput_backend_from_backend(ds_backend);
155 ds_log(DS_DBG, "Starting libinput backend");
157 backend->udev = udev_new();
158 backend->libinput_context = libinput_udev_create_context(&libinput_impl,
159 backend, backend->udev);
160 if (!backend->libinput_context) {
161 ds_log(DS_ERR, "Failed to create libinput context");
165 if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) {
166 ds_log(DS_ERR, "Failed to assign libinput seat");
170 libinput_log_set_handler(backend->libinput_context, log_libinput);
171 libinput_log_set_priority(backend->libinput_context,
172 LIBINPUT_LOG_PRIORITY_DEBUG);
174 libinput_fd = libinput_get_fd(backend->libinput_context);
175 if (wl_list_empty(&backend->devices)) {
176 handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend);
177 if (wl_list_empty(&backend->devices)) {
178 ds_log(DS_ERR, "libinput initialization failed, no input devices");
183 event_loop = wl_display_get_event_loop(backend->display);
184 if (backend->server_event_source) {
185 wl_event_source_remove(backend->server_event_source);
187 backend->server_event_source =
188 wl_event_loop_add_fd(event_loop, libinput_fd, WL_EVENT_READABLE,
189 handle_libinput_readable, backend);
190 if (!backend->server_event_source) {
191 ds_log(DS_ERR, "Failed to create input event on event loop");
194 ds_log(DS_DBG, "libinput successfully initialized");
200 libinput_backend_iface_destroy(struct ds_backend *backend)
202 struct ds_libinput_backend *libinput_backend;
207 libinput_backend = libinput_backend_from_backend(backend);
208 libinput_backend_destroy(libinput_backend);
211 static const struct ds_backend_interface libinput_backend_interface =
213 .start = libinput_backend_iface_start,
214 .destroy = libinput_backend_iface_destroy,
219 libinput_backend_handle_display_destroy(struct wl_listener *listener,
222 struct ds_libinput_backend *libinput_backend;
225 wl_container_of(listener, libinput_backend, display_destroy);
226 libinput_backend_destroy(libinput_backend);