1/* 2 * Copyright © 2013 Jonas Ådahl 3 * Copyright © 2013-2018 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#include "config.h" 26 27#include <errno.h> 28#include <inttypes.h> 29#include <stdio.h> 30#include <stdlib.h> 31#include <stdarg.h> 32#include <string.h> 33#include <sys/epoll.h> 34#include <unistd.h> 35#include <assert.h> 36 37#include "libinput.h" 38#include "libinput-private.h" 39#include "evdev.h" 40#include "timer.h" 41#include "quirks.h" 42 43#define require_event_type(li_, type_, retval_, ...) \ 44 if (type_ == LIBINPUT_EVENT_NONE) abort(); \ 45 if (!check_event_type(li_, __func__, type_, __VA_ARGS__, -1)) \ 46 return retval_; \ 47 48#define ASSERT_INT_SIZE(type_) \ 49 static_assert(sizeof(type_) == sizeof(unsigned int), \ 50 "sizeof(" #type_ ") must be sizeof(uint)") 51 52ASSERT_INT_SIZE(enum libinput_log_priority); 53ASSERT_INT_SIZE(enum libinput_device_capability); 54ASSERT_INT_SIZE(enum libinput_key_state); 55ASSERT_INT_SIZE(enum libinput_led); 56ASSERT_INT_SIZE(enum libinput_button_state); 57ASSERT_INT_SIZE(enum libinput_pointer_axis); 58ASSERT_INT_SIZE(enum libinput_pointer_axis_source); 59ASSERT_INT_SIZE(enum libinput_tablet_pad_ring_axis_source); 60ASSERT_INT_SIZE(enum libinput_tablet_pad_strip_axis_source); 61ASSERT_INT_SIZE(enum libinput_tablet_tool_type); 62ASSERT_INT_SIZE(enum libinput_tablet_tool_proximity_state); 63ASSERT_INT_SIZE(enum libinput_tablet_tool_tip_state); 64ASSERT_INT_SIZE(enum libinput_switch_state); 65ASSERT_INT_SIZE(enum libinput_switch); 66ASSERT_INT_SIZE(enum libinput_event_type); 67ASSERT_INT_SIZE(enum libinput_config_status); 68ASSERT_INT_SIZE(enum libinput_config_tap_state); 69ASSERT_INT_SIZE(enum libinput_config_tap_button_map); 70ASSERT_INT_SIZE(enum libinput_config_drag_state); 71ASSERT_INT_SIZE(enum libinput_config_drag_lock_state); 72ASSERT_INT_SIZE(enum libinput_config_send_events_mode); 73ASSERT_INT_SIZE(enum libinput_config_accel_profile); 74ASSERT_INT_SIZE(enum libinput_config_click_method); 75ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state); 76ASSERT_INT_SIZE(enum libinput_config_scroll_method); 77ASSERT_INT_SIZE(enum libinput_config_dwt_state); 78ASSERT_INT_SIZE(enum libinput_config_dwtp_state); 79 80static inline const char * 81event_type_to_str(enum libinput_event_type type) 82{ 83 switch(type) { 84 CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_ADDED); 85 CASE_RETURN_STRING(LIBINPUT_EVENT_DEVICE_REMOVED); 86 CASE_RETURN_STRING(LIBINPUT_EVENT_KEYBOARD_KEY); 87 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION); 88 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 89 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_BUTTON); 90 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_AXIS); 91 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_WHEEL); 92 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_FINGER); 93 CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS); 94 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_DOWN); 95 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_UP); 96 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_MOTION); 97 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_CANCEL); 98 CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_FRAME); 99 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_AXIS); 100 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 101 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_TIP); 102 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 103 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_BUTTON); 104 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_RING); 105 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_STRIP); 106 CASE_RETURN_STRING(LIBINPUT_EVENT_TABLET_PAD_KEY); 107 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN); 108 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE); 109 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_SWIPE_END); 110 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_BEGIN); 111 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_UPDATE); 112 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_PINCH_END); 113 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_BEGIN); 114 CASE_RETURN_STRING(LIBINPUT_EVENT_GESTURE_HOLD_END); 115 CASE_RETURN_STRING(LIBINPUT_EVENT_SWITCH_TOGGLE); 116 case LIBINPUT_EVENT_NONE: 117 abort(); 118 } 119 120 return NULL; 121} 122 123static inline bool 124check_event_type(struct libinput *libinput, 125 const char *function_name, 126 unsigned int type_in, 127 ...) 128{ 129 bool rc = false; 130 va_list args; 131 unsigned int type_permitted; 132 133 va_start(args, type_in); 134 type_permitted = va_arg(args, unsigned int); 135 136 while (type_permitted != (unsigned int)-1) { 137 if (type_permitted == type_in) { 138 rc = true; 139 break; 140 } 141 type_permitted = va_arg(args, unsigned int); 142 } 143 144 va_end(args); 145 146 if (!rc) { 147 const char *name = event_type_to_str(type_in); 148 log_bug_client(libinput, 149 "Invalid event type %s (%d) passed to %s()\n", 150 name, type_in, function_name); 151 } 152 153 return rc; 154} 155 156struct libinput_source { 157 libinput_source_dispatch_t dispatch; 158 void *user_data; 159 int fd; 160 struct list link; 161}; 162 163struct libinput_event_device_notify { 164 struct libinput_event base; 165}; 166 167struct libinput_event_keyboard { 168 struct libinput_event base; 169 uint64_t time; 170 uint32_t key; 171 uint32_t seat_key_count; 172 enum libinput_key_state state; 173}; 174 175struct libinput_event_pointer { 176 struct libinput_event base; 177 uint64_t time; 178 struct normalized_coords delta; 179 struct device_float_coords delta_raw; 180 struct device_coords absolute; 181 struct discrete_coords discrete; 182 struct wheel_v120 v120; 183 uint32_t button; 184 uint32_t seat_button_count; 185 enum libinput_button_state state; 186 enum libinput_pointer_axis_source source; 187 uint32_t axes; 188}; 189 190struct libinput_event_touch { 191 struct libinput_event base; 192 uint64_t time; 193 int32_t slot; 194 int32_t seat_slot; 195 struct device_coords point; 196}; 197 198struct libinput_event_gesture { 199 struct libinput_event base; 200 uint64_t time; 201 int finger_count; 202 int cancelled; 203 struct normalized_coords delta; 204 struct normalized_coords delta_unaccel; 205 double scale; 206 double angle; 207}; 208 209struct libinput_event_tablet_tool { 210 struct libinput_event base; 211 uint32_t button; 212 enum libinput_button_state state; 213 uint32_t seat_button_count; 214 uint64_t time; 215 struct tablet_axes axes; 216 unsigned char changed_axes[NCHARS(LIBINPUT_TABLET_TOOL_AXIS_MAX + 1)]; 217 struct libinput_tablet_tool *tool; 218 enum libinput_tablet_tool_proximity_state proximity_state; 219 enum libinput_tablet_tool_tip_state tip_state; 220}; 221 222struct libinput_event_tablet_pad { 223 struct libinput_event base; 224 unsigned int mode; 225 struct libinput_tablet_pad_mode_group *mode_group; 226 uint64_t time; 227 struct { 228 uint32_t number; 229 enum libinput_button_state state; 230 } button; 231 struct { 232 uint32_t code; 233 enum libinput_key_state state; 234 } key; 235 struct { 236 enum libinput_tablet_pad_ring_axis_source source; 237 double position; 238 int number; 239 } ring; 240 struct { 241 enum libinput_tablet_pad_strip_axis_source source; 242 double position; 243 int number; 244 } strip; 245}; 246 247struct libinput_event_switch { 248 struct libinput_event base; 249 uint64_t time; 250 enum libinput_switch sw; 251 enum libinput_switch_state state; 252}; 253 254LIBINPUT_ATTRIBUTE_PRINTF(3, 0) 255static void 256libinput_default_log_func(struct libinput *libinput, 257 enum libinput_log_priority priority, 258 const char *format, va_list args) 259{ 260 const char *prefix; 261 262 switch(priority) { 263 case LIBINPUT_LOG_PRIORITY_DEBUG: prefix = "debug"; break; 264 case LIBINPUT_LOG_PRIORITY_INFO: prefix = "info"; break; 265 case LIBINPUT_LOG_PRIORITY_ERROR: prefix = "error"; break; 266 default: prefix="<invalid priority>"; break; 267 } 268 269 fprintf(stderr, "libinput %s: ", prefix); 270 vfprintf(stderr, format, args); 271} 272 273void 274log_msg_va(struct libinput *libinput, 275 enum libinput_log_priority priority, 276 const char *format, 277 va_list args) 278{ 279 if (is_logged(libinput, priority)) 280 libinput->log_handler(libinput, priority, format, args); 281} 282 283void 284log_msg(struct libinput *libinput, 285 enum libinput_log_priority priority, 286 const char *format, ...) 287{ 288 va_list args; 289 290 va_start(args, format); 291 log_msg_va(libinput, priority, format, args); 292 va_end(args); 293} 294 295void 296log_msg_ratelimit(struct libinput *libinput, 297 struct ratelimit *ratelimit, 298 enum libinput_log_priority priority, 299 const char *format, ...) 300{ 301 va_list args; 302 enum ratelimit_state state; 303 304 state = ratelimit_test(ratelimit); 305 if (state == RATELIMIT_EXCEEDED) 306 return; 307 308 va_start(args, format); 309 log_msg_va(libinput, priority, format, args); 310 va_end(args); 311 312 if (state == RATELIMIT_THRESHOLD) 313 log_msg(libinput, 314 priority, 315 "WARNING: log rate limit exceeded (%d msgs per %dms). Discarding future messages.\n", 316 ratelimit->burst, 317 us2ms(ratelimit->interval)); 318} 319 320LIBINPUT_EXPORT void 321libinput_log_set_priority(struct libinput *libinput, 322 enum libinput_log_priority priority) 323{ 324 libinput->log_priority = priority; 325} 326 327LIBINPUT_EXPORT enum libinput_log_priority 328libinput_log_get_priority(const struct libinput *libinput) 329{ 330 return libinput->log_priority; 331} 332 333LIBINPUT_EXPORT void 334libinput_log_set_handler(struct libinput *libinput, 335 libinput_log_handler log_handler) 336{ 337 libinput->log_handler = log_handler; 338} 339 340static void 341libinput_device_group_destroy(struct libinput_device_group *group); 342 343static void 344libinput_post_event(struct libinput *libinput, 345 struct libinput_event *event); 346 347LIBINPUT_EXPORT enum libinput_event_type 348libinput_event_get_type(struct libinput_event *event) 349{ 350 return event->type; 351} 352 353LIBINPUT_EXPORT struct libinput * 354libinput_event_get_context(struct libinput_event *event) 355{ 356 return event->device->seat->libinput; 357} 358 359LIBINPUT_EXPORT struct libinput_device * 360libinput_event_get_device(struct libinput_event *event) 361{ 362 return event->device; 363} 364 365LIBINPUT_EXPORT struct libinput_event_pointer * 366libinput_event_get_pointer_event(struct libinput_event *event) 367{ 368 require_event_type(libinput_event_get_context(event), 369 event->type, 370 NULL, 371 LIBINPUT_EVENT_POINTER_MOTION, 372 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, 373 LIBINPUT_EVENT_POINTER_BUTTON, 374 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 375 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 376 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 377 LIBINPUT_EVENT_POINTER_AXIS); 378 379 return (struct libinput_event_pointer *) event; 380} 381 382LIBINPUT_EXPORT struct libinput_event_keyboard * 383libinput_event_get_keyboard_event(struct libinput_event *event) 384{ 385 require_event_type(libinput_event_get_context(event), 386 event->type, 387 NULL, 388 LIBINPUT_EVENT_KEYBOARD_KEY); 389 390 return (struct libinput_event_keyboard *) event; 391} 392 393LIBINPUT_EXPORT struct libinput_event_touch * 394libinput_event_get_touch_event(struct libinput_event *event) 395{ 396 require_event_type(libinput_event_get_context(event), 397 event->type, 398 NULL, 399 LIBINPUT_EVENT_TOUCH_DOWN, 400 LIBINPUT_EVENT_TOUCH_UP, 401 LIBINPUT_EVENT_TOUCH_MOTION, 402 LIBINPUT_EVENT_TOUCH_CANCEL, 403 LIBINPUT_EVENT_TOUCH_FRAME); 404 return (struct libinput_event_touch *) event; 405} 406 407LIBINPUT_EXPORT struct libinput_event_gesture * 408libinput_event_get_gesture_event(struct libinput_event *event) 409{ 410 require_event_type(libinput_event_get_context(event), 411 event->type, 412 NULL, 413 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 414 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 415 LIBINPUT_EVENT_GESTURE_SWIPE_END, 416 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 417 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 418 LIBINPUT_EVENT_GESTURE_PINCH_END, 419 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 420 LIBINPUT_EVENT_GESTURE_HOLD_END); 421 422 return (struct libinput_event_gesture *) event; 423} 424 425LIBINPUT_EXPORT struct libinput_event_tablet_tool * 426libinput_event_get_tablet_tool_event(struct libinput_event *event) 427{ 428 require_event_type(libinput_event_get_context(event), 429 event->type, 430 NULL, 431 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 432 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, 433 LIBINPUT_EVENT_TABLET_TOOL_TIP, 434 LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 435 436 return (struct libinput_event_tablet_tool *) event; 437} 438 439LIBINPUT_EXPORT struct libinput_event_tablet_pad * 440libinput_event_get_tablet_pad_event(struct libinput_event *event) 441{ 442 require_event_type(libinput_event_get_context(event), 443 event->type, 444 NULL, 445 LIBINPUT_EVENT_TABLET_PAD_RING, 446 LIBINPUT_EVENT_TABLET_PAD_STRIP, 447 LIBINPUT_EVENT_TABLET_PAD_BUTTON, 448 LIBINPUT_EVENT_TABLET_PAD_KEY); 449 450 return (struct libinput_event_tablet_pad *) event; 451} 452 453LIBINPUT_EXPORT struct libinput_event_device_notify * 454libinput_event_get_device_notify_event(struct libinput_event *event) 455{ 456 require_event_type(libinput_event_get_context(event), 457 event->type, 458 NULL, 459 LIBINPUT_EVENT_DEVICE_ADDED, 460 LIBINPUT_EVENT_DEVICE_REMOVED); 461 462 return (struct libinput_event_device_notify *) event; 463} 464 465LIBINPUT_EXPORT struct libinput_event_switch * 466libinput_event_get_switch_event(struct libinput_event *event) 467{ 468 require_event_type(libinput_event_get_context(event), 469 event->type, 470 NULL, 471 LIBINPUT_EVENT_SWITCH_TOGGLE); 472 473 return (struct libinput_event_switch *) event; 474} 475 476LIBINPUT_EXPORT uint32_t 477libinput_event_keyboard_get_time(struct libinput_event_keyboard *event) 478{ 479 require_event_type(libinput_event_get_context(&event->base), 480 event->base.type, 481 0, 482 LIBINPUT_EVENT_KEYBOARD_KEY); 483 484 return us2ms(event->time); 485} 486 487LIBINPUT_EXPORT uint64_t 488libinput_event_keyboard_get_time_usec(struct libinput_event_keyboard *event) 489{ 490 require_event_type(libinput_event_get_context(&event->base), 491 event->base.type, 492 0, 493 LIBINPUT_EVENT_KEYBOARD_KEY); 494 495 return event->time; 496} 497 498LIBINPUT_EXPORT uint32_t 499libinput_event_keyboard_get_key(struct libinput_event_keyboard *event) 500{ 501 require_event_type(libinput_event_get_context(&event->base), 502 event->base.type, 503 0, 504 LIBINPUT_EVENT_KEYBOARD_KEY); 505 506 return event->key; 507} 508 509LIBINPUT_EXPORT enum libinput_key_state 510libinput_event_keyboard_get_key_state(struct libinput_event_keyboard *event) 511{ 512 require_event_type(libinput_event_get_context(&event->base), 513 event->base.type, 514 0, 515 LIBINPUT_EVENT_KEYBOARD_KEY); 516 517 return event->state; 518} 519 520LIBINPUT_EXPORT uint32_t 521libinput_event_keyboard_get_seat_key_count( 522 struct libinput_event_keyboard *event) 523{ 524 require_event_type(libinput_event_get_context(&event->base), 525 event->base.type, 526 0, 527 LIBINPUT_EVENT_KEYBOARD_KEY); 528 529 return event->seat_key_count; 530} 531 532LIBINPUT_EXPORT uint32_t 533libinput_event_pointer_get_time(struct libinput_event_pointer *event) 534{ 535 require_event_type(libinput_event_get_context(&event->base), 536 event->base.type, 537 0, 538 LIBINPUT_EVENT_POINTER_MOTION, 539 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, 540 LIBINPUT_EVENT_POINTER_BUTTON, 541 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 542 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 543 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 544 LIBINPUT_EVENT_POINTER_AXIS); 545 546 return us2ms(event->time); 547} 548 549LIBINPUT_EXPORT uint64_t 550libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event) 551{ 552 require_event_type(libinput_event_get_context(&event->base), 553 event->base.type, 554 0, 555 LIBINPUT_EVENT_POINTER_MOTION, 556 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, 557 LIBINPUT_EVENT_POINTER_BUTTON, 558 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 559 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 560 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 561 LIBINPUT_EVENT_POINTER_AXIS); 562 563 return event->time; 564} 565 566LIBINPUT_EXPORT double 567libinput_event_pointer_get_dx(struct libinput_event_pointer *event) 568{ 569 require_event_type(libinput_event_get_context(&event->base), 570 event->base.type, 571 0, 572 LIBINPUT_EVENT_POINTER_MOTION); 573 574 return event->delta.x; 575} 576 577LIBINPUT_EXPORT double 578libinput_event_pointer_get_dy(struct libinput_event_pointer *event) 579{ 580 require_event_type(libinput_event_get_context(&event->base), 581 event->base.type, 582 0, 583 LIBINPUT_EVENT_POINTER_MOTION); 584 585 return event->delta.y; 586} 587 588LIBINPUT_EXPORT double 589libinput_event_pointer_get_dx_unaccelerated( 590 struct libinput_event_pointer *event) 591{ 592 require_event_type(libinput_event_get_context(&event->base), 593 event->base.type, 594 0, 595 LIBINPUT_EVENT_POINTER_MOTION); 596 597 return event->delta_raw.x; 598} 599 600LIBINPUT_EXPORT double 601libinput_event_pointer_get_dy_unaccelerated( 602 struct libinput_event_pointer *event) 603{ 604 require_event_type(libinput_event_get_context(&event->base), 605 event->base.type, 606 0, 607 LIBINPUT_EVENT_POINTER_MOTION); 608 609 return event->delta_raw.y; 610} 611 612LIBINPUT_EXPORT double 613libinput_event_pointer_get_absolute_x(struct libinput_event_pointer *event) 614{ 615 struct evdev_device *device = evdev_device(event->base.device); 616 617 require_event_type(libinput_event_get_context(&event->base), 618 event->base.type, 619 0, 620 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 621 622 return evdev_convert_to_mm(device->abs.absinfo_x, event->absolute.x); 623} 624 625LIBINPUT_EXPORT double 626libinput_event_pointer_get_absolute_y(struct libinput_event_pointer *event) 627{ 628 struct evdev_device *device = evdev_device(event->base.device); 629 630 require_event_type(libinput_event_get_context(&event->base), 631 event->base.type, 632 0, 633 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 634 635 return evdev_convert_to_mm(device->abs.absinfo_y, event->absolute.y); 636} 637 638LIBINPUT_EXPORT double 639libinput_event_pointer_get_absolute_x_transformed( 640 struct libinput_event_pointer *event, 641 uint32_t width) 642{ 643 struct evdev_device *device = evdev_device(event->base.device); 644 645 require_event_type(libinput_event_get_context(&event->base), 646 event->base.type, 647 0, 648 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 649 650 return evdev_device_transform_x(device, event->absolute.x, width); 651} 652 653LIBINPUT_EXPORT double 654libinput_event_pointer_get_absolute_y_transformed( 655 struct libinput_event_pointer *event, 656 uint32_t height) 657{ 658 struct evdev_device *device = evdev_device(event->base.device); 659 660 require_event_type(libinput_event_get_context(&event->base), 661 event->base.type, 662 0, 663 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 664 665 return evdev_device_transform_y(device, event->absolute.y, height); 666} 667 668LIBINPUT_EXPORT uint32_t 669libinput_event_pointer_get_button(struct libinput_event_pointer *event) 670{ 671 require_event_type(libinput_event_get_context(&event->base), 672 event->base.type, 673 0, 674 LIBINPUT_EVENT_POINTER_BUTTON); 675 676 return event->button; 677} 678 679LIBINPUT_EXPORT enum libinput_button_state 680libinput_event_pointer_get_button_state(struct libinput_event_pointer *event) 681{ 682 require_event_type(libinput_event_get_context(&event->base), 683 event->base.type, 684 0, 685 LIBINPUT_EVENT_POINTER_BUTTON); 686 687 return event->state; 688} 689 690LIBINPUT_EXPORT uint32_t 691libinput_event_pointer_get_seat_button_count( 692 struct libinput_event_pointer *event) 693{ 694 require_event_type(libinput_event_get_context(&event->base), 695 event->base.type, 696 0, 697 LIBINPUT_EVENT_POINTER_BUTTON); 698 699 return event->seat_button_count; 700} 701 702LIBINPUT_EXPORT int 703libinput_event_pointer_has_axis(struct libinput_event_pointer *event, 704 enum libinput_pointer_axis axis) 705{ 706 require_event_type(libinput_event_get_context(&event->base), 707 event->base.type, 708 0, 709 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 710 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 711 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 712 LIBINPUT_EVENT_POINTER_AXIS); 713 714 switch (axis) { 715 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: 716 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: 717 return !!(event->axes & bit(axis)); 718 } 719 720 return 0; 721} 722 723LIBINPUT_EXPORT double 724libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, 725 enum libinput_pointer_axis axis) 726{ 727 struct libinput *libinput = event->base.device->seat->libinput; 728 double value = 0; 729 730 require_event_type(libinput_event_get_context(&event->base), 731 event->base.type, 732 0.0, 733 LIBINPUT_EVENT_POINTER_AXIS); 734 735 if (!libinput_event_pointer_has_axis(event, axis)) { 736 log_bug_client(libinput, "value requested for unset axis\n"); 737 } else { 738 switch (axis) { 739 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: 740 value = event->delta.x; 741 break; 742 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: 743 value = event->delta.y; 744 break; 745 } 746 } 747 748 return value; 749} 750 751LIBINPUT_EXPORT double 752libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, 753 enum libinput_pointer_axis axis) 754{ 755 struct libinput *libinput = event->base.device->seat->libinput; 756 double value = 0; 757 758 require_event_type(libinput_event_get_context(&event->base), 759 event->base.type, 760 0.0, 761 LIBINPUT_EVENT_POINTER_AXIS); 762 763 if (!libinput_event_pointer_has_axis(event, axis)) { 764 log_bug_client(libinput, "value requested for unset axis\n"); 765 } else { 766 switch (axis) { 767 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: 768 value = event->discrete.x; 769 break; 770 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: 771 value = event->discrete.y; 772 break; 773 } 774 } 775 return value; 776} 777 778LIBINPUT_EXPORT double 779libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event, 780 enum libinput_pointer_axis axis) 781{ 782 struct libinput *libinput = event->base.device->seat->libinput; 783 double value = 0; 784 785 require_event_type(libinput_event_get_context(&event->base), 786 event->base.type, 787 0.0, 788 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 789 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 790 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS); 791 792 if (!libinput_event_pointer_has_axis(event, axis)) { 793 log_bug_client(libinput, "value requested for unset axis\n"); 794 } else { 795 switch (axis) { 796 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: 797 value = event->delta.x; 798 break; 799 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: 800 value = event->delta.y; 801 break; 802 } 803 } 804 return value; 805} 806 807LIBINPUT_EXPORT double 808libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event, 809 enum libinput_pointer_axis axis) 810{ 811 struct libinput *libinput = event->base.device->seat->libinput; 812 double value = 0; 813 814 require_event_type(libinput_event_get_context(&event->base), 815 event->base.type, 816 0.0, 817 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL); 818 819 if (!libinput_event_pointer_has_axis(event, axis)) { 820 log_bug_client(libinput, "value requested for unset axis\n"); 821 } else { 822 switch (axis) { 823 case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: 824 value = event->v120.x; 825 break; 826 case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: 827 value = event->v120.y; 828 break; 829 } 830 } 831 return value; 832} 833 834LIBINPUT_EXPORT enum libinput_pointer_axis_source 835libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event) 836{ 837 require_event_type(libinput_event_get_context(&event->base), 838 event->base.type, 839 0, 840 LIBINPUT_EVENT_POINTER_AXIS); 841 842 return event->source; 843} 844 845LIBINPUT_EXPORT uint32_t 846libinput_event_touch_get_time(struct libinput_event_touch *event) 847{ 848 require_event_type(libinput_event_get_context(&event->base), 849 event->base.type, 850 0, 851 LIBINPUT_EVENT_TOUCH_DOWN, 852 LIBINPUT_EVENT_TOUCH_UP, 853 LIBINPUT_EVENT_TOUCH_MOTION, 854 LIBINPUT_EVENT_TOUCH_CANCEL, 855 LIBINPUT_EVENT_TOUCH_FRAME); 856 857 return us2ms(event->time); 858} 859 860LIBINPUT_EXPORT uint64_t 861libinput_event_touch_get_time_usec(struct libinput_event_touch *event) 862{ 863 require_event_type(libinput_event_get_context(&event->base), 864 event->base.type, 865 0, 866 LIBINPUT_EVENT_TOUCH_DOWN, 867 LIBINPUT_EVENT_TOUCH_UP, 868 LIBINPUT_EVENT_TOUCH_MOTION, 869 LIBINPUT_EVENT_TOUCH_CANCEL, 870 LIBINPUT_EVENT_TOUCH_FRAME); 871 872 return event->time; 873} 874 875LIBINPUT_EXPORT int32_t 876libinput_event_touch_get_slot(struct libinput_event_touch *event) 877{ 878 require_event_type(libinput_event_get_context(&event->base), 879 event->base.type, 880 0, 881 LIBINPUT_EVENT_TOUCH_DOWN, 882 LIBINPUT_EVENT_TOUCH_UP, 883 LIBINPUT_EVENT_TOUCH_MOTION, 884 LIBINPUT_EVENT_TOUCH_CANCEL); 885 886 return event->slot; 887} 888 889LIBINPUT_EXPORT int32_t 890libinput_event_touch_get_seat_slot(struct libinput_event_touch *event) 891{ 892 require_event_type(libinput_event_get_context(&event->base), 893 event->base.type, 894 0, 895 LIBINPUT_EVENT_TOUCH_DOWN, 896 LIBINPUT_EVENT_TOUCH_UP, 897 LIBINPUT_EVENT_TOUCH_MOTION, 898 LIBINPUT_EVENT_TOUCH_CANCEL); 899 900 return event->seat_slot; 901} 902 903LIBINPUT_EXPORT double 904libinput_event_touch_get_x(struct libinput_event_touch *event) 905{ 906 struct evdev_device *device = evdev_device(event->base.device); 907 908 require_event_type(libinput_event_get_context(&event->base), 909 event->base.type, 910 0, 911 LIBINPUT_EVENT_TOUCH_DOWN, 912 LIBINPUT_EVENT_TOUCH_MOTION); 913 914 return evdev_convert_to_mm(device->abs.absinfo_x, event->point.x); 915} 916 917LIBINPUT_EXPORT double 918libinput_event_touch_get_x_transformed(struct libinput_event_touch *event, 919 uint32_t width) 920{ 921 struct evdev_device *device = evdev_device(event->base.device); 922 923 require_event_type(libinput_event_get_context(&event->base), 924 event->base.type, 925 0, 926 LIBINPUT_EVENT_TOUCH_DOWN, 927 LIBINPUT_EVENT_TOUCH_MOTION); 928 929 return evdev_device_transform_x(device, event->point.x, width); 930} 931 932LIBINPUT_EXPORT double 933libinput_event_touch_get_y_transformed(struct libinput_event_touch *event, 934 uint32_t height) 935{ 936 struct evdev_device *device = evdev_device(event->base.device); 937 938 require_event_type(libinput_event_get_context(&event->base), 939 event->base.type, 940 0, 941 LIBINPUT_EVENT_TOUCH_DOWN, 942 LIBINPUT_EVENT_TOUCH_MOTION); 943 944 return evdev_device_transform_y(device, event->point.y, height); 945} 946 947LIBINPUT_EXPORT double 948libinput_event_touch_get_y(struct libinput_event_touch *event) 949{ 950 struct evdev_device *device = evdev_device(event->base.device); 951 952 require_event_type(libinput_event_get_context(&event->base), 953 event->base.type, 954 0, 955 LIBINPUT_EVENT_TOUCH_DOWN, 956 LIBINPUT_EVENT_TOUCH_MOTION); 957 958 return evdev_convert_to_mm(device->abs.absinfo_y, event->point.y); 959} 960 961LIBINPUT_EXPORT uint32_t 962libinput_event_gesture_get_time(struct libinput_event_gesture *event) 963{ 964 require_event_type(libinput_event_get_context(&event->base), 965 event->base.type, 966 0, 967 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 968 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 969 LIBINPUT_EVENT_GESTURE_PINCH_END, 970 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 971 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 972 LIBINPUT_EVENT_GESTURE_SWIPE_END, 973 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 974 LIBINPUT_EVENT_GESTURE_HOLD_END); 975 976 return us2ms(event->time); 977} 978 979LIBINPUT_EXPORT uint64_t 980libinput_event_gesture_get_time_usec(struct libinput_event_gesture *event) 981{ 982 require_event_type(libinput_event_get_context(&event->base), 983 event->base.type, 984 0, 985 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 986 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 987 LIBINPUT_EVENT_GESTURE_PINCH_END, 988 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 989 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 990 LIBINPUT_EVENT_GESTURE_SWIPE_END, 991 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 992 LIBINPUT_EVENT_GESTURE_HOLD_END); 993 994 return event->time; 995} 996 997LIBINPUT_EXPORT int 998libinput_event_gesture_get_finger_count(struct libinput_event_gesture *event) 999{ 1000 require_event_type(libinput_event_get_context(&event->base), 1001 event->base.type, 1002 0, 1003 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1004 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1005 LIBINPUT_EVENT_GESTURE_PINCH_END, 1006 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 1007 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1008 LIBINPUT_EVENT_GESTURE_SWIPE_END, 1009 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 1010 LIBINPUT_EVENT_GESTURE_HOLD_END); 1011 1012 return event->finger_count; 1013} 1014 1015LIBINPUT_EXPORT int 1016libinput_event_gesture_get_cancelled(struct libinput_event_gesture *event) 1017{ 1018 require_event_type(libinput_event_get_context(&event->base), 1019 event->base.type, 1020 0, 1021 LIBINPUT_EVENT_GESTURE_PINCH_END, 1022 LIBINPUT_EVENT_GESTURE_SWIPE_END, 1023 LIBINPUT_EVENT_GESTURE_HOLD_END); 1024 1025 return event->cancelled; 1026} 1027 1028LIBINPUT_EXPORT double 1029libinput_event_gesture_get_dx(struct libinput_event_gesture *event) 1030{ 1031 require_event_type(libinput_event_get_context(&event->base), 1032 event->base.type, 1033 0.0, 1034 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1035 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1036 LIBINPUT_EVENT_GESTURE_PINCH_END, 1037 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 1038 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1039 LIBINPUT_EVENT_GESTURE_SWIPE_END); 1040 1041 return event->delta.x; 1042} 1043 1044LIBINPUT_EXPORT double 1045libinput_event_gesture_get_dy(struct libinput_event_gesture *event) 1046{ 1047 require_event_type(libinput_event_get_context(&event->base), 1048 event->base.type, 1049 0.0, 1050 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1051 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1052 LIBINPUT_EVENT_GESTURE_PINCH_END, 1053 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 1054 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1055 LIBINPUT_EVENT_GESTURE_SWIPE_END); 1056 1057 return event->delta.y; 1058} 1059 1060LIBINPUT_EXPORT double 1061libinput_event_gesture_get_dx_unaccelerated( 1062 struct libinput_event_gesture *event) 1063{ 1064 require_event_type(libinput_event_get_context(&event->base), 1065 event->base.type, 1066 0.0, 1067 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1068 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1069 LIBINPUT_EVENT_GESTURE_PINCH_END, 1070 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 1071 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1072 LIBINPUT_EVENT_GESTURE_SWIPE_END); 1073 1074 return event->delta_unaccel.x; 1075} 1076 1077LIBINPUT_EXPORT double 1078libinput_event_gesture_get_dy_unaccelerated( 1079 struct libinput_event_gesture *event) 1080{ 1081 require_event_type(libinput_event_get_context(&event->base), 1082 event->base.type, 1083 0.0, 1084 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1085 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1086 LIBINPUT_EVENT_GESTURE_PINCH_END, 1087 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 1088 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 1089 LIBINPUT_EVENT_GESTURE_SWIPE_END); 1090 1091 return event->delta_unaccel.y; 1092} 1093 1094LIBINPUT_EXPORT double 1095libinput_event_gesture_get_scale(struct libinput_event_gesture *event) 1096{ 1097 require_event_type(libinput_event_get_context(&event->base), 1098 event->base.type, 1099 0.0, 1100 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1101 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1102 LIBINPUT_EVENT_GESTURE_PINCH_END); 1103 1104 return event->scale; 1105} 1106 1107LIBINPUT_EXPORT double 1108libinput_event_gesture_get_angle_delta(struct libinput_event_gesture *event) 1109{ 1110 require_event_type(libinput_event_get_context(&event->base), 1111 event->base.type, 1112 0.0, 1113 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 1114 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 1115 LIBINPUT_EVENT_GESTURE_PINCH_END); 1116 1117 return event->angle; 1118} 1119 1120LIBINPUT_EXPORT int 1121libinput_event_tablet_tool_x_has_changed( 1122 struct libinput_event_tablet_tool *event) 1123{ 1124 require_event_type(libinput_event_get_context(&event->base), 1125 event->base.type, 1126 0, 1127 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1128 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1129 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1130 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1131 1132 return bit_is_set(event->changed_axes, 1133 LIBINPUT_TABLET_TOOL_AXIS_X); 1134} 1135 1136LIBINPUT_EXPORT int 1137libinput_event_tablet_tool_y_has_changed( 1138 struct libinput_event_tablet_tool *event) 1139{ 1140 require_event_type(libinput_event_get_context(&event->base), 1141 event->base.type, 1142 0, 1143 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1144 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1145 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1146 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1147 1148 return bit_is_set(event->changed_axes, 1149 LIBINPUT_TABLET_TOOL_AXIS_Y); 1150} 1151 1152LIBINPUT_EXPORT int 1153libinput_event_tablet_tool_pressure_has_changed( 1154 struct libinput_event_tablet_tool *event) 1155{ 1156 require_event_type(libinput_event_get_context(&event->base), 1157 event->base.type, 1158 0, 1159 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1160 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1161 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1162 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1163 1164 return bit_is_set(event->changed_axes, 1165 LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); 1166} 1167 1168LIBINPUT_EXPORT int 1169libinput_event_tablet_tool_distance_has_changed( 1170 struct libinput_event_tablet_tool *event) 1171{ 1172 require_event_type(libinput_event_get_context(&event->base), 1173 event->base.type, 1174 0, 1175 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1176 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1177 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1178 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1179 1180 return bit_is_set(event->changed_axes, 1181 LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); 1182} 1183 1184LIBINPUT_EXPORT int 1185libinput_event_tablet_tool_tilt_x_has_changed( 1186 struct libinput_event_tablet_tool *event) 1187{ 1188 require_event_type(libinput_event_get_context(&event->base), 1189 event->base.type, 1190 0, 1191 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1192 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1193 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1194 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1195 1196 return bit_is_set(event->changed_axes, 1197 LIBINPUT_TABLET_TOOL_AXIS_TILT_X); 1198} 1199 1200LIBINPUT_EXPORT int 1201libinput_event_tablet_tool_tilt_y_has_changed( 1202 struct libinput_event_tablet_tool *event) 1203{ 1204 require_event_type(libinput_event_get_context(&event->base), 1205 event->base.type, 1206 0, 1207 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1208 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1209 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1210 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1211 1212 return bit_is_set(event->changed_axes, 1213 LIBINPUT_TABLET_TOOL_AXIS_TILT_Y); 1214} 1215 1216LIBINPUT_EXPORT int 1217libinput_event_tablet_tool_rotation_has_changed( 1218 struct libinput_event_tablet_tool *event) 1219{ 1220 require_event_type(libinput_event_get_context(&event->base), 1221 event->base.type, 1222 0, 1223 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1224 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1225 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1226 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1227 1228 return bit_is_set(event->changed_axes, 1229 LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); 1230} 1231 1232LIBINPUT_EXPORT int 1233libinput_event_tablet_tool_slider_has_changed( 1234 struct libinput_event_tablet_tool *event) 1235{ 1236 require_event_type(libinput_event_get_context(&event->base), 1237 event->base.type, 1238 0, 1239 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1240 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1241 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1242 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1243 1244 return bit_is_set(event->changed_axes, 1245 LIBINPUT_TABLET_TOOL_AXIS_SLIDER); 1246} 1247 1248LIBINPUT_EXPORT int 1249libinput_event_tablet_tool_size_major_has_changed( 1250 struct libinput_event_tablet_tool *event) 1251{ 1252 require_event_type(libinput_event_get_context(&event->base), 1253 event->base.type, 1254 0, 1255 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1256 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1257 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1258 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1259 1260 return bit_is_set(event->changed_axes, 1261 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR); 1262} 1263 1264LIBINPUT_EXPORT int 1265libinput_event_tablet_tool_size_minor_has_changed( 1266 struct libinput_event_tablet_tool *event) 1267{ 1268 require_event_type(libinput_event_get_context(&event->base), 1269 event->base.type, 1270 0, 1271 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1272 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1273 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1274 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1275 1276 return bit_is_set(event->changed_axes, 1277 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MINOR); 1278} 1279 1280LIBINPUT_EXPORT int 1281libinput_event_tablet_tool_wheel_has_changed( 1282 struct libinput_event_tablet_tool *event) 1283{ 1284 require_event_type(libinput_event_get_context(&event->base), 1285 event->base.type, 1286 0, 1287 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1288 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1289 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1290 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1291 1292 return bit_is_set(event->changed_axes, 1293 LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL); 1294} 1295 1296LIBINPUT_EXPORT double 1297libinput_event_tablet_tool_get_x(struct libinput_event_tablet_tool *event) 1298{ 1299 struct evdev_device *device = evdev_device(event->base.device); 1300 1301 require_event_type(libinput_event_get_context(&event->base), 1302 event->base.type, 1303 0, 1304 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1305 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1306 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1307 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1308 1309 return evdev_convert_to_mm(device->abs.absinfo_x, 1310 event->axes.point.x); 1311} 1312 1313LIBINPUT_EXPORT double 1314libinput_event_tablet_tool_get_y(struct libinput_event_tablet_tool *event) 1315{ 1316 struct evdev_device *device = evdev_device(event->base.device); 1317 1318 require_event_type(libinput_event_get_context(&event->base), 1319 event->base.type, 1320 0, 1321 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1322 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1323 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1324 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1325 1326 return evdev_convert_to_mm(device->abs.absinfo_y, 1327 event->axes.point.y); 1328} 1329 1330LIBINPUT_EXPORT double 1331libinput_event_tablet_tool_get_dx(struct libinput_event_tablet_tool *event) 1332{ 1333 require_event_type(libinput_event_get_context(&event->base), 1334 event->base.type, 1335 0, 1336 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1337 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1338 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1339 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1340 1341 return event->axes.delta.x; 1342} 1343 1344LIBINPUT_EXPORT double 1345libinput_event_tablet_tool_get_dy(struct libinput_event_tablet_tool *event) 1346{ 1347 require_event_type(libinput_event_get_context(&event->base), 1348 event->base.type, 1349 0, 1350 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1351 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1352 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1353 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1354 1355 return event->axes.delta.y; 1356} 1357 1358LIBINPUT_EXPORT double 1359libinput_event_tablet_tool_get_pressure(struct libinput_event_tablet_tool *event) 1360{ 1361 require_event_type(libinput_event_get_context(&event->base), 1362 event->base.type, 1363 0, 1364 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1365 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1366 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1367 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1368 1369 return event->axes.pressure; 1370} 1371 1372LIBINPUT_EXPORT double 1373libinput_event_tablet_tool_get_distance(struct libinput_event_tablet_tool *event) 1374{ 1375 require_event_type(libinput_event_get_context(&event->base), 1376 event->base.type, 1377 0, 1378 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1379 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1380 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1381 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1382 1383 return event->axes.distance; 1384} 1385 1386LIBINPUT_EXPORT double 1387libinput_event_tablet_tool_get_tilt_x(struct libinput_event_tablet_tool *event) 1388{ 1389 require_event_type(libinput_event_get_context(&event->base), 1390 event->base.type, 1391 0, 1392 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1393 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1394 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1395 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1396 1397 return event->axes.tilt.x; 1398} 1399 1400LIBINPUT_EXPORT double 1401libinput_event_tablet_tool_get_tilt_y(struct libinput_event_tablet_tool *event) 1402{ 1403 require_event_type(libinput_event_get_context(&event->base), 1404 event->base.type, 1405 0, 1406 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1407 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1408 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1409 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1410 1411 return event->axes.tilt.y; 1412} 1413 1414LIBINPUT_EXPORT double 1415libinput_event_tablet_tool_get_rotation(struct libinput_event_tablet_tool *event) 1416{ 1417 require_event_type(libinput_event_get_context(&event->base), 1418 event->base.type, 1419 0, 1420 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1421 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1422 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1423 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1424 1425 return event->axes.rotation; 1426} 1427 1428LIBINPUT_EXPORT double 1429libinput_event_tablet_tool_get_slider_position(struct libinput_event_tablet_tool *event) 1430{ 1431 require_event_type(libinput_event_get_context(&event->base), 1432 event->base.type, 1433 0, 1434 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1435 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1436 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1437 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1438 1439 return event->axes.slider; 1440} 1441 1442LIBINPUT_EXPORT double 1443libinput_event_tablet_tool_get_size_major(struct libinput_event_tablet_tool *event) 1444{ 1445 require_event_type(libinput_event_get_context(&event->base), 1446 event->base.type, 1447 0, 1448 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1449 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1450 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1451 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1452 1453 return event->axes.size.major; 1454} 1455 1456LIBINPUT_EXPORT double 1457libinput_event_tablet_tool_get_size_minor(struct libinput_event_tablet_tool *event) 1458{ 1459 require_event_type(libinput_event_get_context(&event->base), 1460 event->base.type, 1461 0, 1462 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1463 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1464 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1465 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1466 1467 return event->axes.size.minor; 1468} 1469 1470LIBINPUT_EXPORT double 1471libinput_event_tablet_tool_get_wheel_delta(struct libinput_event_tablet_tool *event) 1472{ 1473 require_event_type(libinput_event_get_context(&event->base), 1474 event->base.type, 1475 0, 1476 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1477 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1478 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1479 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1480 1481 return event->axes.wheel; 1482} 1483 1484LIBINPUT_EXPORT int 1485libinput_event_tablet_tool_get_wheel_delta_discrete( 1486 struct libinput_event_tablet_tool *event) 1487{ 1488 require_event_type(libinput_event_get_context(&event->base), 1489 event->base.type, 1490 0, 1491 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1492 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1493 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1494 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1495 1496 return event->axes.wheel_discrete; 1497} 1498 1499LIBINPUT_EXPORT double 1500libinput_event_tablet_tool_get_x_transformed(struct libinput_event_tablet_tool *event, 1501 uint32_t width) 1502{ 1503 struct evdev_device *device = evdev_device(event->base.device); 1504 1505 require_event_type(libinput_event_get_context(&event->base), 1506 event->base.type, 1507 0, 1508 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1509 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1510 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1511 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1512 1513 return evdev_device_transform_x(device, 1514 event->axes.point.x, 1515 width); 1516} 1517 1518LIBINPUT_EXPORT double 1519libinput_event_tablet_tool_get_y_transformed(struct libinput_event_tablet_tool *event, 1520 uint32_t height) 1521{ 1522 struct evdev_device *device = evdev_device(event->base.device); 1523 1524 require_event_type(libinput_event_get_context(&event->base), 1525 event->base.type, 1526 0, 1527 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1528 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1529 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1530 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1531 1532 return evdev_device_transform_y(device, 1533 event->axes.point.y, 1534 height); 1535} 1536 1537LIBINPUT_EXPORT struct libinput_tablet_tool * 1538libinput_event_tablet_tool_get_tool(struct libinput_event_tablet_tool *event) 1539{ 1540 require_event_type(libinput_event_get_context(&event->base), 1541 event->base.type, 1542 0, 1543 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1544 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1545 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1546 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1547 1548 return event->tool; 1549} 1550 1551LIBINPUT_EXPORT enum libinput_tablet_tool_proximity_state 1552libinput_event_tablet_tool_get_proximity_state(struct libinput_event_tablet_tool *event) 1553{ 1554 require_event_type(libinput_event_get_context(&event->base), 1555 event->base.type, 1556 0, 1557 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1558 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1559 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1560 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1561 1562 return event->proximity_state; 1563} 1564 1565LIBINPUT_EXPORT enum libinput_tablet_tool_tip_state 1566libinput_event_tablet_tool_get_tip_state(struct libinput_event_tablet_tool *event) 1567{ 1568 require_event_type(libinput_event_get_context(&event->base), 1569 event->base.type, 1570 0, 1571 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1572 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1573 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1574 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1575 1576 return event->tip_state; 1577} 1578 1579LIBINPUT_EXPORT uint32_t 1580libinput_event_tablet_tool_get_time(struct libinput_event_tablet_tool *event) 1581{ 1582 require_event_type(libinput_event_get_context(&event->base), 1583 event->base.type, 1584 0, 1585 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1586 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1587 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1588 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1589 1590 return us2ms(event->time); 1591} 1592 1593LIBINPUT_EXPORT uint64_t 1594libinput_event_tablet_tool_get_time_usec(struct libinput_event_tablet_tool *event) 1595{ 1596 require_event_type(libinput_event_get_context(&event->base), 1597 event->base.type, 1598 0, 1599 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 1600 LIBINPUT_EVENT_TABLET_TOOL_TIP, 1601 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 1602 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY); 1603 1604 return event->time; 1605} 1606 1607LIBINPUT_EXPORT uint32_t 1608libinput_event_tablet_tool_get_button(struct libinput_event_tablet_tool *event) 1609{ 1610 require_event_type(libinput_event_get_context(&event->base), 1611 event->base.type, 1612 0, 1613 LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 1614 1615 return event->button; 1616} 1617 1618LIBINPUT_EXPORT enum libinput_button_state 1619libinput_event_tablet_tool_get_button_state(struct libinput_event_tablet_tool *event) 1620{ 1621 require_event_type(libinput_event_get_context(&event->base), 1622 event->base.type, 1623 0, 1624 LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 1625 1626 return event->state; 1627} 1628 1629LIBINPUT_EXPORT uint32_t 1630libinput_event_tablet_tool_get_seat_button_count(struct libinput_event_tablet_tool *event) 1631{ 1632 require_event_type(libinput_event_get_context(&event->base), 1633 event->base.type, 1634 0, 1635 LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 1636 1637 return event->seat_button_count; 1638} 1639 1640LIBINPUT_EXPORT enum libinput_tablet_tool_type 1641libinput_tablet_tool_get_type(struct libinput_tablet_tool *tool) 1642{ 1643 return tool->type; 1644} 1645 1646LIBINPUT_EXPORT uint64_t 1647libinput_tablet_tool_get_tool_id(struct libinput_tablet_tool *tool) 1648{ 1649 return tool->tool_id; 1650} 1651 1652LIBINPUT_EXPORT int 1653libinput_tablet_tool_is_unique(struct libinput_tablet_tool *tool) 1654{ 1655 return tool->serial != 0; 1656} 1657 1658LIBINPUT_EXPORT uint64_t 1659libinput_tablet_tool_get_serial(struct libinput_tablet_tool *tool) 1660{ 1661 return tool->serial; 1662} 1663 1664LIBINPUT_EXPORT int 1665libinput_tablet_tool_has_pressure(struct libinput_tablet_tool *tool) 1666{ 1667 return bit_is_set(tool->axis_caps, 1668 LIBINPUT_TABLET_TOOL_AXIS_PRESSURE); 1669} 1670 1671LIBINPUT_EXPORT int 1672libinput_tablet_tool_has_distance(struct libinput_tablet_tool *tool) 1673{ 1674 return bit_is_set(tool->axis_caps, 1675 LIBINPUT_TABLET_TOOL_AXIS_DISTANCE); 1676} 1677 1678LIBINPUT_EXPORT int 1679libinput_tablet_tool_has_tilt(struct libinput_tablet_tool *tool) 1680{ 1681 return bit_is_set(tool->axis_caps, 1682 LIBINPUT_TABLET_TOOL_AXIS_TILT_X); 1683} 1684 1685LIBINPUT_EXPORT int 1686libinput_tablet_tool_has_rotation(struct libinput_tablet_tool *tool) 1687{ 1688 return bit_is_set(tool->axis_caps, 1689 LIBINPUT_TABLET_TOOL_AXIS_ROTATION_Z); 1690} 1691 1692LIBINPUT_EXPORT int 1693libinput_tablet_tool_has_slider(struct libinput_tablet_tool *tool) 1694{ 1695 return bit_is_set(tool->axis_caps, 1696 LIBINPUT_TABLET_TOOL_AXIS_SLIDER); 1697} 1698 1699LIBINPUT_EXPORT int 1700libinput_tablet_tool_has_wheel(struct libinput_tablet_tool *tool) 1701{ 1702 return bit_is_set(tool->axis_caps, 1703 LIBINPUT_TABLET_TOOL_AXIS_REL_WHEEL); 1704} 1705 1706LIBINPUT_EXPORT int 1707libinput_tablet_tool_has_size(struct libinput_tablet_tool *tool) 1708{ 1709 return bit_is_set(tool->axis_caps, 1710 LIBINPUT_TABLET_TOOL_AXIS_SIZE_MAJOR); 1711} 1712 1713LIBINPUT_EXPORT int 1714libinput_tablet_tool_has_button(struct libinput_tablet_tool *tool, 1715 uint32_t code) 1716{ 1717 if (NCHARS(code) > sizeof(tool->buttons)) 1718 return 0; 1719 1720 return bit_is_set(tool->buttons, code); 1721} 1722 1723LIBINPUT_EXPORT void 1724libinput_tablet_tool_set_user_data(struct libinput_tablet_tool *tool, 1725 void *user_data) 1726{ 1727 tool->user_data = user_data; 1728} 1729 1730LIBINPUT_EXPORT void * 1731libinput_tablet_tool_get_user_data(struct libinput_tablet_tool *tool) 1732{ 1733 return tool->user_data; 1734} 1735 1736LIBINPUT_EXPORT struct libinput_tablet_tool * 1737libinput_tablet_tool_ref(struct libinput_tablet_tool *tool) 1738{ 1739 tool->refcount++; 1740 return tool; 1741} 1742 1743LIBINPUT_EXPORT struct libinput_tablet_tool * 1744libinput_tablet_tool_unref(struct libinput_tablet_tool *tool) 1745{ 1746 assert(tool->refcount > 0); 1747 1748 tool->refcount--; 1749 if (tool->refcount > 0) 1750 return tool; 1751 1752 list_remove(&tool->link); 1753 free(tool); 1754 return NULL; 1755} 1756 1757LIBINPUT_EXPORT struct libinput_event * 1758libinput_event_switch_get_base_event(struct libinput_event_switch *event) 1759{ 1760 require_event_type(libinput_event_get_context(&event->base), 1761 event->base.type, 1762 NULL, 1763 LIBINPUT_EVENT_SWITCH_TOGGLE); 1764 1765 return &event->base; 1766} 1767 1768LIBINPUT_EXPORT enum libinput_switch 1769libinput_event_switch_get_switch(struct libinput_event_switch *event) 1770{ 1771 require_event_type(libinput_event_get_context(&event->base), 1772 event->base.type, 1773 0, 1774 LIBINPUT_EVENT_SWITCH_TOGGLE); 1775 1776 return event->sw; 1777} 1778 1779LIBINPUT_EXPORT enum libinput_switch_state 1780libinput_event_switch_get_switch_state(struct libinput_event_switch *event) 1781{ 1782 require_event_type(libinput_event_get_context(&event->base), 1783 event->base.type, 1784 0, 1785 LIBINPUT_EVENT_SWITCH_TOGGLE); 1786 1787 return event->state; 1788} 1789 1790LIBINPUT_EXPORT uint32_t 1791libinput_event_switch_get_time(struct libinput_event_switch *event) 1792{ 1793 require_event_type(libinput_event_get_context(&event->base), 1794 event->base.type, 1795 0, 1796 LIBINPUT_EVENT_SWITCH_TOGGLE); 1797 1798 return us2ms(event->time); 1799} 1800 1801LIBINPUT_EXPORT uint64_t 1802libinput_event_switch_get_time_usec(struct libinput_event_switch *event) 1803{ 1804 require_event_type(libinput_event_get_context(&event->base), 1805 event->base.type, 1806 0, 1807 LIBINPUT_EVENT_SWITCH_TOGGLE); 1808 1809 return event->time; 1810} 1811 1812struct libinput_source * 1813libinput_add_fd(struct libinput *libinput, 1814 int fd, 1815 libinput_source_dispatch_t dispatch, 1816 void *user_data) 1817{ 1818 struct libinput_source *source; 1819 struct epoll_event ep; 1820 1821 source = zalloc(sizeof *source); 1822 source->dispatch = dispatch; 1823 source->user_data = user_data; 1824 source->fd = fd; 1825 1826 memset(&ep, 0, sizeof ep); 1827 ep.events = EPOLLIN; 1828 ep.data.ptr = source; 1829 1830 if (epoll_ctl(libinput->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) { 1831 free(source); 1832 return NULL; 1833 } 1834 1835 return source; 1836} 1837 1838void 1839libinput_remove_source(struct libinput *libinput, 1840 struct libinput_source *source) 1841{ 1842 epoll_ctl(libinput->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL); 1843 source->fd = -1; 1844 list_insert(&libinput->source_destroy_list, &source->link); 1845} 1846 1847int 1848libinput_init(struct libinput *libinput, 1849 const struct libinput_interface *interface, 1850 const struct libinput_interface_backend *interface_backend, 1851 void *user_data) 1852{ 1853 assert(interface->open_restricted != NULL); 1854 assert(interface->close_restricted != NULL); 1855 1856 libinput->epoll_fd = epoll_create1(EPOLL_CLOEXEC); 1857 if (libinput->epoll_fd < 0) 1858 return -1; 1859 1860 libinput->events_len = 4; 1861 libinput->events = zalloc(libinput->events_len * sizeof(*libinput->events)); 1862 libinput->log_handler = libinput_default_log_func; 1863 libinput->log_priority = LIBINPUT_LOG_PRIORITY_ERROR; 1864 libinput->interface = interface; 1865 libinput->interface_backend = interface_backend; 1866 libinput->user_data = user_data; 1867 libinput->refcount = 1; 1868 list_init(&libinput->source_destroy_list); 1869 list_init(&libinput->seat_list); 1870 list_init(&libinput->device_group_list); 1871 list_init(&libinput->tool_list); 1872 1873 if (libinput_timer_subsys_init(libinput) != 0) { 1874 free(libinput->events); 1875 close(libinput->epoll_fd); 1876 return -1; 1877 } 1878 1879 return 0; 1880} 1881 1882void 1883libinput_init_quirks(struct libinput *libinput) 1884{ 1885 const char *data_path, 1886 *override_file = NULL; 1887 struct quirks_context *quirks; 1888 1889 if (libinput->quirks_initialized) 1890 return; 1891 1892 /* If we fail, we'll fail next time too */ 1893 libinput->quirks_initialized = true; 1894 1895 data_path = getenv("LIBINPUT_QUIRKS_DIR"); 1896 if (!data_path) { 1897 data_path = LIBINPUT_QUIRKS_DIR; 1898 override_file = LIBINPUT_QUIRKS_OVERRIDE_FILE; 1899 } 1900 1901 quirks = quirks_init_subsystem(data_path, 1902 override_file, 1903 log_msg_va, 1904 libinput, 1905 QLOG_LIBINPUT_LOGGING); 1906 if (!quirks) { 1907 log_error(libinput, 1908 "Failed to load the device quirks from %s%s%s. " 1909 "This will negatively affect device behavior. " 1910 "See %s/device-quirks.html for details.\n", 1911 data_path, 1912 override_file ? " and " : "", 1913 override_file ? override_file : "", 1914 HTTP_DOC_LINK 1915 ); 1916 return; 1917 } 1918 1919 libinput->quirks = quirks; 1920} 1921 1922static void 1923libinput_device_destroy(struct libinput_device *device); 1924 1925static void 1926libinput_seat_destroy(struct libinput_seat *seat); 1927 1928static void 1929libinput_drop_destroyed_sources(struct libinput *libinput) 1930{ 1931 struct libinput_source *source; 1932 1933 list_for_each_safe(source, &libinput->source_destroy_list, link) 1934 free(source); 1935 list_init(&libinput->source_destroy_list); 1936} 1937 1938LIBINPUT_EXPORT struct libinput * 1939libinput_ref(struct libinput *libinput) 1940{ 1941 libinput->refcount++; 1942 return libinput; 1943} 1944 1945LIBINPUT_EXPORT struct libinput * 1946libinput_unref(struct libinput *libinput) 1947{ 1948 struct libinput_event *event; 1949 struct libinput_device *device; 1950 struct libinput_seat *seat; 1951 struct libinput_tablet_tool *tool; 1952 struct libinput_device_group *group; 1953 1954 if (libinput == NULL) 1955 return NULL; 1956 1957 assert(libinput->refcount > 0); 1958 libinput->refcount--; 1959 if (libinput->refcount > 0) 1960 return libinput; 1961 1962 libinput_suspend(libinput); 1963 1964 libinput->interface_backend->destroy(libinput); 1965 1966 while ((event = libinput_get_event(libinput))) 1967 libinput_event_destroy(event); 1968 1969 free(libinput->events); 1970 1971 list_for_each_safe(seat, &libinput->seat_list, link) { 1972 list_for_each_safe(device, 1973 &seat->devices_list, 1974 link) 1975 libinput_device_destroy(device); 1976 1977 libinput_seat_destroy(seat); 1978 } 1979 1980 list_for_each_safe(group, 1981 &libinput->device_group_list, 1982 link) { 1983 libinput_device_group_destroy(group); 1984 } 1985 1986 list_for_each_safe(tool, &libinput->tool_list, link) { 1987 libinput_tablet_tool_unref(tool); 1988 } 1989 1990 libinput_timer_subsys_destroy(libinput); 1991 libinput_drop_destroyed_sources(libinput); 1992 quirks_context_unref(libinput->quirks); 1993 close(libinput->epoll_fd); 1994 free(libinput); 1995 1996 return NULL; 1997} 1998 1999static void 2000libinput_event_tablet_tool_destroy(struct libinput_event_tablet_tool *event) 2001{ 2002 libinput_tablet_tool_unref(event->tool); 2003} 2004 2005static void 2006libinput_event_tablet_pad_destroy(struct libinput_event_tablet_pad *event) 2007{ 2008 if (event->base.type != LIBINPUT_EVENT_TABLET_PAD_KEY) 2009 libinput_tablet_pad_mode_group_unref(event->mode_group); 2010} 2011 2012LIBINPUT_EXPORT void 2013libinput_event_destroy(struct libinput_event *event) 2014{ 2015 if (event == NULL) 2016 return; 2017 2018 switch(event->type) { 2019 case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: 2020 case LIBINPUT_EVENT_TABLET_TOOL_AXIS: 2021 case LIBINPUT_EVENT_TABLET_TOOL_TIP: 2022 case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: 2023 libinput_event_tablet_tool_destroy( 2024 libinput_event_get_tablet_tool_event(event)); 2025 break; 2026 case LIBINPUT_EVENT_TABLET_PAD_RING: 2027 case LIBINPUT_EVENT_TABLET_PAD_STRIP: 2028 case LIBINPUT_EVENT_TABLET_PAD_BUTTON: 2029 case LIBINPUT_EVENT_TABLET_PAD_KEY: 2030 libinput_event_tablet_pad_destroy( 2031 libinput_event_get_tablet_pad_event(event)); 2032 break; 2033 default: 2034 break; 2035 } 2036 2037 if (event->device) 2038 libinput_device_unref(event->device); 2039 2040 free(event); 2041} 2042 2043int 2044open_restricted(struct libinput *libinput, 2045 const char *path, int flags) 2046{ 2047 return libinput->interface->open_restricted(path, 2048 flags, 2049 libinput->user_data); 2050} 2051 2052void 2053close_restricted(struct libinput *libinput, int fd) 2054{ 2055 libinput->interface->close_restricted(fd, libinput->user_data); 2056} 2057 2058bool 2059ignore_litest_test_suite_device(struct udev_device *device) 2060{ 2061 if (!getenv("LIBINPUT_RUNNING_TEST_SUITE") && 2062 udev_device_get_property_value(device, "LIBINPUT_TEST_DEVICE")) 2063 return true; 2064 2065 return false; 2066} 2067 2068void 2069libinput_seat_init(struct libinput_seat *seat, 2070 struct libinput *libinput, 2071 const char *physical_name, 2072 const char *logical_name, 2073 libinput_seat_destroy_func destroy) 2074{ 2075 seat->refcount = 1; 2076 seat->libinput = libinput; 2077 seat->physical_name = safe_strdup(physical_name); 2078 seat->logical_name = safe_strdup(logical_name); 2079 seat->destroy = destroy; 2080 list_init(&seat->devices_list); 2081 list_insert(&libinput->seat_list, &seat->link); 2082} 2083 2084LIBINPUT_EXPORT struct libinput_seat * 2085libinput_seat_ref(struct libinput_seat *seat) 2086{ 2087 seat->refcount++; 2088 return seat; 2089} 2090 2091static void 2092libinput_seat_destroy(struct libinput_seat *seat) 2093{ 2094 list_remove(&seat->link); 2095 free(seat->logical_name); 2096 free(seat->physical_name); 2097 seat->destroy(seat); 2098} 2099 2100LIBINPUT_EXPORT struct libinput_seat * 2101libinput_seat_unref(struct libinput_seat *seat) 2102{ 2103 assert(seat->refcount > 0); 2104 seat->refcount--; 2105 if (seat->refcount == 0) { 2106 libinput_seat_destroy(seat); 2107 return NULL; 2108 } 2109 2110 return seat; 2111} 2112 2113LIBINPUT_EXPORT void 2114libinput_seat_set_user_data(struct libinput_seat *seat, void *user_data) 2115{ 2116 seat->user_data = user_data; 2117} 2118 2119LIBINPUT_EXPORT void * 2120libinput_seat_get_user_data(struct libinput_seat *seat) 2121{ 2122 return seat->user_data; 2123} 2124 2125LIBINPUT_EXPORT struct libinput * 2126libinput_seat_get_context(struct libinput_seat *seat) 2127{ 2128 return seat->libinput; 2129} 2130 2131LIBINPUT_EXPORT const char * 2132libinput_seat_get_physical_name(struct libinput_seat *seat) 2133{ 2134 return seat->physical_name; 2135} 2136 2137LIBINPUT_EXPORT const char * 2138libinput_seat_get_logical_name(struct libinput_seat *seat) 2139{ 2140 return seat->logical_name; 2141} 2142 2143void 2144libinput_device_init(struct libinput_device *device, 2145 struct libinput_seat *seat) 2146{ 2147 device->seat = seat; 2148 device->refcount = 1; 2149 list_init(&device->event_listeners); 2150} 2151 2152LIBINPUT_EXPORT struct libinput_device * 2153libinput_device_ref(struct libinput_device *device) 2154{ 2155 device->refcount++; 2156 return device; 2157} 2158 2159static void 2160libinput_device_destroy(struct libinput_device *device) 2161{ 2162 assert(list_empty(&device->event_listeners)); 2163 evdev_device_destroy(evdev_device(device)); 2164} 2165 2166LIBINPUT_EXPORT struct libinput_device * 2167libinput_device_unref(struct libinput_device *device) 2168{ 2169 assert(device->refcount > 0); 2170 device->refcount--; 2171 if (device->refcount == 0) { 2172 libinput_device_destroy(device); 2173 return NULL; 2174 } 2175 2176 return device; 2177} 2178 2179LIBINPUT_EXPORT int 2180libinput_get_fd(struct libinput *libinput) 2181{ 2182 return libinput->epoll_fd; 2183} 2184 2185LIBINPUT_EXPORT int 2186libinput_dispatch(struct libinput *libinput) 2187{ 2188 static uint8_t take_time_snapshot; 2189 struct libinput_source *source; 2190 struct epoll_event ep[32]; 2191 int i, count; 2192 2193 /* Every 10 calls to libinput_dispatch() we take the current time so 2194 * we can check the delay between our current time and the event 2195 * timestamps */ 2196 if ((++take_time_snapshot % 10) == 0) 2197 libinput->dispatch_time = libinput_now(libinput); 2198 else if (libinput->dispatch_time) 2199 libinput->dispatch_time = 0; 2200 2201 count = epoll_wait(libinput->epoll_fd, ep, ARRAY_LENGTH(ep), 0); 2202 if (count < 0) 2203 return -errno; 2204 2205 for (i = 0; i < count; ++i) { 2206 source = ep[i].data.ptr; 2207 if (source->fd == -1) 2208 continue; 2209 2210 source->dispatch(source->user_data); 2211 } 2212 2213 libinput_drop_destroyed_sources(libinput); 2214 2215 return 0; 2216} 2217 2218void 2219libinput_device_init_event_listener(struct libinput_event_listener *listener) 2220{ 2221 list_init(&listener->link); 2222} 2223 2224void 2225libinput_device_add_event_listener(struct libinput_device *device, 2226 struct libinput_event_listener *listener, 2227 void (*notify_func)( 2228 uint64_t time, 2229 struct libinput_event *event, 2230 void *notify_func_data), 2231 void *notify_func_data) 2232{ 2233 listener->notify_func = notify_func; 2234 listener->notify_func_data = notify_func_data; 2235 list_insert(&device->event_listeners, &listener->link); 2236} 2237 2238void 2239libinput_device_remove_event_listener(struct libinput_event_listener *listener) 2240{ 2241 list_remove(&listener->link); 2242} 2243 2244static uint32_t 2245update_seat_key_count(struct libinput_seat *seat, 2246 int32_t key, 2247 enum libinput_key_state state) 2248{ 2249 assert(key >= 0 && key <= KEY_MAX); 2250 2251 switch (state) { 2252 case LIBINPUT_KEY_STATE_PRESSED: 2253 return ++seat->button_count[key]; 2254 case LIBINPUT_KEY_STATE_RELEASED: 2255 /* We might not have received the first PRESSED event. */ 2256 if (seat->button_count[key] == 0) 2257 return 0; 2258 2259 return --seat->button_count[key]; 2260 } 2261 2262 return 0; 2263} 2264 2265static uint32_t 2266update_seat_button_count(struct libinput_seat *seat, 2267 int32_t button, 2268 enum libinput_button_state state) 2269{ 2270 assert(button >= 0 && button <= KEY_MAX); 2271 2272 switch (state) { 2273 case LIBINPUT_BUTTON_STATE_PRESSED: 2274 return ++seat->button_count[button]; 2275 case LIBINPUT_BUTTON_STATE_RELEASED: 2276 /* We might not have received the first PRESSED event. */ 2277 if (seat->button_count[button] == 0) 2278 return 0; 2279 2280 return --seat->button_count[button]; 2281 } 2282 2283 return 0; 2284} 2285 2286static void 2287init_event_base(struct libinput_event *event, 2288 struct libinput_device *device, 2289 enum libinput_event_type type) 2290{ 2291 event->type = type; 2292 event->device = device; 2293} 2294 2295static void 2296post_base_event(struct libinput_device *device, 2297 enum libinput_event_type type, 2298 struct libinput_event *event) 2299{ 2300 struct libinput *libinput = device->seat->libinput; 2301 init_event_base(event, device, type); 2302 libinput_post_event(libinput, event); 2303} 2304 2305static void 2306post_device_event(struct libinput_device *device, 2307 uint64_t time, 2308 enum libinput_event_type type, 2309 struct libinput_event *event) 2310{ 2311 struct libinput_event_listener *listener; 2312#if 0 2313 struct libinput *libinput = device->seat->libinput; 2314 2315 if (libinput->last_event_time > time) { 2316 log_bug_libinput(device->seat->libinput, 2317 "out-of-order timestamps for %s time %" PRIu64 "\n", 2318 event_type_to_str(type), 2319 time); 2320 } 2321 libinput->last_event_time = time; 2322#endif 2323 2324 init_event_base(event, device, type); 2325 2326 list_for_each_safe(listener, &device->event_listeners, link) 2327 listener->notify_func(time, event, listener->notify_func_data); 2328 2329 libinput_post_event(device->seat->libinput, event); 2330} 2331 2332void 2333notify_added_device(struct libinput_device *device) 2334{ 2335 struct libinput_event_device_notify *added_device_event; 2336 2337 added_device_event = zalloc(sizeof *added_device_event); 2338 2339 post_base_event(device, 2340 LIBINPUT_EVENT_DEVICE_ADDED, 2341 &added_device_event->base); 2342 2343#ifdef __clang_analyzer__ 2344 /* clang doesn't realize we're not leaking the event here, so 2345 * pretend to free it */ 2346 free(added_device_event); 2347#endif 2348} 2349 2350void 2351notify_removed_device(struct libinput_device *device) 2352{ 2353 struct libinput_event_device_notify *removed_device_event; 2354 2355 removed_device_event = zalloc(sizeof *removed_device_event); 2356 2357 post_base_event(device, 2358 LIBINPUT_EVENT_DEVICE_REMOVED, 2359 &removed_device_event->base); 2360 2361#ifdef __clang_analyzer__ 2362 /* clang doesn't realize we're not leaking the event here, so 2363 * pretend to free it */ 2364 free(removed_device_event); 2365#endif 2366} 2367 2368static inline bool 2369device_has_cap(struct libinput_device *device, 2370 enum libinput_device_capability cap) 2371{ 2372 const char *capability; 2373 2374 if (libinput_device_has_capability(device, cap)) 2375 return true; 2376 2377 switch (cap) { 2378 case LIBINPUT_DEVICE_CAP_POINTER: 2379 capability = "CAP_POINTER"; 2380 break; 2381 case LIBINPUT_DEVICE_CAP_KEYBOARD: 2382 capability = "CAP_KEYBOARD"; 2383 break; 2384 case LIBINPUT_DEVICE_CAP_TOUCH: 2385 capability = "CAP_TOUCH"; 2386 break; 2387 case LIBINPUT_DEVICE_CAP_GESTURE: 2388 capability = "CAP_GESTURE"; 2389 break; 2390 case LIBINPUT_DEVICE_CAP_TABLET_TOOL: 2391 capability = "CAP_TABLET_TOOL"; 2392 break; 2393 case LIBINPUT_DEVICE_CAP_TABLET_PAD: 2394 capability = "CAP_TABLET_PAD"; 2395 break; 2396 case LIBINPUT_DEVICE_CAP_SWITCH: 2397 capability = "CAP_SWITCH"; 2398 break; 2399 } 2400 2401 log_bug_libinput(device->seat->libinput, 2402 "Event for missing capability %s on device \"%s\"\n", 2403 capability, 2404 libinput_device_get_name(device)); 2405 2406 return false; 2407} 2408 2409void 2410keyboard_notify_key(struct libinput_device *device, 2411 uint64_t time, 2412 uint32_t key, 2413 enum libinput_key_state state) 2414{ 2415 struct libinput_event_keyboard *key_event; 2416 uint32_t seat_key_count; 2417 2418 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_KEYBOARD)) 2419 return; 2420 2421 key_event = zalloc(sizeof *key_event); 2422 2423 seat_key_count = update_seat_key_count(device->seat, key, state); 2424 2425 *key_event = (struct libinput_event_keyboard) { 2426 .time = time, 2427 .key = key, 2428 .state = state, 2429 .seat_key_count = seat_key_count, 2430 }; 2431 2432 post_device_event(device, time, 2433 LIBINPUT_EVENT_KEYBOARD_KEY, 2434 &key_event->base); 2435} 2436 2437void 2438pointer_notify_motion(struct libinput_device *device, 2439 uint64_t time, 2440 const struct normalized_coords *delta, 2441 const struct device_float_coords *raw) 2442{ 2443 struct libinput_event_pointer *motion_event; 2444 2445 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2446 return; 2447 2448 motion_event = zalloc(sizeof *motion_event); 2449 2450 *motion_event = (struct libinput_event_pointer) { 2451 .time = time, 2452 .delta = *delta, 2453 .delta_raw = *raw, 2454 }; 2455 2456 post_device_event(device, time, 2457 LIBINPUT_EVENT_POINTER_MOTION, 2458 &motion_event->base); 2459} 2460 2461void 2462pointer_notify_motion_absolute(struct libinput_device *device, 2463 uint64_t time, 2464 const struct device_coords *point) 2465{ 2466 struct libinput_event_pointer *motion_absolute_event; 2467 2468 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2469 return; 2470 2471 motion_absolute_event = zalloc(sizeof *motion_absolute_event); 2472 2473 *motion_absolute_event = (struct libinput_event_pointer) { 2474 .time = time, 2475 .absolute = *point, 2476 }; 2477 2478 post_device_event(device, time, 2479 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, 2480 &motion_absolute_event->base); 2481} 2482 2483void 2484pointer_notify_button(struct libinput_device *device, 2485 uint64_t time, 2486 int32_t button, 2487 enum libinput_button_state state) 2488{ 2489 struct libinput_event_pointer *button_event; 2490 int32_t seat_button_count; 2491 2492 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2493 return; 2494 2495 button_event = zalloc(sizeof *button_event); 2496 2497 seat_button_count = update_seat_button_count(device->seat, 2498 button, 2499 state); 2500 2501 *button_event = (struct libinput_event_pointer) { 2502 .time = time, 2503 .button = button, 2504 .state = state, 2505 .seat_button_count = seat_button_count, 2506 }; 2507 2508 post_device_event(device, time, 2509 LIBINPUT_EVENT_POINTER_BUTTON, 2510 &button_event->base); 2511} 2512 2513void 2514pointer_notify_axis_finger(struct libinput_device *device, 2515 uint64_t time, 2516 uint32_t axes, 2517 const struct normalized_coords *delta) 2518{ 2519 struct libinput_event_pointer *axis_event, *axis_event_legacy; 2520 const struct discrete_coords zero_discrete = {0}; 2521 const struct wheel_v120 zero_v120 = {0}; 2522 2523 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2524 return; 2525 2526 axis_event = zalloc(sizeof *axis_event); 2527 axis_event_legacy = zalloc(sizeof *axis_event_legacy); 2528 2529 *axis_event = (struct libinput_event_pointer) { 2530 .time = time, 2531 .delta = *delta, 2532 .source = LIBINPUT_POINTER_AXIS_SOURCE_FINGER, 2533 .axes = axes, 2534 .discrete = zero_discrete, 2535 .v120 = zero_v120, 2536 }; 2537 *axis_event_legacy = *axis_event; 2538 2539 post_device_event(device, time, 2540 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 2541 &axis_event->base); 2542 post_device_event(device, time, 2543 LIBINPUT_EVENT_POINTER_AXIS, 2544 &axis_event_legacy->base); 2545} 2546 2547void 2548pointer_notify_axis_continuous(struct libinput_device *device, 2549 uint64_t time, 2550 uint32_t axes, 2551 const struct normalized_coords *delta) 2552{ 2553 struct libinput_event_pointer *axis_event, *axis_event_legacy; 2554 const struct discrete_coords zero_discrete = {0}; 2555 const struct wheel_v120 zero_v120 = {0}; 2556 2557 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2558 return; 2559 2560 axis_event = zalloc(sizeof *axis_event); 2561 axis_event_legacy = zalloc(sizeof *axis_event_legacy); 2562 2563 *axis_event = (struct libinput_event_pointer) { 2564 .time = time, 2565 .delta = *delta, 2566 .source = LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, 2567 .axes = axes, 2568 .discrete = zero_discrete, 2569 .v120 = zero_v120, 2570 }; 2571 *axis_event_legacy = *axis_event; 2572 2573 post_device_event(device, time, 2574 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 2575 &axis_event->base); 2576 post_device_event(device, time, 2577 LIBINPUT_EVENT_POINTER_AXIS, 2578 &axis_event_legacy->base); 2579} 2580 2581void 2582pointer_notify_axis_legacy_wheel(struct libinput_device *device, 2583 uint64_t time, 2584 uint32_t axes, 2585 const struct normalized_coords *delta, 2586 const struct discrete_coords *discrete) 2587{ 2588 struct libinput_event_pointer *axis_event; 2589 const struct wheel_v120 zero_v120 = {0}; 2590 2591 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2592 return; 2593 2594 axis_event = zalloc(sizeof *axis_event); 2595 2596 *axis_event = (struct libinput_event_pointer) { 2597 .time = time, 2598 .delta = *delta, 2599 .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, 2600 .axes = axes, 2601 .discrete = *discrete, 2602 .v120 = zero_v120, 2603 }; 2604 2605 post_device_event(device, time, 2606 LIBINPUT_EVENT_POINTER_AXIS, 2607 &axis_event->base); 2608} 2609 2610void 2611pointer_notify_axis_wheel(struct libinput_device *device, 2612 uint64_t time, 2613 uint32_t axes, 2614 const struct normalized_coords *delta, 2615 const struct wheel_v120 *v120) 2616{ 2617 struct libinput_event_pointer *axis_event; 2618 2619 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER)) 2620 return; 2621 2622 axis_event = zalloc(sizeof *axis_event); 2623 2624 *axis_event = (struct libinput_event_pointer) { 2625 .time = time, 2626 .delta = *delta, 2627 .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, 2628 .axes = axes, 2629 .discrete.x = 0, 2630 .discrete.y = 0, 2631 .v120 = *v120, 2632 }; 2633 2634 post_device_event(device, time, 2635 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 2636 &axis_event->base); 2637 2638 /* legacy wheel events are sent separately */ 2639} 2640 2641void 2642touch_notify_touch_down(struct libinput_device *device, 2643 uint64_t time, 2644 int32_t slot, 2645 int32_t seat_slot, 2646 const struct device_coords *point) 2647{ 2648 struct libinput_event_touch *touch_event; 2649 2650 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) 2651 return; 2652 2653 touch_event = zalloc(sizeof *touch_event); 2654 2655 *touch_event = (struct libinput_event_touch) { 2656 .time = time, 2657 .slot = slot, 2658 .seat_slot = seat_slot, 2659 .point = *point, 2660 }; 2661 2662 post_device_event(device, time, 2663 LIBINPUT_EVENT_TOUCH_DOWN, 2664 &touch_event->base); 2665} 2666 2667void 2668touch_notify_touch_motion(struct libinput_device *device, 2669 uint64_t time, 2670 int32_t slot, 2671 int32_t seat_slot, 2672 const struct device_coords *point) 2673{ 2674 struct libinput_event_touch *touch_event; 2675 2676 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) 2677 return; 2678 2679 touch_event = zalloc(sizeof *touch_event); 2680 2681 *touch_event = (struct libinput_event_touch) { 2682 .time = time, 2683 .slot = slot, 2684 .seat_slot = seat_slot, 2685 .point = *point, 2686 }; 2687 2688 post_device_event(device, time, 2689 LIBINPUT_EVENT_TOUCH_MOTION, 2690 &touch_event->base); 2691} 2692 2693void 2694touch_notify_touch_up(struct libinput_device *device, 2695 uint64_t time, 2696 int32_t slot, 2697 int32_t seat_slot) 2698{ 2699 struct libinput_event_touch *touch_event; 2700 2701 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) 2702 return; 2703 2704 touch_event = zalloc(sizeof *touch_event); 2705 2706 *touch_event = (struct libinput_event_touch) { 2707 .time = time, 2708 .slot = slot, 2709 .seat_slot = seat_slot, 2710 }; 2711 2712 post_device_event(device, time, 2713 LIBINPUT_EVENT_TOUCH_UP, 2714 &touch_event->base); 2715} 2716 2717void 2718touch_notify_touch_cancel(struct libinput_device *device, 2719 uint64_t time, 2720 int32_t slot, 2721 int32_t seat_slot) 2722{ 2723 struct libinput_event_touch *touch_event; 2724 2725 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) 2726 return; 2727 2728 touch_event = zalloc(sizeof *touch_event); 2729 2730 *touch_event = (struct libinput_event_touch) { 2731 .time = time, 2732 .slot = slot, 2733 .seat_slot = seat_slot, 2734 }; 2735 2736 post_device_event(device, time, 2737 LIBINPUT_EVENT_TOUCH_CANCEL, 2738 &touch_event->base); 2739} 2740 2741void 2742touch_notify_frame(struct libinput_device *device, 2743 uint64_t time) 2744{ 2745 struct libinput_event_touch *touch_event; 2746 2747 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_TOUCH)) 2748 return; 2749 2750 touch_event = zalloc(sizeof *touch_event); 2751 2752 *touch_event = (struct libinput_event_touch) { 2753 .time = time, 2754 }; 2755 2756 post_device_event(device, time, 2757 LIBINPUT_EVENT_TOUCH_FRAME, 2758 &touch_event->base); 2759} 2760 2761void 2762tablet_notify_axis(struct libinput_device *device, 2763 uint64_t time, 2764 struct libinput_tablet_tool *tool, 2765 enum libinput_tablet_tool_tip_state tip_state, 2766 unsigned char *changed_axes, 2767 const struct tablet_axes *axes) 2768{ 2769 struct libinput_event_tablet_tool *axis_event; 2770 2771 axis_event = zalloc(sizeof *axis_event); 2772 2773 *axis_event = (struct libinput_event_tablet_tool) { 2774 .time = time, 2775 .tool = libinput_tablet_tool_ref(tool), 2776 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, 2777 .tip_state = tip_state, 2778 .axes = *axes, 2779 }; 2780 2781 memcpy(axis_event->changed_axes, 2782 changed_axes, 2783 sizeof(axis_event->changed_axes)); 2784 2785 post_device_event(device, 2786 time, 2787 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 2788 &axis_event->base); 2789} 2790 2791void 2792tablet_notify_proximity(struct libinput_device *device, 2793 uint64_t time, 2794 struct libinput_tablet_tool *tool, 2795 enum libinput_tablet_tool_proximity_state proximity_state, 2796 unsigned char *changed_axes, 2797 const struct tablet_axes *axes) 2798{ 2799 struct libinput_event_tablet_tool *proximity_event; 2800 2801 proximity_event = zalloc(sizeof *proximity_event); 2802 2803 *proximity_event = (struct libinput_event_tablet_tool) { 2804 .time = time, 2805 .tool = libinput_tablet_tool_ref(tool), 2806 .tip_state = LIBINPUT_TABLET_TOOL_TIP_UP, 2807 .proximity_state = proximity_state, 2808 .axes = *axes, 2809 }; 2810 memcpy(proximity_event->changed_axes, 2811 changed_axes, 2812 sizeof(proximity_event->changed_axes)); 2813 2814 post_device_event(device, 2815 time, 2816 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, 2817 &proximity_event->base); 2818} 2819 2820void 2821tablet_notify_tip(struct libinput_device *device, 2822 uint64_t time, 2823 struct libinput_tablet_tool *tool, 2824 enum libinput_tablet_tool_tip_state tip_state, 2825 unsigned char *changed_axes, 2826 const struct tablet_axes *axes) 2827{ 2828 struct libinput_event_tablet_tool *tip_event; 2829 2830 tip_event = zalloc(sizeof *tip_event); 2831 2832 *tip_event = (struct libinput_event_tablet_tool) { 2833 .time = time, 2834 .tool = libinput_tablet_tool_ref(tool), 2835 .tip_state = tip_state, 2836 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, 2837 .axes = *axes, 2838 }; 2839 memcpy(tip_event->changed_axes, 2840 changed_axes, 2841 sizeof(tip_event->changed_axes)); 2842 2843 post_device_event(device, 2844 time, 2845 LIBINPUT_EVENT_TABLET_TOOL_TIP, 2846 &tip_event->base); 2847} 2848 2849void 2850tablet_notify_button(struct libinput_device *device, 2851 uint64_t time, 2852 struct libinput_tablet_tool *tool, 2853 enum libinput_tablet_tool_tip_state tip_state, 2854 const struct tablet_axes *axes, 2855 int32_t button, 2856 enum libinput_button_state state) 2857{ 2858 struct libinput_event_tablet_tool *button_event; 2859 int32_t seat_button_count; 2860 2861 button_event = zalloc(sizeof *button_event); 2862 2863 seat_button_count = update_seat_button_count(device->seat, 2864 button, 2865 state); 2866 2867 *button_event = (struct libinput_event_tablet_tool) { 2868 .time = time, 2869 .tool = libinput_tablet_tool_ref(tool), 2870 .button = button, 2871 .state = state, 2872 .seat_button_count = seat_button_count, 2873 .proximity_state = LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN, 2874 .tip_state = tip_state, 2875 .axes = *axes, 2876 }; 2877 2878 post_device_event(device, 2879 time, 2880 LIBINPUT_EVENT_TABLET_TOOL_BUTTON, 2881 &button_event->base); 2882} 2883 2884void 2885tablet_pad_notify_button(struct libinput_device *device, 2886 uint64_t time, 2887 int32_t button, 2888 enum libinput_button_state state, 2889 struct libinput_tablet_pad_mode_group *group) 2890{ 2891 struct libinput_event_tablet_pad *button_event; 2892 unsigned int mode; 2893 2894 button_event = zalloc(sizeof *button_event); 2895 2896 mode = libinput_tablet_pad_mode_group_get_mode(group); 2897 2898 *button_event = (struct libinput_event_tablet_pad) { 2899 .time = time, 2900 .button.number = button, 2901 .button.state = state, 2902 .mode_group = libinput_tablet_pad_mode_group_ref(group), 2903 .mode = mode, 2904 }; 2905 2906 post_device_event(device, 2907 time, 2908 LIBINPUT_EVENT_TABLET_PAD_BUTTON, 2909 &button_event->base); 2910} 2911 2912void 2913tablet_pad_notify_ring(struct libinput_device *device, 2914 uint64_t time, 2915 unsigned int number, 2916 double value, 2917 enum libinput_tablet_pad_ring_axis_source source, 2918 struct libinput_tablet_pad_mode_group *group) 2919{ 2920 struct libinput_event_tablet_pad *ring_event; 2921 unsigned int mode; 2922 2923 ring_event = zalloc(sizeof *ring_event); 2924 2925 mode = libinput_tablet_pad_mode_group_get_mode(group); 2926 2927 *ring_event = (struct libinput_event_tablet_pad) { 2928 .time = time, 2929 .ring.number = number, 2930 .ring.position = value, 2931 .ring.source = source, 2932 .mode_group = libinput_tablet_pad_mode_group_ref(group), 2933 .mode = mode, 2934 }; 2935 2936 post_device_event(device, 2937 time, 2938 LIBINPUT_EVENT_TABLET_PAD_RING, 2939 &ring_event->base); 2940} 2941 2942void 2943tablet_pad_notify_strip(struct libinput_device *device, 2944 uint64_t time, 2945 unsigned int number, 2946 double value, 2947 enum libinput_tablet_pad_strip_axis_source source, 2948 struct libinput_tablet_pad_mode_group *group) 2949{ 2950 struct libinput_event_tablet_pad *strip_event; 2951 unsigned int mode; 2952 2953 strip_event = zalloc(sizeof *strip_event); 2954 2955 mode = libinput_tablet_pad_mode_group_get_mode(group); 2956 2957 *strip_event = (struct libinput_event_tablet_pad) { 2958 .time = time, 2959 .strip.number = number, 2960 .strip.position = value, 2961 .strip.source = source, 2962 .mode_group = libinput_tablet_pad_mode_group_ref(group), 2963 .mode = mode, 2964 }; 2965 2966 post_device_event(device, 2967 time, 2968 LIBINPUT_EVENT_TABLET_PAD_STRIP, 2969 &strip_event->base); 2970} 2971 2972void 2973tablet_pad_notify_key(struct libinput_device *device, 2974 uint64_t time, 2975 int32_t key, 2976 enum libinput_key_state state) 2977{ 2978 struct libinput_event_tablet_pad *key_event; 2979 2980 key_event = zalloc(sizeof *key_event); 2981 2982 *key_event = (struct libinput_event_tablet_pad) { 2983 .time = time, 2984 .key.code = key, 2985 .key.state = state, 2986 }; 2987 2988 post_device_event(device, 2989 time, 2990 LIBINPUT_EVENT_TABLET_PAD_KEY, 2991 &key_event->base); 2992} 2993 2994static void 2995gesture_notify(struct libinput_device *device, 2996 uint64_t time, 2997 enum libinput_event_type type, 2998 int finger_count, 2999 bool cancelled, 3000 const struct normalized_coords *delta, 3001 const struct normalized_coords *unaccel, 3002 double scale, 3003 double angle) 3004{ 3005 struct libinput_event_gesture *gesture_event; 3006 3007 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_GESTURE)) 3008 return; 3009 3010 gesture_event = zalloc(sizeof *gesture_event); 3011 3012 *gesture_event = (struct libinput_event_gesture) { 3013 .time = time, 3014 .finger_count = finger_count, 3015 .cancelled = cancelled, 3016 .delta = *delta, 3017 .delta_unaccel = *unaccel, 3018 .scale = scale, 3019 .angle = angle, 3020 }; 3021 3022 post_device_event(device, time, type, 3023 &gesture_event->base); 3024} 3025 3026void 3027gesture_notify_swipe(struct libinput_device *device, 3028 uint64_t time, 3029 enum libinput_event_type type, 3030 int finger_count, 3031 const struct normalized_coords *delta, 3032 const struct normalized_coords *unaccel) 3033{ 3034 gesture_notify(device, time, type, finger_count, 0, delta, unaccel, 3035 0.0, 0.0); 3036} 3037 3038void 3039gesture_notify_swipe_end(struct libinput_device *device, 3040 uint64_t time, 3041 int finger_count, 3042 bool cancelled) 3043{ 3044 const struct normalized_coords zero = { 0.0, 0.0 }; 3045 3046 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_SWIPE_END, 3047 finger_count, cancelled, &zero, &zero, 0.0, 0.0); 3048} 3049 3050void 3051gesture_notify_pinch(struct libinput_device *device, 3052 uint64_t time, 3053 enum libinput_event_type type, 3054 int finger_count, 3055 const struct normalized_coords *delta, 3056 const struct normalized_coords *unaccel, 3057 double scale, 3058 double angle) 3059{ 3060 gesture_notify(device, time, type, finger_count, 0, 3061 delta, unaccel, scale, angle); 3062} 3063 3064void 3065gesture_notify_pinch_end(struct libinput_device *device, 3066 uint64_t time, 3067 int finger_count, 3068 double scale, 3069 bool cancelled) 3070{ 3071 const struct normalized_coords zero = { 0.0, 0.0 }; 3072 3073 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_PINCH_END, 3074 finger_count, cancelled, &zero, &zero, scale, 0.0); 3075} 3076 3077void 3078gesture_notify_hold(struct libinput_device *device, 3079 uint64_t time, 3080 int finger_count) 3081{ 3082 const struct normalized_coords zero = { 0.0, 0.0 }; 3083 3084 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 3085 finger_count, 0, &zero, &zero, 0.0, 0.0); 3086} 3087 3088void 3089gesture_notify_hold_end(struct libinput_device *device, 3090 uint64_t time, 3091 int finger_count, 3092 bool cancelled) 3093{ 3094 const struct normalized_coords zero = { 0.0, 0.0 }; 3095 3096 gesture_notify(device, time, LIBINPUT_EVENT_GESTURE_HOLD_END, 3097 finger_count, cancelled, &zero, &zero, 0, 0.0); 3098} 3099 3100void 3101switch_notify_toggle(struct libinput_device *device, 3102 uint64_t time, 3103 enum libinput_switch sw, 3104 enum libinput_switch_state state) 3105{ 3106 struct libinput_event_switch *switch_event; 3107 3108 if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_SWITCH)) 3109 return; 3110 3111 switch_event = zalloc(sizeof *switch_event); 3112 3113 *switch_event = (struct libinput_event_switch) { 3114 .time = time, 3115 .sw = sw, 3116 .state = state, 3117 }; 3118 3119 post_device_event(device, time, 3120 LIBINPUT_EVENT_SWITCH_TOGGLE, 3121 &switch_event->base); 3122 3123#ifdef __clang_analyzer__ 3124 /* clang doesn't realize we're not leaking the event here, so 3125 * pretend to free it */ 3126 free(switch_event); 3127#endif 3128} 3129 3130static void 3131libinput_post_event(struct libinput *libinput, 3132 struct libinput_event *event) 3133{ 3134 struct libinput_event **events = libinput->events; 3135 size_t events_len = libinput->events_len; 3136 size_t events_count = libinput->events_count; 3137 size_t move_len; 3138 size_t new_out; 3139 3140#if 0 3141 log_debug(libinput, "Queuing %s\n", event_type_to_str(event->type)); 3142#endif 3143 3144 events_count++; 3145 if (events_count > events_len) { 3146 void *tmp; 3147 3148 events_len *= 2; 3149 tmp = realloc(events, events_len * sizeof *events); 3150 if (!tmp) { 3151 log_error(libinput, 3152 "Failed to reallocate event ring buffer. " 3153 "Events may be discarded\n"); 3154 return; 3155 } 3156 3157 events = tmp; 3158 3159 if (libinput->events_count > 0 && libinput->events_in == 0) { 3160 libinput->events_in = libinput->events_len; 3161 } else if (libinput->events_count > 0 && 3162 libinput->events_out >= libinput->events_in) { 3163 move_len = libinput->events_len - libinput->events_out; 3164 new_out = events_len - move_len; 3165 memmove(events + new_out, 3166 events + libinput->events_out, 3167 move_len * sizeof *events); 3168 libinput->events_out = new_out; 3169 } 3170 3171 libinput->events = events; 3172 libinput->events_len = events_len; 3173 } 3174 3175 if (event->device) 3176 libinput_device_ref(event->device); 3177 3178 libinput->events_count = events_count; 3179 events[libinput->events_in] = event; 3180 libinput->events_in = (libinput->events_in + 1) % libinput->events_len; 3181} 3182 3183LIBINPUT_EXPORT struct libinput_event * 3184libinput_get_event(struct libinput *libinput) 3185{ 3186 struct libinput_event *event; 3187 3188 if (libinput->events_count == 0) 3189 return NULL; 3190 3191 event = libinput->events[libinput->events_out]; 3192 libinput->events_out = 3193 (libinput->events_out + 1) % libinput->events_len; 3194 libinput->events_count--; 3195 3196 return event; 3197} 3198 3199LIBINPUT_EXPORT enum libinput_event_type 3200libinput_next_event_type(struct libinput *libinput) 3201{ 3202 struct libinput_event *event; 3203 3204 if (libinput->events_count == 0) 3205 return LIBINPUT_EVENT_NONE; 3206 3207 event = libinput->events[libinput->events_out]; 3208 return event->type; 3209} 3210 3211LIBINPUT_EXPORT void 3212libinput_set_user_data(struct libinput *libinput, 3213 void *user_data) 3214{ 3215 libinput->user_data = user_data; 3216} 3217 3218LIBINPUT_EXPORT void * 3219libinput_get_user_data(struct libinput *libinput) 3220{ 3221 return libinput->user_data; 3222} 3223 3224LIBINPUT_EXPORT int 3225libinput_resume(struct libinput *libinput) 3226{ 3227 return libinput->interface_backend->resume(libinput); 3228} 3229 3230LIBINPUT_EXPORT void 3231libinput_suspend(struct libinput *libinput) 3232{ 3233 libinput->interface_backend->suspend(libinput); 3234} 3235 3236LIBINPUT_EXPORT void 3237libinput_device_set_user_data(struct libinput_device *device, void *user_data) 3238{ 3239 device->user_data = user_data; 3240} 3241 3242LIBINPUT_EXPORT void * 3243libinput_device_get_user_data(struct libinput_device *device) 3244{ 3245 return device->user_data; 3246} 3247 3248LIBINPUT_EXPORT struct libinput * 3249libinput_device_get_context(struct libinput_device *device) 3250{ 3251 return libinput_seat_get_context(device->seat); 3252} 3253 3254LIBINPUT_EXPORT struct libinput_device_group * 3255libinput_device_get_device_group(struct libinput_device *device) 3256{ 3257 return device->group; 3258} 3259 3260LIBINPUT_EXPORT const char * 3261libinput_device_get_sysname(struct libinput_device *device) 3262{ 3263 return evdev_device_get_sysname((struct evdev_device *) device); 3264} 3265 3266LIBINPUT_EXPORT const char * 3267libinput_device_get_name(struct libinput_device *device) 3268{ 3269 return evdev_device_get_name((struct evdev_device *) device); 3270} 3271 3272LIBINPUT_EXPORT unsigned int 3273libinput_device_get_id_product(struct libinput_device *device) 3274{ 3275 return evdev_device_get_id_product((struct evdev_device *) device); 3276} 3277 3278LIBINPUT_EXPORT unsigned int 3279libinput_device_get_id_vendor(struct libinput_device *device) 3280{ 3281 return evdev_device_get_id_vendor((struct evdev_device *) device); 3282} 3283 3284LIBINPUT_EXPORT const char * 3285libinput_device_get_output_name(struct libinput_device *device) 3286{ 3287 return evdev_device_get_output((struct evdev_device *) device); 3288} 3289 3290LIBINPUT_EXPORT struct libinput_seat * 3291libinput_device_get_seat(struct libinput_device *device) 3292{ 3293 return device->seat; 3294} 3295 3296LIBINPUT_EXPORT int 3297libinput_device_set_seat_logical_name(struct libinput_device *device, 3298 const char *name) 3299{ 3300 struct libinput *libinput = device->seat->libinput; 3301 3302 if (name == NULL) 3303 return -1; 3304 3305 return libinput->interface_backend->device_change_seat(device, 3306 name); 3307} 3308 3309LIBINPUT_EXPORT struct udev_device * 3310libinput_device_get_udev_device(struct libinput_device *device) 3311{ 3312 return evdev_device_get_udev_device((struct evdev_device *)device); 3313} 3314 3315LIBINPUT_EXPORT void 3316libinput_device_led_update(struct libinput_device *device, 3317 enum libinput_led leds) 3318{ 3319 evdev_device_led_update((struct evdev_device *) device, leds); 3320} 3321 3322LIBINPUT_EXPORT int 3323libinput_device_has_capability(struct libinput_device *device, 3324 enum libinput_device_capability capability) 3325{ 3326 return evdev_device_has_capability((struct evdev_device *) device, 3327 capability); 3328} 3329 3330LIBINPUT_EXPORT int 3331libinput_device_get_size(struct libinput_device *device, 3332 double *width, 3333 double *height) 3334{ 3335 return evdev_device_get_size((struct evdev_device *)device, 3336 width, 3337 height); 3338} 3339 3340LIBINPUT_EXPORT int 3341libinput_device_pointer_has_button(struct libinput_device *device, uint32_t code) 3342{ 3343 return evdev_device_has_button((struct evdev_device *)device, code); 3344} 3345 3346LIBINPUT_EXPORT int 3347libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code) 3348{ 3349 return evdev_device_has_key((struct evdev_device *)device, code); 3350} 3351 3352LIBINPUT_EXPORT int 3353libinput_device_touch_get_touch_count(struct libinput_device *device) 3354{ 3355 return evdev_device_get_touch_count((struct evdev_device *)device); 3356} 3357 3358LIBINPUT_EXPORT int 3359libinput_device_switch_has_switch(struct libinput_device *device, 3360 enum libinput_switch sw) 3361{ 3362 return evdev_device_has_switch((struct evdev_device *)device, sw); 3363} 3364 3365LIBINPUT_EXPORT int 3366libinput_device_tablet_pad_has_key(struct libinput_device *device, uint32_t code) 3367{ 3368 return evdev_device_tablet_pad_has_key((struct evdev_device *)device, 3369 code); 3370} 3371 3372LIBINPUT_EXPORT int 3373libinput_device_tablet_pad_get_num_buttons(struct libinput_device *device) 3374{ 3375 return evdev_device_tablet_pad_get_num_buttons((struct evdev_device *)device); 3376} 3377 3378LIBINPUT_EXPORT int 3379libinput_device_tablet_pad_get_num_rings(struct libinput_device *device) 3380{ 3381 return evdev_device_tablet_pad_get_num_rings((struct evdev_device *)device); 3382} 3383 3384LIBINPUT_EXPORT int 3385libinput_device_tablet_pad_get_num_strips(struct libinput_device *device) 3386{ 3387 return evdev_device_tablet_pad_get_num_strips((struct evdev_device *)device); 3388} 3389 3390LIBINPUT_EXPORT int 3391libinput_device_tablet_pad_get_num_mode_groups(struct libinput_device *device) 3392{ 3393 return evdev_device_tablet_pad_get_num_mode_groups((struct evdev_device *)device); 3394} 3395 3396LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group* 3397libinput_device_tablet_pad_get_mode_group(struct libinput_device *device, 3398 unsigned int index) 3399{ 3400 return evdev_device_tablet_pad_get_mode_group((struct evdev_device *)device, 3401 index); 3402} 3403 3404LIBINPUT_EXPORT unsigned int 3405libinput_tablet_pad_mode_group_get_num_modes( 3406 struct libinput_tablet_pad_mode_group *group) 3407{ 3408 return group->num_modes; 3409} 3410 3411LIBINPUT_EXPORT unsigned int 3412libinput_tablet_pad_mode_group_get_mode(struct libinput_tablet_pad_mode_group *group) 3413{ 3414 return group->current_mode; 3415} 3416 3417LIBINPUT_EXPORT unsigned int 3418libinput_tablet_pad_mode_group_get_index(struct libinput_tablet_pad_mode_group *group) 3419{ 3420 return group->index; 3421} 3422 3423LIBINPUT_EXPORT int 3424libinput_tablet_pad_mode_group_has_button(struct libinput_tablet_pad_mode_group *group, 3425 unsigned int button) 3426{ 3427 if ((int)button >= 3428 libinput_device_tablet_pad_get_num_buttons(group->device)) 3429 return 0; 3430 3431 return !!(group->button_mask & bit(button)); 3432} 3433 3434LIBINPUT_EXPORT int 3435libinput_tablet_pad_mode_group_has_ring(struct libinput_tablet_pad_mode_group *group, 3436 unsigned int ring) 3437{ 3438 if ((int)ring >= 3439 libinput_device_tablet_pad_get_num_rings(group->device)) 3440 return 0; 3441 3442 return !!(group->ring_mask & bit(ring)); 3443} 3444 3445LIBINPUT_EXPORT int 3446libinput_tablet_pad_mode_group_has_strip(struct libinput_tablet_pad_mode_group *group, 3447 unsigned int strip) 3448{ 3449 if ((int)strip >= 3450 libinput_device_tablet_pad_get_num_strips(group->device)) 3451 return 0; 3452 3453 return !!(group->strip_mask & bit(strip)); 3454} 3455 3456LIBINPUT_EXPORT int 3457libinput_tablet_pad_mode_group_button_is_toggle(struct libinput_tablet_pad_mode_group *group, 3458 unsigned int button) 3459{ 3460 if ((int)button >= 3461 libinput_device_tablet_pad_get_num_buttons(group->device)) 3462 return 0; 3463 3464 return !!(group->toggle_button_mask & bit(button)); 3465} 3466 3467LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * 3468libinput_tablet_pad_mode_group_ref( 3469 struct libinput_tablet_pad_mode_group *group) 3470{ 3471 group->refcount++; 3472 return group; 3473} 3474 3475LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * 3476libinput_tablet_pad_mode_group_unref( 3477 struct libinput_tablet_pad_mode_group *group) 3478{ 3479 assert(group->refcount > 0); 3480 3481 group->refcount--; 3482 if (group->refcount > 0) 3483 return group; 3484 3485 list_remove(&group->link); 3486 group->destroy(group); 3487 return NULL; 3488} 3489 3490LIBINPUT_EXPORT void 3491libinput_tablet_pad_mode_group_set_user_data( 3492 struct libinput_tablet_pad_mode_group *group, 3493 void *user_data) 3494{ 3495 group->user_data = user_data; 3496} 3497 3498LIBINPUT_EXPORT void * 3499libinput_tablet_pad_mode_group_get_user_data( 3500 struct libinput_tablet_pad_mode_group *group) 3501{ 3502 return group->user_data; 3503} 3504 3505LIBINPUT_EXPORT struct libinput_event * 3506libinput_event_device_notify_get_base_event(struct libinput_event_device_notify *event) 3507{ 3508 require_event_type(libinput_event_get_context(&event->base), 3509 event->base.type, 3510 NULL, 3511 LIBINPUT_EVENT_DEVICE_ADDED, 3512 LIBINPUT_EVENT_DEVICE_REMOVED); 3513 3514 return &event->base; 3515} 3516 3517LIBINPUT_EXPORT struct libinput_event * 3518libinput_event_keyboard_get_base_event(struct libinput_event_keyboard *event) 3519{ 3520 require_event_type(libinput_event_get_context(&event->base), 3521 event->base.type, 3522 NULL, 3523 LIBINPUT_EVENT_KEYBOARD_KEY); 3524 3525 return &event->base; 3526} 3527 3528LIBINPUT_EXPORT struct libinput_event * 3529libinput_event_pointer_get_base_event(struct libinput_event_pointer *event) 3530{ 3531 require_event_type(libinput_event_get_context(&event->base), 3532 event->base.type, 3533 NULL, 3534 LIBINPUT_EVENT_POINTER_MOTION, 3535 LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, 3536 LIBINPUT_EVENT_POINTER_BUTTON, 3537 LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, 3538 LIBINPUT_EVENT_POINTER_SCROLL_FINGER, 3539 LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, 3540 LIBINPUT_EVENT_POINTER_AXIS); 3541 3542 return &event->base; 3543} 3544 3545LIBINPUT_EXPORT struct libinput_event * 3546libinput_event_touch_get_base_event(struct libinput_event_touch *event) 3547{ 3548 require_event_type(libinput_event_get_context(&event->base), 3549 event->base.type, 3550 NULL, 3551 LIBINPUT_EVENT_TOUCH_DOWN, 3552 LIBINPUT_EVENT_TOUCH_UP, 3553 LIBINPUT_EVENT_TOUCH_MOTION, 3554 LIBINPUT_EVENT_TOUCH_CANCEL, 3555 LIBINPUT_EVENT_TOUCH_FRAME); 3556 3557 return &event->base; 3558} 3559 3560LIBINPUT_EXPORT struct libinput_event * 3561libinput_event_gesture_get_base_event(struct libinput_event_gesture *event) 3562{ 3563 require_event_type(libinput_event_get_context(&event->base), 3564 event->base.type, 3565 NULL, 3566 LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN, 3567 LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, 3568 LIBINPUT_EVENT_GESTURE_SWIPE_END, 3569 LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, 3570 LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, 3571 LIBINPUT_EVENT_GESTURE_PINCH_END, 3572 LIBINPUT_EVENT_GESTURE_HOLD_BEGIN, 3573 LIBINPUT_EVENT_GESTURE_HOLD_END); 3574 3575 return &event->base; 3576} 3577 3578LIBINPUT_EXPORT struct libinput_event * 3579libinput_event_tablet_tool_get_base_event(struct libinput_event_tablet_tool *event) 3580{ 3581 require_event_type(libinput_event_get_context(&event->base), 3582 event->base.type, 3583 NULL, 3584 LIBINPUT_EVENT_TABLET_TOOL_AXIS, 3585 LIBINPUT_EVENT_TABLET_TOOL_TIP, 3586 LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, 3587 LIBINPUT_EVENT_TABLET_TOOL_BUTTON); 3588 3589 return &event->base; 3590} 3591 3592LIBINPUT_EXPORT double 3593libinput_event_tablet_pad_get_ring_position(struct libinput_event_tablet_pad *event) 3594{ 3595 require_event_type(libinput_event_get_context(&event->base), 3596 event->base.type, 3597 0.0, 3598 LIBINPUT_EVENT_TABLET_PAD_RING); 3599 3600 return event->ring.position; 3601} 3602 3603LIBINPUT_EXPORT unsigned int 3604libinput_event_tablet_pad_get_ring_number(struct libinput_event_tablet_pad *event) 3605{ 3606 require_event_type(libinput_event_get_context(&event->base), 3607 event->base.type, 3608 0, 3609 LIBINPUT_EVENT_TABLET_PAD_RING); 3610 3611 return event->ring.number; 3612} 3613 3614LIBINPUT_EXPORT enum libinput_tablet_pad_ring_axis_source 3615libinput_event_tablet_pad_get_ring_source(struct libinput_event_tablet_pad *event) 3616{ 3617 require_event_type(libinput_event_get_context(&event->base), 3618 event->base.type, 3619 LIBINPUT_TABLET_PAD_RING_SOURCE_UNKNOWN, 3620 LIBINPUT_EVENT_TABLET_PAD_RING); 3621 3622 return event->ring.source; 3623} 3624 3625LIBINPUT_EXPORT double 3626libinput_event_tablet_pad_get_strip_position(struct libinput_event_tablet_pad *event) 3627{ 3628 require_event_type(libinput_event_get_context(&event->base), 3629 event->base.type, 3630 0.0, 3631 LIBINPUT_EVENT_TABLET_PAD_STRIP); 3632 3633 return event->strip.position; 3634} 3635 3636LIBINPUT_EXPORT unsigned int 3637libinput_event_tablet_pad_get_strip_number(struct libinput_event_tablet_pad *event) 3638{ 3639 require_event_type(libinput_event_get_context(&event->base), 3640 event->base.type, 3641 0, 3642 LIBINPUT_EVENT_TABLET_PAD_STRIP); 3643 3644 return event->strip.number; 3645} 3646 3647LIBINPUT_EXPORT enum libinput_tablet_pad_strip_axis_source 3648libinput_event_tablet_pad_get_strip_source(struct libinput_event_tablet_pad *event) 3649{ 3650 require_event_type(libinput_event_get_context(&event->base), 3651 event->base.type, 3652 LIBINPUT_TABLET_PAD_STRIP_SOURCE_UNKNOWN, 3653 LIBINPUT_EVENT_TABLET_PAD_STRIP); 3654 3655 return event->strip.source; 3656} 3657 3658LIBINPUT_EXPORT uint32_t 3659libinput_event_tablet_pad_get_button_number(struct libinput_event_tablet_pad *event) 3660{ 3661 require_event_type(libinput_event_get_context(&event->base), 3662 event->base.type, 3663 0, 3664 LIBINPUT_EVENT_TABLET_PAD_BUTTON); 3665 3666 return event->button.number; 3667} 3668 3669LIBINPUT_EXPORT enum libinput_button_state 3670libinput_event_tablet_pad_get_button_state(struct libinput_event_tablet_pad *event) 3671{ 3672 require_event_type(libinput_event_get_context(&event->base), 3673 event->base.type, 3674 LIBINPUT_BUTTON_STATE_RELEASED, 3675 LIBINPUT_EVENT_TABLET_PAD_BUTTON); 3676 3677 return event->button.state; 3678} 3679 3680LIBINPUT_EXPORT uint32_t 3681libinput_event_tablet_pad_get_key(struct libinput_event_tablet_pad *event) 3682{ 3683 require_event_type(libinput_event_get_context(&event->base), 3684 event->base.type, 3685 0, 3686 LIBINPUT_EVENT_TABLET_PAD_KEY); 3687 3688 return event->key.code; 3689} 3690 3691LIBINPUT_EXPORT enum libinput_key_state 3692libinput_event_tablet_pad_get_key_state(struct libinput_event_tablet_pad *event) 3693{ 3694 require_event_type(libinput_event_get_context(&event->base), 3695 event->base.type, 3696 LIBINPUT_KEY_STATE_RELEASED, 3697 LIBINPUT_EVENT_TABLET_PAD_KEY); 3698 3699 return event->key.state; 3700} 3701 3702LIBINPUT_EXPORT unsigned int 3703libinput_event_tablet_pad_get_mode(struct libinput_event_tablet_pad *event) 3704{ 3705 require_event_type(libinput_event_get_context(&event->base), 3706 event->base.type, 3707 0, 3708 LIBINPUT_EVENT_TABLET_PAD_RING, 3709 LIBINPUT_EVENT_TABLET_PAD_STRIP, 3710 LIBINPUT_EVENT_TABLET_PAD_BUTTON); 3711 3712 return event->mode; 3713} 3714 3715LIBINPUT_EXPORT struct libinput_tablet_pad_mode_group * 3716libinput_event_tablet_pad_get_mode_group(struct libinput_event_tablet_pad *event) 3717{ 3718 require_event_type(libinput_event_get_context(&event->base), 3719 event->base.type, 3720 NULL, 3721 LIBINPUT_EVENT_TABLET_PAD_RING, 3722 LIBINPUT_EVENT_TABLET_PAD_STRIP, 3723 LIBINPUT_EVENT_TABLET_PAD_BUTTON); 3724 3725 return event->mode_group; 3726} 3727 3728LIBINPUT_EXPORT uint32_t 3729libinput_event_tablet_pad_get_time(struct libinput_event_tablet_pad *event) 3730{ 3731 require_event_type(libinput_event_get_context(&event->base), 3732 event->base.type, 3733 0, 3734 LIBINPUT_EVENT_TABLET_PAD_RING, 3735 LIBINPUT_EVENT_TABLET_PAD_STRIP, 3736 LIBINPUT_EVENT_TABLET_PAD_BUTTON, 3737 LIBINPUT_EVENT_TABLET_PAD_KEY); 3738 3739 return us2ms(event->time); 3740} 3741 3742LIBINPUT_EXPORT uint64_t 3743libinput_event_tablet_pad_get_time_usec(struct libinput_event_tablet_pad *event) 3744{ 3745 require_event_type(libinput_event_get_context(&event->base), 3746 event->base.type, 3747 0, 3748 LIBINPUT_EVENT_TABLET_PAD_RING, 3749 LIBINPUT_EVENT_TABLET_PAD_STRIP, 3750 LIBINPUT_EVENT_TABLET_PAD_BUTTON, 3751 LIBINPUT_EVENT_TABLET_PAD_KEY); 3752 3753 return event->time; 3754} 3755 3756LIBINPUT_EXPORT struct libinput_event * 3757libinput_event_tablet_pad_get_base_event(struct libinput_event_tablet_pad *event) 3758{ 3759 require_event_type(libinput_event_get_context(&event->base), 3760 event->base.type, 3761 NULL, 3762 LIBINPUT_EVENT_TABLET_PAD_RING, 3763 LIBINPUT_EVENT_TABLET_PAD_STRIP, 3764 LIBINPUT_EVENT_TABLET_PAD_BUTTON, 3765 LIBINPUT_EVENT_TABLET_PAD_KEY); 3766 3767 return &event->base; 3768} 3769 3770LIBINPUT_EXPORT struct libinput_device_group * 3771libinput_device_group_ref(struct libinput_device_group *group) 3772{ 3773 group->refcount++; 3774 return group; 3775} 3776 3777struct libinput_device_group * 3778libinput_device_group_create(struct libinput *libinput, 3779 const char *identifier) 3780{ 3781 struct libinput_device_group *group; 3782 3783 group = zalloc(sizeof *group); 3784 group->refcount = 1; 3785 group->identifier = safe_strdup(identifier); 3786 3787 list_init(&group->link); 3788 list_insert(&libinput->device_group_list, &group->link); 3789 3790 return group; 3791} 3792 3793struct libinput_device_group * 3794libinput_device_group_find_group(struct libinput *libinput, 3795 const char *identifier) 3796{ 3797 struct libinput_device_group *g = NULL; 3798 3799 list_for_each(g, &libinput->device_group_list, link) { 3800 if (identifier && g->identifier && 3801 streq(g->identifier, identifier)) { 3802 return g; 3803 } 3804 } 3805 3806 return NULL; 3807} 3808 3809void 3810libinput_device_set_device_group(struct libinput_device *device, 3811 struct libinput_device_group *group) 3812{ 3813 device->group = group; 3814 libinput_device_group_ref(group); 3815} 3816 3817static void 3818libinput_device_group_destroy(struct libinput_device_group *group) 3819{ 3820 list_remove(&group->link); 3821 free(group->identifier); 3822 free(group); 3823} 3824 3825LIBINPUT_EXPORT struct libinput_device_group * 3826libinput_device_group_unref(struct libinput_device_group *group) 3827{ 3828 assert(group->refcount > 0); 3829 group->refcount--; 3830 if (group->refcount == 0) { 3831 libinput_device_group_destroy(group); 3832 return NULL; 3833 } 3834 3835 return group; 3836} 3837 3838LIBINPUT_EXPORT void 3839libinput_device_group_set_user_data(struct libinput_device_group *group, 3840 void *user_data) 3841{ 3842 group->user_data = user_data; 3843} 3844 3845LIBINPUT_EXPORT void * 3846libinput_device_group_get_user_data(struct libinput_device_group *group) 3847{ 3848 return group->user_data; 3849} 3850 3851LIBINPUT_EXPORT const char * 3852libinput_config_status_to_str(enum libinput_config_status status) 3853{ 3854 const char *str = NULL; 3855 3856 switch(status) { 3857 case LIBINPUT_CONFIG_STATUS_SUCCESS: 3858 str = "Success"; 3859 break; 3860 case LIBINPUT_CONFIG_STATUS_UNSUPPORTED: 3861 str = "Unsupported configuration option"; 3862 break; 3863 case LIBINPUT_CONFIG_STATUS_INVALID: 3864 str = "Invalid argument range"; 3865 break; 3866 } 3867 3868 return str; 3869} 3870 3871LIBINPUT_EXPORT int 3872libinput_device_config_tap_get_finger_count(struct libinput_device *device) 3873{ 3874 return device->config.tap ? device->config.tap->count(device) : 0; 3875} 3876 3877LIBINPUT_EXPORT enum libinput_config_status 3878libinput_device_config_tap_set_enabled(struct libinput_device *device, 3879 enum libinput_config_tap_state enable) 3880{ 3881 if (enable != LIBINPUT_CONFIG_TAP_ENABLED && 3882 enable != LIBINPUT_CONFIG_TAP_DISABLED) 3883 return LIBINPUT_CONFIG_STATUS_INVALID; 3884 3885 if (libinput_device_config_tap_get_finger_count(device) == 0) 3886 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 3887 LIBINPUT_CONFIG_STATUS_SUCCESS; 3888 3889 return device->config.tap->set_enabled(device, enable); 3890 3891} 3892 3893LIBINPUT_EXPORT enum libinput_config_tap_state 3894libinput_device_config_tap_get_enabled(struct libinput_device *device) 3895{ 3896 if (libinput_device_config_tap_get_finger_count(device) == 0) 3897 return LIBINPUT_CONFIG_TAP_DISABLED; 3898 3899 return device->config.tap->get_enabled(device); 3900} 3901 3902LIBINPUT_EXPORT enum libinput_config_tap_state 3903libinput_device_config_tap_get_default_enabled(struct libinput_device *device) 3904{ 3905 if (libinput_device_config_tap_get_finger_count(device) == 0) 3906 return LIBINPUT_CONFIG_TAP_DISABLED; 3907 3908 return device->config.tap->get_default(device); 3909} 3910 3911LIBINPUT_EXPORT enum libinput_config_status 3912libinput_device_config_tap_set_button_map(struct libinput_device *device, 3913 enum libinput_config_tap_button_map map) 3914{ 3915 switch (map) { 3916 case LIBINPUT_CONFIG_TAP_MAP_LRM: 3917 case LIBINPUT_CONFIG_TAP_MAP_LMR: 3918 break; 3919 default: 3920 return LIBINPUT_CONFIG_STATUS_INVALID; 3921 } 3922 3923 if (libinput_device_config_tap_get_finger_count(device) == 0) 3924 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 3925 3926 return device->config.tap->set_map(device, map); 3927} 3928 3929LIBINPUT_EXPORT enum libinput_config_tap_button_map 3930libinput_device_config_tap_get_button_map(struct libinput_device *device) 3931{ 3932 if (libinput_device_config_tap_get_finger_count(device) == 0) 3933 return LIBINPUT_CONFIG_TAP_MAP_LRM; 3934 3935 return device->config.tap->get_map(device); 3936} 3937 3938LIBINPUT_EXPORT enum libinput_config_tap_button_map 3939libinput_device_config_tap_get_default_button_map(struct libinput_device *device) 3940{ 3941 if (libinput_device_config_tap_get_finger_count(device) == 0) 3942 return LIBINPUT_CONFIG_TAP_MAP_LRM; 3943 3944 return device->config.tap->get_default_map(device); 3945} 3946 3947LIBINPUT_EXPORT enum libinput_config_status 3948libinput_device_config_tap_set_drag_enabled(struct libinput_device *device, 3949 enum libinput_config_drag_state enable) 3950{ 3951 if (enable != LIBINPUT_CONFIG_DRAG_ENABLED && 3952 enable != LIBINPUT_CONFIG_DRAG_DISABLED) 3953 return LIBINPUT_CONFIG_STATUS_INVALID; 3954 3955 if (libinput_device_config_tap_get_finger_count(device) == 0) 3956 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 3957 LIBINPUT_CONFIG_STATUS_SUCCESS; 3958 3959 return device->config.tap->set_drag_enabled(device, enable); 3960} 3961 3962LIBINPUT_EXPORT enum libinput_config_drag_state 3963libinput_device_config_tap_get_drag_enabled(struct libinput_device *device) 3964{ 3965 if (libinput_device_config_tap_get_finger_count(device) == 0) 3966 return LIBINPUT_CONFIG_DRAG_DISABLED; 3967 3968 return device->config.tap->get_drag_enabled(device); 3969} 3970 3971LIBINPUT_EXPORT enum libinput_config_drag_state 3972libinput_device_config_tap_get_default_drag_enabled(struct libinput_device *device) 3973{ 3974 if (libinput_device_config_tap_get_finger_count(device) == 0) 3975 return LIBINPUT_CONFIG_DRAG_DISABLED; 3976 3977 return device->config.tap->get_default_drag_enabled(device); 3978} 3979 3980LIBINPUT_EXPORT enum libinput_config_status 3981libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device, 3982 enum libinput_config_drag_lock_state enable) 3983{ 3984 if (enable != LIBINPUT_CONFIG_DRAG_LOCK_ENABLED && 3985 enable != LIBINPUT_CONFIG_DRAG_LOCK_DISABLED) 3986 return LIBINPUT_CONFIG_STATUS_INVALID; 3987 3988 if (libinput_device_config_tap_get_finger_count(device) == 0) 3989 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 3990 LIBINPUT_CONFIG_STATUS_SUCCESS; 3991 3992 return device->config.tap->set_draglock_enabled(device, enable); 3993} 3994 3995LIBINPUT_EXPORT enum libinput_config_drag_lock_state 3996libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device) 3997{ 3998 if (libinput_device_config_tap_get_finger_count(device) == 0) 3999 return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; 4000 4001 return device->config.tap->get_draglock_enabled(device); 4002} 4003 4004LIBINPUT_EXPORT enum libinput_config_drag_lock_state 4005libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device) 4006{ 4007 if (libinput_device_config_tap_get_finger_count(device) == 0) 4008 return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; 4009 4010 return device->config.tap->get_default_draglock_enabled(device); 4011} 4012 4013LIBINPUT_EXPORT int 4014libinput_device_config_calibration_has_matrix(struct libinput_device *device) 4015{ 4016 return device->config.calibration ? 4017 device->config.calibration->has_matrix(device) : 0; 4018} 4019 4020LIBINPUT_EXPORT enum libinput_config_status 4021libinput_device_config_calibration_set_matrix(struct libinput_device *device, 4022 const float matrix[6]) 4023{ 4024 if (!libinput_device_config_calibration_has_matrix(device)) 4025 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4026 4027 return device->config.calibration->set_matrix(device, matrix); 4028} 4029 4030LIBINPUT_EXPORT int 4031libinput_device_config_calibration_get_matrix(struct libinput_device *device, 4032 float matrix[6]) 4033{ 4034 if (!libinput_device_config_calibration_has_matrix(device)) 4035 return 0; 4036 4037 return device->config.calibration->get_matrix(device, matrix); 4038} 4039 4040LIBINPUT_EXPORT int 4041libinput_device_config_calibration_get_default_matrix(struct libinput_device *device, 4042 float matrix[6]) 4043{ 4044 if (!libinput_device_config_calibration_has_matrix(device)) 4045 return 0; 4046 4047 return device->config.calibration->get_default_matrix(device, matrix); 4048} 4049 4050LIBINPUT_EXPORT uint32_t 4051libinput_device_config_send_events_get_modes(struct libinput_device *device) 4052{ 4053 uint32_t modes = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; 4054 4055 if (device->config.sendevents) 4056 modes |= device->config.sendevents->get_modes(device); 4057 4058 return modes; 4059} 4060 4061LIBINPUT_EXPORT enum libinput_config_status 4062libinput_device_config_send_events_set_mode(struct libinput_device *device, 4063 uint32_t mode) 4064{ 4065 if ((libinput_device_config_send_events_get_modes(device) & mode) != mode) 4066 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4067 4068 if (device->config.sendevents) 4069 return device->config.sendevents->set_mode(device, mode); 4070 4071 /* mode must be _ENABLED to get here */ 4072 return LIBINPUT_CONFIG_STATUS_SUCCESS; 4073} 4074 4075LIBINPUT_EXPORT uint32_t 4076libinput_device_config_send_events_get_mode(struct libinput_device *device) 4077{ 4078 if (device->config.sendevents) 4079 return device->config.sendevents->get_mode(device); 4080 4081 return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; 4082} 4083 4084LIBINPUT_EXPORT uint32_t 4085libinput_device_config_send_events_get_default_mode(struct libinput_device *device) 4086{ 4087 return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; 4088} 4089 4090LIBINPUT_EXPORT int 4091libinput_device_config_accel_is_available(struct libinput_device *device) 4092{ 4093 return device->config.accel ? 4094 device->config.accel->available(device) : 0; 4095} 4096 4097LIBINPUT_EXPORT enum libinput_config_status 4098libinput_device_config_accel_set_speed(struct libinput_device *device, 4099 double speed) 4100{ 4101 /* Need the negation in case speed is NaN */ 4102 if (!(speed >= -1.0 && speed <= 1.0)) 4103 return LIBINPUT_CONFIG_STATUS_INVALID; 4104 4105 if (!libinput_device_config_accel_is_available(device)) 4106 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4107 4108 return device->config.accel->set_speed(device, speed); 4109} 4110LIBINPUT_EXPORT double 4111libinput_device_config_accel_get_speed(struct libinput_device *device) 4112{ 4113 if (!libinput_device_config_accel_is_available(device)) 4114 return 0; 4115 4116 return device->config.accel->get_speed(device); 4117} 4118 4119LIBINPUT_EXPORT double 4120libinput_device_config_accel_get_default_speed(struct libinput_device *device) 4121{ 4122 if (!libinput_device_config_accel_is_available(device)) 4123 return 0; 4124 4125 return device->config.accel->get_default_speed(device); 4126} 4127 4128LIBINPUT_EXPORT uint32_t 4129libinput_device_config_accel_get_profiles(struct libinput_device *device) 4130{ 4131 if (!libinput_device_config_accel_is_available(device)) 4132 return 0; 4133 4134 return device->config.accel->get_profiles(device); 4135} 4136 4137LIBINPUT_EXPORT enum libinput_config_accel_profile 4138libinput_device_config_accel_get_profile(struct libinput_device *device) 4139{ 4140 if (!libinput_device_config_accel_is_available(device)) 4141 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; 4142 4143 return device->config.accel->get_profile(device); 4144} 4145 4146LIBINPUT_EXPORT enum libinput_config_accel_profile 4147libinput_device_config_accel_get_default_profile(struct libinput_device *device) 4148{ 4149 if (!libinput_device_config_accel_is_available(device)) 4150 return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; 4151 4152 return device->config.accel->get_default_profile(device); 4153} 4154 4155LIBINPUT_EXPORT enum libinput_config_status 4156libinput_device_config_accel_set_profile(struct libinput_device *device, 4157 enum libinput_config_accel_profile profile) 4158{ 4159 switch (profile) { 4160 case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: 4161 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: 4162 case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: 4163 break; 4164 default: 4165 return LIBINPUT_CONFIG_STATUS_INVALID; 4166 } 4167 4168 if (!libinput_device_config_accel_is_available(device) || 4169 (libinput_device_config_accel_get_profiles(device) & profile) == 0) 4170 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4171 4172 return device->config.accel->set_profile(device, profile); 4173} 4174 4175static inline struct libinput_config_accel_custom_func * 4176libinput_config_accel_custom_func_create(void) 4177{ 4178 struct libinput_config_accel_custom_func *func = zalloc(sizeof(*func)); 4179 4180 func->step = 1.0; 4181 func->npoints = 2; 4182 func->points[0] = 0.0; /* default to a flat unaccelerated function */ 4183 func->points[1] = 1.0; 4184 4185 return func; 4186} 4187 4188static inline void 4189libinput_config_accel_custom_func_destroy(struct libinput_config_accel_custom_func * func) 4190{ 4191 free(func); 4192} 4193 4194LIBINPUT_EXPORT struct libinput_config_accel * 4195libinput_config_accel_create(enum libinput_config_accel_profile profile) 4196{ 4197 struct libinput_config_accel *config = zalloc(sizeof(*config)); 4198 4199 config->profile = profile; 4200 4201 switch (profile) { 4202 case LIBINPUT_CONFIG_ACCEL_PROFILE_NONE: 4203 break; 4204 case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: 4205 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: 4206 return config; 4207 case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: 4208 config->custom.fallback = libinput_config_accel_custom_func_create(); 4209 return config; 4210 } 4211 4212 free(config); 4213 return NULL; 4214} 4215 4216LIBINPUT_EXPORT void 4217libinput_config_accel_destroy(struct libinput_config_accel *accel_config) 4218{ 4219 libinput_config_accel_custom_func_destroy(accel_config->custom.fallback); 4220 libinput_config_accel_custom_func_destroy(accel_config->custom.motion); 4221 libinput_config_accel_custom_func_destroy(accel_config->custom.scroll); 4222 free(accel_config); 4223} 4224 4225LIBINPUT_EXPORT enum libinput_config_status 4226libinput_device_config_accel_apply(struct libinput_device *device, 4227 struct libinput_config_accel *accel_config) 4228{ 4229 enum libinput_config_status status; 4230 status = libinput_device_config_accel_set_profile(device, accel_config->profile); 4231 if (status != LIBINPUT_CONFIG_STATUS_SUCCESS) 4232 return status; 4233 4234 switch (accel_config->profile) { 4235 case LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT: 4236 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: 4237 { 4238 double speed = libinput_device_config_accel_get_default_speed(device); 4239 return libinput_device_config_accel_set_speed(device, speed); 4240 } 4241 case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: 4242 return device->config.accel->set_accel_config(device, accel_config); 4243 4244 default: 4245 return LIBINPUT_CONFIG_STATUS_INVALID; 4246 } 4247} 4248 4249LIBINPUT_EXPORT enum libinput_config_status 4250libinput_config_accel_set_points(struct libinput_config_accel *config, 4251 enum libinput_config_accel_type accel_type, 4252 double step, size_t npoints, double *points) 4253{ 4254 if (config->profile != LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) 4255 return LIBINPUT_CONFIG_STATUS_INVALID; 4256 4257 switch (accel_type) { 4258 case LIBINPUT_ACCEL_TYPE_FALLBACK: 4259 case LIBINPUT_ACCEL_TYPE_MOTION: 4260 case LIBINPUT_ACCEL_TYPE_SCROLL: 4261 break; 4262 default: 4263 return LIBINPUT_CONFIG_STATUS_INVALID; 4264 } 4265 4266 if (step <= 0 || step > LIBINPUT_ACCEL_STEP_MAX) 4267 return LIBINPUT_CONFIG_STATUS_INVALID; 4268 4269 if (npoints < LIBINPUT_ACCEL_NPOINTS_MIN || npoints > LIBINPUT_ACCEL_NPOINTS_MAX) 4270 return LIBINPUT_CONFIG_STATUS_INVALID; 4271 4272 for (size_t idx = 0; idx < npoints; idx++) { 4273 if (points[idx] < LIBINPUT_ACCEL_POINT_MIN_VALUE || 4274 points[idx] > LIBINPUT_ACCEL_POINT_MAX_VALUE) 4275 return LIBINPUT_CONFIG_STATUS_INVALID; 4276 } 4277 4278 struct libinput_config_accel_custom_func *func = libinput_config_accel_custom_func_create(); 4279 4280 func->step = step; 4281 func->npoints = npoints; 4282 memcpy(func->points, points, sizeof(*points) * npoints); 4283 4284 switch (accel_type) { 4285 case LIBINPUT_ACCEL_TYPE_FALLBACK: 4286 libinput_config_accel_custom_func_destroy(config->custom.fallback); 4287 config->custom.fallback = func; 4288 break; 4289 case LIBINPUT_ACCEL_TYPE_MOTION: 4290 libinput_config_accel_custom_func_destroy(config->custom.motion); 4291 config->custom.motion = func; 4292 break; 4293 case LIBINPUT_ACCEL_TYPE_SCROLL: 4294 libinput_config_accel_custom_func_destroy(config->custom.scroll); 4295 config->custom.scroll = func; 4296 break; 4297 } 4298 4299 return LIBINPUT_CONFIG_STATUS_SUCCESS; 4300} 4301 4302LIBINPUT_EXPORT int 4303libinput_device_config_scroll_has_natural_scroll(struct libinput_device *device) 4304{ 4305 if (!device->config.natural_scroll) 4306 return 0; 4307 4308 return device->config.natural_scroll->has(device); 4309} 4310 4311LIBINPUT_EXPORT enum libinput_config_status 4312libinput_device_config_scroll_set_natural_scroll_enabled(struct libinput_device *device, 4313 int enabled) 4314{ 4315 if (!libinput_device_config_scroll_has_natural_scroll(device)) 4316 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4317 4318 return device->config.natural_scroll->set_enabled(device, enabled); 4319} 4320 4321LIBINPUT_EXPORT int 4322libinput_device_config_scroll_get_natural_scroll_enabled(struct libinput_device *device) 4323{ 4324 if (!device->config.natural_scroll) 4325 return 0; 4326 4327 return device->config.natural_scroll->get_enabled(device); 4328} 4329 4330LIBINPUT_EXPORT int 4331libinput_device_config_scroll_get_default_natural_scroll_enabled(struct libinput_device *device) 4332{ 4333 if (!device->config.natural_scroll) 4334 return 0; 4335 4336 return device->config.natural_scroll->get_default_enabled(device); 4337} 4338 4339LIBINPUT_EXPORT int 4340libinput_device_config_left_handed_is_available(struct libinput_device *device) 4341{ 4342 if (!device->config.left_handed) 4343 return 0; 4344 4345 return device->config.left_handed->has(device); 4346} 4347 4348LIBINPUT_EXPORT enum libinput_config_status 4349libinput_device_config_left_handed_set(struct libinput_device *device, 4350 int left_handed) 4351{ 4352 if (!libinput_device_config_left_handed_is_available(device)) 4353 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4354 4355 return device->config.left_handed->set(device, left_handed); 4356} 4357 4358LIBINPUT_EXPORT int 4359libinput_device_config_left_handed_get(struct libinput_device *device) 4360{ 4361 if (!libinput_device_config_left_handed_is_available(device)) 4362 return 0; 4363 4364 return device->config.left_handed->get(device); 4365} 4366 4367LIBINPUT_EXPORT int 4368libinput_device_config_left_handed_get_default(struct libinput_device *device) 4369{ 4370 if (!libinput_device_config_left_handed_is_available(device)) 4371 return 0; 4372 4373 return device->config.left_handed->get_default(device); 4374} 4375 4376LIBINPUT_EXPORT uint32_t 4377libinput_device_config_click_get_methods(struct libinput_device *device) 4378{ 4379 if (device->config.click_method) 4380 return device->config.click_method->get_methods(device); 4381 4382 return 0; 4383} 4384 4385LIBINPUT_EXPORT enum libinput_config_status 4386libinput_device_config_click_set_method(struct libinput_device *device, 4387 enum libinput_config_click_method method) 4388{ 4389 /* Check method is a single valid method */ 4390 switch (method) { 4391 case LIBINPUT_CONFIG_CLICK_METHOD_NONE: 4392 case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS: 4393 case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER: 4394 break; 4395 default: 4396 return LIBINPUT_CONFIG_STATUS_INVALID; 4397 } 4398 4399 if ((libinput_device_config_click_get_methods(device) & method) != method) 4400 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4401 4402 if (device->config.click_method) 4403 return device->config.click_method->set_method(device, method); 4404 4405 /* method must be _NONE to get here */ 4406 return LIBINPUT_CONFIG_STATUS_SUCCESS; 4407} 4408 4409LIBINPUT_EXPORT enum libinput_config_click_method 4410libinput_device_config_click_get_method(struct libinput_device *device) 4411{ 4412 if (device->config.click_method) 4413 return device->config.click_method->get_method(device); 4414 4415 return LIBINPUT_CONFIG_CLICK_METHOD_NONE; 4416} 4417 4418LIBINPUT_EXPORT enum libinput_config_click_method 4419libinput_device_config_click_get_default_method(struct libinput_device *device) 4420{ 4421 if (device->config.click_method) 4422 return device->config.click_method->get_default_method(device); 4423 4424 return LIBINPUT_CONFIG_CLICK_METHOD_NONE; 4425} 4426 4427LIBINPUT_EXPORT int 4428libinput_device_config_middle_emulation_is_available( 4429 struct libinput_device *device) 4430{ 4431 if (device->config.middle_emulation) 4432 return device->config.middle_emulation->available(device); 4433 4434 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; 4435} 4436 4437LIBINPUT_EXPORT enum libinput_config_status 4438libinput_device_config_middle_emulation_set_enabled( 4439 struct libinput_device *device, 4440 enum libinput_config_middle_emulation_state enable) 4441{ 4442 int available = 4443 libinput_device_config_middle_emulation_is_available(device); 4444 4445 switch (enable) { 4446 case LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED: 4447 if (!available) 4448 return LIBINPUT_CONFIG_STATUS_SUCCESS; 4449 break; 4450 case LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED: 4451 if (!available) 4452 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4453 break; 4454 default: 4455 return LIBINPUT_CONFIG_STATUS_INVALID; 4456 } 4457 4458 return device->config.middle_emulation->set(device, enable); 4459} 4460 4461LIBINPUT_EXPORT enum libinput_config_middle_emulation_state 4462libinput_device_config_middle_emulation_get_enabled( 4463 struct libinput_device *device) 4464{ 4465 if (!libinput_device_config_middle_emulation_is_available(device)) 4466 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; 4467 4468 return device->config.middle_emulation->get(device); 4469} 4470 4471LIBINPUT_EXPORT enum libinput_config_middle_emulation_state 4472libinput_device_config_middle_emulation_get_default_enabled( 4473 struct libinput_device *device) 4474{ 4475 if (!libinput_device_config_middle_emulation_is_available(device)) 4476 return LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; 4477 4478 return device->config.middle_emulation->get_default(device); 4479} 4480 4481LIBINPUT_EXPORT uint32_t 4482libinput_device_config_scroll_get_methods(struct libinput_device *device) 4483{ 4484 if (device->config.scroll_method) 4485 return device->config.scroll_method->get_methods(device); 4486 4487 return 0; 4488} 4489 4490LIBINPUT_EXPORT enum libinput_config_status 4491libinput_device_config_scroll_set_method(struct libinput_device *device, 4492 enum libinput_config_scroll_method method) 4493{ 4494 /* Check method is a single valid method */ 4495 switch (method) { 4496 case LIBINPUT_CONFIG_SCROLL_NO_SCROLL: 4497 case LIBINPUT_CONFIG_SCROLL_2FG: 4498 case LIBINPUT_CONFIG_SCROLL_EDGE: 4499 case LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN: 4500 break; 4501 default: 4502 return LIBINPUT_CONFIG_STATUS_INVALID; 4503 } 4504 4505 if ((libinput_device_config_scroll_get_methods(device) & method) != method) 4506 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4507 4508 if (device->config.scroll_method) 4509 return device->config.scroll_method->set_method(device, method); 4510 4511 /* method must be _NO_SCROLL to get here */ 4512 return LIBINPUT_CONFIG_STATUS_SUCCESS; 4513} 4514 4515LIBINPUT_EXPORT enum libinput_config_scroll_method 4516libinput_device_config_scroll_get_method(struct libinput_device *device) 4517{ 4518 if (device->config.scroll_method) 4519 return device->config.scroll_method->get_method(device); 4520 4521 return LIBINPUT_CONFIG_SCROLL_NO_SCROLL; 4522} 4523 4524LIBINPUT_EXPORT enum libinput_config_scroll_method 4525libinput_device_config_scroll_get_default_method(struct libinput_device *device) 4526{ 4527 if (device->config.scroll_method) 4528 return device->config.scroll_method->get_default_method(device); 4529 4530 return LIBINPUT_CONFIG_SCROLL_NO_SCROLL; 4531} 4532 4533LIBINPUT_EXPORT enum libinput_config_status 4534libinput_device_config_scroll_set_button(struct libinput_device *device, 4535 uint32_t button) 4536{ 4537 if ((libinput_device_config_scroll_get_methods(device) & 4538 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4539 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4540 4541 if (button && !libinput_device_pointer_has_button(device, button)) 4542 return LIBINPUT_CONFIG_STATUS_INVALID; 4543 4544 return device->config.scroll_method->set_button(device, button); 4545} 4546 4547LIBINPUT_EXPORT uint32_t 4548libinput_device_config_scroll_get_button(struct libinput_device *device) 4549{ 4550 if ((libinput_device_config_scroll_get_methods(device) & 4551 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4552 return 0; 4553 4554 return device->config.scroll_method->get_button(device); 4555} 4556 4557LIBINPUT_EXPORT uint32_t 4558libinput_device_config_scroll_get_default_button(struct libinput_device *device) 4559{ 4560 if ((libinput_device_config_scroll_get_methods(device) & 4561 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4562 return 0; 4563 4564 return device->config.scroll_method->get_default_button(device); 4565} 4566 4567LIBINPUT_EXPORT enum libinput_config_status 4568libinput_device_config_scroll_set_button_lock(struct libinput_device *device, 4569 enum libinput_config_scroll_button_lock_state state) 4570{ 4571 if ((libinput_device_config_scroll_get_methods(device) & 4572 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4573 return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; 4574 4575 switch (state) { 4576 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED: 4577 case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED: 4578 break; 4579 default: 4580 return LIBINPUT_CONFIG_STATUS_INVALID; 4581 } 4582 4583 return device->config.scroll_method->set_button_lock(device, state); 4584} 4585 4586LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state 4587libinput_device_config_scroll_get_button_lock(struct libinput_device *device) 4588{ 4589 if ((libinput_device_config_scroll_get_methods(device) & 4590 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4591 return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED; 4592 4593 return device->config.scroll_method->get_button_lock(device); 4594} 4595 4596LIBINPUT_EXPORT enum libinput_config_scroll_button_lock_state 4597libinput_device_config_scroll_get_default_button_lock(struct libinput_device *device) 4598{ 4599 if ((libinput_device_config_scroll_get_methods(device) & 4600 LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) == 0) 4601 return LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED; 4602 4603 return device->config.scroll_method->get_default_button_lock(device); 4604} 4605 4606LIBINPUT_EXPORT int 4607libinput_device_config_dwt_is_available(struct libinput_device *device) 4608{ 4609 if (!device->config.dwt) 4610 return 0; 4611 4612 return device->config.dwt->is_available(device); 4613} 4614 4615LIBINPUT_EXPORT enum libinput_config_status 4616libinput_device_config_dwt_set_enabled(struct libinput_device *device, 4617 enum libinput_config_dwt_state enable) 4618{ 4619 if (enable != LIBINPUT_CONFIG_DWT_ENABLED && 4620 enable != LIBINPUT_CONFIG_DWT_DISABLED) 4621 return LIBINPUT_CONFIG_STATUS_INVALID; 4622 4623 if (!libinput_device_config_dwt_is_available(device)) 4624 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 4625 LIBINPUT_CONFIG_STATUS_SUCCESS; 4626 4627 return device->config.dwt->set_enabled(device, enable); 4628} 4629 4630LIBINPUT_EXPORT enum libinput_config_dwt_state 4631libinput_device_config_dwt_get_enabled(struct libinput_device *device) 4632{ 4633 if (!libinput_device_config_dwt_is_available(device)) 4634 return LIBINPUT_CONFIG_DWT_DISABLED; 4635 4636 return device->config.dwt->get_enabled(device); 4637} 4638 4639LIBINPUT_EXPORT enum libinput_config_dwt_state 4640libinput_device_config_dwt_get_default_enabled(struct libinput_device *device) 4641{ 4642 if (!libinput_device_config_dwt_is_available(device)) 4643 return LIBINPUT_CONFIG_DWT_DISABLED; 4644 4645 return device->config.dwt->get_default_enabled(device); 4646} 4647 4648LIBINPUT_EXPORT int 4649libinput_device_config_dwtp_is_available(struct libinput_device *device) 4650{ 4651 if (!device->config.dwtp) 4652 return 0; 4653 4654 return device->config.dwtp->is_available(device); 4655} 4656 4657LIBINPUT_EXPORT enum libinput_config_status 4658libinput_device_config_dwtp_set_enabled(struct libinput_device *device, 4659 enum libinput_config_dwtp_state enable) 4660{ 4661 if (enable != LIBINPUT_CONFIG_DWTP_ENABLED && 4662 enable != LIBINPUT_CONFIG_DWTP_DISABLED) 4663 return LIBINPUT_CONFIG_STATUS_INVALID; 4664 4665 if (!libinput_device_config_dwtp_is_available(device)) 4666 return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 4667 LIBINPUT_CONFIG_STATUS_SUCCESS; 4668 4669 return device->config.dwtp->set_enabled(device, enable); 4670} 4671 4672LIBINPUT_EXPORT enum libinput_config_dwtp_state 4673libinput_device_config_dwtp_get_enabled(struct libinput_device *device) 4674{ 4675 if (!libinput_device_config_dwtp_is_available(device)) 4676 return LIBINPUT_CONFIG_DWTP_DISABLED; 4677 4678 return device->config.dwtp->get_enabled(device); 4679} 4680 4681LIBINPUT_EXPORT enum libinput_config_dwtp_state 4682libinput_device_config_dwtp_get_default_enabled(struct libinput_device *device) 4683{ 4684 if (!libinput_device_config_dwtp_is_available(device)) 4685 return LIBINPUT_CONFIG_DWTP_DISABLED; 4686 4687 return device->config.dwtp->get_default_enabled(device); 4688} 4689 4690LIBINPUT_EXPORT int 4691libinput_device_config_rotation_is_available(struct libinput_device *device) 4692{ 4693 if (!device->config.rotation) 4694 return 0; 4695 4696 return device->config.rotation->is_available(device); 4697} 4698 4699LIBINPUT_EXPORT enum libinput_config_status 4700libinput_device_config_rotation_set_angle(struct libinput_device *device, 4701 unsigned int degrees_cw) 4702{ 4703 if (!libinput_device_config_rotation_is_available(device)) 4704 return degrees_cw ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED : 4705 LIBINPUT_CONFIG_STATUS_SUCCESS; 4706 4707 if (degrees_cw >= 360) 4708 return LIBINPUT_CONFIG_STATUS_INVALID; 4709 4710 return device->config.rotation->set_angle(device, degrees_cw); 4711} 4712 4713LIBINPUT_EXPORT unsigned int 4714libinput_device_config_rotation_get_angle(struct libinput_device *device) 4715{ 4716 if (!libinput_device_config_rotation_is_available(device)) 4717 return 0; 4718 4719 return device->config.rotation->get_angle(device); 4720} 4721 4722LIBINPUT_EXPORT unsigned int 4723libinput_device_config_rotation_get_default_angle(struct libinput_device *device) 4724{ 4725 if (!libinput_device_config_rotation_is_available(device)) 4726 return 0; 4727 4728 return device->config.rotation->get_default_angle(device); 4729} 4730 4731#if HAVE_LIBWACOM 4732WacomDeviceDatabase * 4733libinput_libwacom_ref(struct libinput *li) 4734{ 4735 WacomDeviceDatabase *db = NULL; 4736 if (!li->libwacom.db) { 4737 db = libwacom_database_new(); 4738 if (!db) { 4739 log_error(li, 4740 "Failed to initialize libwacom context\n"); 4741 return NULL; 4742 } 4743 4744 li->libwacom.db = db; 4745 li->libwacom.refcount = 0; 4746 } 4747 4748 li->libwacom.refcount++; 4749 db = li->libwacom.db; 4750 return db; 4751} 4752 4753void 4754libinput_libwacom_unref(struct libinput *li) 4755{ 4756 if (!li->libwacom.db) 4757 return; 4758 4759 assert(li->libwacom.refcount >= 1); 4760 4761 if (--li->libwacom.refcount == 0) { 4762 libwacom_database_destroy(li->libwacom.db); 4763 li->libwacom.db = NULL; 4764 } 4765} 4766#endif 4767