ps2mouse.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 213 行

CPP
213
字号
/* -*-C-*-
 *
 * $Revision: 1.1 $
 *   $Author: kwelton $
 *     $Date: 2000/04/12 00:50:42 $
 *
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 *
 * Copyright (c) 1995-1998  Microsoft Corporation
 * Copyright (c) 2000 ARM Limited
 * All Rights Reserved
 */

#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <rio.h>

#include "ps2port.hpp"
#include "ps2mouse.hpp"
#include "ps2keybd.hpp"

BOOL Ps2Mouse::Initialize(Ps2Port *pp2p)
{
    m_pp2p = pp2p;
    m_hevInterrupt = NULL;
    m_ui8ButtonState = 0;
    m_cReportFormatLength = pp2p -> bIntelliMouseFound() ? 4 : 3;

    return TRUE;
}

static BOOL IsValidTriplet(char status, char x, char y)
{
    BOOL fNegativeX, fNegativeY;

    fNegativeX = status & 0x10;
    fNegativeY = status & 0x20;

    if (!(status & 0x08))
        return FALSE;

    if ((fNegativeX && (x >= 0)) || ((!fNegativeX) && (x < 0)))
        return FALSE;

    if ((fNegativeY && (y >= 0)) || ((!fNegativeY) && (y < 0)))
        return FALSE;

    return TRUE;
}

BOOL Ps2Mouse::IsrThreadProc(void)
{
    bool bInPacket = FALSE;
    const int cmsInPacketTimeout = 50;
    int cmsWaitTimeout;
    int cBytes = 0;
    UINT8 ui8Data;
    INT8 buf[4];
    long x, y;
    long w = 0;
    BYTE bIRQ, bSYSINTR;
    DWORD dwRet;
    UINT8 ui8Buttons;
    UINT8 ui8XorButtons;
    unsigned int evfMouse;

    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (m_hevInterrupt == NULL)
        goto leave;

    // Convert the IRQ value to a SYSINTR value and store in HWObj.
    bIRQ = (BYTE) RIO_IRQ_MOUSE;

    KernelIoControl(IOCTL_HAL_TRANSLATE_IRQ, (LPVOID) &bIRQ, sizeof(bIRQ),
                    (LPVOID) &bSYSINTR, sizeof(bSYSINTR), &dwRet);

    if (!InterruptInitialize(bSYSINTR, m_hevInterrupt, NULL, 0))
        goto leave;

    m_pp2p -> MouseInterruptEnable();

    for (;;)
    {
      wait_for_interrupt:
        if (bInPacket)
            cmsWaitTimeout = cmsInPacketTimeout;
        else
            cmsWaitTimeout = INFINITE;

        if (WaitForSingleObject(m_hevInterrupt,
                                cmsWaitTimeout) == WAIT_TIMEOUT)
        {
            cBytes = 0;
            bInPacket = FALSE;
            DEBUGMSG(1, (TEXT("inpacket timeout\r\n")));
            goto wait_for_interrupt;
        }

        if (m_pp2p -> MouseDataRead(&ui8Data))
        {
            if (cBytes == 0)
                bInPacket = TRUE;

            if (cBytes < m_cReportFormatLength)
                buf[cBytes++] = ui8Data;

            if (cBytes == m_cReportFormatLength)
            {
                evfMouse = 0;

                ui8XorButtons = buf[0] ^ m_ui8ButtonState;
                if (ui8XorButtons)
                {
                    ui8Buttons = buf[0];

                    if (ui8XorButtons & 0x01)
                    {
                        if (ui8Buttons & 0x01)
                            evfMouse |= MOUSEEVENTF_LEFTDOWN;
                        else
                            evfMouse |= MOUSEEVENTF_LEFTUP;
                    }

                    if (ui8XorButtons & 0x02)
                    {
                        if (ui8Buttons & 0x02)
                            evfMouse |= MOUSEEVENTF_RIGHTDOWN;
                        else
                            evfMouse |= MOUSEEVENTF_RIGHTUP;
                    }

                    if (ui8XorButtons & 0x04)
                    {
                        if (ui8Buttons & 0x04)
                            evfMouse |= MOUSEEVENTF_MIDDLEDOWN;
                        else
                            evfMouse |= MOUSEEVENTF_MIDDLEUP;
                    }

                    m_ui8ButtonState = buf[0];
                }

                if (buf[1] || buf[2])
                    evfMouse |= MOUSEEVENTF_MOVE;

                x = buf[1];
                y = -buf[2];

                /*
                 * If IntelliMouse present buf[3] contains the relative
                 * displacement of the mouse wheel
                 */
                if(m_pp2p->bIntelliMouseFound() && buf[3])
                {
                    evfMouse |= MOUSEEVENTF_WHEEL;

                    // we need to scale by WHEEL_DELTA = 120
                    w = -buf[3] * 120;
                }

                if (IsValidTriplet(buf[0], buf[1], buf[2]))
                    mouse_event(evfMouse, x, y, w, NULL);
                else
                {
                    DEBUGMSG(1, (TEXT("%02X, %02X, %02X, %02X\r\n"),
                                 (BYTE)buf[0], (BYTE)buf[1],
                                 (BYTE)buf[2], buf[3]));
                    DEBUGMSG(1, (TEXT("Invalid mouse packet...")
                                 TEXT("discarding.\r\n")));
                }

                cBytes = 0;
                bInPacket = FALSE;
            }
        }
        else
            ERRORMSG(1,(TEXT("Error reading mouse data\r\n")));

        InterruptDone(bSYSINTR);
    }

  leave:
    return TRUE;
}

DWORD Ps2MouseIsrThread(Ps2Mouse *pp2m)
{
    pp2m->IsrThreadProc();

    return 0;
}

BOOL Ps2Mouse::IsrThreadStart(void)
{
    HANDLE hthrd;

    hthrd = CreateThread(NULL, 0,
                         (LPTHREAD_START_ROUTINE)Ps2MouseIsrThread,
                         this, 0, NULL);

    // Since we don't need the handle, close it now.
    CloseHandle(hthrd);
    return TRUE;
}

/* EOF ps2mouse.cpp */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?