mouse.c revision 3e41e457
1/* 2 * 3 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. 4 * Copyright 1993 by David Dawes <dawes@xfree86.org> 5 * Copyright 2002 by SuSE Linux AG, Author: Egbert Eich 6 * Copyright 1994-2002 by The XFree86 Project, Inc. 7 * Copyright 2002 by Paul Elliott 8 * 9 * Permission to use, copy, modify, distribute, and sell this software and its 10 * documentation for any purpose is hereby granted without fee, provided that 11 * the above copyright notice appear in all copies and that both that 12 * copyright notice and this permission notice appear in supporting 13 * documentation, and that the names of copyright holders not be 14 * used in advertising or publicity pertaining to distribution of the 15 * software without specific, written prior permission. The copyright holders 16 * make no representations about the suitability of this 17 * software for any purpose. It is provided "as is" without express or 18 * implied warranty. 19 * 20 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 21 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 23 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 24 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 25 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 26 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 27 * 28 */ 29/* Patch for PS/2 Intellimouse - Tim Goodwin 1997-11-06. */ 30 31/* 32 * [JCH-96/01/21] Added fourth button support for PROT_GLIDEPOINT mouse 33 * protocol. 34 */ 35 36/* 37 * [TVO-97/03/05] Added microsoft IntelliMouse support 38 */ 39 40/* 41 * [PME-02/08/11] Added suport for drag lock buttons 42 * for use with 4 button trackballs for convenience 43 * and to help limited dexterity persons 44 */ 45 46#ifdef HAVE_CONFIG_H 47#include "config.h" 48#endif 49 50#include <xorg-server.h> 51#include <math.h> 52#include <string.h> 53#include <stdio.h> 54#include <stdlib.h> 55#include <X11/X.h> 56#include <X11/Xproto.h> 57 58#include "xf86.h" 59 60#include <X11/extensions/XI.h> 61#include <X11/extensions/XIproto.h> 62#include "extnsionst.h" 63#include "extinit.h" 64 65#include "xf86Xinput.h" 66#include "xf86_OSproc.h" 67#include "xf86OSmouse.h" 68 69#ifndef NEED_XF86_TYPES 70#define NEED_XF86_TYPES /* for xisb.h when !XFree86LOADER */ 71#endif 72 73#ifdef __NetBSD__ 74#include <time.h> 75#include <dev/wscons/wsconsio.h> 76#include <sys/ioctl.h> 77#endif 78 79#include "compiler.h" 80 81#include "xisb.h" 82#include "mouse.h" 83#include "mousePriv.h" 84#include "mipointer.h" 85 86enum { 87 /* number of bits in mapped nibble */ 88 NIB_BITS=4, 89 /* size of map of nibbles to bitmask */ 90 NIB_SIZE= (1 << NIB_BITS), 91 /* mask for map */ 92 NIB_MASK= (NIB_SIZE -1), 93 /* number of maps to map all the buttons */ 94 NIB_COUNT = ((MSE_MAXBUTTONS+NIB_BITS-1)/NIB_BITS) 95}; 96 97/*data to be used in implementing trackball drag locks.*/ 98typedef struct _DragLockRec { 99 100 /* Fields used to implement trackball drag locks. */ 101 /* mask for those buttons that are ordinary drag lock buttons */ 102 int lockButtonsM; 103 104 /* mask for the master drag lock button if any */ 105 int masterLockM; 106 107 /* button state up/down from last time adjusted for drag locks */ 108 int lockLastButtons; 109 110 /* 111 * true if master lock state i.e. master drag lock 112 * button has just been pressed 113 */ 114 int masterTS; 115 116 /* simulate these buttons being down although they are not */ 117 int simulatedDown; 118 119 /* 120 * data to map bits for drag lock buttons to corresponding 121 * bits for the target buttons 122 */ 123 int nib_table[NIB_COUNT][NIB_SIZE]; 124 125} DragLockRec, *DragLockPtr; 126 127 128static InputInfoPtr MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags); 129#if 0 130static void MouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags); 131#endif 132 133static int MouseProc(DeviceIntPtr device, int what); 134static Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0, 135 int v1, int v2, int v3, int v4, int v5, int *x, 136 int *y); 137 138static void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl); 139static void MousePostEvent(InputInfoPtr pInfo, int buttons, 140 int dx, int dy, int dz, int dw); 141static void MouseReadInput(InputInfoPtr pInfo); 142static void MouseBlockHandler(pointer data, struct timeval **waitTime, 143 pointer LastSelectMask); 144static void MouseWakeupHandler(pointer data, int i, pointer LastSelectMask); 145static void FlushButtons(MouseDevPtr pMse); 146 147static Bool SetupMouse(InputInfoPtr pInfo); 148static Bool initMouseHW(InputInfoPtr pInfo); 149#ifdef SUPPORT_MOUSE_RESET 150static Bool mouseReset(InputInfoPtr pInfo, unsigned char val); 151static void ps2WakeupHandler(pointer data, int i, pointer LastSelectMask); 152static void ps2BlockHandler(pointer data, struct timeval **waitTime, 153 pointer LastSelectMask); 154#endif 155 156/* mouse autoprobe stuff */ 157static const char *autoOSProtocol(InputInfoPtr pInfo, int *protoPara); 158static void autoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync); 159static void checkForErraticMovements(InputInfoPtr pInfo, int dx, int dy); 160static Bool collectData(MouseDevPtr pMse, unsigned char u); 161static void SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID); 162static Bool autoGood(MouseDevPtr pMse); 163 164#undef MOUSE 165_X_EXPORT InputDriverRec MOUSE = { 166 1, 167 "mouse", 168 NULL, 169 MousePreInit, 170 /*MouseUnInit,*/NULL, 171 NULL, 172 0 173}; 174 175#define RETRY_COUNT 4 176 177/* 178 * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc, 179 * ALPS GlidePoint, Thinking Mouse. 180 */ 181static const char *msDefaults[] = { 182 "BaudRate", "1200", 183 "DataBits", "7", 184 "StopBits", "1", 185 "Parity", "None", 186 "FlowControl", "None", 187 "VTime", "0", 188 "VMin", "1", 189 NULL 190}; 191/* MouseSystems */ 192static const char *mlDefaults[] = { 193 "BaudRate", "1200", 194 "DataBits", "8", 195 "StopBits", "2", 196 "Parity", "None", 197 "FlowControl", "None", 198 "VTime", "0", 199 "VMin", "1", 200 NULL 201}; 202/* MMSeries */ 203static const char *mmDefaults[] = { 204 "BaudRate", "1200", 205 "DataBits", "8", 206 "StopBits", "1", 207 "Parity", "Odd", 208 "FlowControl", "None", 209 "VTime", "0", 210 "VMin", "1", 211 NULL 212}; 213#if 0 214/* Logitech series 9 *//* same as msc: now mlDefaults */ 215static const char *logiDefaults[] = { 216 "BaudRate", "1200", 217 "DataBits", "8", 218 "StopBits", "2", 219 "Parity", "None", 220 "FlowControl", "None", 221 "VTime", "0", 222 "VMin", "1", 223 NULL 224}; 225#endif 226/* Hitachi Tablet */ 227static const char *mmhitDefaults[] = { 228 "BaudRate", "1200", 229 "DataBits", "8", 230 "StopBits", "1", 231 "Parity", "None", 232 "FlowControl", "None", 233 "VTime", "0", 234 "VMin", "1", 235 NULL 236}; 237/* AceCad Tablet */ 238static const char *acecadDefaults[] = { 239 "BaudRate", "9600", 240 "DataBits", "8", 241 "StopBits", "1", 242 "Parity", "Odd", 243 "FlowControl", "None", 244 "VTime", "0", 245 "VMin", "1", 246 NULL 247}; 248 249static MouseProtocolRec mouseProtocols[] = { 250 251 /* Serial protocols */ 252 { "Microsoft", MSE_SERIAL, msDefaults, PROT_MS }, 253 { "MouseSystems", MSE_SERIAL, mlDefaults, PROT_MSC }, 254 { "MMSeries", MSE_SERIAL, mmDefaults, PROT_MM }, 255 { "Logitech", MSE_SERIAL, mlDefaults, PROT_LOGI }, 256 { "MouseMan", MSE_SERIAL, msDefaults, PROT_LOGIMAN }, 257 { "MMHitTab", MSE_SERIAL, mmhitDefaults, PROT_MMHIT }, 258 { "GlidePoint", MSE_SERIAL, msDefaults, PROT_GLIDE }, 259 { "IntelliMouse", MSE_SERIAL, msDefaults, PROT_IMSERIAL }, 260 { "ThinkingMouse", MSE_SERIAL, msDefaults, PROT_THINKING }, 261 { "AceCad", MSE_SERIAL, acecadDefaults, PROT_ACECAD }, 262 { "ValuMouseScroll", MSE_SERIAL, msDefaults, PROT_VALUMOUSESCROLL }, 263 264 /* Standard PS/2 */ 265 { "PS/2", MSE_PS2, NULL, PROT_PS2 }, 266 { "GenericPS/2", MSE_PS2, NULL, PROT_GENPS2 }, 267 268 /* Extended PS/2 */ 269 { "ImPS/2", MSE_XPS2, NULL, PROT_IMPS2 }, 270 { "ExplorerPS/2", MSE_XPS2, NULL, PROT_EXPPS2 }, 271 { "ThinkingMousePS/2", MSE_XPS2, NULL, PROT_THINKPS2 }, 272 { "MouseManPlusPS/2", MSE_XPS2, NULL, PROT_MMPS2 }, 273 { "GlidePointPS/2", MSE_XPS2, NULL, PROT_GLIDEPS2 }, 274 { "NetMousePS/2", MSE_XPS2, NULL, PROT_NETPS2 }, 275 { "NetScrollPS/2", MSE_XPS2, NULL, PROT_NETSCPS2 }, 276 277 /* Bus Mouse */ 278 { "BusMouse", MSE_BUS, NULL, PROT_BM }, 279 280 /* Auto-detect (PnP) */ 281 { "Auto", MSE_AUTO, NULL, PROT_AUTO }, 282 283 /* Misc (usually OS-specific) */ 284 { "SysMouse", MSE_MISC, mlDefaults, PROT_SYSMOUSE }, 285 286 /* end of list */ 287 { NULL, MSE_NONE, NULL, PROT_UNKNOWN } 288}; 289 290/* Process options common to all mouse types. */ 291static void 292MouseCommonOptions(InputInfoPtr pInfo) 293{ 294 MouseDevPtr pMse; 295 MessageType buttons_from = X_CONFIG; 296 char *s; 297 int origButtons; 298 int i; 299 300 pMse = pInfo->private; 301 302 pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0); 303 if (!pMse->buttons) { 304 pMse->buttons = MSE_DFLTBUTTONS; 305 buttons_from = X_DEFAULT; 306 } 307 origButtons = pMse->buttons; 308 309 pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options, 310 "Emulate3Buttons", FALSE); 311 if (!xf86FindOptionValue(pInfo->options,"Emulate3Buttons")) { 312 pMse->emulate3ButtonsSoft = TRUE; 313 pMse->emulate3Buttons = TRUE; 314 } 315 316 pMse->emulate3Timeout = xf86SetIntOption(pInfo->options, 317 "Emulate3Timeout", 50); 318 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) { 319 MessageType from = X_CONFIG; 320 if (pMse->emulate3ButtonsSoft) 321 from = X_DEFAULT; 322 xf86Msg(from, "%s: Emulate3Buttons, Emulate3Timeout: %d\n", 323 pInfo->name, pMse->emulate3Timeout); 324 } 325 326 pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE); 327 if (pMse->chordMiddle) 328 xf86Msg(X_CONFIG, "%s: ChordMiddle\n", pInfo->name); 329 pMse->flipXY = xf86SetBoolOption(pInfo->options, "FlipXY", FALSE); 330 if (pMse->flipXY) 331 xf86Msg(X_CONFIG, "%s: FlipXY\n", pInfo->name); 332 if (xf86SetBoolOption(pInfo->options, "InvX", FALSE)) { 333 pMse->invX = -1; 334 xf86Msg(X_CONFIG, "%s: InvX\n", pInfo->name); 335 } else 336 pMse->invX = 1; 337 if (xf86SetBoolOption(pInfo->options, "InvY", FALSE)) { 338 pMse->invY = -1; 339 xf86Msg(X_CONFIG, "%s: InvY\n", pInfo->name); 340 } else 341 pMse->invY = 1; 342 pMse->angleOffset = xf86SetIntOption(pInfo->options, "AngleOffset", 0); 343 344 345 if (pMse->pDragLock) 346 xfree(pMse->pDragLock); 347 pMse->pDragLock = NULL; 348 349 s = xf86SetStrOption(pInfo->options, "DragLockButtons", NULL); 350 351 if (s) { 352 int lock; /* lock button */ 353 int target; /* target button */ 354 int lockM,targetM; /* bitmasks for drag lock, target */ 355 int i, j; /* indexes */ 356 char *s1; /* parse input string */ 357 DragLockPtr pLock; 358 359 pLock = pMse->pDragLock = xcalloc(1, sizeof(DragLockRec)); 360 /* init code */ 361 362 /* initial string to be taken apart */ 363 s1 = s; 364 365 /* keep getting numbers which are buttons */ 366 while ((s1 != NULL) && (lock = strtol(s1, &s1, 10)) != 0) { 367 368 /* check sanity for a button */ 369 if ((lock < 0) || (lock > MSE_MAXBUTTONS)) { 370 xf86Msg(X_WARNING, "DragLock: Invalid button number = %d\n", 371 lock); 372 break; 373 }; 374 /* turn into a button mask */ 375 lockM = 1 << (lock - 1); 376 377 /* try to get drag lock button */ 378 if ((s1 == NULL) || ((target=strtol(s1, &s1, 10)) == 0)) { 379 /*if no target, must be a master drag lock button */ 380 /* save master drag lock mask */ 381 pLock->masterLockM = lockM; 382 xf86Msg(X_CONFIG, 383 "DragLock button %d is master drag lock", 384 lock); 385 } else { 386 /* have target button number*/ 387 /* check target button number for sanity */ 388 if ((target < 0) || (target > MSE_MAXBUTTONS)) { 389 xf86Msg(X_WARNING, 390 "DragLock: Invalid button number for target=%d\n", 391 target); 392 break; 393 } 394 395 /* target button mask */ 396 targetM = 1 << (target - 1); 397 398 xf86Msg(X_CONFIG, 399 "DragLock: button %d is drag lock for button %d\n", 400 lock,target); 401 lock--; 402 403 /* initialize table that maps drag lock mask to target mask */ 404 pLock->nib_table[lock / NIB_BITS][1 << (lock % NIB_BITS)] = 405 targetM; 406 407 /* add new drag lock to mask of drag locks */ 408 pLock->lockButtonsM |= lockM; 409 } 410 411 } 412 413 /* 414 * fill out rest of map that maps sets of drag lock buttons 415 * to sets of target buttons, in the form of masks 416 */ 417 418 /* for each nibble */ 419 for (i = 0; i < NIB_COUNT; i++) { 420 /* for each possible set of bits for that nibble */ 421 for (j = 0; j < NIB_SIZE; j++) { 422 int ff, fM, otherbits; 423 424 /* get first bit set in j*/ 425 ff = ffs(j) - 1; 426 /* if 0 bits set nothing to do */ 427 if (ff >= 0) { 428 /* form mask for fist bit set */ 429 fM = 1 << ff; 430 /* mask off first bit set to get remaining bits set*/ 431 otherbits = j & ~fM; 432 /* 433 * if otherbits =0 then only 1 bit set 434 * so j=fM 435 * nib_table[i][fM] already calculated if fM has 436 * only 1 bit set. 437 * nib_table[i][j] has already been filled in 438 * by previous loop. otherwise 439 * otherbits < j so nibtable[i][otherbits] 440 * has already been calculated. 441 */ 442 if (otherbits) 443 pLock->nib_table[i][j] = 444 pLock->nib_table[i][fM] | 445 pLock->nib_table[i][otherbits]; 446 447 } 448 } 449 } 450 xfree(s); 451 } 452 453 s = xf86SetStrOption(pInfo->options, "ZAxisMapping", "4 5"); 454 if (s) { 455 int b1 = 0, b2 = 0, b3 = 0, b4 = 0; 456 char *msg = NULL; 457 458 pMse->negativeZ = pMse->positiveZ = MSE_NOAXISMAP; 459 pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP; 460 if (!xf86NameCmp(s, "x")) { 461 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX; 462 msg = xstrdup("X axis"); 463 } else if (!xf86NameCmp(s, "y")) { 464 pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY; 465 msg = xstrdup("Y axis"); 466 } else if (sscanf(s, "%d %d %d %d", &b1, &b2, &b3, &b4) >= 2 && 467 b1 > 0 && b1 <= MSE_MAXBUTTONS && 468 b2 > 0 && b2 <= MSE_MAXBUTTONS) { 469 msg = xstrdup("buttons XX and YY"); 470 if (msg) 471 sprintf(msg, "buttons %d and %d", b1, b2); 472 pMse->negativeZ = 1 << (b1-1); 473 pMse->positiveZ = 1 << (b2-1); 474 if (b3 > 0 && b3 <= MSE_MAXBUTTONS && 475 b4 > 0 && b4 <= MSE_MAXBUTTONS) { 476 if (msg) 477 xfree(msg); 478 msg = xstrdup("buttons XX, YY, ZZ and WW"); 479 if (msg) 480 sprintf(msg, "buttons %d, %d, %d and %d", b1, b2, b3, b4); 481 pMse->negativeW = 1 << (b3-1); 482 pMse->positiveW = 1 << (b4-1); 483 } 484 if (b1 > pMse->buttons) pMse->buttons = b1; 485 if (b2 > pMse->buttons) pMse->buttons = b2; 486 if (b3 > pMse->buttons) pMse->buttons = b3; 487 if (b4 > pMse->buttons) pMse->buttons = b4; 488 } 489 if (msg) { 490 xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg); 491 xfree(msg); 492 } else { 493 xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n", 494 pInfo->name, s); 495 } 496 xfree(s); 497 } 498 if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) { 499 Bool yFromConfig = FALSE; 500 int wheelButton; 501 502 pMse->emulateWheel = TRUE; 503 wheelButton = xf86SetIntOption(pInfo->options, 504 "EmulateWheelButton", 4); 505 if (wheelButton < 0 || wheelButton > MSE_MAXBUTTONS) { 506 xf86Msg(X_WARNING, "%s: Invalid EmulateWheelButton value: %d\n", 507 pInfo->name, wheelButton); 508 wheelButton = 4; 509 } 510 pMse->wheelButton = wheelButton; 511 512 pMse->wheelInertia = xf86SetIntOption(pInfo->options, 513 "EmulateWheelInertia", 10); 514 if (pMse->wheelInertia <= 0) { 515 xf86Msg(X_WARNING, "%s: Invalid EmulateWheelInertia value: %d\n", 516 pInfo->name, pMse->wheelInertia); 517 pMse->wheelInertia = 10; 518 } 519 pMse->wheelButtonTimeout = xf86SetIntOption(pInfo->options, 520 "EmulateWheelTimeout", 200); 521 if (pMse->wheelButtonTimeout <= 0) { 522 xf86Msg(X_WARNING, "%s: Invalid EmulateWheelTimeout value: %d\n", 523 pInfo->name, pMse->wheelButtonTimeout); 524 pMse->wheelButtonTimeout = 200; 525 } 526 527 pMse->negativeX = MSE_NOAXISMAP; 528 pMse->positiveX = MSE_NOAXISMAP; 529 s = xf86SetStrOption(pInfo->options, "XAxisMapping", NULL); 530 if (s) { 531 int b1 = 0, b2 = 0; 532 char *msg = NULL; 533 534 if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 535 b1 > 0 && b1 <= MSE_MAXBUTTONS && 536 b2 > 0 && b2 <= MSE_MAXBUTTONS) { 537 msg = xstrdup("buttons XX and YY"); 538 if (msg) 539 sprintf(msg, "buttons %d and %d", b1, b2); 540 pMse->negativeX = b1; 541 pMse->positiveX = b2; 542 if (b1 > pMse->buttons) pMse->buttons = b1; 543 if (b2 > pMse->buttons) pMse->buttons = b2; 544 } else { 545 xf86Msg(X_WARNING, "%s: Invalid XAxisMapping value: \"%s\"\n", 546 pInfo->name, s); 547 } 548 if (msg) { 549 xf86Msg(X_CONFIG, "%s: XAxisMapping: %s\n", pInfo->name, msg); 550 xfree(msg); 551 } 552 xfree(s); 553 } 554 s = xf86SetStrOption(pInfo->options, "YAxisMapping", NULL); 555 if (s) { 556 int b1 = 0, b2 = 0; 557 char *msg = NULL; 558 559 if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 560 b1 > 0 && b1 <= MSE_MAXBUTTONS && 561 b2 > 0 && b2 <= MSE_MAXBUTTONS) { 562 msg = xstrdup("buttons XX and YY"); 563 if (msg) 564 sprintf(msg, "buttons %d and %d", b1, b2); 565 pMse->negativeY = b1; 566 pMse->positiveY = b2; 567 if (b1 > pMse->buttons) pMse->buttons = b1; 568 if (b2 > pMse->buttons) pMse->buttons = b2; 569 yFromConfig = TRUE; 570 } else { 571 xf86Msg(X_WARNING, "%s: Invalid YAxisMapping value: \"%s\"\n", 572 pInfo->name, s); 573 } 574 if (msg) { 575 xf86Msg(X_CONFIG, "%s: YAxisMapping: %s\n", pInfo->name, msg); 576 xfree(msg); 577 } 578 xfree(s); 579 } 580 if (!yFromConfig) { 581 pMse->negativeY = 4; 582 pMse->positiveY = 5; 583 if (pMse->negativeY > pMse->buttons) 584 pMse->buttons = pMse->negativeY; 585 if (pMse->positiveY > pMse->buttons) 586 pMse->buttons = pMse->positiveY; 587 xf86Msg(X_DEFAULT, "%s: YAxisMapping: buttons %d and %d\n", 588 pInfo->name, pMse->negativeY, pMse->positiveY); 589 } 590 xf86Msg(X_CONFIG, "%s: EmulateWheel, EmulateWheelButton: %d, " 591 "EmulateWheelInertia: %d, " 592 "EmulateWheelTimeout: %d\n", 593 pInfo->name, wheelButton, pMse->wheelInertia, 594 pMse->wheelButtonTimeout); 595 } 596 s = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL); 597 if (s) { 598 int b, n = 0; 599 char *s1 = s; 600 /* keep getting numbers which are buttons */ 601 while (s1 && n < MSE_MAXBUTTONS && (b = strtol(s1, &s1, 10)) != 0) { 602 /* check sanity for a button */ 603 if (b < 0 || b > MSE_MAXBUTTONS) { 604 xf86Msg(X_WARNING, 605 "ButtonMapping: Invalid button number = %d\n", b); 606 break; 607 }; 608 pMse->buttonMap[n++] = 1 << (b-1); 609 if (b > pMse->buttons) pMse->buttons = b; 610 } 611 xfree(s); 612 } 613 /* get maximum of mapped buttons */ 614 for (i = pMse->buttons-1; i >= 0; i--) { 615 int f = ffs (pMse->buttonMap[i]); 616 if (f > pMse->buttons) 617 pMse->buttons = f; 618 } 619 if (origButtons != pMse->buttons) 620 buttons_from = X_CONFIG; 621 xf86Msg(buttons_from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons); 622 623 pMse->doubleClickSourceButtonMask = 0; 624 pMse->doubleClickTargetButtonMask = 0; 625 pMse->doubleClickTargetButton = 0; 626 s = xf86SetStrOption(pInfo->options, "DoubleClickButtons", NULL); 627 if (s) { 628 int b1 = 0, b2 = 0; 629 char *msg = NULL; 630 631 if ((sscanf(s, "%d %d", &b1, &b2) == 2) && 632 (b1 > 0) && (b1 <= MSE_MAXBUTTONS) && (b2 > 0) && (b2 <= MSE_MAXBUTTONS)) { 633 msg = xstrdup("buttons XX and YY"); 634 if (msg) 635 sprintf(msg, "buttons %d and %d", b1, b2); 636 pMse->doubleClickTargetButton = b1; 637 pMse->doubleClickTargetButtonMask = 1 << (b1 - 1); 638 pMse->doubleClickSourceButtonMask = 1 << (b2 - 1); 639 if (b1 > pMse->buttons) pMse->buttons = b1; 640 if (b2 > pMse->buttons) pMse->buttons = b2; 641 } else { 642 xf86Msg(X_WARNING, "%s: Invalid DoubleClickButtons value: \"%s\"\n", 643 pInfo->name, s); 644 } 645 if (msg) { 646 xf86Msg(X_CONFIG, "%s: DoubleClickButtons: %s\n", pInfo->name, msg); 647 xfree(msg); 648 } 649 xfree(s); 650 } 651} 652/* 653 * map bits corresponding to lock buttons. 654 * for each bit for a lock button, 655 * turn on bit corresponding to button button that the lock 656 * button services. 657 */ 658 659static int 660lock2targetMap(DragLockPtr pLock, int lockMask) 661{ 662 int result,i; 663 result = 0; 664 665 /* 666 * for each nibble group of bits, use 667 * map for that group to get corresponding 668 * bits, turn them on. 669 * if 4 or less buttons only first map will 670 * need to be used. 671 */ 672 for (i = 0; (i < NIB_COUNT) && lockMask; i++) { 673 result |= pLock->nib_table[i][lockMask& NIB_MASK]; 674 675 lockMask &= ~NIB_MASK; 676 lockMask >>= NIB_BITS; 677 } 678 return result; 679} 680 681static void 682MouseHWOptions(InputInfoPtr pInfo) 683{ 684 MouseDevPtr pMse = pInfo->private; 685 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 686 687 if (mPriv == NULL) 688 return; 689 690 if ((mPriv->soft 691 = xf86SetBoolOption(pInfo->options, "AutoSoft", FALSE))) { 692 xf86Msg(X_CONFIG, "Don't initialize mouse when auto-probing\n"); 693 } 694 pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0); 695 if (pMse->sampleRate) { 696 xf86Msg(X_CONFIG, "%s: SampleRate: %d\n", pInfo->name, 697 pMse->sampleRate); 698 } 699 pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0); 700 if (pMse->resolution) { 701 xf86Msg(X_CONFIG, "%s: Resolution: %d\n", pInfo->name, 702 pMse->resolution); 703 } 704 705 if ((mPriv->sensitivity 706 = xf86SetRealOption(pInfo->options, "Sensitivity", 1.0))) { 707 xf86Msg(X_CONFIG, "%s: Sensitivity: %g\n", pInfo->name, 708 mPriv->sensitivity); 709 } 710} 711 712static void 713MouseSerialOptions(InputInfoPtr pInfo) 714{ 715 MouseDevPtr pMse = pInfo->private; 716 Bool clearDTR, clearRTS; 717 718 719 pMse->baudRate = xf86SetIntOption(pInfo->options, "BaudRate", 0); 720 if (pMse->baudRate) { 721 xf86Msg(X_CONFIG, "%s: BaudRate: %d\n", pInfo->name, 722 pMse->baudRate); 723 } 724 725 if ((clearDTR = xf86SetBoolOption(pInfo->options, "ClearDTR",FALSE))) 726 pMse->mouseFlags |= MF_CLEAR_DTR; 727 728 729 if ((clearRTS = xf86SetBoolOption(pInfo->options, "ClearRTS",FALSE))) 730 pMse->mouseFlags |= MF_CLEAR_RTS; 731 732 if (clearDTR || clearRTS) { 733 xf86Msg(X_CONFIG, "%s: ", pInfo->name); 734 if (clearDTR) { 735 xf86ErrorF("ClearDTR"); 736 if (clearRTS) 737 xf86ErrorF(", "); 738 } 739 if (clearRTS) { 740 xf86ErrorF("ClearRTS"); 741 } 742 xf86ErrorF("\n"); 743 } 744} 745 746static MouseProtocolID 747ProtocolNameToID(const char *name) 748{ 749 int i; 750 751 for (i = 0; mouseProtocols[i].name; i++) 752 if (xf86NameCmp(name, mouseProtocols[i].name) == 0) 753 return mouseProtocols[i].id; 754 return PROT_UNKNOWN; 755} 756 757static const char * 758ProtocolIDToName(MouseProtocolID id) 759{ 760 int i; 761 762 switch (id) { 763 case PROT_UNKNOWN: 764 return "Unknown"; 765 break; 766 case PROT_UNSUP: 767 return "Unsupported"; 768 break; 769 default: 770 for (i = 0; mouseProtocols[i].name; i++) 771 if (id == mouseProtocols[i].id) 772 return mouseProtocols[i].name; 773 return "Invalid"; 774 } 775} 776 777static int 778ProtocolIDToClass(MouseProtocolID id) 779{ 780 int i; 781 782 switch (id) { 783 case PROT_UNKNOWN: 784 case PROT_UNSUP: 785 return MSE_NONE; 786 break; 787 default: 788 for (i = 0; mouseProtocols[i].name; i++) 789 if (id == mouseProtocols[i].id) 790 return mouseProtocols[i].class; 791 return MSE_NONE; 792 } 793} 794 795static MouseProtocolPtr 796GetProtocol(MouseProtocolID id) { 797 int i; 798 799 switch (id) { 800 case PROT_UNKNOWN: 801 case PROT_UNSUP: 802 return NULL; 803 break; 804 default: 805 for (i = 0; mouseProtocols[i].name; i++) 806 if (id == mouseProtocols[i].id) { 807 return &mouseProtocols[i]; 808 } 809 return NULL; 810 } 811} 812 813static OSMouseInfoPtr osInfo = NULL; 814 815static Bool 816InitProtocols(void) 817{ 818 int classes; 819 int i; 820 const char *osname = NULL; 821 822 if (osInfo) 823 return TRUE; 824 825 osInfo = xf86OSMouseInit(0); 826 if (!osInfo) 827 return FALSE; 828 if (!osInfo->SupportedInterfaces) 829 return FALSE; 830 831 classes = osInfo->SupportedInterfaces(); 832 if (!classes) 833 return FALSE; 834 835 /* Mark unsupported interface classes. */ 836 for (i = 0; mouseProtocols[i].name; i++) 837 if (!(mouseProtocols[i].class & classes)) 838 mouseProtocols[i].id = PROT_UNSUP; 839 840 for (i = 0; mouseProtocols[i].name; i++) 841 if (mouseProtocols[i].class & MSE_MISC) 842 if (!osInfo->CheckProtocol || 843 !osInfo->CheckProtocol(mouseProtocols[i].name)) 844 mouseProtocols[i].id = PROT_UNSUP; 845 846 /* NetBSD uses PROT_BM for "PS/2". */ 847 xf86GetOS(&osname, NULL, NULL, NULL); 848 if (osname && xf86NameCmp(osname, "netbsd") == 0) 849 for (i = 0; mouseProtocols[i].name; i++) 850 if (mouseProtocols[i].id == PROT_PS2) 851 mouseProtocols[i].id = PROT_BM; 852 853 return TRUE; 854} 855 856static InputInfoPtr 857MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags) 858{ 859 InputInfoPtr pInfo; 860 MouseDevPtr pMse; 861 mousePrivPtr mPriv; 862 MessageType protocolFrom = X_DEFAULT, deviceFrom = X_CONFIG; 863 const char *protocol, *osProt = NULL; 864 const char *device; 865 MouseProtocolID protocolID; 866 MouseProtocolPtr pProto; 867 Bool detected; 868 int i; 869 870 if (!InitProtocols()) 871 return NULL; 872 873 if (!(pInfo = xf86AllocateInput(drv, 0))) 874 return NULL; 875 876 /* Initialise the InputInfoRec. */ 877 pInfo->name = dev->identifier; 878 pInfo->type_name = XI_MOUSE; 879 pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS; 880 pInfo->device_control = MouseProc; 881 pInfo->read_input = MouseReadInput; 882#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 883 pInfo->motion_history_proc = xf86GetMotionEvents; 884 pInfo->history_size = 0; 885#endif 886 pInfo->control_proc = NULL; 887 pInfo->close_proc = NULL; 888 pInfo->switch_mode = NULL; 889 pInfo->conversion_proc = MouseConvert; 890 pInfo->reverse_conversion_proc = NULL; 891 pInfo->fd = -1; 892 pInfo->dev = NULL; 893 pInfo->private_flags = 0; 894 pInfo->always_core_feedback = NULL; 895 pInfo->conf_idev = dev; 896 897 /* Check if SendDragEvents has been disabled. */ 898 if (!xf86SetBoolOption(dev->commonOptions, "SendDragEvents", TRUE)) { 899 pInfo->flags &= ~XI86_SEND_DRAG_EVENTS; 900 } 901 902 /* Allocate the MouseDevRec and initialise it. */ 903 /* 904 * XXX This should be done by a function in the core server since the 905 * MouseDevRec is defined in the os-support layer. 906 */ 907 if (!(pMse = xcalloc(sizeof(MouseDevRec), 1))) 908 return pInfo; 909 pInfo->private = pMse; 910 pMse->Ctrl = MouseCtrl; 911 pMse->PostEvent = MousePostEvent; 912 pMse->CommonOptions = MouseCommonOptions; 913 914 /* Find the protocol type. */ 915 protocol = xf86SetStrOption(dev->commonOptions, "Protocol", NULL); 916 if (protocol) { 917 protocolFrom = X_CONFIG; 918 } else if (osInfo->DefaultProtocol) { 919 protocol = osInfo->DefaultProtocol(); 920 protocolFrom = X_DEFAULT; 921 } 922 if (!protocol) { 923 xf86Msg(X_ERROR, "%s: No Protocol specified\n", pInfo->name); 924 return pInfo; 925 } 926 927 /* Default Mapping: 1 2 3 8 9 10 11 ... */ 928 for (i = 0; i < MSE_MAXBUTTONS; i++) 929 pMse->buttonMap[i] = 1 << (i > 2 && i < MSE_MAXBUTTONS-4 ? i+4 : i); 930 931 protocolID = ProtocolNameToID(protocol); 932 do { 933 detected = TRUE; 934 switch (protocolID) { 935 case PROT_AUTO: 936 if (osInfo->SetupAuto) { 937 if ((osProt = osInfo->SetupAuto(pInfo,NULL))) { 938 MouseProtocolID id = ProtocolNameToID(osProt); 939 if (id == PROT_UNKNOWN || id == PROT_UNSUP) { 940 protocolID = id; 941 protocol = osProt; 942 detected = FALSE; 943 } 944 } 945 } 946 break; 947 case PROT_UNKNOWN: 948 /* Check for a builtin OS-specific protocol, 949 * and call its PreInit. */ 950 if (osInfo->CheckProtocol 951 && osInfo->CheckProtocol(protocol)) { 952 if (!xf86CheckStrOption(dev->commonOptions, "Device", NULL) && 953 osInfo->FindDevice) { 954 xf86Msg(X_WARNING, "%s: No Device specified, " 955 "looking for one...\n", pInfo->name); 956 if (!osInfo->FindDevice(pInfo, protocol, 0)) { 957 xf86Msg(X_ERROR, "%s: Cannot find which device " 958 "to use.\n", pInfo->name); 959 } else 960 deviceFrom = X_PROBED; 961 } 962 if (osInfo->PreInit) { 963 osInfo->PreInit(pInfo, protocol, 0); 964 } 965 return pInfo; 966 } 967 xf86Msg(X_ERROR, "%s: Unknown protocol \"%s\"\n", 968 pInfo->name, protocol); 969 return pInfo; 970 break; 971 case PROT_UNSUP: 972 xf86Msg(X_ERROR, 973 "%s: Protocol \"%s\" is not supported on this " 974 "platform\n", pInfo->name, protocol); 975 return pInfo; 976 break; 977 default: 978 break; 979 980 } 981 } while (!detected); 982 983 if (!xf86CheckStrOption(dev->commonOptions, "Device", NULL) && 984 osInfo->FindDevice) { 985 xf86Msg(X_WARNING, "%s: No Device specified, looking for one...\n", 986 pInfo->name); 987 if (!osInfo->FindDevice(pInfo, protocol, 0)) { 988 xf86Msg(X_ERROR, "%s: Cannot find which device to use.\n", 989 pInfo->name); 990 } else { 991 deviceFrom = X_PROBED; 992 xf86MarkOptionUsedByName(dev->commonOptions, "Device"); 993 } 994 } 995 996 device = xf86CheckStrOption(dev->commonOptions, "Device", NULL); 997 if (device) 998 xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device); 999 1000 xf86Msg(protocolFrom, "%s: Protocol: \"%s\"\n", pInfo->name, protocol); 1001 if (!(pProto = GetProtocol(protocolID))) 1002 return pInfo; 1003 1004 pMse->protocolID = protocolID; 1005 pMse->oldProtocolID = protocolID; /* hack */ 1006 1007 pMse->autoProbe = FALSE; 1008 /* Collect the options, and process the common options. */ 1009 xf86CollectInputOptions(pInfo, pProto->defaults, NULL); 1010 xf86ProcessCommonOptions(pInfo, pInfo->options); 1011 1012 /* Check if the device can be opened. */ 1013 pInfo->fd = xf86OpenSerial(pInfo->options); 1014 if (pInfo->fd == -1) { 1015 if (xf86GetAllowMouseOpenFail()) 1016 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 1017 else { 1018 xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); 1019 if (pMse->mousePriv) 1020 xfree(pMse->mousePriv); 1021 xfree(pMse); 1022 pInfo->private = NULL; 1023 return pInfo; 1024 } 1025 } 1026 xf86CloseSerial(pInfo->fd); 1027 pInfo->fd = -1; 1028 1029 if (!(mPriv = (pointer) xcalloc(sizeof(mousePrivRec), 1))) 1030 return pInfo; 1031 pMse->mousePriv = mPriv; 1032 pMse->CommonOptions(pInfo); 1033 pMse->checkMovements = checkForErraticMovements; 1034 pMse->autoProbeMouse = autoProbeMouse; 1035 pMse->collectData = collectData; 1036 pMse->dataGood = autoGood; 1037 1038 MouseHWOptions(pInfo); 1039 MouseSerialOptions(pInfo); 1040 1041 pInfo->flags |= XI86_CONFIGURED; 1042 return pInfo; 1043} 1044 1045 1046static void 1047MouseReadInput(InputInfoPtr pInfo) 1048{ 1049 MouseDevPtr pMse; 1050 int j, buttons, dx, dy, dz, dw, baddata; 1051 int pBufP; 1052 int c; 1053 unsigned char *pBuf, u; 1054 1055 1056 pMse = pInfo->private; 1057 pBufP = pMse->protoBufTail; 1058 pBuf = pMse->protoBuf; 1059 1060 if (pInfo->fd == -1) 1061 return; 1062 1063 /* 1064 * Set blocking to -1 on the first call because we know there is data to 1065 * read. Xisb automatically clears it after one successful read so that 1066 * succeeding reads are preceeded by a select with a 0 timeout to prevent 1067 * read from blocking indefinitely. 1068 */ 1069 XisbBlockDuration(pMse->buffer, -1); 1070 1071 while ((c = XisbRead(pMse->buffer)) >= 0) { 1072 u = (unsigned char)c; 1073 1074#if defined (EXTMOUSEDEBUG) || defined (MOUSEDATADEBUG) 1075 ErrorF("mouse byte: %2.2x\n",u); 1076#endif 1077 1078 /* if we do autoprobing collect the data */ 1079 if (pMse->collectData && pMse->autoProbe) 1080 if (pMse->collectData(pMse,u)) 1081 continue; 1082 1083#ifdef SUPPORT_MOUSE_RESET 1084 if (mouseReset(pInfo,u)) { 1085 pBufP = 0; 1086 continue; 1087 } 1088#endif 1089 if (pBufP >= pMse->protoPara[4]) { 1090 /* 1091 * Buffer contains a full packet, which has already been processed: 1092 * Empty the buffer and check for optional 4th byte, which will be 1093 * processed directly, without being put into the buffer first. 1094 */ 1095 pBufP = 0; 1096 if ((u & pMse->protoPara[0]) != pMse->protoPara[1] && 1097 (u & pMse->protoPara[5]) == pMse->protoPara[6]) { 1098 /* 1099 * Hack for Logitech MouseMan Mouse - Middle button 1100 * 1101 * Unfortunately this mouse has variable length packets: the 1102 * standard Microsoft 3 byte packet plus an optional 4th byte 1103 * whenever the middle button status changes. 1104 * 1105 * We have already processed the standard packet with the 1106 * movement and button info. Now post an event message with 1107 * the old status of the left and right buttons and the 1108 * updated middle button. 1109 */ 1110 /* 1111 * Even worse, different MouseMen and TrackMen differ in the 1112 * 4th byte: some will send 0x00/0x20, others 0x01/0x21, or 1113 * even 0x02/0x22, so I have to strip off the lower bits. 1114 * [CHRIS-211092] 1115 * 1116 * [JCH-96/01/21] 1117 * HACK for ALPS "fourth button". (It's bit 0x10 of the 1118 * "fourth byte" and it is activated by tapping the glidepad 1119 * with the finger! 8^) We map it to bit bit3, and the 1120 * reverse map in xf86Events just has to be extended so that 1121 * it is identified as Button 4. The lower half of the 1122 * reverse-map may remain unchanged. 1123 */ 1124 /* 1125 * [KAZU-030897] 1126 * Receive the fourth byte only when preceeding three bytes 1127 * have been detected (pBufP >= pMse->protoPara[4]). In the 1128 * previous versions, the test was pBufP == 0; we may have 1129 * mistakingly received a byte even if we didn't see anything 1130 * preceeding the byte. 1131 */ 1132#ifdef EXTMOUSEDEBUG 1133 ErrorF("mouse 4th byte %02x\n",u); 1134#endif 1135 dx = dy = dz = dw = 0; 1136 buttons = 0; 1137 switch (pMse->protocolID) { 1138 1139 /* 1140 * [KAZU-221197] 1141 * IntelliMouse, NetMouse (including NetMouse Pro) and Mie 1142 * Mouse always send the fourth byte, whereas the fourth byte 1143 * is optional for GlidePoint and ThinkingMouse. The fourth 1144 * byte is also optional for MouseMan+ and FirstMouse+ in 1145 * their native mode. It is always sent if they are in the 1146 * IntelliMouse compatible mode. 1147 */ 1148 case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, 1149 MouseMan+ */ 1150 dz = (u & 0x08) ? 1151 (u & 0x0f) - 16 : (u & 0x0f); 1152 if ((dz >= 7) || (dz <= -7)) 1153 dz = 0; 1154 buttons |= ((int)(u & 0x10) >> 3) 1155 | ((int)(u & 0x20) >> 2) 1156 | (pMse->lastButtons & 0x05); 1157 break; 1158 1159 case PROT_GLIDE: 1160 case PROT_THINKING: 1161 buttons |= ((int)(u & 0x10) >> 1); 1162 /* fall through */ 1163 1164 default: 1165 buttons |= ((int)(u & 0x20) >> 4) | 1166 (pMse->lastButtons & 0x05); 1167 break; 1168 } 1169 goto post_event; 1170 } 1171 } 1172 /* End of packet buffer flush and 4th byte hack. */ 1173 1174 /* 1175 * Append next byte to buffer (which is empty or contains an 1176 * incomplete packet); iterate if packet (still) not complete. 1177 */ 1178 pBuf[pBufP++] = u; 1179 if (pBufP != pMse->protoPara[4]) continue; 1180#ifdef EXTMOUSEDEBUG2 1181 { 1182 int i; 1183 ErrorF("received %d bytes",pBufP); 1184 for ( i=0; i < pBufP; i++) 1185 ErrorF(" %02x",pBuf[i]); 1186 ErrorF("\n"); 1187 } 1188#endif 1189 1190 /* 1191 * Hack for resyncing: We check here for a package that is: 1192 * a) illegal (detected by wrong data-package header) 1193 * b) invalid (0x80 == -128 and that might be wrong for MouseSystems) 1194 * c) bad header-package 1195 * 1196 * NOTE: b) is a violation of the MouseSystems-Protocol, since values 1197 * of -128 are allowed, but since they are very seldom we can 1198 * easily use them as package-header with no button pressed. 1199 * NOTE/2: On a PS/2 mouse any byte is valid as a data byte. 1200 * Furthermore, 0x80 is not valid as a header byte. For a PS/2 1201 * mouse we skip checking data bytes. For resyncing a PS/2 1202 * mouse we require the two most significant bits in the header 1203 * byte to be 0. These are the overflow bits, and in case of 1204 * an overflow we actually lose sync. Overflows are very rare, 1205 * however, and we quickly gain sync again after an overflow 1206 * condition. This is the best we can do. (Actually, we could 1207 * use bit 0x08 in the header byte for resyncing, since that 1208 * bit is supposed to be always on, but nobody told Microsoft...) 1209 */ 1210 1211 /* 1212 * [KAZU,OYVIND-120398] 1213 * The above hack is wrong! Because of b) above, we shall see 1214 * erroneous mouse events so often when the MouseSystem mouse is 1215 * moved quickly. As for the PS/2 and its variants, we don't need 1216 * to treat them as special cases, because protoPara[2] and 1217 * protoPara[3] are both 0x00 for them, thus, any data bytes will 1218 * never be discarded. 0x80 is rejected for MMSeries, Logitech 1219 * and MMHittab protocols, because protoPara[2] and protoPara[3] 1220 * are 0x80 and 0x00 respectively. The other protocols are 7-bit 1221 * protocols; there is no use checking 0x80. 1222 * 1223 * All in all we should check the condition a) only. 1224 */ 1225 1226 /* 1227 * [OYVIND-120498] 1228 * Check packet for valid data: 1229 * If driver is in sync with datastream, the packet is considered 1230 * bad if any byte (header and/or data) contains an invalid value. 1231 * 1232 * If packet is bad, we discard the first byte and shift the buffer. 1233 * Next iteration will then check the new situation for validity. 1234 * 1235 * If flag MF_SAFE is set in proto[7] and the driver 1236 * is out of sync, the packet is also considered bad if 1237 * any of the data bytes contains a valid header byte value. 1238 * This situation could occur if the buffer contains 1239 * the tail of one packet and the header of the next. 1240 * 1241 * Note: The driver starts in out-of-sync mode (pMse->inSync = 0). 1242 */ 1243 1244 baddata = 0; 1245 1246 /* All databytes must be valid. */ 1247 for (j = 1; j < pBufP; j++ ) 1248 if ((pBuf[j] & pMse->protoPara[2]) != pMse->protoPara[3]) 1249 baddata = 1; 1250 1251 /* If out of sync, don't mistake a header byte for data. */ 1252 if ((pMse->protoPara[7] & MPF_SAFE) && !pMse->inSync) 1253 for (j = 1; j < pBufP; j++ ) 1254 if ((pBuf[j] & pMse->protoPara[0]) == pMse->protoPara[1]) 1255 baddata = 1; 1256 1257 /* Accept or reject the packet ? */ 1258 if ((pBuf[0] & pMse->protoPara[0]) != pMse->protoPara[1] || baddata) { 1259 if (pMse->inSync) { 1260#ifdef EXTMOUSEDEBUG 1261 ErrorF("mouse driver lost sync\n"); 1262#endif 1263 } 1264#ifdef EXTMOUSEDEBUG 1265 ErrorF("skipping byte %02x\n",*pBuf); 1266#endif 1267 /* Tell auto probe that we are out of sync */ 1268 if (pMse->autoProbeMouse && pMse->autoProbe) 1269 pMse->autoProbeMouse(pInfo, FALSE, pMse->inSync); 1270 pMse->protoBufTail = --pBufP; 1271 for (j = 0; j < pBufP; j++) 1272 pBuf[j] = pBuf[j+1]; 1273 pMse->inSync = 0; 1274 continue; 1275 } 1276 /* Tell auto probe that we were successful */ 1277 if (pMse->autoProbeMouse && pMse->autoProbe) 1278 pMse->autoProbeMouse(pInfo, TRUE, FALSE); 1279 1280 if (!pMse->inSync) { 1281#ifdef EXTMOUSEDEBUG 1282 ErrorF("mouse driver back in sync\n"); 1283#endif 1284 pMse->inSync = 1; 1285 } 1286 1287 if (!pMse->dataGood(pMse)) 1288 continue; 1289 1290 /* 1291 * Packet complete and verified, now process it ... 1292 */ 1293 REDO_INTERPRET: 1294 dz = dw = 0; 1295 switch (pMse->protocolID) { 1296 case PROT_LOGIMAN: /* MouseMan / TrackMan [CHRIS-211092] */ 1297 case PROT_MS: /* Microsoft */ 1298 if (pMse->chordMiddle) 1299 buttons = (((int) pBuf[0] & 0x30) == 0x30) ? 2 : 1300 ((int)(pBuf[0] & 0x20) >> 3) 1301 | ((int)(pBuf[0] & 0x10) >> 4); 1302 else 1303 buttons = (pMse->lastButtons & 2) 1304 | ((int)(pBuf[0] & 0x20) >> 3) 1305 | ((int)(pBuf[0] & 0x10) >> 4); 1306 dx = (signed char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1307 dy = (signed char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1308 break; 1309 1310 case PROT_GLIDE: /* ALPS GlidePoint */ 1311 case PROT_THINKING: /* ThinkingMouse */ 1312 case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, MouseMan+ */ 1313 buttons = (pMse->lastButtons & (8 + 2)) 1314 | ((int)(pBuf[0] & 0x20) >> 3) 1315 | ((int)(pBuf[0] & 0x10) >> 4); 1316 dx = (signed char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1317 dy = (signed char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1318 break; 1319 1320 case PROT_MSC: /* Mouse Systems Corp */ 1321 buttons = (~pBuf[0]) & 0x07; 1322 dx = (signed char)(pBuf[1]) + (char)(pBuf[3]); 1323 dy = - ((signed char)(pBuf[2]) + (char)(pBuf[4])); 1324 break; 1325 1326 case PROT_MMHIT: /* MM_HitTablet */ 1327 buttons = pBuf[0] & 0x07; 1328 if (buttons != 0) 1329 buttons = 1 << (buttons - 1); 1330 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1331 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1332 break; 1333 1334 case PROT_ACECAD: /* ACECAD */ 1335 /* ACECAD is almost exactly like MM but the buttons are different */ 1336 buttons = (pBuf[0] & 0x02) | ((pBuf[0] & 0x04) >> 2) | 1337 ((pBuf[0] & 1) << 2); 1338 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1339 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1340 break; 1341 1342 case PROT_MM: /* MM Series */ 1343 case PROT_LOGI: /* Logitech Mice */ 1344 buttons = pBuf[0] & 0x07; 1345 dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1]; 1346 dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2]; 1347 break; 1348 1349 case PROT_BM: /* BusMouse */ 1350 buttons = (~pBuf[0]) & 0x07; 1351 dx = (signed char)pBuf[1]; 1352 dy = - (signed char)pBuf[2]; 1353 break; 1354 1355 case PROT_PS2: /* PS/2 mouse */ 1356 case PROT_GENPS2: /* generic PS/2 mouse */ 1357 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1358 (pBuf[0] & 0x02) >> 1 | /* Right */ 1359 (pBuf[0] & 0x01) << 2; /* Left */ 1360 dx = (pBuf[0] & 0x10) ? (int)pBuf[1]-256 : (int)pBuf[1]; 1361 dy = (pBuf[0] & 0x20) ? -((int)pBuf[2]-256) : -(int)pBuf[2]; 1362 break; 1363 1364 /* PS/2 mouse variants */ 1365 case PROT_IMPS2: /* IntelliMouse PS/2 */ 1366 case PROT_NETPS2: /* NetMouse PS/2 */ 1367 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1368 (pBuf[0] & 0x02) >> 1 | /* Right */ 1369 (pBuf[0] & 0x01) << 2 | /* Left */ 1370 (pBuf[0] & 0x40) >> 3 | /* button 4 */ 1371 (pBuf[0] & 0x80) >> 3; /* button 5 */ 1372 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1373 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1374 /* 1375 * The next cast must be 'signed char' for platforms (like PPC) 1376 * where char defaults to unsigned. 1377 */ 1378 dz = (signed char)(pBuf[3] | ((pBuf[3] & 0x08) ? 0xf8 : 0)); 1379 if ((pBuf[3] & 0xf8) && ((pBuf[3] & 0xf8) != 0xf8)) { 1380 if (pMse->autoProbe) { 1381 SetMouseProto(pMse, PROT_EXPPS2); 1382 xf86Msg(X_INFO, 1383 "Mouse autoprobe: Changing protocol to %s\n", 1384 pMse->protocol); 1385 1386 goto REDO_INTERPRET; 1387 } else 1388 dz = 0; 1389 } 1390 break; 1391 1392 case PROT_EXPPS2: /* IntelliMouse Explorer PS/2 */ 1393 if (pMse->autoProbe && (pBuf[3] & 0xC0)) { 1394 SetMouseProto(pMse, PROT_IMPS2); 1395 xf86Msg(X_INFO,"Mouse autoprobe: Changing protocol to %s\n", 1396 pMse->protocol); 1397 goto REDO_INTERPRET; 1398 } 1399 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1400 (pBuf[0] & 0x02) >> 1 | /* Right */ 1401 (pBuf[0] & 0x01) << 2 | /* Left */ 1402 (pBuf[3] & 0x10) >> 1 | /* button 4 */ 1403 (pBuf[3] & 0x20) >> 1; /* button 5 */ 1404 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1405 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1406 if (pMse->negativeW != MSE_NOAXISMAP) { 1407 switch (pBuf[3] & 0x0f) { 1408 case 0x00: break; 1409 case 0x01: dz = 1; break; 1410 case 0x02: dw = 1; break; 1411 case 0x0e: dw = -1; break; 1412 case 0x0f: dz = -1; break; 1413 default: 1414 xf86Msg(X_INFO, 1415 "Mouse autoprobe: Disabling secondary wheel\n"); 1416 pMse->negativeW = pMse->positiveW = MSE_NOAXISMAP; 1417 } 1418 } 1419 if (pMse->negativeW == MSE_NOAXISMAP) 1420 dz = (pBuf[3]&0x08) ? (pBuf[3]&0x0f) - 16 : (pBuf[3]&0x0f); 1421 break; 1422 1423 case PROT_MMPS2: /* MouseMan+ PS/2 */ 1424 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1425 (pBuf[0] & 0x02) >> 1 | /* Right */ 1426 (pBuf[0] & 0x01) << 2; /* Left */ 1427 dx = (pBuf[0] & 0x10) ? pBuf[1] - 256 : pBuf[1]; 1428 if (((pBuf[0] & 0x48) == 0x48) && 1429 (abs(dx) > 191) && 1430 ((((pBuf[2] & 0x03) << 2) | 0x02) == (pBuf[1] & 0x0f))) { 1431 /* extended data packet */ 1432 switch ((((pBuf[0] & 0x30) >> 2) | ((pBuf[1] & 0x30) >> 4))) { 1433 case 1: /* wheel data packet */ 1434 buttons |= ((pBuf[2] & 0x10) ? 0x08 : 0) | /* 4th button */ 1435 ((pBuf[2] & 0x20) ? 0x10 : 0); /* 5th button */ 1436 dx = dy = 0; 1437 dz = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 : 1438 (pBuf[2] & 0x0f); 1439 break; 1440 case 2: /* Logitech reserves this packet type */ 1441 /* 1442 * IBM ScrollPoint uses this packet to encode its 1443 * stick movement. 1444 */ 1445 buttons |= (pMse->lastButtons & ~0x07); 1446 dx = dy = 0; 1447 dz = (pBuf[2] & 0x80) ? ((pBuf[2] >> 4) & 0x0f) - 16 : 1448 ((pBuf[2] >> 4) & 0x0f); 1449 dw = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 : 1450 (pBuf[2] & 0x0f); 1451 break; 1452 case 0: /* device type packet - shouldn't happen */ 1453 default: 1454 buttons |= (pMse->lastButtons & ~0x07); 1455 dx = dy = 0; 1456 dz = 0; 1457 break; 1458 } 1459 } else { 1460 buttons |= (pMse->lastButtons & ~0x07); 1461 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1462 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1463 } 1464 break; 1465 1466 case PROT_GLIDEPS2: /* GlidePoint PS/2 */ 1467 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1468 (pBuf[0] & 0x02) >> 1 | /* Right */ 1469 (pBuf[0] & 0x01) << 2 | /* Left */ 1470 ((pBuf[0] & 0x08) ? 0 : 0x08);/* fourth button */ 1471 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1472 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1473 break; 1474 1475 case PROT_NETSCPS2: /* NetScroll PS/2 */ 1476 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1477 (pBuf[0] & 0x02) >> 1 | /* Right */ 1478 (pBuf[0] & 0x01) << 2 | /* Left */ 1479 ((pBuf[3] & 0x02) ? 0x08 : 0) | /* button 4 */ 1480 ((pBuf[3] & 0x01) ? 0x10 : 0); /* button 5 */ 1481 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1482 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1483 dz = (pBuf[3] & 0x10) ? pBuf[4] - 256 : pBuf[4]; 1484 break; 1485 1486 case PROT_THINKPS2: /* ThinkingMouse PS/2 */ 1487 buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */ 1488 (pBuf[0] & 0x02) >> 1 | /* Right */ 1489 (pBuf[0] & 0x01) << 2 | /* Left */ 1490 ((pBuf[0] & 0x08) ? 0x08 : 0);/* fourth button */ 1491 pBuf[1] |= (pBuf[0] & 0x40) ? 0x80 : 0x00; 1492 dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1]; 1493 dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2]; 1494 break; 1495 1496 case PROT_SYSMOUSE: /* sysmouse */ 1497 buttons = (~pBuf[0]) & 0x07; 1498 dx = (signed char)(pBuf[1]) + (signed char)(pBuf[3]); 1499 dy = - ((signed char)(pBuf[2]) + (signed char)(pBuf[4])); 1500 /* FreeBSD sysmouse sends additional data bytes */ 1501 if (pMse->protoPara[4] >= 8) { 1502 /* 1503 * These casts must be 'signed char' for platforms (like PPC) 1504 * where char defaults to unsigned. 1505 */ 1506 dz = ((signed char)(pBuf[5] << 1) + 1507 (signed char)(pBuf[6] << 1)) >> 1; 1508 buttons |= (int)(~pBuf[7] & 0x7f) << 3; 1509 } 1510 break; 1511 1512 case PROT_VALUMOUSESCROLL: /* Kensington ValuMouseScroll */ 1513 buttons = ((int)(pBuf[0] & 0x20) >> 3) 1514 | ((int)(pBuf[0] & 0x10) >> 4) 1515 | ((int)(pBuf[3] & 0x10) >> 3); 1516 dx = (signed char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F)); 1517 dy = (signed char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F)); 1518 dz = (pBuf[3] & 0x08) ? ((int)(pBuf[3] & 0x0F) - 0x10) : 1519 ((int)(pBuf[3] & 0x0F)); 1520 break; 1521 1522 default: /* There's a table error */ 1523#ifdef EXTMOUSEDEBUG 1524 ErrorF("mouse table error\n"); 1525#endif 1526 continue; 1527 } 1528#ifdef EXTMOUSEDEBUG 1529 ErrorF("packet"); 1530 for ( j=0; j < pBufP; j++) 1531 ErrorF(" %02x",pBuf[j]); 1532 ErrorF("\n"); 1533#endif 1534 1535post_event: 1536#ifdef EXTMOUSEDEBUG 1537 ErrorF("dx=%i dy=%i dz=%i dw=%i buttons=%x\n",dx,dy,dz,dw,buttons); 1538#endif 1539 /* When auto-probing check if data makes sense */ 1540 if (pMse->checkMovements && pMse->autoProbe) 1541 pMse->checkMovements(pInfo,dx,dy); 1542 /* post an event */ 1543 pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); 1544 1545 /* 1546 * We don't reset pBufP here yet, as there may be an additional data 1547 * byte in some protocols. See above. 1548 */ 1549 } 1550 pMse->protoBufTail = pBufP; 1551} 1552 1553/* 1554 * MouseCtrl -- 1555 * Alter the control parameters for the mouse. Note that all 1556 * settings are now handled by dix. 1557 */ 1558 1559static void 1560MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl) 1561{ 1562 /* This function intentionally left blank */ 1563} 1564 1565/* 1566 *************************************************************************** 1567 * 1568 * MouseProc -- 1569 * 1570 *************************************************************************** 1571 */ 1572 1573static int 1574MouseProc(DeviceIntPtr device, int what) 1575{ 1576 InputInfoPtr pInfo; 1577 MouseDevPtr pMse; 1578 mousePrivPtr mPriv; 1579 unsigned char map[MSE_MAXBUTTONS + 1]; 1580 int i; 1581#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 1582 Atom btn_labels[MSE_MAXBUTTONS] = {0}; 1583 Atom axes_labels[2] = { 0, 0 }; 1584#endif 1585 1586 pInfo = device->public.devicePrivate; 1587 pMse = pInfo->private; 1588 pMse->device = device; 1589 1590 switch (what) 1591 { 1592 case DEVICE_INIT: 1593 device->public.on = FALSE; 1594 /* 1595 * [KAZU-241097] We don't know exactly how many buttons the 1596 * device has, so setup the map with the maximum number. 1597 */ 1598 for (i = 0; i < MSE_MAXBUTTONS; i++) 1599 map[i + 1] = i + 1; 1600 1601 /* FIXME: we should probably set the labels here */ 1602 1603 InitPointerDeviceStruct((DevicePtr)device, map, 1604 min(pMse->buttons, MSE_MAXBUTTONS), 1605#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 1606 btn_labels, 1607#endif 1608#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1609 miPointerGetMotionEvents, 1610#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 3 1611 GetMotionHistory, 1612#endif 1613 pMse->Ctrl, 1614#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1615 miPointerGetMotionBufferSize() 1616#else 1617 GetMotionHistorySize(), 2 1618#endif 1619#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 1620 , axes_labels 1621#endif 1622 ); 1623 1624 /* X valuator */ 1625 xf86InitValuatorAxisStruct(device, 0, 1626#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 1627 axes_labels[0], 1628#endif 1629 -1, -1, 1, 0, 1); 1630 xf86InitValuatorDefaults(device, 0); 1631 /* Y valuator */ 1632 xf86InitValuatorAxisStruct(device, 1, 1633#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 1634 axes_labels[1], 1635#endif 1636 -1, -1, 1, 0, 1); 1637 xf86InitValuatorDefaults(device, 1); 1638#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) == 0 1639 xf86MotionHistoryAllocate(pInfo); 1640#endif 1641 1642#ifdef EXTMOUSEDEBUG 1643 ErrorF("assigning %p atom=%d name=%s\n", device, pInfo->atom, 1644 pInfo->name); 1645#endif 1646 break; 1647 1648 case DEVICE_ON: 1649 pInfo->fd = xf86OpenSerial(pInfo->options); 1650 if (pInfo->fd == -1) 1651 xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); 1652 else { 1653#if defined(__NetBSD__) && defined(WSCONS_SUPPORT) && defined(WSMOUSEIO_SETVERSION) 1654 int version = WSMOUSE_EVENT_VERSION; 1655 if (ioctl(pInfo->fd, WSMOUSEIO_SETVERSION, &version) == -1) 1656 xf86Msg(X_WARNING, "%s: cannot set version\n", pInfo->name); 1657#endif 1658 if (pMse->xisbscale) 1659 pMse->buffer = XisbNew(pInfo->fd, pMse->xisbscale * 4); 1660 else 1661 pMse->buffer = XisbNew(pInfo->fd, 64); 1662 if (!pMse->buffer) { 1663 xf86CloseSerial(pInfo->fd); 1664 pInfo->fd = -1; 1665 } else { 1666 if (!SetupMouse(pInfo)) { 1667 xf86CloseSerial(pInfo->fd); 1668 pInfo->fd = -1; 1669 XisbFree(pMse->buffer); 1670 pMse->buffer = NULL; 1671 } else { 1672 mPriv = (mousePrivPtr)pMse->mousePriv; 1673 if (mPriv != NULL) { 1674 if ( pMse->protocolID != PROT_AUTO) { 1675 pMse->inSync = TRUE; /* @@@ */ 1676 if (mPriv->soft) 1677 mPriv->autoState = AUTOPROBE_GOOD; 1678 else 1679 mPriv->autoState = AUTOPROBE_H_GOOD; 1680 } else { 1681 if (mPriv->soft) 1682 mPriv->autoState = AUTOPROBE_NOPROTO; 1683 else 1684 mPriv->autoState = AUTOPROBE_H_NOPROTO; 1685 } 1686 } 1687 xf86FlushInput(pInfo->fd); 1688 xf86AddEnabledDevice(pInfo); 1689 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) { 1690 RegisterBlockAndWakeupHandlers (MouseBlockHandler, 1691 MouseWakeupHandler, 1692 (pointer) pInfo); 1693 } 1694 } 1695 } 1696 } 1697 pMse->lastButtons = 0; 1698 pMse->lastMappedButtons = 0; 1699 pMse->emulateState = 0; 1700 pMse->emulate3Pending = FALSE; 1701 pMse->wheelButtonExpires = GetTimeInMillis (); 1702 device->public.on = TRUE; 1703 FlushButtons(pMse); 1704 break; 1705 1706 case DEVICE_OFF: 1707 if (pInfo->fd != -1) { 1708 xf86RemoveEnabledDevice(pInfo); 1709 if (pMse->buffer) { 1710 XisbFree(pMse->buffer); 1711 pMse->buffer = NULL; 1712 } 1713 xf86CloseSerial(pInfo->fd); 1714 pInfo->fd = -1; 1715 if (pMse->emulate3Buttons || pMse->emulate3ButtonsSoft) 1716 { 1717 RemoveBlockAndWakeupHandlers (MouseBlockHandler, 1718 MouseWakeupHandler, 1719 (pointer) pInfo); 1720 } 1721 } 1722 device->public.on = FALSE; 1723 break; 1724 case DEVICE_CLOSE: 1725 xfree(pMse->mousePriv); 1726 pMse->mousePriv = NULL; 1727 break; 1728 } 1729 return Success; 1730} 1731 1732/* 1733 *************************************************************************** 1734 * 1735 * MouseConvert -- 1736 * Convert valuators to X and Y. 1737 * 1738 *************************************************************************** 1739 */ 1740static Bool 1741MouseConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2, 1742 int v3, int v4, int v5, int *x, int *y) 1743{ 1744 if (first != 0 || num != 2) 1745 return FALSE; 1746 1747 *x = v0; 1748 *y = v1; 1749 1750 return TRUE; 1751} 1752 1753/********************************************************************** 1754 * 1755 * FlushButtons -- reset button states. 1756 * 1757 **********************************************************************/ 1758 1759static void 1760FlushButtons(MouseDevPtr pMse) 1761{ 1762 pMse->lastButtons = 0; 1763 pMse->lastMappedButtons = 0; 1764} 1765 1766/********************************************************************** 1767 * 1768 * Emulate3Button support code 1769 * 1770 **********************************************************************/ 1771 1772 1773/* 1774 * Lets create a simple finite-state machine for 3 button emulation: 1775 * 1776 * We track buttons 1 and 3 (left and right). There are 11 states: 1777 * 0 ground - initial state 1778 * 1 delayed left - left pressed, waiting for right 1779 * 2 delayed right - right pressed, waiting for left 1780 * 3 pressed middle - right and left pressed, emulated middle sent 1781 * 4 pressed left - left pressed and sent 1782 * 5 pressed right - right pressed and sent 1783 * 6 released left - left released after emulated middle 1784 * 7 released right - right released after emulated middle 1785 * 8 repressed left - left pressed after released left 1786 * 9 repressed right - right pressed after released right 1787 * 10 pressed both - both pressed, not emulating middle 1788 * 1789 * At each state, we need handlers for the following events 1790 * 0: no buttons down 1791 * 1: left button down 1792 * 2: right button down 1793 * 3: both buttons down 1794 * 4: emulate3Timeout passed without a button change 1795 * Note that button events are not deltas, they are the set of buttons being 1796 * pressed now. It's possible (ie, mouse hardware does it) to go from (eg) 1797 * left down to right down without anything in between, so all cases must be 1798 * handled. 1799 * 1800 * a handler consists of three values: 1801 * 0: action1 1802 * 1: action2 1803 * 2: new emulation state 1804 * 1805 * action > 0: ButtonPress 1806 * action = 0: nothing 1807 * action < 0: ButtonRelease 1808 * 1809 * The comment preceeding each section is the current emulation state. 1810 * The comments to the right are of the form 1811 * <button state> (<events>) -> <new emulation state> 1812 * which should be read as 1813 * If the buttons are in <button state>, generate <events> then go to 1814 * <new emulation state>. 1815 */ 1816static signed char stateTab[11][5][3] = { 1817/* 0 ground */ 1818 { 1819 { 0, 0, 0 }, /* nothing -> ground (no change) */ 1820 { 0, 0, 1 }, /* left -> delayed left */ 1821 { 0, 0, 2 }, /* right -> delayed right */ 1822 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1823 { 0, 0, -1 } /* timeout N/A */ 1824 }, 1825/* 1 delayed left */ 1826 { 1827 { 1, -1, 0 }, /* nothing (left event) -> ground */ 1828 { 0, 0, 1 }, /* left -> delayed left (no change) */ 1829 { 1, -1, 2 }, /* right (left event) -> delayed right */ 1830 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1831 { 1, 0, 4 }, /* timeout (left press) -> pressed left */ 1832 }, 1833/* 2 delayed right */ 1834 { 1835 { 3, -3, 0 }, /* nothing (right event) -> ground */ 1836 { 3, -3, 1 }, /* left (right event) -> delayed left (no change) */ 1837 { 0, 0, 2 }, /* right -> delayed right (no change) */ 1838 { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ 1839 { 3, 0, 5 }, /* timeout (right press) -> pressed right */ 1840 }, 1841/* 3 pressed middle */ 1842 { 1843 { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1844 { 0, 0, 7 }, /* left -> released right */ 1845 { 0, 0, 6 }, /* right -> released left */ 1846 { 0, 0, 3 }, /* left & right -> pressed middle (no change) */ 1847 { 0, 0, -1 }, /* timeout N/A */ 1848 }, 1849/* 4 pressed left */ 1850 { 1851 { -1, 0, 0 }, /* nothing (left release) -> ground */ 1852 { 0, 0, 4 }, /* left -> pressed left (no change) */ 1853 { -1, 0, 2 }, /* right (left release) -> delayed right */ 1854 { 3, 0, 10 }, /* left & right (right press) -> pressed both */ 1855 { 0, 0, -1 }, /* timeout N/A */ 1856 }, 1857/* 5 pressed right */ 1858 { 1859 { -3, 0, 0 }, /* nothing (right release) -> ground */ 1860 { -3, 0, 1 }, /* left (right release) -> delayed left */ 1861 { 0, 0, 5 }, /* right -> pressed right (no change) */ 1862 { 1, 0, 10 }, /* left & right (left press) -> pressed both */ 1863 { 0, 0, -1 }, /* timeout N/A */ 1864 }, 1865/* 6 released left */ 1866 { 1867 { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1868 { -2, 0, 1 }, /* left (middle release) -> delayed left */ 1869 { 0, 0, 6 }, /* right -> released left (no change) */ 1870 { 1, 0, 8 }, /* left & right (left press) -> repressed left */ 1871 { 0, 0, -1 }, /* timeout N/A */ 1872 }, 1873/* 7 released right */ 1874 { 1875 { -2, 0, 0 }, /* nothing (middle release) -> ground */ 1876 { 0, 0, 7 }, /* left -> released right (no change) */ 1877 { -2, 0, 2 }, /* right (middle release) -> delayed right */ 1878 { 3, 0, 9 }, /* left & right (right press) -> repressed right */ 1879 { 0, 0, -1 }, /* timeout N/A */ 1880 }, 1881/* 8 repressed left */ 1882 { 1883 { -2, -1, 0 }, /* nothing (middle release, left release) -> ground */ 1884 { -2, 0, 4 }, /* left (middle release) -> pressed left */ 1885 { -1, 0, 6 }, /* right (left release) -> released left */ 1886 { 0, 0, 8 }, /* left & right -> repressed left (no change) */ 1887 { 0, 0, -1 }, /* timeout N/A */ 1888 }, 1889/* 9 repressed right */ 1890 { 1891 { -2, -3, 0 }, /* nothing (middle release, right release) -> ground */ 1892 { -3, 0, 7 }, /* left (right release) -> released right */ 1893 { -2, 0, 5 }, /* right (middle release) -> pressed right */ 1894 { 0, 0, 9 }, /* left & right -> repressed right (no change) */ 1895 { 0, 0, -1 }, /* timeout N/A */ 1896 }, 1897/* 10 pressed both */ 1898 { 1899 { -1, -3, 0 }, /* nothing (left release, right release) -> ground */ 1900 { -3, 0, 4 }, /* left (right release) -> pressed left */ 1901 { -1, 0, 5 }, /* right (left release) -> pressed right */ 1902 { 0, 0, 10 }, /* left & right -> pressed both (no change) */ 1903 { 0, 0, -1 }, /* timeout N/A */ 1904 }, 1905}; 1906 1907/* 1908 * Table to allow quick reversal of natural button mapping to correct mapping 1909 */ 1910 1911/* 1912 * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol 1913 * with a fourth button activated by tapping the PAD. 1914 * The 2nd line corresponds to 4th button on; the drv sends 1915 * the buttons in the following map (MSBit described first) : 1916 * 0 | 4th | 1st | 2nd | 3rd 1917 * And we remap them (MSBit described first) : 1918 * 0 | 4th | 3rd | 2nd | 1st 1919 */ 1920static char reverseMap[16] = { 0, 4, 2, 6, 1921 1, 5, 3, 7, 1922 8, 12, 10, 14, 1923 9, 13, 11, 15 }; 1924 1925static char hitachMap[16] = { 0, 2, 1, 3, 1926 8, 10, 9, 11, 1927 4, 6, 5, 7, 1928 12, 14, 13, 15 }; 1929 1930#define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f]) 1931 1932static CARD32 1933buttonTimer(InputInfoPtr pInfo) 1934{ 1935 MouseDevPtr pMse; 1936 int sigstate; 1937 int id; 1938 1939 pMse = pInfo->private; 1940 1941 sigstate = xf86BlockSIGIO (); 1942 1943 pMse->emulate3Pending = FALSE; 1944 if ((id = stateTab[pMse->emulateState][4][0]) != 0) { 1945 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 1946 pMse->emulateState = stateTab[pMse->emulateState][4][2]; 1947 } else { 1948 ErrorF("Got unexpected buttonTimer in state %d\n", pMse->emulateState); 1949 } 1950 1951 xf86UnblockSIGIO (sigstate); 1952 return 0; 1953} 1954 1955static Bool 1956Emulate3ButtonsSoft(InputInfoPtr pInfo) 1957{ 1958 MouseDevPtr pMse = pInfo->private; 1959 1960 if (!pMse->emulate3ButtonsSoft) 1961 return TRUE; 1962 1963#if defined(__NetBSD__) && defined(WSCONS_SUPPORT) 1964 /* 1965 * XXXX - check for pMse->protocolID being wsmouse? Why doesn't it 1966 * have it's own ID? 1967 * On NetBSD a wsmouse is a multiplexed device. Imagine a notebook 1968 * with two-button mousepad, and an external USB mouse plugged in 1969 * temporarily. After using button 3 on the external mouse and 1970 * unplugging it again, the mousepad will still need to emulate 1971 * 3 buttons. 1972 */ 1973 return TRUE; 1974#endif 1975 1976 pMse->emulate3Buttons = FALSE; 1977 1978 if (pMse->emulate3Pending) 1979 buttonTimer(pInfo); 1980 1981 xf86Msg(X_INFO,"3rd Button detected: disabling emulate3Button\n"); 1982 1983 RemoveBlockAndWakeupHandlers (MouseBlockHandler, MouseWakeupHandler, 1984 (pointer) pInfo); 1985 1986 return FALSE; 1987} 1988 1989static void MouseBlockHandler(pointer data, 1990 struct timeval **waitTime, 1991 pointer LastSelectMask) 1992{ 1993 InputInfoPtr pInfo = (InputInfoPtr) data; 1994 MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 1995 int ms; 1996 1997 if (pMse->emulate3Pending) 1998 { 1999 ms = pMse->emulate3Expires - GetTimeInMillis (); 2000 if (ms <= 0) 2001 ms = 0; 2002 AdjustWaitForDelay (waitTime, ms); 2003 } 2004} 2005 2006static void MouseWakeupHandler(pointer data, 2007 int i, 2008 pointer LastSelectMask) 2009{ 2010 InputInfoPtr pInfo = (InputInfoPtr) data; 2011 MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 2012 int ms; 2013 2014 if (pMse->emulate3Pending) 2015 { 2016 ms = pMse->emulate3Expires - GetTimeInMillis (); 2017 if (ms <= 0) 2018 buttonTimer (pInfo); 2019 } 2020} 2021 2022/******************************************************************* 2023 * 2024 * Post mouse events 2025 * 2026 *******************************************************************/ 2027 2028static void 2029MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy) 2030{ 2031 MouseDevPtr pMse; 2032 int emulateButtons; 2033 int id, change; 2034 int emuWheelDelta, emuWheelButton, emuWheelButtonMask; 2035 int wheelButtonMask; 2036 int ms; 2037 2038 pMse = pInfo->private; 2039 2040 change = buttons ^ pMse->lastMappedButtons; 2041 pMse->lastMappedButtons = buttons; 2042 2043 /* Do single button double click */ 2044 if (pMse->doubleClickSourceButtonMask) { 2045 if (buttons & pMse->doubleClickSourceButtonMask) { 2046 if (!(pMse->doubleClickOldSourceState)) { 2047 /* double-click button has just been pressed. Ignore it if target button 2048 * is already down. 2049 */ 2050 if (!(buttons & pMse->doubleClickTargetButtonMask)) { 2051 /* Target button isn't down, so send a double-click */ 2052 xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 1, 0, 0); 2053 xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 0, 0, 0); 2054 xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 1, 0, 0); 2055 xf86PostButtonEvent(pInfo->dev, 0, pMse->doubleClickTargetButton, 0, 0, 0); 2056 } 2057 } 2058 pMse->doubleClickOldSourceState = 1; 2059 } 2060 else 2061 pMse->doubleClickOldSourceState = 0; 2062 2063 /* Whatever happened, mask the double-click button so it doesn't get 2064 * processed as a normal button as well. 2065 */ 2066 buttons &= ~(pMse->doubleClickSourceButtonMask); 2067 change &= ~(pMse->doubleClickSourceButtonMask); 2068 } 2069 2070 if (pMse->emulateWheel) { 2071 /* Emulate wheel button handling */ 2072 if(pMse->wheelButton == 0) 2073 wheelButtonMask = 0; 2074 else 2075 wheelButtonMask = 1 << (pMse->wheelButton - 1); 2076 2077 if (change & wheelButtonMask) { 2078 if (buttons & wheelButtonMask) { 2079 /* Start timeout handling */ 2080 pMse->wheelButtonExpires = GetTimeInMillis () + pMse->wheelButtonTimeout; 2081 ms = - pMse->wheelButtonTimeout; 2082 } else { 2083 ms = pMse->wheelButtonExpires - GetTimeInMillis (); 2084 2085 if (0 < ms) { 2086 /* 2087 * If the button is released early enough emit the button 2088 * press/release events 2089 */ 2090 xf86PostButtonEvent(pInfo->dev, 0, pMse->wheelButton, 1, 0, 0); 2091 xf86PostButtonEvent(pInfo->dev, 0, pMse->wheelButton, 0, 0, 0); 2092 } 2093 } 2094 } else 2095 ms = pMse->wheelButtonExpires - GetTimeInMillis (); 2096 2097 /* Intercept wheel emulation if the necessary button is depressed or 2098 if no button is necessary */ 2099 if ((buttons & wheelButtonMask) || wheelButtonMask==0) { 2100 if (ms <= 0 || wheelButtonMask==0) { 2101 /* Y axis movement */ 2102 if (pMse->negativeY != MSE_NOAXISMAP) { 2103 pMse->wheelYDistance += dy; 2104 if (pMse->wheelYDistance < 0) { 2105 emuWheelDelta = -pMse->wheelInertia; 2106 emuWheelButton = pMse->negativeY; 2107 } else { 2108 emuWheelDelta = pMse->wheelInertia; 2109 emuWheelButton = pMse->positiveY; 2110 } 2111 emuWheelButtonMask = 1 << (emuWheelButton - 1); 2112 while (abs(pMse->wheelYDistance) > pMse->wheelInertia) { 2113 pMse->wheelYDistance -= emuWheelDelta; 2114 2115 pMse->wheelXDistance = 0; 2116 /* 2117 * Synthesize the press and release, but not when 2118 * the button to be synthesized is already pressed 2119 * "for real". 2120 */ 2121 if (!(emuWheelButtonMask & buttons) || 2122 (emuWheelButtonMask & wheelButtonMask)) { 2123 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0); 2124 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0); 2125 } 2126 } 2127 } 2128 2129 /* X axis movement */ 2130 if (pMse->negativeX != MSE_NOAXISMAP) { 2131 pMse->wheelXDistance += dx; 2132 if (pMse->wheelXDistance < 0) { 2133 emuWheelDelta = -pMse->wheelInertia; 2134 emuWheelButton = pMse->negativeX; 2135 } else { 2136 emuWheelDelta = pMse->wheelInertia; 2137 emuWheelButton = pMse->positiveX; 2138 } 2139 emuWheelButtonMask = 1 << (emuWheelButton - 1); 2140 while (abs(pMse->wheelXDistance) > pMse->wheelInertia) { 2141 pMse->wheelXDistance -= emuWheelDelta; 2142 2143 pMse->wheelYDistance = 0; 2144 /* 2145 * Synthesize the press and release, but not when 2146 * the button to be synthesized is already pressed 2147 * "for real". 2148 */ 2149 if (!(emuWheelButtonMask & buttons) || 2150 (emuWheelButtonMask & wheelButtonMask)) { 2151 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 1, 0, 0); 2152 xf86PostButtonEvent(pInfo->dev, 0, emuWheelButton, 0, 0, 0); 2153 } 2154 } 2155 } 2156 } 2157 2158 /* Absorb the mouse movement while the wheel button is pressed. */ 2159 dx = 0; 2160 dy = 0; 2161 } 2162 /* 2163 * Button events for the wheel button are only emitted through 2164 * the timeout code. 2165 */ 2166 buttons &= ~wheelButtonMask; 2167 change &= ~wheelButtonMask; 2168 } 2169 2170 if (pMse->emulate3ButtonsSoft && pMse->emulate3Pending && (dx || dy)) 2171 buttonTimer(pInfo); 2172 2173 if (dx || dy) 2174 xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy); 2175 2176 if (change) { 2177 2178 /* 2179 * adjust buttons state for drag locks! 2180 * if there is drag locks 2181 */ 2182 if (pMse->pDragLock) { 2183 DragLockPtr pLock; 2184 int tarOfGoingDown, tarOfDown; 2185 int realbuttons; 2186 2187 /* get drag lock block */ 2188 pLock = pMse->pDragLock; 2189 /* save real buttons */ 2190 realbuttons = buttons; 2191 2192 /* if drag lock used */ 2193 2194 /* state of drag lock buttons not seen always up */ 2195 2196 buttons &= ~pLock->lockButtonsM; 2197 2198 /* 2199 * if lock buttons being depressed changes state of 2200 * targets simulatedDown. 2201 */ 2202 tarOfGoingDown = lock2targetMap(pLock, 2203 realbuttons & change & pLock->lockButtonsM); 2204 pLock->simulatedDown ^= tarOfGoingDown; 2205 2206 /* targets of drag locks down */ 2207 tarOfDown = lock2targetMap(pLock, 2208 realbuttons & pLock->lockButtonsM); 2209 2210 /* 2211 * when simulatedDown set and target pressed, 2212 * simulatedDown goes false 2213 */ 2214 pLock->simulatedDown &= ~(realbuttons & change); 2215 2216 /* 2217 * if master drag lock released 2218 * then master drag lock state on 2219 */ 2220 pLock->masterTS |= (~realbuttons & change) & pLock->masterLockM; 2221 2222 /* if master state, buttons going down are simulatedDown */ 2223 if (pLock->masterTS) 2224 pLock->simulatedDown |= (realbuttons & change); 2225 2226 /* if any button pressed, no longer in master drag lock state */ 2227 if (realbuttons & change) 2228 pLock->masterTS = 0; 2229 2230 /* if simulatedDown or drag lock down, simulate down */ 2231 buttons |= (pLock->simulatedDown | tarOfDown); 2232 2233 /* master button not seen */ 2234 buttons &= ~(pLock->masterLockM); 2235 2236 /* buttons changed since last time */ 2237 change = buttons ^ pLock->lockLastButtons; 2238 2239 /* save this time for next last time. */ 2240 pLock->lockLastButtons = buttons; 2241 } 2242 2243 if (pMse->emulate3Buttons 2244 && (!(buttons & 0x02) || Emulate3ButtonsSoft(pInfo))) { 2245 2246 /* handle all but buttons 1 & 3 normally */ 2247 2248 change &= ~05; 2249 2250 /* emulate the third button by the other two */ 2251 2252 emulateButtons = (buttons & 01) | ((buttons &04) >> 1); 2253 2254 if ((id = stateTab[pMse->emulateState][emulateButtons][0]) != 0) 2255 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 2256 if ((id = stateTab[pMse->emulateState][emulateButtons][1]) != 0) 2257 xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0); 2258 2259 pMse->emulateState = 2260 stateTab[pMse->emulateState][emulateButtons][2]; 2261 2262 if (stateTab[pMse->emulateState][4][0] != 0) { 2263 pMse->emulate3Expires = GetTimeInMillis () + pMse->emulate3Timeout; 2264 pMse->emulate3Pending = TRUE; 2265 } else { 2266 pMse->emulate3Pending = FALSE; 2267 } 2268 } 2269 2270 while (change) { 2271 id = ffs(change); 2272 change &= ~(1 << (id - 1)); 2273 xf86PostButtonEvent(pInfo->dev, 0, id, 2274 (buttons & (1 << (id - 1))), 0, 0); 2275 } 2276 2277 } 2278} 2279 2280static void 2281MousePostEvent(InputInfoPtr pInfo, int truebuttons, 2282 int dx, int dy, int dz, int dw) 2283{ 2284 MouseDevPtr pMse; 2285 mousePrivPtr mousepriv; 2286 int zbutton = 0, wbutton = 0, zbuttoncount = 0, wbuttoncount = 0; 2287 int i, b, buttons = 0; 2288 2289 pMse = pInfo->private; 2290 mousepriv = (mousePrivPtr)pMse->mousePriv; 2291 2292 if (pMse->protocolID == PROT_MMHIT) 2293 b = reverseBits(hitachMap, truebuttons); 2294 else 2295 b = reverseBits(reverseMap, truebuttons); 2296 2297 /* Remap mouse buttons */ 2298 b &= (1<<MSE_MAXBUTTONS)-1; 2299 for (i = 0; b; i++) { 2300 if (b & 1) 2301 buttons |= pMse->buttonMap[i]; 2302 b >>= 1; 2303 } 2304 2305 /* Map the Z axis movement. */ 2306 /* XXX Could this go in the conversion_proc? */ 2307 switch (pMse->negativeZ) { 2308 case MSE_NOZMAP: /* do nothing */ 2309 dz = 0; 2310 break; 2311 case MSE_MAPTOX: 2312 if (dz != 0) { 2313 dx = dz; 2314 dz = 0; 2315 } 2316 break; 2317 case MSE_MAPTOY: 2318 if (dz != 0) { 2319 dy = dz; 2320 dz = 0; 2321 } 2322 break; 2323 default: /* buttons */ 2324 buttons &= ~(pMse->negativeZ | pMse->positiveZ); 2325 if (dz < 0) { 2326 zbutton = pMse->negativeZ; 2327 zbuttoncount = -dz; 2328 } else if (dz > 0) { 2329 zbutton = pMse->positiveZ; 2330 zbuttoncount = dz; 2331 } 2332 dz = 0; 2333 break; 2334 } 2335 switch (pMse->negativeW) { 2336 case MSE_NOZMAP: /* do nothing */ 2337 dw = 0; 2338 break; 2339 case MSE_MAPTOX: 2340 if (dw != 0) { 2341 dx = dw; 2342 dw = 0; 2343 } 2344 break; 2345 case MSE_MAPTOY: 2346 if (dw != 0) { 2347 dy = dw; 2348 dw = 0; 2349 } 2350 break; 2351 default: /* buttons */ 2352 buttons &= ~(pMse->negativeW | pMse->positiveW); 2353 if (dw < 0) { 2354 wbutton = pMse->negativeW; 2355 wbuttoncount = -dw; 2356 } else if (dw > 0) { 2357 wbutton = pMse->positiveW; 2358 wbuttoncount = dw; 2359 } 2360 dw = 0; 2361 break; 2362 } 2363 2364 2365 /* Apply angle offset */ 2366 if (pMse->angleOffset != 0) { 2367 double rad = 3.141592653 * pMse->angleOffset / 180.0; 2368 int ndx = dx; 2369 dx = (int)((dx * cos(rad)) + (dy * sin(rad)) + 0.5); 2370 dy = (int)((dy * cos(rad)) - (ndx * sin(rad)) + 0.5); 2371 } 2372 2373 dx = pMse->invX * dx; 2374 dy = pMse->invY * dy; 2375 if (pMse->flipXY) { 2376 int tmp = dx; 2377 dx = dy; 2378 dy = tmp; 2379 } 2380 2381 /* Accumulate the scaled dx, dy in the private variables 2382 fracdx,fracdy and return the integer number part */ 2383 if (mousepriv) { 2384 mousepriv->fracdx += mousepriv->sensitivity*dx; 2385 mousepriv->fracdy += mousepriv->sensitivity*dy; 2386 mousepriv->fracdx -= ( dx=(int)(mousepriv->fracdx) ); 2387 mousepriv->fracdy -= ( dy=(int)(mousepriv->fracdy) ); 2388 } 2389 2390 /* If mouse wheel movement has to be mapped on a button, we need to 2391 * loop for button press and release events. */ 2392 do { 2393 MouseDoPostEvent(pInfo, buttons | zbutton | wbutton, dx, dy); 2394 dx = dy = 0; 2395 if (zbutton || wbutton) 2396 MouseDoPostEvent(pInfo, buttons, 0, 0); 2397 if (--zbuttoncount <= 0) 2398 zbutton = 0; 2399 if (--wbuttoncount <= 0) 2400 wbutton = 0; 2401 } while (zbutton || wbutton); 2402 2403 pMse->lastButtons = truebuttons; 2404} 2405/****************************************************************** 2406 * 2407 * Mouse Setup Code 2408 * 2409 ******************************************************************/ 2410/* 2411 * This array is indexed by the MouseProtocolID values, so the order of the 2412 * entries must match that of the MouseProtocolID enum in xf86OSmouse.h. 2413 */ 2414static unsigned char proto[PROT_NUMPROTOS][8] = { 2415 /* --header-- ---data--- packet -4th-byte- mouse */ 2416 /* mask id mask id bytes mask id flags */ 2417 /* Serial mice */ 2418 { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MicroSoft */ 2419 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_SAFE }, /* MouseSystems */ 2420 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MMSeries */ 2421 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* Logitech */ 2422 { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MouseMan */ 2423 { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MM_HitTablet */ 2424 { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* GlidePoint */ 2425 { 0x40, 0x40, 0x40, 0x00, 3, ~0x3f, 0x00, MPF_NONE }, /* IntelliMouse */ 2426 { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* ThinkingMouse */ 2427 { 0x80, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ACECAD */ 2428 { 0x40, 0x40, 0x40, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* ValuMouseScroll */ 2429 /* PS/2 variants */ 2430 { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* PS/2 mouse */ 2431 { 0xc8, 0x08, 0x00, 0x00, 3, 0x00, 0x00, MPF_NONE }, /* genericPS/2 mouse*/ 2432 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* IntelliMouse */ 2433 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* Explorer */ 2434 { 0x80, 0x80, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ThinkingMouse */ 2435 { 0x08, 0x08, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MouseMan+ */ 2436 { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* GlidePoint */ 2437 { 0x08, 0x08, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* NetMouse */ 2438 { 0xc0, 0x00, 0x00, 0x00, 6, 0x00, 0xff, MPF_NONE }, /* NetScroll */ 2439 /* Bus Mouse */ 2440 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* BusMouse */ 2441 { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* Auto (dummy) */ 2442 { 0xf8, 0x80, 0x00, 0x00, 8, 0x00, 0xff, MPF_NONE }, /* SysMouse */ 2443}; 2444 2445 2446/* 2447 * SetupMouse -- 2448 * Sets up the mouse parameters 2449 */ 2450static Bool 2451SetupMouse(InputInfoPtr pInfo) 2452{ 2453 MouseDevPtr pMse; 2454 int i; 2455 int protoPara[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; 2456 const char *name = NULL; 2457 Bool automatic = FALSE; 2458 2459 pMse = pInfo->private; 2460 2461 /* Handle the "Auto" protocol. */ 2462 if (pMse->protocolID == PROT_AUTO) { 2463 /* 2464 * We come here when user specifies protocol "auto" in 2465 * the configuration file or thru the xf86misc extensions. 2466 * So we initialize autoprobing here. 2467 * Probe for PnP/OS mouse first. If unsuccessful 2468 * try to guess protocol from incoming data. 2469 */ 2470 automatic = TRUE; 2471 pMse->autoProbe = TRUE; 2472 name = autoOSProtocol(pInfo,protoPara); 2473 if (name) { 2474#ifdef EXTMOUSEDEBUG 2475 ErrorF("PnP/OS Mouse detected: %s\n",name); 2476#endif 2477 } 2478 } 2479 2480 SetMouseProto(pMse, pMse->protocolID); 2481 2482 if (automatic) { 2483 if (name) { 2484 /* Possible protoPara overrides from SetupAuto. */ 2485 for (i = 0; i < sizeof(pMse->protoPara); i++) 2486 if (protoPara[i] != -1) 2487 pMse->protoPara[i] = protoPara[i]; 2488 /* if we come here PnP/OS mouse probing was successful */ 2489 } else { 2490#if 1 2491 /* PnP/OS mouse probing wasn't successful; we look at data */ 2492#else 2493 xf86Msg(X_ERROR, "%s: cannot determine the mouse protocol\n", 2494 pInfo->name); 2495 return FALSE; 2496#endif 2497 } 2498 } 2499 2500 /* 2501 * If protocol has changed fetch the default options 2502 * for the new protocol. 2503 */ 2504 if (pMse->oldProtocolID != pMse->protocolID) { 2505 pointer tmp = NULL; 2506 if ((pMse->protocolID >= 0) 2507 && (pMse->protocolID < PROT_NUMPROTOS) 2508 && mouseProtocols[pMse->protocolID].defaults) 2509 tmp = xf86OptionListCreate( 2510 mouseProtocols[pMse->protocolID].defaults, -1, 0); 2511 pInfo->options = xf86OptionListMerge(pInfo->options, tmp); 2512 /* 2513 * If baudrate is set write it back to the option 2514 * list so that the serial interface code can access 2515 * the new value. Not set means default. 2516 */ 2517 if (pMse->baudRate) 2518 xf86ReplaceIntOption(pInfo->options, "BaudRate", pMse->baudRate); 2519 pMse->oldProtocolID = pMse->protocolID; /* hack */ 2520 } 2521 2522 2523 /* Set the port parameters. */ 2524 if (!automatic) 2525 xf86SetSerial(pInfo->fd, pInfo->options); 2526 2527 if (!initMouseHW(pInfo)) 2528 return FALSE; 2529 2530 pMse->protoBufTail = 0; 2531 pMse->inSync = 0; 2532 2533 return TRUE; 2534} 2535 2536/******************************************************************** 2537 * 2538 * Mouse HW setup code 2539 * 2540 ********************************************************************/ 2541 2542/* 2543** The following lines take care of the Logitech MouseMan protocols. 2544** The "Logitech" protocol is for the old "series 9" Logitech products. 2545** All products since then use the "MouseMan" protocol. Some models 2546** were programmable, but most (all?) of the current models are not. 2547** 2548** NOTE: There are different versions of both MouseMan and TrackMan! 2549** Hence I add another protocol PROT_LOGIMAN, which the user can 2550** specify as MouseMan in his XF86Config file. This entry was 2551** formerly handled as a special case of PROT_MS. However, people 2552** who don't have the middle button problem, can still specify 2553** Microsoft and use PROT_MS. 2554** 2555** By default, these mice should use a 3 byte Microsoft protocol 2556** plus a 4th byte for the middle button. However, the mouse might 2557** have switched to a different protocol before we use it, so I send 2558** the proper sequence just in case. 2559** 2560** NOTE: - all commands to (at least the European) MouseMan have to 2561** be sent at 1200 Baud. 2562** - each command starts with a '*'. 2563** - whenever the MouseMan receives a '*', it will switch back 2564** to 1200 Baud. Hence I have to select the desired protocol 2565** first, then select the baud rate. 2566** 2567** The protocols supported by the (European) MouseMan are: 2568** - 5 byte packed binary protocol, as with the Mouse Systems 2569** mouse. Selected by sequence "*U". 2570** - 2 button 3 byte MicroSoft compatible protocol. Selected 2571** by sequence "*V". 2572** - 3 button 3+1 byte MicroSoft compatible protocol (default). 2573** Selected by sequence "*X". 2574** 2575** The following baud rates are supported: 2576** - 1200 Baud (default). Selected by sequence "*n". 2577** - 9600 Baud. Selected by sequence "*q". 2578** 2579** Selecting a sample rate is no longer supported with the MouseMan! 2580** [CHRIS-211092] 2581*/ 2582 2583/* 2584 * Do a reset wrap mode before reset. 2585 */ 2586#define do_ps2Reset(x) { \ 2587 int i = RETRY_COUNT;\ 2588 while (i-- > 0) { \ 2589 xf86FlushInput(x->fd); \ 2590 if (ps2Reset(x)) break; \ 2591 } \ 2592 } 2593 2594 2595static Bool 2596initMouseHW(InputInfoPtr pInfo) 2597{ 2598 MouseDevPtr pMse = pInfo->private; 2599 const char *s; 2600 unsigned char c; 2601 int speed; 2602 pointer options; 2603 unsigned char *param = NULL; 2604 int paramlen = 0; 2605 int count = RETRY_COUNT; 2606 Bool ps2Init = TRUE; 2607 2608 switch (pMse->protocolID) { 2609 case PROT_LOGI: /* Logitech Mice */ 2610 /* 2611 * The baud rate selection command must be sent at the current 2612 * baud rate; try all likely settings. 2613 */ 2614 speed = pMse->baudRate; 2615 switch (speed) { 2616 case 9600: 2617 s = "*q"; 2618 break; 2619 case 4800: 2620 s = "*p"; 2621 break; 2622 case 2400: 2623 s = "*o"; 2624 break; 2625 case 1200: 2626 s = "*n"; 2627 break; 2628 default: 2629 /* Fallback value */ 2630 speed = 1200; 2631 s = "*n"; 2632 } 2633 xf86SetSerialSpeed(pInfo->fd, 9600); 2634 xf86WriteSerial(pInfo->fd, s, 2); 2635 usleep(100000); 2636 xf86SetSerialSpeed(pInfo->fd, 4800); 2637 xf86WriteSerial(pInfo->fd, s, 2); 2638 usleep(100000); 2639 xf86SetSerialSpeed(pInfo->fd, 2400); 2640 xf86WriteSerial(pInfo->fd, s, 2); 2641 usleep(100000); 2642 xf86SetSerialSpeed(pInfo->fd, 1200); 2643 xf86WriteSerial(pInfo->fd, s, 2); 2644 usleep(100000); 2645 xf86SetSerialSpeed(pInfo->fd, speed); 2646 2647 /* Select MM series data format. */ 2648 xf86WriteSerial(pInfo->fd, "S", 1); 2649 usleep(100000); 2650 /* Set the parameters up for the MM series protocol. */ 2651 options = pInfo->options; 2652 xf86CollectInputOptions(pInfo, mmDefaults, NULL); 2653 xf86SetSerial(pInfo->fd, pInfo->options); 2654 pInfo->options = options; 2655 2656 /* Select report rate/frequency. */ 2657 if (pMse->sampleRate <= 0) c = 'O'; /* 100 */ 2658 else if (pMse->sampleRate <= 15) c = 'J'; /* 10 */ 2659 else if (pMse->sampleRate <= 27) c = 'K'; /* 20 */ 2660 else if (pMse->sampleRate <= 42) c = 'L'; /* 35 */ 2661 else if (pMse->sampleRate <= 60) c = 'R'; /* 50 */ 2662 else if (pMse->sampleRate <= 85) c = 'M'; /* 67 */ 2663 else if (pMse->sampleRate <= 125) c = 'Q'; /* 100 */ 2664 else c = 'N'; /* 150 */ 2665 xf86WriteSerial(pInfo->fd, &c, 1); 2666 break; 2667 2668 case PROT_LOGIMAN: 2669 speed = pMse->baudRate; 2670 switch (speed) { 2671 case 9600: 2672 s = "*q"; 2673 break; 2674 case 1200: 2675 s = "*n"; 2676 break; 2677 default: 2678 /* Fallback value */ 2679 speed = 1200; 2680 s = "*n"; 2681 } 2682 xf86SetSerialSpeed(pInfo->fd, 1200); 2683 xf86WriteSerial(pInfo->fd, "*n", 2); 2684 xf86WriteSerial(pInfo->fd, "*X", 2); 2685 xf86WriteSerial(pInfo->fd, s, 2); 2686 usleep(100000); 2687 xf86SetSerialSpeed(pInfo->fd, speed); 2688 break; 2689 2690 case PROT_MMHIT: /* MM_HitTablet */ 2691 /* 2692 * Initialize Hitachi PUMA Plus - Model 1212E to desired settings. 2693 * The tablet must be configured to be in MM mode, NO parity, 2694 * Binary Format. pMse->sampleRate controls the sensitivity 2695 * of the tablet. We only use this tablet for it's 4-button puck 2696 * so we don't run in "Absolute Mode". 2697 */ 2698 xf86WriteSerial(pInfo->fd, "z8", 2); /* Set Parity = "NONE" */ 2699 usleep(50000); 2700 xf86WriteSerial(pInfo->fd, "zb", 2); /* Set Format = "Binary" */ 2701 usleep(50000); 2702 xf86WriteSerial(pInfo->fd, "@", 1); /* Set Report Mode = "Stream" */ 2703 usleep(50000); 2704 xf86WriteSerial(pInfo->fd, "R", 1); /* Set Output Rate = "45 rps" */ 2705 usleep(50000); 2706 xf86WriteSerial(pInfo->fd, "I\x20", 2); /* Set Incrememtal Mode "20" */ 2707 usleep(50000); 2708 xf86WriteSerial(pInfo->fd, "E", 1); /* Set Data Type = "Relative */ 2709 usleep(50000); 2710 /* 2711 * These sample rates translate to 'lines per inch' on the Hitachi 2712 * tablet. 2713 */ 2714 if (pMse->sampleRate <= 40) c = 'g'; 2715 else if (pMse->sampleRate <= 100) c = 'd'; 2716 else if (pMse->sampleRate <= 200) c = 'e'; 2717 else if (pMse->sampleRate <= 500) c = 'h'; 2718 else if (pMse->sampleRate <= 1000) c = 'j'; 2719 else c = 'd'; 2720 xf86WriteSerial(pInfo->fd, &c, 1); 2721 usleep(50000); 2722 xf86WriteSerial(pInfo->fd, "\021", 1); /* Resume DATA output */ 2723 break; 2724 2725 case PROT_THINKING: /* ThinkingMouse */ 2726 /* This mouse may send a PnP ID string, ignore it. */ 2727 usleep(200000); 2728 xf86FlushInput(pInfo->fd); 2729 /* Send the command to initialize the beast. */ 2730 for (s = "E5E5"; *s; ++s) { 2731 xf86WriteSerial(pInfo->fd, s, 1); 2732 if ((xf86WaitForInput(pInfo->fd, 1000000) <= 0)) 2733 break; 2734 xf86ReadSerial(pInfo->fd, &c, 1); 2735 if (c != *s) 2736 break; 2737 } 2738 break; 2739 2740 case PROT_MSC: /* MouseSystems Corp */ 2741 usleep(100000); 2742 xf86FlushInput(pInfo->fd); 2743 break; 2744 2745 case PROT_ACECAD: 2746 /* initialize */ 2747 /* A nul character resets. */ 2748 xf86WriteSerial(pInfo->fd, "", 1); 2749 usleep(50000); 2750 /* Stream out relative mode high resolution increments of 1. */ 2751 xf86WriteSerial(pInfo->fd, "@EeI!", 5); 2752 break; 2753 2754 case PROT_BM: /* bus/InPort mouse */ 2755 if (osInfo->SetBMRes) 2756 osInfo->SetBMRes(pInfo, pMse->protocol, pMse->sampleRate, 2757 pMse->resolution); 2758 break; 2759 2760 case PROT_GENPS2: 2761 ps2Init = FALSE; 2762 break; 2763 2764 case PROT_PS2: 2765 case PROT_GLIDEPS2: 2766 break; 2767 2768 case PROT_IMPS2: /* IntelliMouse */ 2769 { 2770 static unsigned char seq[] = { 243, 200, 243, 100, 243, 80 }; 2771 param = seq; 2772 paramlen = sizeof(seq); 2773 } 2774 break; 2775 2776 case PROT_EXPPS2: /* IntelliMouse Explorer */ 2777 { 2778 static unsigned char seq[] = { 243, 200, 243, 100, 243, 80, 2779 243, 200, 243, 200, 243, 80 }; 2780 2781 param = seq; 2782 paramlen = sizeof(seq); 2783 } 2784 break; 2785 2786 case PROT_NETPS2: /* NetMouse, NetMouse Pro, Mie Mouse */ 2787 case PROT_NETSCPS2: /* NetScroll */ 2788 { 2789 static unsigned char seq[] = { 232, 3, 230, 230, 230, 233 }; 2790 2791 param = seq; 2792 paramlen = sizeof(seq); 2793 } 2794 break; 2795 2796 case PROT_MMPS2: /* MouseMan+, FirstMouse+ */ 2797 { 2798 static unsigned char seq[] = { 230, 232, 0, 232, 3, 232, 2, 232, 1, 2799 230, 232, 3, 232, 1, 232, 2, 232, 3 }; 2800 param = seq; 2801 paramlen = sizeof(seq); 2802 } 2803 break; 2804 2805 case PROT_THINKPS2: /* ThinkingMouse */ 2806 { 2807 static unsigned char seq[] = { 243, 10, 232, 0, 243, 20, 243, 60, 2808 243, 40, 243, 20, 243, 20, 243, 60, 2809 243, 40, 243, 20, 243, 20 }; 2810 param = seq; 2811 paramlen = sizeof(seq); 2812 } 2813 break; 2814 case PROT_SYSMOUSE: 2815 if (osInfo->SetMiscRes) 2816 osInfo->SetMiscRes(pInfo, pMse->protocol, pMse->sampleRate, 2817 pMse->resolution); 2818 break; 2819 2820 default: 2821 /* Nothing to do. */ 2822 break; 2823 } 2824 2825 if (pMse->class & (MSE_PS2 | MSE_XPS2)) { 2826 /* 2827 * If one part of the PS/2 mouse initialization fails 2828 * redo complete initialization. There are mice which 2829 * have occasional problems with initialization and 2830 * are in an unknown state. 2831 */ 2832 if (ps2Init) { 2833 REDO: 2834 do_ps2Reset(pInfo); 2835 if (paramlen > 0) { 2836 if (!ps2SendPacket(pInfo,param,paramlen)) { 2837 usleep(30000); 2838 xf86FlushInput(pInfo->fd); 2839 if (!count--) 2840 return TRUE; 2841 goto REDO; 2842 } 2843 ps2GetDeviceID(pInfo); 2844 usleep(30000); 2845 xf86FlushInput(pInfo->fd); 2846 } 2847 2848 if (osInfo->SetPS2Res) { 2849 osInfo->SetPS2Res(pInfo, pMse->protocol, pMse->sampleRate, 2850 pMse->resolution); 2851 } else { 2852 unsigned char c2[2]; 2853 2854 c = 0xE6; /*230*/ /* 1:1 scaling */ 2855 if (!ps2SendPacket(pInfo,&c,1)) { 2856 if (!count--) 2857 return TRUE; 2858 goto REDO; 2859 } 2860 c2[0] = 0xF3; /*243*/ /* set sampling rate */ 2861 if (pMse->sampleRate > 0) { 2862 if (pMse->sampleRate >= 200) 2863 c2[1] = 200; 2864 else if (pMse->sampleRate >= 100) 2865 c2[1] = 100; 2866 else if (pMse->sampleRate >= 80) 2867 c2[1] = 80; 2868 else if (pMse->sampleRate >= 60) 2869 c2[1] = 60; 2870 else if (pMse->sampleRate >= 40) 2871 c2[1] = 40; 2872 else 2873 c2[1] = 20; 2874 } else { 2875 c2[1] = 100; 2876 } 2877 if (!ps2SendPacket(pInfo,c2,2)) { 2878 if (!count--) 2879 return TRUE; 2880 goto REDO; 2881 } 2882 c2[0] = 0xE8; /*232*/ /* set device resolution */ 2883 if (pMse->resolution > 0) { 2884 if (pMse->resolution >= 200) 2885 c2[1] = 3; 2886 else if (pMse->resolution >= 100) 2887 c2[1] = 2; 2888 else if (pMse->resolution >= 50) 2889 c2[1] = 1; 2890 else 2891 c2[1] = 0; 2892 } else { 2893 c2[1] = 3; /* used to be 2, W. uses 3 */ 2894 } 2895 if (!ps2SendPacket(pInfo,c2,2)) { 2896 if (!count--) 2897 return TRUE; 2898 goto REDO; 2899 } 2900 usleep(30000); 2901 xf86FlushInput(pInfo->fd); 2902 if (!ps2EnableDataReporting(pInfo)) { 2903 xf86Msg(X_INFO, "%s: ps2EnableDataReporting: failed\n", 2904 pInfo->name); 2905 xf86FlushInput(pInfo->fd); 2906 if (!count--) 2907 return TRUE; 2908 goto REDO; 2909 } else { 2910 xf86Msg(X_INFO, "%s: ps2EnableDataReporting: succeeded\n", 2911 pInfo->name); 2912 } 2913 } 2914 /* 2915 * The PS/2 reset handling needs to be rechecked. 2916 * We need to wait until after the 4.3 release. 2917 */ 2918 } 2919 } else { 2920 if (paramlen > 0) { 2921 if (xf86WriteSerial(pInfo->fd, param, paramlen) != paramlen) 2922 xf86Msg(X_ERROR, "%s: Mouse initialization failed\n", 2923 pInfo->name); 2924 usleep(30000); 2925 xf86FlushInput(pInfo->fd); 2926 } 2927 } 2928 2929 return TRUE; 2930} 2931 2932#ifdef SUPPORT_MOUSE_RESET 2933static Bool 2934mouseReset(InputInfoPtr pInfo, unsigned char val) 2935{ 2936 MouseDevPtr pMse = pInfo->private; 2937 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 2938 CARD32 prevEvent = mousepriv->lastEvent; 2939 Bool expectReset = FALSE; 2940 Bool ret = FALSE; 2941 2942 mousepriv->lastEvent = GetTimeInMillis(); 2943 2944#ifdef EXTMOUSEDEBUG 2945 ErrorF("byte: 0x%x time: %li\n",val,mousepriv->lastEvent); 2946#endif 2947 /* 2948 * We believe that the following is true: 2949 * When the mouse is replugged it will send a reset package 2950 * It takes several seconds to replug a mouse: We don't see 2951 * events for several seconds before we see the replug event package. 2952 * There is no significant delay between consecutive bytes 2953 * of a replug event package. 2954 * There are no bytes sent after the replug event package until 2955 * the mouse is reset. 2956 */ 2957 2958 if (mousepriv->current == 0 2959 && (mousepriv->lastEvent - prevEvent) < 4000) 2960 return FALSE; 2961 2962 if (mousepriv->current > 0 2963 && (mousepriv->lastEvent - prevEvent) >= 1000) { 2964 mousepriv->inReset = FALSE; 2965 mousepriv->current = 0; 2966 return FALSE; 2967 } 2968 2969 if (mousepriv->inReset) 2970 mousepriv->inReset = FALSE; 2971 2972#ifdef EXTMOUSEDEBUG 2973 ErrorF("Mouse Current: %i 0x%x\n",mousepriv->current, val); 2974#endif 2975 2976 /* here we put the mouse specific reset detection */ 2977 /* They need to do three things: */ 2978 /* Check if byte may be a reset byte */ 2979 /* If so: Set expectReset TRUE */ 2980 /* If convinced: Set inReset TRUE */ 2981 /* Register BlockAndWakeupHandler */ 2982 2983 /* PS/2 */ 2984 { 2985 unsigned char seq[] = { 0xaa, 0x00 }; 2986 int len = sizeof(seq); 2987 2988 if (seq[mousepriv->current] == val) 2989 expectReset = TRUE; 2990 2991 if (len == mousepriv->current + 1) { 2992 mousepriv->inReset = TRUE; 2993 mousepriv->expires = GetTimeInMillis() + 1000; 2994 2995#ifdef EXTMOUSEDEBUG 2996 ErrorF("Found PS/2 Reset string\n"); 2997#endif 2998 RegisterBlockAndWakeupHandlers (ps2BlockHandler, 2999 ps2WakeupHandler, (pointer) pInfo); 3000 ret = TRUE; 3001 } 3002 } 3003 3004 if (!expectReset) 3005 mousepriv->current = 0; 3006 else 3007 mousepriv->current++; 3008 return ret; 3009} 3010 3011static void 3012ps2BlockHandler(pointer data, struct timeval **waitTime, 3013 pointer LastSelectMask) 3014{ 3015 InputInfoPtr pInfo = (InputInfoPtr) data; 3016 MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 3017 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 3018 int ms; 3019 3020 if (mousepriv->inReset) { 3021 ms = mousepriv->expires - GetTimeInMillis (); 3022 if (ms <= 0) 3023 ms = 0; 3024 AdjustWaitForDelay (waitTime, ms); 3025 } else 3026 RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler, 3027 (pointer) pInfo); 3028} 3029 3030static void 3031ps2WakeupHandler(pointer data, int i, pointer LastSelectMask) 3032{ 3033 InputInfoPtr pInfo = (InputInfoPtr) data; 3034 MouseDevPtr pMse = (MouseDevPtr) pInfo->private; 3035 mousePrivPtr mousepriv = (mousePrivPtr)pMse->mousePriv; 3036 int ms; 3037 3038 if (mousepriv->inReset) { 3039 unsigned char val; 3040 int blocked; 3041 3042 ms = mousepriv->expires - GetTimeInMillis(); 3043 if (ms > 0) 3044 return; 3045 3046 blocked = xf86BlockSIGIO (); 3047 3048 xf86MsgVerb(X_INFO,3, 3049 "Got reinsert event: reinitializing PS/2 mouse\n"); 3050 val = 0xf4; 3051 if (xf86WriteSerial(pInfo->fd, &val, 1) != 1) 3052 xf86Msg(X_ERROR, "%s: Write to mouse failed\n", 3053 pInfo->name); 3054 xf86UnblockSIGIO(blocked); 3055 } 3056 RemoveBlockAndWakeupHandlers (ps2BlockHandler, ps2WakeupHandler, 3057 (pointer) pInfo); 3058} 3059#endif /* SUPPORT_MOUSE_RESET */ 3060 3061/************************************************************ 3062 * 3063 * Autoprobe stuff 3064 * 3065 ************************************************************/ 3066#ifdef EXTMOUSEDEBUG 3067# define AP_DBG(x) { ErrorF("Autoprobe: "); ErrorF x; } 3068# define AP_DBGC(x) ErrorF x ; 3069# else 3070# define AP_DBG(x) 3071# define AP_DBGC(x) 3072#endif 3073 3074static 3075MouseProtocolID hardProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI, 3076 PROT_LOGIMAN, PROT_MMHIT, 3077 PROT_GLIDE, PROT_IMSERIAL, 3078 PROT_THINKING, PROT_ACECAD, 3079 PROT_THINKPS2, PROT_MMPS2, 3080 PROT_GLIDEPS2, 3081 PROT_NETSCPS2, PROT_EXPPS2,PROT_IMPS2, 3082 PROT_GENPS2, PROT_NETPS2, 3083 PROT_MS, 3084 PROT_UNKNOWN 3085}; 3086 3087static 3088MouseProtocolID softProtocolList[] = { PROT_MSC, PROT_MM, PROT_LOGI, 3089 PROT_LOGIMAN, PROT_MMHIT, 3090 PROT_GLIDE, PROT_IMSERIAL, 3091 PROT_THINKING, PROT_ACECAD, 3092 PROT_THINKPS2, PROT_MMPS2, 3093 PROT_GLIDEPS2, 3094 PROT_NETSCPS2 ,PROT_IMPS2, 3095 PROT_GENPS2, 3096 PROT_MS, 3097 PROT_UNKNOWN 3098}; 3099 3100static const char * 3101autoOSProtocol(InputInfoPtr pInfo, int *protoPara) 3102{ 3103 MouseDevPtr pMse = pInfo->private; 3104 const char *name = NULL; 3105 MouseProtocolID protocolID = PROT_UNKNOWN; 3106 3107 /* Check if the OS has a detection mechanism. */ 3108 if (osInfo->SetupAuto) { 3109 name = osInfo->SetupAuto(pInfo, protoPara); 3110 if (name) { 3111 protocolID = ProtocolNameToID(name); 3112 switch (protocolID) { 3113 case PROT_UNKNOWN: 3114 /* Check for a builtin OS-specific protocol. */ 3115 if (osInfo->CheckProtocol && osInfo->CheckProtocol(name)) { 3116 /* We can only come here if the protocol has been 3117 * changed to auto thru the xf86misc extension 3118 * and we have detected an OS specific builtin 3119 * protocol. Currently we cannot handle this */ 3120 name = NULL; 3121 } else 3122 name = NULL; 3123 break; 3124 case PROT_UNSUP: 3125 name = NULL; 3126 break; 3127 default: 3128 break; 3129 } 3130 } 3131 } 3132 if (!name) { 3133 /* A PnP serial mouse? */ 3134 protocolID = MouseGetPnpProtocol(pInfo); 3135 if (protocolID >= 0 && protocolID < PROT_NUMPROTOS) { 3136 name = ProtocolIDToName(protocolID); 3137 xf86Msg(X_PROBED, "%s: PnP-detected protocol: \"%s\"\n", 3138 pInfo->name, name); 3139 } 3140 } 3141 if (!name && osInfo->GuessProtocol) { 3142 name = osInfo->GuessProtocol(pInfo, 0); 3143 if (name) 3144 protocolID = ProtocolNameToID(name); 3145 } 3146 3147 if (name) { 3148 pMse->protocolID = protocolID; 3149 } 3150 3151 return name; 3152} 3153 3154/* 3155 * createProtocolList() -- create a list of protocols which may 3156 * match on the incoming data stream. 3157 */ 3158static void 3159createProtoList(MouseDevPtr pMse, MouseProtocolID *protoList) 3160{ 3161 int i, j, k = 0; 3162 MouseProtocolID prot; 3163 unsigned char *para; 3164 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3165 MouseProtocolID *tmplist = NULL; 3166 int blocked; 3167 3168 AP_DBGC(("Autoprobe: ")); 3169 for (i = 0; i < mPriv->count; i++) 3170 AP_DBGC(("%2.2x ", (unsigned char) mPriv->data[i])); 3171 AP_DBGC(("\n")); 3172 3173 blocked = xf86BlockSIGIO (); 3174 3175 /* create a private copy first so we can write in the old list */ 3176 if ((tmplist = xalloc(sizeof(MouseProtocolID) * NUM_AUTOPROBE_PROTOS))){ 3177 for (i = 0; protoList[i] != PROT_UNKNOWN; i++) { 3178 tmplist[i] = protoList[i]; 3179 } 3180 tmplist[i] = PROT_UNKNOWN; 3181 protoList = tmplist; 3182 } else 3183 return; 3184 3185 for (i = 0; ((prot = protoList[i]) != PROT_UNKNOWN 3186 && (k < NUM_AUTOPROBE_PROTOS - 1)) ; i++) { 3187 Bool bad = TRUE; 3188 unsigned char byte = 0; 3189 int count = 0; 3190 int next_header_candidate = 0; 3191 int header_count = 0; 3192 3193 if (!GetProtocol(prot)) 3194 continue; 3195 para = proto[prot]; 3196 3197 AP_DBG(("Protocol: %s ", ProtocolIDToName(prot))); 3198 3199#ifdef EXTMOUSEDEBUG 3200 for (j = 0; j < 7; j++) 3201 AP_DBGC(("%2.2x ", (unsigned char) para[j])); 3202 AP_DBGC(("\n")); 3203#endif 3204 j = 0; 3205 while (1) { 3206 /* look for header */ 3207 while (j < mPriv->count) { 3208 if (((byte = mPriv->data[j++]) & para[0]) == para[1]){ 3209 AP_DBG(("found header %2.2x\n",byte)); 3210 next_header_candidate = j; 3211 count = 1; 3212 break; 3213 } else { 3214 /* 3215 * Bail out if number of bytes per package have 3216 * been tested for header. 3217 * Take bytes per package of leading garbage into 3218 * account. 3219 */ 3220 if (j > para[4] && ++header_count > para[4]) { 3221 j = mPriv->count; 3222 break; 3223 } 3224 } 3225 } 3226 /* check if remaining data matches protocol */ 3227 while (j < mPriv->count) { 3228 byte = mPriv->data[j++]; 3229 if (count == para[4]) { 3230 count = 0; 3231 /* check and eat excess byte */ 3232 if (((byte & para[0]) != para[1]) 3233 && ((byte & para[5]) == para[6])) { 3234 AP_DBG(("excess byte found\n")); 3235 continue; 3236 } 3237 } 3238 if (count == 0) { 3239 /* validate next header */ 3240 bad = FALSE; 3241 AP_DBG(("Complete set found\n")); 3242 if ((byte & para[0]) != para[1]) { 3243 AP_DBG(("Autoprobe: header bad\n")); 3244 bad = TRUE; 3245 break; 3246 } else { 3247 count++; 3248 continue; 3249 } 3250 } 3251 /* validate data */ 3252 else if (((byte & para[2]) != para[3]) 3253 || ((para[7] & MPF_SAFE) 3254 && ((byte & para[0]) == para[1]))) { 3255 AP_DBG(("data bad\n")); 3256 bad = TRUE; 3257 break; 3258 } else { 3259 count ++; 3260 continue; 3261 } 3262 } 3263 if (!bad) { 3264 /* this is a matching protocol */ 3265 mPriv->protoList[k++] = prot; 3266 AP_DBG(("Autoprobe: Adding protocol %s to list (entry %i)\n", 3267 ProtocolIDToName(prot),k-1)); 3268 break; 3269 } 3270 j = next_header_candidate; 3271 next_header_candidate = 0; 3272 /* we have tested number of bytes per package for header */ 3273 if (j > para[4] && ++header_count > para[4]) 3274 break; 3275 /* we have not found anything that looks like a header */ 3276 if (!next_header_candidate) 3277 break; 3278 AP_DBG(("Looking for new header\n")); 3279 } 3280 } 3281 3282 xf86UnblockSIGIO(blocked); 3283 3284 mPriv->protoList[k] = PROT_UNKNOWN; 3285 3286 xfree(tmplist); 3287} 3288 3289 3290/* This only needs to be done once */ 3291static void **serialDefaultsList = NULL; 3292 3293/* 3294 * createSerialDefaultsLists() - create a list of the different default 3295 * settings for the serial interface of the known protocols. 3296 */ 3297static void 3298createSerialDefaultsList(void) 3299{ 3300 int i = 0, j, k; 3301 3302 serialDefaultsList = (void **)xnfalloc(sizeof(void*)); 3303 serialDefaultsList[0] = NULL; 3304 3305 for (j = 0; mouseProtocols[j].name; j++) { 3306 if (!mouseProtocols[j].defaults) 3307 continue; 3308 for (k = 0; k < i; k++) 3309 if (mouseProtocols[j].defaults == serialDefaultsList[k]) 3310 continue; 3311 i++; 3312 serialDefaultsList = (void**)xnfrealloc(serialDefaultsList, 3313 sizeof(void*)*(i+1)); 3314 serialDefaultsList[i-1] = mouseProtocols[j].defaults; 3315 serialDefaultsList[i] = NULL; 3316 } 3317} 3318 3319typedef enum { 3320 STATE_INVALID, 3321 STATE_UNCERTAIN, 3322 STATE_VALID 3323} validState; 3324 3325/* Probing threshold values */ 3326#define PROBE_UNCERTAINTY 50 3327#define BAD_CERTAINTY 6 3328#define BAD_INC_CERTAINTY 1 3329#define BAD_INC_CERTAINTY_WHEN_SYNC_LOST 2 3330 3331static validState 3332validCount(mousePrivPtr mPriv, Bool inSync, Bool lostSync) 3333{ 3334 if (inSync) { 3335 if (!--mPriv->goodCount) { 3336 /* we are sure to have found the correct protocol */ 3337 mPriv->badCount = 0; 3338 return STATE_VALID; 3339 } 3340 AP_DBG(("%i successful rounds to go\n", 3341 mPriv->goodCount)); 3342 return STATE_UNCERTAIN; 3343 } 3344 3345 3346 /* We are out of sync again */ 3347 mPriv->goodCount = PROBE_UNCERTAINTY; 3348 /* We increase uncertainty of having the correct protocol */ 3349 mPriv->badCount+= lostSync ? BAD_INC_CERTAINTY_WHEN_SYNC_LOST 3350 : BAD_INC_CERTAINTY; 3351 3352 if (mPriv->badCount < BAD_CERTAINTY) { 3353 /* We are not convinced yet to have the wrong protocol */ 3354 AP_DBG(("Changing protocol after: %i rounds\n", 3355 BAD_CERTAINTY - mPriv->badCount)); 3356 return STATE_UNCERTAIN; 3357 } 3358 return STATE_INVALID; 3359} 3360 3361#define RESET_VALIDATION mPriv->goodCount = PROBE_UNCERTAINTY;\ 3362 mPriv->badCount = 0;\ 3363 mPriv->prevDx = 0;\ 3364 mPriv->prevDy = 0;\ 3365 mPriv->accDx = 0;\ 3366 mPriv->accDy = 0;\ 3367 mPriv->acc = 0; 3368 3369static void 3370autoProbeMouse(InputInfoPtr pInfo, Bool inSync, Bool lostSync) 3371{ 3372 MouseDevPtr pMse = pInfo->private; 3373 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3374 3375 MouseProtocolID *protocolList = NULL; 3376 3377 while (1) { 3378 switch (mPriv->autoState) { 3379 case AUTOPROBE_GOOD: 3380 if (inSync) 3381 return; 3382 AP_DBG(("State GOOD\n")); 3383 RESET_VALIDATION; 3384 mPriv->autoState = AUTOPROBE_VALIDATE1; 3385 return; 3386 case AUTOPROBE_H_GOOD: 3387 if (inSync) 3388 return; 3389 AP_DBG(("State H_GOOD\n")); 3390 RESET_VALIDATION; 3391 mPriv->autoState = AUTOPROBE_H_VALIDATE2; 3392 return; 3393 case AUTOPROBE_H_NOPROTO: 3394 AP_DBG(("State H_NOPROTO\n")); 3395 mPriv->protocolID = 0; 3396 mPriv->autoState = AUTOPROBE_H_SETPROTO; 3397 break; 3398 case AUTOPROBE_H_SETPROTO: 3399 AP_DBG(("State H_SETPROTO\n")); 3400 if ((pMse->protocolID = hardProtocolList[mPriv->protocolID++]) 3401 == PROT_UNKNOWN) { 3402 mPriv->protocolID = 0; 3403 break; 3404 } else if (GetProtocol(pMse->protocolID) && SetupMouse(pInfo)) { 3405 FlushButtons(pMse); 3406 RESET_VALIDATION; 3407 AP_DBG(("Autoprobe: Trying Protocol: %s\n", 3408 ProtocolIDToName(pMse->protocolID))); 3409 mPriv->autoState = AUTOPROBE_H_VALIDATE1; 3410 return; 3411 } 3412 break; 3413 case AUTOPROBE_H_VALIDATE1: 3414 AP_DBG(("State H_VALIDATE1\n")); 3415 switch (validCount(mPriv,inSync,lostSync)) { 3416 case STATE_INVALID: 3417 mPriv->autoState = AUTOPROBE_H_SETPROTO; 3418 break; 3419 case STATE_VALID: 3420 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3421 ProtocolIDToName(pMse->protocolID)); 3422 mPriv->autoState = AUTOPROBE_H_GOOD; 3423 return; 3424 case STATE_UNCERTAIN: 3425 return; 3426 default: 3427 break; 3428 } 3429 break; 3430 case AUTOPROBE_H_VALIDATE2: 3431 AP_DBG(("State H_VALIDATE2\n")); 3432 switch (validCount(mPriv,inSync,lostSync)) { 3433 case STATE_INVALID: 3434 mPriv->autoState = AUTOPROBE_H_AUTODETECT; 3435 break; 3436 case STATE_VALID: 3437 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3438 ProtocolIDToName(pMse->protocolID)); 3439 mPriv->autoState = AUTOPROBE_H_GOOD; 3440 return; 3441 case STATE_UNCERTAIN: 3442 return; 3443 } 3444 break; 3445 case AUTOPROBE_H_AUTODETECT: 3446 AP_DBG(("State H_AUTODETECT\n")); 3447 pMse->protocolID = PROT_AUTO; 3448 AP_DBG(("Looking for PnP/OS mouse\n")); 3449 mPriv->count = 0; 3450 SetupMouse(pInfo); 3451 if (pMse->protocolID != PROT_AUTO) 3452 mPriv->autoState = AUTOPROBE_H_GOOD; 3453 else 3454 mPriv->autoState = AUTOPROBE_H_NOPROTO; 3455 break; 3456 case AUTOPROBE_NOPROTO: 3457 AP_DBG(("State NOPROTO\n")); 3458 mPriv->count = 0; 3459 mPriv->serialDefaultsNum = -1; 3460 mPriv->autoState = AUTOPROBE_COLLECT; 3461 break; 3462 case AUTOPROBE_COLLECT: 3463 AP_DBG(("State COLLECT\n")); 3464 if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES) 3465 return; 3466 protocolList = softProtocolList; 3467 mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST; 3468 break; 3469 case AUTOPROBE_CREATE_PROTOLIST: 3470 AP_DBG(("State CREATE_PROTOLIST\n")); 3471 createProtoList(pMse, protocolList); 3472 mPriv->protocolID = 0; 3473 mPriv->autoState = AUTOPROBE_SWITCH_PROTOCOL; 3474 break; 3475 case AUTOPROBE_AUTODETECT: 3476 AP_DBG(("State AUTODETECT\n")); 3477 pMse->protocolID = PROT_AUTO; 3478 AP_DBG(("Looking for PnP/OS mouse\n")); 3479 mPriv->count = 0; 3480 SetupMouse(pInfo); 3481 if (pMse->protocolID != PROT_AUTO) 3482 mPriv->autoState = AUTOPROBE_GOOD; 3483 else 3484 mPriv->autoState = AUTOPROBE_NOPROTO; 3485 break; 3486 case AUTOPROBE_VALIDATE1: 3487 AP_DBG(("State VALIDATE1\n")); 3488 switch (validCount(mPriv,inSync,lostSync)) { 3489 case STATE_INVALID: 3490 mPriv->autoState = AUTOPROBE_AUTODETECT; 3491 break; 3492 case STATE_VALID: 3493 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3494 ProtocolIDToName(pMse->protocolID)); 3495 mPriv->autoState = AUTOPROBE_GOOD; 3496 break; 3497 case STATE_UNCERTAIN: 3498 return; 3499 } 3500 break; 3501 case AUTOPROBE_VALIDATE2: 3502 AP_DBG(("State VALIDATE2\n")); 3503 switch (validCount(mPriv,inSync,lostSync)) { 3504 case STATE_INVALID: 3505 protocolList = &mPriv->protoList[mPriv->protocolID]; 3506 mPriv->autoState = AUTOPROBE_CREATE_PROTOLIST; 3507 break; 3508 case STATE_VALID: 3509 xf86Msg(X_INFO,"Mouse autoprobe: selecting %s protocol\n", 3510 ProtocolIDToName(pMse->protocolID)); 3511 mPriv->autoState = AUTOPROBE_GOOD; 3512 break; 3513 case STATE_UNCERTAIN: 3514 return; 3515 } 3516 break; 3517 case AUTOPROBE_SWITCHSERIAL: 3518 { 3519 pointer serialDefaults; 3520 AP_DBG(("State SWITCHSERIAL\n")); 3521 3522 if (!serialDefaultsList) 3523 createSerialDefaultsList(); 3524 3525 AP_DBG(("Switching serial params\n")); 3526 if ((serialDefaults = 3527 serialDefaultsList[++mPriv->serialDefaultsNum]) == NULL) { 3528 mPriv->serialDefaultsNum = 0; 3529 } else { 3530 pointer tmp = xf86OptionListCreate(serialDefaults, -1, 0); 3531 xf86SetSerial(pInfo->fd, tmp); 3532 xf86OptionListFree(tmp); 3533 mPriv->count = 0; 3534 mPriv->autoState = AUTOPROBE_COLLECT; 3535 } 3536 break; 3537 } 3538 case AUTOPROBE_SWITCH_PROTOCOL: 3539 { 3540 MouseProtocolID proto; 3541 void *defaults; 3542 AP_DBG(("State SWITCH_PROTOCOL\n")); 3543 proto = mPriv->protoList[mPriv->protocolID++]; 3544 if (proto == PROT_UNKNOWN) 3545 mPriv->autoState = AUTOPROBE_SWITCHSERIAL; 3546 else if (!(defaults = GetProtocol(proto)->defaults) 3547 || (mPriv->serialDefaultsNum == -1 3548 && (defaults == msDefaults)) 3549 || (mPriv->serialDefaultsNum != -1 3550 && serialDefaultsList[mPriv->serialDefaultsNum] 3551 == defaults)) { 3552 AP_DBG(("Changing Protocol to %s\n", 3553 ProtocolIDToName(proto))); 3554 SetMouseProto(pMse,proto); 3555 FlushButtons(pMse); 3556 RESET_VALIDATION; 3557 mPriv->autoState = AUTOPROBE_VALIDATE2; 3558 return; 3559 } 3560 break; 3561 } 3562 } 3563 } 3564} 3565 3566static Bool 3567autoGood(MouseDevPtr pMse) 3568{ 3569 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3570 3571 if (!pMse->autoProbe) 3572 return TRUE; 3573 3574 switch (mPriv->autoState) { 3575 case AUTOPROBE_GOOD: 3576 case AUTOPROBE_H_GOOD: 3577 return TRUE; 3578 case AUTOPROBE_VALIDATE1: /* @@@ */ 3579 case AUTOPROBE_H_VALIDATE1: /* @@@ */ 3580 case AUTOPROBE_VALIDATE2: 3581 case AUTOPROBE_H_VALIDATE2: 3582 if (mPriv->goodCount < PROBE_UNCERTAINTY/2) 3583 return TRUE; 3584 default: 3585 return FALSE; 3586 } 3587} 3588 3589 3590#define TOT_THRESHOLD 3000 3591#define VAL_THRESHOLD 40 3592 3593/* 3594 * checkForErraticMovements() -- check if mouse 'jumps around'. 3595 */ 3596static void 3597checkForErraticMovements(InputInfoPtr pInfo, int dx, int dy) 3598{ 3599 MouseDevPtr pMse = pInfo->private; 3600 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3601 3602 if (!mPriv->goodCount) 3603 return; 3604 3605#if 0 3606 if (abs(dx - mPriv->prevDx) > 300 3607 || abs(dy - mPriv->prevDy) > 300) 3608 AP_DBG(("erratic1 behaviour\n")); 3609#endif 3610 if (abs(dx) > VAL_THRESHOLD) { 3611 if (sign(dx) == sign(mPriv->prevDx)) { 3612 mPriv->accDx += dx; 3613 if (abs(mPriv->accDx) > mPriv->acc) { 3614 mPriv->acc = abs(mPriv->accDx); 3615 AP_DBG(("acc=%i\n",mPriv->acc)); 3616 } 3617 else 3618 AP_DBG(("accDx=%i\n",mPriv->accDx)); 3619 } else { 3620 mPriv->accDx = 0; 3621 } 3622 } 3623 3624 if (abs(dy) > VAL_THRESHOLD) { 3625 if (sign(dy) == sign(mPriv->prevDy)) { 3626 mPriv->accDy += dy; 3627 if (abs(mPriv->accDy) > mPriv->acc) { 3628 mPriv->acc = abs(mPriv->accDy); 3629 AP_DBG(("acc: %i\n",mPriv->acc)); 3630 } else 3631 AP_DBG(("accDy=%i\n",mPriv->accDy)); 3632 } else { 3633 mPriv->accDy = 0; 3634 } 3635 } 3636 mPriv->prevDx = dx; 3637 mPriv->prevDy = dy; 3638 if (mPriv->acc > TOT_THRESHOLD) { 3639 mPriv->goodCount = PROBE_UNCERTAINTY; 3640 mPriv->prevDx = 0; 3641 mPriv->prevDy = 0; 3642 mPriv->accDx = 0; 3643 mPriv->accDy = 0; 3644 mPriv->acc = 0; 3645 AP_DBG(("erratic2 behaviour\n")); 3646 autoProbeMouse(pInfo, FALSE,TRUE); 3647 } 3648} 3649 3650static void 3651SetMouseProto(MouseDevPtr pMse, MouseProtocolID protocolID) 3652{ 3653 pMse->protocolID = protocolID; 3654 pMse->protocol = ProtocolIDToName(pMse->protocolID); 3655 pMse->class = ProtocolIDToClass(pMse->protocolID); 3656 if ((pMse->protocolID >= 0) && (pMse->protocolID < PROT_NUMPROTOS)) 3657 memcpy(pMse->protoPara, proto[pMse->protocolID], 3658 sizeof(pMse->protoPara)); 3659 3660 if (pMse->emulate3ButtonsSoft) 3661 pMse->emulate3Buttons = TRUE; 3662} 3663 3664/* 3665 * collectData() -- collect data bytes sent by mouse. 3666 */ 3667static Bool 3668collectData(MouseDevPtr pMse, unsigned char u) 3669{ 3670 mousePrivPtr mPriv = (mousePrivPtr)pMse->mousePriv; 3671 if (mPriv->count < NUM_MSE_AUTOPROBE_TOTAL) { 3672 mPriv->data[mPriv->count++] = u; 3673 if (mPriv->count <= NUM_MSE_AUTOPROBE_BYTES) { 3674 return TRUE; 3675 } 3676 } 3677 return FALSE; 3678} 3679 3680/**************** end of autoprobe stuff *****************/ 3681 3682 3683static void 3684xf86MouseUnplug(pointer p) 3685{ 3686} 3687static pointer 3688xf86MousePlug(pointer module, 3689 pointer options, 3690 int *errmaj, 3691 int *errmin) 3692{ 3693 static Bool Initialised = FALSE; 3694 3695 if (!Initialised) 3696 Initialised = TRUE; 3697 3698 xf86AddInputDriver(&MOUSE, module, 0); 3699 3700 return module; 3701} 3702 3703static XF86ModuleVersionInfo xf86MouseVersionRec = 3704{ 3705 "mouse", 3706 MODULEVENDORSTRING, 3707 MODINFOSTRING1, 3708 MODINFOSTRING2, 3709 XORG_VERSION_CURRENT, 3710 PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, 3711 ABI_CLASS_XINPUT, 3712 ABI_XINPUT_VERSION, 3713 MOD_CLASS_XINPUT, 3714 {0, 0, 0, 0} /* signature, to be patched into the file by */ 3715 /* a tool */ 3716}; 3717 3718_X_EXPORT XF86ModuleData mouseModuleData = { 3719 &xf86MouseVersionRec, 3720 xf86MousePlug, 3721 xf86MouseUnplug 3722}; 3723 3724/* 3725 Look at hitachi device stuff. 3726*/ 3727