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.

1020 lines
25 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. //
  253. // Set DTR
  254. //
  255. Print(DeviceExtension, DBG_SS_NOISE, ("Setting DTR...\n"));
  256. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_DTR,
  257. DeviceExtension->TopOfStack,
  258. &event,
  259. &iosb);
  260. if (!NT_SUCCESS(status)) {
  261. return status;
  262. }
  263. //
  264. // Clear RTS
  265. //
  266. Print(DeviceExtension, DBG_SS_NOISE, ("Clearing RTS...\n"));
  267. status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_RTS,
  268. DeviceExtension->TopOfStack,
  269. &event,
  270. &iosb);
  271. if (!NT_SUCCESS(status)) {
  272. return status;
  273. }
  274. //
  275. // Set a timer for 200 ms
  276. //
  277. status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
  278. if (!NT_SUCCESS(status)) {
  279. Print(DeviceExtension, DBG_SS_ERROR,
  280. ("Timer failed with status %x\n", status));
  281. return status;
  282. }
  283. return status;
  284. }
  285. #define BUFFER_SIZE 256
  286. MOUSETYPE
  287. MSerDetect(
  288. PDEVICE_EXTENSION DeviceExtension
  289. )
  290. /*++
  291. Routine Description:
  292. Detection code for pointing devices that identify themselves at
  293. power on time.
  294. Arguments:
  295. Port - Pointer to the serial port.
  296. BaudClock - The external frequency driving the serial chip.
  297. Return Value:
  298. The type of mouse detected.
  299. --*/
  300. {
  301. ULONG count = 0;
  302. MOUSETYPE mouseType = NO_MOUSE;
  303. NTSTATUS status;
  304. ULONG i;
  305. CHAR receiveBuffer[BUFFER_SIZE];
  306. PAGED_CODE();
  307. Print(DeviceExtension, DBG_SS_TRACE,
  308. ("MSerDetect enter\n"));
  309. status = SerialMouseInitializePort(DeviceExtension);
  310. if (!NT_SUCCESS(status)) {
  311. Print(DeviceExtension, DBG_SS_ERROR,
  312. ("Initializing the port failed (%x)\n", status));
  313. // return status;
  314. }
  315. status = MSerPowerDown(DeviceExtension);
  316. if (!NT_SUCCESS(status)) {
  317. Print(DeviceExtension, DBG_SS_ERROR,
  318. ("PowerDown failed (%x)\n", status));
  319. // return status;
  320. }
  321. //
  322. // Set the baud rate.
  323. //
  324. SerialMouseSetBaudRate(DeviceExtension, MSER_BAUDRATE);
  325. //
  326. // Set the data format so that the possible answer can be recognized.
  327. //
  328. SerialMouseSetLineCtrl(DeviceExtension,
  329. &Protocol[MSER_PROTOCOL_MP].LineCtrl);
  330. //
  331. // Clean possible garbage in uart input buffer.
  332. //
  333. SerialMouseFlushReadBuffer(DeviceExtension);
  334. status = MSerPowerUp(DeviceExtension);
  335. if (!NT_SUCCESS(status)) {
  336. Print(DeviceExtension, DBG_SS_ERROR, ("Powerup failed (%x)\n", status));
  337. }
  338. //
  339. // Get the possible first reset character ('M' or 'B'), followed
  340. // by any other characters the hardware happens to send back.
  341. //
  342. // Note: Typically, we expect to get just one character ('M' or
  343. // 'B'), perhaps followed by a '2' or '3' (to indicate the
  344. // number of mouse buttons. On some machines, we're
  345. // getting extraneous characters before the 'M'.
  346. // We get extraneous characters after the expected data if this a
  347. // true PnP comm device
  348. //
  349. ASSERT(CSER_POWER_UP >= MINIMUM_RESET_TIME);
  350. status = SerialMouseSetReadTimeouts(DeviceExtension, 200);
  351. if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
  352. &receiveBuffer[count]))) {
  353. count++;
  354. SerialMouseSetReadTimeouts(DeviceExtension, 100);
  355. while (count < (BUFFER_SIZE - 1)) {
  356. if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
  357. &receiveBuffer[count]))) {
  358. count++;
  359. } else {
  360. break;
  361. }
  362. }
  363. }
  364. *(receiveBuffer + count) = 0;
  365. Print(DeviceExtension, DBG_SS_NOISE, ("Receive buffer:\n"));
  366. for (i = 0; i < count; i++) {
  367. Print(DeviceExtension, DBG_SS_NOISE, ("\t0x%x\n", receiveBuffer[i]));
  368. }
  369. //
  370. //
  371. // Analyze the possible mouse answer. Start at the beginning of the
  372. // "good" data in the receive buffer, ignoring extraneous characters
  373. // that may have come in before the 'M' or 'B'.
  374. //
  375. for (i = 0; i < count; i++) {
  376. if (receiveBuffer[i] == 'M') {
  377. if (receiveBuffer[i + 1] == '3') {
  378. Print(DeviceExtension, DBG_SS_INFO,
  379. ("Detected MSeries 3 buttons\n"));
  380. mouseType = MOUSE_3B;
  381. }
  382. else if (receiveBuffer[i + 1] == 'Z') {
  383. Print(DeviceExtension, DBG_SS_INFO,
  384. ("Detected Wheel Mouse\n"));
  385. mouseType = MOUSE_Z;
  386. }
  387. else {
  388. Print(DeviceExtension, DBG_SS_INFO,
  389. ("Detected MSeries 2 buttons\n"));
  390. mouseType = MOUSE_2B;
  391. }
  392. break;
  393. } else if (receiveBuffer[i] == 'B') {
  394. Print(DeviceExtension, DBG_SS_INFO,
  395. ("Detected Ballpoint\n"));
  396. mouseType = BALLPOINT;
  397. break;
  398. }
  399. }
  400. if (i >= count) {
  401. //
  402. // Special case: If another device is connected (CSeries, for
  403. // example) and this device sends a character (movement), the
  404. // minimum power up time might not be respected. Take
  405. // care of this unlikely case.
  406. //
  407. if (count != 0) {
  408. SerialMouseWait(DeviceExtension, -CSER_POWER_UP);
  409. }
  410. Print(DeviceExtension, DBG_SS_ERROR | DBG_SS_INFO,
  411. ("No MSeries detected\n"));
  412. mouseType = NO_MOUSE;
  413. }
  414. //
  415. // Make sure that all subsequent reads are blocking and do not timeout
  416. //
  417. if (mouseType != NO_MOUSE) {
  418. SerialMouseSetReadTimeouts(DeviceExtension, 0);
  419. }
  420. Print(DeviceExtension, DBG_SS_INFO,
  421. ("mouse type is %d\n", (ULONG) mouseType));
  422. return mouseType;
  423. }
  424. BOOLEAN
  425. MSerHandlerMP(
  426. IN PDEVICE_EXTENSION DeviceExtension,
  427. IN PMOUSE_INPUT_DATA CurrentInput,
  428. IN PHANDLER_DATA HandlerData,
  429. IN UCHAR Value,
  430. IN UCHAR LineState
  431. )
  432. /*++
  433. Routine Description:
  434. This is the protocol handler routine for the Microsoft Plus protocol.
  435. Arguments:
  436. CurrentInput - Pointer to the report packet.
  437. HandlerData - Instance specific static data for the handler.
  438. Value - The input buffer value.
  439. LineState - The serial port line state.
  440. Return Value:
  441. Returns TRUE if the handler has a complete report ready.
  442. --*/
  443. {
  444. BOOLEAN retval = FALSE;
  445. ULONG middleButton;
  446. Print(DeviceExtension, DBG_HANDLER_TRACE, ("MP protocol handler, enter\n"));
  447. if ((Value & MP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  448. if ((HandlerData->State != STATE3)) {
  449. //
  450. // We definitely have a synchronization problem (likely a data
  451. // overrun).
  452. //
  453. HandlerData->Error++;
  454. }
  455. else if ((HandlerData->PreviousButtons & MOUSE_BUTTON_3) != 0) {
  456. //
  457. // We didn't receive the expected fourth byte. Missed it?
  458. // Reset button 3 to zero.
  459. //
  460. HandlerData->PreviousButtons ^= MOUSE_BUTTON_3;
  461. HandlerData->Error++;
  462. }
  463. Print(DeviceExtension, DBG_HANDLER_ERROR,
  464. ("Synch error. State: %u\n",
  465. HandlerData->State
  466. ));
  467. HandlerData->State = STATE0;
  468. }
  469. else if (!(Value & MP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  470. HandlerData->Error++;
  471. Print(DeviceExtension, DBG_HANDLER_ERROR,
  472. ("Synch error. State: %u\n",
  473. HandlerData->State
  474. ));
  475. goto LExit;
  476. }
  477. //
  478. // Check for a line state error.
  479. //
  480. //
  481. // Set the untranslated value.
  482. //
  483. HandlerData->Raw[HandlerData->State] = Value;
  484. Print(DeviceExtension, DBG_HANDLER_NOISE,
  485. ("State%u\n", HandlerData->State));
  486. switch (HandlerData->State) {
  487. case STATE0:
  488. case STATE1:
  489. HandlerData->State++;
  490. break;
  491. case STATE2:
  492. HandlerData->State++;
  493. //
  494. // Build the report.
  495. //
  496. CurrentInput->RawButtons =
  497. (HandlerData->Raw[0] & MP_BUTTON_LEFT) >> MP_BUTTON_LEFT_SR;
  498. CurrentInput->RawButtons |=
  499. (HandlerData->Raw[0] & MP_BUTTON_RIGHT) >> MP_BUTTON_RIGHT_SR;
  500. CurrentInput->RawButtons |=
  501. HandlerData->PreviousButtons & MOUSE_BUTTON_3;
  502. CurrentInput->LastX =
  503. (SCHAR)(HandlerData->Raw[1] |
  504. ((HandlerData->Raw[0] & MP_UPPER_MASKX) << MP_UPPER_MASKX_SL));
  505. CurrentInput->LastY =
  506. (SCHAR)(HandlerData->Raw[2] |
  507. ((HandlerData->Raw[0] & MP_UPPER_MASKY) << MP_UPPER_MASKY_SL));
  508. retval = TRUE;
  509. break;
  510. case STATE3:
  511. HandlerData->State = STATE0;
  512. middleButton =
  513. (HandlerData->Raw[STATE3] & MP_BUTTON_MIDDLE) >> MP_BUTTON_MIDDLE_SR;
  514. //
  515. // Send a report only if the middle button state changed.
  516. //
  517. if (middleButton ^ (HandlerData->PreviousButtons & MOUSE_BUTTON_3)) {
  518. //
  519. // Toggle the state of the middle button.
  520. //
  521. CurrentInput->RawButtons ^= MP_BUTTON_MIDDLE_MASK;
  522. CurrentInput->LastX = 0;
  523. CurrentInput->LastY = 0;
  524. //
  525. // Send the report one more time.
  526. //
  527. retval = TRUE;
  528. }
  529. break;
  530. default:
  531. Print(DeviceExtension, DBG_HANDLER_ERROR,
  532. ("MP Handler failure: incorrect state value.\n"
  533. ));
  534. ASSERT(FALSE);
  535. }
  536. LExit:
  537. Print(DeviceExtension, DBG_HANDLER_TRACE, ("MP protocol handler: exit\n"));
  538. return retval;
  539. }
  540. BOOLEAN
  541. MSerHandlerBP(
  542. IN PDEVICE_EXTENSION DeviceExtension,
  543. IN PMOUSE_INPUT_DATA CurrentInput,
  544. IN PHANDLER_DATA HandlerData,
  545. IN UCHAR Value,
  546. IN UCHAR LineState
  547. )
  548. /*++
  549. Routine Description:
  550. This is the protocol handler routine for the Microsoft Ballpoint protocol.
  551. Arguments:
  552. CurrentInput - Pointer to the report packet.
  553. HandlerData - Instance specific static data for the handler.
  554. Value - The input buffer value.
  555. LineState - The serial port line state.
  556. Return Value:
  557. Returns TRUE if the handler has a complete report ready.
  558. --*/
  559. {
  560. BOOLEAN retval = FALSE;
  561. Print(DeviceExtension, DBG_HANDLER_TRACE, ("BP protocol handler, enter\n"));
  562. //
  563. // Check for synchronization errors.
  564. //
  565. if ((Value & BP_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  566. HandlerData->Error++;
  567. Print(DeviceExtension, DBG_HANDLER_ERROR,
  568. ("Synch error. State: %u\n", HandlerData->State
  569. ));
  570. HandlerData->State = STATE0;
  571. }
  572. else if (!(Value & BP_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  573. HandlerData->Error++;
  574. Print(DeviceExtension, DBG_HANDLER_ERROR,
  575. ("Synch error. State: %u\n", HandlerData->State
  576. ));
  577. goto LExit;
  578. }
  579. //
  580. // Check for a line state error.
  581. //
  582. //
  583. // Set the untranslated value.
  584. //
  585. HandlerData->Raw[HandlerData->State] = Value;
  586. Print(DeviceExtension, DBG_HANDLER_NOISE,
  587. ("State%u\n", HandlerData->State));
  588. switch (HandlerData->State) {
  589. case STATE0:
  590. case STATE1:
  591. case STATE2:
  592. HandlerData->State++;
  593. break;
  594. case STATE3:
  595. HandlerData->State = STATE0;
  596. //
  597. // Build the report.
  598. //
  599. CurrentInput->RawButtons =
  600. (HandlerData->Raw[0] & BP_BUTTON_LEFT) >> BP_BUTTON_LEFT_SR;
  601. CurrentInput->RawButtons |=
  602. (HandlerData->Raw[0] & BP_BUTTON_RIGHT) >> BP_BUTTON_RIGHT_SR;
  603. CurrentInput->LastX = HandlerData->Raw[3] & BP_SIGN_MASKX ?
  604. (LONG)(HandlerData->Raw[1] | (ULONG)(-1 & ~0xFF) |
  605. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL)):
  606. (LONG)(HandlerData->Raw[1] |
  607. ((HandlerData->Raw[0] & BP_UPPER_MASKX) << BP_UPPER_MASKX_SL));
  608. CurrentInput->LastY = HandlerData->Raw[3] & BP_SIGN_MASKY ?
  609. (LONG)(HandlerData->Raw[2] | (ULONG)(-1 & ~0xFF) |
  610. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL)):
  611. (LONG)(HandlerData->Raw[2] |
  612. ((HandlerData->Raw[0] & BP_UPPER_MASKY) << BP_UPPER_MASKY_SL));
  613. retval = TRUE;
  614. break;
  615. default:
  616. Print(DeviceExtension, DBG_HANDLER_ERROR,
  617. ("BP Handler failure: incorrect state value.\n"
  618. ));
  619. ASSERT(FALSE);
  620. }
  621. LExit:
  622. Print(DeviceExtension, DBG_HANDLER_TRACE, ("BP protocol handler: exit\n"));
  623. return retval;
  624. }
  625. BOOLEAN
  626. MSerHandlerZ(
  627. IN PDEVICE_EXTENSION DeviceExtension,
  628. IN PMOUSE_INPUT_DATA CurrentInput,
  629. IN PHANDLER_DATA HandlerData,
  630. IN UCHAR Value,
  631. IN UCHAR LineState
  632. )
  633. /*++
  634. Routine Description:
  635. This is the protocol handler routine for the Microsoft Magellan Mouse
  636. (wheel mouse)
  637. Arguments:
  638. CurrentInput - Pointer to the report packet.
  639. HandlerData - Instance specific static data for the handler.
  640. Value - The input buffer value.
  641. LineState - The serial port line state.
  642. Return Value:
  643. Returns TRUE if the handler has a complete report ready.
  644. --*/
  645. {
  646. BOOLEAN retval = FALSE;
  647. ULONG middleButton;
  648. CHAR zMotion = 0;
  649. Print(DeviceExtension, DBG_HANDLER_TRACE, ("Z protocol handler, enter\n"));
  650. if ((Value & Z_SYNCH_BIT) && (HandlerData->State != STATE0)) {
  651. if ((HandlerData->State != STATE3)) {
  652. //
  653. // We definitely have a synchronization problem (likely a data
  654. // overrun).
  655. //
  656. HandlerData->Error++;
  657. }
  658. Print(DeviceExtension, DBG_HANDLER_ERROR,
  659. ("Z Synch error #1. State: %u\n", HandlerData->State
  660. ));
  661. HandlerData->State = STATE0;
  662. }
  663. else if (!(Value & Z_SYNCH_BIT) && (HandlerData->State == STATE0)) {
  664. HandlerData->Error++;
  665. Print(DeviceExtension, DBG_HANDLER_ERROR,
  666. ("Z Synch error #2. State: %u\n", HandlerData->State
  667. ));
  668. goto LExit;
  669. }
  670. //
  671. // Check for a line state error.
  672. //
  673. //
  674. // Set the untranslated value.
  675. //
  676. HandlerData->Raw[HandlerData->State] = Value;
  677. Print(DeviceExtension, DBG_HANDLER_NOISE,
  678. ("Z State%u\n", HandlerData->State));
  679. switch (HandlerData->State) {
  680. case STATE0:
  681. case STATE1:
  682. case STATE2:
  683. HandlerData->State++;
  684. break;
  685. case STATE3:
  686. //
  687. // Check to see if the mouse is going to the high bits of
  688. // the wheel movement. If not, this is the last bit - transition
  689. // back to state0
  690. //
  691. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  692. HandlerData->State = STATE0;
  693. HandlerData->Raw[STATE4] = 0;
  694. retval = TRUE;
  695. }
  696. else {
  697. HandlerData->State++;
  698. }
  699. break;
  700. case STATE4:
  701. Print(DeviceExtension, DBG_HANDLER_NOISE,
  702. ("Z Got that 5th byte\n"));
  703. HandlerData->State = STATE0;
  704. retval = TRUE;
  705. break;
  706. default:
  707. Print(DeviceExtension, DBG_HANDLER_ERROR,
  708. ("Z Handler failure: incorrect state value.\n"
  709. ));
  710. ASSERT(FALSE);
  711. }
  712. if (retval) {
  713. CurrentInput->RawButtons = 0;
  714. if(HandlerData->Raw[STATE0] & Z_BUTTON_LEFT) {
  715. CurrentInput->RawButtons |= MOUSE_BUTTON_LEFT;
  716. }
  717. if(HandlerData->Raw[STATE0] & Z_BUTTON_RIGHT) {
  718. CurrentInput->RawButtons |= MOUSE_BUTTON_RIGHT;
  719. }
  720. if(HandlerData->Raw[STATE3] & Z_BUTTON_MIDDLE) {
  721. CurrentInput->RawButtons |= MOUSE_BUTTON_MIDDLE;
  722. }
  723. CurrentInput->LastX =
  724. (SCHAR)(HandlerData->Raw[STATE1] |
  725. ((HandlerData->Raw[0] & Z_UPPER_MASKX) << Z_UPPER_MASKX_SL));
  726. CurrentInput->LastY =
  727. (SCHAR)(HandlerData->Raw[STATE2] |
  728. ((HandlerData->Raw[0] & Z_UPPER_MASKY) << Z_UPPER_MASKY_SL));
  729. //
  730. // If the extra bit isn't set then the 4th byte contains
  731. // a 4 bit signed quantity for the wheel movement. if it
  732. // is set, then we need to combine the z info from the
  733. // two bytes
  734. //
  735. if((HandlerData->Raw[STATE3] & Z_EXTRA_BIT) == 0) {
  736. zMotion = HandlerData->Raw[STATE3] & Z_LOWER_MASKZ;
  737. //
  738. // Sign extend the 4 bit
  739. //
  740. if(zMotion & 0x08) {
  741. zMotion |= 0xf0;
  742. }
  743. } else {
  744. zMotion = ((HandlerData->Raw[STATE3] & Z_LOWER_MASKZ) |
  745. ((HandlerData->Raw[STATE4] & Z_UPPER_MASKZ)
  746. << Z_UPPER_MASKZ_SL));
  747. }
  748. if(zMotion == 0) {
  749. CurrentInput->ButtonData = 0;
  750. } else {
  751. CurrentInput->ButtonData = 0x0078;
  752. if(zMotion & 0x80) {
  753. CurrentInput->ButtonData = 0x0078;
  754. } else {
  755. CurrentInput->ButtonData = 0xff88;
  756. }
  757. CurrentInput->ButtonFlags |= MOUSE_WHEEL;
  758. }
  759. }
  760. LExit:
  761. Print(DeviceExtension, DBG_HANDLER_TRACE, ("Z protocol handler: exit\n"));
  762. return retval;
  763. }