1/* 2 * Copyright © 1999 Keith Packard 3 * Copyright © 2006 Nokia Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of the authors not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. The authors make no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#include <xkb-config.h> 27#endif 28#include "kdrive.h" 29#include "inputstr.h" 30 31#define XK_PUBLISHING 32#include <X11/keysym.h> 33#if HAVE_X11_XF86KEYSYM_H 34#include <X11/XF86keysym.h> 35#endif 36#include <stdio.h> 37#ifdef __sun 38#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ 39#endif 40 41#include "xkbsrv.h" 42 43#include <X11/extensions/XI.h> 44#include <X11/extensions/XIproto.h> 45#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ 46#include "exevents.h" 47#include "extinit.h" 48#include "exglobals.h" 49#include "eventstr.h" 50#include "xserver-properties.h" 51#include "inpututils.h" 52#include "optionstr.h" 53 54#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 55#include <hotplug.h> 56#endif 57 58#define AtomFromName(x) MakeAtom(x, strlen(x), 1) 59 60struct KdConfigDevice { 61 char *line; 62 struct KdConfigDevice *next; 63}; 64 65/* kdKeyboards and kdPointers hold all the real devices. */ 66static KdKeyboardInfo *kdKeyboards = NULL; 67static KdPointerInfo *kdPointers = NULL; 68static struct KdConfigDevice *kdConfigKeyboards = NULL; 69static struct KdConfigDevice *kdConfigPointers = NULL; 70 71static KdKeyboardDriver *kdKeyboardDrivers = NULL; 72static KdPointerDriver *kdPointerDrivers = NULL; 73 74static Bool kdInputEnabled; 75static Bool kdOffScreen; 76static unsigned long kdOffScreenTime; 77 78static KdPointerMatrix kdPointerMatrix = { 79 {{1, 0, 0}, 80 {0, 1, 0}} 81}; 82 83extern Bool kdRawPointerCoordinates; 84 85extern const char *kdGlobalXkbRules; 86extern const char *kdGlobalXkbModel; 87extern const char *kdGlobalXkbLayout; 88extern const char *kdGlobalXkbVariant; 89extern const char *kdGlobalXkbOptions; 90 91#ifdef FNONBLOCK 92#define NOBLOCK FNONBLOCK 93#else 94#define NOBLOCK FNDELAY 95#endif 96 97static void 98KdResetInputMachine(void) 99{ 100 KdPointerInfo *pi; 101 102 for (pi = kdPointers; pi; pi = pi->next) { 103 pi->mouseState = start; 104 pi->eventHeld = FALSE; 105 } 106} 107 108void 109KdDisableInput(void) 110{ 111 KdKeyboardInfo *ki; 112 KdPointerInfo *pi; 113 114 input_lock(); 115 116 for (ki = kdKeyboards; ki; ki = ki->next) { 117 if (ki->driver && ki->driver->Disable) 118 (*ki->driver->Disable) (ki); 119 } 120 121 for (pi = kdPointers; pi; pi = pi->next) { 122 if (pi->driver && pi->driver->Disable) 123 (*pi->driver->Disable) (pi); 124 } 125 126 kdInputEnabled = FALSE; 127} 128 129void 130KdEnableInput(void) 131{ 132 InternalEvent ev; 133 KdKeyboardInfo *ki; 134 KdPointerInfo *pi; 135 136 kdInputEnabled = TRUE; 137 138 ev.any.time = GetTimeInMillis(); 139 140 for (ki = kdKeyboards; ki; ki = ki->next) { 141 if (ki->driver && ki->driver->Enable) 142 (*ki->driver->Enable) (ki); 143 /* reset screen saver */ 144 NoticeEventTime (&ev, ki->dixdev); 145 } 146 147 for (pi = kdPointers; pi; pi = pi->next) { 148 if (pi->driver && pi->driver->Enable) 149 (*pi->driver->Enable) (pi); 150 /* reset screen saver */ 151 NoticeEventTime (&ev, pi->dixdev); 152 } 153 154 input_unlock(); 155} 156 157static KdKeyboardDriver * 158KdFindKeyboardDriver(const char *name) 159{ 160 KdKeyboardDriver *ret; 161 162 /* ask a stupid question ... */ 163 if (!name) 164 return NULL; 165 166 for (ret = kdKeyboardDrivers; ret; ret = ret->next) { 167 if (strcmp(ret->name, name) == 0) 168 return ret; 169 } 170 171 return NULL; 172} 173 174static KdPointerDriver * 175KdFindPointerDriver(const char *name) 176{ 177 KdPointerDriver *ret; 178 179 /* ask a stupid question ... */ 180 if (!name) 181 return NULL; 182 183 for (ret = kdPointerDrivers; ret; ret = ret->next) { 184 if (strcmp(ret->name, name) == 0) 185 return ret; 186 } 187 188 return NULL; 189} 190 191static int 192KdPointerProc(DeviceIntPtr pDevice, int onoff) 193{ 194 DevicePtr pDev = (DevicePtr) pDevice; 195 KdPointerInfo *pi; 196 Atom xiclass; 197 Atom *btn_labels; 198 Atom *axes_labels; 199 200 if (!pDev) 201 return BadImplementation; 202 203 for (pi = kdPointers; pi; pi = pi->next) { 204 if (pi->dixdev && pi->dixdev->id == pDevice->id) 205 break; 206 } 207 208 if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { 209 ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", 210 pDevice->id); 211 return BadImplementation; 212 } 213 214 switch (onoff) { 215 case DEVICE_INIT: 216#ifdef DEBUG 217 ErrorF("initialising pointer %s ...\n", pi->name); 218#endif 219 if (!pi->driver) { 220 if (!pi->driverPrivate) { 221 ErrorF("no driver specified for pointer device \"%s\" (%s)\n", 222 pi->name ? pi->name : "(unnamed)", pi->path); 223 return BadImplementation; 224 } 225 226 pi->driver = KdFindPointerDriver(pi->driverPrivate); 227 if (!pi->driver) { 228 ErrorF("Couldn't find pointer driver %s\n", 229 pi->driverPrivate ? (char *) pi->driverPrivate : 230 "(unnamed)"); 231 return !Success; 232 } 233 free(pi->driverPrivate); 234 pi->driverPrivate = NULL; 235 } 236 237 if (!pi->driver->Init) { 238 ErrorF("no init function\n"); 239 return BadImplementation; 240 } 241 242 if ((*pi->driver->Init) (pi) != Success) { 243 return !Success; 244 } 245 246 btn_labels = calloc(pi->nButtons, sizeof(Atom)); 247 if (!btn_labels) 248 return BadAlloc; 249 axes_labels = calloc(pi->nAxes, sizeof(Atom)); 250 if (!axes_labels) { 251 free(btn_labels); 252 return BadAlloc; 253 } 254 255 switch (pi->nAxes) { 256 default: 257 case 7: 258 btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); 259 case 6: 260 btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); 261 case 5: 262 btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); 263 case 4: 264 btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); 265 case 3: 266 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); 267 case 2: 268 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); 269 case 1: 270 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); 271 case 0: 272 break; 273 } 274 275 if (pi->nAxes >= 2) { 276 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); 277 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); 278 } 279 280 InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels, 281 (PtrCtrlProcPtr) NoopDDA, 282 GetMotionHistorySize(), pi->nAxes, axes_labels); 283 284 free(btn_labels); 285 free(axes_labels); 286 287 if (pi->inputClass == KD_TOUCHSCREEN) { 288 xiclass = AtomFromName(XI_TOUCHSCREEN); 289 } 290 else { 291 xiclass = AtomFromName(XI_MOUSE); 292 } 293 294 AssignTypeAndName(pi->dixdev, xiclass, 295 pi->name ? pi->name : "Generic KDrive Pointer"); 296 297 return Success; 298 299 case DEVICE_ON: 300 if (pDev->on == TRUE) 301 return Success; 302 303 if (!pi->driver->Enable) { 304 ErrorF("no enable function\n"); 305 return BadImplementation; 306 } 307 308 if ((*pi->driver->Enable) (pi) == Success) { 309 pDev->on = TRUE; 310 return Success; 311 } 312 else { 313 return BadImplementation; 314 } 315 316 return Success; 317 318 case DEVICE_OFF: 319 if (pDev->on == FALSE) { 320 return Success; 321 } 322 323 if (!pi->driver->Disable) { 324 return BadImplementation; 325 } 326 else { 327 (*pi->driver->Disable) (pi); 328 pDev->on = FALSE; 329 return Success; 330 } 331 332 return Success; 333 334 case DEVICE_CLOSE: 335 if (pDev->on) { 336 if (!pi->driver->Disable) { 337 return BadImplementation; 338 } 339 (*pi->driver->Disable) (pi); 340 pDev->on = FALSE; 341 } 342 343 if (!pi->driver->Fini) 344 return BadImplementation; 345 346 (*pi->driver->Fini) (pi); 347 348 KdRemovePointer(pi); 349 350 return Success; 351 } 352 353 /* NOTREACHED */ 354 return BadImplementation; 355} 356 357static void 358KdRingBell(KdKeyboardInfo * ki, int volume, int pitch, int duration) 359{ 360 if (!ki || !ki->driver || !ki->driver->Bell) 361 return; 362 363 if (kdInputEnabled) 364 (*ki->driver->Bell) (ki, volume, pitch, duration); 365} 366 367static void 368KdBell(int volume, DeviceIntPtr pDev, void *arg, int something) 369{ 370 KeybdCtrl *ctrl = arg; 371 KdKeyboardInfo *ki = NULL; 372 373 for (ki = kdKeyboards; ki; ki = ki->next) { 374 if (ki->dixdev && ki->dixdev->id == pDev->id) 375 break; 376 } 377 378 if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) 379 return; 380 381 KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); 382} 383 384void 385DDXRingBell(int volume, int pitch, int duration) 386{ 387 KdKeyboardInfo *ki = NULL; 388 389 for (ki = kdKeyboards; ki; ki = ki->next) { 390 if (ki->dixdev->coreEvents) 391 KdRingBell(ki, volume, pitch, duration); 392 } 393} 394 395static void 396KdSetLeds(KdKeyboardInfo * ki, int leds) 397{ 398 if (!ki || !ki->driver) 399 return; 400 401 if (kdInputEnabled) { 402 if (ki->driver->Leds) 403 (*ki->driver->Leds) (ki, leds); 404 } 405} 406 407static void 408KdSetLed(KdKeyboardInfo * ki, int led, Bool on) 409{ 410 if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) 411 return; 412 413 NoteLedState(ki->dixdev, led, on); 414 KdSetLeds(ki, ki->dixdev->kbdfeed->ctrl.leds); 415} 416 417void 418KdSetPointerMatrix(KdPointerMatrix * matrix) 419{ 420 kdPointerMatrix = *matrix; 421} 422 423void 424KdComputePointerMatrix(KdPointerMatrix * m, Rotation randr, int width, 425 int height) 426{ 427 int x_dir = 1, y_dir = 1; 428 int i, j; 429 int size[2]; 430 431 size[0] = width; 432 size[1] = height; 433 if (randr & RR_Reflect_X) 434 x_dir = -1; 435 if (randr & RR_Reflect_Y) 436 y_dir = -1; 437 switch (randr & (RR_Rotate_All)) { 438 case RR_Rotate_0: 439 m->matrix[0][0] = x_dir; 440 m->matrix[0][1] = 0; 441 m->matrix[1][0] = 0; 442 m->matrix[1][1] = y_dir; 443 break; 444 case RR_Rotate_90: 445 m->matrix[0][0] = 0; 446 m->matrix[0][1] = -x_dir; 447 m->matrix[1][0] = y_dir; 448 m->matrix[1][1] = 0; 449 break; 450 case RR_Rotate_180: 451 m->matrix[0][0] = -x_dir; 452 m->matrix[0][1] = 0; 453 m->matrix[1][0] = 0; 454 m->matrix[1][1] = -y_dir; 455 break; 456 case RR_Rotate_270: 457 m->matrix[0][0] = 0; 458 m->matrix[0][1] = x_dir; 459 m->matrix[1][0] = -y_dir; 460 m->matrix[1][1] = 0; 461 break; 462 } 463 for (i = 0; i < 2; i++) { 464 m->matrix[i][2] = 0; 465 for (j = 0; j < 2; j++) 466 if (m->matrix[i][j] < 0) 467 m->matrix[i][2] = size[j] - 1; 468 } 469} 470 471static void 472KdKbdCtrl(DeviceIntPtr pDevice, KeybdCtrl * ctrl) 473{ 474 KdKeyboardInfo *ki; 475 476 for (ki = kdKeyboards; ki; ki = ki->next) { 477 if (ki->dixdev && ki->dixdev->id == pDevice->id) 478 break; 479 } 480 481 if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) 482 return; 483 484 KdSetLeds(ki, ctrl->leds); 485 ki->bellPitch = ctrl->bell_pitch; 486 ki->bellDuration = ctrl->bell_duration; 487} 488 489static int 490KdKeyboardProc(DeviceIntPtr pDevice, int onoff) 491{ 492 Bool ret; 493 DevicePtr pDev = (DevicePtr) pDevice; 494 KdKeyboardInfo *ki; 495 Atom xiclass; 496 XkbRMLVOSet rmlvo; 497 498 if (!pDev) 499 return BadImplementation; 500 501 for (ki = kdKeyboards; ki; ki = ki->next) { 502 if (ki->dixdev && ki->dixdev->id == pDevice->id) 503 break; 504 } 505 506 if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { 507 return BadImplementation; 508 } 509 510 switch (onoff) { 511 case DEVICE_INIT: 512#ifdef DEBUG 513 ErrorF("initialising keyboard %s\n", ki->name); 514#endif 515 if (!ki->driver) { 516 if (!ki->driverPrivate) { 517 ErrorF("no driver specified for keyboard device \"%s\" (%s)\n", 518 ki->name ? ki->name : "(unnamed)", ki->path); 519 return BadImplementation; 520 } 521 522 ki->driver = KdFindKeyboardDriver(ki->driverPrivate); 523 if (!ki->driver) { 524 ErrorF("Couldn't find keyboard driver %s\n", 525 ki->driverPrivate ? (char *) ki->driverPrivate : 526 "(unnamed)"); 527 return !Success; 528 } 529 free(ki->driverPrivate); 530 ki->driverPrivate = NULL; 531 } 532 533 if (!ki->driver->Init) { 534 ErrorF("Keyboard %s: no init function\n", ki->name); 535 return BadImplementation; 536 } 537 538 memset(&rmlvo, 0, sizeof(rmlvo)); 539 rmlvo.rules = ki->xkbRules; 540 rmlvo.model = ki->xkbModel; 541 rmlvo.layout = ki->xkbLayout; 542 rmlvo.variant = ki->xkbVariant; 543 rmlvo.options = ki->xkbOptions; 544 ret = InitKeyboardDeviceStruct(pDevice, &rmlvo, KdBell, KdKbdCtrl); 545 if (!ret) { 546 ErrorF("Couldn't initialise keyboard %s\n", ki->name); 547 return BadImplementation; 548 } 549 550 if ((*ki->driver->Init) (ki) != Success) { 551 return !Success; 552 } 553 554 xiclass = AtomFromName(XI_KEYBOARD); 555 AssignTypeAndName(pDevice, xiclass, 556 ki->name ? ki->name : "Generic KDrive Keyboard"); 557 558 KdResetInputMachine(); 559 560 return Success; 561 562 case DEVICE_ON: 563 if (pDev->on == TRUE) 564 return Success; 565 566 if (!ki->driver->Enable) 567 return BadImplementation; 568 569 if ((*ki->driver->Enable) (ki) != Success) { 570 return BadMatch; 571 } 572 573 pDev->on = TRUE; 574 return Success; 575 576 case DEVICE_OFF: 577 if (pDev->on == FALSE) 578 return Success; 579 580 if (!ki->driver->Disable) 581 return BadImplementation; 582 583 (*ki->driver->Disable) (ki); 584 pDev->on = FALSE; 585 586 return Success; 587 588 break; 589 590 case DEVICE_CLOSE: 591 if (pDev->on) { 592 if (!ki->driver->Disable) 593 return BadImplementation; 594 595 (*ki->driver->Disable) (ki); 596 pDev->on = FALSE; 597 } 598 599 if (!ki->driver->Fini) 600 return BadImplementation; 601 602 (*ki->driver->Fini) (ki); 603 604 KdRemoveKeyboard(ki); 605 606 return Success; 607 } 608 609 /* NOTREACHED */ 610 return BadImplementation; 611} 612 613void 614KdAddPointerDriver(KdPointerDriver * driver) 615{ 616 KdPointerDriver **prev; 617 618 if (!driver) 619 return; 620 621 for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { 622 if (*prev == driver) 623 return; 624 } 625 *prev = driver; 626} 627 628void 629KdRemovePointerDriver(KdPointerDriver * driver) 630{ 631 KdPointerDriver *tmp; 632 633 if (!driver) 634 return; 635 636 /* FIXME remove all pointers using this driver */ 637 for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { 638 if (tmp->next == driver) 639 tmp->next = driver->next; 640 } 641 if (tmp == driver) 642 tmp = NULL; 643} 644 645void 646KdAddKeyboardDriver(KdKeyboardDriver * driver) 647{ 648 KdKeyboardDriver **prev; 649 650 if (!driver) 651 return; 652 653 for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { 654 if (*prev == driver) 655 return; 656 } 657 *prev = driver; 658} 659 660void 661KdRemoveKeyboardDriver(KdKeyboardDriver * driver) 662{ 663 KdKeyboardDriver *tmp; 664 665 if (!driver) 666 return; 667 668 /* FIXME remove all keyboards using this driver */ 669 for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { 670 if (tmp->next == driver) 671 tmp->next = driver->next; 672 } 673 if (tmp == driver) 674 tmp = NULL; 675} 676 677KdKeyboardInfo * 678KdNewKeyboard(void) 679{ 680 KdKeyboardInfo *ki = calloc(sizeof(KdKeyboardInfo), 1); 681 682 if (!ki) 683 return NULL; 684 685 ki->minScanCode = 0; 686 ki->maxScanCode = 0; 687 ki->leds = 0; 688 ki->bellPitch = 1000; 689 ki->bellDuration = 200; 690 ki->next = NULL; 691 ki->options = NULL; 692 ki->name = strdup("Generic Keyboard"); 693 ki->path = NULL; 694 ki->xkbRules = strdup(kdGlobalXkbRules ? kdGlobalXkbRules : XKB_DFLT_RULES); 695 ki->xkbModel = strdup(kdGlobalXkbModel ? kdGlobalXkbModel : XKB_DFLT_MODEL); 696 ki->xkbLayout = strdup(kdGlobalXkbLayout ? kdGlobalXkbLayout : XKB_DFLT_LAYOUT); 697 ki->xkbVariant = strdup(kdGlobalXkbVariant ? kdGlobalXkbVariant :XKB_DFLT_VARIANT); 698 ki->xkbOptions = strdup(kdGlobalXkbOptions ? kdGlobalXkbOptions : XKB_DFLT_OPTIONS); 699 700 return ki; 701} 702 703int 704KdAddConfigKeyboard(char *keyboard) 705{ 706 struct KdConfigDevice **prev, *new; 707 708 if (!keyboard) 709 return Success; 710 711 new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1); 712 if (!new) 713 return BadAlloc; 714 715 new->line = strdup(keyboard); 716 new->next = NULL; 717 718 for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); 719 *prev = new; 720 721 return Success; 722} 723 724int 725KdAddKeyboard(KdKeyboardInfo * ki) 726{ 727 KdKeyboardInfo **prev; 728 729 if (!ki) 730 return !Success; 731 732 ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE); 733 if (!ki->dixdev) { 734 ErrorF("Couldn't register keyboard device %s\n", 735 ki->name ? ki->name : "(unnamed)"); 736 return !Success; 737 } 738 739#ifdef DEBUG 740 ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); 741#endif 742 743 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); 744 *prev = ki; 745 746 return Success; 747} 748 749void 750KdRemoveKeyboard(KdKeyboardInfo * ki) 751{ 752 KdKeyboardInfo **prev; 753 754 if (!ki) 755 return; 756 757 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { 758 if (*prev == ki) { 759 *prev = ki->next; 760 break; 761 } 762 } 763 764 KdFreeKeyboard(ki); 765} 766 767int 768KdAddConfigPointer(char *pointer) 769{ 770 struct KdConfigDevice **prev, *new; 771 772 if (!pointer) 773 return Success; 774 775 new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1); 776 if (!new) 777 return BadAlloc; 778 779 new->line = strdup(pointer); 780 new->next = NULL; 781 782 for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); 783 *prev = new; 784 785 return Success; 786} 787 788int 789KdAddPointer(KdPointerInfo * pi) 790{ 791 KdPointerInfo **prev; 792 793 if (!pi) 794 return Success; 795 796 pi->mouseState = start; 797 pi->eventHeld = FALSE; 798 799 pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE); 800 if (!pi->dixdev) { 801 ErrorF("Couldn't add pointer device %s\n", 802 pi->name ? pi->name : "(unnamed)"); 803 return BadDevice; 804 } 805 806 for (prev = &kdPointers; *prev; prev = &(*prev)->next); 807 *prev = pi; 808 809 return Success; 810} 811 812void 813KdRemovePointer(KdPointerInfo * pi) 814{ 815 KdPointerInfo **prev; 816 817 if (!pi) 818 return; 819 820 for (prev = &kdPointers; *prev; prev = &(*prev)->next) { 821 if (*prev == pi) { 822 *prev = pi->next; 823 break; 824 } 825 } 826 827 KdFreePointer(pi); 828} 829 830/* 831 * You can call your kdriver server with something like: 832 * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd 833 * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br 834 */ 835static Bool 836KdGetOptions(InputOption **options, char *string) 837{ 838 InputOption *newopt = NULL; 839 char *key = NULL, *value = NULL; 840 int tam_key = 0; 841 842 if (strchr(string, '=')) { 843 tam_key = (strchr(string, '=') - string); 844 key = strndup(string, tam_key); 845 if (!key) 846 goto out; 847 848 value = strdup(strchr(string, '=') + 1); 849 if (!value) 850 goto out; 851 } 852 else { 853 key = strdup(string); 854 value = NULL; 855 } 856 857 newopt = input_option_new(*options, key, value); 858 if (newopt) 859 *options = newopt; 860 861 out: 862 free(key); 863 free(value); 864 865 return (newopt != NULL); 866} 867 868static void 869KdParseKbdOptions(KdKeyboardInfo * ki) 870{ 871 InputOption *option = NULL; 872 873 nt_list_for_each_entry(option, ki->options, list.next) { 874 const char *key = input_option_get_key(option); 875 const char *value = input_option_get_value(option); 876 877 if ( 878#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 879 strcasecmp(key, "xkb_rules") == 0 || 880#endif 881 strcasecmp(key, "XkbRules") == 0) 882 ki->xkbRules = strdup(value); 883 else if ( 884#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 885 strcasecmp(key, "xkb_model") == 0 || 886#endif 887 strcasecmp(key, "XkbModel") == 0) 888 ki->xkbModel = strdup(value); 889 else if ( 890#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 891 strcasecmp(key, "xkb_layout") == 0 || 892#endif 893 strcasecmp(key, "XkbLayout") == 0) 894 ki->xkbLayout = strdup(value); 895 else if ( 896#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 897 strcasecmp(key, "xkb_variant") == 0 || 898#endif 899 strcasecmp(key, "XkbVariant") == 0) 900 ki->xkbVariant = strdup(value); 901 else if ( 902#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 903 strcasecmp(key, "xkb_options") == 0 || 904#endif 905 strcasecmp(key, "XkbOptions") == 0) 906 ki->xkbOptions = strdup(value); 907 else if (!strcasecmp(key, "device")) { 908 if (ki->path != NULL) 909 free(ki->path); 910 ki->path = strdup(value); 911 } 912#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 913 else if (!strcasecmp(key, "path")) { 914 if (ki->path != NULL) 915 free(ki->path); 916 ki->path = strdup(value); 917 } 918 else if (!strcasecmp(key, "name")) { 919 free(ki->name); 920 ki->name = strdup(value); 921 } 922#endif 923 else if (!strcasecmp(key, "driver")) 924 ki->driver = KdFindKeyboardDriver(value); 925 else 926 ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", 927 key, value); 928 } 929} 930 931static KdKeyboardInfo * 932KdParseKeyboard(const char *arg) 933{ 934 char save[1024]; 935 char delim; 936 InputOption *options = NULL; 937 KdKeyboardInfo *ki = NULL; 938 939 ki = KdNewKeyboard(); 940 if (!ki) 941 return NULL; 942 943 ki->name = strdup("Unknown KDrive Keyboard"); 944 ki->path = NULL; 945 ki->driver = NULL; 946 ki->driverPrivate = NULL; 947 ki->next = NULL; 948 949 if (!arg) { 950 ErrorF("keybd: no arg\n"); 951 KdFreeKeyboard(ki); 952 return NULL; 953 } 954 955 if (strlen(arg) >= sizeof(save)) { 956 ErrorF("keybd: arg too long\n"); 957 KdFreeKeyboard(ki); 958 return NULL; 959 } 960 961 arg = KdParseFindNext(arg, ",", save, &delim); 962 if (!save[0]) { 963 ErrorF("keybd: failed on save[0]\n"); 964 KdFreeKeyboard(ki); 965 return NULL; 966 } 967 968 if (strcmp(save, "auto") == 0) 969 ki->driverPrivate = NULL; 970 else 971 ki->driverPrivate = strdup(save); 972 973 if (delim != ',') { 974 return ki; 975 } 976 977 arg = KdParseFindNext(arg, ",", save, &delim); 978 979 while (delim == ',') { 980 arg = KdParseFindNext(arg, ",", save, &delim); 981 982 if (!KdGetOptions(&options, save)) { 983 KdFreeKeyboard(ki); 984 return NULL; 985 } 986 } 987 988 if (options) { 989 ki->options = options; 990 KdParseKbdOptions(ki); 991 } 992 993 return ki; 994} 995 996static void 997KdParsePointerOptions(KdPointerInfo * pi) 998{ 999 InputOption *option = NULL; 1000 1001 nt_list_for_each_entry(option, pi->options, list.next) { 1002 const char *key = input_option_get_key(option); 1003 const char *value = input_option_get_value(option); 1004 1005 if (!strcasecmp(key, "emulatemiddle")) 1006 pi->emulateMiddleButton = TRUE; 1007 else if (!strcasecmp(key, "noemulatemiddle")) 1008 pi->emulateMiddleButton = FALSE; 1009 else if (!strcasecmp(key, "transformcoord")) 1010 pi->transformCoordinates = TRUE; 1011 else if (!strcasecmp(key, "rawcoord")) 1012 pi->transformCoordinates = FALSE; 1013 else if (!strcasecmp(key, "device")) { 1014 if (pi->path != NULL) 1015 free(pi->path); 1016 pi->path = strdup(value); 1017 } 1018#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 1019 else if (!strcasecmp(key, "path")) { 1020 if (pi->path != NULL) 1021 free(pi->path); 1022 pi->path = strdup(value); 1023 } 1024 else if (!strcasecmp(key, "name")) { 1025 free(pi->name); 1026 pi->name = strdup(value); 1027 } 1028#endif 1029 else if (!strcasecmp(key, "protocol")) 1030 pi->protocol = strdup(value); 1031 else if (!strcasecmp(key, "driver")) 1032 pi->driver = KdFindPointerDriver(value); 1033 else 1034 ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", 1035 key, value); 1036 } 1037} 1038 1039static KdPointerInfo * 1040KdParsePointer(const char *arg) 1041{ 1042 char save[1024]; 1043 char delim; 1044 KdPointerInfo *pi = NULL; 1045 InputOption *options = NULL; 1046 int i = 0; 1047 1048 pi = KdNewPointer(); 1049 if (!pi) 1050 return NULL; 1051 pi->emulateMiddleButton = kdEmulateMiddleButton; 1052 pi->transformCoordinates = !kdRawPointerCoordinates; 1053 pi->protocol = NULL; 1054 pi->nButtons = 5; /* XXX should not be hardcoded */ 1055 pi->inputClass = KD_MOUSE; 1056 1057 if (!arg) { 1058 ErrorF("mouse: no arg\n"); 1059 KdFreePointer(pi); 1060 return NULL; 1061 } 1062 1063 if (strlen(arg) >= sizeof(save)) { 1064 ErrorF("mouse: arg too long\n"); 1065 KdFreePointer(pi); 1066 return NULL; 1067 } 1068 arg = KdParseFindNext(arg, ",", save, &delim); 1069 if (!save[0]) { 1070 ErrorF("failed on save[0]\n"); 1071 KdFreePointer(pi); 1072 return NULL; 1073 } 1074 1075 if (strcmp(save, "auto") == 0) 1076 pi->driverPrivate = NULL; 1077 else 1078 pi->driverPrivate = strdup(save); 1079 1080 if (delim != ',') { 1081 return pi; 1082 } 1083 1084 arg = KdParseFindNext(arg, ",", save, &delim); 1085 1086 while (delim == ',') { 1087 arg = KdParseFindNext(arg, ",", save, &delim); 1088 if (save[0] == '{') { 1089 char *s = save + 1; 1090 1091 i = 0; 1092 while (*s && *s != '}') { 1093 if ('1' <= *s && *s <= '0' + pi->nButtons) 1094 pi->map[i] = *s - '0'; 1095 else 1096 UseMsg(); 1097 s++; 1098 } 1099 } 1100 else { 1101 if (!KdGetOptions(&options, save)) { 1102 KdFreePointer(pi); 1103 return NULL; 1104 } 1105 } 1106 } 1107 1108 if (options) { 1109 pi->options = options; 1110 KdParsePointerOptions(pi); 1111 } 1112 1113 return pi; 1114} 1115 1116void 1117KdInitInput(void) 1118{ 1119 KdPointerInfo *pi; 1120 KdKeyboardInfo *ki; 1121 struct KdConfigDevice *dev; 1122 1123 if (kdConfigPointers || kdConfigKeyboards) 1124 InputThreadPreInit(); 1125 1126 kdInputEnabled = TRUE; 1127 1128 for (dev = kdConfigPointers; dev; dev = dev->next) { 1129 pi = KdParsePointer(dev->line); 1130 if (!pi) 1131 ErrorF("Failed to parse pointer\n"); 1132 if (KdAddPointer(pi) != Success) 1133 ErrorF("Failed to add pointer!\n"); 1134 } 1135 for (dev = kdConfigKeyboards; dev; dev = dev->next) { 1136 ki = KdParseKeyboard(dev->line); 1137 if (!ki) 1138 ErrorF("Failed to parse keyboard\n"); 1139 if (KdAddKeyboard(ki) != Success) 1140 ErrorF("Failed to add keyboard!\n"); 1141 } 1142 1143 mieqInit(); 1144 1145#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 1146 if (SeatId) /* Enable input hot-plugging */ 1147 config_init(); 1148#endif 1149} 1150 1151void 1152KdCloseInput(void) 1153{ 1154#if defined(CONFIG_UDEV) || defined(CONFIG_HAL) 1155 if (SeatId) /* Input hot-plugging is enabled */ 1156 config_fini(); 1157#endif 1158 1159 mieqFini(); 1160} 1161 1162/* 1163 * Middle button emulation state machine 1164 * 1165 * Possible transitions: 1166 * Button 1 press v1 1167 * Button 1 release ^1 1168 * Button 2 press v2 1169 * Button 2 release ^2 1170 * Button 3 press v3 1171 * Button 3 release ^3 1172 * Button other press vo 1173 * Button other release ^o 1174 * Mouse motion <> 1175 * Keyboard event k 1176 * timeout ... 1177 * outside box <-> 1178 * 1179 * States: 1180 * start 1181 * button_1_pend 1182 * button_1_down 1183 * button_2_down 1184 * button_3_pend 1185 * button_3_down 1186 * synthetic_2_down_13 1187 * synthetic_2_down_3 1188 * synthetic_2_down_1 1189 * 1190 * Transition diagram 1191 * 1192 * start 1193 * v1 -> (hold) (settimeout) button_1_pend 1194 * ^1 -> (deliver) start 1195 * v2 -> (deliver) button_2_down 1196 * ^2 -> (deliever) start 1197 * v3 -> (hold) (settimeout) button_3_pend 1198 * ^3 -> (deliver) start 1199 * vo -> (deliver) start 1200 * ^o -> (deliver) start 1201 * <> -> (deliver) start 1202 * k -> (deliver) start 1203 * 1204 * button_1_pend (button 1 is down, timeout pending) 1205 * ^1 -> (release) (deliver) start 1206 * v2 -> (release) (deliver) button_1_down 1207 * ^2 -> (release) (deliver) button_1_down 1208 * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 1209 * ^3 -> (release) (deliver) button_1_down 1210 * vo -> (release) (deliver) button_1_down 1211 * ^o -> (release) (deliver) button_1_down 1212 * <-> -> (release) (deliver) button_1_down 1213 * <> -> (deliver) button_1_pend 1214 * k -> (release) (deliver) button_1_down 1215 * ... -> (release) button_1_down 1216 * 1217 * button_1_down (button 1 is down) 1218 * ^1 -> (deliver) start 1219 * v2 -> (deliver) button_1_down 1220 * ^2 -> (deliver) button_1_down 1221 * v3 -> (deliver) button_1_down 1222 * ^3 -> (deliver) button_1_down 1223 * vo -> (deliver) button_1_down 1224 * ^o -> (deliver) button_1_down 1225 * <> -> (deliver) button_1_down 1226 * k -> (deliver) button_1_down 1227 * 1228 * button_2_down (button 2 is down) 1229 * v1 -> (deliver) button_2_down 1230 * ^1 -> (deliver) button_2_down 1231 * ^2 -> (deliver) start 1232 * v3 -> (deliver) button_2_down 1233 * ^3 -> (deliver) button_2_down 1234 * vo -> (deliver) button_2_down 1235 * ^o -> (deliver) button_2_down 1236 * <> -> (deliver) button_2_down 1237 * k -> (deliver) button_2_down 1238 * 1239 * button_3_pend (button 3 is down, timeout pending) 1240 * v1 -> (generate v2) synthetic_2_down 1241 * ^1 -> (release) (deliver) button_3_down 1242 * v2 -> (release) (deliver) button_3_down 1243 * ^2 -> (release) (deliver) button_3_down 1244 * ^3 -> (release) (deliver) start 1245 * vo -> (release) (deliver) button_3_down 1246 * ^o -> (release) (deliver) button_3_down 1247 * <-> -> (release) (deliver) button_3_down 1248 * <> -> (deliver) button_3_pend 1249 * k -> (release) (deliver) button_3_down 1250 * ... -> (release) button_3_down 1251 * 1252 * button_3_down (button 3 is down) 1253 * v1 -> (deliver) button_3_down 1254 * ^1 -> (deliver) button_3_down 1255 * v2 -> (deliver) button_3_down 1256 * ^2 -> (deliver) button_3_down 1257 * ^3 -> (deliver) start 1258 * vo -> (deliver) button_3_down 1259 * ^o -> (deliver) button_3_down 1260 * <> -> (deliver) button_3_down 1261 * k -> (deliver) button_3_down 1262 * 1263 * synthetic_2_down_13 (button 1 and 3 are down) 1264 * ^1 -> (generate ^2) synthetic_2_down_3 1265 * v2 -> synthetic_2_down_13 1266 * ^2 -> synthetic_2_down_13 1267 * ^3 -> (generate ^2) synthetic_2_down_1 1268 * vo -> (deliver) synthetic_2_down_13 1269 * ^o -> (deliver) synthetic_2_down_13 1270 * <> -> (deliver) synthetic_2_down_13 1271 * k -> (deliver) synthetic_2_down_13 1272 * 1273 * synthetic_2_down_3 (button 3 is down) 1274 * v1 -> (deliver) synthetic_2_down_3 1275 * ^1 -> (deliver) synthetic_2_down_3 1276 * v2 -> synthetic_2_down_3 1277 * ^2 -> synthetic_2_down_3 1278 * ^3 -> start 1279 * vo -> (deliver) synthetic_2_down_3 1280 * ^o -> (deliver) synthetic_2_down_3 1281 * <> -> (deliver) synthetic_2_down_3 1282 * k -> (deliver) synthetic_2_down_3 1283 * 1284 * synthetic_2_down_1 (button 1 is down) 1285 * ^1 -> start 1286 * v2 -> synthetic_2_down_1 1287 * ^2 -> synthetic_2_down_1 1288 * v3 -> (deliver) synthetic_2_down_1 1289 * ^3 -> (deliver) synthetic_2_down_1 1290 * vo -> (deliver) synthetic_2_down_1 1291 * ^o -> (deliver) synthetic_2_down_1 1292 * <> -> (deliver) synthetic_2_down_1 1293 * k -> (deliver) synthetic_2_down_1 1294 */ 1295 1296typedef enum _inputClass { 1297 down_1, up_1, 1298 down_2, up_2, 1299 down_3, up_3, 1300 down_o, up_o, 1301 motion, outside_box, 1302 keyboard, timeout, 1303 num_input_class 1304} KdInputClass; 1305 1306typedef enum _inputAction { 1307 noop, 1308 hold, 1309 setto, 1310 deliver, 1311 release, 1312 clearto, 1313 gen_down_2, 1314 gen_up_2 1315} KdInputAction; 1316 1317#define MAX_ACTIONS 2 1318 1319typedef struct _inputTransition { 1320 KdInputAction actions[MAX_ACTIONS]; 1321 KdPointerState nextState; 1322} KdInputTransition; 1323 1324static const 1325KdInputTransition kdInputMachine[num_input_states][num_input_class] = { 1326 /* start */ 1327 { 1328 {{hold, setto}, button_1_pend}, /* v1 */ 1329 {{deliver, noop}, start}, /* ^1 */ 1330 {{deliver, noop}, button_2_down}, /* v2 */ 1331 {{deliver, noop}, start}, /* ^2 */ 1332 {{hold, setto}, button_3_pend}, /* v3 */ 1333 {{deliver, noop}, start}, /* ^3 */ 1334 {{deliver, noop}, start}, /* vo */ 1335 {{deliver, noop}, start}, /* ^o */ 1336 {{deliver, noop}, start}, /* <> */ 1337 {{deliver, noop}, start}, /* <-> */ 1338 {{noop, noop}, start}, /* k */ 1339 {{noop, noop}, start}, /* ... */ 1340 }, 1341 /* button_1_pend */ 1342 { 1343 {{noop, noop}, button_1_pend}, /* v1 */ 1344 {{release, deliver}, start}, /* ^1 */ 1345 {{release, deliver}, button_1_down}, /* v2 */ 1346 {{release, deliver}, button_1_down}, /* ^2 */ 1347 {{clearto, gen_down_2}, synth_2_down_13}, /* v3 */ 1348 {{release, deliver}, button_1_down}, /* ^3 */ 1349 {{release, deliver}, button_1_down}, /* vo */ 1350 {{release, deliver}, button_1_down}, /* ^o */ 1351 {{deliver, noop}, button_1_pend}, /* <> */ 1352 {{release, deliver}, button_1_down}, /* <-> */ 1353 {{noop, noop}, button_1_down}, /* k */ 1354 {{release, noop}, button_1_down}, /* ... */ 1355 }, 1356 /* button_1_down */ 1357 { 1358 {{noop, noop}, button_1_down}, /* v1 */ 1359 {{deliver, noop}, start}, /* ^1 */ 1360 {{deliver, noop}, button_1_down}, /* v2 */ 1361 {{deliver, noop}, button_1_down}, /* ^2 */ 1362 {{deliver, noop}, button_1_down}, /* v3 */ 1363 {{deliver, noop}, button_1_down}, /* ^3 */ 1364 {{deliver, noop}, button_1_down}, /* vo */ 1365 {{deliver, noop}, button_1_down}, /* ^o */ 1366 {{deliver, noop}, button_1_down}, /* <> */ 1367 {{deliver, noop}, button_1_down}, /* <-> */ 1368 {{noop, noop}, button_1_down}, /* k */ 1369 {{noop, noop}, button_1_down}, /* ... */ 1370 }, 1371 /* button_2_down */ 1372 { 1373 {{deliver, noop}, button_2_down}, /* v1 */ 1374 {{deliver, noop}, button_2_down}, /* ^1 */ 1375 {{noop, noop}, button_2_down}, /* v2 */ 1376 {{deliver, noop}, start}, /* ^2 */ 1377 {{deliver, noop}, button_2_down}, /* v3 */ 1378 {{deliver, noop}, button_2_down}, /* ^3 */ 1379 {{deliver, noop}, button_2_down}, /* vo */ 1380 {{deliver, noop}, button_2_down}, /* ^o */ 1381 {{deliver, noop}, button_2_down}, /* <> */ 1382 {{deliver, noop}, button_2_down}, /* <-> */ 1383 {{noop, noop}, button_2_down}, /* k */ 1384 {{noop, noop}, button_2_down}, /* ... */ 1385 }, 1386 /* button_3_pend */ 1387 { 1388 {{clearto, gen_down_2}, synth_2_down_13}, /* v1 */ 1389 {{release, deliver}, button_3_down}, /* ^1 */ 1390 {{release, deliver}, button_3_down}, /* v2 */ 1391 {{release, deliver}, button_3_down}, /* ^2 */ 1392 {{release, deliver}, button_3_down}, /* v3 */ 1393 {{release, deliver}, start}, /* ^3 */ 1394 {{release, deliver}, button_3_down}, /* vo */ 1395 {{release, deliver}, button_3_down}, /* ^o */ 1396 {{deliver, noop}, button_3_pend}, /* <> */ 1397 {{release, deliver}, button_3_down}, /* <-> */ 1398 {{release, noop}, button_3_down}, /* k */ 1399 {{release, noop}, button_3_down}, /* ... */ 1400 }, 1401 /* button_3_down */ 1402 { 1403 {{deliver, noop}, button_3_down}, /* v1 */ 1404 {{deliver, noop}, button_3_down}, /* ^1 */ 1405 {{deliver, noop}, button_3_down}, /* v2 */ 1406 {{deliver, noop}, button_3_down}, /* ^2 */ 1407 {{noop, noop}, button_3_down}, /* v3 */ 1408 {{deliver, noop}, start}, /* ^3 */ 1409 {{deliver, noop}, button_3_down}, /* vo */ 1410 {{deliver, noop}, button_3_down}, /* ^o */ 1411 {{deliver, noop}, button_3_down}, /* <> */ 1412 {{deliver, noop}, button_3_down}, /* <-> */ 1413 {{noop, noop}, button_3_down}, /* k */ 1414 {{noop, noop}, button_3_down}, /* ... */ 1415 }, 1416 /* synthetic_2_down_13 */ 1417 { 1418 {{noop, noop}, synth_2_down_13}, /* v1 */ 1419 {{gen_up_2, noop}, synth_2_down_3}, /* ^1 */ 1420 {{noop, noop}, synth_2_down_13}, /* v2 */ 1421 {{noop, noop}, synth_2_down_13}, /* ^2 */ 1422 {{noop, noop}, synth_2_down_13}, /* v3 */ 1423 {{gen_up_2, noop}, synth_2_down_1}, /* ^3 */ 1424 {{deliver, noop}, synth_2_down_13}, /* vo */ 1425 {{deliver, noop}, synth_2_down_13}, /* ^o */ 1426 {{deliver, noop}, synth_2_down_13}, /* <> */ 1427 {{deliver, noop}, synth_2_down_13}, /* <-> */ 1428 {{noop, noop}, synth_2_down_13}, /* k */ 1429 {{noop, noop}, synth_2_down_13}, /* ... */ 1430 }, 1431 /* synthetic_2_down_3 */ 1432 { 1433 {{deliver, noop}, synth_2_down_3}, /* v1 */ 1434 {{deliver, noop}, synth_2_down_3}, /* ^1 */ 1435 {{deliver, noop}, synth_2_down_3}, /* v2 */ 1436 {{deliver, noop}, synth_2_down_3}, /* ^2 */ 1437 {{noop, noop}, synth_2_down_3}, /* v3 */ 1438 {{noop, noop}, start}, /* ^3 */ 1439 {{deliver, noop}, synth_2_down_3}, /* vo */ 1440 {{deliver, noop}, synth_2_down_3}, /* ^o */ 1441 {{deliver, noop}, synth_2_down_3}, /* <> */ 1442 {{deliver, noop}, synth_2_down_3}, /* <-> */ 1443 {{noop, noop}, synth_2_down_3}, /* k */ 1444 {{noop, noop}, synth_2_down_3}, /* ... */ 1445 }, 1446 /* synthetic_2_down_1 */ 1447 { 1448 {{noop, noop}, synth_2_down_1}, /* v1 */ 1449 {{noop, noop}, start}, /* ^1 */ 1450 {{deliver, noop}, synth_2_down_1}, /* v2 */ 1451 {{deliver, noop}, synth_2_down_1}, /* ^2 */ 1452 {{deliver, noop}, synth_2_down_1}, /* v3 */ 1453 {{deliver, noop}, synth_2_down_1}, /* ^3 */ 1454 {{deliver, noop}, synth_2_down_1}, /* vo */ 1455 {{deliver, noop}, synth_2_down_1}, /* ^o */ 1456 {{deliver, noop}, synth_2_down_1}, /* <> */ 1457 {{deliver, noop}, synth_2_down_1}, /* <-> */ 1458 {{noop, noop}, synth_2_down_1}, /* k */ 1459 {{noop, noop}, synth_2_down_1}, /* ... */ 1460 }, 1461}; 1462 1463#define EMULATION_WINDOW 10 1464#define EMULATION_TIMEOUT 100 1465 1466static int 1467KdInsideEmulationWindow(KdPointerInfo * pi, int x, int y, int z) 1468{ 1469 pi->emulationDx = pi->heldEvent.x - x; 1470 pi->emulationDy = pi->heldEvent.y - y; 1471 1472 return (abs(pi->emulationDx) < EMULATION_WINDOW && 1473 abs(pi->emulationDy) < EMULATION_WINDOW); 1474} 1475 1476static KdInputClass 1477KdClassifyInput(KdPointerInfo * pi, int type, int x, int y, int z, int b) 1478{ 1479 switch (type) { 1480 case ButtonPress: 1481 switch (b) { 1482 case 1: 1483 return down_1; 1484 case 2: 1485 return down_2; 1486 case 3: 1487 return down_3; 1488 default: 1489 return down_o; 1490 } 1491 break; 1492 case ButtonRelease: 1493 switch (b) { 1494 case 1: 1495 return up_1; 1496 case 2: 1497 return up_2; 1498 case 3: 1499 return up_3; 1500 default: 1501 return up_o; 1502 } 1503 break; 1504 case MotionNotify: 1505 if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) 1506 return outside_box; 1507 else 1508 return motion; 1509 default: 1510 return keyboard; 1511 } 1512 return keyboard; 1513} 1514 1515static void 1516_KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z, 1517 int b, int absrel, Bool force); 1518/* We return true if we're stealing the event. */ 1519static Bool 1520KdRunMouseMachine(KdPointerInfo * pi, KdInputClass c, int type, int x, int y, 1521 int z, int b, int absrel) 1522{ 1523 const KdInputTransition *t; 1524 int a; 1525 1526 c = KdClassifyInput(pi, type, x, y, z, b); 1527 t = &kdInputMachine[pi->mouseState][c]; 1528 for (a = 0; a < MAX_ACTIONS; a++) { 1529 switch (t->actions[a]) { 1530 case noop: 1531 break; 1532 case hold: 1533 pi->eventHeld = TRUE; 1534 pi->emulationDx = 0; 1535 pi->emulationDy = 0; 1536 pi->heldEvent.type = type; 1537 pi->heldEvent.x = x; 1538 pi->heldEvent.y = y; 1539 pi->heldEvent.z = z; 1540 pi->heldEvent.flags = b; 1541 pi->heldEvent.absrel = absrel; 1542 return TRUE; 1543 break; 1544 case setto: 1545 pi->emulationTimeout = GetTimeInMillis() + EMULATION_TIMEOUT; 1546 pi->timeoutPending = TRUE; 1547 break; 1548 case deliver: 1549 _KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x, 1550 pi->heldEvent.y, pi->heldEvent.z, 1551 pi->heldEvent.flags, pi->heldEvent.absrel, 1552 TRUE); 1553 break; 1554 case release: 1555 pi->eventHeld = FALSE; 1556 pi->timeoutPending = FALSE; 1557 _KdEnqueuePointerEvent(pi, pi->heldEvent.type, pi->heldEvent.x, 1558 pi->heldEvent.y, pi->heldEvent.z, 1559 pi->heldEvent.flags, pi->heldEvent.absrel, 1560 TRUE); 1561 return TRUE; 1562 break; 1563 case clearto: 1564 pi->timeoutPending = FALSE; 1565 break; 1566 case gen_down_2: 1567 _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, 2, absrel, TRUE); 1568 pi->eventHeld = FALSE; 1569 return TRUE; 1570 break; 1571 case gen_up_2: 1572 _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, 2, absrel, TRUE); 1573 return TRUE; 1574 break; 1575 } 1576 } 1577 pi->mouseState = t->nextState; 1578 return FALSE; 1579} 1580 1581static int 1582KdHandlePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z, int b, 1583 int absrel) 1584{ 1585 if (pi->emulateMiddleButton) 1586 return KdRunMouseMachine(pi, KdClassifyInput(pi, type, x, y, z, b), 1587 type, x, y, z, b, absrel); 1588 return FALSE; 1589} 1590 1591static void 1592_KdEnqueuePointerEvent(KdPointerInfo * pi, int type, int x, int y, int z, 1593 int b, int absrel, Bool force) 1594{ 1595 int valuators[3] = { x, y, z }; 1596 ValuatorMask mask; 1597 1598 /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ 1599 if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) 1600 return; 1601 1602 valuator_mask_set_range(&mask, 0, 3, valuators); 1603 1604 QueuePointerEvents(pi->dixdev, type, b, absrel, &mask); 1605} 1606 1607static void 1608KdReceiveTimeout(KdPointerInfo * pi) 1609{ 1610 KdRunMouseMachine(pi, timeout, 0, 0, 0, 0, 0, 0); 1611} 1612 1613extern int nClients; 1614 1615static void 1616KdCheckLock(void) 1617{ 1618 KeyClassPtr keyc = NULL; 1619 Bool isSet = FALSE, shouldBeSet = FALSE; 1620 KdKeyboardInfo *tmp = NULL; 1621 1622 for (tmp = kdKeyboards; tmp; tmp = tmp->next) { 1623 if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { 1624 keyc = tmp->dixdev->key; 1625 isSet = (tmp->leds & (1 << (tmp->LockLed - 1))) != 0; 1626 /* FIXME: Just use XKB indicators! */ 1627 shouldBeSet = 1628 ! !(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask); 1629 if (isSet != shouldBeSet) 1630 KdSetLed(tmp, tmp->LockLed, shouldBeSet); 1631 } 1632 } 1633} 1634 1635void 1636KdEnqueueKeyboardEvent(KdKeyboardInfo * ki, 1637 unsigned char scan_code, unsigned char is_up) 1638{ 1639 unsigned char key_code; 1640 int type; 1641 1642 if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) 1643 return; 1644 1645 if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) { 1646 key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; 1647 1648 /* 1649 * Set up this event -- the type may be modified below 1650 */ 1651 if (is_up) 1652 type = KeyRelease; 1653 else 1654 type = KeyPress; 1655 1656 QueueKeyboardEvents(ki->dixdev, type, key_code); 1657 } 1658 else { 1659 ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", 1660 ki->name, scan_code, ki->minScanCode, ki->maxScanCode); 1661 } 1662} 1663 1664/* 1665 * kdEnqueuePointerEvent 1666 * 1667 * This function converts hardware mouse event information into X event 1668 * information. A mouse movement event is passed off to MI to generate 1669 * a MotionNotify event, if appropriate. Button events are created and 1670 * passed off to MI for enqueueing. 1671 */ 1672 1673/* FIXME do something a little more clever to deal with multiple axes here */ 1674void 1675KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry, 1676 int rz) 1677{ 1678 unsigned char buttons; 1679 int x, y, z; 1680 int (*matrix)[3] = kdPointerMatrix.matrix; 1681 unsigned long button; 1682 int n; 1683 int dixflags = 0; 1684 1685 if (!pi) 1686 return; 1687 1688 /* we don't need to transform z, so we don't. */ 1689 if (flags & KD_MOUSE_DELTA) { 1690 if (pi->transformCoordinates) { 1691 x = matrix[0][0] * rx + matrix[0][1] * ry; 1692 y = matrix[1][0] * rx + matrix[1][1] * ry; 1693 } 1694 else { 1695 x = rx; 1696 y = ry; 1697 } 1698 } 1699 else { 1700 if (pi->transformCoordinates) { 1701 x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2]; 1702 y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2]; 1703 } 1704 else { 1705 x = rx; 1706 y = ry; 1707 } 1708 } 1709 z = rz; 1710 1711 if (flags & KD_MOUSE_DELTA) { 1712 if (x || y || z) { 1713 dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; 1714 _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, 1715 FALSE); 1716 } 1717 } 1718 else { 1719 dixflags = POINTER_ABSOLUTE; 1720 if (flags & KD_POINTER_DESKTOP) 1721 dixflags |= POINTER_DESKTOP; 1722 if (x != pi->dixdev->last.valuators[0] || 1723 y != pi->dixdev->last.valuators[1]) 1724 _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, 1725 FALSE); 1726 } 1727 1728 buttons = flags; 1729 1730 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) { 1731 if (((pi->buttonState & button) ^ (buttons & button)) && 1732 !(buttons & button)) { 1733 _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, 1734 dixflags, FALSE); 1735 } 1736 } 1737 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; button <<= 1, n++) { 1738 if (((pi->buttonState & button) ^ (buttons & button)) && 1739 (buttons & button)) { 1740 _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, 1741 dixflags, FALSE); 1742 } 1743 } 1744 1745 pi->buttonState = buttons; 1746} 1747 1748void 1749KdBlockHandler(ScreenPtr pScreen, void *timeo) 1750{ 1751 KdPointerInfo *pi; 1752 int myTimeout = 0; 1753 1754 for (pi = kdPointers; pi; pi = pi->next) { 1755 if (pi->timeoutPending) { 1756 int ms; 1757 1758 ms = pi->emulationTimeout - GetTimeInMillis(); 1759 if (ms < 1) 1760 ms = 1; 1761 if (ms < myTimeout || myTimeout == 0) 1762 myTimeout = ms; 1763 } 1764 } 1765 if (myTimeout > 0) 1766 AdjustWaitForDelay(timeo, myTimeout); 1767} 1768 1769void 1770KdWakeupHandler(ScreenPtr pScreen, int result) 1771{ 1772 KdPointerInfo *pi; 1773 1774 for (pi = kdPointers; pi; pi = pi->next) { 1775 if (pi->timeoutPending) { 1776 if ((long) (GetTimeInMillis() - pi->emulationTimeout) >= 0) { 1777 pi->timeoutPending = FALSE; 1778 input_lock(); 1779 KdReceiveTimeout(pi); 1780 input_unlock(); 1781 } 1782 } 1783 } 1784} 1785 1786#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) 1787 1788static Bool 1789KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 1790{ 1791 ScreenPtr pScreen = *ppScreen; 1792 ScreenPtr pNewScreen; 1793 int n; 1794 int dx, dy; 1795 int best_x, best_y; 1796 int n_best_x, n_best_y; 1797 CARD32 ms; 1798 1799 if (kdDisableZaphod || screenInfo.numScreens <= 1) 1800 return FALSE; 1801 1802 if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) 1803 return FALSE; 1804 1805 ms = GetTimeInMillis(); 1806 if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) 1807 return FALSE; 1808 kdOffScreen = TRUE; 1809 kdOffScreenTime = ms; 1810 n_best_x = -1; 1811 best_x = 32767; 1812 n_best_y = -1; 1813 best_y = 32767; 1814 for (n = 0; n < screenInfo.numScreens; n++) { 1815 pNewScreen = screenInfo.screens[n]; 1816 if (pNewScreen == pScreen) 1817 continue; 1818 dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; 1819 dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; 1820 if (*x < 0) { 1821 if (dx < 0 && -dx < best_x) { 1822 best_x = -dx; 1823 n_best_x = n; 1824 } 1825 } 1826 else if (*x >= pScreen->width) { 1827 if (dx > 0 && dx < best_x) { 1828 best_x = dx; 1829 n_best_x = n; 1830 } 1831 } 1832 if (*y < 0) { 1833 if (dy < 0 && -dy < best_y) { 1834 best_y = -dy; 1835 n_best_y = n; 1836 } 1837 } 1838 else if (*y >= pScreen->height) { 1839 if (dy > 0 && dy < best_y) { 1840 best_y = dy; 1841 n_best_y = n; 1842 } 1843 } 1844 } 1845 if (best_y < best_x) 1846 n_best_x = n_best_y; 1847 if (n_best_x == -1) 1848 return FALSE; 1849 pNewScreen = screenInfo.screens[n_best_x]; 1850 1851 if (*x < 0) 1852 *x += pNewScreen->width; 1853 if (*y < 0) 1854 *y += pNewScreen->height; 1855 1856 if (*x >= pScreen->width) 1857 *x -= pScreen->width; 1858 if (*y >= pScreen->height) 1859 *y -= pScreen->height; 1860 1861 *ppScreen = pNewScreen; 1862 return TRUE; 1863} 1864 1865static void 1866KdCrossScreen(ScreenPtr pScreen, Bool entering) 1867{ 1868} 1869 1870static void 1871KdWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 1872{ 1873 input_lock(); 1874 miPointerWarpCursor(pDev, pScreen, x, y); 1875 input_unlock(); 1876} 1877 1878miPointerScreenFuncRec kdPointerScreenFuncs = { 1879 KdCursorOffScreen, 1880 KdCrossScreen, 1881 KdWarpCursor 1882}; 1883 1884void 1885ProcessInputEvents(void) 1886{ 1887 mieqProcessInputEvents(); 1888 KdCheckLock(); 1889} 1890 1891/* At the moment, absolute/relative is up to the client. */ 1892int 1893SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) 1894{ 1895 return BadMatch; 1896} 1897 1898int 1899SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, 1900 int *valuators, int first_valuator, int num_valuators) 1901{ 1902 return BadMatch; 1903} 1904 1905int 1906ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, 1907 xDeviceCtl * control) 1908{ 1909 switch (control->control) { 1910 case DEVICE_RESOLUTION: 1911 /* FIXME do something more intelligent here */ 1912 return BadMatch; 1913 1914 case DEVICE_ABS_CALIB: 1915 case DEVICE_ABS_AREA: 1916 case DEVICE_CORE: 1917 return BadMatch; 1918 case DEVICE_ENABLE: 1919 return Success; 1920 1921 default: 1922 return BadMatch; 1923 } 1924 1925 /* NOTREACHED */ 1926 return BadImplementation; 1927} 1928 1929int 1930NewInputDeviceRequest(InputOption *options, InputAttributes * attrs, 1931 DeviceIntPtr *pdev) 1932{ 1933 InputOption *option = NULL, *optionsdup = NULL; 1934 KdPointerInfo *pi = NULL; 1935 KdKeyboardInfo *ki = NULL; 1936 1937 nt_list_for_each_entry(option, options, list.next) { 1938 const char *key = input_option_get_key(option); 1939 const char *value = input_option_get_value(option); 1940 optionsdup = input_option_new(optionsdup, key, value); 1941 1942 if (strcmp(key, "type") == 0) { 1943 if (strcmp(value, "pointer") == 0) { 1944 pi = KdNewPointer(); 1945 if (!pi) { 1946 input_option_free_list(&optionsdup); 1947 return BadAlloc; 1948 } 1949 } 1950 else if (strcmp(value, "keyboard") == 0) { 1951 ki = KdNewKeyboard(); 1952 if (!ki) { 1953 input_option_free_list(&optionsdup); 1954 return BadAlloc; 1955 } 1956 } 1957 else { 1958 ErrorF("unrecognised device type!\n"); 1959 return BadValue; 1960 } 1961 } 1962#ifdef CONFIG_HAL 1963 else if (strcmp(key, "_source") == 0 && 1964 strcmp(value, "server/hal") == 0) { 1965 if (SeatId) { 1966 /* Input hot-plugging is enabled */ 1967 if (attrs->flags & ATTR_POINTER) { 1968 pi = KdNewPointer(); 1969 if (!pi) { 1970 input_option_free_list(&optionsdup); 1971 return BadAlloc; 1972 } 1973 } 1974 else if (attrs->flags & ATTR_KEYBOARD) { 1975 ki = KdNewKeyboard(); 1976 if (!ki) { 1977 input_option_free_list(&optionsdup); 1978 return BadAlloc; 1979 } 1980 } 1981 } 1982 else { 1983 ErrorF("Ignoring device from HAL.\n"); 1984 input_option_free_list(&optionsdup); 1985 return BadValue; 1986 } 1987 } 1988#endif 1989#ifdef CONFIG_UDEV 1990 else if (strcmp(key, "_source") == 0 && 1991 strcmp(value, "server/udev") == 0) { 1992 if (SeatId) { 1993 /* Input hot-plugging is enabled */ 1994 if (attrs->flags & ATTR_POINTER) { 1995 pi = KdNewPointer(); 1996 if (!pi) { 1997 input_option_free_list(&optionsdup); 1998 return BadAlloc; 1999 } 2000 } 2001 else if (attrs->flags & ATTR_KEYBOARD) { 2002 ki = KdNewKeyboard(); 2003 if (!ki) { 2004 input_option_free_list(&optionsdup); 2005 return BadAlloc; 2006 } 2007 } 2008 } 2009 else { 2010 ErrorF("Ignoring device from udev.\n"); 2011 input_option_free_list(&optionsdup); 2012 return BadValue; 2013 } 2014 } 2015#endif 2016 } 2017 2018 if (pi) { 2019 pi->options = optionsdup; 2020 KdParsePointerOptions(pi); 2021 2022 if (!pi->driver) { 2023 ErrorF("couldn't find driver for pointer device \"%s\" (%s)\n", 2024 pi->name ? pi->name : "(unnamed)", pi->path); 2025 KdFreePointer(pi); 2026 return BadValue; 2027 } 2028 2029 if (KdAddPointer(pi) != Success || 2030 ActivateDevice(pi->dixdev, TRUE) != Success || 2031 EnableDevice(pi->dixdev, TRUE) != TRUE) { 2032 ErrorF("couldn't add or enable pointer \"%s\" (%s)\n", 2033 pi->name ? pi->name : "(unnamed)", pi->path); 2034 KdFreePointer(pi); 2035 return BadImplementation; 2036 } 2037 2038 *pdev = pi->dixdev; 2039 } 2040 else if (ki) { 2041 ki->options = optionsdup; 2042 KdParseKbdOptions(ki); 2043 2044 if (!ki->driver) { 2045 ErrorF("couldn't find driver for keyboard device \"%s\" (%s)\n", 2046 ki->name ? ki->name : "(unnamed)", ki->path); 2047 KdFreeKeyboard(ki); 2048 return BadValue; 2049 } 2050 2051 if (KdAddKeyboard(ki) != Success || 2052 ActivateDevice(ki->dixdev, TRUE) != Success || 2053 EnableDevice(ki->dixdev, TRUE) != TRUE) { 2054 ErrorF("couldn't add or enable keyboard \"%s\" (%s)\n", 2055 ki->name ? ki->name : "(unnamed)", ki->path); 2056 KdFreeKeyboard(ki); 2057 return BadImplementation; 2058 } 2059 2060 *pdev = ki->dixdev; 2061 } 2062 else { 2063 ErrorF("unrecognised device identifier: %s\n", 2064 input_option_get_value(input_option_find(optionsdup, 2065 "device"))); 2066 input_option_free_list(&optionsdup); 2067 return BadValue; 2068 } 2069 2070 return Success; 2071} 2072 2073void 2074DeleteInputDeviceRequest(DeviceIntPtr pDev) 2075{ 2076 RemoveDevice(pDev, TRUE); 2077} 2078 2079void 2080RemoveInputDeviceTraces(const char *config_info) 2081{ 2082} 2083