kinput.c revision 05b261ec
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_CONFIG_H 25#include <kdrive-config.h> 26#endif 27#include "kdrive.h" 28#include "inputstr.h" 29 30#define XK_PUBLISHING 31#include <X11/keysym.h> 32#if HAVE_X11_XF86KEYSYM_H 33#include <X11/XF86keysym.h> 34#endif 35#include <signal.h> 36#include <stdio.h> 37#ifdef sun 38#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ 39#endif 40 41#ifdef XKB 42#include <xkbsrv.h> 43#endif 44 45#include <X11/extensions/XI.h> 46#include <X11/extensions/XIproto.h> 47#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ 48#include "exevents.h" 49#include "extinit.h" 50#include "exglobals.h" 51 52#define AtomFromName(x) MakeAtom(x, strlen(x), 1) 53 54struct KdConfigDevice { 55 char *line; 56 struct KdConfigDevice *next; 57}; 58 59/* kdKeyboards and kdPointers hold all the real devices. */ 60static KdKeyboardInfo *kdKeyboards = NULL; 61static KdPointerInfo *kdPointers = NULL; 62static struct KdConfigDevice *kdConfigKeyboards = NULL; 63static struct KdConfigDevice *kdConfigPointers = NULL; 64 65static KdKeyboardDriver *kdKeyboardDrivers = NULL; 66static KdPointerDriver *kdPointerDrivers = NULL; 67 68static xEvent *kdEvents = NULL; 69 70static Bool kdInputEnabled; 71static Bool kdOffScreen; 72static unsigned long kdOffScreenTime; 73static KdPointerMatrix kdPointerMatrix = { 74 { { 1, 0, 0 }, 75 { 0, 1, 0 } } 76}; 77 78void KdResetInputMachine (void); 79 80#define IsKeyDown(ki, key) ((ki->keyState[(key) >> 3] >> ((key) & 7)) & 1) 81#define KEYMAP(ki) (ki->dixdev->key->curKeySyms) 82#define KEYMAPDDX(ki) (ki->keySyms) 83#define KEYCOL1(ki, k) (KEYMAP(ki).map[((k)-(KEYMAP(ki).minKeyCode))*KEYMAP(ki).mapWidth]) 84#define KEYCOL1DDX(ki, k) (KEYMAPDDX(ki).map[((k)-(KEYMAPDDX(ki).minKeyCode))*KEYMAPDDX(ki).mapWidth]) 85 86#define KD_MAX_INPUT_FDS 8 87 88typedef struct _kdInputFd { 89 int fd; 90 void (*read) (int fd, void *closure); 91 int (*enable) (int fd, void *closure); 92 void (*disable) (int fd, void *closure); 93 void *closure; 94} KdInputFd; 95 96static KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; 97static int kdNumInputFds; 98 99extern Bool kdRawPointerCoordinates; 100 101static void 102KdSigio (int sig) 103{ 104 int i; 105 106 for (i = 0; i < kdNumInputFds; i++) 107 (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); 108} 109 110static void 111KdBlockSigio (void) 112{ 113 sigset_t set; 114 115 sigemptyset (&set); 116 sigaddset (&set, SIGIO); 117 sigprocmask (SIG_BLOCK, &set, 0); 118} 119 120static void 121KdUnblockSigio (void) 122{ 123 sigset_t set; 124 125 sigemptyset (&set); 126 sigaddset (&set, SIGIO); 127 sigprocmask (SIG_UNBLOCK, &set, 0); 128} 129 130#ifdef DEBUG_SIGIO 131 132void 133KdAssertSigioBlocked (char *where) 134{ 135 sigset_t set, old; 136 137 sigemptyset (&set); 138 sigprocmask (SIG_BLOCK, &set, &old); 139 if (!sigismember (&old, SIGIO)) { 140 ErrorF ("SIGIO not blocked at %s\n", where); 141 KdBacktrace(0); 142 } 143} 144 145#else 146 147#define KdAssertSigioBlocked(s) 148 149#endif 150 151static int kdnFds; 152 153#ifdef FNONBLOCK 154#define NOBLOCK FNONBLOCK 155#else 156#define NOBLOCK FNDELAY 157#endif 158 159void 160KdResetInputMachine (void) 161{ 162 KdPointerInfo *pi; 163 164 for (pi = kdPointers; pi; pi = pi->next) { 165 pi->mouseState = start; 166 pi->eventHeld = FALSE; 167 } 168} 169 170static void 171KdNonBlockFd (int fd) 172{ 173 int flags; 174 flags = fcntl (fd, F_GETFL); 175 flags |= FASYNC|NOBLOCK; 176 fcntl (fd, F_SETFL, flags); 177} 178 179static void 180KdAddFd (int fd) 181{ 182 struct sigaction act; 183 sigset_t set; 184 185 kdnFds++; 186 fcntl (fd, F_SETOWN, getpid()); 187 KdNonBlockFd (fd); 188 AddEnabledDevice (fd); 189 memset (&act, '\0', sizeof act); 190 act.sa_handler = KdSigio; 191 sigemptyset (&act.sa_mask); 192 sigaddset (&act.sa_mask, SIGIO); 193 sigaddset (&act.sa_mask, SIGALRM); 194 sigaddset (&act.sa_mask, SIGVTALRM); 195 sigaction (SIGIO, &act, 0); 196 sigemptyset (&set); 197 sigprocmask (SIG_SETMASK, &set, 0); 198} 199 200static void 201KdRemoveFd (int fd) 202{ 203 struct sigaction act; 204 int flags; 205 206 kdnFds--; 207 RemoveEnabledDevice (fd); 208 flags = fcntl (fd, F_GETFL); 209 flags &= ~(FASYNC|NOBLOCK); 210 fcntl (fd, F_SETFL, flags); 211 if (kdnFds == 0) 212 { 213 memset (&act, '\0', sizeof act); 214 act.sa_handler = SIG_IGN; 215 sigemptyset (&act.sa_mask); 216 sigaction (SIGIO, &act, 0); 217 } 218} 219 220Bool 221KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure) 222{ 223 if (kdNumInputFds == KD_MAX_INPUT_FDS) 224 return FALSE; 225 kdInputFds[kdNumInputFds].fd = fd; 226 kdInputFds[kdNumInputFds].read = read; 227 kdInputFds[kdNumInputFds].enable = 0; 228 kdInputFds[kdNumInputFds].disable = 0; 229 kdInputFds[kdNumInputFds].closure = closure; 230 kdNumInputFds++; 231 if (kdInputEnabled) 232 KdAddFd (fd); 233 return TRUE; 234} 235 236void 237KdUnregisterFd (void *closure, int fd, Bool do_close) 238{ 239 int i, j; 240 241 for (i = 0; i < kdNumInputFds; i++) { 242 if (kdInputFds[i].closure == closure && 243 (fd == -1 || kdInputFds[i].fd == fd)) { 244 if (kdInputEnabled) 245 KdRemoveFd (kdInputFds[i].fd); 246 if (do_close) 247 close (kdInputFds[i].fd); 248 kdNumInputFds--; 249 for (j = i; j < kdNumInputFds; j++) 250 kdInputFds[j] = kdInputFds[j+1]; 251 break; 252 } 253 } 254} 255 256void 257KdUnregisterFds (void *closure, Bool do_close) 258{ 259 KdUnregisterFd(closure, -1, do_close); 260} 261 262void 263KdDisableInput (void) 264{ 265 KdKeyboardInfo *ki; 266 KdPointerInfo *pi; 267 int found = 0, i = 0; 268 269 KdBlockSigio(); 270 271 for (ki = kdKeyboards; ki; ki = ki->next) { 272 if (ki->driver && ki->driver->Disable) 273 (*ki->driver->Disable) (ki); 274 } 275 276 for (pi = kdPointers; pi; pi = pi->next) { 277 if (pi->driver && pi->driver->Disable) 278 (*pi->driver->Disable) (pi); 279 } 280 281 if (kdNumInputFds) { 282 ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!", 283 kdNumInputFds); 284 i = 0; 285 while (i < kdNumInputFds) { 286 found = 0; 287 for (ki = kdKeyboards; ki; ki = ki->next) { 288 if (ki == kdInputFds[i].closure) { 289 ErrorF(" fd %d belongs to keybd driver %s\n", 290 kdInputFds[i].fd, 291 ki->driver && ki->driver->name ? 292 ki->driver->name : "(unnamed!)"); 293 found = 1; 294 break; 295 } 296 } 297 298 if (found) { 299 i++; 300 continue; 301 } 302 303 for (pi = kdPointers; pi; pi = pi->next) { 304 if (pi == kdInputFds[i].closure) { 305 ErrorF(" fd %d belongs to pointer driver %s\n", 306 kdInputFds[i].fd, 307 pi->driver && pi->driver->name ? 308 pi->driver->name : "(unnamed!)"); 309 break; 310 } 311 } 312 313 if (found) { 314 i++; 315 continue; 316 } 317 318 ErrorF(" fd %d not claimed by any active device!\n", 319 kdInputFds[i].fd); 320 KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE); 321 } 322 } 323 324 kdInputEnabled = FALSE; 325} 326 327void 328KdEnableInput (void) 329{ 330 xEvent xE; 331 KdKeyboardInfo *ki; 332 KdPointerInfo *pi; 333 334 kdInputEnabled = TRUE; 335 336 for (ki = kdKeyboards; ki; ki = ki->next) { 337 if (ki->driver && ki->driver->Enable) 338 (*ki->driver->Enable) (ki); 339 } 340 341 for (pi = kdPointers; pi; pi = pi->next) { 342 if (pi->driver && pi->driver->Enable) 343 (*pi->driver->Enable) (pi); 344 } 345 346 /* reset screen saver */ 347 xE.u.keyButtonPointer.time = GetTimeInMillis (); 348 NoticeEventTime (&xE); 349 350 KdUnblockSigio (); 351} 352 353static KdKeyboardDriver * 354KdFindKeyboardDriver (char *name) 355{ 356 KdKeyboardDriver *ret; 357 358 /* ask a stupid question ... */ 359 if (!name) 360 return NULL; 361 362 for (ret = kdKeyboardDrivers; ret; ret = ret->next) { 363 if (strcmp(ret->name, name) == 0) 364 return ret; 365 } 366 367 return NULL; 368} 369 370static KdPointerDriver * 371KdFindPointerDriver (char *name) 372{ 373 KdPointerDriver *ret; 374 375 /* ask a stupid question ... */ 376 if (!name) 377 return NULL; 378 379 for (ret = kdPointerDrivers; ret; ret = ret->next) { 380 if (strcmp(ret->name, name) == 0) 381 return ret; 382 } 383 384 return NULL; 385} 386 387static int 388KdPointerProc(DeviceIntPtr pDevice, int onoff) 389{ 390 DevicePtr pDev = (DevicePtr)pDevice; 391 KdPointerInfo *pi; 392 Atom xiclass; 393 394 if (!pDev) 395 return BadImplementation; 396 397 for (pi = kdPointers; pi; pi = pi->next) { 398 if (pi->dixdev && pi->dixdev->id == pDevice->id) 399 break; 400 } 401 402 if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { 403 ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", 404 pDevice->id); 405 return BadImplementation; 406 } 407 408 switch (onoff) 409 { 410 case DEVICE_INIT: 411#ifdef DEBUG 412 ErrorF("initialising pointer %s ...\n", pi->name); 413#endif 414 if (!pi->driver) { 415 if (!pi->driverPrivate) { 416 ErrorF("no driver specified for %s\n", pi->name); 417 return BadImplementation; 418 } 419 420 pi->driver = KdFindPointerDriver(pi->driverPrivate); 421 if (!pi->driver) { 422 ErrorF("Couldn't find pointer driver %s\n", 423 pi->driverPrivate ? (char *) pi->driverPrivate : 424 "(unnamed)"); 425 return !Success; 426 } 427 xfree(pi->driverPrivate); 428 pi->driverPrivate = NULL; 429 } 430 431 if (!pi->driver->Init) { 432 ErrorF("no init function\n"); 433 return BadImplementation; 434 } 435 436 if ((*pi->driver->Init) (pi) != Success) { 437 return !Success; 438 } 439 440 InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, 441 GetMotionHistory, 442 (PtrCtrlProcPtr)NoopDDA, 443 GetMotionHistorySize(), pi->nAxes); 444 445 if (pi->inputClass == KD_TOUCHSCREEN) { 446 InitAbsoluteClassDeviceStruct(pDevice); 447 xiclass = AtomFromName(XI_TOUCHSCREEN); 448 } 449 else { 450 xiclass = AtomFromName(XI_MOUSE); 451 } 452 453 AssignTypeAndName(pi->dixdev, xiclass, 454 pi->name ? pi->name : "Generic KDrive Pointer"); 455 456 return Success; 457 458 case DEVICE_ON: 459 if (pDev->on == TRUE) 460 return Success; 461 462 if (!pi->driver->Enable) { 463 ErrorF("no enable function\n"); 464 return BadImplementation; 465 } 466 467 if ((*pi->driver->Enable) (pi) == Success) { 468 pDev->on = TRUE; 469 return Success; 470 } 471 else { 472 return BadImplementation; 473 } 474 475 return Success; 476 477 case DEVICE_OFF: 478 if (pDev->on == FALSE) { 479 return Success; 480 } 481 482 if (!pi->driver->Disable) { 483 return BadImplementation; 484 } 485 else { 486 (*pi->driver->Disable) (pi); 487 pDev->on = FALSE; 488 return Success; 489 } 490 491 return Success; 492 493 case DEVICE_CLOSE: 494 if (pDev->on) { 495 if (!pi->driver->Disable) { 496 return BadImplementation; 497 } 498 (*pi->driver->Disable) (pi); 499 pDev->on = FALSE; 500 } 501 502 if (!pi->driver->Fini) 503 return BadImplementation; 504 505 (*pi->driver->Fini) (pi); 506 507 KdRemovePointer(pi); 508 509 return Success; 510 } 511 512 /* NOTREACHED */ 513 return BadImplementation; 514} 515 516Bool 517LegalModifier(unsigned int key, DeviceIntPtr pDev) 518{ 519 return TRUE; 520} 521 522static void 523KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something) 524{ 525 KeybdCtrl *ctrl = arg; 526 KdKeyboardInfo *ki = NULL; 527 528 for (ki = kdKeyboards; ki; ki = ki->next) { 529 if (ki->dixdev && ki->dixdev->id == pDev->id) 530 break; 531 } 532 533 if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) 534 return; 535 536 KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); 537} 538 539void 540DDXRingBell(int volume, int pitch, int duration) 541{ 542 KdKeyboardInfo *ki = NULL; 543 544 if (kdOsFuncs->Bell) { 545 (*kdOsFuncs->Bell)(volume, pitch, duration); 546 } 547 else { 548 for (ki = kdKeyboards; ki; ki = ki->next) { 549 if (ki->dixdev->coreEvents) 550 KdRingBell(ki, volume, pitch, duration); 551 } 552 } 553} 554 555void 556KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration) 557{ 558 if (!ki || !ki->driver || !ki->driver->Bell) 559 return; 560 561 if (kdInputEnabled) 562 (*ki->driver->Bell) (ki, volume, pitch, duration); 563} 564 565 566static void 567KdSetLeds (KdKeyboardInfo *ki, int leds) 568{ 569 if (!ki || !ki->driver) 570 return; 571 572 if (kdInputEnabled) { 573 if (ki->driver->Leds) 574 (*ki->driver->Leds) (ki, leds); 575 } 576} 577 578void 579KdSetLed (KdKeyboardInfo *ki, int led, Bool on) 580{ 581 if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) 582 return; 583 584 NoteLedState (ki->dixdev, led, on); 585 KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds); 586} 587 588void 589KdSetPointerMatrix (KdPointerMatrix *matrix) 590{ 591 kdPointerMatrix = *matrix; 592} 593 594void 595KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width, 596 int height) 597{ 598 int x_dir = 1, y_dir = 1; 599 int i, j; 600 int size[2]; 601 602 size[0] = width; size[1] = height; 603 if (randr & RR_Reflect_X) 604 x_dir = -1; 605 if (randr & RR_Reflect_Y) 606 y_dir = -1; 607 switch (randr & (RR_Rotate_All)) { 608 case RR_Rotate_0: 609 m->matrix[0][0] = x_dir; m->matrix[0][1] = 0; 610 m->matrix[1][0] = 0; m->matrix[1][1] = y_dir; 611 break; 612 case RR_Rotate_90: 613 m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir; 614 m->matrix[1][0] = y_dir; m->matrix[1][1] = 0; 615 break; 616 case RR_Rotate_180: 617 m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0; 618 m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir; 619 break; 620 case RR_Rotate_270: 621 m->matrix[0][0] = 0; m->matrix[0][1] = x_dir; 622 m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0; 623 break; 624 } 625 for (i = 0; i < 2; i++) 626 { 627 m->matrix[i][2] = 0; 628 for (j = 0 ; j < 2; j++) 629 if (m->matrix[i][j] < 0) 630 m->matrix[i][2] = size[j] - 1; 631 } 632} 633 634static void 635KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl) 636{ 637 KdKeyboardInfo *ki; 638 639 for (ki = kdKeyboards; ki; ki = ki->next) { 640 if (ki->dixdev && ki->dixdev->id == pDevice->id) 641 break; 642 } 643 644 if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) 645 return; 646 647 KdSetLeds(ki, ctrl->leds); 648 ki->bellPitch = ctrl->bell_pitch; 649 ki->bellDuration = ctrl->bell_duration; 650} 651 652extern KeybdCtrl defaultKeyboardControl; 653 654static void 655KdInitAutoRepeats (KdKeyboardInfo *ki) 656{ 657 int key_code; 658 unsigned char mask; 659 int i; 660 unsigned char *repeats; 661 662 repeats = defaultKeyboardControl.autoRepeats; 663 memset (repeats, '\0', 32); 664 for (key_code = KD_MIN_KEYCODE; key_code <= KD_MAX_KEYCODE; key_code++) 665 { 666 if (!ki->modmap[key_code]) 667 { 668 i = key_code >> 3; 669 mask = 1 << (key_code & 7); 670 repeats[i] |= mask; 671 } 672 } 673} 674 675const KdKeySymModsRec kdKeySymMods[] = { 676 { XK_Control_L, ControlMask }, 677 { XK_Control_R, ControlMask }, 678 { XK_Shift_L, ShiftMask }, 679 { XK_Shift_R, ShiftMask }, 680 { XK_Caps_Lock, LockMask }, 681 { XK_Shift_Lock, LockMask }, 682 { XK_Alt_L, Mod1Mask }, 683 { XK_Alt_R, Mod1Mask }, 684 { XK_Meta_L, Mod1Mask }, 685 { XK_Meta_R, Mod1Mask }, 686 { XK_Num_Lock, Mod2Mask }, 687 { XK_Super_L, Mod3Mask }, 688 { XK_Super_R, Mod3Mask }, 689 { XK_Hyper_L, Mod3Mask }, 690 { XK_Hyper_R, Mod3Mask }, 691 { XK_Mode_switch, Mod4Mask }, 692 /* PDA specific hacks */ 693#ifdef XF86XK_Start 694 { XF86XK_Start, ControlMask }, 695#endif 696 { XK_Menu, ShiftMask }, 697 { XK_telephone, Mod1Mask }, 698#ifdef XF86XK_AudioRecord 699 { XF86XK_AudioRecord, Mod2Mask }, 700#endif 701#ifdef XF86XK_Calendar 702 { XF86XK_Calendar, Mod3Mask } 703#endif 704}; 705 706#define NUM_SYM_MODS (sizeof(kdKeySymMods) / sizeof(kdKeySymMods[0])) 707 708static void 709KdInitModMap (KdKeyboardInfo *ki) 710{ 711 int key_code; 712 int row; 713 int width; 714 KeySym *syms; 715 int i; 716 717 width = ki->keySyms.mapWidth; 718 for (key_code = ki->keySyms.minKeyCode; key_code <= ki->keySyms.maxKeyCode; key_code++) 719 { 720 ki->modmap[key_code] = 0; 721 syms = ki->keySyms.map + (key_code - ki->keySyms.minKeyCode) * width; 722 for (row = 0; row < width; row++, syms++) 723 { 724 for (i = 0; i < NUM_SYM_MODS; i++) 725 { 726 if (*syms == kdKeySymMods[i].modsym) 727 ki->modmap[key_code] |= kdKeySymMods[i].modbit; 728 } 729 } 730 } 731} 732 733static int 734KdKeyboardProc(DeviceIntPtr pDevice, int onoff) 735{ 736 Bool ret; 737 DevicePtr pDev = (DevicePtr)pDevice; 738 KdKeyboardInfo *ki; 739 Atom xiclass; 740#ifdef XKB 741 XkbComponentNamesRec names; 742#endif 743 744 if (!pDev) 745 return BadImplementation; 746 747 for (ki = kdKeyboards; ki; ki = ki->next) { 748 if (ki->dixdev && ki->dixdev->id == pDevice->id) 749 break; 750 } 751 752 if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { 753 return BadImplementation; 754 } 755 756 switch (onoff) 757 { 758 case DEVICE_INIT: 759#ifdef DEBUG 760 ErrorF("initialising keyboard %s\n", ki->name); 761#endif 762 if (!ki->driver) { 763 if (!ki->driverPrivate) { 764 ErrorF("no driver specified!\n"); 765 return BadImplementation; 766 } 767 768 ki->driver = KdFindKeyboardDriver(ki->driverPrivate); 769 if (!ki->driver) { 770 ErrorF("Couldn't find keyboard driver %s\n", 771 ki->driverPrivate ? (char *) ki->driverPrivate : 772 "(unnamed)"); 773 return !Success; 774 } 775 xfree(ki->driverPrivate); 776 ki->driverPrivate = NULL; 777 } 778 779 if (!ki->driver->Init) { 780 ErrorF("Keyboard %s: no init function\n", ki->name); 781 return BadImplementation; 782 } 783 784 if ((*ki->driver->Init) (ki) != Success) { 785 return !Success; 786 } 787 788 KdInitModMap(ki); 789 KdInitAutoRepeats(ki); 790 791#ifdef XKB 792 if (!noXkbExtension) { 793 memset(&names, 0, sizeof(XkbComponentNamesRec)); 794 795 XkbSetRulesDflts (ki->xkbRules, ki->xkbModel, ki->xkbLayout, 796 ki->xkbVariant, ki->xkbOptions); 797 798 ret = XkbInitKeyboardDeviceStruct (pDevice, 799 &names, 800 &ki->keySyms, 801 ki->modmap, 802 KdBell, KdKbdCtrl); 803 } 804 else 805#endif 806 ret = InitKeyboardDeviceStruct(pDev, 807 &ki->keySyms, 808 ki->modmap, 809 KdBell, KdKbdCtrl); 810 if (!ret) { 811 ErrorF("Couldn't initialise keyboard %s\n", ki->name); 812 return BadImplementation; 813 } 814 815 xiclass = AtomFromName(XI_KEYBOARD); 816 AssignTypeAndName(pDevice, xiclass, 817 ki->name ? ki->name : "Generic KDrive Keyboard"); 818 819 KdResetInputMachine(); 820 821 return Success; 822 823 case DEVICE_ON: 824 if (pDev->on == TRUE) 825 return Success; 826 827 if (!ki->driver->Enable) 828 return BadImplementation; 829 830 if ((*ki->driver->Enable) (ki) != Success) { 831 return BadMatch; 832 } 833 834 pDev->on = TRUE; 835 return Success; 836 837 case DEVICE_OFF: 838 if (pDev->on == FALSE) 839 return Success; 840 841 if (!ki->driver->Disable) 842 return BadImplementation; 843 844 (*ki->driver->Disable) (ki); 845 pDev->on = FALSE; 846 847 return Success; 848 849 break; 850 851 case DEVICE_CLOSE: 852 if (pDev->on) { 853 if (!ki->driver->Disable) 854 return BadImplementation; 855 856 (*ki->driver->Disable) (ki); 857 pDev->on = FALSE; 858 } 859 860 if (!ki->driver->Fini) 861 return BadImplementation; 862 863 (*ki->driver->Fini) (ki); 864 865 KdRemoveKeyboard(ki); 866 867 return Success; 868 } 869 870 /* NOTREACHED */ 871 return BadImplementation; 872} 873 874void 875KdAddPointerDriver (KdPointerDriver *driver) 876{ 877 KdPointerDriver **prev; 878 879 if (!driver) 880 return; 881 882 for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { 883 if (*prev == driver) 884 return; 885 } 886 *prev = driver; 887} 888 889void 890KdRemovePointerDriver (KdPointerDriver *driver) 891{ 892 KdPointerDriver *tmp; 893 894 if (!driver) 895 return; 896 897 /* FIXME remove all pointers using this driver */ 898 for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { 899 if (tmp->next == driver) 900 tmp->next = driver->next; 901 } 902 if (tmp == driver) 903 tmp = NULL; 904} 905 906void 907KdAddKeyboardDriver (KdKeyboardDriver *driver) 908{ 909 KdKeyboardDriver **prev; 910 911 if (!driver) 912 return; 913 914 for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { 915 if (*prev == driver) 916 return; 917 } 918 *prev = driver; 919} 920 921void 922KdRemoveKeyboardDriver (KdKeyboardDriver *driver) 923{ 924 KdKeyboardDriver *tmp; 925 926 if (!driver) 927 return; 928 929 /* FIXME remove all keyboards using this driver */ 930 for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { 931 if (tmp->next == driver) 932 tmp->next = driver->next; 933 } 934 if (tmp == driver) 935 tmp = NULL; 936} 937 938KdKeyboardInfo * 939KdNewKeyboard (void) 940{ 941 KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1); 942 943 if (!ki) 944 return NULL; 945 946 ki->keySyms.map = (KeySym *)xcalloc(sizeof(KeySym), 947 KD_MAX_LENGTH * 948 kdDefaultKeySyms.mapWidth); 949 if (!ki->keySyms.map) { 950 xfree(ki); 951 return NULL; 952 } 953 954 memcpy(ki->keySyms.map, kdDefaultKeySyms.map, 955 sizeof(KeySym) * (KD_MAX_LENGTH * kdDefaultKeySyms.mapWidth)); 956 ki->keySyms.minKeyCode = kdDefaultKeySyms.minKeyCode; 957 ki->keySyms.maxKeyCode = kdDefaultKeySyms.maxKeyCode; 958 ki->keySyms.mapWidth = kdDefaultKeySyms.mapWidth; 959 ki->minScanCode = 0; 960 ki->maxScanCode = 0; 961 ki->leds = 0; 962 ki->bellPitch = 1000; 963 ki->bellDuration = 200; 964 ki->next = NULL; 965 ki->options = NULL; 966#ifdef XKB 967 ki->xkbRules = KdSaveString("base"); 968 ki->xkbModel = KdSaveString("pc105"); 969 ki->xkbLayout = KdSaveString("us"); 970 ki->xkbVariant = NULL; 971 ki->xkbOptions = NULL; 972#endif 973 974 return ki; 975} 976 977int 978KdAddConfigKeyboard (char *keyboard) 979{ 980 struct KdConfigDevice **prev, *new; 981 982 if (!keyboard) 983 return Success; 984 985 new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); 986 if (!new) 987 return BadAlloc; 988 989 new->line = xstrdup(keyboard); 990 new->next = NULL; 991 992 for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); 993 *prev = new; 994 995 return Success; 996} 997 998int 999KdAddKeyboard (KdKeyboardInfo *ki) 1000{ 1001 KdKeyboardInfo **prev; 1002 1003 if (!ki) 1004 return !Success; 1005 1006 ki->dixdev = AddInputDevice(KdKeyboardProc, TRUE); 1007 if (!ki->dixdev) { 1008 ErrorF("Couldn't register keyboard device %s\n", 1009 ki->name ? ki->name : "(unnamed)"); 1010 return !Success; 1011 } 1012 1013 RegisterOtherDevice(ki->dixdev); 1014 1015#ifdef DEBUG 1016 ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); 1017#endif 1018 1019 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); 1020 *prev = ki; 1021 1022 return Success; 1023} 1024 1025void 1026KdRemoveKeyboard (KdKeyboardInfo *ki) 1027{ 1028 KdKeyboardInfo **prev; 1029 1030 if (!ki) 1031 return; 1032 1033 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { 1034 if (*prev == ki) { 1035 *prev = ki->next; 1036 break; 1037 } 1038 } 1039 1040 KdFreeKeyboard(ki); 1041} 1042 1043int 1044KdAddConfigPointer (char *pointer) 1045{ 1046 struct KdConfigDevice **prev, *new; 1047 1048 if (!pointer) 1049 return Success; 1050 1051 new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); 1052 if (!new) 1053 return BadAlloc; 1054 1055 new->line = xstrdup(pointer); 1056 new->next = NULL; 1057 1058 for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); 1059 *prev = new; 1060 1061 return Success; 1062} 1063 1064int 1065KdAddPointer (KdPointerInfo *pi) 1066{ 1067 KdPointerInfo **prev; 1068 1069 if (!pi) 1070 return Success; 1071 1072 pi->mouseState = start; 1073 pi->eventHeld = FALSE; 1074 1075 pi->dixdev = AddInputDevice(KdPointerProc, TRUE); 1076 if (!pi->dixdev) { 1077 ErrorF("Couldn't add pointer device %s\n", 1078 pi->name ? pi->name : "(unnamed)"); 1079 return BadDevice; 1080 } 1081 1082 RegisterOtherDevice(pi->dixdev); 1083 1084 for (prev = &kdPointers; *prev; prev = &(*prev)->next); 1085 *prev = pi; 1086 1087 return Success; 1088} 1089 1090void 1091KdRemovePointer (KdPointerInfo *pi) 1092{ 1093 KdPointerInfo **prev; 1094 1095 if (!pi) 1096 return; 1097 1098 for (prev = &kdPointers; *prev; prev = &(*prev)->next) { 1099 if (*prev == pi) { 1100 *prev = pi->next; 1101 break; 1102 } 1103 } 1104 1105 KdFreePointer(pi); 1106} 1107 1108/* 1109 * You can call your kdriver server with something like: 1110 * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd 1111 * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br 1112 */ 1113static Bool 1114KdGetOptions (InputOption **options, char *string) 1115{ 1116 InputOption *newopt = NULL, **tmpo = NULL; 1117 int tam_key = 0; 1118 1119 newopt = (InputOption *) xalloc(sizeof (InputOption)); 1120 if (!newopt) 1121 return FALSE; 1122 1123 bzero(newopt, sizeof (InputOption)); 1124 1125 for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) 1126 ; /* Hello, I'm here */ 1127 *tmpo = newopt; 1128 1129 if (strchr(string, '=')) 1130 { 1131 tam_key = (strchr(string, '=') - string); 1132 newopt->key = (char *)xalloc(tam_key); 1133 strncpy(newopt->key, string, tam_key); 1134 newopt->key[tam_key] = '\0'; 1135 newopt->value = xstrdup(strchr(string, '=') + 1); 1136 } 1137 else 1138 { 1139 newopt->key = xstrdup(string); 1140 newopt->value = NULL; 1141 } 1142 newopt->next = NULL; 1143 1144 return TRUE; 1145} 1146 1147static void 1148KdParseKbdOptions (KdKeyboardInfo *ki) 1149{ 1150 InputOption *option = NULL; 1151 1152 for (option = ki->options; option; option = option->next) 1153 { 1154#ifdef XKB 1155 if (strcasecmp(option->key, "XkbRules") == 0) 1156 ki->xkbRules = option->value; 1157 else if (strcasecmp(option->key, "XkbModel") == 0) 1158 ki->xkbModel = option->value; 1159 else if (strcasecmp(option->key, "XkbLayout") == 0) 1160 ki->xkbLayout = option->value; 1161 else if (strcasecmp(option->key, "XkbVariant") == 0) 1162 ki->xkbVariant = option->value; 1163 else if (strcasecmp(option->key, "XkbOptions") == 0) 1164 ki->xkbOptions = option->value; 1165 else if (!strcasecmp (option->key, "device")) 1166 ki->path = KdSaveString(option->value); 1167 else 1168#endif 1169 ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", 1170 option->key, option->value); 1171 } 1172} 1173 1174KdKeyboardInfo * 1175KdParseKeyboard (char *arg) 1176{ 1177 char save[1024]; 1178 char delim; 1179 InputOption *options = NULL; 1180 KdKeyboardInfo *ki = NULL; 1181 1182 ki = KdNewKeyboard(); 1183 if (!ki) 1184 return NULL; 1185 1186 ki->name = strdup("Unknown KDrive Keyboard"); 1187 ki->path = NULL; 1188 ki->driver = NULL; 1189 ki->driverPrivate = NULL; 1190#ifdef XKB 1191 ki->xkb = NULL; 1192#endif 1193 ki->next = NULL; 1194 1195 if (!arg) 1196 { 1197 ErrorF("keybd: no arg\n"); 1198 KdFreeKeyboard (ki); 1199 return NULL; 1200 } 1201 1202 if (strlen (arg) >= sizeof (save)) 1203 { 1204 ErrorF("keybd: arg too long\n"); 1205 KdFreeKeyboard (ki); 1206 return NULL; 1207 } 1208 1209 arg = KdParseFindNext (arg, ",", save, &delim); 1210 if (!save[0]) 1211 { 1212 ErrorF("keybd: failed on save[0]\n"); 1213 KdFreeKeyboard (ki); 1214 return NULL; 1215 } 1216 1217 if (strcmp (save, "auto") == 0) 1218 ki->driverPrivate = NULL; 1219 else 1220 ki->driverPrivate = xstrdup(save); 1221 1222 if (delim != ',') 1223 { 1224 return ki; 1225 } 1226 1227 arg = KdParseFindNext (arg, ",", save, &delim); 1228 1229 while (delim == ',') 1230 { 1231 arg = KdParseFindNext (arg, ",", save, &delim); 1232 1233 if (!KdGetOptions(&options, save)) 1234 { 1235 KdFreeKeyboard(ki); 1236 return NULL; 1237 } 1238 } 1239 1240 if (options) 1241 { 1242 ki->options = options; 1243 KdParseKbdOptions(ki); 1244 } 1245 1246 return ki; 1247} 1248 1249static void 1250KdParsePointerOptions (KdPointerInfo *pi) 1251{ 1252 InputOption *option = NULL; 1253 1254 for (option = pi->options; option; option = option->next) 1255 { 1256 if (!strcmp (option->key, "emulatemiddle")) 1257 pi->emulateMiddleButton = TRUE; 1258 else if (!strcmp (option->key, "noemulatemiddle")) 1259 pi->emulateMiddleButton = FALSE; 1260 else if (!strcmp (option->key, "transformcoord")) 1261 pi->transformCoordinates = TRUE; 1262 else if (!strcmp (option->key, "rawcoord")) 1263 pi->transformCoordinates = FALSE; 1264 else if (!strcasecmp (option->key, "device")) 1265 pi->path = KdSaveString(option->value); 1266 else 1267 ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", 1268 option->key, option->value); 1269 } 1270} 1271 1272KdPointerInfo * 1273KdParsePointer (char *arg) 1274{ 1275 char save[1024]; 1276 char delim; 1277 KdPointerInfo *pi = NULL; 1278 InputOption *options = NULL; 1279 int i = 0; 1280 1281 pi = KdNewPointer(); 1282 if (!pi) 1283 return NULL; 1284 pi->emulateMiddleButton = kdEmulateMiddleButton; 1285 pi->transformCoordinates = !kdRawPointerCoordinates; 1286 pi->nButtons = 3; 1287 pi->inputClass = KD_MOUSE; 1288 1289 if (!arg) 1290 { 1291 ErrorF("mouse: no arg\n"); 1292 KdFreePointer (pi); 1293 return NULL; 1294 } 1295 1296 if (strlen (arg) >= sizeof (save)) 1297 { 1298 ErrorF("mouse: arg too long\n"); 1299 KdFreePointer (pi); 1300 return NULL; 1301 } 1302 arg = KdParseFindNext (arg, ",", save, &delim); 1303 if (!save[0]) 1304 { 1305 ErrorF("failed on save[0]\n"); 1306 KdFreePointer (pi); 1307 return NULL; 1308 } 1309 1310 if (strcmp(save, "auto") == 0) 1311 pi->driverPrivate = NULL; 1312 else 1313 pi->driverPrivate = xstrdup(save); 1314 1315 if (delim != ',') 1316 { 1317 return pi; 1318 } 1319 1320 arg = KdParseFindNext (arg, ",", save, &delim); 1321 1322 while (delim == ',') 1323 { 1324 arg = KdParseFindNext (arg, ",", save, &delim); 1325 if (save[0] == '{') 1326 { 1327 char *s = save + 1; 1328 i = 0; 1329 while (*s && *s != '}') 1330 { 1331 if ('1' <= *s && *s <= '0' + pi->nButtons) 1332 pi->map[i] = *s - '0'; 1333 else 1334 UseMsg (); 1335 s++; 1336 } 1337 } 1338 else 1339 { 1340 if (!KdGetOptions(&options, save)) 1341 { 1342 KdFreePointer(pi); 1343 return NULL; 1344 } 1345 } 1346 } 1347 1348 if (options) 1349 { 1350 pi->options = options; 1351 KdParsePointerOptions(pi); 1352 } 1353 1354 return pi; 1355} 1356 1357 1358void 1359KdInitInput (void) 1360{ 1361 KdPointerInfo *pi; 1362 KdKeyboardInfo *ki; 1363 struct KdConfigDevice *dev; 1364 1365 kdInputEnabled = TRUE; 1366 1367 for (dev = kdConfigPointers; dev; dev = dev->next) { 1368 pi = KdParsePointer(dev->line); 1369 if (!pi) 1370 ErrorF("Failed to parse pointer\n"); 1371 if (KdAddPointer(pi) != Success) 1372 ErrorF("Failed to add pointer!\n"); 1373 } 1374 for (dev = kdConfigKeyboards; dev; dev = dev->next) { 1375 ki = KdParseKeyboard(dev->line); 1376 if (!ki) 1377 ErrorF("Failed to parse keyboard\n"); 1378 if (KdAddKeyboard(ki) != Success) 1379 ErrorF("Failed to add keyboard!\n"); 1380 } 1381 1382 if (!kdEvents) 1383 kdEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); 1384 if (!kdEvents) 1385 FatalError("Couldn't allocate event buffer\n"); 1386 1387 mieqInit(); 1388} 1389 1390/* 1391 * Middle button emulation state machine 1392 * 1393 * Possible transitions: 1394 * Button 1 press v1 1395 * Button 1 release ^1 1396 * Button 2 press v2 1397 * Button 2 release ^2 1398 * Button 3 press v3 1399 * Button 3 release ^3 1400 * Button other press vo 1401 * Button other release ^o 1402 * Mouse motion <> 1403 * Keyboard event k 1404 * timeout ... 1405 * outside box <-> 1406 * 1407 * States: 1408 * start 1409 * button_1_pend 1410 * button_1_down 1411 * button_2_down 1412 * button_3_pend 1413 * button_3_down 1414 * synthetic_2_down_13 1415 * synthetic_2_down_3 1416 * synthetic_2_down_1 1417 * 1418 * Transition diagram 1419 * 1420 * start 1421 * v1 -> (hold) (settimeout) button_1_pend 1422 * ^1 -> (deliver) start 1423 * v2 -> (deliver) button_2_down 1424 * ^2 -> (deliever) start 1425 * v3 -> (hold) (settimeout) button_3_pend 1426 * ^3 -> (deliver) start 1427 * vo -> (deliver) start 1428 * ^o -> (deliver) start 1429 * <> -> (deliver) start 1430 * k -> (deliver) start 1431 * 1432 * button_1_pend (button 1 is down, timeout pending) 1433 * ^1 -> (release) (deliver) start 1434 * v2 -> (release) (deliver) button_1_down 1435 * ^2 -> (release) (deliver) button_1_down 1436 * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 1437 * ^3 -> (release) (deliver) button_1_down 1438 * vo -> (release) (deliver) button_1_down 1439 * ^o -> (release) (deliver) button_1_down 1440 * <-> -> (release) (deliver) button_1_down 1441 * <> -> (deliver) button_1_pend 1442 * k -> (release) (deliver) button_1_down 1443 * ... -> (release) button_1_down 1444 * 1445 * button_1_down (button 1 is down) 1446 * ^1 -> (deliver) start 1447 * v2 -> (deliver) button_1_down 1448 * ^2 -> (deliver) button_1_down 1449 * v3 -> (deliver) button_1_down 1450 * ^3 -> (deliver) button_1_down 1451 * vo -> (deliver) button_1_down 1452 * ^o -> (deliver) button_1_down 1453 * <> -> (deliver) button_1_down 1454 * k -> (deliver) button_1_down 1455 * 1456 * button_2_down (button 2 is down) 1457 * v1 -> (deliver) button_2_down 1458 * ^1 -> (deliver) button_2_down 1459 * ^2 -> (deliver) start 1460 * v3 -> (deliver) button_2_down 1461 * ^3 -> (deliver) button_2_down 1462 * vo -> (deliver) button_2_down 1463 * ^o -> (deliver) button_2_down 1464 * <> -> (deliver) button_2_down 1465 * k -> (deliver) button_2_down 1466 * 1467 * button_3_pend (button 3 is down, timeout pending) 1468 * v1 -> (generate v2) synthetic_2_down 1469 * ^1 -> (release) (deliver) button_3_down 1470 * v2 -> (release) (deliver) button_3_down 1471 * ^2 -> (release) (deliver) button_3_down 1472 * ^3 -> (release) (deliver) start 1473 * vo -> (release) (deliver) button_3_down 1474 * ^o -> (release) (deliver) button_3_down 1475 * <-> -> (release) (deliver) button_3_down 1476 * <> -> (deliver) button_3_pend 1477 * k -> (release) (deliver) button_3_down 1478 * ... -> (release) button_3_down 1479 * 1480 * button_3_down (button 3 is down) 1481 * v1 -> (deliver) button_3_down 1482 * ^1 -> (deliver) button_3_down 1483 * v2 -> (deliver) button_3_down 1484 * ^2 -> (deliver) button_3_down 1485 * ^3 -> (deliver) start 1486 * vo -> (deliver) button_3_down 1487 * ^o -> (deliver) button_3_down 1488 * <> -> (deliver) button_3_down 1489 * k -> (deliver) button_3_down 1490 * 1491 * synthetic_2_down_13 (button 1 and 3 are down) 1492 * ^1 -> (generate ^2) synthetic_2_down_3 1493 * v2 -> synthetic_2_down_13 1494 * ^2 -> synthetic_2_down_13 1495 * ^3 -> (generate ^2) synthetic_2_down_1 1496 * vo -> (deliver) synthetic_2_down_13 1497 * ^o -> (deliver) synthetic_2_down_13 1498 * <> -> (deliver) synthetic_2_down_13 1499 * k -> (deliver) synthetic_2_down_13 1500 * 1501 * synthetic_2_down_3 (button 3 is down) 1502 * v1 -> (deliver) synthetic_2_down_3 1503 * ^1 -> (deliver) synthetic_2_down_3 1504 * v2 -> synthetic_2_down_3 1505 * ^2 -> synthetic_2_down_3 1506 * ^3 -> start 1507 * vo -> (deliver) synthetic_2_down_3 1508 * ^o -> (deliver) synthetic_2_down_3 1509 * <> -> (deliver) synthetic_2_down_3 1510 * k -> (deliver) synthetic_2_down_3 1511 * 1512 * synthetic_2_down_1 (button 1 is down) 1513 * ^1 -> start 1514 * v2 -> synthetic_2_down_1 1515 * ^2 -> synthetic_2_down_1 1516 * v3 -> (deliver) synthetic_2_down_1 1517 * ^3 -> (deliver) synthetic_2_down_1 1518 * vo -> (deliver) synthetic_2_down_1 1519 * ^o -> (deliver) synthetic_2_down_1 1520 * <> -> (deliver) synthetic_2_down_1 1521 * k -> (deliver) synthetic_2_down_1 1522 */ 1523 1524typedef enum _inputClass { 1525 down_1, up_1, 1526 down_2, up_2, 1527 down_3, up_3, 1528 down_o, up_o, 1529 motion, outside_box, 1530 keyboard, timeout, 1531 num_input_class 1532} KdInputClass; 1533 1534typedef enum _inputAction { 1535 noop, 1536 hold, 1537 setto, 1538 deliver, 1539 release, 1540 clearto, 1541 gen_down_2, 1542 gen_up_2 1543} KdInputAction; 1544 1545#define MAX_ACTIONS 2 1546 1547typedef struct _inputTransition { 1548 KdInputAction actions[MAX_ACTIONS]; 1549 KdPointerState nextState; 1550} KdInputTransition; 1551 1552static const 1553KdInputTransition kdInputMachine[num_input_states][num_input_class] = { 1554 /* start */ 1555 { 1556 { { hold, setto }, button_1_pend }, /* v1 */ 1557 { { deliver, noop }, start }, /* ^1 */ 1558 { { deliver, noop }, button_2_down }, /* v2 */ 1559 { { deliver, noop }, start }, /* ^2 */ 1560 { { hold, setto }, button_3_pend }, /* v3 */ 1561 { { deliver, noop }, start }, /* ^3 */ 1562 { { deliver, noop }, start }, /* vo */ 1563 { { deliver, noop }, start }, /* ^o */ 1564 { { deliver, noop }, start }, /* <> */ 1565 { { deliver, noop }, start }, /* <-> */ 1566 { { noop, noop }, start }, /* k */ 1567 { { noop, noop }, start }, /* ... */ 1568 }, 1569 /* button_1_pend */ 1570 { 1571 { { noop, noop }, button_1_pend }, /* v1 */ 1572 { { release, deliver }, start }, /* ^1 */ 1573 { { release, deliver }, button_1_down }, /* v2 */ 1574 { { release, deliver }, button_1_down }, /* ^2 */ 1575 { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ 1576 { { release, deliver }, button_1_down }, /* ^3 */ 1577 { { release, deliver }, button_1_down }, /* vo */ 1578 { { release, deliver }, button_1_down }, /* ^o */ 1579 { { deliver, noop }, button_1_pend }, /* <> */ 1580 { { release, deliver }, button_1_down }, /* <-> */ 1581 { { noop, noop }, button_1_down }, /* k */ 1582 { { release, noop }, button_1_down }, /* ... */ 1583 }, 1584 /* button_1_down */ 1585 { 1586 { { noop, noop }, button_1_down }, /* v1 */ 1587 { { deliver, noop }, start }, /* ^1 */ 1588 { { deliver, noop }, button_1_down }, /* v2 */ 1589 { { deliver, noop }, button_1_down }, /* ^2 */ 1590 { { deliver, noop }, button_1_down }, /* v3 */ 1591 { { deliver, noop }, button_1_down }, /* ^3 */ 1592 { { deliver, noop }, button_1_down }, /* vo */ 1593 { { deliver, noop }, button_1_down }, /* ^o */ 1594 { { deliver, noop }, button_1_down }, /* <> */ 1595 { { deliver, noop }, button_1_down }, /* <-> */ 1596 { { noop, noop }, button_1_down }, /* k */ 1597 { { noop, noop }, button_1_down }, /* ... */ 1598 }, 1599 /* button_2_down */ 1600 { 1601 { { deliver, noop }, button_2_down }, /* v1 */ 1602 { { deliver, noop }, button_2_down }, /* ^1 */ 1603 { { noop, noop }, button_2_down }, /* v2 */ 1604 { { deliver, noop }, start }, /* ^2 */ 1605 { { deliver, noop }, button_2_down }, /* v3 */ 1606 { { deliver, noop }, button_2_down }, /* ^3 */ 1607 { { deliver, noop }, button_2_down }, /* vo */ 1608 { { deliver, noop }, button_2_down }, /* ^o */ 1609 { { deliver, noop }, button_2_down }, /* <> */ 1610 { { deliver, noop }, button_2_down }, /* <-> */ 1611 { { noop, noop }, button_2_down }, /* k */ 1612 { { noop, noop }, button_2_down }, /* ... */ 1613 }, 1614 /* button_3_pend */ 1615 { 1616 { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ 1617 { { release, deliver }, button_3_down }, /* ^1 */ 1618 { { release, deliver }, button_3_down }, /* v2 */ 1619 { { release, deliver }, button_3_down }, /* ^2 */ 1620 { { release, deliver }, button_3_down }, /* v3 */ 1621 { { release, deliver }, start }, /* ^3 */ 1622 { { release, deliver }, button_3_down }, /* vo */ 1623 { { release, deliver }, button_3_down }, /* ^o */ 1624 { { deliver, noop }, button_3_pend }, /* <> */ 1625 { { release, deliver }, button_3_down }, /* <-> */ 1626 { { release, noop }, button_3_down }, /* k */ 1627 { { release, noop }, button_3_down }, /* ... */ 1628 }, 1629 /* button_3_down */ 1630 { 1631 { { deliver, noop }, button_3_down }, /* v1 */ 1632 { { deliver, noop }, button_3_down }, /* ^1 */ 1633 { { deliver, noop }, button_3_down }, /* v2 */ 1634 { { deliver, noop }, button_3_down }, /* ^2 */ 1635 { { noop, noop }, button_3_down }, /* v3 */ 1636 { { deliver, noop }, start }, /* ^3 */ 1637 { { deliver, noop }, button_3_down }, /* vo */ 1638 { { deliver, noop }, button_3_down }, /* ^o */ 1639 { { deliver, noop }, button_3_down }, /* <> */ 1640 { { deliver, noop }, button_3_down }, /* <-> */ 1641 { { noop, noop }, button_3_down }, /* k */ 1642 { { noop, noop }, button_3_down }, /* ... */ 1643 }, 1644 /* synthetic_2_down_13 */ 1645 { 1646 { { noop, noop }, synth_2_down_13 }, /* v1 */ 1647 { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ 1648 { { noop, noop }, synth_2_down_13 }, /* v2 */ 1649 { { noop, noop }, synth_2_down_13 }, /* ^2 */ 1650 { { noop, noop }, synth_2_down_13 }, /* v3 */ 1651 { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ 1652 { { deliver, noop }, synth_2_down_13 }, /* vo */ 1653 { { deliver, noop }, synth_2_down_13 }, /* ^o */ 1654 { { deliver, noop }, synth_2_down_13 }, /* <> */ 1655 { { deliver, noop }, synth_2_down_13 }, /* <-> */ 1656 { { noop, noop }, synth_2_down_13 }, /* k */ 1657 { { noop, noop }, synth_2_down_13 }, /* ... */ 1658 }, 1659 /* synthetic_2_down_3 */ 1660 { 1661 { { deliver, noop }, synth_2_down_3 }, /* v1 */ 1662 { { deliver, noop }, synth_2_down_3 }, /* ^1 */ 1663 { { deliver, noop }, synth_2_down_3 }, /* v2 */ 1664 { { deliver, noop }, synth_2_down_3 }, /* ^2 */ 1665 { { noop, noop }, synth_2_down_3 }, /* v3 */ 1666 { { noop, noop }, start }, /* ^3 */ 1667 { { deliver, noop }, synth_2_down_3 }, /* vo */ 1668 { { deliver, noop }, synth_2_down_3 }, /* ^o */ 1669 { { deliver, noop }, synth_2_down_3 }, /* <> */ 1670 { { deliver, noop }, synth_2_down_3 }, /* <-> */ 1671 { { noop, noop }, synth_2_down_3 }, /* k */ 1672 { { noop, noop }, synth_2_down_3 }, /* ... */ 1673 }, 1674 /* synthetic_2_down_1 */ 1675 { 1676 { { noop, noop }, synth_2_down_1 }, /* v1 */ 1677 { { noop, noop }, start }, /* ^1 */ 1678 { { deliver, noop }, synth_2_down_1 }, /* v2 */ 1679 { { deliver, noop }, synth_2_down_1 }, /* ^2 */ 1680 { { deliver, noop }, synth_2_down_1 }, /* v3 */ 1681 { { deliver, noop }, synth_2_down_1 }, /* ^3 */ 1682 { { deliver, noop }, synth_2_down_1 }, /* vo */ 1683 { { deliver, noop }, synth_2_down_1 }, /* ^o */ 1684 { { deliver, noop }, synth_2_down_1 }, /* <> */ 1685 { { deliver, noop }, synth_2_down_1 }, /* <-> */ 1686 { { noop, noop }, synth_2_down_1 }, /* k */ 1687 { { noop, noop }, synth_2_down_1 }, /* ... */ 1688 }, 1689}; 1690 1691#define EMULATION_WINDOW 10 1692#define EMULATION_TIMEOUT 100 1693 1694static int 1695KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) 1696{ 1697 pi->emulationDx = pi->heldEvent.x - x; 1698 pi->emulationDy = pi->heldEvent.y - y; 1699 1700 return (abs (pi->emulationDx) < EMULATION_WINDOW && 1701 abs (pi->emulationDy) < EMULATION_WINDOW); 1702} 1703 1704static KdInputClass 1705KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) 1706{ 1707 switch (type) { 1708 case ButtonPress: 1709 switch (b) { 1710 case 1: return down_1; 1711 case 2: return down_2; 1712 case 3: return down_3; 1713 default: return down_o; 1714 } 1715 break; 1716 case ButtonRelease: 1717 switch (b) { 1718 case 1: return up_1; 1719 case 2: return up_2; 1720 case 3: return up_3; 1721 default: return up_o; 1722 } 1723 break; 1724 case MotionNotify: 1725 if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) 1726 return outside_box; 1727 else 1728 return motion; 1729 default: 1730 return keyboard; 1731 } 1732 return keyboard; 1733} 1734 1735#ifndef NDEBUG 1736char *kdStateNames[] = { 1737 "start", 1738 "button_1_pend", 1739 "button_1_down", 1740 "button_2_down", 1741 "button_3_pend", 1742 "button_3_down", 1743 "synth_2_down_13", 1744 "synth_2_down_3", 1745 "synthetic_2_down_1", 1746 "num_input_states" 1747}; 1748 1749char *kdClassNames[] = { 1750 "down_1", "up_1", 1751 "down_2", "up_2", 1752 "down_3", "up_3", 1753 "motion", "ouside_box", 1754 "keyboard", "timeout", 1755 "num_input_class" 1756}; 1757 1758char *kdActionNames[] = { 1759 "noop", 1760 "hold", 1761 "setto", 1762 "deliver", 1763 "release", 1764 "clearto", 1765 "gen_down_2", 1766 "gen_up_2", 1767}; 1768#endif 1769 1770static void 1771KdQueueEvent (DeviceIntPtr pDev, xEvent *ev) 1772{ 1773 KdAssertSigioBlocked ("KdQueueEvent"); 1774 mieqEnqueue (pDev, ev); 1775} 1776 1777/* We return true if we're stealing the event. */ 1778static Bool 1779KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, 1780 int z, int b, int absrel) 1781{ 1782 const KdInputTransition *t; 1783 int a; 1784 1785 c = KdClassifyInput(pi, type, x, y, z, b); 1786 t = &kdInputMachine[pi->mouseState][c]; 1787 for (a = 0; a < MAX_ACTIONS; a++) 1788 { 1789 switch (t->actions[a]) { 1790 case noop: 1791 break; 1792 case hold: 1793 pi->eventHeld = TRUE; 1794 pi->emulationDx = 0; 1795 pi->emulationDy = 0; 1796 pi->heldEvent.type = type; 1797 pi->heldEvent.x = x; 1798 pi->heldEvent.y = y; 1799 pi->heldEvent.z = z; 1800 pi->heldEvent.flags = b; 1801 pi->heldEvent.absrel = absrel; 1802 return TRUE; 1803 break; 1804 case setto: 1805 pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; 1806 pi->timeoutPending = TRUE; 1807 break; 1808 case deliver: 1809 _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, 1810 pi->heldEvent.y, pi->heldEvent.z, 1811 pi->heldEvent.flags, pi->heldEvent.absrel, 1812 TRUE); 1813 break; 1814 case release: 1815 pi->eventHeld = FALSE; 1816 pi->timeoutPending = FALSE; 1817 _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, 1818 pi->heldEvent.y, pi->heldEvent.z, 1819 pi->heldEvent.flags, pi->heldEvent.absrel, 1820 TRUE); 1821 return TRUE; 1822 break; 1823 case clearto: 1824 pi->timeoutPending = FALSE; 1825 break; 1826 case gen_down_2: 1827 _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, 1828 TRUE); 1829 pi->eventHeld = FALSE; 1830 return TRUE; 1831 break; 1832 case gen_up_2: 1833 _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, 1834 TRUE); 1835 return TRUE; 1836 break; 1837 } 1838 } 1839 pi->mouseState = t->nextState; 1840 return FALSE; 1841} 1842 1843static int 1844KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, 1845 int absrel) 1846{ 1847 if (pi->emulateMiddleButton) 1848 return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), 1849 type, x, y, z, b, absrel); 1850 return FALSE; 1851} 1852 1853static void 1854KdReceiveTimeout (KdPointerInfo *pi) 1855{ 1856 KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); 1857} 1858 1859#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10)) 1860#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT)) 1861#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b))) 1862#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b))) 1863 1864CARD32 KdSpecialKeys = 0; 1865 1866/* 1867 * kdCheckTermination 1868 * 1869 * This function checks for the key sequence that terminates the server. When 1870 * detected, it sets the dispatchException flag and returns. The key sequence 1871 * is: 1872 * Control-Alt 1873 * It's assumed that the server will be waken up by the caller when this 1874 * function returns. 1875 */ 1876 1877extern int nClients; 1878 1879static void 1880KdCheckSpecialKeys(KdKeyboardInfo *ki, int type, int sym) 1881{ 1882 if (!ki) 1883 return; 1884 1885 /* 1886 * Ignore key releases 1887 */ 1888 1889 if (type == KeyRelease) 1890 return; 1891 1892 /* Some iPaq keyboard -> mouse button mapping used to be here, but I 1893 * refuse to perpetuate this madness. -daniels */ 1894 1895 /* 1896 * Check for control/alt pressed 1897 */ 1898 if ((ki->dixdev->key->state & (ControlMask|Mod1Mask)) != 1899 (ControlMask|Mod1Mask)) 1900 return; 1901 1902 /* 1903 * Let OS function see keysym first 1904 */ 1905 1906 if (kdOsFuncs->SpecialKey) 1907 if ((*kdOsFuncs->SpecialKey) (sym)) 1908 return; 1909 1910 /* 1911 * Now check for backspace or delete; these signal the 1912 * X server to terminate 1913 * 1914 * I can't believe it's not XKB. -daniels 1915 */ 1916 switch (sym) { 1917 case XK_BackSpace: 1918 case XK_Delete: 1919 case XK_KP_Delete: 1920 /* 1921 * Set the dispatch exception flag so the server will terminate the 1922 * next time through the dispatch loop. 1923 */ 1924 if (kdDontZap == FALSE) 1925 dispatchException |= DE_TERMINATE; 1926 break; 1927 } 1928} 1929 1930/* 1931 * kdEnqueueKeyboardEvent 1932 * 1933 * This function converts hardware keyboard event information into an X event 1934 * and enqueues it using MI. It wakes up the server before returning so that 1935 * the event will be processed normally. 1936 * 1937 */ 1938 1939static void 1940KdHandleKeyboardEvent (KdKeyboardInfo *ki, int type, int key) 1941{ 1942 int byte; 1943 CARD8 bit; 1944 KdPointerInfo *pi; 1945 1946 byte = key >> 3; 1947 bit = 1 << (key & 7); 1948 1949 switch (type) { 1950 case KeyPress: 1951 ki->keyState[byte] |= bit; 1952 break; 1953 case KeyRelease: 1954 ki->keyState[byte] &= ~bit; 1955 break; 1956 } 1957 1958 for (pi = kdPointers; pi; pi = pi->next) 1959 KdRunMouseMachine (pi, keyboard, 0, 0, 0, 0, 0, 0); 1960} 1961 1962void 1963KdReleaseAllKeys (void) 1964{ 1965 int key, nEvents, i; 1966 KdKeyboardInfo *ki; 1967 1968 KdBlockSigio (); 1969 1970 for (ki = kdKeyboards; ki; ki = ki->next) { 1971 for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; 1972 key++) { 1973 if (IsKeyDown(ki, key)) { 1974 KdHandleKeyboardEvent(ki, KeyRelease, key); 1975 nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); 1976 for (i = 0; i < nEvents; i++) 1977 KdQueueEvent (ki->dixdev, kdEvents + i); 1978 } 1979 } 1980 } 1981 1982 KdUnblockSigio (); 1983} 1984 1985static void 1986KdCheckLock (void) 1987{ 1988 KeyClassPtr keyc = NULL; 1989 Bool isSet = FALSE, shouldBeSet = FALSE; 1990 KdKeyboardInfo *tmp = NULL; 1991 1992 for (tmp = kdKeyboards; tmp; tmp = tmp->next) { 1993 if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { 1994 keyc = tmp->dixdev->key; 1995 isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; 1996 shouldBeSet = (keyc->state & LockMask) != 0; 1997 if (isSet != shouldBeSet) 1998 KdSetLed (tmp, tmp->LockLed, shouldBeSet); 1999 } 2000 } 2001} 2002 2003void 2004KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, 2005 unsigned char scan_code, 2006 unsigned char is_up) 2007{ 2008 unsigned char key_code; 2009 KeyClassPtr keyc = NULL; 2010 KeybdCtrl *ctrl = NULL; 2011 int type, nEvents, i; 2012 2013 if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) 2014 return; 2015 2016 keyc = ki->dixdev->key; 2017 ctrl = &ki->dixdev->kbdfeed->ctrl; 2018 2019 if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) 2020 { 2021 key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; 2022 2023 /* 2024 * Set up this event -- the type may be modified below 2025 */ 2026 if (is_up) 2027 type = KeyRelease; 2028 else 2029 type = KeyPress; 2030 2031#ifdef XKB 2032 if (noXkbExtension) 2033#endif 2034 { 2035 KdCheckSpecialKeys(ki, type, key_code); 2036 KdHandleKeyboardEvent(ki, type, key_code); 2037 } 2038 2039 nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); 2040 for (i = 0; i < nEvents; i++) 2041 KdQueueEvent(ki->dixdev, kdEvents + i); 2042 } 2043 else { 2044 ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", 2045 ki->name, scan_code, ki->minScanCode, ki->maxScanCode); 2046 } 2047} 2048 2049/* 2050 * kdEnqueuePointerEvent 2051 * 2052 * This function converts hardware mouse event information into X event 2053 * information. A mouse movement event is passed off to MI to generate 2054 * a MotionNotify event, if appropriate. Button events are created and 2055 * passed off to MI for enqueueing. 2056 */ 2057 2058/* FIXME do something a little more clever to deal with multiple axes here */ 2059void 2060KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, 2061 int rz) 2062{ 2063 CARD32 ms; 2064 unsigned char buttons; 2065 int x, y, z; 2066 int (*matrix)[3] = kdPointerMatrix.matrix; 2067 unsigned long button; 2068 int n; 2069 int dixflags; 2070 2071 if (!pi) 2072 return; 2073 2074 ms = GetTimeInMillis(); 2075 2076 /* we don't need to transform z, so we don't. */ 2077 if (flags & KD_MOUSE_DELTA) { 2078 if (pi->transformCoordinates) { 2079 x = matrix[0][0] * rx + matrix[0][1] * ry; 2080 y = matrix[1][0] * rx + matrix[1][1] * ry; 2081 } 2082 else { 2083 x = rx; 2084 y = ry; 2085 } 2086 } 2087 else { 2088 if (pi->transformCoordinates) { 2089 x = matrix[0][0] * rx + matrix[0][1] * ry; 2090 y = matrix[1][0] * rx + matrix[1][1] * ry; 2091 } 2092 else { 2093 x = rx; 2094 y = ry; 2095 } 2096 } 2097 z = rz; 2098 2099 if (flags & KD_MOUSE_DELTA) 2100 dixflags = POINTER_RELATIVE & POINTER_ACCELERATE; 2101 else 2102 dixflags = POINTER_ABSOLUTE; 2103 2104 _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); 2105 2106 buttons = flags; 2107 2108 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 2109 button <<= 1, n++) { 2110 if (((pi->buttonState & button) ^ (buttons & button)) && 2111 !(buttons & button)) { 2112 _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, 2113 dixflags, FALSE); 2114 } 2115 } 2116 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 2117 button <<= 1, n++) { 2118 if (((pi->buttonState & button) ^ (buttons & button)) && 2119 (buttons & button)) { 2120 _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, 2121 dixflags, FALSE); 2122 } 2123 } 2124 2125 pi->buttonState = buttons; 2126} 2127 2128void 2129_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, 2130 int b, int absrel, Bool force) 2131{ 2132 int nEvents = 0, i = 0; 2133 int valuators[3] = { x, y, z }; 2134 2135 /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ 2136 if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) 2137 return; 2138 2139 nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, 0, 3, 2140 valuators); 2141 for (i = 0; i < nEvents; i++) 2142 KdQueueEvent(pi->dixdev, kdEvents + i); 2143} 2144 2145void 2146KdBlockHandler (int screen, 2147 pointer blockData, 2148 pointer timeout, 2149 pointer readmask) 2150{ 2151 KdPointerInfo *pi; 2152 int myTimeout=0; 2153 2154 for (pi = kdPointers; pi; pi = pi->next) 2155 { 2156 if (pi->timeoutPending) 2157 { 2158 int ms; 2159 2160 ms = pi->emulationTimeout - GetTimeInMillis (); 2161 if (ms < 1) 2162 ms = 1; 2163 if(ms<myTimeout || myTimeout==0) 2164 myTimeout=ms; 2165 } 2166 } 2167 /* if we need to poll for events, do that */ 2168 if(kdOsFuncs->pollEvents) 2169 { 2170 (*kdOsFuncs->pollEvents)(); 2171 myTimeout=20; 2172 } 2173 if(myTimeout>0) 2174 AdjustWaitForDelay (timeout, myTimeout); 2175} 2176 2177void 2178KdWakeupHandler (int screen, 2179 pointer data, 2180 unsigned long lresult, 2181 pointer readmask) 2182{ 2183 int result = (int) lresult; 2184 fd_set *pReadmask = (fd_set *) readmask; 2185 int i; 2186 KdPointerInfo *pi; 2187 2188 if (kdInputEnabled && result > 0) 2189 { 2190 for (i = 0; i < kdNumInputFds; i++) 2191 if (FD_ISSET (kdInputFds[i].fd, pReadmask)) 2192 { 2193 KdBlockSigio (); 2194 (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); 2195 KdUnblockSigio (); 2196 } 2197 } 2198 for (pi = kdPointers; pi; pi = pi->next) 2199 { 2200 if (pi->timeoutPending) 2201 { 2202 if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) 2203 { 2204 pi->timeoutPending = FALSE; 2205 KdBlockSigio (); 2206 KdReceiveTimeout (pi); 2207 KdUnblockSigio (); 2208 } 2209 } 2210 } 2211 if (kdSwitchPending) 2212 KdProcessSwitch (); 2213} 2214 2215#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) 2216 2217static Bool 2218KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 2219{ 2220 ScreenPtr pScreen = *ppScreen; 2221 ScreenPtr pNewScreen; 2222 int n; 2223 int dx, dy; 2224 int best_x, best_y; 2225 int n_best_x, n_best_y; 2226 CARD32 ms; 2227 2228 if (kdDisableZaphod || screenInfo.numScreens <= 1) 2229 return FALSE; 2230 2231 if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) 2232 return FALSE; 2233 2234 ms = GetTimeInMillis (); 2235 if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) 2236 return FALSE; 2237 kdOffScreen = TRUE; 2238 kdOffScreenTime = ms; 2239 n_best_x = -1; 2240 best_x = 32767; 2241 n_best_y = -1; 2242 best_y = 32767; 2243 for (n = 0; n < screenInfo.numScreens; n++) 2244 { 2245 pNewScreen = screenInfo.screens[n]; 2246 if (pNewScreen == pScreen) 2247 continue; 2248 dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; 2249 dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; 2250 if (*x < 0) 2251 { 2252 if (dx <= 0 && -dx < best_x) 2253 { 2254 best_x = -dx; 2255 n_best_x = n; 2256 } 2257 } 2258 else if (*x >= pScreen->width) 2259 { 2260 if (dx >= 0 && dx < best_x) 2261 { 2262 best_x = dx; 2263 n_best_x = n; 2264 } 2265 } 2266 if (*y < 0) 2267 { 2268 if (dy <= 0 && -dy < best_y) 2269 { 2270 best_y = -dy; 2271 n_best_y = n; 2272 } 2273 } 2274 else if (*y >= pScreen->height) 2275 { 2276 if (dy >= 0 && dy < best_y) 2277 { 2278 best_y = dy; 2279 n_best_y = n; 2280 } 2281 } 2282 } 2283 if (best_y < best_x) 2284 n_best_x = n_best_y; 2285 if (n_best_x == -1) 2286 return FALSE; 2287 pNewScreen = screenInfo.screens[n_best_x]; 2288 2289 if (*x < 0) 2290 *x += pNewScreen->width; 2291 if (*y < 0) 2292 *y += pNewScreen->height; 2293 2294 if (*x >= pScreen->width) 2295 *x -= pScreen->width; 2296 if (*y >= pScreen->height) 2297 *y -= pScreen->height; 2298 2299 *ppScreen = pNewScreen; 2300 return TRUE; 2301} 2302 2303static void 2304KdCrossScreen(ScreenPtr pScreen, Bool entering) 2305{ 2306#ifndef XIPAQ 2307 if (entering) 2308 KdEnableScreen (pScreen); 2309 else 2310 KdDisableScreen (pScreen); 2311#endif 2312} 2313 2314int KdCurScreen; /* current event screen */ 2315 2316static void 2317KdWarpCursor (ScreenPtr pScreen, int x, int y) 2318{ 2319 KdBlockSigio (); 2320 KdCurScreen = pScreen->myNum; 2321 miPointerWarpCursor (pScreen, x, y); 2322 KdUnblockSigio (); 2323} 2324 2325miPointerScreenFuncRec kdPointerScreenFuncs = 2326{ 2327 KdCursorOffScreen, 2328 KdCrossScreen, 2329 KdWarpCursor 2330}; 2331 2332void 2333ProcessInputEvents () 2334{ 2335 mieqProcessInputEvents(); 2336 miPointerUpdate(); 2337 if (kdSwitchPending) 2338 KdProcessSwitch (); 2339 KdCheckLock (); 2340} 2341 2342/* FIXME use XSECURITY to work out whether the client should be allowed to 2343 * open and close. */ 2344void 2345OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status) 2346{ 2347 if (!pDev) 2348 *status = BadDevice; 2349 else 2350 *status = Success; 2351} 2352 2353void 2354CloseInputDevice(DeviceIntPtr pDev, ClientPtr client) 2355{ 2356 return; 2357} 2358 2359/* We initialise all input devices at startup. */ 2360void 2361AddOtherInputDevices(void) 2362{ 2363 return; 2364} 2365 2366/* At the moment, absolute/relative is up to the client. */ 2367int 2368SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) 2369{ 2370 return BadMatch; 2371} 2372 2373int 2374SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, 2375 int *valuators, int first_valuator, int num_valuators) 2376{ 2377 return BadMatch; 2378} 2379 2380int 2381ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, 2382 xDeviceCtl *control) 2383{ 2384 switch (control->control) { 2385 case DEVICE_RESOLUTION: 2386 /* FIXME do something more intelligent here */ 2387 return BadMatch; 2388 2389 case DEVICE_ABS_CALIB: 2390 case DEVICE_ABS_AREA: 2391 return Success; 2392 2393 case DEVICE_CORE: 2394 case DEVICE_ENABLE: 2395 return Success; 2396 2397 default: 2398 return BadMatch; 2399 } 2400 2401 /* NOTREACHED */ 2402 return BadImplementation; 2403} 2404 2405int 2406NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) 2407{ 2408 InputOption *option = NULL; 2409 KdPointerInfo *pi = NULL; 2410 KdKeyboardInfo *ki = NULL; 2411 2412 for (option = options; option; option = option->next) { 2413 if (strcmp(option->key, "type") == 0) { 2414 if (strcmp(option->value, "pointer") == 0) { 2415 pi = KdNewPointer(); 2416 if (!pi) 2417 return BadAlloc; 2418 } 2419 else if (strcmp(option->value, "keyboard") == 0) { 2420 ki = KdNewKeyboard(); 2421 if (!ki) 2422 return BadAlloc; 2423 } 2424 else { 2425 ErrorF("unrecognised device type!\n"); 2426 return BadValue; 2427 } 2428 } 2429 } 2430 2431 if (!ki && !pi) { 2432 ErrorF("unrecognised device identifier!\n"); 2433 return BadValue; 2434 } 2435 2436 /* FIXME: change this code below to use KdParseKbdOptions and 2437 * KdParsePointerOptions */ 2438 for (option = options; option; option = option->next) { 2439 if (strcmp(option->key, "device") == 0) { 2440 if (pi && option->value) 2441 pi->path = KdSaveString(option->value); 2442 else if (ki && option->value) 2443 ki->path = KdSaveString(option->value); 2444 } 2445 else if (strcmp(option->key, "driver") == 0) { 2446 if (pi) { 2447 pi->driver = KdFindPointerDriver(option->value); 2448 if (!pi->driver) { 2449 ErrorF("couldn't find driver!\n"); 2450 KdFreePointer(pi); 2451 return BadValue; 2452 } 2453 pi->options = options; 2454 } 2455 else if (ki) { 2456 ki->driver = KdFindKeyboardDriver(option->value); 2457 if (!ki->driver) { 2458 ErrorF("couldn't find driver!\n"); 2459 KdFreeKeyboard(ki); 2460 return BadValue; 2461 } 2462 ki->options = options; 2463 } 2464 } 2465 } 2466 2467 if (pi) { 2468 if (KdAddPointer(pi) != Success || 2469 ActivateDevice(pi->dixdev) != Success || 2470 EnableDevice(pi->dixdev) != TRUE) { 2471 ErrorF("couldn't add or enable pointer\n"); 2472 return BadImplementation; 2473 } 2474 } 2475 else if (ki) { 2476 if (KdAddKeyboard(ki) != Success || 2477 ActivateDevice(ki->dixdev) != Success || 2478 EnableDevice(ki->dixdev) != TRUE) { 2479 ErrorF("couldn't add or enable keyboard\n"); 2480 return BadImplementation; 2481 } 2482 } 2483 2484 if (pi) { 2485 *pdev = pi->dixdev; 2486 } else if(ki) { 2487 *pdev = ki->dixdev; 2488 } 2489 2490 return Success; 2491} 2492 2493void 2494DeleteInputDeviceRequest(DeviceIntPtr pDev) 2495{ 2496 RemoveDevice(pDev); 2497} 2498