e1738613da17b0f88324c7363f4d44d3204c7dbe
[platform/upstream/weston.git] / libweston / libinput-device.c
1 /*
2  * Copyright © 2010 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 <errno.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <linux/input.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <assert.h>
37 #include <libinput.h>
38
39 #include "compositor.h"
40 #include "libinput-device.h"
41 #include "shared/helpers.h"
42 #include "shared/timespec-util.h"
43
44 void
45 evdev_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
59 static void
60 handle_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);
65         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         struct timespec time;
70
71         /* Ignore key events that are not seat wide state changes. */
72         if ((key_state == LIBINPUT_KEY_STATE_PRESSED &&
73              seat_key_count != 1) ||
74             (key_state == LIBINPUT_KEY_STATE_RELEASED &&
75              seat_key_count != 0))
76                 return;
77
78         timespec_from_usec(&time,
79                            libinput_event_keyboard_get_time_usec(keyboard_event));
80
81         notify_key(device->seat, &time,
82                    libinput_event_keyboard_get_key(keyboard_event),
83                    key_state, STATE_UPDATE_AUTOMATIC);
84 }
85
86 static bool
87 handle_pointer_motion(struct libinput_device *libinput_device,
88                       struct libinput_event_pointer *pointer_event)
89 {
90         struct evdev_device *device =
91                 libinput_device_get_user_data(libinput_device);
92         struct weston_pointer_motion_event event = { 0 };
93         struct timespec time;
94         double dx_unaccel, dy_unaccel;
95
96         timespec_from_usec(&time,
97                            libinput_event_pointer_get_time_usec(pointer_event));
98         dx_unaccel = libinput_event_pointer_get_dx_unaccelerated(pointer_event);
99         dy_unaccel = libinput_event_pointer_get_dy_unaccelerated(pointer_event);
100
101         event = (struct weston_pointer_motion_event) {
102                 .mask = WESTON_POINTER_MOTION_REL |
103                         WESTON_POINTER_MOTION_REL_UNACCEL,
104                 .time = time,
105                 .dx = libinput_event_pointer_get_dx(pointer_event),
106                 .dy = libinput_event_pointer_get_dy(pointer_event),
107                 .dx_unaccel = dx_unaccel,
108                 .dy_unaccel = dy_unaccel,
109         };
110
111         notify_motion(device->seat, &time, &event);
112
113         return true;
114 }
115
116 static bool
117 handle_pointer_motion_absolute(
118         struct libinput_device *libinput_device,
119         struct libinput_event_pointer *pointer_event)
120 {
121         struct evdev_device *device =
122                 libinput_device_get_user_data(libinput_device);
123         struct weston_output *output = device->output;
124         struct timespec time;
125         double x, y;
126         uint32_t width, height;
127
128         if (!output)
129                 return false;
130
131         timespec_from_usec(&time,
132                            libinput_event_pointer_get_time_usec(pointer_event));
133         width = device->output->current_mode->width;
134         height = device->output->current_mode->height;
135
136         x = libinput_event_pointer_get_absolute_x_transformed(pointer_event,
137                                                               width);
138         y = libinput_event_pointer_get_absolute_y_transformed(pointer_event,
139                                                               height);
140
141         weston_output_transform_coordinate(device->output, x, y, &x, &y);
142         notify_motion_absolute(device->seat, &time, x, y);
143
144         return true;
145 }
146
147 static bool
148 handle_pointer_button(struct libinput_device *libinput_device,
149                       struct libinput_event_pointer *pointer_event)
150 {
151         struct evdev_device *device =
152                 libinput_device_get_user_data(libinput_device);
153         int button_state =
154                 libinput_event_pointer_get_button_state(pointer_event);
155         int seat_button_count =
156                 libinput_event_pointer_get_seat_button_count(pointer_event);
157         struct timespec time;
158
159         /* Ignore button events that are not seat wide state changes. */
160         if ((button_state == LIBINPUT_BUTTON_STATE_PRESSED &&
161              seat_button_count != 1) ||
162             (button_state == LIBINPUT_BUTTON_STATE_RELEASED &&
163              seat_button_count != 0))
164                 return false;
165
166         timespec_from_usec(&time,
167                            libinput_event_pointer_get_time_usec(pointer_event));
168
169         notify_button(device->seat, &time,
170                       libinput_event_pointer_get_button(pointer_event),
171                       button_state);
172
173         return true;
174 }
175
176 static double
177 normalize_scroll(struct libinput_event_pointer *pointer_event,
178                  enum libinput_pointer_axis axis)
179 {
180         enum libinput_pointer_axis_source source;
181         double value = 0.0;
182
183         source = libinput_event_pointer_get_axis_source(pointer_event);
184         /* libinput < 0.8 sent wheel click events with value 10. Since 0.8
185            the value is the angle of the click in degrees. To keep
186            backwards-compat with existing clients, we just send multiples of
187            the click count.
188          */
189         switch (source) {
190         case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
191                 value = 10 * libinput_event_pointer_get_axis_value_discrete(
192                                                                    pointer_event,
193                                                                    axis);
194                 break;
195         case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
196         case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
197                 value = libinput_event_pointer_get_axis_value(pointer_event,
198                                                               axis);
199                 break;
200         default:
201                 assert(!"unhandled event source in normalize_scroll");
202         }
203
204         return value;
205 }
206
207 static int32_t
208 get_axis_discrete(struct libinput_event_pointer *pointer_event,
209                   enum libinput_pointer_axis axis)
210 {
211         enum libinput_pointer_axis_source source;
212
213         source = libinput_event_pointer_get_axis_source(pointer_event);
214
215         if (source != LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
216                 return 0;
217
218         return libinput_event_pointer_get_axis_value_discrete(pointer_event,
219                                                               axis);
220 }
221
222 static bool
223 handle_pointer_axis(struct libinput_device *libinput_device,
224                     struct libinput_event_pointer *pointer_event)
225 {
226         static int warned;
227         struct evdev_device *device =
228                 libinput_device_get_user_data(libinput_device);
229         double vert, horiz;
230         int32_t vert_discrete, horiz_discrete;
231         enum libinput_pointer_axis axis;
232         struct weston_pointer_axis_event weston_event;
233         enum libinput_pointer_axis_source source;
234         uint32_t wl_axis_source;
235         bool has_vert, has_horiz;
236         struct timespec time;
237
238         has_vert = libinput_event_pointer_has_axis(pointer_event,
239                                    LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
240         has_horiz = libinput_event_pointer_has_axis(pointer_event,
241                                    LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
242
243         if (!has_vert && !has_horiz)
244                 return false;
245
246         source = libinput_event_pointer_get_axis_source(pointer_event);
247         switch (source) {
248         case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
249                 wl_axis_source = WL_POINTER_AXIS_SOURCE_WHEEL;
250                 break;
251         case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
252                 wl_axis_source = WL_POINTER_AXIS_SOURCE_FINGER;
253                 break;
254         case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
255                 wl_axis_source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
256                 break;
257         default:
258                 if (warned < 5) {
259                         weston_log("Unknown scroll source %d.\n", source);
260                         warned++;
261                 }
262                 return false;
263         }
264
265         notify_axis_source(device->seat, wl_axis_source);
266
267         timespec_from_usec(&time,
268                            libinput_event_pointer_get_time_usec(pointer_event));
269
270         if (has_vert) {
271                 axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
272                 vert_discrete = get_axis_discrete(pointer_event, axis);
273                 vert = normalize_scroll(pointer_event, axis);
274
275                 weston_event.axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
276                 weston_event.value = vert;
277                 weston_event.discrete = vert_discrete;
278                 weston_event.has_discrete = (vert_discrete != 0);
279
280                 notify_axis(device->seat, &time, &weston_event);
281         }
282
283         if (has_horiz) {
284                 axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
285                 horiz_discrete = get_axis_discrete(pointer_event, axis);
286                 horiz = normalize_scroll(pointer_event, axis);
287
288                 weston_event.axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
289                 weston_event.value = horiz;
290                 weston_event.discrete = horiz_discrete;
291                 weston_event.has_discrete = (horiz_discrete != 0);
292
293                 notify_axis(device->seat, &time, &weston_event);
294         }
295
296         return true;
297 }
298
299 static void
300 handle_touch_with_coords(struct libinput_device *libinput_device,
301                          struct libinput_event_touch *touch_event,
302                          int touch_type)
303 {
304         struct evdev_device *device =
305                 libinput_device_get_user_data(libinput_device);
306         double x;
307         double y;
308         uint32_t width, height;
309         struct timespec time;
310         int32_t slot;
311
312         if (!device->output)
313                 return;
314
315         timespec_from_usec(&time,
316                            libinput_event_touch_get_time_usec(touch_event));
317         slot = libinput_event_touch_get_seat_slot(touch_event);
318
319         width = device->output->current_mode->width;
320         height = device->output->current_mode->height;
321         x =  libinput_event_touch_get_x_transformed(touch_event, width);
322         y =  libinput_event_touch_get_y_transformed(touch_event, height);
323
324         weston_output_transform_coordinate(device->output,
325                                            x, y, &x, &y);
326
327         notify_touch(device->seat, &time, slot, x, y, touch_type);
328 }
329
330 static void
331 handle_touch_down(struct libinput_device *device,
332                   struct libinput_event_touch *touch_event)
333 {
334         handle_touch_with_coords(device, touch_event, WL_TOUCH_DOWN);
335 }
336
337 static void
338 handle_touch_motion(struct libinput_device *device,
339                     struct libinput_event_touch *touch_event)
340 {
341         handle_touch_with_coords(device, touch_event, WL_TOUCH_MOTION);
342 }
343
344 static void
345 handle_touch_up(struct libinput_device *libinput_device,
346                 struct libinput_event_touch *touch_event)
347 {
348         struct evdev_device *device =
349                 libinput_device_get_user_data(libinput_device);
350         struct timespec time;
351         int32_t slot = libinput_event_touch_get_seat_slot(touch_event);
352
353         timespec_from_usec(&time,
354                            libinput_event_touch_get_time_usec(touch_event));
355
356         notify_touch(device->seat, &time, slot, 0, 0, WL_TOUCH_UP);
357 }
358
359 static void
360 handle_touch_frame(struct libinput_device *libinput_device,
361                    struct libinput_event_touch *touch_event)
362 {
363         struct evdev_device *device =
364                 libinput_device_get_user_data(libinput_device);
365         struct weston_seat *seat = device->seat;
366
367         notify_touch_frame(seat);
368 }
369
370 int
371 evdev_device_process_event(struct libinput_event *event)
372 {
373         struct libinput_device *libinput_device =
374                 libinput_event_get_device(event);
375         struct evdev_device *device =
376                 libinput_device_get_user_data(libinput_device);
377         int handled = 1;
378         bool need_frame = false;
379
380         switch (libinput_event_get_type(event)) {
381         case LIBINPUT_EVENT_KEYBOARD_KEY:
382                 handle_keyboard_key(libinput_device,
383                                     libinput_event_get_keyboard_event(event));
384                 break;
385         case LIBINPUT_EVENT_POINTER_MOTION:
386                 need_frame = handle_pointer_motion(libinput_device,
387                                       libinput_event_get_pointer_event(event));
388                 break;
389         case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
390                 need_frame = handle_pointer_motion_absolute(
391                                 libinput_device,
392                                 libinput_event_get_pointer_event(event));
393                 break;
394         case LIBINPUT_EVENT_POINTER_BUTTON:
395                 need_frame = handle_pointer_button(libinput_device,
396                                       libinput_event_get_pointer_event(event));
397                 break;
398         case LIBINPUT_EVENT_POINTER_AXIS:
399                 need_frame = handle_pointer_axis(
400                                  libinput_device,
401                                  libinput_event_get_pointer_event(event));
402                 break;
403         case LIBINPUT_EVENT_TOUCH_DOWN:
404                 handle_touch_down(libinput_device,
405                                   libinput_event_get_touch_event(event));
406                 break;
407         case LIBINPUT_EVENT_TOUCH_MOTION:
408                 handle_touch_motion(libinput_device,
409                                     libinput_event_get_touch_event(event));
410                 break;
411         case LIBINPUT_EVENT_TOUCH_UP:
412                 handle_touch_up(libinput_device,
413                                 libinput_event_get_touch_event(event));
414                 break;
415         case LIBINPUT_EVENT_TOUCH_FRAME:
416                 handle_touch_frame(libinput_device,
417                                    libinput_event_get_touch_event(event));
418                 break;
419         default:
420                 handled = 0;
421                 weston_log("unknown libinput event %d\n",
422                            libinput_event_get_type(event));
423         }
424
425         if (need_frame)
426                 notify_pointer_frame(device->seat);
427
428         return handled;
429 }
430
431 static void
432 notify_output_destroy(struct wl_listener *listener, void *data)
433 {
434         struct evdev_device *device =
435                 container_of(listener,
436                              struct evdev_device, output_destroy_listener);
437
438         evdev_device_set_output(device, NULL);
439 }
440
441 /**
442  * The WL_CALIBRATION property requires a pixel-specific matrix to be
443  * applied after scaling device coordinates to screen coordinates. libinput
444  * can't do that, so we need to convert the calibration to the normalized
445  * format libinput expects.
446  */
447 void
448 evdev_device_set_calibration(struct evdev_device *device)
449 {
450         struct udev *udev;
451         struct udev_device *udev_device = NULL;
452         const char *sysname = libinput_device_get_sysname(device->device);
453         const char *calibration_values;
454         uint32_t width, height;
455         float calibration[6];
456         enum libinput_config_status status;
457
458         if (!libinput_device_config_calibration_has_matrix(device->device))
459                 return;
460
461         /* If LIBINPUT_CALIBRATION_MATRIX was set to non-identity, we will not
462          * override it with WL_CALIBRATION. It also means we don't need an
463          * output to load a calibration. */
464         if (libinput_device_config_calibration_get_default_matrix(
465                                                           device->device,
466                                                           calibration) != 0)
467                 return;
468
469         if (!device->output) {
470                 weston_log("input device %s has no enabled output associated "
471                            "(%s named), skipping calibration for now.\n",
472                            sysname, device->output_name ?: "none");
473                 return;
474         }
475
476         width = device->output->width;
477         height = device->output->height;
478         if (width == 0 || height == 0)
479                 return;
480
481         udev = udev_new();
482         if (!udev)
483                 return;
484
485         udev_device = udev_device_new_from_subsystem_sysname(udev,
486                                                              "input",
487                                                              sysname);
488         if (!udev_device)
489                 goto out;
490
491         calibration_values =
492                 udev_device_get_property_value(udev_device,
493                                                "WL_CALIBRATION");
494
495         if (calibration_values) {
496                 weston_log("Warning: input device %s has WL_CALIBRATION property set. "
497                            "Support for it will be removed in the future. "
498                            "Please use LIBINPUT_CALIBRATION_MATRIX instead.\n",
499                            sysname);
500         }
501
502         if (!calibration_values || sscanf(calibration_values,
503                                           "%f %f %f %f %f %f",
504                                           &calibration[0],
505                                           &calibration[1],
506                                           &calibration[2],
507                                           &calibration[3],
508                                           &calibration[4],
509                                           &calibration[5]) != 6)
510                 goto out;
511
512         weston_log("Applying calibration: %f %f %f %f %f %f "
513                    "(normalized %f %f)\n",
514                     calibration[0],
515                     calibration[1],
516                     calibration[2],
517                     calibration[3],
518                     calibration[4],
519                     calibration[5],
520                     calibration[2] / width,
521                     calibration[5] / height);
522
523         /* normalize to a format libinput can use. There is a chance of
524            this being wrong if the width/height don't match the device
525            width/height but I'm not sure how to fix that */
526         calibration[2] /= width;
527         calibration[5] /= height;
528
529         status = libinput_device_config_calibration_set_matrix(device->device,
530                                                                calibration);
531         if (status != LIBINPUT_CONFIG_STATUS_SUCCESS)
532                 weston_log("Failed to apply calibration.\n");
533
534 out:
535         if (udev_device)
536                 udev_device_unref(udev_device);
537         udev_unref(udev);
538 }
539
540 void
541 evdev_device_set_output(struct evdev_device *device,
542                         struct weston_output *output)
543 {
544         if (device->output == output)
545                 return;
546
547         if (device->output_destroy_listener.notify) {
548                 wl_list_remove(&device->output_destroy_listener.link);
549                 device->output_destroy_listener.notify = NULL;
550         }
551
552         if (!output) {
553                 weston_log("output for input device %s removed\n",
554                            libinput_device_get_sysname(device->device));
555
556                 device->output = NULL;
557                 return;
558         }
559
560         weston_log("associating input device %s with output %s "
561                    "(%s by udev)\n",
562                    libinput_device_get_sysname(device->device),
563                    output->name,
564                    device->output_name ?: "none");
565
566         device->output = output;
567         device->output_destroy_listener.notify = notify_output_destroy;
568         wl_signal_add(&output->destroy_signal,
569                       &device->output_destroy_listener);
570         evdev_device_set_calibration(device);
571 }
572
573 struct evdev_device *
574 evdev_device_create(struct libinput_device *libinput_device,
575                     struct weston_seat *seat)
576 {
577         struct evdev_device *device;
578
579         device = zalloc(sizeof *device);
580         if (device == NULL)
581                 return NULL;
582
583         device->seat = seat;
584         wl_list_init(&device->link);
585         device->device = libinput_device;
586
587         if (libinput_device_has_capability(libinput_device,
588                                            LIBINPUT_DEVICE_CAP_KEYBOARD)) {
589                 weston_seat_init_keyboard(seat, NULL);
590                 device->seat_caps |= EVDEV_SEAT_KEYBOARD;
591         }
592         if (libinput_device_has_capability(libinput_device,
593                                            LIBINPUT_DEVICE_CAP_POINTER)) {
594                 weston_seat_init_pointer(seat);
595                 device->seat_caps |= EVDEV_SEAT_POINTER;
596         }
597         if (libinput_device_has_capability(libinput_device,
598                                            LIBINPUT_DEVICE_CAP_TOUCH)) {
599                 weston_seat_init_touch(seat);
600                 device->seat_caps |= EVDEV_SEAT_TOUCH;
601         }
602
603         libinput_device_set_user_data(libinput_device, device);
604         libinput_device_ref(libinput_device);
605
606         return device;
607 }
608
609 void
610 evdev_device_destroy(struct evdev_device *device)
611 {
612         if (device->seat_caps & EVDEV_SEAT_POINTER)
613                 weston_seat_release_pointer(device->seat);
614         if (device->seat_caps & EVDEV_SEAT_KEYBOARD)
615                 weston_seat_release_keyboard(device->seat);
616         if (device->seat_caps & EVDEV_SEAT_TOUCH)
617                 weston_seat_release_touch(device->seat);
618
619         if (device->output)
620                 wl_list_remove(&device->output_destroy_listener.link);
621         wl_list_remove(&device->link);
622         libinput_device_unref(device->device);
623         free(device->output_name);
624         free(device);
625 }
626
627 void
628 evdev_notify_keyboard_focus(struct weston_seat *seat,
629                             struct wl_list *evdev_devices)
630 {
631         struct wl_array keys;
632
633         if (seat->keyboard_device_count == 0)
634                 return;
635
636         wl_array_init(&keys);
637         notify_keyboard_focus_in(seat, &keys, STATE_UPDATE_AUTOMATIC);
638         wl_array_release(&keys);
639 }