1 /*
2 * Copyright © 2013 Intel Corporation
3 * Copyright © 2013 Jonas Ådahl
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #include "config.h"
28
29 #include <stdint.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <libinput.h>
35 #include <libudev.h>
36
37 #include <libweston/libweston.h>
38 #include "backend.h"
39 #include "libweston-internal.h"
40 // OHOS remove logger
41 //#include "weston-log-internal.h"
42 #include "launcher-util.h"
43 #include "libinput-seat.h"
44 #include "libinput-device.h"
45 #include "shared/helpers.h"
46 // for multi model input
47 #include "libinput-seat-export.h"
48
49 static libinput_event_listener g_libinput_event_listener = NULL;
set_libinput_event_listener(libinput_event_listener listener)50 void set_libinput_event_listener(libinput_event_listener listener)
51 {
52 g_libinput_event_listener = listener;
53 }
54
55 static void
56 process_events(struct udev_input *input);
57 static struct udev_seat *
58 udev_seat_create(struct udev_input *input, const char *seat_name);
59 static void
60 udev_seat_destroy(struct udev_seat *seat);
61
62 static struct udev_seat *
get_udev_seat(struct udev_input * input,struct libinput_device * device)63 get_udev_seat(struct udev_input *input, struct libinput_device *device)
64 {
65 struct libinput_seat *libinput_seat;
66 const char *seat_name;
67
68 libinput_seat = libinput_device_get_seat(device);
69 seat_name = libinput_seat_get_logical_name(libinput_seat);
70 return udev_seat_get_named(input, seat_name);
71 }
72
73 static struct weston_output *
output_find_by_head_name(struct weston_compositor * compositor,const char * head_name)74 output_find_by_head_name(struct weston_compositor *compositor,
75 const char *head_name)
76 {
77 struct weston_output *output;
78 struct weston_head *head;
79
80 if (!head_name)
81 return NULL;
82
83 /* Only enabled outputs with connected heads.
84 * This means force-enabled outputs but with disconnected heads
85 * will be ignored; if the touchscreen doesn't have a video signal,
86 * touching it is meaningless.
87 */
88 wl_list_for_each(output, &compositor->output_list, link) {
89 wl_list_for_each(head, &output->head_list, output_link) {
90 if (!weston_head_is_connected(head))
91 continue;
92
93 if (strcmp(head_name, head->name) == 0)
94 return output;
95 }
96 }
97
98 return NULL;
99 }
100
101 static void
device_added(struct udev_input * input,struct libinput_device * libinput_device)102 device_added(struct udev_input *input, struct libinput_device *libinput_device)
103 {
104 struct weston_compositor *c;
105 struct evdev_device *device;
106 struct weston_output *output;
107 const char *output_name;
108 struct weston_seat *seat;
109 struct udev_seat *udev_seat;
110 struct weston_pointer *pointer;
111
112 c = input->compositor;
113
114 udev_seat = get_udev_seat(input, libinput_device);
115 if (!udev_seat)
116 return;
117
118 seat = &udev_seat->base;
119 device = evdev_device_create_l(libinput_device, seat);
120 if (device == NULL)
121 return;
122
123 if (input->configure_device != NULL)
124 input->configure_device(c, device->device);
125 evdev_device_set_calibration_l(device);
126 udev_seat = (struct udev_seat *) seat;
127 wl_list_insert(udev_seat->devices_list.prev, &device->link);
128
129 pointer = weston_seat_get_pointer(seat);
130 if (seat->output && pointer)
131 weston_pointer_clamp(pointer,
132 &pointer->x,
133 &pointer->y);
134
135 output_name = libinput_device_get_output_name(libinput_device);
136 if (output_name) {
137 device->output_name = strdup(output_name);
138 output = output_find_by_head_name(c, output_name);
139 evdev_device_set_output_l(device, output);
140 } else if (!wl_list_empty(&c->output_list)) {
141 /* default assignment to an arbitrary output */
142 output = container_of(c->output_list.next,
143 struct weston_output, link);
144 evdev_device_set_output_l(device, output);
145 }
146
147 if (!input->suspended)
148 weston_seat_repick(seat);
149 }
150
151 static void
device_removed(struct udev_input * input,struct libinput_device * libinput_device)152 device_removed(struct udev_input *input, struct libinput_device *libinput_device)
153 {
154 struct evdev_device *device;
155
156 device = libinput_device_get_user_data(libinput_device);
157 evdev_device_destroy_l(device);
158 }
159
160 static void
udev_seat_remove_devices(struct udev_seat * seat)161 udev_seat_remove_devices(struct udev_seat *seat)
162 {
163 struct evdev_device *device, *next;
164
165 wl_list_for_each_safe(device, next, &seat->devices_list, link) {
166 evdev_device_destroy_l(device);
167 }
168 }
169
170 void
udev_input_disable(struct udev_input * input)171 udev_input_disable(struct udev_input *input)
172 {
173 if (input->suspended)
174 return;
175
176 wl_event_source_remove(input->libinput_source);
177 input->libinput_source = NULL;
178 libinput_suspend(input->libinput);
179 process_events(input);
180 input->suspended = 1;
181 }
182
183 static int
udev_input_process_event(struct libinput_event * event)184 udev_input_process_event(struct libinput_event *event)
185 {
186 struct libinput *libinput = libinput_event_get_context(event);
187 struct libinput_device *libinput_device =
188 libinput_event_get_device(event);
189 struct udev_input *input = libinput_get_user_data(libinput);
190 int handled = 1;
191
192 switch (libinput_event_get_type(event)) {
193 case LIBINPUT_EVENT_DEVICE_ADDED:
194 device_added(input, libinput_device);
195 break;
196 case LIBINPUT_EVENT_DEVICE_REMOVED:
197 device_removed(input, libinput_device);
198 break;
199 default:
200 handled = 0;
201 }
202
203 return handled;
204 }
205
206 static void
process_event(struct libinput_event * event)207 process_event(struct libinput_event *event)
208 {
209 if (udev_input_process_event(event))
210 return;
211 if (evdev_device_process_event_l(event))
212 return;
213 }
214
215 static void
process_events(struct udev_input * input)216 process_events(struct udev_input *input)
217 {
218 struct libinput_event *event;
219
220 while ((event = libinput_get_event(input->libinput))) {
221 process_event(event);
222 // for multi model input.
223 if (g_libinput_event_listener)
224 {
225 weston_log("process_events: call libinput_event_listener.\n");
226 g_libinput_event_listener(event);
227 }
228 else
229 {
230 weston_log("process_events: libinput_event_listener is not set.\n");
231 }
232 libinput_event_destroy(event);
233 }
234 }
235
236 static int
udev_input_dispatch(struct udev_input * input)237 udev_input_dispatch(struct udev_input *input)
238 {
239 if (libinput_dispatch(input->libinput) != 0)
240 weston_log("libinput: Failed to dispatch libinput\n");
241
242 process_events(input);
243
244 return 0;
245 }
246
247 static int
libinput_source_dispatch(int fd,uint32_t mask,void * data)248 libinput_source_dispatch(int fd, uint32_t mask, void *data)
249 {
250 struct udev_input *input = data;
251
252 return udev_input_dispatch(input) != 0;
253 }
254
255 static int
open_restricted(const char * path,int flags,void * user_data)256 open_restricted(const char *path, int flags, void *user_data)
257 {
258 struct udev_input *input = user_data;
259 struct weston_launcher *launcher = input->compositor->launcher;
260
261 return weston_launcher_open(launcher, path, flags);
262 }
263
264 static void
close_restricted(int fd,void * user_data)265 close_restricted(int fd, void *user_data)
266 {
267 struct udev_input *input = user_data;
268 struct weston_launcher *launcher = input->compositor->launcher;
269
270 weston_launcher_close(launcher, fd);
271 }
272
273 const struct libinput_interface libinput_interface = {
274 open_restricted,
275 close_restricted,
276 };
277
278 int
udev_input_enable(struct udev_input * input)279 udev_input_enable(struct udev_input *input)
280 {
281 struct wl_event_loop *loop;
282 struct weston_compositor *c = input->compositor;
283 int fd;
284 struct udev_seat *seat;
285 int devices_found = 0;
286
287 loop = wl_display_get_event_loop(c->wl_display);
288 fd = libinput_get_fd(input->libinput);
289 input->libinput_source =
290 wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
291 libinput_source_dispatch, input);
292 if (!input->libinput_source) {
293 return -1;
294 }
295
296 if (input->suspended) {
297 if (libinput_resume(input->libinput) != 0) {
298 wl_event_source_remove(input->libinput_source);
299 input->libinput_source = NULL;
300 return -1;
301 }
302 input->suspended = 0;
303 process_events(input);
304 }
305
306 wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
307 evdev_notify_keyboard_focus_l(&seat->base, &seat->devices_list);
308
309 if (!wl_list_empty(&seat->devices_list))
310 devices_found = 1;
311 }
312
313 if (devices_found == 0 && !c->require_input) {
314 weston_log("warning: no input devices found, but none required "
315 "as per configuration.\n");
316 return 0;
317 }
318
319 if (devices_found == 0) {
320 weston_log(
321 "warning: no input devices on entering Weston. "
322 "Possible causes:\n"
323 "\t- no permissions to read /dev/input/event*\n"
324 "\t- seats misconfigured "
325 "(Weston backend option 'seat', "
326 "udev device property ID_SEAT)\n");
327 return -1;
328 }
329
330 return 0;
331 }
332
333 static void
libinput_log_func(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)334 libinput_log_func(struct libinput *libinput,
335 enum libinput_log_priority priority,
336 const char *format, va_list args)
337 {
338 weston_vlog(format, args);
339 }
340
341 int
udev_input_init(struct udev_input * input,struct weston_compositor * c,struct udev * udev,const char * seat_id,udev_configure_device_t configure_device)342 udev_input_init(struct udev_input *input, struct weston_compositor *c,
343 struct udev *udev, const char *seat_id,
344 udev_configure_device_t configure_device)
345 {
346 enum libinput_log_priority priority = LIBINPUT_LOG_PRIORITY_INFO;
347 const char *log_priority = NULL;
348
349 memset(input, 0, sizeof *input);
350
351 input->compositor = c;
352 input->configure_device = configure_device;
353
354 log_priority = getenv("WESTON_LIBINPUT_LOG_PRIORITY");
355
356 input->libinput = libinput_udev_create_context(&libinput_interface,
357 input, udev);
358 if (!input->libinput) {
359 return -1;
360 }
361
362 libinput_log_set_handler(input->libinput, &libinput_log_func);
363
364 if (log_priority) {
365 if (strcmp(log_priority, "debug") == 0) {
366 priority = LIBINPUT_LOG_PRIORITY_DEBUG;
367 } else if (strcmp(log_priority, "info") == 0) {
368 priority = LIBINPUT_LOG_PRIORITY_INFO;
369 } else if (strcmp(log_priority, "error") == 0) {
370 priority = LIBINPUT_LOG_PRIORITY_ERROR;
371 }
372 }
373
374 libinput_log_set_priority(input->libinput, priority);
375
376 if (libinput_udev_assign_seat(input->libinput, seat_id) != 0) {
377 libinput_unref(input->libinput);
378 return -1;
379 }
380
381 process_events(input);
382
383 return udev_input_enable(input);
384 }
385
386 void
udev_input_destroy(struct udev_input * input)387 udev_input_destroy(struct udev_input *input)
388 {
389 struct udev_seat *seat, *next;
390
391 if (input->libinput_source)
392 wl_event_source_remove(input->libinput_source);
393 wl_list_for_each_safe(seat, next, &input->compositor->seat_list, base.link)
394 udev_seat_destroy(seat);
395 libinput_unref(input->libinput);
396 }
397
398 static void
udev_seat_led_update(struct weston_seat * seat_base,enum weston_led leds)399 udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds)
400 {
401 struct udev_seat *seat = (struct udev_seat *) seat_base;
402 struct evdev_device *device;
403
404 wl_list_for_each(device, &seat->devices_list, link)
405 evdev_led_update_l(device, leds);
406 }
407
408 static void
udev_seat_output_changed(struct udev_seat * seat,struct weston_output * output)409 udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output)
410 {
411 struct evdev_device *device;
412 struct weston_output *found;
413
414 wl_list_for_each(device, &seat->devices_list, link) {
415 /* If we find any input device without an associated output
416 * or an output name to associate with, just tie it with the
417 * output we got here - the default assignment.
418 */
419 if (!device->output_name) {
420 if (!device->output)
421 evdev_device_set_output_l(device, output);
422
423 continue;
424 }
425
426 /* Update all devices' output associations, may they gain or
427 * lose it.
428 */
429 found = output_find_by_head_name(output->compositor,
430 device->output_name);
431 evdev_device_set_output_l(device, found);
432 }
433 }
434
435 static void
notify_output_create(struct wl_listener * listener,void * data)436 notify_output_create(struct wl_listener *listener, void *data)
437 {
438 struct udev_seat *seat = container_of(listener, struct udev_seat,
439 output_create_listener);
440 struct weston_output *output = data;
441
442 udev_seat_output_changed(seat, output);
443 }
444
445 static void
notify_output_heads_changed(struct wl_listener * listener,void * data)446 notify_output_heads_changed(struct wl_listener *listener, void *data)
447 {
448 struct udev_seat *seat = container_of(listener, struct udev_seat,
449 output_heads_listener);
450 struct weston_output *output = data;
451
452 udev_seat_output_changed(seat, output);
453 }
454
455 static struct udev_seat *
udev_seat_create(struct udev_input * input,const char * seat_name)456 udev_seat_create(struct udev_input *input, const char *seat_name)
457 {
458 struct weston_compositor *c = input->compositor;
459 struct udev_seat *seat;
460
461 seat = zalloc(sizeof *seat);
462 if (!seat)
463 return NULL;
464
465 weston_seat_init(&seat->base, c, seat_name);
466 seat->base.led_update = udev_seat_led_update;
467
468 seat->output_create_listener.notify = notify_output_create;
469 wl_signal_add(&c->output_created_signal,
470 &seat->output_create_listener);
471
472 seat->output_heads_listener.notify = notify_output_heads_changed;
473 wl_signal_add(&c->output_heads_changed_signal,
474 &seat->output_heads_listener);
475
476 wl_list_init(&seat->devices_list);
477
478 return seat;
479 }
480
481 static void
udev_seat_destroy(struct udev_seat * seat)482 udev_seat_destroy(struct udev_seat *seat)
483 {
484 struct weston_keyboard *keyboard =
485 weston_seat_get_keyboard(&seat->base);
486
487 if (keyboard)
488 notify_keyboard_focus_out(&seat->base);
489
490 udev_seat_remove_devices(seat);
491 weston_seat_release(&seat->base);
492 wl_list_remove(&seat->output_create_listener.link);
493 wl_list_remove(&seat->output_heads_listener.link);
494 free(seat);
495 }
496
497 struct udev_seat *
udev_seat_get_named(struct udev_input * input,const char * seat_name)498 udev_seat_get_named(struct udev_input *input, const char *seat_name)
499 {
500 struct udev_seat *seat;
501
502 wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
503 if (strcmp(seat->base.seat_name, seat_name) == 0)
504 return seat;
505 }
506
507 return udev_seat_create(input, seat_name);
508 }
509