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

📄 uglusbkbd.c

📁 zinc60t22.tar.gz:zinc在tornado2.2.x下的补丁
💻 C
📖 第 1 页 / 共 2 页
字号:
/* uglusbkbd.c - UGL USB Keyboard Handler *//* Copyright 2003 Wind River Systems, Inc. All Rights Reserved *//*modification history--------------------01a,18jun03,jlb  created*//*DESCRIPTIONThis file provides the USB Keyboard protocol support for UGL.The USB libraries are built on top of each other.  There is a basicUSB support, followed by a support for particular USB device classes,and finally, support of devices such as keyboard and mouse.  Thehighest level support are configured as components from the config/comps/srcdirectory.  The lower levels are in the src/drv/usb directory.This driver is configured to use the class library for a keyboard device anddoes not perform an iosDrvInstall(), or iosDevAdd() as the usb components do.This driver feeds the USB reports into a pipe that is opened by the inputtask rather than a device.  This is to bridge the problem caused by WindMLusing a "select()" in its input task, while the current underlying USB driverdoes not support "select()".  However pipes can be used in a select.A new pipe is created for each device.  For example, "/pipe/uglUsbMse/0".An alternative would be to implement select() functionality for this driverwhich sits on top of the USB drivers that do not support select().Difficulty that may arise:- Hot swappability.USB is inherently hot swappable and its API's reflect that fact.  WindML cansupport this feature in different ways.  For instance if the upper levelUSB component were used for WindML USB, hot swapping a device results in anew device instance.  For example /usbKyd/0 becomes /usbKbd/1 even though itmay be the same keyboard on the same physical port.  An analogous problemmust be accommodated in this driver.Since this driver uses the USB keyboard class library, its attachment callbackonly receives keyboard device attachment notices.  Therefore, if a particularphysical USB port is used by a mouse and it is removed and a keyboard isplugged into it, this driver will still consider that the port is for mouseinput, but is currently detached.  This will occur with keyboards as wellif their driver is similarly architected.An alternative is to do what the upper level component does and close thechannel, and its associated pipe in our case, completely.  Then newattachments can be re-associated appropriately.  This then brings up theissue of the naming scheme (algorithm) for the pipes; continuously incr-easing numbers, or re-use of instance numbers.Yet another alternative, would be to use only a single pipe for all mouse,keyboard, etc. devices.  This would probably require some changes to theinput task's coding.*/#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <ctype.h>#include <ioLib.h>#include <stdio.h>#include <pipeDrv.h>#include <ugl/ugl.h>#include <ugl/uglos.h>#include <ugl/uglmem.h>#include <ugl/uglinput.h>#include <ugl/ugllog.h>#include <ugl/driver/keyboard/uglusbkeybd.h>UGL_USB_KBD_DEVICE  usbKbdData = {0};/* forward declarations */UGL_LOCAL UGL_STATUS uglUsbKbdDestroy (UGL_INPUT_DEVICE * pDevice);UGL_LOCAL UGL_STATUS uglUsbKbdFormatter (UGL_INPUT_DEVICE * pDevice,                                         UGL_EVENT *  pEvent );UGL_LOCAL UGL_STATUS uglUsbKbdInfo ( UGL_INPUT_DEVICE * pDevice,                                     UGL_DEVICE_REQ     request,                                     void *             arg);UGL_LOCAL void newKeys (UGL_USB_KBD_REPORT *current,                       UGL_USB_KBD_REPORT *diffUp,                       UGL_USB_KBD_REPORT *diffDown);UGL_LOCAL UGL_UINT16 MapKeyValue (UGL_UINT16 keyValue, UGL_UINT32 modifiers);UGL_LOCAL void uglUsbKbdCallback (void *cbArg, char pReport);UGL_LOCAL int keyboardCount = 0;/*************************************************************************** uglKbdAttachCallback - receives attach callbacks from keyboard SIO driver** RETURNS: N/A** */UGL_LOCAL void uglKbdAttachCallback    (    void * arg,             /* caller-defined argument */    SIO_CHAN *pChan,        /* pointer to affected SIO_CHAN */    UINT16 attachCode       /* defined as USB_KBD_xxxx */    )    {    if (attachCode == USB_KBD_ATTACH)        {        if (usbKeyboardSioChanLock (pChan) != OK)            {            uglLog (UGL_ERR_TYPE_WARN,                     "usbKeyboardSioChanLock () returned ERROR\n",0,0,0,0,0);            }        else            {            if ((*pChan->pDrvFuncs->callbackInstall)                    (pChan,                    SIO_CALLBACK_PUT_RCV_CHAR,                    (STATUS  (*) (void *, ...)) uglUsbKbdCallback,                    (pVOID) arg)                    != OK)                {                uglLog (UGL_ERR_TYPE_WARN,                         "uglUsbKbdCallback () failed to install\n",0,0,0,0,0);                }            uglLog (UGL_ERR_TYPE_INFO, "USB Keyboard attached\n",0,0,0,0,0);            usbKbdData.state =  UGL_USB_KBD_ATTACHED;            usbKbdData.pSioChan = pChan;            /*             * Configure keyboard for raw scan code and interrupt mode             * (rather than polled).             */            (*pChan->pDrvFuncs->ioctl)(pChan,                                                   SIO_KYBD_MODE_SET,                                                   (void *)SIO_KYBD_MODE_RAW);            (*pChan->pDrvFuncs->ioctl)(pChan,                                                   SIO_MODE_SET,                                                   (void *)SIO_MODE_INT);            }        }    else if (attachCode == USB_KBD_REMOVE)        {        if (usbKeyboardSioChanUnlock (pChan) != OK)            {            uglLog (UGL_ERR_TYPE_WARN,                    "usbKeyboardSioChanUnlock () returned ERROR\n",0,0,0,0,0);            return;            }        uglLog (UGL_ERR_TYPE_INFO, "USB Keyboard removed\n",0,0,0,0,0);        usbKbdData.state = UGL_USB_KBD_UNATTACHED;        }    }/******************************************************************************* uglUsbKbdCallback - Accept scan codes from USB keyboard driver** This routine is called by a USB task when a keyboard event occurs.  The* attempt here is to keep this callback code short.  The processing* occurs in the uglUsbKbdControl() function below.  All we do is write to* the pipe associated with the keyboard.  When that wakes up the select()* in the WindML app's input task, the input task will call the control* function below.**/UGL_LOCAL void uglUsbKbdCallback    (    void *cbArg,    char byteCode    )    {    write ((int)cbArg, &byteCode, 1);    }/******************************************************************************* uglUsbKbdInit - initialize the USB keyboard** This routine initializes the USB keyboard for operation with UGL.  The* keyboard attached to the device <pDevName> is opened and set in the* proper mode to function with UGL.  It creates a device entry for the * input sercice <inSvcId>.** After the proper mode is set it fills in the formatter, control, and* destroy function pointers in the device descriptor and allocates device * specific control data.* * RETURNS: input device identifier assigned to keyboard when success;*          otherwise UGL_NULL** ERRNO: N/A** SEE ALSO: uglUsbKbdDestroy()*/UGL_INPUT_DEVICE_ID uglUsbKbdInit    (    char *                  pDevName,       /* name of device; ignored */    UGL_EVENT_SERVICE_ID    eventServiceId      /* event service */    )    {    UGL_INPUT_DEVICE * pDevice;    int keyboardPipe;    char keyboardName[100];    if (usbKeyboardDevInit() != OK)        {        uglLog (UGL_ERR_TYPE_WARN,                "VxWorks USB keyboard unable to initialize.\n",0,0,0,0,0);        return (UGL_NULL);        }    /* Create the device */    pDevice = uglInputDeviceAdd (eventServiceId);    if (pDevice == UGL_NULL)        {        usbKeyboardDevShutdown();        return (UGL_NULL);        }    /* set the device type as a keyboard */    pDevice->deviceType = UGL_DEVICE_KEYBOARD;    /* set up function pointers for device */    pDevice->format = uglUsbKbdFormatter;    pDevice->destroy = uglUsbKbdDestroy;    pDevice->info = uglUsbKbdInfo;    /*     * Although the attachment callback is registered, the keyboard device is     * unattached until that callback is successfully called by USB.     */    usbKbdData.state = UGL_USB_KBD_UNATTACHED;    /*     * Create pipe so that we can trigger select() in input task.  Since     * is architected to support multiple devices, we'll create a new pipe     * for each.     */    sprintf(keyboardName, "/pipe/uglUsbKbd/%d", keyboardCount);    if (pipeDevCreate(keyboardName,                  UGL_USB_KBD_PIPE_LEN,                  sizeof(HID_KBD_BOOT_REPORT)) != ERROR)        {        /*         * Opening the pipe here in the app.  It will be written to         * from a USB task while in the callback above and then read         * in the input task.         */        keyboardPipe = open(keyboardName, O_RDWR, 0);        if (keyboardPipe != ERROR)            {            int await = 0;            pDevice->fd = keyboardPipe;            /* Register the attach callback */            if (usbKeyboardDynamicAttachRegister (uglKbdAttachCallback,                                             (pVOID) keyboardPipe) == ERROR)                {                close(keyboardPipe);                pipeDevDelete(keyboardName,1);                UGL_FREE(pDevice);                usbKeyboardDevShutdown();                uglLog (UGL_ERR_TYPE_WARN,                        "Call to usbKeyboardDynamicAttachRegister() failed\n",                        0,0,0,0,0);                return (UGL_NULL);                }            usbKbdData.pipeNum = keyboardCount;            keyboardCount++;            /*             * Wait a moment to let USBD hook things up. If it takes longer             * than about a second; keep going it may not be hooked up yet.             */            while (await < 15)                {                if (usbKbdData.state == UGL_USB_KBD_ATTACHED)                    break;                taskDelay(1);                await++;                }            uglLog (UGL_ERR_TYPE_INFO,                    "waited %d ticks for Keyboard attachment\n",                     await, 0, 0, 0, 0);            if (usbKbdData.state != UGL_USB_KBD_ATTACHED)                {                uglLog (UGL_ERR_TYPE_WARN,                        "- Check U/OHCI config and device.\n",0,0,0,0,0);                }            return ((UGL_INPUT_DEVICE_ID) pDevice);            }        else            {            pipeDevDelete(keyboardName,1);            uglLog (UGL_ERR_TYPE_WARN,                    "unable to open keyboard pipe %s\n",                    (int)keyboardName, 0, 0, 0, 0);            }        }    else        uglLog (UGL_ERR_TYPE_WARN,                "unable to create keyboard pipe\n",0,0,0,0,0);    /* If we had a problem... */    UGL_FREE (pDevice);    usbKeyboardDevShutdown();    return (UGL_NULL);    }/******************************************************************************* uglUsbKbdDestroy - destroy the device** This device terminates operations on a USB type keyboard.  It closes the* device and frees all resources.** RETURNS: UGL_STATUS_OK, or UGL_STATUS_ERROR if the operation fails.** ERRNO: N/A** SEE ALSO: uglUsbKbdInit()**/UGL_LOCAL UGL_STATUS uglUsbKbdDestroy    (    UGL_INPUT_DEVICE * pDevice      /* input device */    )    {    char keyboardName[100];    /*     * Detach from USB stuff.  Unregistering requires the identical     * parameters as the Register to work.     */     if (usbKeyboardDynamicAttachUnRegister (uglKbdAttachCallback,                    (pVOID) (pDevice->fd)) == ERROR)         uglLog (UGL_ERR_TYPE_WARN,                    "Unregister of attachment callback failed\n",0,0,0,0,0);    /*      * Uninstall callback; null callback vector     *     * This is only necessary in situations such as if there were     * multiple USB keyboards and one was closed, but the rest remained.     */    if (usbKbdData.pSioChan != 0)        {        if ((*usbKbdData.pSioChan->pDrvFuncs->callbackInstall)                    (usbKbdData.pSioChan,                    SIO_CALLBACK_PUT_RCV_CHAR,                    (STATUS  (*) (void *, ...)) 0,                    (pVOID) 0)                    != OK)            {            uglLog (UGL_ERR_TYPE_WARN,                    "uglUsbKbdCallback () failed to un-install\n",0,0,0,0,0);            }        }    usbKeyboardDevShutdown();    /* close the pipe */    close (pDevice->fd);    /* remove the pipe */    sprintf(keyboardName,             "/pipe/uglUsbKbd/%d", ((int)usbKbdData.pipeNum));    pipeDevDelete(keyboardName, 0);    /* free local storage */    UGL_FREE (pDevice);    return UGL_STATUS_OK;

⌨️ 快捷键说明

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