Source code of Windows XP (NT5)
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.

1085 lines
27 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
  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 "mouser.h"
  17. #include "debug.h"
  18. #include "cseries.h"
  19. #include "mseries.h"
  20. //
  21. // Use the alloc_text pragma to specify the driver initialization routines
  22. // (they can be paged out).
  23. //
  24. #ifdef ALLOC_PRAGMA
  25. #pragma alloc_text(PAGE,MSerSetProtocol)
  26. #pragma alloc_text(PAGE,MSerPowerUp)
  27. #pragma alloc_text(PAGE,MSerPowerDown)
  28. #pragma alloc_text(PAGE,MSerDetect)
  29. #endif // ALLOC_PRAGMA
  30. //
  31. // Constants.
  32. //
  33. #define MSER_BAUDRATE 1200
  34. #define MAX_RESET_BUFFER 8
  35. #define MINIMUM_RESET_TIME (200 * MS_TO_100_NS)
  36. //
  37. // Microsoft Plus.
  38. //
  39. #define MP_SYNCH_BIT 0x40
  40. #define MP_BUTTON_LEFT 0x20
  41. #define MP_BUTTON_RIGHT 0x10
  42. #define MP_BUTTON_MIDDLE 0x20
  43. #define MP_BUTTON_LEFT_SR 5
  44. #define MP_BUTTON_RIGHT_SR 3
  45. #define MP_BUTTON_MIDDLE_SR 3
  46. #define MP_BUTTON_MIDDLE_MASK 0x04
  47. #define MP_UPPER_MASKX 0x03
  48. #define MP_UPPER_MASKY 0x0C
  49. #define MP_UPPER_MASKX_SL 6
  50. #define MP_UPPER_MASKY_SL 4
  51. //
  52. // Microsoft BallPoint.
  53. //
  54. #define BP_SYNCH_BIT 0x40
  55. #define BP_BUTTON_LEFT 0x20
  56. #define BP_BUTTON_RIGHT 0x10
  57. #define BP_BUTTON_3 0x04
  58. #define BP_BUTTON_4 0x08
  59. #define BP_BUTTON_LEFT_SR 5
  60. #define BP_BUTTON_RIGHT_SR 3
  61. #define BP_BUTTON_3_SL 0
  62. #define BP_BUTTON_4_SL 0
  63. #define BP_UPPER_MASKX 0x03
  64. #define BP_UPPER_MASKY 0x0C
  65. #define BP_UPPER_MASKX_SL 6
  66. #define BP_UPPER_MASKY_SL 4
  67. #define BP_SIGN_MASKX 0x01
  68. #define BP_SIGN_MASKY 0x02
  69. //
  70. // Microsoft Magellan Mouse.
  71. //
  72. #define Z_SYNCH_BIT 0x40
  73. #define Z_EXTRA_BIT 0x20
  74. #define Z_BUTTON_LEFT 0x20
  75. #define Z_BUTTON_RIGHT 0x10
  76. #define Z_BUTTON_MIDDLE 0x10
  77. #define Z_BUTTON_LEFT_SR 5
  78. #define Z_BUTTON_RIGHT_SR 3
  79. #define Z_BUTTON_MIDDLE_SR 3
  80. #define Z_BUTTON_MIDDLE_MASK 0x04
  81. #define Z_UPPER_MASKX 0x03
  82. #define Z_UPPER_MASKY 0x0C
  83. #define Z_UPPER_MASKZ 0x0F
  84. #define Z_LOWER_MASKZ 0x0F
  85. #define Z_UPPER_MASKX_SL 6
  86. #define Z_UPPER_MASKY_SL 4
  87. #define Z_UPPER_MASKZ_SL 4
  88. //
  89. // Type definitions.
  90. //
  91. typedef struct _PROTOCOL {
  92. PPROTOCOL_HANDLER Handler;
  93. // UCHAR LineCtrl;
  94. SERIAL_LINE_CONTROL LineCtrl;
  95. } PROTOCOL;
  96. //
  97. // This list is indexed by protocol values MSER_PROTOCOL_*.
  98. //
  99. static PROTOCOL Protocol[] = {
  100. {
  101. MSerHandlerMP, // Microsoft Plus
  102. // ACE_7BW | ACE_1SB
  103. { STOP_BIT_1, NO_PARITY, 7 }
  104. },
  105. {
  106. MSerHandlerBP, // BALLPOINT
  107. // ACE_7BW | ACE_1SB
  108. { STOP_BIT_1, NO_PARITY, 7 }
  109. },
  110. {
  111. MSerHandlerZ, // Magellan Mouse
  112. // ACE_7BW | ACE_1SB
  113. { STOP_BIT_1, NO_PARITY, 7 }
  114. }
  115. };
  116. PPROTOCOL_HANDLER
  117. MSerSetProtocol(
  118. PDEVICE_EXTENSION DeviceExtension,
  119. UCHAR NewProtocol
  120. )
  121. /*++
  122. Routine Description:
  123. Set the mouse protocol. This function only sets the serial port
  124. line control register.
  125. Arguments:
  126. Port - Pointer to the serial port.
  127. NewProtocol - Index into the protocol table.
  128. Return Value:
  129. Pointer to the protocol handler function.
  130. --*/
  131. {
  132. ASSERT(NewProtocol < MSER_PROTOCOL_MAX);
  133. PAGED_CODE();
  134. Print(DeviceExtension, DBG_SS_TRACE, ("MSerSetProtocol called\n"));
  135. //
  136. // Set the protocol
  137. //
  138. SerialMouseSetLineCtrl(DeviceExtension, &Protocol[NewProtocol].LineCtrl);
  139. return Protocol[NewProtocol].Handler;
  140. }
  141. NTSTATUS
  142. MSerPowerUp(
  143. PDEVICE_EXTENSION DeviceExtension
  144. )
  145. /*++
  146. Routine Description:
  147. Powers up the mouse. Just sets the RTS and DTR lines and returns.
  148. Arguments:
  149. Port - Pointer to the serial port.
  150. Return Value:
  151. TRUE.
  152. --*/
  153. {
  154. IO_STATUS_BLOCK iosb;
  155. NTSTATUS status;
  156. KEVENT event;
  157. PAGED_CODE();
  158. Print(DeviceExtension, DBG_SS_TRACE, ("MSerPowerUp called\n"));
  159. KeInitializeEvent(&event, NotificationEvent, FALSE);
  160. //
  161. // Clear DTR
  162. //
  163. Print(DeviceExtension, DBG_SS_NOISE, ("Clearing DTR...\n"));
  164. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_DTR,
  165. DeviceExtension->TopOfStack,
  166. &event,
  167. &iosb
  168. );
  169. if (!NT_SUCCESS(status)) {
  170. return status;
  171. }
  172. //
  173. // Clear RTS
  174. //
  175. Print(DeviceExtension, DBG_SS_NOISE, ("Clearing RTS...\n"));
  176. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_RTS,
  177. DeviceExtension->TopOfStack,
  178. &event,
  179. &iosb
  180. );
  181. if (!NT_SUCCESS(status)) {
  182. return status;
  183. }
  184. //
  185. // Set a timer for 200 ms
  186. //
  187. status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
  188. if (!NT_SUCCESS(status)) {
  189. Print(DeviceExtension, DBG_SS_ERROR,
  190. ("Timer failed with status %x\n", status ));
  191. return status;
  192. }
  193. //
  194. // set DTR
  195. //
  196. Print(DeviceExtension, DBG_SS_NOISE, ("Setting DTR...\n"));
  197. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_DTR,
  198. DeviceExtension->TopOfStack,
  199. &event,
  200. &iosb
  201. );
  202. if (!NT_SUCCESS(status)) {
  203. return status;
  204. }
  205. status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
  206. if (!NT_SUCCESS(status)) {
  207. Print(DeviceExtension, DBG_SS_ERROR,
  208. ("Timer failed with status %x\n", status ));
  209. return status;
  210. }
  211. //
  212. // set RTS
  213. //
  214. Print(DeviceExtension, DBG_SS_NOISE, ("Setting RTS...\n"));
  215. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_RTS,
  216. DeviceExtension->TopOfStack,
  217. &event,
  218. &iosb
  219. );
  220. status = SerialMouseWait(DeviceExtension, -175 * MS_TO_100_NS);
  221. if (!NT_SUCCESS(status)) {
  222. Print(DeviceExtension, DBG_SS_ERROR,
  223. ("Timer failed with status %x\n", status ));
  224. return status;
  225. }
  226. return status;
  227. }
  228. NTSTATUS
  229. MSerPowerDown(
  230. PDEVICE_EXTENSION DeviceExtension
  231. )
  232. /*++
  233. Routine Description:
  234. Powers down the mouse. Sets the RTS line to an inactive state.
  235. Arguments:
  236. Port - Pointer to the serial port.
  237. Return Value:
  238. TRUE.
  239. --*/
  240. {
  241. IO_STATUS_BLOCK iosb;
  242. SERIAL_HANDFLOW shf;
  243. KEVENT event;
  244. NTSTATUS status;
  245. ULONG bits;
  246. PAGED_CODE();
  247. Print(DeviceExtension, DBG_SS_TRACE, ("MSerPowerDown called\n"));
  248. KeInitializeEvent(&event,
  249. NotificationEvent,
  250. FALSE
  251. );
  252. #if 0
  253. //
  254. // Set the handflow to default values
  255. //
  256. Print(DeviceExtension, DBG_SS_NOISE,
  257. ("Setting handflow to default values...\n"));
  258. shf.ControlHandShake = SERIAL_DTR_CONTROL;
  259. shf.FlowReplace = SERIAL_RTS_CONTROL;
  260. shf.XonLimit = 0;
  261. shf.XoffLimit = 0;
  262. status = SerialMouseIoSyncIoctlEx(IOCTL_SERIAL_SET_HANDFLOW,
  263. DeviceExtension->TopOfStack,
  264. &event,
  265. &iosb,
  266. &shf,
  267. sizeof(SERIAL_HANDFLOW),
  268. NULL,
  269. 0);
  270. if (!NT_SUCCESS(status)) {
  271. return status;
  272. }
  273. #endif
  274. //
  275. // Set DTR
  276. //
  277. Print(DeviceExtension, DBG_SS_NOISE, ("Setting DTR...\n"));
  278. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_DTR,
  279. DeviceExtension->TopOfStack,
  280. &event,
  281. &iosb);
  282. if (!NT_SUCCESS(status)) {
  283. return status;
  284. }
  285. //
  286. // Clear RTS
  287. //
  288. Print(DeviceExtension, DBG_SS_NOISE, ("Clearing RTS...\n"));
  289. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_RTS,
  290. DeviceExtension->TopOfStack,
  291. &event,
  292. &iosb);
  293. if (!NT_SUCCESS(status)) {
  294. return status;
  295. }
  296. //
  297. // Set a timer for 200 ms
  298. //
  299. status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
  300. if (!NT_SUCCESS(status)) {
  301. Print(DeviceExtension, DBG_SS_ERROR,
  302. ("Timer failed with status %x\n", status));
  303. return status;
  304. }
  305. return status;
  306. }
  307. #define BUFFER_SIZE 256
  308. MOUSETYPE
  309. MSerDetect(
  310. PDEVICE_EXTENSION DeviceExtension
  311. )
  312. /*++
  313. Routine Description:
  314. Detection code for pointing devices that identify themselves at
  315. power on time.
  316. Arguments:
  317. Port - Pointer to the serial port.
  318. BaudClock - The external frequency driving the serial chip.
  319. Return Value:
  320. The type of mouse detected.
  321. --*/
  322. {
  323. ULONG count = 0;
  324. MOUSETYPE mouseType = NO_MOUSE;
  325. NTSTATUS status;
  326. ULONG i;
  327. CHAR receiveBuffer[BUFFER_SIZE];
  328. PAGED_CODE();
  329. Print(DeviceExtension, DBG_SS_TRACE,
  330. ("MSerDetect enter\n"));
  331. status = SerialMouseInitializePort(DeviceExtension);
  332. if (!NT_SUCCESS(status)) {
  333. Print(DeviceExtension, DBG_SS_ERROR,
  334. ("Initializing the port failed (%x)\n", status));
  335. // return status;
  336. }
  337. status = MSerPowerDown(DeviceExtension);
  338. if (!NT_SUCCESS(status)) {
  339. Print(DeviceExtension, DBG_SS_ERROR,
  340. ("PowerDown failed (%x)\n", status));
  341. // return status;
  342. }
  343. //
  344. // Set the baud rate.
  345. //
  346. SerialMouseSetBaudRate(DeviceExtension, MSER_BAUDRATE);
  347. //
  348. // Set the data format so that the possible answer can be recognized.
  349. //
  350. SerialMouseSetLineCtrl(DeviceExtension,
  351. &Protocol[MSER_PROTOCOL_MP].LineCtrl);
  352. //
  353. // Clean possible garbage in uart input buffer.
  354. //
  355. SerialMouseFlushReadBuffer(DeviceExtension);
  356. status = MSerPowerUp(DeviceExtension);
  357. if (!NT_SUCCESS(status)) {
  358. Print(DeviceExtension, DBG_SS_ERROR, ("Powerup failed (%x)\n", status));
  359. }
  360. //
  361. // Get the possible first reset character ('M' or 'B'), followed
  362. // by any other characters the hardware happens to send back.
  363. //
  364. // Note: Typically, we expect to get just one character ('M' or
  365. // 'B'), perhaps followed by a '2' or '3' (to indicate the
  366. // number of mouse buttons. On some machines, we're
  367. // getting extraneous characters before the 'M'.
  368. // We get extraneous characters after the expected data if this a
  369. // true PnP comm device
  370. //
  371. ASSERT(CSER_POWER_UP >= MINIMUM_RESET_TIME);
  372. status = SerialMouseSetReadTimeouts(DeviceExtension, 200);
  373. if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
  374. &receiveBuffer[count]))) {
  375. count++;
  376. SerialMouseSetReadTimeouts(DeviceExtension, 100);
  377. while (count < (BUFFER_SIZE - 1)) {
  378. if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
  379. &receiveBuffer[count]))) {
  380. count++;
  381. } else {
  382. break;
  383. }
  384. }
  385. }
  386. *(receiveBuffer + count) = 0;
  387. Print(DeviceExtension, DBG_SS_NOISE, ("Receive buffer:\n"));
  388. for (i = 0; i < count; i++) {
  389. Print(DeviceExtension, DBG_SS_NOISE, ("\t0x%x\n", receiveBuffer[i]));
  390. }
  391. //
  392. //
  393. // Analyze the possible mouse answer. Start at the beginning of the
  394. // "good" data in the receive buffer, ignoring extraneous characters
  395. // that may have come in before the 'M' or 'B'.
  396. //
  397. for (i = 0; i < count; i++) {
  398. if (receiveBuffer[i] == 'M') {
  399. if (receiveBuffer[i + 1] == '3') {
  400. Print(DeviceExtension, DBG_SS_INFO,
  401. ("Detected MSeries 3 buttons\n"));
  402. mouseType = MOUSE_3B;
  403. }
  404. else if (receiveBuffer[i + 1] == 'Z') {
  405. Print(DeviceExtension, DBG_SS_INFO,
  406. ("Detected Wheel Mouse\n"));
  407. mouseType = MOUSE_Z;
  408. }
  409. else {
  410. Print(DeviceExtension, DBG_SS_INFO,
  411. ("Detected MSeries 2 buttons\n"));
  412. mouseType = MOUSE_2B;
  413. }
  414. break;
  415. } else if (receiveBuffer[i] == 'B') {
  416. Print(DeviceExtension, DBG_SS_INFO,
  417. ("Detected Ballpoint\n"));
  418. mouseType = BALLPOINT;
  419. break;
  420. }
  421. }
  422. if (i >= count) {
  423. //
  424. // Special case: If another device is connected (CSeries, for
  425. // example) and this device sends a character (movement), the
  426. // minimum power up time might not be respected. Take
  427. // care of this unlikely case.
  428. //
  429. if (count != 0) {
  430. SerialMouseWait(DeviceExtension, -CSER_POWER_UP);
  431. }
  432. Print(DeviceExtension, DBG_SS_ERROR | DBG_SS_INFO,
  433. ("No MSeries detected\n"));
  434. mouseType = NO_MOUSE;
  435. }
  436. //
  437. // Make sure that all subsequent reads are blocking and do not timeout
  438. //
  439. if (mouseType != NO_MOUSE) {
  440. SerialMouseSetReadTimeouts(DeviceExtension, 0);
  441. }
  442. Print(DeviceExtension, DBG_SS_INFO,
  443. ("mouse type is %d\n", (ULONG) mouseType));
  444. return mouseType;
  445. }
  446. BOOLEAN
  447. MSerHandlerMP(
  448. IN PDEVICE_EXTENSION DeviceExtension,
  449. IN PMOUSE_INPUT_DATA CurrentInput,
  450. IN PHANDLER_DATA HandlerData,
  451. IN UCHAR Value,
  452. IN UCHAR LineState
  453. )
  454. /*++
  455. Routine Description:
  456. This is the protocol handler routine for the Microsoft Plus protocol.
  457. Arguments:
  458. CurrentInput - Pointer to the report packet.
  459. HandlerData - Instance specific static data for the handler.
  460. Value - The input buffer value.
  461. LineState - The serial port line state.
  462. Return Value:
  463. Returns TRUE if the handler has a complete report ready.
  464. --*/
  465. {
  466. BOOLEAN retval = FALSE;
  467. ULONG middleButton;
  468. Print(DeviceExtension, DBG_HANDLER_TRACE, ("MP protocol handler, enter\n"));
  469. if ((Value & MP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  470. if ((HandlerData->State != STATE3)) {
  471. //
  472. // We definitely have a synchronization problem (likely a data
  473. // overrun).
  474. //
  475. HandlerData->Error++;
  476. }
  477. else if ((HandlerData->PreviousButtons & MOUSE_BUTTON_3) != 0) {
  478. //
  479. // We didn't receive the expected fourth byte. Missed it?
  480. // Reset button 3 to zero.
  481. //
  482. HandlerData->PreviousButtons ^= MOUSE_BUTTON_3;
  483. HandlerData->Error++;
  484. }
  485. Print(DeviceExtension, DBG_HANDLER_ERROR,
  486. ("Synch error. State: %u\n",
  487. HandlerData->State
  488. ));
  489. HandlerData->State = STATE0;
  490. }
  491. else if (!(Value & MP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  492. HandlerData->Error++;
  493. Print(DeviceExtension, DBG_HANDLER_ERROR,
  494. ("Synch error. State: %u\n",
  495. HandlerData->State
  496. ));
  497. goto LExit;
  498. }
  499. //
  500. // Check for a line state error.
  501. //
  502. // if (LineState & ACE_LERR) {
  503. if (0) {
  504. //
  505. // Reset the handler state.
  506. //
  507. HandlerData->State = STATE0;
  508. HandlerData->Error++;
  509. Print(DeviceExtension, DBG_HANDLER_ERROR,
  510. ("Line status error: %#x\n", LineState));
  511. }
  512. else {
  513. //
  514. // Set the untranslated value.
  515. //
  516. HandlerData->Raw[HandlerData->State] = Value;
  517. Print(DeviceExtension, DBG_HANDLER_NOISE,
  518. ("State%u\n", HandlerData->State));
  519. switch (HandlerData->State) {
  520. case STATE0:
  521. case STATE1:
  522. HandlerData->State++;
  523. break;
  524. case STATE2:
  525. HandlerData->State++;
  526. //
  527. // Build the report.
  528. //
  529. CurrentInput->RawButtons =
  530. (HandlerData->Raw[0] & MP_BUTTON_LEFT) >> MP_BUTTON_LEFT_SR;
  531. CurrentInput->RawButtons |=
  532. (HandlerData->Raw[0] & MP_BUTTON_RIGHT) >> MP_BUTTON_RIGHT_SR;
  533. CurrentInput->RawButtons |=
  534. HandlerData->PreviousButtons & MOUSE_BUTTON_3;
  535. CurrentInput->LastX =
  536. (SCHAR)(HandlerData->Raw[1] |
  537. ((HandlerData->Raw[0] & MP_UPPER_MASKX) << MP_UPPER_MASKX_SL));
  538. CurrentInput->LastY =
  539. (SCHAR)(HandlerData->Raw[2] |
  540. ((HandlerData->Raw[0] & MP_UPPER_MASKY) << MP_UPPER_MASKY_SL));
  541. retval = TRUE;
  542. break;
  543. case STATE3:
  544. HandlerData->State = STATE0;
  545. middleButton =
  546. (HandlerData->Raw[STATE3] & MP_BUTTON_MIDDLE) >> MP_BUTTON_MIDDLE_SR;
  547. //
  548. // Send a report only if the middle button state changed.
  549. //
  550. if (middleButton ^ (HandlerData->PreviousButtons & MOUSE_BUTTON_3)) {
  551. //
  552. // Toggle the state of the middle button.
  553. //
  554. CurrentInput->RawButtons ^= MP_BUTTON_MIDDLE_MASK;
  555. CurrentInput->LastX = 0;
  556. CurrentInput->LastY = 0;
  557. //
  558. // Send the report one more time.
  559. //
  560. retval = TRUE;
  561. }
  562. break;
  563. default:
  564. Print(DeviceExtension, DBG_HANDLER_ERROR,
  565. ("MP Handler failure: incorrect state value.\n"
  566. ));
  567. ASSERT(FALSE);
  568. }
  569. }
  570. LExit:
  571. Print(DeviceExtension, DBG_HANDLER_TRACE, ("MP protocol handler: exit\n"));
  572. return retval;
  573. }
  574. BOOLEAN
  575. MSerHandlerBP(
  576. IN PDEVICE_EXTENSION DeviceExtension,
  577. IN PMOUSE_INPUT_DATA CurrentInput,
  578. IN PHANDLER_DATA HandlerData,
  579. IN UCHAR Value,
  580. IN UCHAR LineState
  581. )
  582. /*++
  583. Routine Description:
  584. This is the protocol handler routine for the Microsoft Ballpoint protocol.
  585. Arguments:
  586. CurrentInput - Pointer to the report packet.
  587. HandlerData - Instance specific static data for the handler.
  588. Value - The input buffer value.
  589. LineState - The serial port line state.
  590. Return Value:
  591. Returns TRUE if the handler has a complete report ready.
  592. --*/
  593. {
  594. BOOLEAN retval = FALSE;
  595. Print(DeviceExtension, DBG_HANDLER_TRACE, ("BP protocol handler, enter\n"));
  596. //
  597. // Check for synchronization errors.
  598. //
  599. if ((Value & BP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  600. HandlerData->Error++;
  601. Print(DeviceExtension, DBG_HANDLER_ERROR,
  602. ("Synch error. State: %u\n", HandlerData->State
  603. ));
  604. HandlerData->State = STATE0;
  605. }
  606. else if (!(Value & BP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  607. HandlerData->Error++;
  608. Print(DeviceExtension, DBG_HANDLER_ERROR,
  609. ("Synch error. State: %u\n", HandlerData->State
  610. ));
  611. goto LExit;
  612. }
  613. //
  614. // Check for a line state error.
  615. //
  616. //if (LineState & ACE_LERR) {
  617. if (0) {
  618. //
  619. // Reset the handler state.
  620. //
  621. HandlerData->State = STATE0;
  622. HandlerData->Error++;
  623. Print(DeviceExtension, DBG_HANDLER_NOISE,
  624. ("Line status error: %#x\n", LineState));
  625. }
  626. else {
  627. //
  628. // Set the untranslated value.
  629. //
  630. HandlerData->Raw[HandlerData->State] = Value;
  631. Print(DeviceExtension, DBG_HANDLER_NOISE,
  632. ("State%u\n", HandlerData->State));
  633. switch (HandlerData->State) {
  634. case STATE0:
  635. case STATE1:
  636. case STATE2:
  637. HandlerData->State++;
  638. break;
  639. case STATE3:
  640. HandlerData->State = STATE0;
  641. //
  642. // Build the report.
  643. //
  644. CurrentInput->RawButtons =
  645. (HandlerData->Raw[0] & BP_BUTTON_LEFT) >> BP_BUTTON_LEFT_SR;
  646. CurrentInput->RawButtons |=
  647. (HandlerData->Raw[0] & BP_BUTTON_RIGHT) >> BP_BUTTON_RIGHT_SR;
  648. #if 0
  649. CurrentInput->ButtonFlags |=
  650. (HandlerData->Raw[3] & BP_BUTTON_3) << BP_BUTTON_3_SL;
  651. CurrentInput->ButtonFlags |=
  652. (HandlerData->Raw[3] & BP_BUTTON_4) << BP_BUTTON_4_SL;
  653. #endif
  654. CurrentInput->LastX = HandlerData->Raw[3] & BP_SIGN_MASKX ?
  655. (LONG)(HandlerData->Raw[1] | (ULONG)(-1 & ~0xFF) |
  656. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL)):
  657. (LONG)(HandlerData->Raw[1] |
  658. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL));
  659. CurrentInput->LastY = HandlerData->Raw[3] & BP_SIGN_MASKY ?
  660. (LONG)(HandlerData->Raw[2] | (ULONG)(-1 & ~0xFF) |
  661. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL)):
  662. (LONG)(HandlerData->Raw[2] |
  663. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL));
  664. retval = TRUE;
  665. break;
  666. default:
  667. Print(DeviceExtension, DBG_HANDLER_ERROR,
  668. ("BP Handler failure: incorrect state value.\n"
  669. ));
  670. ASSERT(FALSE);
  671. }
  672. }
  673. LExit:
  674. Print(DeviceExtension, DBG_HANDLER_TRACE, ("BP protocol handler: exit\n"));
  675. return retval;
  676. }
  677. BOOLEAN
  678. MSerHandlerZ(
  679. IN PDEVICE_EXTENSION DeviceExtension,
  680. IN PMOUSE_INPUT_DATA CurrentInput,
  681. IN PHANDLER_DATA HandlerData,
  682. IN UCHAR Value,
  683. IN UCHAR LineState
  684. )
  685. /*++
  686. Routine Description:
  687. This is the protocol handler routine for the Microsoft Magellan Mouse
  688. (wheel mouse)
  689. Arguments:
  690. CurrentInput - Pointer to the report packet.
  691. HandlerData - Instance specific static data for the handler.
  692. Value - The input buffer value.
  693. LineState - The serial port line state.
  694. Return Value:
  695. Returns TRUE if the handler has a complete report ready.
  696. --*/
  697. {
  698. BOOLEAN retval = FALSE;
  699. ULONG middleButton;
  700. CHAR zMotion = 0;
  701. Print(DeviceExtension, DBG_HANDLER_TRACE, ("Z protocol handler, enter\n"));
  702. if ((Value & Z_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  703. if ((HandlerData->State != STATE3)) {
  704. //
  705. // We definitely have a synchronization problem (likely a data
  706. // overrun).
  707. //
  708. HandlerData->Error++;
  709. }
  710. Print(DeviceExtension, DBG_HANDLER_ERROR,
  711. ("Z Synch error #1. State: %u\n", HandlerData->State
  712. ));
  713. HandlerData->State = STATE0;
  714. }
  715. else if (!(Value & Z_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  716. HandlerData->Error++;
  717. Print(DeviceExtension, DBG_HANDLER_ERROR,
  718. ("Z Synch error #2. State: %u\n", HandlerData->State
  719. ));
  720. goto LExit;
  721. }
  722. //
  723. // Check for a line state error.
  724. //
  725. // if (LineState & ACE_LERR) {
  726. if (0) {
  727. //
  728. // Reset the handler state.
  729. //
  730. HandlerData->State = STATE0;
  731. HandlerData->Error++;
  732. Print(DeviceExtension, DBG_HANDLER_ERROR,
  733. ("Z Line status error: %#x\n", LineState));
  734. }
  735. else {
  736. //
  737. // Set the untranslated value.
  738. //
  739. HandlerData->Raw[HandlerData->State] = Value;
  740. Print(DeviceExtension, DBG_HANDLER_NOISE,
  741. ("Z State%u\n", HandlerData->State));
  742. switch (HandlerData->State) {
  743. case STATE0:
  744. case STATE1:
  745. case STATE2:
  746. HandlerData->State++;
  747. break;
  748. case STATE3:
  749. //
  750. // Check to see if the mouse is going to the high bits of
  751. // the wheel movement. If not, this is the last bit - transition
  752. // back to state0
  753. //
  754. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  755. HandlerData->State = STATE0;
  756. HandlerData->Raw[STATE4] = 0;
  757. retval = TRUE;
  758. }
  759. else {
  760. HandlerData->State++;
  761. }
  762. break;
  763. case STATE4:
  764. Print(DeviceExtension, DBG_HANDLER_NOISE,
  765. ("Z Got that 5th byte\n"));
  766. HandlerData->State = STATE0;
  767. retval = TRUE;
  768. break;
  769. default:
  770. Print(DeviceExtension, DBG_HANDLER_ERROR,
  771. ("Z Handler failure: incorrect state value.\n"
  772. ));
  773. ASSERT(FALSE);
  774. }
  775. if (retval) {
  776. CurrentInput->RawButtons = 0;
  777. if(HandlerData->Raw[STATE0] & Z_BUTTON_LEFT) {
  778. CurrentInput->RawButtons |= MOUSE_BUTTON_LEFT;
  779. }
  780. if(HandlerData->Raw[STATE0] & Z_BUTTON_RIGHT) {
  781. CurrentInput->RawButtons |= MOUSE_BUTTON_RIGHT;
  782. }
  783. if(HandlerData->Raw[STATE3] & Z_BUTTON_MIDDLE) {
  784. CurrentInput->RawButtons |= MOUSE_BUTTON_MIDDLE;
  785. }
  786. CurrentInput->LastX =
  787. (SCHAR)(HandlerData->Raw[STATE1] |
  788. ((HandlerData->Raw[0] & Z_UPPER_MASKX) << Z_UPPER_MASKX_SL));
  789. CurrentInput->LastY =
  790. (SCHAR)(HandlerData->Raw[STATE2] |
  791. ((HandlerData->Raw[0] & Z_UPPER_MASKY) << Z_UPPER_MASKY_SL));
  792. //
  793. // If the extra bit isn't set then the 4th byte contains
  794. // a 4 bit signed quantity for the wheel movement. if it
  795. // is set, then we need to combine the z info from the
  796. // two bytes
  797. //
  798. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  799. zMotion = HandlerData->Raw[STATE3] & Z_LOWER_MASKZ;
  800. //
  801. // Sign extend the 4 bit
  802. //
  803. if(zMotion & 0x08) {
  804. zMotion |= 0xf0;
  805. }
  806. } else {
  807. zMotion = ((HandlerData->Raw[STATE3] & Z_LOWER_MASKZ) |
  808. ((HandlerData->Raw[STATE4] & Z_UPPER_MASKZ)
  809. << Z_UPPER_MASKZ_SL));
  810. }
  811. if(zMotion == 0) {
  812. CurrentInput->ButtonData = 0;
  813. } else {
  814. CurrentInput->ButtonData = 0x0078;
  815. if(zMotion & 0x80) {
  816. CurrentInput->ButtonData = 0x0078;
  817. } else {
  818. CurrentInput->ButtonData = 0xff88;
  819. }
  820. CurrentInput->ButtonFlags |= MOUSE_WHEEL;
  821. }
  822. }
  823. }
  824. LExit:
  825. Print(DeviceExtension, DBG_HANDLER_TRACE, ("Z protocol handler: exit\n"));
  826. return retval;
  827. }