1 /*- 2 * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org> 3 * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@cicgroup.ru> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #include "opt_evdev.h" 31 32 #include <sys/types.h> 33 #include <sys/bitstring.h> 34 #include <sys/systm.h> 35 #include <sys/param.h> 36 #include <sys/kernel.h> 37 #include <sys/conf.h> 38 #include <sys/uio.h> 39 #include <sys/proc.h> 40 #include <sys/poll.h> 41 #include <sys/filio.h> 42 #include <sys/fcntl.h> 43 #include <sys/selinfo.h> 44 #include <sys/malloc.h> 45 #include <sys/time.h> 46 47 #include <dev/evdev/input.h> 48 #include <dev/evdev/evdev.h> 49 #include <dev/evdev/evdev_private.h> 50 51 #ifdef EVDEV_DEBUG 52 #define debugf(client, fmt, args...) printf("evdev cdev: "fmt"\n", ##args) 53 #else 54 #define debugf(client, fmt, args...) 55 #endif 56 57 #define DEF_RING_REPORTS 8 58 59 static d_open_t evdev_open; 60 static d_read_t evdev_read; 61 static d_write_t evdev_write; 62 static d_ioctl_t evdev_ioctl; 63 static d_poll_t evdev_poll; 64 static d_kqfilter_t evdev_kqfilter; 65 66 static int evdev_kqread(struct knote *kn, long hint); 67 static void evdev_kqdetach(struct knote *kn); 68 static void evdev_dtor(void *); 69 static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t); 70 static void evdev_client_filter_queue(struct evdev_client *, uint16_t); 71 72 static struct cdevsw evdev_cdevsw = { 73 .d_version = D_VERSION, 74 .d_open = evdev_open, 75 .d_read = evdev_read, 76 .d_write = evdev_write, 77 .d_ioctl = evdev_ioctl, 78 .d_poll = evdev_poll, 79 .d_kqfilter = evdev_kqfilter, 80 .d_name = "evdev", 81 }; 82 83 static struct filterops evdev_cdev_filterops = { 84 .f_isfd = 1, 85 .f_attach = NULL, 86 .f_detach = evdev_kqdetach, 87 .f_event = evdev_kqread, 88 }; 89 90 static int 91 evdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) 92 { 93 struct evdev_dev *evdev = dev->si_drv1; 94 struct evdev_client *client; 95 size_t buffer_size; 96 int ret; 97 98 if (evdev == NULL) 99 return (ENODEV); 100 101 /* Initialize client structure */ 102 buffer_size = evdev->ev_report_size * DEF_RING_REPORTS; 103 client = malloc(offsetof(struct evdev_client, ec_buffer) + 104 sizeof(struct input_event) * buffer_size, 105 M_EVDEV, M_WAITOK | M_ZERO); 106 107 /* Initialize ring buffer */ 108 client->ec_buffer_size = buffer_size; 109 client->ec_buffer_head = 0; 110 client->ec_buffer_tail = 0; 111 client->ec_buffer_ready = 0; 112 113 client->ec_evdev = evdev; 114 mtx_init(&client->ec_buffer_mtx, "evclient", "evdev", MTX_DEF); 115 knlist_init_mtx(&client->ec_selp.si_note, &client->ec_buffer_mtx); 116 117 /* Avoid race with evdev_unregister */ 118 EVDEV_LOCK(evdev); 119 if (dev->si_drv1 == NULL) 120 ret = ENODEV; 121 else 122 ret = evdev_register_client(evdev, client); 123 124 if (ret != 0) 125 evdev_revoke_client(client); 126 /* 127 * Unlock evdev here because non-sleepable lock held 128 * while calling devfs_set_cdevpriv upsets WITNESS 129 */ 130 EVDEV_UNLOCK(evdev); 131 132 if (!ret) 133 ret = devfs_set_cdevpriv(client, evdev_dtor); 134 135 if (ret != 0) { 136 debugf(client, "cannot register evdev client"); 137 evdev_dtor(client); 138 } 139 140 return (ret); 141 } 142 143 static void 144 evdev_dtor(void *data) 145 { 146 struct evdev_client *client = (struct evdev_client *)data; 147 148 EVDEV_LOCK(client->ec_evdev); 149 if (!client->ec_revoked) 150 evdev_dispose_client(client->ec_evdev, client); 151 EVDEV_UNLOCK(client->ec_evdev); 152 153 knlist_clear(&client->ec_selp.si_note, 0); 154 seldrain(&client->ec_selp); 155 knlist_destroy(&client->ec_selp.si_note); 156 funsetown(&client->ec_sigio); 157 mtx_destroy(&client->ec_buffer_mtx); 158 free(client, M_EVDEV); 159 } 160 161 static int 162 evdev_read(struct cdev *dev, struct uio *uio, int ioflag) 163 { 164 struct evdev_client *client; 165 struct input_event event; 166 int ret = 0; 167 int remaining; 168 169 ret = devfs_get_cdevpriv((void **)&client); 170 if (ret != 0) 171 return (ret); 172 173 debugf(client, "read %zd bytes by thread %d", uio->uio_resid, 174 uio->uio_td->td_tid); 175 176 if (client->ec_revoked) 177 return (ENODEV); 178 179 /* Zero-sized reads are allowed for error checking */ 180 if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event)) 181 return (EINVAL); 182 183 remaining = uio->uio_resid / sizeof(struct input_event); 184 185 EVDEV_CLIENT_LOCKQ(client); 186 187 if (EVDEV_CLIENT_EMPTYQ(client)) { 188 if (ioflag & O_NONBLOCK) 189 ret = EWOULDBLOCK; 190 else { 191 if (remaining != 0) { 192 client->ec_blocked = true; 193 ret = mtx_sleep(client, &client->ec_buffer_mtx, 194 PCATCH, "evread", 0); 195 } 196 } 197 } 198 199 while (ret == 0 && !EVDEV_CLIENT_EMPTYQ(client) && remaining > 0) { 200 memcpy(&event, &client->ec_buffer[client->ec_buffer_head], 201 sizeof(struct input_event)); 202 client->ec_buffer_head = 203 (client->ec_buffer_head + 1) % client->ec_buffer_size; 204 remaining--; 205 206 EVDEV_CLIENT_UNLOCKQ(client); 207 ret = uiomove(&event, sizeof(struct input_event), uio); 208 EVDEV_CLIENT_LOCKQ(client); 209 } 210 211 EVDEV_CLIENT_UNLOCKQ(client); 212 213 return (ret); 214 } 215 216 static int 217 evdev_write(struct cdev *dev, struct uio *uio, int ioflag) 218 { 219 struct evdev_dev *evdev = dev->si_drv1; 220 struct evdev_client *client; 221 struct input_event event; 222 int ret = 0; 223 224 ret = devfs_get_cdevpriv((void **)&client); 225 if (ret != 0) 226 return (ret); 227 228 debugf(client, "write %zd bytes by thread %d", uio->uio_resid, 229 uio->uio_td->td_tid); 230 231 if (client->ec_revoked || evdev == NULL) 232 return (ENODEV); 233 234 if (uio->uio_resid % sizeof(struct input_event) != 0) { 235 debugf(client, "write size not multiple of input_event size"); 236 return (EINVAL); 237 } 238 239 while (uio->uio_resid > 0 && ret == 0) { 240 ret = uiomove(&event, sizeof(struct input_event), uio); 241 if (ret == 0) 242 ret = evdev_inject_event(evdev, event.type, event.code, 243 event.value); 244 } 245 246 return (ret); 247 } 248 249 static int 250 evdev_poll(struct cdev *dev, int events, struct thread *td) 251 { 252 struct evdev_client *client; 253 int ret; 254 int revents = 0; 255 256 ret = devfs_get_cdevpriv((void **)&client); 257 if (ret != 0) 258 return (POLLNVAL); 259 260 debugf(client, "poll by thread %d", td->td_tid); 261 262 if (client->ec_revoked) 263 return (POLLHUP); 264 265 if (events & (POLLIN | POLLRDNORM)) { 266 EVDEV_CLIENT_LOCKQ(client); 267 if (!EVDEV_CLIENT_EMPTYQ(client)) 268 revents = events & (POLLIN | POLLRDNORM); 269 else { 270 client->ec_selected = true; 271 selrecord(td, &client->ec_selp); 272 } 273 EVDEV_CLIENT_UNLOCKQ(client); 274 } 275 276 return (revents); 277 } 278 279 static int 280 evdev_kqfilter(struct cdev *dev, struct knote *kn) 281 { 282 struct evdev_client *client; 283 int ret; 284 285 ret = devfs_get_cdevpriv((void **)&client); 286 if (ret != 0) 287 return (ret); 288 289 if (client->ec_revoked) 290 return (ENODEV); 291 292 switch(kn->kn_filter) { 293 case EVFILT_READ: 294 kn->kn_fop = &evdev_cdev_filterops; 295 break; 296 default: 297 return(EINVAL); 298 } 299 kn->kn_hook = (caddr_t)client; 300 301 knlist_add(&client->ec_selp.si_note, kn, 0); 302 return (0); 303 } 304 305 static int 306 evdev_kqread(struct knote *kn, long hint) 307 { 308 struct evdev_client *client; 309 int ret; 310 311 client = (struct evdev_client *)kn->kn_hook; 312 313 EVDEV_CLIENT_LOCKQ_ASSERT(client); 314 315 if (client->ec_revoked) { 316 kn->kn_flags |= EV_EOF; 317 ret = 1; 318 } else { 319 kn->kn_data = EVDEV_CLIENT_SIZEQ(client) * 320 sizeof(struct input_event); 321 ret = !EVDEV_CLIENT_EMPTYQ(client); 322 } 323 return (ret); 324 } 325 326 static void 327 evdev_kqdetach(struct knote *kn) 328 { 329 struct evdev_client *client; 330 331 client = (struct evdev_client *)kn->kn_hook; 332 knlist_remove(&client->ec_selp.si_note, kn, 0); 333 } 334 335 static int 336 evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 337 struct thread *td) 338 { 339 struct evdev_dev *evdev = dev->si_drv1; 340 struct evdev_client *client; 341 struct input_keymap_entry *ke; 342 int ret, len, limit, type_num; 343 uint32_t code; 344 size_t nvalues; 345 346 ret = devfs_get_cdevpriv((void **)&client); 347 if (ret != 0) 348 return (ret); 349 350 if (client->ec_revoked || evdev == NULL) 351 return (ENODEV); 352 353 /* file I/O ioctl handling */ 354 switch (cmd) { 355 case FIOSETOWN: 356 return (fsetown(*(int *)data, &client->ec_sigio)); 357 358 case FIOGETOWN: 359 *(int *)data = fgetown(&client->ec_sigio); 360 return (0); 361 362 case FIONBIO: 363 return (0); 364 365 case FIOASYNC: 366 if (*(int *)data) 367 client->ec_async = true; 368 else 369 client->ec_async = false; 370 371 return (0); 372 373 case FIONREAD: 374 EVDEV_CLIENT_LOCKQ(client); 375 *(int *)data = 376 EVDEV_CLIENT_SIZEQ(client) * sizeof(struct input_event); 377 EVDEV_CLIENT_UNLOCKQ(client); 378 return (0); 379 } 380 381 len = IOCPARM_LEN(cmd); 382 debugf(client, "ioctl called: cmd=0x%08lx, data=%p", cmd, data); 383 384 /* evdev fixed-length ioctls handling */ 385 switch (cmd) { 386 case EVIOCGVERSION: 387 *(int *)data = EV_VERSION; 388 return (0); 389 390 case EVIOCGID: 391 debugf(client, "EVIOCGID: bus=%d vendor=0x%04x product=0x%04x", 392 evdev->ev_id.bustype, evdev->ev_id.vendor, 393 evdev->ev_id.product); 394 memcpy(data, &evdev->ev_id, sizeof(struct input_id)); 395 return (0); 396 397 case EVIOCGREP: 398 if (!evdev_event_supported(evdev, EV_REP)) 399 return (ENOTSUP); 400 401 memcpy(data, evdev->ev_rep, sizeof(evdev->ev_rep)); 402 return (0); 403 404 case EVIOCSREP: 405 if (!evdev_event_supported(evdev, EV_REP)) 406 return (ENOTSUP); 407 408 evdev_inject_event(evdev, EV_REP, REP_DELAY, ((int *)data)[0]); 409 evdev_inject_event(evdev, EV_REP, REP_PERIOD, 410 ((int *)data)[1]); 411 return (0); 412 413 case EVIOCGKEYCODE: 414 /* Fake unsupported ioctl */ 415 return (0); 416 417 case EVIOCGKEYCODE_V2: 418 if (evdev->ev_methods == NULL || 419 evdev->ev_methods->ev_get_keycode == NULL) 420 return (ENOTSUP); 421 422 ke = (struct input_keymap_entry *)data; 423 evdev->ev_methods->ev_get_keycode(evdev, evdev->ev_softc, ke); 424 return (0); 425 426 case EVIOCSKEYCODE: 427 /* Fake unsupported ioctl */ 428 return (0); 429 430 case EVIOCSKEYCODE_V2: 431 if (evdev->ev_methods == NULL || 432 evdev->ev_methods->ev_set_keycode == NULL) 433 return (ENOTSUP); 434 435 ke = (struct input_keymap_entry *)data; 436 evdev->ev_methods->ev_set_keycode(evdev, evdev->ev_softc, ke); 437 return (0); 438 439 case EVIOCGABS(0) ... EVIOCGABS(ABS_MAX): 440 if (evdev->ev_absinfo == NULL) 441 return (EINVAL); 442 443 memcpy(data, &evdev->ev_absinfo[cmd - EVIOCGABS(0)], 444 sizeof(struct input_absinfo)); 445 return (0); 446 447 case EVIOCSABS(0) ... EVIOCSABS(ABS_MAX): 448 if (evdev->ev_absinfo == NULL) 449 return (EINVAL); 450 451 code = cmd - EVIOCSABS(0); 452 /* mt-slot number can not be changed */ 453 if (code == ABS_MT_SLOT) 454 return (EINVAL); 455 456 EVDEV_LOCK(evdev); 457 evdev_set_absinfo(evdev, code, (struct input_absinfo *)data); 458 EVDEV_UNLOCK(evdev); 459 return (0); 460 461 case EVIOCSFF: 462 case EVIOCRMFF: 463 case EVIOCGEFFECTS: 464 /* Fake unsupported ioctls */ 465 return (0); 466 467 case EVIOCGRAB: 468 EVDEV_LOCK(evdev); 469 if (*(int *)data) 470 ret = evdev_grab_client(evdev, client); 471 else 472 ret = evdev_release_client(evdev, client); 473 EVDEV_UNLOCK(evdev); 474 return (ret); 475 476 case EVIOCREVOKE: 477 if (*(int *)data != 0) 478 return (EINVAL); 479 480 EVDEV_LOCK(evdev); 481 if (dev->si_drv1 != NULL && !client->ec_revoked) { 482 evdev_dispose_client(evdev, client); 483 evdev_revoke_client(client); 484 } 485 EVDEV_UNLOCK(evdev); 486 return (0); 487 488 case EVIOCSCLOCKID: 489 switch (*(int *)data) { 490 case CLOCK_REALTIME: 491 client->ec_clock_id = EV_CLOCK_REALTIME; 492 return (0); 493 case CLOCK_MONOTONIC: 494 client->ec_clock_id = EV_CLOCK_MONOTONIC; 495 return (0); 496 default: 497 return (EINVAL); 498 } 499 } 500 501 /* evdev variable-length ioctls handling */ 502 switch (IOCBASECMD(cmd)) { 503 case EVIOCGNAME(0): 504 strlcpy(data, evdev->ev_name, len); 505 return (0); 506 507 case EVIOCGPHYS(0): 508 if (evdev->ev_shortname[0] == 0) 509 return (ENOENT); 510 511 strlcpy(data, evdev->ev_shortname, len); 512 return (0); 513 514 case EVIOCGUNIQ(0): 515 if (evdev->ev_serial[0] == 0) 516 return (ENOENT); 517 518 strlcpy(data, evdev->ev_serial, len); 519 return (0); 520 521 case EVIOCGPROP(0): 522 limit = MIN(len, bitstr_size(INPUT_PROP_CNT)); 523 memcpy(data, evdev->ev_prop_flags, limit); 524 return (0); 525 526 case EVIOCGMTSLOTS(0): 527 if (evdev->ev_mt == NULL) 528 return (EINVAL); 529 if (len < sizeof(uint32_t)) 530 return (EINVAL); 531 code = *(uint32_t *)data; 532 if (!ABS_IS_MT(code)) 533 return (EINVAL); 534 535 nvalues = 536 MIN(len / sizeof(int32_t) - 1, MAXIMAL_MT_SLOT(evdev) + 1); 537 for (int i = 0; i < nvalues; i++) 538 ((int32_t *)data)[i + 1] = 539 evdev_get_mt_value(evdev, i, code); 540 return (0); 541 542 case EVIOCGKEY(0): 543 limit = MIN(len, bitstr_size(KEY_CNT)); 544 EVDEV_LOCK(evdev); 545 evdev_client_filter_queue(client, EV_KEY); 546 memcpy(data, evdev->ev_key_states, limit); 547 EVDEV_UNLOCK(evdev); 548 return (0); 549 550 case EVIOCGLED(0): 551 limit = MIN(len, bitstr_size(LED_CNT)); 552 EVDEV_LOCK(evdev); 553 evdev_client_filter_queue(client, EV_LED); 554 memcpy(data, evdev->ev_led_states, limit); 555 EVDEV_UNLOCK(evdev); 556 return (0); 557 558 case EVIOCGSND(0): 559 limit = MIN(len, bitstr_size(SND_CNT)); 560 EVDEV_LOCK(evdev); 561 evdev_client_filter_queue(client, EV_SND); 562 memcpy(data, evdev->ev_snd_states, limit); 563 EVDEV_UNLOCK(evdev); 564 return (0); 565 566 case EVIOCGSW(0): 567 limit = MIN(len, bitstr_size(SW_CNT)); 568 EVDEV_LOCK(evdev); 569 evdev_client_filter_queue(client, EV_SW); 570 memcpy(data, evdev->ev_sw_states, limit); 571 EVDEV_UNLOCK(evdev); 572 return (0); 573 574 case EVIOCGBIT(0, 0) ... EVIOCGBIT(EV_MAX, 0): 575 type_num = IOCBASECMD(cmd) - EVIOCGBIT(0, 0); 576 debugf(client, "EVIOCGBIT(%d): data=%p, len=%d", type_num, 577 data, len); 578 return (evdev_ioctl_eviocgbit(evdev, type_num, len, data)); 579 } 580 581 return (EINVAL); 582 } 583 584 static int 585 evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) 586 { 587 unsigned long *bitmap; 588 int limit; 589 590 switch (type) { 591 case 0: 592 bitmap = evdev->ev_type_flags; 593 limit = EV_CNT; 594 break; 595 case EV_KEY: 596 bitmap = evdev->ev_key_flags; 597 limit = KEY_CNT; 598 break; 599 case EV_REL: 600 bitmap = evdev->ev_rel_flags; 601 limit = REL_CNT; 602 break; 603 case EV_ABS: 604 bitmap = evdev->ev_abs_flags; 605 limit = ABS_CNT; 606 break; 607 case EV_MSC: 608 bitmap = evdev->ev_msc_flags; 609 limit = MSC_CNT; 610 break; 611 case EV_LED: 612 bitmap = evdev->ev_led_flags; 613 limit = LED_CNT; 614 break; 615 case EV_SND: 616 bitmap = evdev->ev_snd_flags; 617 limit = SND_CNT; 618 break; 619 case EV_SW: 620 bitmap = evdev->ev_sw_flags; 621 limit = SW_CNT; 622 break; 623 case EV_FF: 624 /* 625 * We don't support EV_FF now, so let's 626 * just fake it returning only zeros. 627 */ 628 bzero(data, len); 629 return (0); 630 default: 631 return (ENOTTY); 632 } 633 634 /* 635 * Clear ioctl data buffer in case it's bigger than 636 * bitmap size 637 */ 638 bzero(data, len); 639 640 limit = bitstr_size(limit); 641 len = MIN(limit, len); 642 memcpy(data, bitmap, len); 643 return (0); 644 } 645 646 void 647 evdev_revoke_client(struct evdev_client *client) 648 { 649 650 EVDEV_LOCK_ASSERT(client->ec_evdev); 651 652 client->ec_revoked = true; 653 } 654 655 void 656 evdev_notify_event(struct evdev_client *client) 657 { 658 659 EVDEV_CLIENT_LOCKQ_ASSERT(client); 660 661 if (client->ec_blocked) { 662 client->ec_blocked = false; 663 wakeup(client); 664 } 665 if (client->ec_selected) { 666 client->ec_selected = false; 667 selwakeup(&client->ec_selp); 668 } 669 KNOTE_LOCKED(&client->ec_selp.si_note, 0); 670 671 if (client->ec_async && client->ec_sigio != NULL) 672 pgsigio(&client->ec_sigio, SIGIO, 0); 673 } 674 675 int 676 evdev_cdev_create(struct evdev_dev *evdev) 677 { 678 struct make_dev_args mda; 679 int ret, unit = 0; 680 681 make_dev_args_init(&mda); 682 mda.mda_flags = MAKEDEV_WAITOK | MAKEDEV_CHECKNAME; 683 mda.mda_devsw = &evdev_cdevsw; 684 mda.mda_uid = UID_ROOT; 685 mda.mda_gid = GID_WHEEL; 686 mda.mda_mode = 0600; 687 mda.mda_si_drv1 = evdev; 688 689 /* Try to coexist with cuse-backed input/event devices */ 690 while ((ret = make_dev_s(&mda, &evdev->ev_cdev, "input/event%d", unit)) 691 == EEXIST) 692 unit++; 693 694 if (ret == 0) 695 evdev->ev_unit = unit; 696 697 return (ret); 698 } 699 700 int 701 evdev_cdev_destroy(struct evdev_dev *evdev) 702 { 703 704 destroy_dev(evdev->ev_cdev); 705 return (0); 706 } 707 708 static void 709 evdev_client_gettime(struct evdev_client *client, struct timeval *tv) 710 { 711 712 switch (client->ec_clock_id) { 713 case EV_CLOCK_BOOTTIME: 714 /* 715 * XXX: FreeBSD does not support true POSIX monotonic clock. 716 * So aliase EV_CLOCK_BOOTTIME to EV_CLOCK_MONOTONIC. 717 */ 718 case EV_CLOCK_MONOTONIC: 719 microuptime(tv); 720 break; 721 722 case EV_CLOCK_REALTIME: 723 default: 724 microtime(tv); 725 break; 726 } 727 } 728 729 void 730 evdev_client_push(struct evdev_client *client, uint16_t type, uint16_t code, 731 int32_t value) 732 { 733 struct timeval time; 734 size_t count, head, tail, ready; 735 736 EVDEV_CLIENT_LOCKQ_ASSERT(client); 737 head = client->ec_buffer_head; 738 tail = client->ec_buffer_tail; 739 ready = client->ec_buffer_ready; 740 count = client->ec_buffer_size; 741 742 /* If queue is full drop its content and place SYN_DROPPED event */ 743 if ((tail + 1) % count == head) { 744 debugf(client, "client %p: buffer overflow", client); 745 746 head = (tail + count - 1) % count; 747 client->ec_buffer[head] = (struct input_event) { 748 .type = EV_SYN, 749 .code = SYN_DROPPED, 750 .value = 0 751 }; 752 /* 753 * XXX: Here is a small race window from now till the end of 754 * report. The queue is empty but client has been already 755 * notified of data readyness. Can be fixed in two ways: 756 * 1. Implement bulk insert so queue lock would not be dropped 757 * till the SYN_REPORT event. 758 * 2. Insert SYN_REPORT just now and skip remaining events 759 */ 760 client->ec_buffer_head = head; 761 client->ec_buffer_ready = head; 762 } 763 764 client->ec_buffer[tail].type = type; 765 client->ec_buffer[tail].code = code; 766 client->ec_buffer[tail].value = value; 767 client->ec_buffer_tail = (tail + 1) % count; 768 769 /* Allow users to read events only after report has been completed */ 770 if (type == EV_SYN && code == SYN_REPORT) { 771 evdev_client_gettime(client, &time); 772 for (; ready != client->ec_buffer_tail; 773 ready = (ready + 1) % count) 774 client->ec_buffer[ready].time = time; 775 client->ec_buffer_ready = client->ec_buffer_tail; 776 } 777 } 778 779 void 780 evdev_client_dumpqueue(struct evdev_client *client) 781 { 782 struct input_event *event; 783 size_t i, head, tail, ready, size; 784 785 head = client->ec_buffer_head; 786 tail = client->ec_buffer_tail; 787 ready = client->ec_buffer_ready; 788 size = client->ec_buffer_size; 789 790 printf("evdev client: %p\n", client); 791 printf("event queue: head=%zu ready=%zu tail=%zu size=%zu\n", 792 head, ready, tail, size); 793 794 printf("queue contents:\n"); 795 796 for (i = 0; i < size; i++) { 797 event = &client->ec_buffer[i]; 798 printf("%zu: ", i); 799 800 if (i < head || i > tail) 801 printf("unused\n"); 802 else 803 printf("type=%d code=%d value=%d ", event->type, 804 event->code, event->value); 805 806 if (i == head) 807 printf("<- head\n"); 808 else if (i == tail) 809 printf("<- tail\n"); 810 else if (i == ready) 811 printf("<- ready\n"); 812 else 813 printf("\n"); 814 } 815 } 816 817 static void 818 evdev_client_filter_queue(struct evdev_client *client, uint16_t type) 819 { 820 struct input_event *event; 821 size_t head, tail, count, i; 822 bool last_was_syn = false; 823 824 EVDEV_CLIENT_LOCKQ(client); 825 826 i = head = client->ec_buffer_head; 827 tail = client->ec_buffer_tail; 828 count = client->ec_buffer_size; 829 client->ec_buffer_ready = client->ec_buffer_tail; 830 831 while (i != client->ec_buffer_tail) { 832 event = &client->ec_buffer[i]; 833 i = (i + 1) % count; 834 835 /* Skip event of given type */ 836 if (event->type == type) 837 continue; 838 839 /* Remove empty SYN_REPORT events */ 840 if (event->type == EV_SYN && event->code == SYN_REPORT) { 841 if (last_was_syn) 842 continue; 843 else 844 client->ec_buffer_ready = (tail + 1) % count; 845 } 846 847 /* Rewrite entry */ 848 memcpy(&client->ec_buffer[tail], event, 849 sizeof(struct input_event)); 850 851 last_was_syn = (event->type == EV_SYN && 852 event->code == SYN_REPORT); 853 854 tail = (tail + 1) % count; 855 } 856 857 client->ec_buffer_head = i; 858 client->ec_buffer_tail = tail; 859 860 EVDEV_CLIENT_UNLOCKQ(client); 861 } 862