• 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 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