⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 detc.c

📁 书中的主要程序文件。在打开例题的.dsw文件后,请读者在 tools菜单下的 Options 的 Directories 标签中选择 Executable files
💻 C
📖 第 1 页 / 共 2 页
字号:
    // Before we mess with the baud rate, put the mouse in prompt mode.
    //
    GGSetReportRate(DeviceExtension, 0);

    for (count = sizeofel(GGBaudRateTable) - 1; count >= 0; count--) {
        if (BaudRate >= GGBaudRateTable[count].BaudRate) {

            //
            // Set the baud rate.
            //

            SerialMouseWriteString(DeviceExtension, GGBaudRateTable[count].Command);
            SerialMouseSetBaudRate(DeviceExtension, GGBaudRateTable[count].BaudRate);

            //
            // Delay to allow the UART and the mouse to synchronize 
            // correctly.  
            //
            SerialMouseWait(DeviceExtension,
                            -GG_BAUDRATE_DELAY
                            );
            break;
        }
    }

    return;
}



PPROTOCOL_HANDLER
GGSetProtocol(
    PDEVICE_EXTENSION   DeviceExtension,
    UCHAR               NewProtocol
    )
/*++

Routine Description:

    Change the mouse protocol.

    Note: Not all the protocols are implemented in this driver.

Arguments:

    Port - Pointer to the serial port.


Return Value:

    Address of the protocol handler function. See the interrupt service 
    routine.

--*/
{
    PAGED_CODE();

    Print(DeviceExtension, DBG_SS_TRACE, ("GGSetProtocol called\n"));

    ASSERT(NewProtocol < GG_PROTOCOL_MAX);

    //
    // Set the protocol.
    //
    SerialMouseWriteChar(DeviceExtension, Protocol[NewProtocol].Command);
    SerialMouseSetLineCtrl(DeviceExtension, &Protocol[NewProtocol].LineCtrl);

    Print(DeviceExtension, DBG_SS_INFO, ("NewProtocol: %u\n", NewProtocol & 0xFF));

    return Protocol[NewProtocol].Handler;
}

BOOLEAN
GGDremov(
    PDEVICE_EXTENSION   DeviceExtension,
    PULONG              HardwareButtons
    )
/*++

Routine Description:

    Detection of a Detc type mouse. The main steps are:

    - Power up the mouse.
    - Cycle through the available baud rates and try to get an answer 
      from the mouse.

    At the end of the routine, a default baud rate and report rate are set.

Arguments:

    Port - Pointer to the serial port.

    HardwareButtons - Returns the number of hardware buttons detected.

Return Value:

    TRUE if a Detc type mouse is detected, otherwise FALSE.

--*/
{
    UCHAR status, numButtons;
    ULONG count;
    BOOLEAN Dremoved = FALSE;

    Print(DeviceExtension, DBG_SS_TRACE, ("GGDremov called\n"));

    //
    // Power up the mouse if necessary.
    //

    GGPowerUp(DeviceExtension);

    //
    // Set the line control register to a format that the mouse can
    // understand (see below: the line is set after the report rate).
    //

    SerialMouseSetLineCtrl(DeviceExtension, &Protocol[GG_PROTOCOL_MM].LineCtrl);

    //
    // Cycle through the different baud rates to detect the mouse.
    //

    for (count = 0; count < sizeofel(BaudRateDremov); count++) {

        SerialMouseSetBaudRate(DeviceExtension, BaudRateDremov[count]);

        //
        // Put the mouse in prompt mode.
        //

        GGSetReportRate(DeviceExtension, 0);

        //
        // Set the MM protocol. This way we get the mouse to talk to us in a
        // specific format. This avoids receiving errors from the line 
        // register.
        //

        GGSetProtocol(DeviceExtension, GG_PROTOCOL_MM);

        //
        // Try to get the status byte.
        //

        SerialMouseWriteChar(DeviceExtension, GG_STATUS_COMMAND);

        //
        // In case something is already there...
        //

        SerialMouseFlushReadBuffer(DeviceExtension);

        SerialMouseSetReadTimeouts(DeviceExtension, 50);
        //
        // Read back the status character.
        //
        if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension, &status)) &&
            (status == GG_STATUS)) {
            Dremoved = TRUE;
            Print(DeviceExtension, DBG_SS_INFO,
                  ("Dremoved mouse at %u baud\n",
                  BaudRateDremov[count]
                  ));
            break;
        }
    }

    if (Dremoved) {

        //
        // Get the number of buttons back from the mouse.
        //
        SerialMouseWriteChar(DeviceExtension, GG_QUERY_BUTTONS_COMMAND);

        //
        // In case something is already there...
        //

        SerialMouseFlushReadBuffer(DeviceExtension);

        //
        // Read back the number of buttons.
        //
        SerialMouseSetReadTimeouts(DeviceExtension, GG_STATUS_DELAY);
        if (NT_SUCCESS(SerialMouseReadChar(DeviceExtension, &numButtons))) {

            numButtons &= 0x0F;
            Print(DeviceExtension, DBG_SS_NOISE, 
                  ("Successfully read number of buttons (%1u)\n", numButtons));

            if (numButtons == 2 || numButtons == 3) {
                *HardwareButtons = numButtons;
            } else {
                *HardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
            }
        } else {
            *HardwareButtons = MOUSE_NUMBER_OF_BUTTONS;
        }

        //
        // Make sure that all subsequent reads are blocking and do not timeout
        //
        SerialMouseSetReadTimeouts(DeviceExtension, 0);
    }

    //
    // Put the mouse back in a default mode. The protocol is already set.
    //
    GGSetBaudRate(DeviceExtension, GG_DEFAULT_BAUDRATE);
    GGSetReportRate(DeviceExtension, GG_DEFAULT_REPORTRATE);

    Print(DeviceExtension, DBG_SS_INFO,
          ("Dremoved: %s\n", Dremoved ? "true" : "false"));
    Print(DeviceExtension, DBG_SS_INFO, ("Status byte: %#x\n", status));

    return Dremoved;
}

