Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

965 lines
22 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Copyright (c) 1993 Logitech Inc.
  4. Module Name:
  5. mseries.c
  6. Abstract:
  7. Environment:
  8. Kernel mode only.
  9. Notes:
  10. Revision History:
  11. --*/
  12. //
  13. // Includes.
  14. //
  15. #include "ntddk.h"
  16. #include "uart.h"
  17. #include "sermouse.h"
  18. #include "debug.h"
  19. #include "cseries.h"
  20. #include "mseries.h"
  21. //
  22. // Use the alloc_text pragma to specify the driver initialization routines
  23. // (they can be paged out).
  24. //
  25. #ifdef ALLOC_PRAGMA
  26. #pragma alloc_text(INIT,MSerSetProtocol)
  27. #pragma alloc_text(INIT,MSerPowerUp)
  28. #pragma alloc_text(INIT,MSerPowerDown)
  29. #pragma alloc_text(INIT,MSerReset)
  30. #pragma alloc_text(INIT,MSerDetect)
  31. #endif // ALLOC_PRAGMA
  32. //
  33. // Constants.
  34. //
  35. #define MSER_BAUDRATE 1200
  36. #define MAX_RESET_BUFFER 8
  37. #define MINIMUM_RESET_TIME 200
  38. //
  39. // Microsoft Plus.
  40. //
  41. #define MP_SYNCH_BIT 0x40
  42. #define MP_BUTTON_LEFT 0x20
  43. #define MP_BUTTON_RIGHT 0x10
  44. #define MP_BUTTON_MIDDLE 0x20
  45. #define MP_BUTTON_LEFT_SR 5
  46. #define MP_BUTTON_RIGHT_SR 3
  47. #define MP_BUTTON_MIDDLE_SR 3
  48. #define MP_BUTTON_MIDDLE_MASK 0x04
  49. #define MP_UPPER_MASKX 0x03
  50. #define MP_UPPER_MASKY 0x0C
  51. #define MP_UPPER_MASKX_SL 6
  52. #define MP_UPPER_MASKY_SL 4
  53. //
  54. // Microsoft BallPoint.
  55. //
  56. #define BP_SYNCH_BIT 0x40
  57. #define BP_BUTTON_LEFT 0x20
  58. #define BP_BUTTON_RIGHT 0x10
  59. #define BP_BUTTON_3 0x04
  60. #define BP_BUTTON_4 0x08
  61. #define BP_BUTTON_LEFT_SR 5
  62. #define BP_BUTTON_RIGHT_SR 3
  63. #define BP_BUTTON_3_SL 0
  64. #define BP_BUTTON_4_SL 0
  65. #define BP_UPPER_MASKX 0x03
  66. #define BP_UPPER_MASKY 0x0C
  67. #define BP_UPPER_MASKX_SL 6
  68. #define BP_UPPER_MASKY_SL 4
  69. #define BP_SIGN_MASKX 0x01
  70. #define BP_SIGN_MASKY 0x02
  71. //
  72. // Microsoft Magellan Mouse.
  73. //
  74. #define Z_SYNCH_BIT 0x40
  75. #define Z_EXTRA_BIT 0x20
  76. #define Z_BUTTON_LEFT 0x20
  77. #define Z_BUTTON_RIGHT 0x10
  78. #define Z_BUTTON_MIDDLE 0x10
  79. #define Z_BUTTON_LEFT_SR 5
  80. #define Z_BUTTON_RIGHT_SR 3
  81. #define Z_BUTTON_MIDDLE_SR 3
  82. #define Z_BUTTON_MIDDLE_MASK 0x04
  83. #define Z_UPPER_MASKX 0x03
  84. #define Z_UPPER_MASKY 0x0C
  85. #define Z_UPPER_MASKZ 0x0F
  86. #define Z_LOWER_MASKZ 0x0F
  87. #define Z_UPPER_MASKX_SL 6
  88. #define Z_UPPER_MASKY_SL 4
  89. #define Z_UPPER_MASKZ_SL 4
  90. //
  91. // Type definitions.
  92. //
  93. typedef struct _PROTOCOL {
  94. PPROTOCOL_HANDLER Handler;
  95. UCHAR LineCtrl;
  96. } PROTOCOL;
  97. //
  98. // This list is indexed by protocol values MSER_PROTOCOL_*.
  99. //
  100. static PROTOCOL Protocol[] = {
  101. {
  102. MSerHandlerMP, // Microsoft Plus
  103. ACE_7BW | ACE_1SB
  104. },
  105. {
  106. MSerHandlerBP, // BALLPOINT
  107. ACE_7BW | ACE_1SB
  108. },
  109. {
  110. MSerHandlerZ, // Magellan Mouse
  111. ACE_7BW | ACE_1SB
  112. }
  113. };
  114. PPROTOCOL_HANDLER
  115. MSerSetProtocol(
  116. PUCHAR Port,
  117. UCHAR NewProtocol
  118. )
  119. /*++
  120. Routine Description:
  121. Set the mouse protocol. This function only sets the serial port
  122. line control register.
  123. Arguments:
  124. Port - Pointer to the serial port.
  125. NewProtocol - Index into the protocol table.
  126. Return Value:
  127. Pointer to the protocol handler function.
  128. --*/
  129. {
  130. ASSERT(NewProtocol < MSER_PROTOCOL_MAX);
  131. //
  132. // Set the protocol
  133. //
  134. UARTSetLineCtrl(Port, Protocol[NewProtocol].LineCtrl);
  135. return Protocol[NewProtocol].Handler;
  136. }
  137. BOOLEAN
  138. MSerPowerUp(
  139. PUCHAR Port
  140. )
  141. /*++
  142. Routine Description:
  143. Powers up the mouse. Just sets the RTS and DTR lines and returns.
  144. Arguments:
  145. Port - Pointer to the serial port.
  146. Return Value:
  147. TRUE.
  148. --*/
  149. {
  150. //
  151. // Turn RTS on to power the mouse up (DTR should already be on,
  152. // but make extra sure).
  153. //
  154. UARTSetModemCtrl(Port, ACE_DTR | ACE_RTS);
  155. //
  156. // Wait 10 ms. The power-up response byte(s) should take at least
  157. // this long to get transmitted.
  158. //
  159. KeStallExecutionProcessor(10 * MS_TO_MICROSECONDS);
  160. return TRUE;
  161. }
  162. BOOLEAN
  163. MSerPowerDown(
  164. PUCHAR Port
  165. )
  166. /*++
  167. Routine Description:
  168. Powers down the mouse. Sets the RTS line to an inactive state.
  169. Arguments:
  170. Port - Pointer to the serial port.
  171. Return Value:
  172. TRUE.
  173. --*/
  174. {
  175. UCHAR lineCtrl = UARTGetModemCtrl(Port);
  176. SerMouPrint((
  177. 2,
  178. "SERMOUSE-MSerPowerDown: The intial line control is: %#X\n",
  179. lineCtrl & 0xFF
  180. ));
  181. UARTSetModemCtrl(Port, (UCHAR) ((lineCtrl & ~ACE_RTS) | ACE_DTR));
  182. //
  183. // Keep RTS low for at least 150 ms, in order to correctly power
  184. // down older Microsoft serial mice. Wait even longer to avoid
  185. // sending some Logitech CSeries mice into the floating point world...
  186. //
  187. ASSERT(CSER_POWER_DOWN >= 150);
  188. KeStallExecutionProcessor(CSER_POWER_DOWN * MS_TO_MICROSECONDS);
  189. return TRUE;
  190. }
  191. BOOLEAN
  192. MSerReset(
  193. PUCHAR Port
  194. )
  195. /*++
  196. Routine Description:
  197. Reset the serial mouse.
  198. Arguments:
  199. Port - Pointer to the serial port.
  200. Return Value:
  201. TRUE.
  202. --*/
  203. {
  204. //
  205. // Remove mouse power if necessary.
  206. //
  207. MSerPowerDown(Port);
  208. //
  209. // Clean possible garbage in uart input buffer.
  210. //
  211. UARTFlushReadBuffer(Port);
  212. //
  213. // Power up the mouse (reset).
  214. //
  215. MSerPowerUp(Port);
  216. return TRUE;
  217. }
  218. MOUSETYPE
  219. MSerDetect(
  220. PUCHAR Port,
  221. ULONG BaudClock
  222. )
  223. /*++
  224. Routine Description:
  225. Detection code for pointing devices that identify themselves at
  226. power on time.
  227. Arguments:
  228. Port - Pointer to the serial port.
  229. BaudClock - The external frequency driving the serial chip.
  230. Return Value:
  231. The type of mouse detected.
  232. --*/
  233. {
  234. ULONG count = 0;
  235. MOUSETYPE mouseType;
  236. CHAR receiveBuffer[MAX_RESET_BUFFER];
  237. ULONG i;
  238. //
  239. // Set the debug output to the main display to avoid timing problems.
  240. //
  241. SerMouSetDebugOutput(DBG_COLOR);
  242. //
  243. // Set the baud rate.
  244. //
  245. UARTSetBaudRate(Port, MSER_BAUDRATE, BaudClock);
  246. //
  247. // Set the data format so that the possible answer can be recognized.
  248. //
  249. UARTSetLineCtrl(Port, Protocol[MSER_PROTOCOL_MP].LineCtrl);
  250. //
  251. // Apply the reset to the mouse.
  252. //
  253. MSerReset(Port);
  254. //
  255. // Get the possible first reset character ('M' or 'B'), followed
  256. // by any other characters the hardware happens to send back.
  257. //
  258. // Note: Typically, we expect to get just one character ('M' or
  259. // 'B'), perhaps followed by a '2' or '3' (to indicate the
  260. // number of mouse buttons. On some machines, we're
  261. // getting extraneous characters before the 'M'. Sometimes
  262. // we get extraneous characters after the expected data, as
  263. // well. They either get read in here, or get flushed
  264. // when SerMouEnableInterrupts executes.
  265. //
  266. ASSERT(CSER_POWER_UP >= MINIMUM_RESET_TIME);
  267. if (UARTReadChar(Port, &receiveBuffer[count], CSER_POWER_UP)) {
  268. count++;
  269. while (count < (MAX_RESET_BUFFER - 1)) {
  270. if (UARTReadChar(Port, &receiveBuffer[count], 100)) {
  271. count++;
  272. } else {
  273. break;
  274. }
  275. }
  276. }
  277. *(receiveBuffer + count) = 0;
  278. SerMouPrint((2, "SERMOUSE-Receive buffer:\n"));
  279. for (i = 0; i < count; i++) {
  280. SerMouPrint((2, "\t0x%x\n", receiveBuffer[i]));
  281. }
  282. SerMouPrint((2, "\n"));
  283. //
  284. // Redirect the output to the serial port.
  285. //
  286. SerMouSetDebugOutput(DBG_SERIAL);
  287. //
  288. //
  289. // Analyze the possible mouse answer. Start at the beginning of the
  290. // "good" data in the receive buffer, ignoring extraneous characters
  291. // that may have come in before the 'M' or 'B'.
  292. //
  293. for (i = 0; i < count; i++) {
  294. if (receiveBuffer[i] == 'M') {
  295. if (receiveBuffer[i + 1] == '3') {
  296. SerMouPrint((2, "SERMOUSE-Detected MSeries 3 buttons\n"));
  297. mouseType = MOUSE_3B;
  298. }
  299. else if (receiveBuffer[i + 1] == 'Z') {
  300. SerMouPrint((2, "SERMOUSE-Detected Wheel Mouse\n"));
  301. mouseType = MOUSE_Z;
  302. }
  303. else {
  304. SerMouPrint((2, "SERMOUSE-Detected MSeries 2 buttons\n"));
  305. mouseType = MOUSE_2B;
  306. }
  307. break;
  308. } else if (receiveBuffer[i] == 'B') {
  309. SerMouPrint((2, "SERMOUSE-Detected Ballpoint\n"));
  310. mouseType = BALLPOINT;
  311. break;
  312. }
  313. }
  314. if (i >= count) {
  315. //
  316. // Special case: If another device is connected (CSeries, for
  317. // example) and this device sends a character (movement), the
  318. // minimum power up time might not be respected. Take
  319. // care of this unlikely case.
  320. //
  321. if (count != 0) {
  322. KeStallExecutionProcessor(CSER_POWER_UP * MS_TO_MICROSECONDS);
  323. }
  324. SerMouPrint((1, "SERMOUSE-No MSeries detected\n"));
  325. mouseType = NO_MOUSE;
  326. }
  327. return mouseType;
  328. }
  329. BOOLEAN
  330. MSerHandlerMP(
  331. IN PMOUSE_INPUT_DATA CurrentInput,
  332. IN PHANDLER_DATA HandlerData,
  333. IN UCHAR Value,
  334. IN UCHAR LineState
  335. )
  336. /*++
  337. Routine Description:
  338. This is the protocol handler routine for the Microsoft Plus protocol.
  339. Arguments:
  340. CurrentInput - Pointer to the report packet.
  341. HandlerData - Instance specific static data for the handler.
  342. Value - The input buffer value.
  343. LineState - The serial port line state.
  344. Return Value:
  345. Returns TRUE if the handler has a complete report ready.
  346. --*/
  347. {
  348. BOOLEAN retval = FALSE;
  349. ULONG middleButton;
  350. SerMouPrint((2, "SERMOUSE-MP protocol handler: enter\n"));
  351. if ((Value & MP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  352. if ((HandlerData->State != STATE3)) {
  353. //
  354. // We definitely have a synchronization problem (likely a data
  355. // overrun).
  356. //
  357. HandlerData->Error++;
  358. }
  359. else if ((HandlerData->PreviousButtons & MOUSE_BUTTON_3) != 0) {
  360. //
  361. // We didn't receive the expected fourth byte. Missed it?
  362. // Reset button 3 to zero.
  363. //
  364. HandlerData->PreviousButtons ^= MOUSE_BUTTON_3;
  365. HandlerData->Error++;
  366. }
  367. SerMouPrint((
  368. 1,
  369. "SERMOUSE-Synch error. State: %u\n", HandlerData->State
  370. ));
  371. HandlerData->State = STATE0;
  372. }
  373. else if (!(Value & MP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  374. HandlerData->Error++;
  375. SerMouPrint((
  376. 1,
  377. "SERMOUSE-Synch error. State: %u\n", HandlerData->State
  378. ));
  379. goto LExit;
  380. }
  381. //
  382. // Check for a line state error.
  383. //
  384. if (LineState & ACE_LERR) {
  385. //
  386. // Reset the handler state.
  387. //
  388. HandlerData->State = STATE0;
  389. HandlerData->Error++;
  390. SerMouPrint((1, "SERMOUSE-Line status error: %#x\n", LineState));
  391. }
  392. else {
  393. //
  394. // Set the untranslated value.
  395. //
  396. HandlerData->Raw[HandlerData->State] = Value;
  397. SerMouPrint((3, "SERMOUSE-State%u\n", HandlerData->State));
  398. switch (HandlerData->State) {
  399. case STATE0:
  400. case STATE1:
  401. HandlerData->State++;
  402. break;
  403. case STATE2:
  404. HandlerData->State++;
  405. //
  406. // Build the report.
  407. //
  408. CurrentInput->RawButtons =
  409. (HandlerData->Raw[0] & MP_BUTTON_LEFT) >> MP_BUTTON_LEFT_SR;
  410. CurrentInput->RawButtons |=
  411. (HandlerData->Raw[0] & MP_BUTTON_RIGHT) >> MP_BUTTON_RIGHT_SR;
  412. CurrentInput->RawButtons |=
  413. HandlerData->PreviousButtons & MOUSE_BUTTON_3;
  414. CurrentInput->LastX =
  415. (SCHAR)(HandlerData->Raw[1] |
  416. ((HandlerData->Raw[0] & MP_UPPER_MASKX) << MP_UPPER_MASKX_SL));
  417. CurrentInput->LastY =
  418. (SCHAR)(HandlerData->Raw[2] |
  419. ((HandlerData->Raw[0] & MP_UPPER_MASKY) << MP_UPPER_MASKY_SL));
  420. retval = TRUE;
  421. break;
  422. case STATE3:
  423. HandlerData->State = STATE0;
  424. middleButton =
  425. (HandlerData->Raw[STATE3] & MP_BUTTON_MIDDLE) >> MP_BUTTON_MIDDLE_SR;
  426. //
  427. // Send a report only if the middle button state changed.
  428. //
  429. if (middleButton ^ (HandlerData->PreviousButtons & MOUSE_BUTTON_3)) {
  430. //
  431. // Toggle the state of the middle button.
  432. //
  433. CurrentInput->RawButtons ^= MP_BUTTON_MIDDLE_MASK;
  434. CurrentInput->LastX = 0;
  435. CurrentInput->LastY = 0;
  436. //
  437. // Send the report one more time.
  438. //
  439. retval = TRUE;
  440. }
  441. break;
  442. default:
  443. SerMouPrint((
  444. 0,
  445. "SERMOUSE-MP Handler failure: incorrect state value.\n"
  446. ));
  447. ASSERT(FALSE);
  448. }
  449. }
  450. LExit:
  451. SerMouPrint((2, "SERMOUSE-MP protocol handler: exit\n"));
  452. return retval;
  453. }
  454. BOOLEAN
  455. MSerHandlerBP(
  456. IN PMOUSE_INPUT_DATA CurrentInput,
  457. IN PHANDLER_DATA HandlerData,
  458. IN UCHAR Value,
  459. IN UCHAR LineState
  460. )
  461. /*++
  462. Routine Description:
  463. This is the protocol handler routine for the Microsoft Ballpoint protocol.
  464. Arguments:
  465. CurrentInput - Pointer to the report packet.
  466. HandlerData - Instance specific static data for the handler.
  467. Value - The input buffer value.
  468. LineState - The serial port line state.
  469. Return Value:
  470. Returns TRUE if the handler has a complete report ready.
  471. --*/
  472. {
  473. BOOLEAN retval = FALSE;
  474. SerMouPrint((2, "SERMOUSE-BP protocol handler: enter\n"));
  475. //
  476. // Check for synchronization errors.
  477. //
  478. if ((Value & BP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  479. HandlerData->Error++;
  480. SerMouPrint((
  481. 1,
  482. "SERMOUSE-Synch error. State: %u\n", HandlerData->State
  483. ));
  484. HandlerData->State = STATE0;
  485. }
  486. else if (!(Value & BP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  487. HandlerData->Error++;
  488. SerMouPrint((
  489. 1,
  490. "SERMOUSE-Synch error. State: %u\n", HandlerData->State
  491. ));
  492. goto LExit;
  493. }
  494. //
  495. // Check for a line state error.
  496. //
  497. if (LineState & ACE_LERR) {
  498. //
  499. // Reset the handler state.
  500. //
  501. HandlerData->State = STATE0;
  502. HandlerData->Error++;
  503. SerMouPrint((1, "SERMOUSE-Line status error: %#x\n", LineState));
  504. }
  505. else {
  506. //
  507. // Set the untranslated value.
  508. //
  509. HandlerData->Raw[HandlerData->State] = Value;
  510. SerMouPrint((3, "SERMOUSE-State%u\n", HandlerData->State));
  511. switch (HandlerData->State) {
  512. case STATE0:
  513. case STATE1:
  514. case STATE2:
  515. HandlerData->State++;
  516. break;
  517. case STATE3:
  518. HandlerData->State = STATE0;
  519. //
  520. // Build the report.
  521. //
  522. CurrentInput->RawButtons =
  523. (HandlerData->Raw[0] & BP_BUTTON_LEFT) >> BP_BUTTON_LEFT_SR;
  524. CurrentInput->RawButtons |=
  525. (HandlerData->Raw[0] & BP_BUTTON_RIGHT) >> BP_BUTTON_RIGHT_SR;
  526. #if 0
  527. CurrentInput->ButtonFlags |=
  528. (HandlerData->Raw[3] & BP_BUTTON_3) << BP_BUTTON_3_SL;
  529. CurrentInput->ButtonFlags |=
  530. (HandlerData->Raw[3] & BP_BUTTON_4) << BP_BUTTON_4_SL;
  531. #endif
  532. CurrentInput->LastX = HandlerData->Raw[3] & BP_SIGN_MASKX ?
  533. (LONG)(HandlerData->Raw[1] | (ULONG)(-1 & ~0xFF) |
  534. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL)):
  535. (LONG)(HandlerData->Raw[1] |
  536. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL));
  537. CurrentInput->LastY = HandlerData->Raw[3] & BP_SIGN_MASKY ?
  538. (LONG)(HandlerData->Raw[2] | (ULONG)(-1 & ~0xFF) |
  539. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL)):
  540. (LONG)(HandlerData->Raw[2] |
  541. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL));
  542. retval = TRUE;
  543. break;
  544. default:
  545. SerMouPrint((
  546. 0,
  547. "SERMOUSE-BP Handler failure: incorrect state value.\n"
  548. ));
  549. ASSERT(FALSE);
  550. }
  551. }
  552. LExit:
  553. SerMouPrint((2, "SERMOUSE-BP protocol handler: exit\n"));
  554. return retval;
  555. }
  556. BOOLEAN
  557. MSerHandlerZ(
  558. IN PMOUSE_INPUT_DATA CurrentInput,
  559. IN PHANDLER_DATA HandlerData,
  560. IN UCHAR Value,
  561. IN UCHAR LineState
  562. )
  563. /*++
  564. Routine Description:
  565. This is the protocol handler routine for the Microsoft Magellan Mouse
  566. (wheel mouse)
  567. Arguments:
  568. CurrentInput - Pointer to the report packet.
  569. HandlerData - Instance specific static data for the handler.
  570. Value - The input buffer value.
  571. LineState - The serial port line state.
  572. Return Value:
  573. Returns TRUE if the handler has a complete report ready.
  574. --*/
  575. {
  576. BOOLEAN retval = FALSE;
  577. ULONG middleButton;
  578. CHAR zMotion = 0;
  579. SerMouPrint((2, "SERMOUSE-Z protocol handler: enter\n"));
  580. if ((Value & Z_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  581. if ((HandlerData->State != STATE3)) {
  582. //
  583. // We definitely have a synchronization problem (likely a data
  584. // overrun).
  585. //
  586. HandlerData->Error++;
  587. }
  588. SerMouPrint((
  589. 1,
  590. "SERMOUSE-Z Synch error. State: %u\n", HandlerData->State
  591. ));
  592. HandlerData->State = STATE0;
  593. }
  594. else if (!(Value & Z_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  595. HandlerData->Error++;
  596. SerMouPrint((
  597. 1,
  598. "SERMOUSE-Z Synch error. State: %u\n", HandlerData->State
  599. ));
  600. goto LExit;
  601. }
  602. //
  603. // Check for a line state error.
  604. //
  605. if (LineState & ACE_LERR) {
  606. //
  607. // Reset the handler state.
  608. //
  609. HandlerData->State = STATE0;
  610. HandlerData->Error++;
  611. SerMouPrint((1, "SERMOUSE-Z Line status error: %#x\n", LineState));
  612. }
  613. else {
  614. //
  615. // Set the untranslated value.
  616. //
  617. HandlerData->Raw[HandlerData->State] = Value;
  618. SerMouPrint((3, "SERMOUSE-Z State%u\n", HandlerData->State));
  619. switch (HandlerData->State) {
  620. case STATE0:
  621. case STATE1:
  622. case STATE2:
  623. HandlerData->State++;
  624. break;
  625. case STATE3:
  626. //
  627. // Check to see if the mouse is going to the high bits of
  628. // the wheel movement. If not, this is the last bit - transition
  629. // back to state0
  630. //
  631. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  632. HandlerData->State = STATE0;
  633. HandlerData->Raw[STATE4] = 0;
  634. retval = TRUE;
  635. }
  636. break;
  637. case STATE4:
  638. DbgPrint("SERMOUSE-Z Got that 5th byte\n");
  639. HandlerData->State = STATE0;
  640. retval = TRUE;
  641. break;
  642. default:
  643. SerMouPrint((
  644. 0,
  645. "SERMOUSE-Z Handler failure: incorrect state value.\n"
  646. ));
  647. ASSERT(FALSE);
  648. }
  649. if(retval) {
  650. CurrentInput->RawButtons = 0;
  651. if(HandlerData->Raw[STATE0] & Z_BUTTON_LEFT) {
  652. CurrentInput->RawButtons |= MOUSE_BUTTON_LEFT;
  653. }
  654. if(HandlerData->Raw[STATE0] & Z_BUTTON_RIGHT) {
  655. CurrentInput->RawButtons |= MOUSE_BUTTON_RIGHT;
  656. }
  657. if(HandlerData->Raw[STATE3] & Z_BUTTON_MIDDLE) {
  658. CurrentInput->RawButtons |= MOUSE_BUTTON_MIDDLE;
  659. }
  660. CurrentInput->LastX =
  661. (SCHAR)(HandlerData->Raw[STATE1] |
  662. ((HandlerData->Raw[0] & Z_UPPER_MASKX) << Z_UPPER_MASKX_SL));
  663. CurrentInput->LastY =
  664. (SCHAR)(HandlerData->Raw[STATE2] |
  665. ((HandlerData->Raw[0] & Z_UPPER_MASKY) << Z_UPPER_MASKY_SL));
  666. //
  667. // If the extra bit isn't set then the 4th byte contains
  668. // a 4 bit signed quantity for the wheel movement. if it
  669. // is set, then we need to combine the z info from the
  670. // two bytes
  671. //
  672. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  673. zMotion = HandlerData->Raw[STATE3] & Z_LOWER_MASKZ;
  674. //
  675. // Sign extend the 4 bit
  676. //
  677. if(zMotion & 0x08) {
  678. zMotion |= 0xf0;
  679. }
  680. } else {
  681. zMotion = ((HandlerData->Raw[STATE3] & Z_LOWER_MASKZ) |
  682. ((HandlerData->Raw[STATE4] & Z_UPPER_MASKZ)
  683. << Z_UPPER_MASKZ_SL));
  684. }
  685. if(zMotion == 0) {
  686. CurrentInput->ButtonData = 0;
  687. } else {
  688. CurrentInput->ButtonData = 0x0078;
  689. if(zMotion & 0x80) {
  690. CurrentInput->ButtonData = 0x0078;
  691. } else {
  692. CurrentInput->ButtonData = 0xff88;
  693. }
  694. CurrentInput->ButtonFlags |= MOUSE_WHEEL;
  695. }
  696. }
  697. }
  698. LExit:
  699. SerMouPrint((2, "SERMOUSE-Z protocol handler: exit\n"));
  700. return retval;
  701. }