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