BOOLEAN
GGHandlerMM(
    IN PDEVICE_EXTENSION    DeviceExtension,
    IN PMOUSE_INPUT_DATA    CurrentInput,
    IN PHANDLER_DATA        HandlerData,
    IN UCHAR                Value,
    IN UCHAR                LineState)

/*++

Routine Description:

    This is the protocol handler routine for the MM protocol.

Arguments:

    CurrentInput - Pointer to the report packet.

    Value - The input buffer value.

    LineState - The serial port line state.

Return Value:

    Returns TRUE if the handler has a completed report.

--*/

{
    BOOLEAN retval = FALSE;

    Print(DeviceExtension, DBG_HANDLER_TRACE, ("MMHandler, enter\n"));

    if ((Value & GG_SYNCH_BIT) && (HandlerData->State != STATE0)) {
        HandlerData->Error++;
        Print(DeviceExtension, DBG_HANDLER_ERROR, 
              ("Synch error. State: %u\n",
              HandlerData->State
              ));
        HandlerData->State = STATE0;
    }
    else if (!(Value & GG_SYNCH_BIT) && (HandlerData->State == STATE0)) {
        HandlerData->Error++;
        Print(DeviceExtension, DBG_HANDLER_ERROR, 
              ("Synch error. State: %u\n",
              HandlerData->State
              ));
        goto LExit;
    }

    //
    // Check for a line state error.
    //
    Print(DeviceExtension, DBG_HANDLER_INFO,
          ("State%u\n", HandlerData->State));
    HandlerData->Raw[HandlerData->State] = Value;

    switch (HandlerData->State) {
    case STATE0:
    case STATE1:
        HandlerData->State++;
        break;

    case STATE2:
        HandlerData->State = STATE0;

        //
        // Buttons formatting.
        //
        CurrentInput->RawButtons =
            (HandlerData->Raw[STATE0] & GG_BUTTON_LEFT) >> GG_BUTTON_LEFT_SR;
        CurrentInput->RawButtons |=
            (HandlerData->Raw[STATE0] & GG_BUTTON_RIGHT) << GG_BUTTON_RIGHT_SL;
        CurrentInput->RawButtons |=
            (HandlerData->Raw[STATE0] & GG_BUTTON_MIDDLE) << GG_BUTTON_MIDDLE_SL;

        //
        // Displacement formatting.
        //

        CurrentInput->LastX = (HandlerData->Raw[STATE0] & SIGN_X) ?
            HandlerData->Raw[STATE1] :
            -(LONG)HandlerData->Raw[STATE1];

        //
        // Note: The Y displacement is positive to the south.
        //

        CurrentInput->LastY = (HandlerData->Raw[STATE0] & SIGN_Y) ?
            -(LONG)HandlerData->Raw[STATE2] :
            HandlerData->Raw[STATE2];

        Print(DeviceExtension, DBG_HANDLER_NOISE,
              ("Displacement X: %ld\n",
              CurrentInput->LastX
              ));
        Print(DeviceExtension, DBG_HANDLER_NOISE,
              ("Displacement Y: %ld\n",
              CurrentInput->LastY
              ));
        Print(DeviceExtension, DBG_HANDLER_NOISE,
              ("Raw Buttons: %0lx\n",
              CurrentInput->RawButtons
              ));

        //
        // The report is complete. Tell the interrupt handler to send it.
        //

        retval = TRUE;

        break;

    default:
        Print(DeviceExtension, DBG_HANDLER_ERROR,
              ("MM Handler failure: incorrect state value.\n"));
        ASSERT(FALSE);
    }

LExit:
    Print(DeviceExtension, DBG_HANDLER_TRACE, ("MMHandler, exit\n"));

    return retval;
}

⌨️ 快捷键说明

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