1/* 2 * Copyright © 2013-2017 Red Hat, Inc. 3 * Copyright © 2020 Povilas Kanapickas <povilas@radix.lt> 4 * 5 * Permission to use, copy, modify, distribute, and sell this software 6 * and its documentation for any purpose is hereby granted without 7 * fee, provided that the above copyright notice appear in all copies 8 * and that both that copyright notice and this permission notice 9 * appear in supporting documentation, and that the name of Red Hat 10 * not be used in advertising or publicity pertaining to distribution 11 * of the software without specific, written prior permission. Red 12 * Hat makes no representations about the suitability of this software 13 * for any purpose. It is provided "as is" without express or implied 14 * warranty. 15 * 16 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 18 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 23 */ 24 25#ifdef HAVE_XORG_CONFIG_H 26#include <xorg-config.h> 27#endif 28 29#include <errno.h> 30#include <fcntl.h> 31#include <unistd.h> 32#include <exevents.h> 33#include <input.h> 34#include <xkbsrv.h> 35#include <xf86.h> 36#include <xf86Xinput.h> 37#include "xorgVersion.h" 38#include <xserver-properties.h> 39#include <os.h> 40#include <X11/Xatom.h> 41 42#include <sys/socket.h> 43#include <sys/stat.h> 44#include <sys/un.h> 45#include <stdbool.h> 46 47#include "xf86-input-inputtest-protocol.h" 48 49#define MAX_POINTER_NUM_AXES 5 /* x, y, hscroll, vscroll, [pressure] */ 50#define MAX_TOUCH_NUM_AXES 5 /* x, y, hscroll, vscroll, pressure */ 51#define TOUCH_MAX_SLOTS 15 52 53#define TOUCH_AXIS_MAX 0xffff 54#define TABLET_PRESSURE_AXIS_MAX 2047 55 56#define EVENT_BUFFER_SIZE 4096 57 58enum xf86ITDeviceType { 59 DEVICE_KEYBOARD = 1, 60 DEVICE_POINTER, 61 DEVICE_POINTER_GESTURE, 62 DEVICE_POINTER_ABS, 63 DEVICE_POINTER_ABS_PROXIMITY, 64 DEVICE_TOUCH, 65}; 66 67enum xf86ITClientState { 68 CLIENT_STATE_NOT_CONNECTED = 0, 69 70 /* connection_fd is valid */ 71 CLIENT_STATE_NEW, 72 73 /* connection_fd is valid and client_protocol.{major,minor} are set */ 74 CLIENT_STATE_READY, 75}; 76 77typedef struct { 78 InputInfoPtr pInfo; 79 80 int socket_fd; /* for accepting new clients */ 81 int connection_fd; /* current client connection */ 82 83 char *socket_path; 84 85 enum xf86ITClientState client_state; 86 struct { 87 int major, minor; 88 } client_protocol; 89 90 struct { 91 char data[EVENT_BUFFER_SIZE]; 92 int valid_length; 93 } buffer; 94 95 uint32_t device_type; 96 97 /* last_processed_event_num == last_event_num and waiting_for_drain != 0 must never be true 98 both at the same time. This would mean that we are waiting for the input queue to be 99 processed, yet all events have already been processed, i.e. a deadlock. 100 101 waiting_for_drain_mutex protects concurrent access to waiting_for_drain variable which 102 may be modified from multiple threads. 103 */ 104 pthread_mutex_t waiting_for_drain_mutex; 105 bool waiting_for_drain; 106 int last_processed_event_num; 107 int last_event_num; 108 109 ValuatorMask *valuators; 110 ValuatorMask *valuators_unaccelerated; 111} xf86ITDevice, *xf86ITDevicePtr; 112 113static void 114read_input_from_connection(InputInfoPtr pInfo); 115 116static Bool 117notify_sync_finished(ClientPtr ptr, void *closure) 118{ 119 int fd = (int)(intptr_t) closure; 120 xf86ITResponseSyncFinished response; 121 response.header.length = sizeof(response); 122 response.header.type = XF86IT_RESPONSE_SYNC_FINISHED; 123 124 input_lock(); 125 /* we don't really care whether the write succeeds. It may fail if the device is 126 already shut down and the descriptor is closed. 127 */ 128 if (write(fd, &response, response.header.length) != response.header.length) { 129 LogMessageVerbSigSafe(X_ERROR, 0, 130 "inputtest: Failed to write sync response: %s\n", 131 strerror(errno)); 132 } 133 input_unlock(); 134 return TRUE; 135} 136 137static void 138input_drain_callback(CallbackListPtr *callback, void *data, void *call_data) 139{ 140 void *drain_write_closure; 141 InputInfoPtr pInfo = data; 142 xf86ITDevicePtr driver_data = pInfo->private; 143 bool notify_synchronization = false; 144 145 pthread_mutex_lock(&driver_data->waiting_for_drain_mutex); 146 driver_data->last_processed_event_num = driver_data->last_event_num; 147 if (driver_data->waiting_for_drain) { 148 driver_data->waiting_for_drain = false; 149 notify_synchronization = true; 150 } 151 pthread_mutex_unlock(&driver_data->waiting_for_drain_mutex); 152 153 if (notify_synchronization) { 154 drain_write_closure = (void*)(intptr_t) driver_data->connection_fd; 155 /* One input event may result in additional sets of events being submitted to the 156 input queue from the input processing code itself. This results in 157 input_drain_callback being called multiple times. 158 159 We therefore schedule a WorkProc (to be run when the server is no longer busy) 160 to notify the client when all current events have been processed. 161 */ 162 xf86IDrvMsg(pInfo, X_DEBUG, "Synchronization finished\n"); 163 QueueWorkProc(notify_sync_finished, NULL, drain_write_closure); 164 } 165} 166 167static void 168read_events(int fd, int ready, void *data) 169{ 170 DeviceIntPtr dev = (DeviceIntPtr) data; 171 InputInfoPtr pInfo = dev->public.devicePrivate; 172 read_input_from_connection(pInfo); 173} 174 175static void 176try_accept_connection(int fd, int ready, void *data) 177{ 178 DeviceIntPtr dev = (DeviceIntPtr) data; 179 InputInfoPtr pInfo = dev->public.devicePrivate; 180 xf86ITDevicePtr driver_data = pInfo->private; 181 int connection_fd; 182 int flags; 183 184 if (driver_data->connection_fd >= 0) 185 return; 186 187 connection_fd = accept(driver_data->socket_fd, NULL, NULL); 188 if (connection_fd < 0) { 189 if (errno == EAGAIN || errno == EWOULDBLOCK) 190 return; 191 xf86IDrvMsg(pInfo, X_ERROR, "Failed to accept a connection\n"); 192 return; 193 } 194 195 xf86IDrvMsg(pInfo, X_DEBUG, "Accepted input control connection\n"); 196 197 flags = fcntl(connection_fd, F_GETFL, 0); 198 fcntl(connection_fd, F_SETFL, flags | O_NONBLOCK); 199 200 driver_data->connection_fd = connection_fd; 201 xf86AddInputEventDrainCallback(input_drain_callback, pInfo); 202 SetNotifyFd(driver_data->connection_fd, read_events, X_NOTIFY_READ, dev); 203 204 driver_data->client_state = CLIENT_STATE_NEW; 205} 206 207static int 208device_on(DeviceIntPtr dev) 209{ 210 InputInfoPtr pInfo = dev->public.devicePrivate; 211 xf86ITDevicePtr driver_data = pInfo->private; 212 213 xf86IDrvMsg(pInfo, X_DEBUG, "Device turned on\n"); 214 215 xf86AddEnabledDevice(pInfo); 216 dev->public.on = TRUE; 217 driver_data->buffer.valid_length = 0; 218 219 try_accept_connection(-1, 0, dev); 220 if (driver_data->connection_fd < 0) 221 SetNotifyFd(driver_data->socket_fd, try_accept_connection, X_NOTIFY_READ, dev); 222 223 return Success; 224} 225 226static void 227teardown_client_connection(InputInfoPtr pInfo) 228{ 229 xf86ITDevicePtr driver_data = pInfo->private; 230 if (driver_data->client_state != CLIENT_STATE_NOT_CONNECTED) { 231 RemoveNotifyFd(driver_data->connection_fd); 232 xf86RemoveInputEventDrainCallback(input_drain_callback, pInfo); 233 234 close(driver_data->connection_fd); 235 driver_data->connection_fd = -1; 236 } 237 RemoveNotifyFd(driver_data->socket_fd); 238 driver_data->client_state = CLIENT_STATE_NOT_CONNECTED; 239} 240 241static int 242device_off(DeviceIntPtr dev) 243{ 244 InputInfoPtr pInfo = dev->public.devicePrivate; 245 246 xf86IDrvMsg(pInfo, X_DEBUG, "Device turned off\n"); 247 248 if (dev->public.on) { 249 teardown_client_connection(pInfo); 250 xf86RemoveEnabledDevice(pInfo); 251 } 252 dev->public.on = FALSE; 253 return Success; 254} 255 256static void 257ptr_ctl(DeviceIntPtr dev, PtrCtrl *ctl) 258{ 259} 260 261static void 262init_button_map(unsigned char *btnmap, size_t size) 263{ 264 int i; 265 266 memset(btnmap, 0, size); 267 for (i = 0; i < size; i++) 268 btnmap[i] = i; 269} 270 271static void 272init_button_labels(Atom *labels, size_t size) 273{ 274 assert(size > 10); 275 276 memset(labels, 0, size * sizeof(Atom)); 277 labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 278 labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 279 labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 280 labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 281 labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); 282 labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 283 labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 284 labels[7] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_SIDE); 285 labels[8] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_EXTRA); 286 labels[9] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_FORWARD); 287 labels[10] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_BACK); 288} 289 290static void 291init_pointer(InputInfoPtr pInfo) 292{ 293 DeviceIntPtr dev= pInfo->dev; 294 int min, max, res; 295 int nbuttons = 7; 296 bool has_pressure = false; 297 int num_axes = 0; 298 299 unsigned char btnmap[MAX_BUTTONS + 1]; 300 Atom btnlabels[MAX_BUTTONS]; 301 Atom axislabels[MAX_POINTER_NUM_AXES]; 302 303 nbuttons = xf86SetIntOption(pInfo->options, "PointerButtonCount", 7); 304 has_pressure = xf86SetBoolOption(pInfo->options, "PointerHasPressure", 305 false); 306 307 init_button_map(btnmap, ARRAY_SIZE(btnmap)); 308 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels)); 309 310 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 311 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 312 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); 313 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); 314 if (has_pressure) 315 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); 316 317 InitPointerDeviceStruct((DevicePtr)dev, 318 btnmap, 319 nbuttons, 320 btnlabels, 321 ptr_ctl, 322 GetMotionHistorySize(), 323 num_axes, 324 axislabels); 325 min = -1; 326 max = -1; 327 res = 0; 328 329 xf86InitValuatorAxisStruct(dev, 0, XIGetKnownProperty(AXIS_LABEL_PROP_REL_X), 330 min, max, res * 1000, 0, res * 1000, Relative); 331 xf86InitValuatorAxisStruct(dev, 1, XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y), 332 min, max, res * 1000, 0, res * 1000, Relative); 333 334 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0); 335 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0); 336 337 if (has_pressure) { 338 xf86InitValuatorAxisStruct(dev, 4, 339 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE), 340 0, 1000, 1, 1, 1, Absolute); 341 } 342} 343 344static void 345init_pointer_absolute(InputInfoPtr pInfo) 346{ 347 DeviceIntPtr dev = pInfo->dev; 348 int min, max, res; 349 int nbuttons = 7; 350 bool has_pressure = false; 351 int num_axes = 0; 352 353 unsigned char btnmap[MAX_BUTTONS + 1]; 354 Atom btnlabels[MAX_BUTTONS]; 355 Atom axislabels[MAX_POINTER_NUM_AXES]; 356 357 nbuttons = xf86SetIntOption(pInfo->options, "PointerButtonCount", 7); 358 has_pressure = xf86SetBoolOption(pInfo->options, "PointerHasPressure", 359 false); 360 361 init_button_map(btnmap, ARRAY_SIZE(btnmap)); 362 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels)); 363 364 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); 365 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); 366 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); 367 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); 368 if (has_pressure) 369 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE); 370 371 InitPointerDeviceStruct((DevicePtr)dev, 372 btnmap, 373 nbuttons, 374 btnlabels, 375 ptr_ctl, 376 GetMotionHistorySize(), 377 num_axes , 378 axislabels); 379 min = 0; 380 max = TOUCH_AXIS_MAX; 381 res = 0; 382 383 xf86InitValuatorAxisStruct(dev, 0, XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X), 384 min, max, res * 1000, 0, res * 1000, Absolute); 385 xf86InitValuatorAxisStruct(dev, 1, XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y), 386 min, max, res * 1000, 0, res * 1000, Absolute); 387 388 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0); 389 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0); 390 391 if (has_pressure) { 392 xf86InitValuatorAxisStruct(dev, 4, 393 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE), 394 0, 1000, 1, 1, 1, Absolute); 395 } 396} 397 398static void 399init_proximity(InputInfoPtr pInfo) 400{ 401 DeviceIntPtr dev = pInfo->dev; 402 InitProximityClassDeviceStruct(dev); 403} 404 405static void 406init_keyboard(InputInfoPtr pInfo) 407{ 408 DeviceIntPtr dev= pInfo->dev; 409 XkbRMLVOSet rmlvo = {0}; 410 XkbRMLVOSet defaults = {0}; 411 412 XkbGetRulesDflts(&defaults); 413 414 rmlvo.rules = xf86SetStrOption(pInfo->options, "xkb_rules", defaults.rules); 415 rmlvo.model = xf86SetStrOption(pInfo->options, "xkb_model", defaults.model); 416 rmlvo.layout = xf86SetStrOption(pInfo->options, "xkb_layout", defaults.layout); 417 rmlvo.variant = xf86SetStrOption(pInfo->options, "xkb_variant", defaults.variant); 418 rmlvo.options = xf86SetStrOption(pInfo->options, "xkb_options", defaults.options); 419 420 InitKeyboardDeviceStruct(dev, &rmlvo, NULL, NULL); 421 XkbFreeRMLVOSet(&rmlvo, FALSE); 422 XkbFreeRMLVOSet(&defaults, FALSE); 423} 424 425static void 426init_touch(InputInfoPtr pInfo) 427{ 428 DeviceIntPtr dev = pInfo->dev; 429 int min, max, res; 430 unsigned char btnmap[MAX_BUTTONS + 1]; 431 Atom btnlabels[MAX_BUTTONS]; 432 Atom axislabels[MAX_TOUCH_NUM_AXES]; 433 int num_axes = 0; 434 int nbuttons = 7; 435 int ntouches = TOUCH_MAX_SLOTS; 436 437 init_button_map(btnmap, ARRAY_SIZE(btnmap)); 438 init_button_labels(btnlabels, ARRAY_SIZE(btnlabels)); 439 440 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X); 441 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y); 442 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); 443 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); 444 axislabels[num_axes++] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PRESSURE); 445 446 InitPointerDeviceStruct((DevicePtr)dev, 447 btnmap, 448 nbuttons, 449 btnlabels, 450 ptr_ctl, 451 GetMotionHistorySize(), 452 num_axes, 453 axislabels); 454 min = 0; 455 max = TOUCH_AXIS_MAX; 456 res = 0; 457 458 xf86InitValuatorAxisStruct(dev, 0, 459 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_X), 460 min, max, res * 1000, 0, res * 1000, Absolute); 461 xf86InitValuatorAxisStruct(dev, 1, 462 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_POSITION_Y), 463 min, max, res * 1000, 0, res * 1000, Absolute); 464 465 SetScrollValuator(dev, 2, SCROLL_TYPE_HORIZONTAL, 120, 0); 466 SetScrollValuator(dev, 3, SCROLL_TYPE_VERTICAL, 120, 0); 467 468 xf86InitValuatorAxisStruct(dev, 4, 469 XIGetKnownProperty(AXIS_LABEL_PROP_ABS_MT_PRESSURE), 470 min, TABLET_PRESSURE_AXIS_MAX, res * 1000, 0, res * 1000, Absolute); 471 472 ntouches = xf86SetIntOption(pInfo->options, "TouchCount", TOUCH_MAX_SLOTS); 473 if (ntouches == 0) /* unknown */ 474 ntouches = TOUCH_MAX_SLOTS; 475 InitTouchClassDeviceStruct(dev, ntouches, XIDirectTouch, 2); 476} 477 478static void 479init_gesture(InputInfoPtr pInfo) 480{ 481 DeviceIntPtr dev = pInfo->dev; 482 int ntouches = TOUCH_MAX_SLOTS; 483 InitGestureClassDeviceStruct(dev, ntouches); 484} 485 486static void 487device_init(DeviceIntPtr dev) 488{ 489 InputInfoPtr pInfo = dev->public.devicePrivate; 490 xf86ITDevicePtr driver_data = pInfo->private; 491 492 dev->public.on = FALSE; 493 494 switch (driver_data->device_type) { 495 case DEVICE_KEYBOARD: 496 init_keyboard(pInfo); 497 break; 498 case DEVICE_POINTER: 499 init_pointer(pInfo); 500 break; 501 case DEVICE_POINTER_GESTURE: 502 init_pointer(pInfo); 503 init_gesture(pInfo); 504 break; 505 case DEVICE_POINTER_ABS: 506 init_pointer_absolute(pInfo); 507 break; 508 case DEVICE_POINTER_ABS_PROXIMITY: 509 init_pointer_absolute(pInfo); 510 init_proximity(pInfo); 511 break; 512 case DEVICE_TOUCH: 513 init_touch(pInfo); 514 break; 515 } 516} 517 518static void 519device_destroy(DeviceIntPtr dev) 520{ 521 InputInfoPtr pInfo = dev->public.devicePrivate; 522 xf86IDrvMsg(pInfo, X_INFO, "Close\n"); 523} 524 525static int 526device_control(DeviceIntPtr dev, int mode) 527{ 528 switch (mode) { 529 case DEVICE_INIT: 530 device_init(dev); 531 break; 532 case DEVICE_ON: 533 device_on(dev); 534 break; 535 case DEVICE_OFF: 536 device_off(dev); 537 break; 538 case DEVICE_CLOSE: 539 device_destroy(dev); 540 break; 541 } 542 543 return Success; 544} 545 546static void 547convert_to_valuator_mask(xf86ITValuatorData *event, ValuatorMask *mask) 548{ 549 valuator_mask_zero(mask); 550 for (int i = 0; i < min(XF86IT_MAX_VALUATORS, MAX_VALUATORS); ++i) { 551 if (BitIsOn(event->mask, i)) { 552 if (event->has_unaccelerated) { 553 valuator_mask_set_unaccelerated(mask, i, event->valuators[i], 554 event->unaccelerated[i]); 555 } else { 556 valuator_mask_set_double(mask, i, event->valuators[i]); 557 } 558 } 559 } 560} 561 562static void 563handle_client_version(InputInfoPtr pInfo, xf86ITEventClientVersion *event) 564{ 565 xf86ITDevicePtr driver_data = pInfo->private; 566 xf86ITResponseServerVersion response; 567 568 response.header.length = sizeof(response); 569 response.header.type = XF86IT_RESPONSE_SERVER_VERSION; 570 response.major = XF86IT_PROTOCOL_VERSION_MAJOR; 571 response.minor = XF86IT_PROTOCOL_VERSION_MINOR; 572 573 if (write(driver_data->connection_fd, &response, response.header.length) != response.header.length) { 574 xf86IDrvMsg(pInfo, X_ERROR, "Error writing driver version: %s\n", strerror(errno)); 575 teardown_client_connection(pInfo); 576 return; 577 } 578 579 if (event->major != XF86IT_PROTOCOL_VERSION_MAJOR || 580 event->minor > XF86IT_PROTOCOL_VERSION_MINOR) 581 { 582 xf86IDrvMsg(pInfo, X_ERROR, "Unsupported protocol version: %d.%d (current %d.%d)\n", 583 event->major, event->minor, 584 XF86IT_PROTOCOL_VERSION_MAJOR, 585 XF86IT_PROTOCOL_VERSION_MINOR); 586 teardown_client_connection(pInfo); 587 return; 588 } 589 590 driver_data->client_protocol.major = event->major; 591 driver_data->client_protocol.minor = event->minor; 592 593 driver_data->client_state = CLIENT_STATE_READY; 594} 595 596static void 597handle_wait_for_sync(InputInfoPtr pInfo) 598{ 599 xf86ITDevicePtr driver_data = pInfo->private; 600 bool notify_synchronization = false; 601 void *drain_write_closure; 602 603 xf86IDrvMsg(pInfo, X_DEBUG, "Handling sync event\n"); 604 605 pthread_mutex_lock(&driver_data->waiting_for_drain_mutex); 606 if (driver_data->last_processed_event_num == driver_data->last_event_num) { 607 notify_synchronization = true; 608 } else { 609 driver_data->waiting_for_drain = true; 610 } 611 pthread_mutex_unlock(&driver_data->waiting_for_drain_mutex); 612 613 if (notify_synchronization) { 614 drain_write_closure = (void*)(intptr_t) driver_data->connection_fd; 615 xf86IDrvMsg(pInfo, X_DEBUG, "Synchronization finished\n"); 616 notify_sync_finished(NULL, drain_write_closure); 617 } 618} 619 620static void 621handle_motion(InputInfoPtr pInfo, xf86ITEventMotion *event) 622{ 623 DeviceIntPtr dev = pInfo->dev; 624 xf86ITDevicePtr driver_data = pInfo->private; 625 ValuatorMask *mask = driver_data->valuators; 626 627 xf86IDrvMsg(pInfo, X_DEBUG, "Handling motion event\n"); 628 629 driver_data->last_event_num++; 630 631 convert_to_valuator_mask(&event->valuators, mask); 632 xf86PostMotionEventM(dev, event->is_absolute ? Absolute : Relative, mask); 633} 634 635static void 636handle_proximity(InputInfoPtr pInfo, xf86ITEventProximity *event) 637{ 638 DeviceIntPtr dev = pInfo->dev; 639 xf86ITDevicePtr driver_data = pInfo->private; 640 ValuatorMask *mask = driver_data->valuators; 641 642 xf86IDrvMsg(pInfo, X_DEBUG, "Handling proximity event\n"); 643 644 driver_data->last_event_num++; 645 646 convert_to_valuator_mask(&event->valuators, mask); 647 xf86PostProximityEventM(dev, event->is_prox_in, mask); 648} 649 650static void 651handle_button(InputInfoPtr pInfo, xf86ITEventButton *event) 652{ 653 DeviceIntPtr dev = pInfo->dev; 654 xf86ITDevicePtr driver_data = pInfo->private; 655 ValuatorMask *mask = driver_data->valuators; 656 657 xf86IDrvMsg(pInfo, X_DEBUG, "Handling button event\n"); 658 659 driver_data->last_event_num++; 660 661 convert_to_valuator_mask(&event->valuators, mask); 662 xf86PostButtonEventM(dev, event->is_absolute ? Absolute : Relative, event->button, 663 event->is_press, mask); 664} 665 666static void 667handle_key(InputInfoPtr pInfo, xf86ITEventKey *event) 668{ 669 DeviceIntPtr dev = pInfo->dev; 670 xf86ITDevicePtr driver_data = pInfo->private; 671 672 xf86IDrvMsg(pInfo, X_DEBUG, "Handling key event\n"); 673 674 driver_data->last_event_num++; 675 676 xf86PostKeyboardEvent(dev, event->key_code, event->is_press); 677} 678 679static void 680handle_touch(InputInfoPtr pInfo, xf86ITEventTouch *event) 681{ 682 DeviceIntPtr dev = pInfo->dev; 683 xf86ITDevicePtr driver_data = pInfo->private; 684 ValuatorMask *mask = driver_data->valuators; 685 686 xf86IDrvMsg(pInfo, X_DEBUG, "Handling touch event\n"); 687 688 driver_data->last_event_num++; 689 690 convert_to_valuator_mask(&event->valuators, mask); 691 xf86PostTouchEvent(dev, event->touchid, event->touch_type, 0, mask); 692} 693 694static void 695handle_gesture_swipe(InputInfoPtr pInfo, xf86ITEventGestureSwipe *event) 696{ 697 DeviceIntPtr dev = pInfo->dev; 698 xf86ITDevicePtr driver_data = pInfo->private; 699 700 xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture swipe event\n"); 701 702 driver_data->last_event_num++; 703 704 xf86PostGestureSwipeEvent(dev, event->gesture_type, event->num_touches, event->flags, 705 event->delta_x, event->delta_y, 706 event->delta_unaccel_x, event->delta_unaccel_y); 707} 708 709static void 710handle_gesture_pinch(InputInfoPtr pInfo, xf86ITEventGesturePinch *event) 711{ 712 DeviceIntPtr dev = pInfo->dev; 713 xf86ITDevicePtr driver_data = pInfo->private; 714 715 xf86IDrvMsg(pInfo, X_DEBUG, "Handling gesture pinch event\n"); 716 717 driver_data->last_event_num++; 718 719 xf86PostGesturePinchEvent(dev, event->gesture_type, event->num_touches, event->flags, 720 event->delta_x, event->delta_y, 721 event->delta_unaccel_x, event->delta_unaccel_y, 722 event->scale, event->delta_angle); 723} 724 725static void 726client_new_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event) 727{ 728 switch (event->header.type) { 729 case XF86IT_EVENT_CLIENT_VERSION: 730 handle_client_version(pInfo, &event->version); 731 break; 732 default: 733 xf86IDrvMsg(pInfo, X_ERROR, "Event before client is ready: event type %d\n", 734 event->header.type); 735 teardown_client_connection(pInfo); 736 break; 737 } 738} 739 740static void 741client_ready_handle_event(InputInfoPtr pInfo, xf86ITEventAny *event) 742{ 743 switch (event->header.type) { 744 case XF86IT_EVENT_WAIT_FOR_SYNC: 745 handle_wait_for_sync(pInfo); 746 break; 747 case XF86IT_EVENT_MOTION: 748 handle_motion(pInfo, &event->motion); 749 break; 750 case XF86IT_EVENT_PROXIMITY: 751 handle_proximity(pInfo, &event->proximity); 752 break; 753 case XF86IT_EVENT_BUTTON: 754 handle_button(pInfo, &event->button); 755 break; 756 case XF86IT_EVENT_KEY: 757 handle_key(pInfo, &event->key); 758 break; 759 case XF86IT_EVENT_TOUCH: 760 handle_touch(pInfo, &event->touch); 761 break; 762 case XF86IT_EVENT_GESTURE_PINCH: 763 handle_gesture_pinch(pInfo, &(event->pinch)); 764 break; 765 case XF86IT_EVENT_GESTURE_SWIPE: 766 handle_gesture_swipe(pInfo, &(event->swipe)); 767 break; 768 case XF86IT_EVENT_CLIENT_VERSION: 769 xf86IDrvMsg(pInfo, X_ERROR, "Only single ClientVersion event is allowed\n"); 770 teardown_client_connection(pInfo); 771 break; 772 default: 773 xf86IDrvMsg(pInfo, X_ERROR, "Invalid event when client is ready %d\n", 774 event->header.type); 775 teardown_client_connection(pInfo); 776 break; 777 } 778} 779 780static void 781handle_event(InputInfoPtr pInfo, xf86ITEventAny *event) 782{ 783 xf86ITDevicePtr driver_data = pInfo->private; 784 785 if (!pInfo->dev->public.on) 786 return; 787 788 switch (driver_data->client_state) { 789 case CLIENT_STATE_NOT_CONNECTED: 790 xf86IDrvMsg(pInfo, X_ERROR, "Got event when client is not connected\n"); 791 break; 792 case CLIENT_STATE_NEW: 793 client_new_handle_event(pInfo, event); 794 break; 795 case CLIENT_STATE_READY: 796 client_ready_handle_event(pInfo, event); 797 break; 798 } 799} 800 801static bool 802is_supported_event(enum xf86ITEventType type) 803{ 804 switch (type) { 805 case XF86IT_EVENT_CLIENT_VERSION: 806 case XF86IT_EVENT_WAIT_FOR_SYNC: 807 case XF86IT_EVENT_MOTION: 808 case XF86IT_EVENT_PROXIMITY: 809 case XF86IT_EVENT_BUTTON: 810 case XF86IT_EVENT_KEY: 811 case XF86IT_EVENT_TOUCH: 812 case XF86IT_EVENT_GESTURE_PINCH: 813 case XF86IT_EVENT_GESTURE_SWIPE: 814 return true; 815 } 816 return false; 817} 818 819static int 820get_event_size(enum xf86ITEventType type) 821{ 822 switch (type) { 823 case XF86IT_EVENT_CLIENT_VERSION: return sizeof(xf86ITEventClientVersion); 824 case XF86IT_EVENT_WAIT_FOR_SYNC: return sizeof(xf86ITEventWaitForSync); 825 case XF86IT_EVENT_MOTION: return sizeof(xf86ITEventMotion); 826 case XF86IT_EVENT_PROXIMITY: return sizeof(xf86ITEventProximity); 827 case XF86IT_EVENT_BUTTON: return sizeof(xf86ITEventButton); 828 case XF86IT_EVENT_KEY: return sizeof(xf86ITEventKey); 829 case XF86IT_EVENT_TOUCH: return sizeof(xf86ITEventTouch); 830 case XF86IT_EVENT_GESTURE_PINCH: return sizeof(xf86ITEventGesturePinch); 831 case XF86IT_EVENT_GESTURE_SWIPE: return sizeof(xf86ITEventGestureSwipe); 832 } 833 abort(); 834} 835 836static void 837read_input_from_connection(InputInfoPtr pInfo) 838{ 839 xf86ITDevicePtr driver_data = pInfo->private; 840 841 while (1) { 842 int processed_size = 0; 843 int read_size = read(driver_data->connection_fd, 844 driver_data->buffer.data + driver_data->buffer.valid_length, 845 EVENT_BUFFER_SIZE - driver_data->buffer.valid_length); 846 847 if (read_size < 0) { 848 if (errno == EAGAIN || errno == EWOULDBLOCK) 849 return; 850 851 xf86IDrvMsg(pInfo, X_ERROR, "Error reading events: %s\n", strerror(errno)); 852 teardown_client_connection(pInfo); 853 return; 854 } 855 856 driver_data->buffer.valid_length += read_size; 857 858 while (1) { 859 xf86ITEventHeader event_header; 860 char *event_begin = driver_data->buffer.data + processed_size; 861 862 if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader)) 863 break; 864 865 /* Note that event_begin pointer is not aligned, accessing it directly is 866 undefined behavior. We must use memcpy to copy the data to aligned data 867 area. Most compilers will optimize out this call out and use whatever 868 is most efficient to access unaligned data on a particular platform */ 869 memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader)); 870 871 if (event_header.length >= EVENT_BUFFER_SIZE) { 872 xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n", 873 event_header.length); 874 teardown_client_connection(pInfo); 875 return; 876 } 877 878 if (driver_data->buffer.valid_length - processed_size < event_header.length) 879 break; 880 881 if (is_supported_event(event_header.type)) { 882 int expected_event_size = get_event_size(event_header.type); 883 884 if (event_header.length != expected_event_size) { 885 xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, " 886 "expected %d (event type: %d)\n", 887 event_header.length, expected_event_size, 888 (int) event_header.type); 889 teardown_client_connection(pInfo); 890 return; 891 } 892 893 /* We could use event_begin pointer directly, but we want to ensure correct 894 data alignment (if only so that address sanitizer does not complain) */ 895 xf86ITEventAny event_data; 896 memset(&event_data, 0, sizeof(event_data)); 897 memcpy(&event_data, event_begin, event_header.length); 898 handle_event(pInfo, &event_data); 899 } 900 processed_size += event_header.length; 901 } 902 903 if (processed_size > 0) { 904 memmove(driver_data->buffer.data, 905 driver_data->buffer.data + processed_size, 906 driver_data->buffer.valid_length - processed_size); 907 driver_data->buffer.valid_length -= processed_size; 908 } 909 910 if (read_size == 0) 911 break; 912 } 913} 914 915static void 916read_input(InputInfoPtr pInfo) 917{ 918 /* The test input driver does not set up the pInfo->fd and use the regular 919 read_input callback because we want to only accept the connection to 920 the controlling socket after the device is turned on. 921 */ 922} 923 924static const char* 925get_type_name(InputInfoPtr pInfo, xf86ITDevicePtr driver_data) 926{ 927 switch (driver_data->device_type) { 928 case DEVICE_TOUCH: return XI_TOUCHSCREEN; 929 case DEVICE_POINTER: return XI_MOUSE; 930 case DEVICE_POINTER_GESTURE: return XI_TOUCHPAD; 931 case DEVICE_POINTER_ABS: return XI_MOUSE; 932 case DEVICE_POINTER_ABS_PROXIMITY: return XI_TABLET; 933 case DEVICE_KEYBOARD: return XI_KEYBOARD; 934 } 935 xf86IDrvMsg(pInfo, X_ERROR, "Unexpected device type %d\n", 936 driver_data->device_type); 937 return XI_KEYBOARD; 938} 939 940static xf86ITDevicePtr 941device_alloc(void) 942{ 943 xf86ITDevicePtr driver_data = calloc(sizeof(xf86ITDevice), 1); 944 945 if (!driver_data) 946 return NULL; 947 948 driver_data->socket_fd = -1; 949 driver_data->connection_fd = -1; 950 951 return driver_data; 952} 953 954static void 955free_driver_data(xf86ITDevicePtr driver_data) 956{ 957 if (driver_data) { 958 close(driver_data->connection_fd); 959 close(driver_data->socket_fd); 960 if (driver_data->socket_path) 961 unlink(driver_data->socket_path); 962 free(driver_data->socket_path); 963 pthread_mutex_destroy(&driver_data->waiting_for_drain_mutex); 964 965 if (driver_data->valuators) 966 valuator_mask_free(&driver_data->valuators); 967 if (driver_data->valuators_unaccelerated) 968 valuator_mask_free(&driver_data->valuators_unaccelerated); 969 } 970 free(driver_data); 971} 972 973static int 974pre_init(InputDriverPtr drv, InputInfoPtr pInfo, int flags) 975{ 976 xf86ITDevicePtr driver_data = NULL; 977 char *device_type_option; 978 struct sockaddr_un addr; 979 980 pInfo->type_name = 0; 981 pInfo->device_control = device_control; 982 pInfo->read_input = read_input; 983 pInfo->control_proc = NULL; 984 pInfo->switch_mode = NULL; 985 986 driver_data = device_alloc(); 987 if (!driver_data) 988 goto fail; 989 990 driver_data->client_state = CLIENT_STATE_NOT_CONNECTED; 991 driver_data->last_event_num = 1; 992 driver_data->last_processed_event_num = 0; 993 driver_data->waiting_for_drain = false; 994 pthread_mutex_init(&driver_data->waiting_for_drain_mutex, NULL); 995 996 driver_data->valuators = valuator_mask_new(6); 997 if (!driver_data->valuators) 998 goto fail; 999 1000 driver_data->valuators_unaccelerated = valuator_mask_new(2); 1001 if (!driver_data->valuators_unaccelerated) 1002 goto fail; 1003 1004 driver_data->socket_path = xf86SetStrOption(pInfo->options, "SocketPath", NULL); 1005 if (!driver_data->socket_path){ 1006 xf86IDrvMsg(pInfo, X_ERROR, "SocketPath must be specified\n"); 1007 goto fail; 1008 } 1009 1010 if (strlen(driver_data->socket_path) >= sizeof(addr.sun_path)) { 1011 xf86IDrvMsg(pInfo, X_ERROR, "SocketPath is too long\n"); 1012 goto fail; 1013 } 1014 1015 unlink(driver_data->socket_path); 1016 1017#ifdef SOCK_NONBLOCK 1018 driver_data->socket_fd = socket(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); 1019#else 1020 int fd = socket(PF_UNIX, SOCK_STREAM, 0); 1021 if (fd >= 0) { 1022 flags = fcntl(fd, F_GETFL, 0); 1023 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { 1024 fd = -1; 1025 } 1026 } 1027 driver_data->socket_fd = fd; 1028#endif 1029 1030 if (driver_data->socket_fd < 0) { 1031 xf86IDrvMsg(pInfo, X_ERROR, "Failed to create a socket for communication: %s\n", 1032 strerror(errno)); 1033 goto fail; 1034 } 1035 1036 memset(&addr, 0, sizeof(addr)); 1037 addr.sun_family = AF_UNIX; 1038 strncpy(addr.sun_path, driver_data->socket_path, sizeof(addr.sun_path) - 1); 1039 1040 if (bind(driver_data->socket_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) { 1041 xf86IDrvMsg(pInfo, X_ERROR, "Failed to assign address to the socket\n"); 1042 goto fail; 1043 } 1044 1045 if (chmod(driver_data->socket_path, 0777) != 0) { 1046 xf86IDrvMsg(pInfo, X_ERROR, "Failed to chmod the socket path\n"); 1047 goto fail; 1048 } 1049 1050 if (listen(driver_data->socket_fd, 1) != 0) { 1051 xf86IDrvMsg(pInfo, X_ERROR, "Failed to listen on the socket\n"); 1052 goto fail; 1053 } 1054 1055 device_type_option = xf86SetStrOption(pInfo->options, "DeviceType", NULL); 1056 if (device_type_option == NULL) { 1057 xf86IDrvMsg(pInfo, X_ERROR, "DeviceType option must be specified\n"); 1058 goto fail; 1059 } 1060 1061 if (strcmp(device_type_option, "Keyboard") == 0) { 1062 driver_data->device_type = DEVICE_KEYBOARD; 1063 } else if (strcmp(device_type_option, "Pointer") == 0) { 1064 driver_data->device_type = DEVICE_POINTER; 1065 } else if (strcmp(device_type_option, "PointerGesture") == 0) { 1066 driver_data->device_type = DEVICE_POINTER_GESTURE; 1067 } else if (strcmp(device_type_option, "PointerAbsolute") == 0) { 1068 driver_data->device_type = DEVICE_POINTER_ABS; 1069 } else if (strcmp(device_type_option, "PointerAbsoluteProximity") == 0) { 1070 driver_data->device_type = DEVICE_POINTER_ABS_PROXIMITY; 1071 } else if (strcmp(device_type_option, "Touch") == 0) { 1072 driver_data->device_type = DEVICE_TOUCH; 1073 } else { 1074 xf86IDrvMsg(pInfo, X_ERROR, "Unsupported DeviceType option.\n"); 1075 goto fail; 1076 } 1077 free(device_type_option); 1078 1079 pInfo->private = driver_data; 1080 driver_data->pInfo = pInfo; 1081 1082 pInfo->type_name = get_type_name(pInfo, driver_data); 1083 1084 return Success; 1085fail: 1086 free_driver_data(driver_data); 1087 return BadValue; 1088} 1089 1090static void 1091uninit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) 1092{ 1093 xf86ITDevicePtr driver_data = pInfo->private; 1094 free_driver_data(driver_data); 1095 pInfo->private = NULL; 1096 xf86DeleteInput(pInfo, flags); 1097} 1098 1099InputDriverRec driver = { 1100 .driverVersion = 1, 1101 .driverName = "inputtest", 1102 .PreInit = pre_init, 1103 .UnInit = uninit, 1104 .module = NULL, 1105 .default_options = NULL, 1106 .capabilities = 0 1107}; 1108 1109static XF86ModuleVersionInfo version_info = { 1110 "inputtest", 1111 MODULEVENDORSTRING, 1112 MODINFOSTRING1, 1113 MODINFOSTRING2, 1114 XORG_VERSION_CURRENT, 1115 XORG_VERSION_MAJOR, 1116 XORG_VERSION_MINOR, 1117 XORG_VERSION_PATCH, 1118 ABI_CLASS_XINPUT, 1119 ABI_XINPUT_VERSION, 1120 MOD_CLASS_XINPUT, 1121 {0, 0, 0, 0} 1122}; 1123 1124static void* 1125setup_proc(void *module, void *options, int *errmaj, int *errmin) 1126{ 1127 xf86AddInputDriver(&driver, module, 0); 1128 return module; 1129} 1130 1131_X_EXPORT XF86ModuleData inputtestModuleData = { 1132 .vers = &version_info, 1133 .setup = &setup_proc, 1134 .teardown = NULL 1135}; 1136