?? usbkeyboardlib.c
字號:
} } /* * If newTypematicChar is 0, then no keys were received in * this report - so no keys are being held down. If * newTypematicChar matches the previous typematic char, * then allow the typematic timer to continue. If * newTypematicChar is different (but non-zero), then start * a new timer. In all cases, only one key may be active * for typematic repeat to be enabled. */ if (activeCount != 1) newTypematicChar = 0; if (newTypematicChar != pSioChan->typematicChar) { pSioChan->typematicChar = newTypematicChar; if (newTypematicChar != 0) { pSioChan->typematicTime = OSS_TIME (); pSioChan->typematicCount = 0; } } updateTypematic (pSioChan); } /* invoke receive callback */ while (pSioChan->inQueueCount > 0 && pSioChan->putRxCharCallback != NULL && pSioChan->mode == SIO_MODE_INT) { (*pSioChan->putRxCharCallback) (pSioChan->putRxCharArg, nextInChar (pSioChan)); } /* * Copy the current list of active keys to the channel * structure, overwriting the previous list. */ for (i = 0; i < BOOT_RPT_KEYCOUNT; i++) pSioChan->activeScanCodes [i] = pReport->scanCodes [i]; }/***************************************************************************** usbKeyboardIoctl - special device control** This routine is largely a no-op for the usbKeyboardLib. The only ioctls* which are used by this module are the SIO_AVAIL_MODES_GET and SIO_MODE_SET.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request** ERRNO: none**\NOMANUAL*/LOCAL int usbKeyboardIoctl ( SIO_CHAN *pChan, /* device to control */ int request, /* request code */ void *someArg /* some argument */ ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; int arg = (int) someArg; switch (request) { case SIO_BAUD_SET: /* baud rate has no meaning for USB. We store the desired * baud rate value and return OK. */ pSioChan->baudRate = arg; return OK; case SIO_BAUD_GET: /* Return baud rate to caller */ *((int *) arg) = pSioChan->baudRate; return OK; case SIO_MODE_SET: /* Set driver operating mode: interrupt or polled */ if (arg != SIO_MODE_POLL && arg != SIO_MODE_INT) return EIO; pSioChan->mode = arg; return OK; case SIO_MODE_GET: /* Return current driver operating mode for channel */ *((int *) arg) = pSioChan->mode; return OK; case SIO_AVAIL_MODES_GET: /* Return modes supported by driver. */ *((int *) arg) = SIO_MODE_INT | SIO_MODE_POLL; return OK; case SIO_OPEN: /* Channel is always open. */ return OK; case SIO_KYBD_MODE_SET: switch (arg) { case SIO_KYBD_MODE_RAW: case SIO_KYBD_MODE_ASCII: break; case SIO_KYBD_MODE_UNICODE: return ENOSYS; /* usb doesn't support unicode */ } pSioChan->scanMode = arg; return OK; case SIO_KYBD_MODE_GET: *(int *)someArg = pSioChan->scanMode; return OK; case SIO_KYBD_LED_SET: { UINT8 ledReport; /* update the channel's information about the LED state */ pSioChan->numLock = (arg & SIO_KYBD_LED_NUM) ? SIO_KYBD_LED_NUM : 0; pSioChan->capsLock = (arg & SIO_KYBD_LED_CAP) ? SIO_KYBD_LED_CAP : 0; pSioChan->scrLock = (arg & SIO_KYBD_LED_SCR) ? SIO_KYBD_LED_SCR : 0; /* * We are relying on the SIO_KYBD_LED_X macros matching the USB * LED equivelants. */ ledReport = arg; /* set the LED's */ setLedReport (pSioChan, ledReport); return OK; } case SIO_KYBD_LED_GET: { int tempArg; tempArg = (pSioChan->capsLock) ? SIO_KYBD_LED_CAP : 0; tempArg |= (pSioChan->scrLock) ? SIO_KYBD_LED_SCR : 0; tempArg |= (pSioChan->numLock) ? SIO_KYBD_LED_NUM : 0; *(int *) someArg = tempArg; return OK; } case SIO_HW_OPTS_SET: /* optional, not supported */ case SIO_HW_OPTS_GET: /* optional, not supported */ case SIO_HUP: /* hang up is not supported */ default: /* unknown/unsupported command. */ return ENOSYS; } }/***************************************************************************** usbKeyboardTxStartup - start the interrupt transmitter** The USB keyboard SIO driver does not support output to the keyboard.** RETURNS: EIO** ERRNO: none**\NOMANUAL*/LOCAL int usbKeyboardTxStartup ( SIO_CHAN *pChan /* channel to start */ ) { return EIO; }/***************************************************************************** usbKeyboardCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters* and receiving characters.** RETURNS: OK on success, or ENOSYS for an unsupported callback type** ERRNO: none**\NOMANUAL*/ LOCAL int usbKeyboardCallbackInstall ( SIO_CHAN *pChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback) (void *tmp, ...), /* callback */ void *callbackArg /* parameter to callback */ ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pSioChan->getTxCharCallback = (STATUS (*)()) (callback); pSioChan->getTxCharArg = callbackArg; return OK; case SIO_CALLBACK_PUT_RCV_CHAR: pSioChan->putRxCharCallback = (STATUS (*)()) (callback); pSioChan->putRxCharArg = callbackArg; return OK; default: return ENOSYS; } }/***************************************************************************** usbKeyboardPollOutput - output a character in polled mode** The USB keyboard SIO driver does not support output to the keyboard.** RETURNS: EIO** ERRNO: none**\NOMANUAL*/LOCAL int usbKeyboardPollOutput ( SIO_CHAN *pChan, char outChar ) { return EIO; }/***************************************************************************** usbKeyboardPollInput - poll the device for input** This function polls the keyboard device for input.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty, ENOSYS if the device is interrupt-only.** ERRNO: none**\NOMANUAL */LOCAL int usbKeyboardPollInput ( SIO_CHAN *pChan, char *thisChar ) { pUSB_KBD_SIO_CHAN pSioChan = (pUSB_KBD_SIO_CHAN) pChan; int status = OK; /* validate parameters */ if (thisChar == NULL) return EIO; OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK); /* Check if the input queue is empty. */ if (pSioChan->inQueueCount == 0) status = EAGAIN; else { /* Return a character from the input queue. */ *thisChar = nextInChar (pSioChan); } OSS_MUTEX_RELEASE (kbdMutex); return status; }/***************************************************************************** initKbdIrp - Initialize IRP to listen for input on interrupt pipe** This function intializes the IRP to listen on the interrupt pipe** RETURNS: TRUE if able to submit IRP successfully, else FALSE** ERRNO: none**\NOMANUAL*/LOCAL BOOL initKbdIrp ( pUSB_KBD_SIO_CHAN pSioChan ) { pUSB_IRP pIrp = &pSioChan->irp; /* Initialize IRP */ memset (pIrp, 0, sizeof (*pIrp)); pIrp->userPtr = pSioChan; pIrp->irpLen = sizeof (*pIrp); pIrp->userCallback = usbKeyboardIrpCallback; pIrp->timeout = USB_TIMEOUT_NONE; pIrp->transferLen = sizeof (HID_KBD_BOOT_REPORT); pIrp->bfrCount = 1; pIrp->bfrList [0].pid = USB_PID_IN; pIrp->bfrList [0].pBfr = (pUINT8) pSioChan->pBootReport; pIrp->bfrList [0].bfrLen = sizeof (HID_KBD_BOOT_REPORT); /* Submit IRP */ if (usbdTransfer (usbdHandle, pSioChan->pipeHandle, pIrp) != OK) return FALSE; pSioChan->irpInUse = TRUE; return TRUE; }/***************************************************************************** usbKeyboardIrpCallback - Invoked upon IRP completion/cancellation** Examines the cause of the IRP completion. If completion was successful,* interprets the USB keyboard's boot report and re-submits the IRP.** RETURNS: N/A** ERRNO: none**\NOMANUAL*/LOCAL VOID usbKeyboardIrpCallback ( pVOID p /* completed IRP */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; pUSB_KBD_SIO_CHAN pSioChan = pIrp->userPtr; OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK); /* Was the IRP successful? */ if (pIrp->result == OK) { /* Interpret the keyboard report */ interpKbdReport (pSioChan); } /* Re-submit the IRP unless it was canceled - which would happen only * during pipe shutdown (e.g., the disappearance of the device). */ pSioChan->irpInUse = FALSE; if (pIrp->result != S_usbHcdLib_IRP_CANCELED) { initKbdIrp (pSioChan); } else { if (!pSioChan->connected) { /* Release structure. */ if (pSioChan->pBootReport != NULL) OSS_FREE (pSioChan->pBootReport); OSS_FREE (pSioChan); } } OSS_MUTEX_RELEASE (kbdMutex); }/***************************************************************************** typematicThread - Updates typematic state for each active channel** Updates typematic state for each active channel** RETURNS: N/A** ERRNO: none**\NOMANUAL*/LOCAL VOID typematicThread ( pVOID param /* param not used by this thread */ ) { pUSB_KBD_SIO_CHAN pSioChan; while (!killTypematic) { OSS_MUTEX_TAKE (kbdMutex, OSS_BLOCK); /* Walk the list of open channels and update the typematic * state for each. */ pSioChan = usbListFirst (&sioList); while (pSioChan != NULL)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -