kinput.c revision 52397711
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 ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; 1025 ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; 1026 RegisterOtherDevice(ki->dixdev); 1027 1028#ifdef DEBUG 1029 ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); 1030#endif 1031 1032 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); 1033 *prev = ki; 1034 1035 return Success; 1036} 1037 1038void 1039KdRemoveKeyboard (KdKeyboardInfo *ki) 1040{ 1041 KdKeyboardInfo **prev; 1042 1043 if (!ki) 1044 return; 1045 1046 for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { 1047 if (*prev == ki) { 1048 *prev = ki->next; 1049 break; 1050 } 1051 } 1052 1053 KdFreeKeyboard(ki); 1054} 1055 1056int 1057KdAddConfigPointer (char *pointer) 1058{ 1059 struct KdConfigDevice **prev, *new; 1060 1061 if (!pointer) 1062 return Success; 1063 1064 new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); 1065 if (!new) 1066 return BadAlloc; 1067 1068 new->line = xstrdup(pointer); 1069 new->next = NULL; 1070 1071 for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); 1072 *prev = new; 1073 1074 return Success; 1075} 1076 1077int 1078KdAddPointer (KdPointerInfo *pi) 1079{ 1080 KdPointerInfo **prev; 1081 1082 if (!pi) 1083 return Success; 1084 1085 pi->mouseState = start; 1086 pi->eventHeld = FALSE; 1087 1088 pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE); 1089 if (!pi->dixdev) { 1090 ErrorF("Couldn't add pointer device %s\n", 1091 pi->name ? pi->name : "(unnamed)"); 1092 return BadDevice; 1093 } 1094 1095 pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab; 1096 pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab; 1097 RegisterOtherDevice(pi->dixdev); 1098 1099 for (prev = &kdPointers; *prev; prev = &(*prev)->next); 1100 *prev = pi; 1101 1102 return Success; 1103} 1104 1105void 1106KdRemovePointer (KdPointerInfo *pi) 1107{ 1108 KdPointerInfo **prev; 1109 1110 if (!pi) 1111 return; 1112 1113 for (prev = &kdPointers; *prev; prev = &(*prev)->next) { 1114 if (*prev == pi) { 1115 *prev = pi->next; 1116 break; 1117 } 1118 } 1119 1120 KdFreePointer(pi); 1121} 1122 1123/* 1124 * You can call your kdriver server with something like: 1125 * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd 1126 * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br 1127 */ 1128static Bool 1129KdGetOptions (InputOption **options, char *string) 1130{ 1131 InputOption *newopt = NULL, **tmpo = NULL; 1132 int tam_key = 0; 1133 1134 newopt = xcalloc(1, sizeof (InputOption)); 1135 if (!newopt) 1136 return FALSE; 1137 1138 for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) 1139 ; /* Hello, I'm here */ 1140 *tmpo = newopt; 1141 1142 if (strchr(string, '=')) 1143 { 1144 tam_key = (strchr(string, '=') - string); 1145 newopt->key = (char *)xalloc(tam_key); 1146 strncpy(newopt->key, string, tam_key); 1147 newopt->key[tam_key] = '\0'; 1148 newopt->value = xstrdup(strchr(string, '=') + 1); 1149 } 1150 else 1151 { 1152 newopt->key = xstrdup(string); 1153 newopt->value = NULL; 1154 } 1155 newopt->next = NULL; 1156 1157 return TRUE; 1158} 1159 1160static void 1161KdParseKbdOptions (KdKeyboardInfo *ki) 1162{ 1163 InputOption *option = NULL; 1164 1165 for (option = ki->options; option; option = option->next) 1166 { 1167#ifdef XKB 1168 if (strcasecmp(option->key, "XkbRules") == 0) 1169 ki->xkbRules = option->value; 1170 else if (strcasecmp(option->key, "XkbModel") == 0) 1171 ki->xkbModel = option->value; 1172 else if (strcasecmp(option->key, "XkbLayout") == 0) 1173 ki->xkbLayout = option->value; 1174 else if (strcasecmp(option->key, "XkbVariant") == 0) 1175 ki->xkbVariant = option->value; 1176 else if (strcasecmp(option->key, "XkbOptions") == 0) 1177 ki->xkbOptions = option->value; 1178 else if (!strcasecmp (option->key, "device")) 1179 ki->path = KdSaveString(option->value); 1180 else 1181#endif 1182 ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", 1183 option->key, option->value); 1184 } 1185} 1186 1187KdKeyboardInfo * 1188KdParseKeyboard (char *arg) 1189{ 1190 char save[1024]; 1191 char delim; 1192 InputOption *options = NULL; 1193 KdKeyboardInfo *ki = NULL; 1194 1195 ki = KdNewKeyboard(); 1196 if (!ki) 1197 return NULL; 1198 1199 ki->name = strdup("Unknown KDrive Keyboard"); 1200 ki->path = NULL; 1201 ki->driver = NULL; 1202 ki->driverPrivate = NULL; 1203#ifdef XKB 1204 ki->xkb = NULL; 1205#endif 1206 ki->next = NULL; 1207 1208 if (!arg) 1209 { 1210 ErrorF("keybd: no arg\n"); 1211 KdFreeKeyboard (ki); 1212 return NULL; 1213 } 1214 1215 if (strlen (arg) >= sizeof (save)) 1216 { 1217 ErrorF("keybd: arg too long\n"); 1218 KdFreeKeyboard (ki); 1219 return NULL; 1220 } 1221 1222 arg = KdParseFindNext (arg, ",", save, &delim); 1223 if (!save[0]) 1224 { 1225 ErrorF("keybd: failed on save[0]\n"); 1226 KdFreeKeyboard (ki); 1227 return NULL; 1228 } 1229 1230 if (strcmp (save, "auto") == 0) 1231 ki->driverPrivate = NULL; 1232 else 1233 ki->driverPrivate = xstrdup(save); 1234 1235 if (delim != ',') 1236 { 1237 return ki; 1238 } 1239 1240 arg = KdParseFindNext (arg, ",", save, &delim); 1241 1242 while (delim == ',') 1243 { 1244 arg = KdParseFindNext (arg, ",", save, &delim); 1245 1246 if (!KdGetOptions(&options, save)) 1247 { 1248 KdFreeKeyboard(ki); 1249 return NULL; 1250 } 1251 } 1252 1253 if (options) 1254 { 1255 ki->options = options; 1256 KdParseKbdOptions(ki); 1257 } 1258 1259 return ki; 1260} 1261 1262static void 1263KdParsePointerOptions (KdPointerInfo *pi) 1264{ 1265 InputOption *option = NULL; 1266 1267 for (option = pi->options; option; option = option->next) 1268 { 1269 if (!strcmp (option->key, "emulatemiddle")) 1270 pi->emulateMiddleButton = TRUE; 1271 else if (!strcmp (option->key, "noemulatemiddle")) 1272 pi->emulateMiddleButton = FALSE; 1273 else if (!strcmp (option->key, "transformcoord")) 1274 pi->transformCoordinates = TRUE; 1275 else if (!strcmp (option->key, "rawcoord")) 1276 pi->transformCoordinates = FALSE; 1277 else if (!strcasecmp (option->key, "device")) 1278 pi->path = KdSaveString(option->value); 1279 else 1280 ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", 1281 option->key, option->value); 1282 } 1283} 1284 1285KdPointerInfo * 1286KdParsePointer (char *arg) 1287{ 1288 char save[1024]; 1289 char delim; 1290 KdPointerInfo *pi = NULL; 1291 InputOption *options = NULL; 1292 int i = 0; 1293 1294 pi = KdNewPointer(); 1295 if (!pi) 1296 return NULL; 1297 pi->emulateMiddleButton = kdEmulateMiddleButton; 1298 pi->transformCoordinates = !kdRawPointerCoordinates; 1299 pi->nButtons = 5; /* XXX should not be hardcoded */ 1300 pi->inputClass = KD_MOUSE; 1301 1302 if (!arg) 1303 { 1304 ErrorF("mouse: no arg\n"); 1305 KdFreePointer (pi); 1306 return NULL; 1307 } 1308 1309 if (strlen (arg) >= sizeof (save)) 1310 { 1311 ErrorF("mouse: arg too long\n"); 1312 KdFreePointer (pi); 1313 return NULL; 1314 } 1315 arg = KdParseFindNext (arg, ",", save, &delim); 1316 if (!save[0]) 1317 { 1318 ErrorF("failed on save[0]\n"); 1319 KdFreePointer (pi); 1320 return NULL; 1321 } 1322 1323 if (strcmp(save, "auto") == 0) 1324 pi->driverPrivate = NULL; 1325 else 1326 pi->driverPrivate = xstrdup(save); 1327 1328 if (delim != ',') 1329 { 1330 return pi; 1331 } 1332 1333 arg = KdParseFindNext (arg, ",", save, &delim); 1334 1335 while (delim == ',') 1336 { 1337 arg = KdParseFindNext (arg, ",", save, &delim); 1338 if (save[0] == '{') 1339 { 1340 char *s = save + 1; 1341 i = 0; 1342 while (*s && *s != '}') 1343 { 1344 if ('1' <= *s && *s <= '0' + pi->nButtons) 1345 pi->map[i] = *s - '0'; 1346 else 1347 UseMsg (); 1348 s++; 1349 } 1350 } 1351 else 1352 { 1353 if (!KdGetOptions(&options, save)) 1354 { 1355 KdFreePointer(pi); 1356 return NULL; 1357 } 1358 } 1359 } 1360 1361 if (options) 1362 { 1363 pi->options = options; 1364 KdParsePointerOptions(pi); 1365 } 1366 1367 return pi; 1368} 1369 1370 1371void 1372KdInitInput (void) 1373{ 1374 KdPointerInfo *pi; 1375 KdKeyboardInfo *ki; 1376 struct KdConfigDevice *dev; 1377 1378 kdInputEnabled = TRUE; 1379 1380 for (dev = kdConfigPointers; dev; dev = dev->next) { 1381 pi = KdParsePointer(dev->line); 1382 if (!pi) 1383 ErrorF("Failed to parse pointer\n"); 1384 if (KdAddPointer(pi) != Success) 1385 ErrorF("Failed to add pointer!\n"); 1386 } 1387 for (dev = kdConfigKeyboards; dev; dev = dev->next) { 1388 ki = KdParseKeyboard(dev->line); 1389 if (!ki) 1390 ErrorF("Failed to parse keyboard\n"); 1391 if (KdAddKeyboard(ki) != Success) 1392 ErrorF("Failed to add keyboard!\n"); 1393 } 1394 1395 mieqInit(); 1396} 1397 1398/* 1399 * Middle button emulation state machine 1400 * 1401 * Possible transitions: 1402 * Button 1 press v1 1403 * Button 1 release ^1 1404 * Button 2 press v2 1405 * Button 2 release ^2 1406 * Button 3 press v3 1407 * Button 3 release ^3 1408 * Button other press vo 1409 * Button other release ^o 1410 * Mouse motion <> 1411 * Keyboard event k 1412 * timeout ... 1413 * outside box <-> 1414 * 1415 * States: 1416 * start 1417 * button_1_pend 1418 * button_1_down 1419 * button_2_down 1420 * button_3_pend 1421 * button_3_down 1422 * synthetic_2_down_13 1423 * synthetic_2_down_3 1424 * synthetic_2_down_1 1425 * 1426 * Transition diagram 1427 * 1428 * start 1429 * v1 -> (hold) (settimeout) button_1_pend 1430 * ^1 -> (deliver) start 1431 * v2 -> (deliver) button_2_down 1432 * ^2 -> (deliever) start 1433 * v3 -> (hold) (settimeout) button_3_pend 1434 * ^3 -> (deliver) start 1435 * vo -> (deliver) start 1436 * ^o -> (deliver) start 1437 * <> -> (deliver) start 1438 * k -> (deliver) start 1439 * 1440 * button_1_pend (button 1 is down, timeout pending) 1441 * ^1 -> (release) (deliver) start 1442 * v2 -> (release) (deliver) button_1_down 1443 * ^2 -> (release) (deliver) button_1_down 1444 * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 1445 * ^3 -> (release) (deliver) button_1_down 1446 * vo -> (release) (deliver) button_1_down 1447 * ^o -> (release) (deliver) button_1_down 1448 * <-> -> (release) (deliver) button_1_down 1449 * <> -> (deliver) button_1_pend 1450 * k -> (release) (deliver) button_1_down 1451 * ... -> (release) button_1_down 1452 * 1453 * button_1_down (button 1 is down) 1454 * ^1 -> (deliver) start 1455 * v2 -> (deliver) button_1_down 1456 * ^2 -> (deliver) button_1_down 1457 * v3 -> (deliver) button_1_down 1458 * ^3 -> (deliver) button_1_down 1459 * vo -> (deliver) button_1_down 1460 * ^o -> (deliver) button_1_down 1461 * <> -> (deliver) button_1_down 1462 * k -> (deliver) button_1_down 1463 * 1464 * button_2_down (button 2 is down) 1465 * v1 -> (deliver) button_2_down 1466 * ^1 -> (deliver) button_2_down 1467 * ^2 -> (deliver) start 1468 * v3 -> (deliver) button_2_down 1469 * ^3 -> (deliver) button_2_down 1470 * vo -> (deliver) button_2_down 1471 * ^o -> (deliver) button_2_down 1472 * <> -> (deliver) button_2_down 1473 * k -> (deliver) button_2_down 1474 * 1475 * button_3_pend (button 3 is down, timeout pending) 1476 * v1 -> (generate v2) synthetic_2_down 1477 * ^1 -> (release) (deliver) button_3_down 1478 * v2 -> (release) (deliver) button_3_down 1479 * ^2 -> (release) (deliver) button_3_down 1480 * ^3 -> (release) (deliver) start 1481 * vo -> (release) (deliver) button_3_down 1482 * ^o -> (release) (deliver) button_3_down 1483 * <-> -> (release) (deliver) button_3_down 1484 * <> -> (deliver) button_3_pend 1485 * k -> (release) (deliver) button_3_down 1486 * ... -> (release) button_3_down 1487 * 1488 * button_3_down (button 3 is down) 1489 * v1 -> (deliver) button_3_down 1490 * ^1 -> (deliver) button_3_down 1491 * v2 -> (deliver) button_3_down 1492 * ^2 -> (deliver) button_3_down 1493 * ^3 -> (deliver) start 1494 * vo -> (deliver) button_3_down 1495 * ^o -> (deliver) button_3_down 1496 * <> -> (deliver) button_3_down 1497 * k -> (deliver) button_3_down 1498 * 1499 * synthetic_2_down_13 (button 1 and 3 are down) 1500 * ^1 -> (generate ^2) synthetic_2_down_3 1501 * v2 -> synthetic_2_down_13 1502 * ^2 -> synthetic_2_down_13 1503 * ^3 -> (generate ^2) synthetic_2_down_1 1504 * vo -> (deliver) synthetic_2_down_13 1505 * ^o -> (deliver) synthetic_2_down_13 1506 * <> -> (deliver) synthetic_2_down_13 1507 * k -> (deliver) synthetic_2_down_13 1508 * 1509 * synthetic_2_down_3 (button 3 is down) 1510 * v1 -> (deliver) synthetic_2_down_3 1511 * ^1 -> (deliver) synthetic_2_down_3 1512 * v2 -> synthetic_2_down_3 1513 * ^2 -> synthetic_2_down_3 1514 * ^3 -> start 1515 * vo -> (deliver) synthetic_2_down_3 1516 * ^o -> (deliver) synthetic_2_down_3 1517 * <> -> (deliver) synthetic_2_down_3 1518 * k -> (deliver) synthetic_2_down_3 1519 * 1520 * synthetic_2_down_1 (button 1 is down) 1521 * ^1 -> start 1522 * v2 -> synthetic_2_down_1 1523 * ^2 -> synthetic_2_down_1 1524 * v3 -> (deliver) synthetic_2_down_1 1525 * ^3 -> (deliver) synthetic_2_down_1 1526 * vo -> (deliver) synthetic_2_down_1 1527 * ^o -> (deliver) synthetic_2_down_1 1528 * <> -> (deliver) synthetic_2_down_1 1529 * k -> (deliver) synthetic_2_down_1 1530 */ 1531 1532typedef enum _inputClass { 1533 down_1, up_1, 1534 down_2, up_2, 1535 down_3, up_3, 1536 down_o, up_o, 1537 motion, outside_box, 1538 keyboard, timeout, 1539 num_input_class 1540} KdInputClass; 1541 1542typedef enum _inputAction { 1543 noop, 1544 hold, 1545 setto, 1546 deliver, 1547 release, 1548 clearto, 1549 gen_down_2, 1550 gen_up_2 1551} KdInputAction; 1552 1553#define MAX_ACTIONS 2 1554 1555typedef struct _inputTransition { 1556 KdInputAction actions[MAX_ACTIONS]; 1557 KdPointerState nextState; 1558} KdInputTransition; 1559 1560static const 1561KdInputTransition kdInputMachine[num_input_states][num_input_class] = { 1562 /* start */ 1563 { 1564 { { hold, setto }, button_1_pend }, /* v1 */ 1565 { { deliver, noop }, start }, /* ^1 */ 1566 { { deliver, noop }, button_2_down }, /* v2 */ 1567 { { deliver, noop }, start }, /* ^2 */ 1568 { { hold, setto }, button_3_pend }, /* v3 */ 1569 { { deliver, noop }, start }, /* ^3 */ 1570 { { deliver, noop }, start }, /* vo */ 1571 { { deliver, noop }, start }, /* ^o */ 1572 { { deliver, noop }, start }, /* <> */ 1573 { { deliver, noop }, start }, /* <-> */ 1574 { { noop, noop }, start }, /* k */ 1575 { { noop, noop }, start }, /* ... */ 1576 }, 1577 /* button_1_pend */ 1578 { 1579 { { noop, noop }, button_1_pend }, /* v1 */ 1580 { { release, deliver }, start }, /* ^1 */ 1581 { { release, deliver }, button_1_down }, /* v2 */ 1582 { { release, deliver }, button_1_down }, /* ^2 */ 1583 { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ 1584 { { release, deliver }, button_1_down }, /* ^3 */ 1585 { { release, deliver }, button_1_down }, /* vo */ 1586 { { release, deliver }, button_1_down }, /* ^o */ 1587 { { deliver, noop }, button_1_pend }, /* <> */ 1588 { { release, deliver }, button_1_down }, /* <-> */ 1589 { { noop, noop }, button_1_down }, /* k */ 1590 { { release, noop }, button_1_down }, /* ... */ 1591 }, 1592 /* button_1_down */ 1593 { 1594 { { noop, noop }, button_1_down }, /* v1 */ 1595 { { deliver, noop }, start }, /* ^1 */ 1596 { { deliver, noop }, button_1_down }, /* v2 */ 1597 { { deliver, noop }, button_1_down }, /* ^2 */ 1598 { { deliver, noop }, button_1_down }, /* v3 */ 1599 { { deliver, noop }, button_1_down }, /* ^3 */ 1600 { { deliver, noop }, button_1_down }, /* vo */ 1601 { { deliver, noop }, button_1_down }, /* ^o */ 1602 { { deliver, noop }, button_1_down }, /* <> */ 1603 { { deliver, noop }, button_1_down }, /* <-> */ 1604 { { noop, noop }, button_1_down }, /* k */ 1605 { { noop, noop }, button_1_down }, /* ... */ 1606 }, 1607 /* button_2_down */ 1608 { 1609 { { deliver, noop }, button_2_down }, /* v1 */ 1610 { { deliver, noop }, button_2_down }, /* ^1 */ 1611 { { noop, noop }, button_2_down }, /* v2 */ 1612 { { deliver, noop }, start }, /* ^2 */ 1613 { { deliver, noop }, button_2_down }, /* v3 */ 1614 { { deliver, noop }, button_2_down }, /* ^3 */ 1615 { { deliver, noop }, button_2_down }, /* vo */ 1616 { { deliver, noop }, button_2_down }, /* ^o */ 1617 { { deliver, noop }, button_2_down }, /* <> */ 1618 { { deliver, noop }, button_2_down }, /* <-> */ 1619 { { noop, noop }, button_2_down }, /* k */ 1620 { { noop, noop }, button_2_down }, /* ... */ 1621 }, 1622 /* button_3_pend */ 1623 { 1624 { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ 1625 { { release, deliver }, button_3_down }, /* ^1 */ 1626 { { release, deliver }, button_3_down }, /* v2 */ 1627 { { release, deliver }, button_3_down }, /* ^2 */ 1628 { { release, deliver }, button_3_down }, /* v3 */ 1629 { { release, deliver }, start }, /* ^3 */ 1630 { { release, deliver }, button_3_down }, /* vo */ 1631 { { release, deliver }, button_3_down }, /* ^o */ 1632 { { deliver, noop }, button_3_pend }, /* <> */ 1633 { { release, deliver }, button_3_down }, /* <-> */ 1634 { { release, noop }, button_3_down }, /* k */ 1635 { { release, noop }, button_3_down }, /* ... */ 1636 }, 1637 /* button_3_down */ 1638 { 1639 { { deliver, noop }, button_3_down }, /* v1 */ 1640 { { deliver, noop }, button_3_down }, /* ^1 */ 1641 { { deliver, noop }, button_3_down }, /* v2 */ 1642 { { deliver, noop }, button_3_down }, /* ^2 */ 1643 { { noop, noop }, button_3_down }, /* v3 */ 1644 { { deliver, noop }, start }, /* ^3 */ 1645 { { deliver, noop }, button_3_down }, /* vo */ 1646 { { deliver, noop }, button_3_down }, /* ^o */ 1647 { { deliver, noop }, button_3_down }, /* <> */ 1648 { { deliver, noop }, button_3_down }, /* <-> */ 1649 { { noop, noop }, button_3_down }, /* k */ 1650 { { noop, noop }, button_3_down }, /* ... */ 1651 }, 1652 /* synthetic_2_down_13 */ 1653 { 1654 { { noop, noop }, synth_2_down_13 }, /* v1 */ 1655 { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ 1656 { { noop, noop }, synth_2_down_13 }, /* v2 */ 1657 { { noop, noop }, synth_2_down_13 }, /* ^2 */ 1658 { { noop, noop }, synth_2_down_13 }, /* v3 */ 1659 { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ 1660 { { deliver, noop }, synth_2_down_13 }, /* vo */ 1661 { { deliver, noop }, synth_2_down_13 }, /* ^o */ 1662 { { deliver, noop }, synth_2_down_13 }, /* <> */ 1663 { { deliver, noop }, synth_2_down_13 }, /* <-> */ 1664 { { noop, noop }, synth_2_down_13 }, /* k */ 1665 { { noop, noop }, synth_2_down_13 }, /* ... */ 1666 }, 1667 /* synthetic_2_down_3 */ 1668 { 1669 { { deliver, noop }, synth_2_down_3 }, /* v1 */ 1670 { { deliver, noop }, synth_2_down_3 }, /* ^1 */ 1671 { { deliver, noop }, synth_2_down_3 }, /* v2 */ 1672 { { deliver, noop }, synth_2_down_3 }, /* ^2 */ 1673 { { noop, noop }, synth_2_down_3 }, /* v3 */ 1674 { { noop, noop }, start }, /* ^3 */ 1675 { { deliver, noop }, synth_2_down_3 }, /* vo */ 1676 { { deliver, noop }, synth_2_down_3 }, /* ^o */ 1677 { { deliver, noop }, synth_2_down_3 }, /* <> */ 1678 { { deliver, noop }, synth_2_down_3 }, /* <-> */ 1679 { { noop, noop }, synth_2_down_3 }, /* k */ 1680 { { noop, noop }, synth_2_down_3 }, /* ... */ 1681 }, 1682 /* synthetic_2_down_1 */ 1683 { 1684 { { noop, noop }, synth_2_down_1 }, /* v1 */ 1685 { { noop, noop }, start }, /* ^1 */ 1686 { { deliver, noop }, synth_2_down_1 }, /* v2 */ 1687 { { deliver, noop }, synth_2_down_1 }, /* ^2 */ 1688 { { deliver, noop }, synth_2_down_1 }, /* v3 */ 1689 { { deliver, noop }, synth_2_down_1 }, /* ^3 */ 1690 { { deliver, noop }, synth_2_down_1 }, /* vo */ 1691 { { deliver, noop }, synth_2_down_1 }, /* ^o */ 1692 { { deliver, noop }, synth_2_down_1 }, /* <> */ 1693 { { deliver, noop }, synth_2_down_1 }, /* <-> */ 1694 { { noop, noop }, synth_2_down_1 }, /* k */ 1695 { { noop, noop }, synth_2_down_1 }, /* ... */ 1696 }, 1697}; 1698 1699#define EMULATION_WINDOW 10 1700#define EMULATION_TIMEOUT 100 1701 1702static int 1703KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) 1704{ 1705 pi->emulationDx = pi->heldEvent.x - x; 1706 pi->emulationDy = pi->heldEvent.y - y; 1707 1708 return (abs (pi->emulationDx) < EMULATION_WINDOW && 1709 abs (pi->emulationDy) < EMULATION_WINDOW); 1710} 1711 1712static KdInputClass 1713KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) 1714{ 1715 switch (type) { 1716 case ButtonPress: 1717 switch (b) { 1718 case 1: return down_1; 1719 case 2: return down_2; 1720 case 3: return down_3; 1721 default: return down_o; 1722 } 1723 break; 1724 case ButtonRelease: 1725 switch (b) { 1726 case 1: return up_1; 1727 case 2: return up_2; 1728 case 3: return up_3; 1729 default: return up_o; 1730 } 1731 break; 1732 case MotionNotify: 1733 if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) 1734 return outside_box; 1735 else 1736 return motion; 1737 default: 1738 return keyboard; 1739 } 1740 return keyboard; 1741} 1742 1743#ifdef DEBUG 1744char *kdStateNames[] = { 1745 "start", 1746 "button_1_pend", 1747 "button_1_down", 1748 "button_2_down", 1749 "button_3_pend", 1750 "button_3_down", 1751 "synth_2_down_13", 1752 "synth_2_down_3", 1753 "synthetic_2_down_1", 1754 "num_input_states" 1755}; 1756 1757char *kdClassNames[] = { 1758 "down_1", "up_1", 1759 "down_2", "up_2", 1760 "down_3", "up_3", 1761 "motion", "ouside_box", 1762 "keyboard", "timeout", 1763 "num_input_class" 1764}; 1765 1766char *kdActionNames[] = { 1767 "noop", 1768 "hold", 1769 "setto", 1770 "deliver", 1771 "release", 1772 "clearto", 1773 "gen_down_2", 1774 "gen_up_2", 1775}; 1776#endif /* DEBUG */ 1777 1778static void 1779KdQueueEvent (DeviceIntPtr pDev, xEvent *ev) 1780{ 1781 KdAssertSigioBlocked ("KdQueueEvent"); 1782 mieqEnqueue (pDev, ev); 1783} 1784 1785/* We return true if we're stealing the event. */ 1786static Bool 1787KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, 1788 int z, int b, int absrel) 1789{ 1790 const KdInputTransition *t; 1791 int a; 1792 1793 c = KdClassifyInput(pi, type, x, y, z, b); 1794 t = &kdInputMachine[pi->mouseState][c]; 1795 for (a = 0; a < MAX_ACTIONS; a++) 1796 { 1797 switch (t->actions[a]) { 1798 case noop: 1799 break; 1800 case hold: 1801 pi->eventHeld = TRUE; 1802 pi->emulationDx = 0; 1803 pi->emulationDy = 0; 1804 pi->heldEvent.type = type; 1805 pi->heldEvent.x = x; 1806 pi->heldEvent.y = y; 1807 pi->heldEvent.z = z; 1808 pi->heldEvent.flags = b; 1809 pi->heldEvent.absrel = absrel; 1810 return TRUE; 1811 break; 1812 case setto: 1813 pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; 1814 pi->timeoutPending = TRUE; 1815 break; 1816 case deliver: 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 break; 1822 case release: 1823 pi->eventHeld = FALSE; 1824 pi->timeoutPending = FALSE; 1825 _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, 1826 pi->heldEvent.y, pi->heldEvent.z, 1827 pi->heldEvent.flags, pi->heldEvent.absrel, 1828 TRUE); 1829 return TRUE; 1830 break; 1831 case clearto: 1832 pi->timeoutPending = FALSE; 1833 break; 1834 case gen_down_2: 1835 _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, 1836 TRUE); 1837 pi->eventHeld = FALSE; 1838 return TRUE; 1839 break; 1840 case gen_up_2: 1841 _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, 1842 TRUE); 1843 return TRUE; 1844 break; 1845 } 1846 } 1847 pi->mouseState = t->nextState; 1848 return FALSE; 1849} 1850 1851static int 1852KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, 1853 int absrel) 1854{ 1855 if (pi->emulateMiddleButton) 1856 return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), 1857 type, x, y, z, b, absrel); 1858 return FALSE; 1859} 1860 1861static void 1862KdReceiveTimeout (KdPointerInfo *pi) 1863{ 1864 KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); 1865} 1866 1867#define KILL_SEQUENCE ((1L << KK_CONTROL)|(1L << KK_ALT)|(1L << KK_F8)|(1L << KK_F10)) 1868#define SPECIAL_SEQUENCE ((1L << KK_CONTROL) | (1L << KK_ALT)) 1869#define SETKILLKEY(b) (KdSpecialKeys |= (1L << (b))) 1870#define CLEARKILLKEY(b) (KdSpecialKeys &= ~(1L << (b))) 1871 1872CARD32 KdSpecialKeys = 0; 1873 1874/* 1875 * kdCheckTermination 1876 * 1877 * This function checks for the key sequence that terminates the server. When 1878 * detected, it sets the dispatchException flag and returns. The key sequence 1879 * is: 1880 * Control-Alt 1881 * It's assumed that the server will be waken up by the caller when this 1882 * function returns. 1883 */ 1884 1885extern int nClients; 1886 1887static void 1888KdCheckSpecialKeys(KdKeyboardInfo *ki, int type, int sym) 1889{ 1890 if (!ki) 1891 return; 1892 1893 /* 1894 * Ignore key releases 1895 */ 1896 1897 if (type == KeyRelease) 1898 return; 1899 1900 /* Some iPaq keyboard -> mouse button mapping used to be here, but I 1901 * refuse to perpetuate this madness. -daniels */ 1902 1903 /* 1904 * Check for control/alt pressed 1905 */ 1906 if ((ki->dixdev->key->state & (ControlMask|Mod1Mask)) != 1907 (ControlMask|Mod1Mask)) 1908 return; 1909 1910 /* 1911 * Let OS function see keysym first 1912 */ 1913 1914 if (kdOsFuncs->SpecialKey) 1915 if ((*kdOsFuncs->SpecialKey) (sym)) 1916 return; 1917 1918 /* 1919 * Now check for backspace or delete; these signal the 1920 * X server to terminate 1921 * 1922 * I can't believe it's not XKB. -daniels 1923 */ 1924 switch (sym) { 1925 case XK_BackSpace: 1926 case XK_Delete: 1927 case XK_KP_Delete: 1928 /* 1929 * Set the dispatch exception flag so the server will terminate the 1930 * next time through the dispatch loop. 1931 */ 1932 if (kdAllowZap || party_like_its_1989) 1933 dispatchException |= DE_TERMINATE; 1934 break; 1935 } 1936} 1937 1938/* 1939 * kdEnqueueKeyboardEvent 1940 * 1941 * This function converts hardware keyboard event information into an X event 1942 * and enqueues it using MI. It wakes up the server before returning so that 1943 * the event will be processed normally. 1944 * 1945 */ 1946 1947static void 1948KdHandleKeyboardEvent (KdKeyboardInfo *ki, int type, int key) 1949{ 1950 int byte; 1951 CARD8 bit; 1952 KdPointerInfo *pi; 1953 1954 byte = key >> 3; 1955 bit = 1 << (key & 7); 1956 1957 switch (type) { 1958 case KeyPress: 1959 ki->keyState[byte] |= bit; 1960 break; 1961 case KeyRelease: 1962 ki->keyState[byte] &= ~bit; 1963 break; 1964 } 1965 1966 for (pi = kdPointers; pi; pi = pi->next) 1967 KdRunMouseMachine (pi, keyboard, 0, 0, 0, 0, 0, 0); 1968} 1969 1970void 1971KdReleaseAllKeys (void) 1972{ 1973 int key, nEvents, i; 1974 KdKeyboardInfo *ki; 1975 1976 KdBlockSigio (); 1977 1978 for (ki = kdKeyboards; ki; ki = ki->next) { 1979 for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; 1980 key++) { 1981 if (IsKeyDown(ki, key)) { 1982 KdHandleKeyboardEvent(ki, KeyRelease, key); 1983 GetEventList(&kdEvents); 1984 nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); 1985 for (i = 0; i < nEvents; i++) 1986 KdQueueEvent (ki->dixdev, (kdEvents + i)->event); 1987 } 1988 } 1989 } 1990 1991 KdUnblockSigio (); 1992} 1993 1994static void 1995KdCheckLock (void) 1996{ 1997 KeyClassPtr keyc = NULL; 1998 Bool isSet = FALSE, shouldBeSet = FALSE; 1999 KdKeyboardInfo *tmp = NULL; 2000 2001 for (tmp = kdKeyboards; tmp; tmp = tmp->next) { 2002 if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { 2003 keyc = tmp->dixdev->key; 2004 isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; 2005 shouldBeSet = (keyc->state & LockMask) != 0; 2006 if (isSet != shouldBeSet) 2007 KdSetLed (tmp, tmp->LockLed, shouldBeSet); 2008 } 2009 } 2010} 2011 2012void 2013KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, 2014 unsigned char scan_code, 2015 unsigned char is_up) 2016{ 2017 unsigned char key_code; 2018 KeyClassPtr keyc = NULL; 2019 KeybdCtrl *ctrl = NULL; 2020 int type, nEvents, i; 2021 2022 if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) 2023 return; 2024 2025 keyc = ki->dixdev->key; 2026 ctrl = &ki->dixdev->kbdfeed->ctrl; 2027 2028 if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) 2029 { 2030 key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; 2031 2032 /* 2033 * Set up this event -- the type may be modified below 2034 */ 2035 if (is_up) 2036 type = KeyRelease; 2037 else 2038 type = KeyPress; 2039 2040#ifdef XKB 2041 if (noXkbExtension) 2042#endif 2043 { 2044 KdCheckSpecialKeys(ki, type, key_code); 2045 KdHandleKeyboardEvent(ki, type, key_code); 2046 } 2047 2048 GetEventList(&kdEvents); 2049 nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); 2050 for (i = 0; i < nEvents; i++) 2051 KdQueueEvent(ki->dixdev, (kdEvents + i)->event); 2052 } 2053 else { 2054 ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", 2055 ki->name, scan_code, ki->minScanCode, ki->maxScanCode); 2056 } 2057} 2058 2059/* 2060 * kdEnqueuePointerEvent 2061 * 2062 * This function converts hardware mouse event information into X event 2063 * information. A mouse movement event is passed off to MI to generate 2064 * a MotionNotify event, if appropriate. Button events are created and 2065 * passed off to MI for enqueueing. 2066 */ 2067 2068/* FIXME do something a little more clever to deal with multiple axes here */ 2069void 2070KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, 2071 int rz) 2072{ 2073 CARD32 ms; 2074 unsigned char buttons; 2075 int x, y, z; 2076 int (*matrix)[3] = kdPointerMatrix.matrix; 2077 unsigned long button; 2078 int n; 2079 int dixflags = 0; 2080 2081 if (!pi) 2082 return; 2083 2084 ms = GetTimeInMillis(); 2085 2086 /* we don't need to transform z, so we don't. */ 2087 if (flags & KD_MOUSE_DELTA) { 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 else { 2098 if (pi->transformCoordinates) { 2099 x = matrix[0][0] * rx + matrix[0][1] * ry; 2100 y = matrix[1][0] * rx + matrix[1][1] * ry; 2101 } 2102 else { 2103 x = rx; 2104 y = ry; 2105 } 2106 } 2107 z = rz; 2108 2109 if (flags & KD_MOUSE_DELTA) 2110 { 2111 if (x || y || z) 2112 { 2113 dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; 2114 _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); 2115 } 2116 } else 2117 { 2118 dixflags = POINTER_ABSOLUTE; 2119 if (x != pi->dixdev->last.valuators[0] || 2120 y != pi->dixdev->last.valuators[1]) 2121 _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); 2122 } 2123 2124 buttons = flags; 2125 2126 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 2127 button <<= 1, n++) { 2128 if (((pi->buttonState & button) ^ (buttons & button)) && 2129 !(buttons & button)) { 2130 _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, 2131 dixflags, FALSE); 2132 } 2133 } 2134 for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; 2135 button <<= 1, n++) { 2136 if (((pi->buttonState & button) ^ (buttons & button)) && 2137 (buttons & button)) { 2138 _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, 2139 dixflags, FALSE); 2140 } 2141 } 2142 2143 pi->buttonState = buttons; 2144} 2145 2146void 2147_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, 2148 int b, int absrel, Bool force) 2149{ 2150 int nEvents = 0, i = 0; 2151 int valuators[3] = { x, y, z }; 2152 2153 /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ 2154 if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) 2155 return; 2156 2157 GetEventList(&kdEvents); 2158 nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, 2159 0, 3, valuators); 2160 for (i = 0; i < nEvents; i++) 2161 KdQueueEvent(pi->dixdev, (kdEvents + i)->event); 2162} 2163 2164void 2165KdBlockHandler (int screen, 2166 pointer blockData, 2167 pointer timeout, 2168 pointer readmask) 2169{ 2170 KdPointerInfo *pi; 2171 int myTimeout=0; 2172 2173 for (pi = kdPointers; pi; pi = pi->next) 2174 { 2175 if (pi->timeoutPending) 2176 { 2177 int ms; 2178 2179 ms = pi->emulationTimeout - GetTimeInMillis (); 2180 if (ms < 1) 2181 ms = 1; 2182 if(ms<myTimeout || myTimeout==0) 2183 myTimeout=ms; 2184 } 2185 } 2186 /* if we need to poll for events, do that */ 2187 if(kdOsFuncs->pollEvents) 2188 { 2189 (*kdOsFuncs->pollEvents)(); 2190 myTimeout=20; 2191 } 2192 if(myTimeout>0) 2193 AdjustWaitForDelay (timeout, myTimeout); 2194} 2195 2196void 2197KdWakeupHandler (int screen, 2198 pointer data, 2199 unsigned long lresult, 2200 pointer readmask) 2201{ 2202 int result = (int) lresult; 2203 fd_set *pReadmask = (fd_set *) readmask; 2204 int i; 2205 KdPointerInfo *pi; 2206 2207 if (kdInputEnabled && result > 0) 2208 { 2209 for (i = 0; i < kdNumInputFds; i++) 2210 if (FD_ISSET (kdInputFds[i].fd, pReadmask)) 2211 { 2212 KdBlockSigio (); 2213 (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); 2214 KdUnblockSigio (); 2215 } 2216 } 2217 for (pi = kdPointers; pi; pi = pi->next) 2218 { 2219 if (pi->timeoutPending) 2220 { 2221 if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) 2222 { 2223 pi->timeoutPending = FALSE; 2224 KdBlockSigio (); 2225 KdReceiveTimeout (pi); 2226 KdUnblockSigio (); 2227 } 2228 } 2229 } 2230 if (kdSwitchPending) 2231 KdProcessSwitch (); 2232} 2233 2234#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) 2235 2236static Bool 2237KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 2238{ 2239 ScreenPtr pScreen = *ppScreen; 2240 ScreenPtr pNewScreen; 2241 int n; 2242 int dx, dy; 2243 int best_x, best_y; 2244 int n_best_x, n_best_y; 2245 CARD32 ms; 2246 2247 if (kdDisableZaphod || screenInfo.numScreens <= 1) 2248 return FALSE; 2249 2250 if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) 2251 return FALSE; 2252 2253 ms = GetTimeInMillis (); 2254 if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) 2255 return FALSE; 2256 kdOffScreen = TRUE; 2257 kdOffScreenTime = ms; 2258 n_best_x = -1; 2259 best_x = 32767; 2260 n_best_y = -1; 2261 best_y = 32767; 2262 for (n = 0; n < screenInfo.numScreens; n++) 2263 { 2264 pNewScreen = screenInfo.screens[n]; 2265 if (pNewScreen == pScreen) 2266 continue; 2267 dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; 2268 dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; 2269 if (*x < 0) 2270 { 2271 if (dx <= 0 && -dx < best_x) 2272 { 2273 best_x = -dx; 2274 n_best_x = n; 2275 } 2276 } 2277 else if (*x >= pScreen->width) 2278 { 2279 if (dx >= 0 && dx < best_x) 2280 { 2281 best_x = dx; 2282 n_best_x = n; 2283 } 2284 } 2285 if (*y < 0) 2286 { 2287 if (dy <= 0 && -dy < best_y) 2288 { 2289 best_y = -dy; 2290 n_best_y = n; 2291 } 2292 } 2293 else if (*y >= pScreen->height) 2294 { 2295 if (dy >= 0 && dy < best_y) 2296 { 2297 best_y = dy; 2298 n_best_y = n; 2299 } 2300 } 2301 } 2302 if (best_y < best_x) 2303 n_best_x = n_best_y; 2304 if (n_best_x == -1) 2305 return FALSE; 2306 pNewScreen = screenInfo.screens[n_best_x]; 2307 2308 if (*x < 0) 2309 *x += pNewScreen->width; 2310 if (*y < 0) 2311 *y += pNewScreen->height; 2312 2313 if (*x >= pScreen->width) 2314 *x -= pScreen->width; 2315 if (*y >= pScreen->height) 2316 *y -= pScreen->height; 2317 2318 *ppScreen = pNewScreen; 2319 return TRUE; 2320} 2321 2322static void 2323KdCrossScreen(ScreenPtr pScreen, Bool entering) 2324{ 2325#ifndef XIPAQ 2326 if (entering) 2327 KdEnableScreen (pScreen); 2328 else 2329 KdDisableScreen (pScreen); 2330#endif 2331} 2332 2333int KdCurScreen; /* current event screen */ 2334 2335static void 2336KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) 2337{ 2338 KdBlockSigio (); 2339 KdCurScreen = pScreen->myNum; 2340 miPointerWarpCursor(pDev, pScreen, x, y); 2341 KdUnblockSigio (); 2342} 2343 2344miPointerScreenFuncRec kdPointerScreenFuncs = 2345{ 2346 KdCursorOffScreen, 2347 KdCrossScreen, 2348 KdWarpCursor 2349}; 2350 2351void 2352ProcessInputEvents () 2353{ 2354 mieqProcessInputEvents(); 2355 miPointerUpdateSprite(inputInfo.pointer); 2356 if (kdSwitchPending) 2357 KdProcessSwitch (); 2358 KdCheckLock (); 2359} 2360 2361/* FIXME use XSECURITY to work out whether the client should be allowed to 2362 * open and close. */ 2363void 2364OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status) 2365{ 2366 if (!pDev) 2367 *status = BadDevice; 2368 else 2369 *status = Success; 2370} 2371 2372void 2373CloseInputDevice(DeviceIntPtr pDev, ClientPtr client) 2374{ 2375 return; 2376} 2377 2378/* We initialise all input devices at startup. */ 2379void 2380AddOtherInputDevices(void) 2381{ 2382 return; 2383} 2384 2385/* At the moment, absolute/relative is up to the client. */ 2386int 2387SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) 2388{ 2389 return BadMatch; 2390} 2391 2392int 2393SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, 2394 int *valuators, int first_valuator, int num_valuators) 2395{ 2396 return BadMatch; 2397} 2398 2399int 2400ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, 2401 xDeviceCtl *control) 2402{ 2403 switch (control->control) { 2404 case DEVICE_RESOLUTION: 2405 /* FIXME do something more intelligent here */ 2406 return BadMatch; 2407 2408 case DEVICE_ABS_CALIB: 2409 case DEVICE_ABS_AREA: 2410 return Success; 2411 2412 case DEVICE_CORE: 2413 return BadMatch; 2414 case DEVICE_ENABLE: 2415 return Success; 2416 2417 default: 2418 return BadMatch; 2419 } 2420 2421 /* NOTREACHED */ 2422 return BadImplementation; 2423} 2424 2425int 2426NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) 2427{ 2428 InputOption *option = NULL; 2429 KdPointerInfo *pi = NULL; 2430 KdKeyboardInfo *ki = NULL; 2431 2432 for (option = options; option; option = option->next) { 2433 if (strcmp(option->key, "type") == 0) { 2434 if (strcmp(option->value, "pointer") == 0) { 2435 pi = KdNewPointer(); 2436 if (!pi) 2437 return BadAlloc; 2438 } 2439 else if (strcmp(option->value, "keyboard") == 0) { 2440 ki = KdNewKeyboard(); 2441 if (!ki) 2442 return BadAlloc; 2443 } 2444 else { 2445 ErrorF("unrecognised device type!\n"); 2446 return BadValue; 2447 } 2448 } 2449 } 2450 2451 if (!ki && !pi) { 2452 ErrorF("unrecognised device identifier!\n"); 2453 return BadValue; 2454 } 2455 2456 /* FIXME: change this code below to use KdParseKbdOptions and 2457 * KdParsePointerOptions */ 2458 for (option = options; option; option = option->next) { 2459 if (strcmp(option->key, "device") == 0) { 2460 if (pi && option->value) 2461 pi->path = KdSaveString(option->value); 2462 else if (ki && option->value) 2463 ki->path = KdSaveString(option->value); 2464 } 2465 else if (strcmp(option->key, "driver") == 0) { 2466 if (pi) { 2467 pi->driver = KdFindPointerDriver(option->value); 2468 if (!pi->driver) { 2469 ErrorF("couldn't find driver!\n"); 2470 KdFreePointer(pi); 2471 return BadValue; 2472 } 2473 pi->options = options; 2474 } 2475 else if (ki) { 2476 ki->driver = KdFindKeyboardDriver(option->value); 2477 if (!ki->driver) { 2478 ErrorF("couldn't find driver!\n"); 2479 KdFreeKeyboard(ki); 2480 return BadValue; 2481 } 2482 ki->options = options; 2483 } 2484 } 2485 } 2486 2487 if (pi) { 2488 if (KdAddPointer(pi) != Success || 2489 ActivateDevice(pi->dixdev) != Success || 2490 EnableDevice(pi->dixdev) != TRUE) { 2491 ErrorF("couldn't add or enable pointer\n"); 2492 return BadImplementation; 2493 } 2494 } 2495 else if (ki) { 2496 if (KdAddKeyboard(ki) != Success || 2497 ActivateDevice(ki->dixdev) != Success || 2498 EnableDevice(ki->dixdev) != TRUE) { 2499 ErrorF("couldn't add or enable keyboard\n"); 2500 return BadImplementation; 2501 } 2502 } 2503 2504 if (pi) { 2505 *pdev = pi->dixdev; 2506 } else if(ki) { 2507 *pdev = ki->dixdev; 2508 } 2509 2510 return Success; 2511} 2512 2513void 2514DeleteInputDeviceRequest(DeviceIntPtr pDev) 2515{ 2516 RemoveDevice(pDev); 2517} 2518