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