1 /*
2 * Copyright © 2013 Jonas Ådahl
3 * Copyright © 2013-2015 Red Hat, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef LIBINPUT_PRIVATE_H
26 #define LIBINPUT_PRIVATE_H
27
28 #include "config.h"
29
30 #include <errno.h>
31 #include <math.h>
32 #include <stdarg.h>
33
34 #include "linux/input.h"
35
36 #include "libinput.h"
37 #include "libinput-util.h"
38 #include "libinput-version.h"
39
40 #if LIBINPUT_VERSION_MICRO >= 90
41 #define HTTP_DOC_LINK "https://wayland.freedesktop.org/libinput/doc/latest/"
42 #else
43 #define HTTP_DOC_LINK "https://wayland.freedesktop.org/libinput/doc/" LIBINPUT_VERSION "/"
44 #endif
45
46 struct libinput_source;
47
48 /* A coordinate pair in device coordinates */
49 struct device_coords {
50 int x, y;
51 };
52
53 /*
54 * A coordinate pair in device coordinates, capable of holding non discrete
55 * values, this is necessary e.g. when device coordinates get averaged.
56 */
57 struct device_float_coords {
58 double x, y;
59 };
60
61 /* A dpi-normalized coordinate pair */
62 struct normalized_coords {
63 double x, y;
64 };
65
66 /* A discrete step pair (mouse wheels) */
67 struct discrete_coords {
68 int x, y;
69 };
70
71 /* A pair of coordinates normalized to a [0,1] or [-1, 1] range */
72 struct normalized_range_coords {
73 double x, y;
74 };
75
76 /* A pair of angles in degrees */
77 struct wheel_angle {
78 double x, y;
79 };
80
81 /* A pair of angles in degrees */
82 struct tilt_degrees {
83 double x, y;
84 };
85
86 /* A threshold with an upper and lower limit */
87 struct threshold {
88 int upper;
89 int lower;
90 };
91
92 /* A pair of coordinates in mm */
93 struct phys_coords {
94 double x;
95 double y;
96 };
97
98 /* A pair of tilt flags */
99 struct wheel_tilt_flags {
100 bool vertical, horizontal;
101 };
102
103 struct libinput_interface_backend {
104 int (*resume)(struct libinput *libinput);
105 void (*suspend)(struct libinput *libinput);
106 void (*destroy)(struct libinput *libinput);
107 int (*device_change_seat)(struct libinput_device *device,
108 const char *seat_name);
109 };
110
111 struct libinput {
112 int epoll_fd;
113 struct list source_destroy_list;
114
115 struct list seat_list;
116
117 struct {
118 struct list list;
119 struct libinput_source *source;
120 int fd;
121 uint64_t next_expiry;
122 } timer;
123
124 struct libinput_event **events;
125 size_t events_count;
126 size_t events_len;
127 size_t events_in;
128 size_t events_out;
129
130 struct list tool_list;
131
132 const struct libinput_interface *interface;
133 const struct libinput_interface_backend *interface_backend;
134
135 libinput_log_handler log_handler;
136 enum libinput_log_priority log_priority;
137 void *user_data;
138 int refcount;
139
140 struct list device_group_list;
141
142 uint64_t last_event_time;
143
144 bool quirks_initialized;
145 struct quirks_context *quirks;
146 };
147
148 typedef void (*libinput_seat_destroy_func) (struct libinput_seat *seat);
149
150 struct libinput_seat {
151 struct libinput *libinput;
152 struct list link;
153 struct list devices_list;
154 void *user_data;
155 int refcount;
156 libinput_seat_destroy_func destroy;
157
158 char *physical_name;
159 char *logical_name;
160
161 uint32_t slot_map;
162
163 uint32_t button_count[KEY_CNT];
164 };
165
166 struct libinput_device_config_tap {
167 int (*count)(struct libinput_device *device);
168 enum libinput_config_status (*set_enabled)(struct libinput_device *device,
169 enum libinput_config_tap_state enable);
170 enum libinput_config_tap_state (*get_enabled)(struct libinput_device *device);
171 enum libinput_config_tap_state (*get_default)(struct libinput_device *device);
172
173 enum libinput_config_status (*set_map)(struct libinput_device *device,
174 enum libinput_config_tap_button_map map);
175 enum libinput_config_tap_button_map (*get_map)(struct libinput_device *device);
176 enum libinput_config_tap_button_map (*get_default_map)(struct libinput_device *device);
177
178 enum libinput_config_status (*set_drag_enabled)(struct libinput_device *device,
179 enum libinput_config_drag_state);
180 enum libinput_config_drag_state (*get_drag_enabled)(struct libinput_device *device);
181 enum libinput_config_drag_state (*get_default_drag_enabled)(struct libinput_device *device);
182
183 enum libinput_config_status (*set_draglock_enabled)(struct libinput_device *device,
184 enum libinput_config_drag_lock_state);
185 enum libinput_config_drag_lock_state (*get_draglock_enabled)(struct libinput_device *device);
186 enum libinput_config_drag_lock_state (*get_default_draglock_enabled)(struct libinput_device *device);
187 };
188
189 struct libinput_device_config_calibration {
190 int (*has_matrix)(struct libinput_device *device);
191 enum libinput_config_status (*set_matrix)(struct libinput_device *device,
192 const float matrix[6]);
193 int (*get_matrix)(struct libinput_device *device,
194 float matrix[6]);
195 int (*get_default_matrix)(struct libinput_device *device,
196 float matrix[6]);
197 };
198
199 struct libinput_device_config_send_events {
200 uint32_t (*get_modes)(struct libinput_device *device);
201 enum libinput_config_status (*set_mode)(struct libinput_device *device,
202 enum libinput_config_send_events_mode mode);
203 enum libinput_config_send_events_mode (*get_mode)(struct libinput_device *device);
204 enum libinput_config_send_events_mode (*get_default_mode)(struct libinput_device *device);
205 };
206
207 struct libinput_device_config_accel {
208 int (*available)(struct libinput_device *device);
209 enum libinput_config_status (*set_speed)(struct libinput_device *device,
210 double speed);
211 double (*get_speed)(struct libinput_device *device);
212 double (*get_default_speed)(struct libinput_device *device);
213
214 uint32_t (*get_profiles)(struct libinput_device *device);
215 enum libinput_config_status (*set_profile)(struct libinput_device *device,
216 enum libinput_config_accel_profile);
217 enum libinput_config_accel_profile (*get_profile)(struct libinput_device *device);
218 enum libinput_config_accel_profile (*get_default_profile)(struct libinput_device *device);
219 };
220
221 struct libinput_device_config_natural_scroll {
222 int (*has)(struct libinput_device *device);
223 enum libinput_config_status (*set_enabled)(struct libinput_device *device,
224 int enabled);
225 int (*get_enabled)(struct libinput_device *device);
226 int (*get_default_enabled)(struct libinput_device *device);
227 };
228
229 struct libinput_device_config_left_handed {
230 int (*has)(struct libinput_device *device);
231 enum libinput_config_status (*set)(struct libinput_device *device, int left_handed);
232 int (*get)(struct libinput_device *device);
233 int (*get_default)(struct libinput_device *device);
234 };
235
236 struct libinput_device_config_scroll_method {
237 uint32_t (*get_methods)(struct libinput_device *device);
238 enum libinput_config_status (*set_method)(struct libinput_device *device,
239 enum libinput_config_scroll_method method);
240 enum libinput_config_scroll_method (*get_method)(struct libinput_device *device);
241 enum libinput_config_scroll_method (*get_default_method)(struct libinput_device *device);
242 enum libinput_config_status (*set_button)(struct libinput_device *device,
243 uint32_t button);
244 uint32_t (*get_button)(struct libinput_device *device);
245 uint32_t (*get_default_button)(struct libinput_device *device);
246 };
247
248 struct libinput_device_config_click_method {
249 uint32_t (*get_methods)(struct libinput_device *device);
250 enum libinput_config_status (*set_method)(struct libinput_device *device,
251 enum libinput_config_click_method method);
252 enum libinput_config_click_method (*get_method)(struct libinput_device *device);
253 enum libinput_config_click_method (*get_default_method)(struct libinput_device *device);
254 };
255
256 struct libinput_device_config_middle_emulation {
257 int (*available)(struct libinput_device *device);
258 enum libinput_config_status (*set)(
259 struct libinput_device *device,
260 enum libinput_config_middle_emulation_state);
261 enum libinput_config_middle_emulation_state (*get)(
262 struct libinput_device *device);
263 enum libinput_config_middle_emulation_state (*get_default)(
264 struct libinput_device *device);
265 };
266
267 struct libinput_device_config_dwt {
268 int (*is_available)(struct libinput_device *device);
269 enum libinput_config_status (*set_enabled)(
270 struct libinput_device *device,
271 enum libinput_config_dwt_state enable);
272 enum libinput_config_dwt_state (*get_enabled)(
273 struct libinput_device *device);
274 enum libinput_config_dwt_state (*get_default_enabled)(
275 struct libinput_device *device);
276 };
277
278 struct libinput_device_config_rotation {
279 int (*is_available)(struct libinput_device *device);
280 enum libinput_config_status (*set_angle)(
281 struct libinput_device *device,
282 unsigned int degrees_cw);
283 unsigned int (*get_angle)(struct libinput_device *device);
284 unsigned int (*get_default_angle)(struct libinput_device *device);
285 };
286
287 struct libinput_device_config {
288 struct libinput_device_config_tap *tap;
289 struct libinput_device_config_calibration *calibration;
290 struct libinput_device_config_send_events *sendevents;
291 struct libinput_device_config_accel *accel;
292 struct libinput_device_config_natural_scroll *natural_scroll;
293 struct libinput_device_config_left_handed *left_handed;
294 struct libinput_device_config_scroll_method *scroll_method;
295 struct libinput_device_config_click_method *click_method;
296 struct libinput_device_config_middle_emulation *middle_emulation;
297 struct libinput_device_config_dwt *dwt;
298 struct libinput_device_config_rotation *rotation;
299 };
300
301 struct libinput_device_group {
302 int refcount;
303 void *user_data;
304 char *identifier; /* unique identifier or NULL for singletons */
305
306 struct list link;
307 };
308
309 struct libinput_device {
310 struct libinput_seat *seat;
311 struct libinput_device_group *group;
312 struct list link;
313 struct list event_listeners;
314 void *user_data;
315 int refcount;
316 struct libinput_device_config config;
317 };
318
319 enum libinput_tablet_tool_axis {
320 LIBINPUT_TABLET_TOOL_AXIS_X = 1,
321 LIBINPUT_TABLET_TOOL_AXIS_Y = 2,
322 LIBINPUT_TABLET_TOOL_AXIS_DISTANCE = 3,
323 LIBINPUT_TABLET_TOOL_AXIS_PRESSURE = 4,
324 LIBINPUT_TABLET_TOOL_AXIS_TILT_X = 5,
325 LIBINPUT_TABLET_TOOL_AXIS_TILT_Y = 6,
326 LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z = 7,
327 LIBINPUT_TABLET_TOOL_AXIS_SLIDER = 8,
328 LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL = 9,
329 };
330
331 #define LIBINPUT_TABLET_TOOL_AXIS_MAX LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL
332
333 struct tablet_axes {
334 struct device_coords point;
335 struct normalized_coords delta;
336 double distance;
337 double pressure;
338 struct tilt_degrees tilt;
339 double rotation;
340 double slider;
341 double wheel;
342 int wheel_discrete;
343 };
344
345 struct libinput_tablet_tool {
346 struct list link;
347 uint32_t serial;
348 uint32_t tool_id;
349 enum libinput_tablet_tool_type type;
350 unsigned char axis_caps[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)];
351 unsigned char buttons[NCHARS(KEY_MAX) + 1];
352 int refcount;
353 void *user_data;
354
355 /* The pressure threshold assumes a pressure_offset of 0 */
356 struct threshold pressure_threshold;
357 int pressure_offset; /* in device coordinates */
358 bool has_pressure_offset;
359 };
360
361 struct libinput_tablet_pad_mode_group {
362 struct libinput_device *device;
363 struct list link;
364 int refcount;
365 void *user_data;
366
367 unsigned int index;
368 unsigned int num_modes;
369 unsigned int current_mode;
370
371 uint32_t button_mask;
372 uint32_t ring_mask;
373 uint32_t strip_mask;
374
375 uint32_t toggle_button_mask;
376
377 void (*destroy)(struct libinput_tablet_pad_mode_group *group);
378 };
379
380 struct libinput_event {
381 enum libinput_event_type type;
382 struct libinput_device *device;
383 };
384
385 struct libinput_event_listener {
386 struct list link;
387 void (*notify_func)(uint64_t time, struct libinput_event *ev, void *notify_func_data);
388 void *notify_func_data;
389 };
390
391 typedef void (*libinput_source_dispatch_t)(void *data);
392
393 #define log_debug(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__)
394 #define log_info(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__)
395 #define log_error(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__)
396 #define log_bug_kernel(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "kernel bug: " __VA_ARGS__)
397 #define log_bug_libinput(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__)
398 #define log_bug_client(li_, ...) log_msg((li_), LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__)
399
400 #define log_debug_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__)
401 #define log_info_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_INFO, __VA_ARGS__)
402 #define log_error_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_ERROR, __VA_ARGS__)
403 #define log_bug_kernel_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_ERROR, "kernel bug: " __VA_ARGS__)
404 #define log_bug_libinput_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_ERROR, "libinput bug: " __VA_ARGS__)
405 #define log_bug_client_ratelimit(li_, r_, ...) log_msg_ratelimit((li_), (r_), LIBINPUT_LOG_PRIORITY_ERROR, "client bug: " __VA_ARGS__)
406
407 void
408 log_msg_ratelimit(struct libinput *libinput,
409 struct ratelimit *ratelimit,
410 enum libinput_log_priority priority,
411 const char *format, ...)
412 LIBINPUT_ATTRIBUTE_PRINTF(4, 5);
413
414 void
415 log_msg(struct libinput *libinput,
416 enum libinput_log_priority priority,
417 const char *format, ...)
418 LIBINPUT_ATTRIBUTE_PRINTF(3, 4);
419
420 void
421 log_msg_va(struct libinput *libinput,
422 enum libinput_log_priority priority,
423 const char *format,
424 va_list args)
425 LIBINPUT_ATTRIBUTE_PRINTF(3, 0);
426
427 int
428 libinput_init(struct libinput *libinput,
429 const struct libinput_interface *interface,
430 const struct libinput_interface_backend *interface_backend,
431 void *user_data);
432
433 void
434 libinput_init_quirks(struct libinput *libinput);
435
436 struct libinput_source *
437 libinput_add_fd(struct libinput *libinput,
438 int fd,
439 libinput_source_dispatch_t dispatch,
440 void *data);
441
442 void
443 libinput_remove_source(struct libinput *libinput,
444 struct libinput_source *source);
445
446 int
447 open_restricted(struct libinput *libinput,
448 const char *path, int flags);
449
450 void
451 close_restricted(struct libinput *libinput, int fd);
452
453 bool
454 ignore_litest_test_suite_device(struct udev_device *device);
455
456 void
457 libinput_seat_init(struct libinput_seat *seat,
458 struct libinput *libinput,
459 const char *physical_name,
460 const char *logical_name,
461 libinput_seat_destroy_func destroy);
462
463 void
464 libinput_device_init(struct libinput_device *device,
465 struct libinput_seat *seat);
466
467 struct libinput_device_group *
468 libinput_device_group_create(struct libinput *libinput,
469 const char *identifier);
470
471 struct libinput_device_group *
472 libinput_device_group_find_group(struct libinput *libinput,
473 const char *identifier);
474
475 void
476 libinput_device_set_device_group(struct libinput_device *device,
477 struct libinput_device_group *group);
478
479 void
480 libinput_device_init_event_listener(struct libinput_event_listener *listener);
481
482 void
483 libinput_device_add_event_listener(struct libinput_device *device,
484 struct libinput_event_listener *listener,
485 void (*notify_func)(
486 uint64_t time,
487 struct libinput_event *event,
488 void *notify_func_data),
489 void *notify_func_data);
490
491 void
492 libinput_device_remove_event_listener(struct libinput_event_listener *listener);
493
494 void
495 notify_added_device(struct libinput_device *device);
496
497 void
498 notify_removed_device(struct libinput_device *device);
499
500 void
501 keyboard_notify_key(struct libinput_device *device,
502 uint64_t time,
503 uint32_t key,
504 enum libinput_key_state state);
505
506 void
507 pointer_notify_motion(struct libinput_device *device,
508 uint64_t time,
509 const struct normalized_coords *delta,
510 const struct device_float_coords *raw);
511
512 void
513 pointer_notify_motion_absolute(struct libinput_device *device,
514 uint64_t time,
515 const struct device_coords *point);
516
517 void
518 pointer_notify_button(struct libinput_device *device,
519 uint64_t time,
520 int32_t button,
521 enum libinput_button_state state);
522
523 void
524 pointer_notify_axis(struct libinput_device *device,
525 uint64_t time,
526 uint32_t axes,
527 enum libinput_pointer_axis_source source,
528 const struct normalized_coords *delta,
529 const struct discrete_coords *discrete);
530
531 void
532 touch_notify_touch_down(struct libinput_device *device,
533 uint64_t time,
534 int32_t slot,
535 int32_t seat_slot,
536 const struct device_coords *point);
537
538 void
539 touch_notify_touch_motion(struct libinput_device *device,
540 uint64_t time,
541 int32_t slot,
542 int32_t seat_slot,
543 const struct device_coords *point);
544
545 void
546 touch_notify_touch_up(struct libinput_device *device,
547 uint64_t time,
548 int32_t slot,
549 int32_t seat_slot);
550
551 void
552 touch_notify_touch_cancel(struct libinput_device *device,
553 uint64_t time,
554 int32_t slot,
555 int32_t seat_slot);
556
557 void
558 touch_notify_frame(struct libinput_device *device,
559 uint64_t time);
560
561 void
562 gesture_notify_swipe(struct libinput_device *device,
563 uint64_t time,
564 enum libinput_event_type type,
565 int finger_count,
566 const struct normalized_coords *delta,
567 const struct normalized_coords *unaccel);
568
569 void
570 gesture_notify_swipe_end(struct libinput_device *device,
571 uint64_t time,
572 int finger_count,
573 int cancelled);
574
575 void
576 gesture_notify_pinch(struct libinput_device *device,
577 uint64_t time,
578 enum libinput_event_type type,
579 int finger_count,
580 const struct normalized_coords *delta,
581 const struct normalized_coords *unaccel,
582 double scale,
583 double angle);
584
585 void
586 gesture_notify_pinch_end(struct libinput_device *device,
587 uint64_t time,
588 int finger_count,
589 double scale,
590 int cancelled);
591
592 void
593 tablet_notify_axis(struct libinput_device *device,
594 uint64_t time,
595 struct libinput_tablet_tool *tool,
596 enum libinput_tablet_tool_tip_state tip_state,
597 unsigned char *changed_axes,
598 const struct tablet_axes *axes);
599
600 void
601 tablet_notify_proximity(struct libinput_device *device,
602 uint64_t time,
603 struct libinput_tablet_tool *tool,
604 enum libinput_tablet_tool_proximity_state state,
605 unsigned char *changed_axes,
606 const struct tablet_axes *axes);
607
608 void
609 tablet_notify_tip(struct libinput_device *device,
610 uint64_t time,
611 struct libinput_tablet_tool *tool,
612 enum libinput_tablet_tool_tip_state tip_state,
613 unsigned char *changed_axes,
614 const struct tablet_axes *axes);
615
616 void
617 tablet_notify_button(struct libinput_device *device,
618 uint64_t time,
619 struct libinput_tablet_tool *tool,
620 enum libinput_tablet_tool_tip_state tip_state,
621 const struct tablet_axes *axes,
622 int32_t button,
623 enum libinput_button_state state);
624
625 void
626 tablet_pad_notify_button(struct libinput_device *device,
627 uint64_t time,
628 int32_t button,
629 enum libinput_button_state state,
630 struct libinput_tablet_pad_mode_group *group);
631 void
632 tablet_pad_notify_ring(struct libinput_device *device,
633 uint64_t time,
634 unsigned int number,
635 double value,
636 enum libinput_tablet_pad_ring_axis_source source,
637 struct libinput_tablet_pad_mode_group *group);
638 void
639 tablet_pad_notify_strip(struct libinput_device *device,
640 uint64_t time,
641 unsigned int number,
642 double value,
643 enum libinput_tablet_pad_strip_axis_source source,
644 struct libinput_tablet_pad_mode_group *group);
645 void
646 switch_notify_toggle(struct libinput_device *device,
647 uint64_t time,
648 enum libinput_switch sw,
649 enum libinput_switch_state state);
650
651 static inline uint64_t
libinput_now(struct libinput * libinput)652 libinput_now(struct libinput *libinput)
653 {
654 struct timespec ts = { 0, 0 };
655
656 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
657 log_error(libinput, "clock_gettime failed: %s\n", strerror(errno));
658 return 0;
659 }
660
661 return s2us(ts.tv_sec) + ns2us(ts.tv_nsec);
662 }
663
664 static inline struct device_float_coords
device_delta(const struct device_coords a,const struct device_coords b)665 device_delta(const struct device_coords a, const struct device_coords b)
666 {
667 struct device_float_coords delta;
668
669 delta.x = a.x - b.x;
670 delta.y = a.y - b.y;
671
672 return delta;
673 }
674
675 static inline struct device_float_coords
device_average(const struct device_coords a,const struct device_coords b)676 device_average(const struct device_coords a, const struct device_coords b)
677 {
678 struct device_float_coords average;
679
680 average.x = (a.x + b.x) / 2.0;
681 average.y = (a.y + b.y) / 2.0;
682
683 return average;
684 }
685
686 static inline struct device_float_coords
device_float_delta(const struct device_float_coords a,const struct device_float_coords b)687 device_float_delta(const struct device_float_coords a, const struct device_float_coords b)
688 {
689 struct device_float_coords delta;
690
691 delta.x = a.x - b.x;
692 delta.y = a.y - b.y;
693
694 return delta;
695 }
696
697 static inline struct device_float_coords
device_float_average(const struct device_float_coords a,const struct device_float_coords b)698 device_float_average(const struct device_float_coords a, const struct device_float_coords b)
699 {
700 struct device_float_coords average;
701
702 average.x = (a.x + b.x) / 2.0;
703 average.y = (a.y + b.y) / 2.0;
704
705 return average;
706 }
707
708 static inline bool
device_float_is_zero(const struct device_float_coords coords)709 device_float_is_zero(const struct device_float_coords coords)
710 {
711 return coords.x == 0.0 && coords.y == 0.0;
712 }
713
714 static inline double
normalized_length(const struct normalized_coords norm)715 normalized_length(const struct normalized_coords norm)
716 {
717 return hypot(norm.x, norm.y);
718 }
719
720 static inline bool
normalized_is_zero(const struct normalized_coords norm)721 normalized_is_zero(const struct normalized_coords norm)
722 {
723 return norm.x == 0.0 && norm.y == 0.0;
724 }
725
726 static inline double
length_in_mm(const struct phys_coords mm)727 length_in_mm(const struct phys_coords mm)
728 {
729 return hypot(mm.x, mm.y);
730 }
731
732 enum directions {
733 N = 1 << 0,
734 NE = 1 << 1,
735 E = 1 << 2,
736 SE = 1 << 3,
737 S = 1 << 4,
738 SW = 1 << 5,
739 W = 1 << 6,
740 NW = 1 << 7,
741 UNDEFINED_DIRECTION = 0xff
742 };
743
744 static inline uint32_t
xy_get_direction(double x,double y)745 xy_get_direction(double x, double y)
746 {
747 uint32_t dir = UNDEFINED_DIRECTION;
748 int d1, d2;
749 double r;
750
751 if (fabs(x) < 2.0 && fabs(y) < 2.0) {
752 if (x > 0.0 && y > 0.0)
753 dir = S | SE | E;
754 else if (x > 0.0 && y < 0.0)
755 dir = N | NE | E;
756 else if (x < 0.0 && y > 0.0)
757 dir = S | SW | W;
758 else if (x < 0.0 && y < 0.0)
759 dir = N | NW | W;
760 else if (x > 0.0)
761 dir = NE | E | SE;
762 else if (x < 0.0)
763 dir = NW | W | SW;
764 else if (y > 0.0)
765 dir = SE | S | SW;
766 else if (y < 0.0)
767 dir = NE | N | NW;
768 } else {
769 /* Calculate r within the interval [0 to 8)
770 *
771 * r = [0 .. 2π] where 0 is North
772 * d_f = r / 2π ([0 .. 1))
773 * d_8 = 8 * d_f
774 */
775 r = atan2(y, x);
776 r = fmod(r + 2.5*M_PI, 2*M_PI);
777 r *= 4*M_1_PI;
778
779 /* Mark one or two close enough octants */
780 d1 = (int)(r + 0.9) % 8;
781 d2 = (int)(r + 0.1) % 8;
782
783 dir = (1 << d1) | (1 << d2);
784 }
785
786 return dir;
787 }
788
789 static inline uint32_t
phys_get_direction(const struct phys_coords mm)790 phys_get_direction(const struct phys_coords mm)
791 {
792 return xy_get_direction(mm.x, mm.y);
793 }
794
795 /**
796 * Get the direction for the given set of coordinates.
797 * assumption: coordinates are normalized to one axis resolution.
798 */
799 static inline uint32_t
device_float_get_direction(const struct device_float_coords coords)800 device_float_get_direction(const struct device_float_coords coords)
801 {
802 return xy_get_direction(coords.x, coords.y);
803 }
804 #endif /* LIBINPUT_PRIVATE_H */
805