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