?? sermouse.c
字號:
}
ctmo.ReadIntervalTimeout = MAXDWORD;
ctmo.ReadTotalTimeoutMultiplier = 0;
ctmo.ReadTotalTimeoutConstant = 0;
if ( !SetCommTimeouts(g_hSerial, &ctmo) ) {
DEBUGMSG(1, (TEXT("SetCommTimeouts error %d\r\n"), GetLastError()));
return (FALSE);
}
if ( !SetCommMask (g_hSerial, EV_RXCHAR) ) {
DEBUGMSG (ZONE_ERROR, (TEXT("Error from SetCommMask %d\r\n"), GetLastError()));
return (FALSE);
}
FUNC("-InitSerialPort");
return (TRUE);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
DWORD
SRM_Init(
DWORD dwInitParam
)
{
BOOL fRet = FALSE;
FUNC("+SRM_Init");
g_hReadThread = NULL;
g_hSerial = (HANDLE) NULL;
g_hThreadStopped = CreateEvent (0, FALSE, FALSE, 0);
g_fStopThread = FALSE;
if ( DetectSerialMouse(dwInitParam) ) {
DEBUGMSG(1, (TEXT("Serial Mouse Found.\r\n")));
g_hReadThread = CreateThread(NULL, 0, ReadThread, 0, 0, NULL);
if ( g_hReadThread == NULL ) {
DEBUGMSG(1, (TEXT("Fatal Error! Failed to create SerMouse Read thread.\r\n")));
return (FALSE);
} else {
// We don't need the thread handle we just got, so we're going to
// close it right away.
CloseHandle(g_hReadThread);
g_hReadThread = NULL;
}
fRet = TRUE;
}
FUNC("-SRM_Init");
return (fRet);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
BOOL
SRM_Deinit(
DWORD dwData
)
{
FUNC("+SRM_Deinit");
//
// Tell the ReadThread to shut down as soon as possible.
//
g_fStopThread = TRUE;
if ( g_hSerial ) {
//
// WakeUp the WaitCommEvent if necessary
//
SetCommMask (g_hSerial, 0);
}
WaitForSingleObject(g_hThreadStopped, 2000); // Don't wait forever.
DEBUGMSG(ZONE_INIT, (TEXT("THREAD EXIT...\r\n")));
CloseHandle(g_hThreadStopped);
if ( g_hSerial != NULL ) {
CloseHandle(g_hSerial);
g_hSerial = NULL;
}
if ( g_hReadThread != NULL ) {
CloseHandle(g_hReadThread);
g_hReadThread = NULL;
}
FUNC("-SRM_Deinit");
return (TRUE);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ULONG CALLBACK
ReadThread(PVOID pv)
{
const UINT8 cSyncBitMask = 0x40;
UINT8 serialBytes[3];
UINT8 rawData[3];
UINT8 curByte = 0;
BOOL bSuccess;
DWORD dwBytesRead;
DWORD count;
DWORD fdwCommMask;
FUNC("+ReadThread");
//
// The thread can be exitted by setting g_fStopThread.
//
while ( !g_fStopThread ) {
//
// We spend most of our time waiting for a serial event here.
//
WaitCommEvent (g_hSerial, &fdwCommMask, 0);
DEBUGMSG(ZONE_READTHREAD, (TEXT("SerMouse : ReadThread : Past WaitCommEvent\r\n")));
if ( fdwCommMask & EV_RXCHAR ) {
//
// We've woken up due to a real character arriving.
//
DEBUGMSG(ZONE_READTHREAD, (TEXT("SerMouse : ReadThread : Char ready\r\n")));
do {
//
// Continue to read the serial port while data is available.
//
bSuccess = ReadFile(g_hSerial, &serialBytes, 3, &dwBytesRead, NULL);
//
// Only get 7-bits of data back from ReadFile here.
//
serialBytes[0] &= 0x7F;
serialBytes[1] &= 0x7F;
serialBytes[2] &= 0x7F;
if ( !bSuccess ) {
DEBUGMSG(ZONE_ERROR, (TEXT("SerMouse : ReadFile error %d\r\n"), GetLastError()));
} else if ( dwBytesRead == 0 ) {
//
// Timed out with no data read. Do nothing.
//
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : ReadFile timed out with zero bytes\r\n")));
} else {
//
// Successfully received commands from the mouse.
//
DEBUGMSG(ZONE_READTHREAD, (TEXT("SerMouse : ReadThread : Read %d bytes\r\n"), dwBytesRead));
for ( count = 0; count < dwBytesRead; count++ ) {
// Pick the byte up
rawData[curByte] = serialBytes[count];
switch ( curByte ) {
// First byte has the sync bit set, next two don't.
case 0:
if ( (rawData[0] & cSyncBitMask) != 0 ) {
curByte++;
}
break;
case 1:
if ( (rawData[1] & cSyncBitMask) == 0 ) {
curByte++;
} else {
curByte = 0;
}
break;
case 2:
if ( (rawData[2] & cSyncBitMask) == 0 ) {
SendData(rawData);
}
curByte = 0;
break;
}
}
}
} while ( (!g_fStopThread) && dwBytesRead && bSuccess );
} else {
DEBUGMSG(ZONE_READTHREAD, (TEXT("SerMouse : ReadThread : NO CHAR!!!\r\n")));
}
}
//
// Signal to Deinit that we are exiting now, so it's safe to cleanup.
//
SetEvent (g_hThreadStopped);
return (1);
}
// -----------------------------------------------------------------------------
// UINT8 rawData[] assumed to be 3 long.
// -----------------------------------------------------------------------------
BOOL
SendData(
UINT8 rawData[]
)
{
unsigned int evfMouse = 0;
static BOOL bLastB0Down = FALSE;
static BOOL bLastB1Down = FALSE;
BOOL bButton0Down;
BOOL bButton1Down;
INT16 xOffset;
INT16 yOffset;
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : +SendData()\r\n")));
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : RawData[0x%02X][0x%02X][0x%02X]\r\n"),
rawData[0], rawData[1], rawData[2]));
bButton0Down = ((rawData[0] & gcB0BitMask) != 0);
bButton1Down = ((rawData[0] & gcB1BitMask) != 0);
xOffset = (INT8)(((rawData[0] & 0x03) << 6) | rawData[1]);
yOffset = (INT8)(((rawData[0] & 0x0C) << 4) | rawData[2]);
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : xOffset = %d, yOffset = %d\r\n"), xOffset, yOffset));
if ( xOffset || yOffset )
evfMouse |= MOUSEEVENTF_MOVE;
if ( bLastB0Down != bButton0Down || bButton0Down ) {
if ( bButton0Down ) {
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : Left Button Down\r\n")));
evfMouse |= MOUSEEVENTF_LEFTDOWN;
} else {
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : Left Button Up\r\n")));
evfMouse |= MOUSEEVENTF_LEFTUP;
}
bLastB0Down = bButton0Down;
}
if ( bLastB1Down != bButton1Down || bButton1Down ) {
if ( bButton1Down ) {
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : Right Button Down\r\n")));
evfMouse |= MOUSEEVENTF_RIGHTDOWN;
} else {
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : Right Button Up\r\n")));
evfMouse |= MOUSEEVENTF_RIGHTUP;
}
bLastB1Down = bButton1Down;
}
mouse_event(evfMouse, xOffset, yOffset, 0, 0);
DEBUGMSG(ZONE_DATA, (TEXT("SerMouse : -SendData()\r\n")));
return (TRUE);
}
// -----------------------------------------------------------------------------
//
// These are the required entry points needed by DEVICE.EXE in order to
// load as a device driver. The Serial Mouse driver is pretty simply though
// so all we need to do is load and run. We only implement Init and Deinit.
//
// You could make a nice little Mouse Set Speed utility by allowing an app
// to do a CreateFile on "SRM1:" and making IOCTL calls. Thus you'd also have
// to implement SRM_Open, SRM_Close, SRM_IOControl.
//
// -----------------------------------------------------------------------------
DWORD SRM_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {return (4);}
BOOL SRM_Close(DWORD dwData) {return (TRUE);}
DWORD SRM_Read (DWORD dwData, LPVOID pBuf, DWORD Len) {return (0);}
DWORD SRM_Write(DWORD dwData, LPCVOID pBuf, DWORD Len) {return (0);}
DWORD SRM_Seek (DWORD dwData, long pos, DWORD type) {return (DWORD)-1;}
VOID SRM_PowerUp (VOID) {}
VOID SRM_PowerDown(VOID) {}
BOOL SRM_IOControl(DWORD p1, DWORD p2, PBYTE p3, DWORD p4, PBYTE p5,
DWORD p6, PDWORD p7) {return (TRUE);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -