• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bool
process_multimodalinput_touch_event(struct libinput_event * event,struct evdev_device * device,void ** data)216 process_multimodalinput_touch_event(struct libinput_event *event, struct evdev_device *device, void **data)
217 {
218     if (!event) {
219         weston_log("process_multimodalinput_events: libinput_event is nullptr.\n");
220         return false;
221     }
222     if (!device) {
223         weston_log("process_multimodalinput_events: evdev_device is nullptr.\n");
224         return false;
225     }
226     struct weston_touch *touch = device->touch_device->aggregate;
227     if (!touch || !touch->focus) {
228         weston_log("process_multimodalinput_events: weston_touch_has_focus_resource return false.\n");
229         return false;
230     }
231 
232     uint32_t width = device->output->current_mode->width;
233     uint32_t height = device->output->current_mode->height;
234     struct libinput_event_touch *touch_event = libinput_event_get_touch_event(event);
235     if (!touch_event) {
236         weston_log("process_multimodalinput_events: libinput_event_get_touch_event return false.\n");
237         return false;
238     }
239     double double_x = libinput_event_touch_get_x_transformed(touch_event, width);
240     double double_y = libinput_event_touch_get_y_transformed(touch_event, height);
241     weston_output_transform_coordinate(device->output, double_x, double_y, &double_x, &double_y);
242 
243     wl_fixed_t x = wl_fixed_from_double(double_x);
244     wl_fixed_t y = wl_fixed_from_double(double_y);
245 
246     wl_fixed_t sx, sy;
247     weston_view_from_global_fixed(touch->focus, x, y, &sx, &sy);
248     double dx = wl_fixed_to_double(sx);
249     double dy = wl_fixed_to_double(sy);
250 
251     *data = malloc(sizeof(struct multimodal_input_pointer_data));
252     if (!(*data)) {
253         weston_log("process_multimodalinput_events: malloc multimodal_input_pointer_data return null.\n");
254         return false;
255     }
256     struct multimodal_input_pointer_data *pdata = (struct multimodal_input_pointer_data *)(*data);
257     pdata->x = double_x;
258     pdata->y = double_y;
259     pdata->sx = dx;
260     pdata->sy = dy;
261     return true;
262 }
263 
264 bool
process_multimodalinput_pointer_event(struct evdev_device * device,void ** data)265 process_multimodalinput_pointer_event(struct evdev_device *device, void **data)
266 {
267     if (!device) {
268         weston_log("process_multimodalinput_events: evdev_device is nullptr.\n");
269         return false;
270     }
271     struct weston_pointer *pointer = weston_seat_get_pointer(device->seat);
272     if (!pointer) {
273         weston_log("process_multimodalinput_events: weston_seat_get_pointer return null.\n");
274         return false;
275     }
276     *data = malloc(sizeof(struct multimodal_input_pointer_data));
277     if (!(*data)) {
278         weston_log("process_multimodalinput_events: malloc multimodal_input_pointer_data return null.\n");
279         return false;
280     }
281     struct multimodal_input_pointer_data *pdata = (struct multimodal_input_pointer_data *)(*data);
282     pdata->x = wl_fixed_to_int(pointer->x);
283     pdata->y = wl_fixed_to_int(pointer->y);
284     pdata->sx = wl_fixed_to_int(pointer->sx);
285     pdata->sy = wl_fixed_to_int(pointer->sy);
286     return true;
287 }
288 
289 void
process_multimodalinput_events(struct libinput_event * event)290 process_multimodalinput_events(struct libinput_event *event)
291 {
292     if (!event) {
293         weston_log("process_multimodalinput_events: libinput_event is nullptr.\n");
294         return;
295     }
296     if (!g_libinput_event_listener) {
297         weston_log("process_multimodalinput_events: libinput_event_listener is not set.\n");
298         return;
299     }
300     struct libinput_device *libinput_dev = libinput_event_get_device(event);
301     if (!libinput_dev) {
302         weston_log("process_multimodalinput_events: libinput_event_get_device is nullptr.\n");
303         return;
304     }
305     struct evdev_device *device = libinput_device_get_user_data(libinput_dev);
306     if (!device || !device->output) {
307         weston_log("process_multimodalinput_events: libinput_device_get_user_data evdev_device is nullptr.\n");
308         return;
309     }
310 
311     struct multimodal_libinput_event muli_event = {};
312     muli_event.event = event;
313     int type = libinput_event_get_type(event);
314     if (LIBINPUT_EVENT_TOUCH_DOWN == type || LIBINPUT_EVENT_TOUCH_MOTION == type) {
315         if (!process_multimodalinput_touch_event(event, device, (void **)&muli_event.userdata)) {
316             weston_log("process_multimodalinput_events: process_multimodalinput_touch_event "
317                        "return false.\n");
318             return;
319         }
320     } else if (LIBINPUT_EVENT_POINTER_MOTION == type || LIBINPUT_EVENT_POINTER_BUTTON == type) {
321         if (!process_multimodalinput_pointer_event(device, (void **)&muli_event.userdata)) {
322             weston_log("process_multimodalinput_events: process_multimodalinput_pointer_event "
323                        "return false.\n");
324             return;
325         }
326     }
327     g_libinput_event_listener(&muli_event);
328     if (muli_event.userdata) {
329         free(muli_event.userdata);
330         muli_event.userdata = NULL;
331     }
332 }
333 
334 static void
process_events(struct udev_input * input)335 process_events(struct udev_input *input)
336 {
337     struct libinput_event *event = NULL;
338     while ((event = libinput_get_event(input->libinput))) {
339         process_event(event);
340         process_multimodalinput_events(event);
341         libinput_event_destroy(event);
342     }
343 }
344 
345 static int
udev_input_dispatch(struct udev_input * input)346 udev_input_dispatch(struct udev_input *input)
347 {
348 	if (libinput_dispatch(input->libinput) != 0)
349 		weston_log("libinput: Failed to dispatch libinput\n");
350 
351 	process_events(input);
352 
353 	return 0;
354 }
355 
356 static int
libinput_source_dispatch(int fd,uint32_t mask,void * data)357 libinput_source_dispatch(int fd, uint32_t mask, void *data)
358 {
359 	struct udev_input *input = data;
360 
361 	return udev_input_dispatch(input) != 0;
362 }
363 
364 static int
open_restricted(const char * path,int flags,void * user_data)365 open_restricted(const char *path, int flags, void *user_data)
366 {
367 	struct udev_input *input = user_data;
368 	struct weston_launcher *launcher = input->compositor->launcher;
369 
370 	return weston_launcher_open(launcher, path, flags);
371 }
372 
373 static void
close_restricted(int fd,void * user_data)374 close_restricted(int fd, void *user_data)
375 {
376 	struct udev_input *input = user_data;
377 	struct weston_launcher *launcher = input->compositor->launcher;
378 
379 	weston_launcher_close(launcher, fd);
380 }
381 
382 const struct libinput_interface libinput_interface = {
383 	open_restricted,
384 	close_restricted,
385 };
386 
387 int
udev_input_enable(struct udev_input * input)388 udev_input_enable(struct udev_input *input)
389 {
390 	struct wl_event_loop *loop;
391 	struct weston_compositor *c = input->compositor;
392 	int fd;
393 	struct udev_seat *seat;
394 	int devices_found = 0;
395 
396 	loop = wl_display_get_event_loop(c->wl_display);
397 	fd = libinput_get_fd(input->libinput);
398 	input->libinput_source =
399 		wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
400 				     libinput_source_dispatch, input);
401 	if (!input->libinput_source) {
402 		return -1;
403 	}
404 
405 	if (input->suspended) {
406 		if (libinput_resume(input->libinput) != 0) {
407 			wl_event_source_remove(input->libinput_source);
408 			input->libinput_source = NULL;
409 			return -1;
410 		}
411 		input->suspended = 0;
412 		process_events(input);
413 	}
414 
415 	wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
416 		evdev_notify_keyboard_focus_l(&seat->base, &seat->devices_list);
417 
418 		if (!wl_list_empty(&seat->devices_list))
419 			devices_found = 1;
420 	}
421 
422 	if (devices_found == 0 && !c->require_input) {
423 		weston_log("warning: no input devices found, but none required "
424 			   "as per configuration.\n");
425 		return 0;
426 	}
427 
428 	if (devices_found == 0) {
429 		weston_log(
430 			"warning: no input devices on entering Weston. "
431 			"Possible causes:\n"
432 			"\t- no permissions to read /dev/input/event*\n"
433 			"\t- seats misconfigured "
434 			"(Weston backend option 'seat', "
435 			"udev device property ID_SEAT)\n");
436 		return -1;
437 	}
438 
439 	return 0;
440 }
441 
442 static void
libinput_log_func(struct libinput * libinput,enum libinput_log_priority priority,const char * format,va_list args)443 libinput_log_func(struct libinput *libinput,
444 		  enum libinput_log_priority priority,
445 		  const char *format, va_list args)
446 {
447 	weston_vlog(format, args);
448 }
449 
450 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)451 udev_input_init(struct udev_input *input, struct weston_compositor *c,
452 		struct udev *udev, const char *seat_id,
453 		udev_configure_device_t configure_device)
454 {
455 	enum libinput_log_priority priority = LIBINPUT_LOG_PRIORITY_INFO;
456 	const char *log_priority = NULL;
457 
458 	memset(input, 0, sizeof *input);
459 
460 	input->compositor = c;
461 	input->configure_device = configure_device;
462 
463 	log_priority = getenv("WESTON_LIBINPUT_LOG_PRIORITY");
464 
465 	input->libinput = libinput_udev_create_context(&libinput_interface,
466 						       input, udev);
467 	if (!input->libinput) {
468 		return -1;
469 	}
470 
471 	libinput_log_set_handler(input->libinput, &libinput_log_func);
472 
473 	if (log_priority) {
474 		if (strcmp(log_priority, "debug") == 0) {
475 			priority = LIBINPUT_LOG_PRIORITY_DEBUG;
476 		} else if (strcmp(log_priority, "info") == 0) {
477 			priority = LIBINPUT_LOG_PRIORITY_INFO;
478 		} else if (strcmp(log_priority, "error") == 0) {
479 			priority = LIBINPUT_LOG_PRIORITY_ERROR;
480 		}
481 	}
482 
483 	libinput_log_set_priority(input->libinput, priority);
484 
485 	if (libinput_udev_assign_seat(input->libinput, seat_id) != 0) {
486 		libinput_unref(input->libinput);
487 		return -1;
488 	}
489 
490 	process_events(input);
491 
492 	return udev_input_enable(input);
493 }
494 
495 void
udev_input_destroy(struct udev_input * input)496 udev_input_destroy(struct udev_input *input)
497 {
498 	struct udev_seat *seat, *next;
499 
500 	if (input->libinput_source)
501 		wl_event_source_remove(input->libinput_source);
502 	wl_list_for_each_safe(seat, next, &input->compositor->seat_list, base.link)
503 		udev_seat_destroy(seat);
504 	libinput_unref(input->libinput);
505 }
506 
507 static void
udev_seat_led_update(struct weston_seat * seat_base,enum weston_led leds)508 udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds)
509 {
510 	struct udev_seat *seat = (struct udev_seat *) seat_base;
511 	struct evdev_device *device;
512 
513 	wl_list_for_each(device, &seat->devices_list, link)
514 		evdev_led_update_l(device, leds);
515 }
516 
517 static void
udev_seat_output_changed(struct udev_seat * seat,struct weston_output * output)518 udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output)
519 {
520 	struct evdev_device *device;
521 	struct weston_output *found;
522 
523 	wl_list_for_each(device, &seat->devices_list, link) {
524 		/* If we find any input device without an associated output
525 		 * or an output name to associate with, just tie it with the
526 		 * output we got here - the default assignment.
527 		 */
528 		if (!device->output_name) {
529 			if (!device->output)
530 				evdev_device_set_output_l(device, output);
531 
532 			continue;
533 		}
534 
535 		/* Update all devices' output associations, may they gain or
536 		 * lose it.
537 		 */
538 		found = output_find_by_head_name(output->compositor,
539 						 device->output_name);
540 		evdev_device_set_output_l(device, found);
541 	}
542 }
543 
544 static void
notify_output_create(struct wl_listener * listener,void * data)545 notify_output_create(struct wl_listener *listener, void *data)
546 {
547 	struct udev_seat *seat = container_of(listener, struct udev_seat,
548 					      output_create_listener);
549 	struct weston_output *output = data;
550 
551 	udev_seat_output_changed(seat, output);
552 }
553 
554 static void
notify_output_heads_changed(struct wl_listener * listener,void * data)555 notify_output_heads_changed(struct wl_listener *listener, void *data)
556 {
557 	struct udev_seat *seat = container_of(listener, struct udev_seat,
558 					      output_heads_listener);
559 	struct weston_output *output = data;
560 
561 	udev_seat_output_changed(seat, output);
562 }
563 
564 static struct udev_seat *
udev_seat_create(struct udev_input * input,const char * seat_name)565 udev_seat_create(struct udev_input *input, const char *seat_name)
566 {
567 	struct weston_compositor *c = input->compositor;
568 	struct udev_seat *seat;
569 
570 	seat = zalloc(sizeof *seat);
571 	if (!seat)
572 		return NULL;
573 
574 	weston_seat_init(&seat->base, c, seat_name);
575 	seat->base.led_update = udev_seat_led_update;
576 
577 	seat->output_create_listener.notify = notify_output_create;
578 	wl_signal_add(&c->output_created_signal,
579 		      &seat->output_create_listener);
580 
581 	seat->output_heads_listener.notify = notify_output_heads_changed;
582 	wl_signal_add(&c->output_heads_changed_signal,
583 		      &seat->output_heads_listener);
584 
585 	wl_list_init(&seat->devices_list);
586 
587 	return seat;
588 }
589 
590 static void
udev_seat_destroy(struct udev_seat * seat)591 udev_seat_destroy(struct udev_seat *seat)
592 {
593 	struct weston_keyboard *keyboard =
594 		weston_seat_get_keyboard(&seat->base);
595 
596 	if (keyboard)
597 		notify_keyboard_focus_out(&seat->base);
598 
599 	udev_seat_remove_devices(seat);
600 	weston_seat_release(&seat->base);
601 	wl_list_remove(&seat->output_create_listener.link);
602 	wl_list_remove(&seat->output_heads_listener.link);
603 	free(seat);
604 }
605 
606 struct udev_seat *
udev_seat_get_named(struct udev_input * input,const char * seat_name)607 udev_seat_get_named(struct udev_input *input, const char *seat_name)
608 {
609 	struct udev_seat *seat;
610 
611 	wl_list_for_each(seat, &input->compositor->seat_list, base.link) {
612 		if (strcmp(seat->base.seat_name, seat_name) == 0)
613 			return seat;
614 	}
615 
616 	return udev_seat_create(input, seat_name);
617 }
618