?? mseries.c
字號(hào):
/*++
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved
Copyright (c) 1993 Logitech Inc.
Module Name:
mseries.c
Abstract:
Environment:
Kernel mode only.
Notes:
Revision History:
--*/
//
// Includes.
//
#include "ntddk.h"
#include "mouser.h"
#include "debug.h"
#include "cseries.h"
#include "mseries.h"
//
// Use the alloc_text pragma to specify the driver initialization routines
// (they can be paged out).
//
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,MSerSetProtocol)
#pragma alloc_text(PAGE,MSerPowerUp)
#pragma alloc_text(PAGE,MSerPowerDown)
#pragma alloc_text(PAGE,MSerDetect)
#endif // ALLOC_PRAGMA
//
// Constants.
//
#define MSER_BAUDRATE 1200
#define MAX_RESET_BUFFER 8
#define MINIMUM_RESET_TIME (200 * MS_TO_100_NS)
//
// Microsoft Plus.
//
#define MP_SYNCH_BIT 0x40
#define MP_BUTTON_LEFT 0x20
#define MP_BUTTON_RIGHT 0x10
#define MP_BUTTON_MIDDLE 0x20
#define MP_BUTTON_LEFT_SR 5
#define MP_BUTTON_RIGHT_SR 3
#define MP_BUTTON_MIDDLE_SR 3
#define MP_BUTTON_MIDDLE_MASK 0x04
#define MP_UPPER_MASKX 0x03
#define MP_UPPER_MASKY 0x0C
#define MP_UPPER_MASKX_SL 6
#define MP_UPPER_MASKY_SL 4
//
// Microsoft BallPoint.
//
#define BP_SYNCH_BIT 0x40
#define BP_BUTTON_LEFT 0x20
#define BP_BUTTON_RIGHT 0x10
#define BP_BUTTON_3 0x04
#define BP_BUTTON_4 0x08
#define BP_BUTTON_LEFT_SR 5
#define BP_BUTTON_RIGHT_SR 3
#define BP_BUTTON_3_SL 0
#define BP_BUTTON_4_SL 0
#define BP_UPPER_MASKX 0x03
#define BP_UPPER_MASKY 0x0C
#define BP_UPPER_MASKX_SL 6
#define BP_UPPER_MASKY_SL 4
#define BP_SIGN_MASKX 0x01
#define BP_SIGN_MASKY 0x02
//
// Microsoft Magellan Mouse.
//
#define Z_SYNCH_BIT 0x40
#define Z_EXTRA_BIT 0x20
#define Z_BUTTON_LEFT 0x20
#define Z_BUTTON_RIGHT 0x10
#define Z_BUTTON_MIDDLE 0x10
#define Z_BUTTON_LEFT_SR 5
#define Z_BUTTON_RIGHT_SR 3
#define Z_BUTTON_MIDDLE_SR 3
#define Z_BUTTON_MIDDLE_MASK 0x04
#define Z_UPPER_MASKX 0x03
#define Z_UPPER_MASKY 0x0C
#define Z_UPPER_MASKZ 0x0F
#define Z_LOWER_MASKZ 0x0F
#define Z_UPPER_MASKX_SL 6
#define Z_UPPER_MASKY_SL 4
#define Z_UPPER_MASKZ_SL 4
//
// Type definitions.
//
typedef struct _PROTOCOL {
PPROTOCOL_HANDLER Handler;
// UCHAR LineCtrl;
SERIAL_LINE_CONTROL LineCtrl;
} PROTOCOL;
//
// This list is indexed by protocol values MSER_PROTOCOL_*.
//
static PROTOCOL Protocol[] = {
{
MSerHandlerMP, // Microsoft Plus
// ACE_7BW | ACE_1SB
{ STOP_BIT_1, NO_PARITY, 7 }
},
{
MSerHandlerBP, // BALLPOINT
// ACE_7BW | ACE_1SB
{ STOP_BIT_1, NO_PARITY, 7 }
},
{
MSerHandlerZ, // Magellan Mouse
// ACE_7BW | ACE_1SB
{ STOP_BIT_1, NO_PARITY, 7 }
}
};
PPROTOCOL_HANDLER
MSerSetProtocol(
PDEVICE_EXTENSION DeviceExtension,
UCHAR NewProtocol
)
/*++
Routine Description:
Set the mouse protocol. This function only sets the serial port
line control register.
Arguments:
Port - Pointer to the serial port.
NewProtocol - Index into the protocol table.
Return Value:
Pointer to the protocol handler function.
--*/
{
ASSERT(NewProtocol < MSER_PROTOCOL_MAX);
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE, ("MSerSetProtocol called\n"));
//
// Set the protocol
//
SerialMouseSetLineCtrl(DeviceExtension, &Protocol[NewProtocol].LineCtrl);
return Protocol[NewProtocol].Handler;
}
NTSTATUS
MSerPowerUp(
PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
Powers up the mouse. Just sets the RTS and DTR lines and returns.
Arguments:
Port - Pointer to the serial port.
Return Value:
TRUE.
--*/
{
IO_STATUS_BLOCK iosb;
NTSTATUS status;
KEVENT event;
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE, ("MSerPowerUp called\n"));
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// Clear DTR
//
Print(DeviceExtension, DBG_SS_NOISE, ("Clearing DTR...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_DTR,
DeviceExtension->TopOfStack,
&event,
&iosb
);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Clear RTS
//
Print(DeviceExtension, DBG_SS_NOISE, ("Clearing RTS...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_RTS,
DeviceExtension->TopOfStack,
&event,
&iosb
);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Set a timer for 200 ms
//
status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("Timer failed with status %x\n", status ));
return status;
}
//
// set DTR
//
Print(DeviceExtension, DBG_SS_NOISE, ("Setting DTR...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_DTR,
DeviceExtension->TopOfStack,
&event,
&iosb
);
if (!NT_SUCCESS(status)) {
return status;
}
status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("Timer failed with status %x\n", status ));
return status;
}
//
// set RTS
//
Print(DeviceExtension, DBG_SS_NOISE, ("Setting RTS...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_RTS,
DeviceExtension->TopOfStack,
&event,
&iosb
);
status = SerialMouseWait(DeviceExtension, -175 * MS_TO_100_NS);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("Timer failed with status %x\n", status ));
return status;
}
return status;
}
NTSTATUS
MSerPowerDown(
PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
Powers down the mouse. Sets the RTS line to an inactive state.
Arguments:
Port - Pointer to the serial port.
Return Value:
TRUE.
--*/
{
IO_STATUS_BLOCK iosb;
SERIAL_HANDFLOW shf;
KEVENT event;
NTSTATUS status;
ULONG bits;
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE, ("MSerPowerDown called\n"));
KeInitializeEvent(&event,
NotificationEvent,
FALSE
);
//
// Set DTR
//
Print(DeviceExtension, DBG_SS_NOISE, ("Setting DTR...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_SET_DTR,
DeviceExtension->TopOfStack,
&event,
&iosb);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Clear RTS
//
Print(DeviceExtension, DBG_SS_NOISE, ("Clearing RTS...\n"));
status = SerialMouseIoSyncIoctl(IOCTL_SERIAL_CLR_RTS,
DeviceExtension->TopOfStack,
&event,
&iosb);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Set a timer for 200 ms
//
status = SerialMouseWait(DeviceExtension, -PAUSE_200_MS);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("Timer failed with status %x\n", status));
return status;
}
return status;
}
#define BUFFER_SIZE 256
MOUSETYPE
MSerDetect(
PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
Detection code for pointing devices that identify themselves at
power on time.
Arguments:
Port - Pointer to the serial port.
BaudClock - The external frequency driving the serial chip.
Return Value:
The type of mouse detected.
--*/
{
ULONG count = 0;
MOUSETYPE mouseType = NO_MOUSE;
NTSTATUS status;
ULONG i;
CHAR receiveBuffer[BUFFER_SIZE];
PAGED_CODE();
Print(DeviceExtension, DBG_SS_TRACE,
("MSerDetect enter\n"));
status = SerialMouseInitializePort(DeviceExtension);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("Initializing the port failed (%x)\n", status));
// return status;
}
status = MSerPowerDown(DeviceExtension);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR,
("PowerDown failed (%x)\n", status));
// return status;
}
//
// Set the baud rate.
//
SerialMouseSetBaudRate(DeviceExtension, MSER_BAUDRATE);
//
// Set the data format so that the possible answer can be recognized.
//
SerialMouseSetLineCtrl(DeviceExtension,
&Protocol[MSER_PROTOCOL_MP].LineCtrl);
//
// Clean possible garbage in uart input buffer.
//
SerialMouseFlushReadBuffer(DeviceExtension);
status = MSerPowerUp(DeviceExtension);
if (!NT_SUCCESS(status)) {
Print(DeviceExtension, DBG_SS_ERROR, ("Powerup failed (%x)\n", status));
}
//
// Get the possible first reset character ('M' or 'B'), followed
// by any other characters the hardware happens to send back.
//
// Note: Typically, we expect to get just one character ('M' or
// 'B'), perhaps followed by a '2' or '3' (to indicate the
// number of mouse buttons. On some machines, we're
// getting extraneous characters before the 'M'.
// We get extraneous characters after the expected data if this a
// true PnP comm device
//
ASSERT(CSER_POWER_UP >= MINIMUM_RESET_TIME);
status = SerialMouseSetReadTimeouts(DeviceExtension, 200);
if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
&receiveBuffer[count]))) {
count++;
SerialMouseSetReadTimeouts(DeviceExtension, 100);
while (count < (BUFFER_SIZE - 1)) {
if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension,
&receiveBuffer[count]))) {
count++;
} else {
break;
}
}
}
*(receiveBuffer + count) = 0;
Print(DeviceExtension, DBG_SS_NOISE, ("Receive buffer:\n"));
for (i = 0; i < count; i++) {
Print(DeviceExtension, DBG_SS_NOISE, ("\t0x%x\n", receiveBuffer[i]));
}
//
//
// Analyze the possible mouse answer. Start at the beginning of the
// "good" data in the receive buffer, ignoring extraneous characters
// that may have come in before the 'M' or 'B'.
//
for (i = 0; i < count; i++) {
if (receiveBuffer[i] == 'M') {
if (receiveBuffer[i + 1] == '3') {
Print(DeviceExtension, DBG_SS_INFO,
("Detected MSeries 3 buttons\n"));
mouseType = MOUSE_3B;
}
else if (receiveBuffer[i + 1] == 'Z') {
Print(DeviceExtension, DBG_SS_INFO,
("Detected Wheel Mouse\n"));
mouseType = MOUSE_Z;
}
else {
Print(DeviceExtension, DBG_SS_INFO,
("Detected MSeries 2 buttons\n"));
mouseType = MOUSE_2B;
}
break;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -