blob: 2126084c8b8894c087bec33f1547c4f0141145f3 [file] [log] [blame]
Jonas Ådahle0de3c22014-03-12 22:08:42 +01001/*
2 * Copyright © 2010 Intel Corporation
3 * Copyright © 2013 Jonas Ådahl
4 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -07005 * 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:
Jonas Ådahle0de3c22014-03-12 22:08:42 +010012 *
Bryce Harringtona0bbfea2015-06-11 15:35:43 -070013 * 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.
Jonas Ådahle0de3c22014-03-12 22:08:42 +010025 */
26
27#include "config.h"
28
29#include <errno.h>
30#include <stdlib.h>
31#include <string.h>
32#include <linux/input.h>
33#include <unistd.h>
34#include <fcntl.h>
35#include <mtdev.h>
36#include <assert.h>
37#include <libinput.h>
38
39#include "compositor.h"
40#include "libinput-device.h"
Jon Cruz867d50e2015-06-15 15:37:10 -070041#include "shared/helpers.h"
Giulio Camuffod52f3b72016-06-02 21:48:11 +030042#include "weston.h"
Jonas Ådahle0de3c22014-03-12 22:08:42 +010043
Jonas Ådahle0de3c22014-03-12 22:08:42 +010044void
45evdev_led_update(struct evdev_device *device, enum weston_led weston_leds)
46{
47 enum libinput_led leds = 0;
48
49 if (weston_leds & LED_NUM_LOCK)
50 leds |= LIBINPUT_LED_NUM_LOCK;
51 if (weston_leds & LED_CAPS_LOCK)
52 leds |= LIBINPUT_LED_CAPS_LOCK;
53 if (weston_leds & LED_SCROLL_LOCK)
54 leds |= LIBINPUT_LED_SCROLL_LOCK;
55
56 libinput_device_led_update(device->device, leds);
57}
58
59static void
60handle_keyboard_key(struct libinput_device *libinput_device,
61 struct libinput_event_keyboard *keyboard_event)
62{
63 struct evdev_device *device =
64 libinput_device_get_user_data(libinput_device);
Jonas Ådahl90d1ac82015-01-30 12:23:00 +080065 int key_state =
66 libinput_event_keyboard_get_key_state(keyboard_event);
67 int seat_key_count =
68 libinput_event_keyboard_get_seat_key_count(keyboard_event);
69
70 /* Ignore key events that are not seat wide state changes. */
71 if ((key_state == LIBINPUT_KEY_STATE_PRESSED &&
72 seat_key_count != 1) ||
73 (key_state == LIBINPUT_KEY_STATE_RELEASED &&
74 seat_key_count != 0))
75 return;
Jonas Ådahle0de3c22014-03-12 22:08:42 +010076
77 notify_key(device->seat,
78 libinput_event_keyboard_get_time(keyboard_event),
79 libinput_event_keyboard_get_key(keyboard_event),
Chris Michael7e7f7932016-02-22 08:47:24 -050080 key_state, STATE_UPDATE_AUTOMATIC);
Jonas Ådahle0de3c22014-03-12 22:08:42 +010081}
82
Peter Hutterer87743e92016-01-18 16:38:22 +100083static bool
Jonas Ådahle0de3c22014-03-12 22:08:42 +010084handle_pointer_motion(struct libinput_device *libinput_device,
85 struct libinput_event_pointer *pointer_event)
86{
87 struct evdev_device *device =
88 libinput_device_get_user_data(libinput_device);
Jonas Ådahld2510102014-10-05 21:39:14 +020089 struct weston_pointer_motion_event event = { 0 };
Jonas Ådahle0de3c22014-03-12 22:08:42 +010090
Jonas Ådahld2510102014-10-05 21:39:14 +020091 event = (struct weston_pointer_motion_event) {
92 .mask = WESTON_POINTER_MOTION_REL,
93 .dx = libinput_event_pointer_get_dx(pointer_event),
94 .dy = libinput_event_pointer_get_dy(pointer_event),
95 };
96
Jonas Ådahle0de3c22014-03-12 22:08:42 +010097 notify_motion(device->seat,
98 libinput_event_pointer_get_time(pointer_event),
Jonas Ådahld2510102014-10-05 21:39:14 +020099 &event);
Peter Hutterer87743e92016-01-18 16:38:22 +1000100
101 return true;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100102}
103
Peter Hutterer87743e92016-01-18 16:38:22 +1000104static bool
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100105handle_pointer_motion_absolute(
106 struct libinput_device *libinput_device,
107 struct libinput_event_pointer *pointer_event)
108{
109 struct evdev_device *device =
110 libinput_device_get_user_data(libinput_device);
111 struct weston_output *output = device->output;
112 uint32_t time;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200113 double x, y;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100114 uint32_t width, height;
115
116 if (!output)
Peter Hutterer87743e92016-01-18 16:38:22 +1000117 return false;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100118
119 time = libinput_event_pointer_get_time(pointer_event);
120 width = device->output->current_mode->width;
121 height = device->output->current_mode->height;
122
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200123 x = libinput_event_pointer_get_absolute_x_transformed(pointer_event,
124 width);
125 y = libinput_event_pointer_get_absolute_y_transformed(pointer_event,
126 height);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100127
128 weston_output_transform_coordinate(device->output, x, y, &x, &y);
129 notify_motion_absolute(device->seat, time, x, y);
Peter Hutterer87743e92016-01-18 16:38:22 +1000130
131 return true;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100132}
133
Peter Hutterer87743e92016-01-18 16:38:22 +1000134static bool
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100135handle_pointer_button(struct libinput_device *libinput_device,
136 struct libinput_event_pointer *pointer_event)
137{
138 struct evdev_device *device =
139 libinput_device_get_user_data(libinput_device);
Jonas Ådahle90b9e92015-01-30 12:22:59 +0800140 int button_state =
141 libinput_event_pointer_get_button_state(pointer_event);
142 int seat_button_count =
143 libinput_event_pointer_get_seat_button_count(pointer_event);
144
145 /* Ignore button events that are not seat wide state changes. */
146 if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED &&
147 seat_button_count != 1) ||
148 (button_state == LIBINPUT_BUTTON_STATE_RELEASED &&
149 seat_button_count != 0))
Peter Hutterer87743e92016-01-18 16:38:22 +1000150 return false;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100151
152 notify_button(device->seat,
153 libinput_event_pointer_get_time(pointer_event),
154 libinput_event_pointer_get_button(pointer_event),
Christopher Michaele1719c72016-02-19 11:07:00 -0500155 button_state);
156
Peter Hutterer87743e92016-01-18 16:38:22 +1000157 return true;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100158}
159
Peter Hutterer5dddd412015-01-15 13:14:43 +1000160static double
161normalize_scroll(struct libinput_event_pointer *pointer_event,
162 enum libinput_pointer_axis axis)
163{
Peter Hutterer5dddd412015-01-15 13:14:43 +1000164 enum libinput_pointer_axis_source source;
Peter Hutterer87743e92016-01-18 16:38:22 +1000165 double value = 0.0;
Peter Hutterer5dddd412015-01-15 13:14:43 +1000166
167 source = libinput_event_pointer_get_axis_source(pointer_event);
168 /* libinput < 0.8 sent wheel click events with value 10. Since 0.8
169 the value is the angle of the click in degrees. To keep
170 backwards-compat with existing clients, we just send multiples of
171 the click count.
172 */
173 switch (source) {
174 case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
175 value = 10 * libinput_event_pointer_get_axis_value_discrete(
176 pointer_event,
177 axis);
178 break;
179 case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
180 case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
181 value = libinput_event_pointer_get_axis_value(pointer_event,
182 axis);
183 break;
Peter Hutterer5dddd412015-01-15 13:14:43 +1000184 }
185
186 return value;
187}
188
Peter Hutterer87743e92016-01-18 16:38:22 +1000189static int32_t
190get_axis_discrete(struct libinput_event_pointer *pointer_event,
191 enum libinput_pointer_axis axis)
192{
193 enum libinput_pointer_axis_source source;
194
195 source = libinput_event_pointer_get_axis_source(pointer_event);
196
197 if (source != LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
198 return 0;
199
200 return libinput_event_pointer_get_axis_value_discrete(pointer_event,
201 axis);
202}
203
204static bool
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100205handle_pointer_axis(struct libinput_device *libinput_device,
206 struct libinput_event_pointer *pointer_event)
207{
Peter Hutterer87743e92016-01-18 16:38:22 +1000208 static int warned;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100209 struct evdev_device *device =
210 libinput_device_get_user_data(libinput_device);
Peter Hutterer87743e92016-01-18 16:38:22 +1000211 double vert, horiz;
212 int32_t vert_discrete, horiz_discrete;
Peter Huttererc54f23d2015-01-13 11:55:37 +1000213 enum libinput_pointer_axis axis;
Peter Hutterer89b6a492016-01-18 15:58:17 +1000214 struct weston_pointer_axis_event weston_event;
Peter Hutterer87743e92016-01-18 16:38:22 +1000215 enum libinput_pointer_axis_source source;
216 uint32_t wl_axis_source;
217 bool has_vert, has_horiz;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100218
Peter Hutterer87743e92016-01-18 16:38:22 +1000219 has_vert = libinput_event_pointer_has_axis(pointer_event,
220 LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
221 has_horiz = libinput_event_pointer_has_axis(pointer_event,
222 LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
223
224 if (!has_vert && !has_horiz)
225 return false;
226
227 source = libinput_event_pointer_get_axis_source(pointer_event);
228 switch (source) {
229 case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
230 wl_axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
231 break;
232 case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
233 wl_axis_source = WL_POINTER_AXIS_SOURCE_FINGER;
234 break;
235 case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
236 wl_axis_source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
237 break;
238 default:
239 if (warned < 5) {
240 weston_log("Unknown scroll source %d.\n", source);
241 warned++;
242 }
243 return false;
244 }
245
246 notify_axis_source(device->seat, wl_axis_source);
247
248 if (has_vert) {
249 axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
250 vert_discrete = get_axis_discrete(pointer_event, axis);
251 vert = normalize_scroll(pointer_event, axis);
252
Peter Hutterer89b6a492016-01-18 15:58:17 +1000253 weston_event.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200254 weston_event.value = vert;
Peter Hutterer87743e92016-01-18 16:38:22 +1000255 weston_event.discrete = vert_discrete;
256 weston_event.has_discrete = (vert_discrete != 0);
257
Peter Huttererc54f23d2015-01-13 11:55:37 +1000258 notify_axis(device->seat,
259 libinput_event_pointer_get_time(pointer_event),
Peter Hutterer89b6a492016-01-18 15:58:17 +1000260 &weston_event);
Peter Huttererc54f23d2015-01-13 11:55:37 +1000261 }
262
Peter Hutterer87743e92016-01-18 16:38:22 +1000263 if (has_horiz) {
264 axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
265 horiz_discrete = get_axis_discrete(pointer_event, axis);
266 horiz = normalize_scroll(pointer_event, axis);
267
Peter Hutterer89b6a492016-01-18 15:58:17 +1000268 weston_event.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200269 weston_event.value = horiz;
Peter Hutterer87743e92016-01-18 16:38:22 +1000270 weston_event.discrete = horiz_discrete;
271 weston_event.has_discrete = (horiz_discrete != 0);
272
Peter Huttererc54f23d2015-01-13 11:55:37 +1000273 notify_axis(device->seat,
274 libinput_event_pointer_get_time(pointer_event),
Peter Hutterer89b6a492016-01-18 15:58:17 +1000275 &weston_event);
Peter Huttererc54f23d2015-01-13 11:55:37 +1000276 }
Peter Hutterer87743e92016-01-18 16:38:22 +1000277
278 return true;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100279}
280
281static void
282handle_touch_with_coords(struct libinput_device *libinput_device,
283 struct libinput_event_touch *touch_event,
284 int touch_type)
285{
286 struct evdev_device *device =
287 libinput_device_get_user_data(libinput_device);
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200288 double x;
289 double y;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100290 uint32_t width, height;
291 uint32_t time;
292 int32_t slot;
293
Ander Conselvan de Oliveiraf957dfb2014-04-24 15:11:14 +0300294 if (!device->output)
295 return;
296
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100297 time = libinput_event_touch_get_time(touch_event);
298 slot = libinput_event_touch_get_seat_slot(touch_event);
299
300 width = device->output->current_mode->width;
301 height = device->output->current_mode->height;
Giulio Camuffo90a6fc62016-03-22 17:44:54 +0200302 x = libinput_event_touch_get_x_transformed(touch_event, width);
303 y = libinput_event_touch_get_y_transformed(touch_event, height);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100304
305 weston_output_transform_coordinate(device->output,
306 x, y, &x, &y);
307
308 notify_touch(device->seat, time, slot, x, y, touch_type);
309}
310
311static void
312handle_touch_down(struct libinput_device *device,
313 struct libinput_event_touch *touch_event)
314{
315 handle_touch_with_coords(device, touch_event, WL_TOUCH_DOWN);
316}
317
318static void
319handle_touch_motion(struct libinput_device *device,
320 struct libinput_event_touch *touch_event)
321{
322 handle_touch_with_coords(device, touch_event, WL_TOUCH_MOTION);
323}
324
325static void
326handle_touch_up(struct libinput_device *libinput_device,
327 struct libinput_event_touch *touch_event)
328{
329 struct evdev_device *device =
330 libinput_device_get_user_data(libinput_device);
331 uint32_t time = libinput_event_touch_get_time(touch_event);
332 int32_t slot = libinput_event_touch_get_seat_slot(touch_event);
333
334 notify_touch(device->seat, time, slot, 0, 0, WL_TOUCH_UP);
335}
336
Jonas Ådahl1679f232014-04-12 09:39:51 +0200337static void
338handle_touch_frame(struct libinput_device *libinput_device,
339 struct libinput_event_touch *touch_event)
340{
341 struct evdev_device *device =
342 libinput_device_get_user_data(libinput_device);
343 struct weston_seat *seat = device->seat;
344
345 notify_touch_frame(seat);
346}
347
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100348int
349evdev_device_process_event(struct libinput_event *event)
350{
351 struct libinput_device *libinput_device =
352 libinput_event_get_device(event);
Peter Hutterer87743e92016-01-18 16:38:22 +1000353 struct evdev_device *device =
354 libinput_device_get_user_data(libinput_device);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100355 int handled = 1;
Peter Hutterer87743e92016-01-18 16:38:22 +1000356 bool need_frame = false;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100357
358 switch (libinput_event_get_type(event)) {
359 case LIBINPUT_EVENT_KEYBOARD_KEY:
360 handle_keyboard_key(libinput_device,
361 libinput_event_get_keyboard_event(event));
362 break;
363 case LIBINPUT_EVENT_POINTER_MOTION:
Peter Hutterer87743e92016-01-18 16:38:22 +1000364 need_frame = handle_pointer_motion(libinput_device,
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100365 libinput_event_get_pointer_event(event));
366 break;
367 case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
Peter Hutterer87743e92016-01-18 16:38:22 +1000368 need_frame = handle_pointer_motion_absolute(
369 libinput_device,
370 libinput_event_get_pointer_event(event));
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100371 break;
372 case LIBINPUT_EVENT_POINTER_BUTTON:
Peter Hutterer87743e92016-01-18 16:38:22 +1000373 need_frame = handle_pointer_button(libinput_device,
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100374 libinput_event_get_pointer_event(event));
375 break;
376 case LIBINPUT_EVENT_POINTER_AXIS:
Peter Hutterer87743e92016-01-18 16:38:22 +1000377 need_frame = handle_pointer_axis(
378 libinput_device,
379 libinput_event_get_pointer_event(event));
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100380 break;
381 case LIBINPUT_EVENT_TOUCH_DOWN:
382 handle_touch_down(libinput_device,
383 libinput_event_get_touch_event(event));
384 break;
385 case LIBINPUT_EVENT_TOUCH_MOTION:
386 handle_touch_motion(libinput_device,
387 libinput_event_get_touch_event(event));
388 break;
389 case LIBINPUT_EVENT_TOUCH_UP:
390 handle_touch_up(libinput_device,
391 libinput_event_get_touch_event(event));
U. Artie Eoffcd9e5452014-04-17 07:53:24 -0700392 break;
Jonas Ådahl1679f232014-04-12 09:39:51 +0200393 case LIBINPUT_EVENT_TOUCH_FRAME:
394 handle_touch_frame(libinput_device,
395 libinput_event_get_touch_event(event));
396 break;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100397 default:
398 handled = 0;
399 weston_log("unknown libinput event %d\n",
400 libinput_event_get_type(event));
401 }
402
Peter Hutterer87743e92016-01-18 16:38:22 +1000403 if (need_frame)
404 notify_pointer_frame(device->seat);
405
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100406 return handled;
407}
408
409static void
410notify_output_destroy(struct wl_listener *listener, void *data)
411{
412 struct evdev_device *device =
413 container_of(listener,
414 struct evdev_device, output_destroy_listener);
415 struct weston_compositor *c = device->seat->compositor;
416 struct weston_output *output;
417
Ander Conselvan de Oliveiraa7caef92014-04-24 15:11:17 +0300418 if (!device->output_name && !wl_list_empty(&c->output_list)) {
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100419 output = container_of(c->output_list.next,
420 struct weston_output, link);
421 evdev_device_set_output(device, output);
422 } else {
423 device->output = NULL;
424 }
425}
426
Peter Hutterer3fbba492014-09-09 13:02:25 +1000427/**
428 * The WL_CALIBRATION property requires a pixel-specific matrix to be
429 * applied after scaling device coordinates to screen coordinates. libinput
430 * can't do that, so we need to convert the calibration to the normalized
431 * format libinput expects.
432 */
433static void
434evdev_device_set_calibration(struct evdev_device *device)
435{
436 struct udev *udev;
437 struct udev_device *udev_device = NULL;
438 const char *sysname = libinput_device_get_sysname(device->device);
439 const char *calibration_values;
440 uint32_t width, height;
441 float calibration[6];
442 enum libinput_config_status status;
443
444 if (!device->output)
445 return;
446
447 width = device->output->width;
448 height = device->output->height;
449 if (width == 0 || height == 0)
450 return;
451
452 /* If libinput has a pre-set calibration matrix, don't override it */
453 if (!libinput_device_config_calibration_has_matrix(device->device) ||
454 libinput_device_config_calibration_get_default_matrix(
455 device->device,
456 calibration) != 0)
457 return;
458
459 udev = udev_new();
460 if (!udev)
461 return;
462
463 udev_device = udev_device_new_from_subsystem_sysname(udev,
464 "input",
465 sysname);
466 if (!udev_device)
467 goto out;
468
469 calibration_values =
470 udev_device_get_property_value(udev_device,
471 "WL_CALIBRATION");
472
473 if (!calibration_values || sscanf(calibration_values,
474 "%f %f %f %f %f %f",
475 &calibration[0],
476 &calibration[1],
477 &calibration[2],
478 &calibration[3],
479 &calibration[4],
480 &calibration[5]) != 6)
481 goto out;
482
483 weston_log("Applying calibration: %f %f %f %f %f %f "
484 "(normalized %f %f)\n",
485 calibration[0],
486 calibration[1],
487 calibration[2],
488 calibration[3],
489 calibration[4],
490 calibration[5],
491 calibration[2] / width,
492 calibration[5] / height);
493
494 /* normalize to a format libinput can use. There is a chance of
495 this being wrong if the width/height don't match the device
496 width/height but I'm not sure how to fix that */
497 calibration[2] /= width;
498 calibration[5] /= height;
499
500 status = libinput_device_config_calibration_set_matrix(device->device,
501 calibration);
502 if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
503 weston_log("Failed to apply calibration.\n");
504
505out:
506 if (udev_device)
507 udev_device_unref(udev_device);
508 udev_unref(udev);
509}
510
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100511void
512evdev_device_set_output(struct evdev_device *device,
513 struct weston_output *output)
514{
U. Artie Eoff161c6c52014-04-17 07:53:25 -0700515 if (device->output_destroy_listener.notify) {
516 wl_list_remove(&device->output_destroy_listener.link);
517 device->output_destroy_listener.notify = NULL;
518 }
519
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100520 device->output = output;
521 device->output_destroy_listener.notify = notify_output_destroy;
522 wl_signal_add(&output->destroy_signal,
523 &device->output_destroy_listener);
Peter Hutterer3fbba492014-09-09 13:02:25 +1000524 evdev_device_set_calibration(device);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100525}
526
Jonas Ådahl05e4a1f2014-07-22 22:49:41 +0200527static void
528configure_device(struct evdev_device *device)
529{
530 struct weston_compositor *compositor = device->seat->compositor;
531 struct weston_config_section *s;
Giulio Camuffod52f3b72016-06-02 21:48:11 +0300532 struct weston_config *config = wet_get_config(compositor);
Jonas Ådahl05e4a1f2014-07-22 22:49:41 +0200533 int enable_tap;
534 int enable_tap_default;
535
Giulio Camuffod52f3b72016-06-02 21:48:11 +0300536 s = weston_config_get_section(config,
Jonas Ådahl05e4a1f2014-07-22 22:49:41 +0200537 "libinput", NULL, NULL);
538
539 if (libinput_device_config_tap_get_finger_count(device->device) > 0) {
540 enable_tap_default =
541 libinput_device_config_tap_get_default_enabled(
542 device->device);
543 weston_config_section_get_bool(s, "enable_tap",
544 &enable_tap,
545 enable_tap_default);
546 libinput_device_config_tap_set_enabled(device->device,
547 enable_tap);
548 }
Peter Hutterer3fbba492014-09-09 13:02:25 +1000549
550 evdev_device_set_calibration(device);
Jonas Ådahl05e4a1f2014-07-22 22:49:41 +0200551}
552
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100553struct evdev_device *
554evdev_device_create(struct libinput_device *libinput_device,
555 struct weston_seat *seat)
556{
557 struct evdev_device *device;
558
559 device = zalloc(sizeof *device);
560 if (device == NULL)
561 return NULL;
562
563 device->seat = seat;
564 wl_list_init(&device->link);
565 device->device = libinput_device;
566
567 if (libinput_device_has_capability(libinput_device,
568 LIBINPUT_DEVICE_CAP_KEYBOARD)) {
569 weston_seat_init_keyboard(seat, NULL);
570 device->seat_caps |= EVDEV_SEAT_KEYBOARD;
571 }
572 if (libinput_device_has_capability(libinput_device,
573 LIBINPUT_DEVICE_CAP_POINTER)) {
574 weston_seat_init_pointer(seat);
575 device->seat_caps |= EVDEV_SEAT_POINTER;
576 }
577 if (libinput_device_has_capability(libinput_device,
578 LIBINPUT_DEVICE_CAP_TOUCH)) {
579 weston_seat_init_touch(seat);
580 device->seat_caps |= EVDEV_SEAT_TOUCH;
581 }
582
583 libinput_device_set_user_data(libinput_device, device);
584 libinput_device_ref(libinput_device);
585
Jonas Ådahl05e4a1f2014-07-22 22:49:41 +0200586 configure_device(device);
587
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100588 return device;
589}
590
591void
592evdev_device_destroy(struct evdev_device *device)
593{
594 if (device->seat_caps & EVDEV_SEAT_POINTER)
595 weston_seat_release_pointer(device->seat);
596 if (device->seat_caps & EVDEV_SEAT_KEYBOARD)
597 weston_seat_release_keyboard(device->seat);
598 if (device->seat_caps & EVDEV_SEAT_TOUCH)
599 weston_seat_release_touch(device->seat);
600
601 if (device->output)
602 wl_list_remove(&device->output_destroy_listener.link);
603 wl_list_remove(&device->link);
604 libinput_device_unref(device->device);
605 free(device->devnode);
606 free(device->output_name);
607 free(device);
608}
609
610void
611evdev_notify_keyboard_focus(struct weston_seat *seat,
612 struct wl_list *evdev_devices)
613{
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100614 struct wl_array keys;
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100615
Derek Foremand621df22014-11-19 11:04:12 -0600616 if (seat->keyboard_device_count == 0)
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100617 return;
618
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100619 wl_array_init(&keys);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100620 notify_keyboard_focus_in(seat, &keys, STATE_UPDATE_AUTOMATIC);
Jonas Ådahle0de3c22014-03-12 22:08:42 +0100621 wl_array_release(&keys);
622}