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

📄 usbkeyboardlib.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
    };

LOCAL UINT16 extendedAltFunctionKeyCodes [] =
    {
        0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
        0x70, 0x71, 0x8b, 0x8c
    };

LOCAL UINT16 extendedKeypadKeyCodes [] =
    {
        0x4F, 0x50, 0x51, 0x4B, 0x00, 0x4D, 0x47, 0x48,
        0x49, 0x52, 0x53
    };

/* globals */

unsigned int TYPEMATIC_DELAY  = 500;    /* 500 msec delay */
unsigned int TYPEMATIC_PERIOD = 66;     /* 66 msec = approx 15 char/sec */


/***************************************************************************
*
* cvtScanCodeToKeyCode - converts scan code to key code if possible
*
* <scanCode> is the scan code to be interpreted and <modifiers> is the 
* current state of the keyboard modifies (e.g., SHIFT).  
*
* RETURNS: ASCII code if mapping exists, CAPLOCK, SCRLOCK, NUMLOCK, or
*          NOTKEY if no mapping.
*
* ERRNO: None
*
*\NOMANUAL
*/

LOCAL UINT16 cvtScanCodeToKeyCode
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    UINT16 scanCode,
    UINT16 modifiers
    )

    {

    /* Translate keypad keys. */

    if( ISKEYPADSCANCODE(scanCode) )
	{

        if( !!(modifiers & MOD_KEY_SHIFT) ^ !!(pSioChan->numLock) )
            return( scanCodes [scanCode] );

        if( ISKEYPADEXTSCANCODE(scanCode) )
	    {

            /* If the table contains 0 (like entry for keypad '5') 
	     * return NOTKEY. 
	     */

            if(extendedKeypadKeyCodes[scanCode-0x59] == 0) 
		return(NOTKEY);

            return(0xFF00 | extendedKeypadKeyCodes[scanCode-0x59]);
	    }
        return( scanCodes [scanCode] );
	}

    /* Translate extended keys. */

    if( ISALPHASCANCODE(scanCode) && (modifiers & MOD_KEY_ALT) )
        return(0xFF00 | extendedAlphaKeyCodes[scanCode-0x04]);

    if( ISOTHEREXTENDEDSCANCODE(scanCode) )
        return(0xFF00 | extendedOtherKeyCodes[scanCode-0x49]);

    if( ISFUNCTIONSCANCODE(scanCode) && (modifiers & MOD_KEY_ALT) )
        return(0xFF00 | extendedAltFunctionKeyCodes[scanCode-0x3A]);

    if( ISFUNCTIONSCANCODE(scanCode))
        return(0xFF00 | extendedFunctionKeyCodes[scanCode-0x3A]);

    /* Translate the scan code into a preliminary ASCII code */

    if (scanCode < SCAN_CODE_TBL_LEN)
	{
        /* Translate alpha keys */

        if( ISALPHASCANCODE(scanCode) )
	    {
            if( modifiers & MOD_KEY_CTRL )
                return( scanCodesShift [scanCode] - CTRL_CASE_OFFSET);

            if( !!(modifiers & MOD_KEY_SHIFT) ^ !!(pSioChan->capsLock) )
                return( scanCodesShift [scanCode] );

            else
                return( scanCodes [scanCode] );
	    }

        /* Translate non-alpha keys */

        if ((modifiers & (MOD_KEY_SHIFT | MOD_KEY_CTRL)) != 0)
        	return( scanCodesShift [scanCode] );

        else
	        return( scanCodes [scanCode] );
	}

    return(NOTKEY);
    }


/***************************************************************************
*
* isKeyPresent - determines if a key is present in an array of keys
*
* This function determines whether the <key> is present in the array <pKeyArray>
*
* RETURNS: TRUE if <key> is present in the <keyArray>, else returns FALSE
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL BOOL isKeyPresent
    (
    pUINT16 pKeyArray,
    UINT16 key
    )

    {
    UINT16 i;

    for (i = 0; i < BOOT_RPT_KEYCOUNT; i++)
	if (key == pKeyArray [i])
	    return TRUE;

    return FALSE;
    }


/***************************************************************************
*
* setLedReport - Issues a SET_REPORT to change a keyboard's LEDs
*
* This function isses a <SET_REPORT> request to change keyboards LED
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID setLedReport
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    UINT8 ledReport
    )

    {

    UINT8 * pLedReport = OSS_CALLOC (sizeof (UINT8));

    if (pLedReport == NULL)
	return;

    *pLedReport = ledReport;

    usbHidReportSet (usbdHandle, 
		     pSioChan->nodeId, 
		     pSioChan->interface, 
		     USB_HID_RPT_TYPE_OUTPUT,      
		     0, 
		     pLedReport, 
		     sizeof (ledReport));

    OSS_FREE (pLedReport);
    }


/***************************************************************************
*
* changeKeyState - changes keyboard state
*
* <key> is CAPLOCK, SCRLOCK, or NUMLOCK.  If <key> is not already 
* active, then, toggle the current keyboard state for the corresponding item.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID changeKbdState
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    UINT16 scanCode, 			/* not used */
    pBOOL pKeyState
    )

    {
    UINT8 ledReport;

    /* The scancode is newly active, toggle the corresponding keyboard state. */

    *pKeyState = !(*pKeyState);


    /* Update the keyboard LEDs */

    ledReport = (pSioChan->capsLock) ? RPT_LED_CAPS_LOCK : 0;
    ledReport |= (pSioChan->scrLock) ? RPT_LED_SCROLL_LOCK : 0;
    ledReport |= (pSioChan->numLock) ? RPT_LED_NUM_LOCK : 0;

    setLedReport (pSioChan, ledReport);

    }

