VirtualBox

Changeset 27838 in vbox for trunk/src


Ignore:
Timestamp:
Mar 30, 2010 5:52:53 PM (15 years ago)
Author:
vboxsync
Message:

USB keyboard: avoid loosing keypresses due to missed URBs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Input/UsbKbd.cpp

    r27129 r27838  
    1313*   Header Files                                                               *
    1414*******************************************************************************/
    15 #define LOG_GROUP   LOG_GROUP_USB_MSD
     15#define LOG_GROUP   LOG_GROUP_USB_KBD
    1616#include <VBox/pdmusb.h>
    1717#include <VBox/log.h>
     
    160160    /** Someone is waiting on the done queue. */
    161161    bool                fHaveDoneQueueWaiter;
     162    /** If no URB since last key press */
     163    bool                fNoUrbSinceLastPress;
     164    /* Keys released since last URB */
     165    uint8_t             aReleasedKeys[6];
    162166
    163167    /**
     
    603607    pThis->bIdle = 0;
    604608    memset(&pThis->Report, 0, sizeof(pThis->Report));
     609    pThis->fNoUrbSinceLastPress = false;
     610    memset(&pThis->aReleasedKeys, 0, sizeof(pThis->aReleasedKeys));
    605611
    606612    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aEps); i++)
     
    625631}
    626632
     633static void usbHidUpdateReportReleased(PUSBHID pThis, uint8_t u8HidCode)
     634{
     635    unsigned i;
     636   
     637    for (i = 0; i < RT_ELEMENTS(pThis->Report.aKeys); ++i)
     638    {
     639        if (pThis->Report.aKeys[i] == u8HidCode)
     640        {
     641            pThis->Report.aKeys[i] = 0;
     642            break;                              /* Remove key down. */
     643        }
     644    }
     645
     646    if (i == RT_ELEMENTS(pThis->Report.aKeys))
     647    {
     648        //            AssertMsgFailed(("Key is up but was never down!?"));
     649    }
     650}
    627651
    628652/**
     
    636660        PUSBHIDK_REPORT pReport = &pThis->Report;
    637661        size_t          cbCopy;
     662        unsigned        i;
    638663
    639664        cbCopy = sizeof(*pReport);
    640665        memcpy(&pUrb->abData[0], pReport, cbCopy);
     666        pThis->fNoUrbSinceLastPress = false;
     667        for (i=0; i < RT_ELEMENTS(pThis->aReleasedKeys); ++i)
     668        {
     669            if (pThis->aReleasedKeys[i] != 0)
     670            {
     671                usbHidUpdateReportReleased(pThis, pThis->aReleasedKeys[i]);
     672                pThis->aReleasedKeys[i] = 0;
     673            }
     674        }
    641675//        LogRel(("Sent report: %x : %x %x, size %d\n", pReport->ShiftState, pReport->aKeys[0], pReport->aKeys[1], cbCopy));
    642676        return usbHidCompleteOk(pThis, pUrb, cbCopy);
     677    }
     678    else
     679    {
     680        Log(("No available URB for USB kbd\n"));
    643681    }
    644682    return VINF_EOF;
     
    695733                }
    696734            }
     735
     736            pThis->fNoUrbSinceLastPress = true;
     737
    697738            if (i == RT_ELEMENTS(pReport->aKeys))
    698739            {
    699740                /* We ran out of room. Report error. */
     741                Log(("no more room in usbHidKeyboardPutEvent\n"));
    700742                // @todo!!
    701743            }
     
    703745        else
    704746        {
    705             for (i = 0; i < RT_ELEMENTS(pReport->aKeys); ++i)
    706             {
    707                 if (pReport->aKeys[i] == u8HidCode)
     747            /* We have to avoid coalescing key presses and releases, so put all releases somewhere else */
     748            if (pThis->fNoUrbSinceLastPress)
     749            {               
     750                for (i = 0; i < RT_ELEMENTS(pThis->aReleasedKeys); ++i)
    708751                {
    709                     pReport->aKeys[i] = 0;
    710                     break;                              /* Remove key down. */
     752                    if (pThis->aReleasedKeys[i] == 0)
     753                    {
     754                        pThis->aReleasedKeys[i] = u8HidCode;
     755                        break;
     756                    }
    711757                }
    712758            }
    713             if (i == RT_ELEMENTS(pReport->aKeys))
    714             {
    715     //            AssertMsgFailed(("Key is up but was never down!?"));
    716             }
     759            else
     760                usbHidUpdateReportReleased(pThis, u8HidCode);
    717761        }
    718762
     
    841885{
    842886    PVUSBSETUP pSetup = (PVUSBSETUP)&pUrb->abData[0];
     887    LogFlow(("usbHidHandleDefaultPipe: cbData=%d\n", pUrb->cbData));
     888
    843889    AssertReturn(pUrb->cbData >= sizeof(*pSetup), VERR_VUSB_FAILED_TO_QUEUE_URB);
    844890
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette