pl050mouse.cpp

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

CPP
229
字号
/* -*-C-*-
 *
 * $Revision: 1.5 $
 *   $Author: kwelton $
 *     $Date: 2000/08/08 19:41:55 $
 *
 * 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 "pl050port.hpp"
#include "pl050mouse.hpp"
#include "pl050keybd.hpp"

static const unsigned char cmdMouseEnable = 0xf4;

static pl050Mouse *mouseport;

/**********************************************************************/

static bool isValidTriplet(signed char *buf)
{
    bool fNegativeX, fNegativeY;

    fNegativeX = (buf[0] & 0x10) != 0;
    fNegativeY = (buf[0] & 0x20) != 0;

    if (!(buf[0] & 0x08))
        return false;

    if ((fNegativeX && (buf[1] >= 0)) ||
        ((!fNegativeX) && (buf[1] < 0)))
        return false;

    if ((fNegativeY && (buf[2] >= 0)) ||
        ((!fNegativeY) && (buf[2] < 0)))
        return false;

    return true;
}

extern "C" unsigned int MouseISRUpcall(bool timedout, unsigned int scancode)
{
    long x, y;
    long w = 0;
    UINT8 ui8Buttons;
    UINT8 ui8XorButtons;
    unsigned int evfMouse;

    if (timedout)
    {
        mouseport->cBytes = 0;
        mouseport->bInPacket = FALSE;
        DEBUGMSG(1, (TEXT("pl050::MouseISRUpcall: inpacket timeout\r\n")));

        return INFINITE;
    }

#if 0
    DEBUGMSG(1, (TEXT("pl050::MouseISRUpcall: event %x\r\n"), scancode));
#endif /* 0/1 */

    /*
     * we didn't timeout - process the scancode
     */
    if (mouseport->cBytes == 0)
        mouseport->bInPacket = TRUE;

    if (mouseport->cBytes < mouseport->m_cReportFormatLength)
        mouseport->buf[mouseport->cBytes++] = (signed char)scancode;

    if (mouseport->cBytes == mouseport->m_cReportFormatLength)
    {
        evfMouse = 0;

        ui8XorButtons = mouseport->buf[0] ^ mouseport->m_ui8ButtonState;

        if (ui8XorButtons)
        {
            ui8Buttons = mouseport->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;
            }

            mouseport->m_ui8ButtonState = mouseport->buf[0];
        }

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

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

        /*
         * If IntelliMouse connected, mouseport->buf[3] contains
         * the relative displacement of the mouse wheel
         *
         * 20000611 KWelton
         *
         * it's much more efficient to check the format length to see
         * whether we have an Intellimouse, rather than calling into
         * the port class every time
         */
#ifdef OldCode
        if(m_pp2p->IntelliMouseFound() && mouseport->buf[3])
        {
            evfMouse |= MOUSEEVENTF_WHEEL;

            // we need to scale by WHEEL_DELTA = 120
            w = -(mouseport->buf[3]) * 120;
        }
#else /* OldCode */
        if(mouseport->m_cReportFormatLength == 4 && mouseport->buf[3])
        {
            evfMouse |= MOUSEEVENTF_WHEEL;

            // we need to scale by WHEEL_DELTA = 120
            w = -(mouseport->buf[3]) * 120;
        }
#endif /* OldCode */

        if (isValidTriplet(mouseport->buf))
        {
#if 0
            RETAILMSG(1, (TEXT("MouseEvent: %x [%d, %d, %d]\r\n"),
                         evfMouse, x, y, w));
#endif /* 0/1 */
            mouse_event(evfMouse, x, y, w, NULL);
        }
        else
        {
            DEBUGMSG(1, (TEXT("%02X, %02X, %02X, %02X\r\n"),
                         (BYTE)mouseport->buf[0], (BYTE)mouseport->buf[1],
                         (BYTE)mouseport->buf[2], mouseport->buf[3]));
            DEBUGMSG(1, (TEXT("Invalid mouse packet...")
                         TEXT("discarding.\r\n")));
        }

        mouseport->cBytes = 0;
        mouseport->bInPacket = FALSE;
    }

    return (mouseport->bInPacket) ? 50 : INFINITE;
}

DWORD pl050MouseIsrThread(void)
{
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    mouseport->m_pp2p->ISRLoop(INFINITE);

    ERRORMSG(1, (TEXT("pl050mouse: ISR thread proc has returned!\r\n")));

    return 0;
}

/**********************************************************************/

bool pl050Mouse::Initialise(pl050Port *port)
{
    mouseport = this;

    m_pp2p = port;
    m_hevInterrupt = NULL;
    m_ui8ButtonState = 0;
    m_cReportFormatLength = port->IntelliMouseFound() ? 4 : 3;

    cBytes = 0;
    bInPacket = FALSE;

    port->OpenPort();
    (void)(port->ACKCommand(cmdMouseEnable));

    /*
     * unlike the keyboard driver, there's no kernel callback
     * registration for the mouse, so register the ISR upcall
     * here
     */
    port->SetISRUpcall(MouseISRUpcall);

    return true;
}

bool pl050Mouse::IsrThreadStart(void)
{
    HANDLE hthrd;

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

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

    return true;
}

/* EOF pl050mouse.cpp */

⌨️ 快捷键说明

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