/***************************************************************************
*
* interpScanCode - interprets keyboard scan code
*
* Interprets the <scanCode> according to the <modifiers>.  This function
* handles any special requirements, such as turning an LED ON or OFF in
* response to a keypress.
*
* RETURNS: N/A.
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL void interpScanCode
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    UINT16 scanCode,
    UINT16 modifiers
    )

    {

    /* If the key is already active, ignore it. */

    if (isKeyPresent (pSioChan->activeScanCodes, scanCode))
        return;

    /* Determine if special handling is required for the key */

    switch (scanCode)
	{
        case CAPLOCK:   /* key is CAPLOCK */
        case CAPLOCK_LOCKING:   /* key is CAPLOCK */

	        changeKbdState (pSioChan, scanCode, &pSioChan->capsLock);
	        break;

        case SCRLOCK:   /* key is SCRLOCK */
        case SCRLOCK_LOCKING:   /* key is SCRLOCK */

	        changeKbdState (pSioChan, scanCode, &pSioChan->scrLock);
	        break;

        case NUMLOCK:   /* key is NUMLOCK */
        case NUMLOCK_LOCKING:   /* key is NUMLOCK */

	        changeKbdState (pSioChan, scanCode, &pSioChan->numLock);
	        break;

        case NOTKEY:    /* no valid scan code mapping */
        default:	/* an ASCII character */

	    break;
	}
    }


/***************************************************************************
*
* putInChar - puts a character into channel's input queue
*
* This function puts character <putChar> in the queue
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID putInChar
    (
    pUSB_KBD_SIO_CHAN pSioChan,
    char putChar
    )

    {
    if (pSioChan->inQueueCount < KBD_Q_DEPTH)
	{
	pSioChan->inQueue [pSioChan->inQueueIn] = putChar;

	if (++pSioChan->inQueueIn == KBD_Q_DEPTH)
	    pSioChan->inQueueIn = 0;

	pSioChan->inQueueCount++;
	}
    }


/***************************************************************************
*
* nextInChar - returns next character from input queue
*
* Returns the next character from the channel's input queue and updates
* the queue pointers.  The caller must ensure that at least one character
* is in the queue prior to calling this function.
*
* RETURNS: next char in queue
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL char nextInChar
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

    {
    char inChar = pSioChan->inQueue [pSioChan->inQueueOut];

    if (++pSioChan->inQueueOut == KBD_Q_DEPTH)
	pSioChan->inQueueOut = 0;

    pSioChan->inQueueCount--;

    return inChar;
    }


/***************************************************************************
*
* updateTypematic - generates typematic characters for channel if appropriate
*
* This function generates typematic characters for channel if appropriate
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID updateTypematic
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

    {
    UINT32 diffTime;
    UINT32 repeatCount;


    /* If the given channel is active and a typematic character is
     * indicated, then update the typematic state.
     */


    if (pSioChan->connected && pSioChan->typematicChar != 0)
	{

        diffTime = OSS_TIME () - pSioChan->typematicTime;

        /* If the typematic delay has passed, then it is time to start
         * injecting characters into the queue.
         */

        if (diffTime >= TYPEMATIC_DELAY)
	    {
	    diffTime -= TYPEMATIC_DELAY;
	    repeatCount = diffTime / TYPEMATIC_PERIOD + 1;

	    /* Inject characters into the queue.  If the queue is
	     * full, putInChar() dumps the character, but we increment
	     * the typematicCount anyway.  This keeps the queue from
	     * getting too far ahead of the user. 
	     */

	    while (repeatCount > pSioChan->typematicCount)
		{
			
		/* determine the mode in which the driver is operating */

                if (pSioChan->scanMode == SIO_KYBD_MODE_ASCII)
                    {
                    if (ISEXTENDEDKEYCODE(pSioChan->typematicChar))
		        {
		        if(pSioChan->inQueueCount < KBD_Q_DEPTH-1)
			    {
			    putInChar (pSioChan, (char) 0);
			    putInChar (pSioChan,
				   (char) pSioChan->typematicChar & 0xFF);
			    }
		        }
		    else
		        {
		        putInChar (pSioChan, pSioChan->typematicChar);
		        }

                    }
                else
                    {
                    /*
                     * in RAW Mode put the modifier, scancode and trailing byte
                     * into the queue
                     * in the typematicChar variable the 1st byte is for the 
                     * modifier and the second byte is for scan code
                     */

                    putInChar (pSioChan, (pSioChan->typematicChar) >> 0x8);
                    putInChar (pSioChan, (pSioChan->typematicChar & 0xFF));
                    putInChar (pSioChan, 0xFF);

                    }

		pSioChan->typematicCount++;
		}

	    /* invoke receive callback */

	    while (pSioChan->inQueueCount > 0 &&
		    pSioChan->putRxCharCallback != NULL &&
		    pSioChan->mode == SIO_MODE_INT)
		{
                (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg,
						nextInChar (pSioChan));
		}
	    }
	}
    }


/***************************************************************************
*
* interpKbdReport - interprets USB keyboard BOOT report
*
* Interprets a keyboard boot report and updates channel state as
* appropriate.  Operates in one of two modes: ASCII or RAW.  In ASCII mode
* it inserts the ascii character into the character buffer and implements
* typematic repeat.  In RAW mode it always inserts the modifier byte
* regardless of change, it inserts any keypresses that are currently active
* and it inserts a terminating byte of 0xff into the character buffer.
*
* RETURNS: N/A
*
* ERRNO: none
*
*\NOMANUAL
*/

LOCAL VOID interpKbdReport
    (
    pUSB_KBD_SIO_CHAN pSioChan
    )

⌨️ 快捷键说明

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