VirtualBox

Changeset 27060 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Mar 4, 2010 9:44:59 PM (15 years ago)
Author:
vboxsync
Message:

Devices, Main: add support for multiple pointing devices and let the guest choose which to use

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/MouseImpl.cpp

    r26982 r27060  
    3131#include <VBox/VMMDev.h>
    3232
     33/** @name Mouse device capabilities bitfield
     34 * @{ */
     35enum
     36{
     37    /** The mouse device can do relative reporting */
     38    MOUSE_DEVCAP_RELATIVE = 1,
     39    /** The mouse device can do absolute reporting */
     40    MOUSE_DEVCAP_ABSOLUTE = 2
     41};
     42/** @} */
     43
    3344/**
    3445 * Mouse driver instance data.
    3546 */
    36 typedef struct DRVMAINMOUSE
     47struct DRVMAINMOUSE
    3748{
    3849    /** Pointer to the mouse object. */
     
    4455    /** Our mouse connector interface. */
    4556    PDMIMOUSECONNECTOR          IConnector;
    46 } DRVMAINMOUSE, *PDRVMAINMOUSE;
     57    /** The capabilities of this device. */
     58    uint32_t                    u32DevCaps;
     59};
    4760
    4861
     
    5467HRESULT Mouse::FinalConstruct()
    5568{
    56     mpDrv = NULL;
    57     uDevCaps = MOUSE_DEVCAP_RELATIVE;
     69    RT_ZERO(mpDrv);
    5870    fVMMDevCanAbs = false;
    5971    fVMMDevNeedsHostCursor = false;
     
    116128        return;
    117129
    118     if (mpDrv)
    119         mpDrv->pMouse = NULL;
    120     mpDrv = NULL;
     130    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
     131    {
     132        if (mpDrv[i])
     133            mpDrv[i]->pMouse = NULL;
     134        mpDrv[i] = NULL;
     135    }
    121136
    122137#ifdef VBOXBFE_WITHOUT_COM
     
    170185
    171186    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    172 
    173     CHECK_CONSOLE_DRV (mpDrv);
    174 
    175     if (uDevCaps & MOUSE_DEVCAP_ABSOLUTE)
    176         *absoluteSupported = TRUE;
    177     else
    178         *absoluteSupported = fVMMDevCanAbs;
    179 
     187    bool fAbs = false;
     188
     189    if (fVMMDevCanAbs)
     190        fAbs = TRUE;
     191
     192    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
     193        if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
     194            fAbs = TRUE;
     195
     196    *absoluteSupported = fAbs;
    180197    return S_OK;
    181198}
     
    197214
    198215    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    199 
    200     CHECK_CONSOLE_DRV (mpDrv);
    201 
    202     if (uDevCaps & MOUSE_DEVCAP_RELATIVE)
    203         *relativeSupported = TRUE;
    204 
     216    bool fRel = false;
     217
     218    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
     219        if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
     220            fRel = TRUE;
     221
     222    *relativeSupported = fRel;
    205223    return S_OK;
    206224}
     
    221239
    222240    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    223 
    224     CHECK_CONSOLE_DRV (mpDrv);
    225241
    226242    *pfNeedsHostCursor = fVMMDevNeedsHostCursor;
     
    258274    if (dx || dy || dz || dw || fButtons != mLastButtons)
    259275    {
    260         PPDMIMOUSEPORT pUpPort = mpDrv->pUpPort;
     276        PPDMIMOUSEPORT pUpPort = NULL;
     277        for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
     278        {
     279            if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
     280                pUpPort = mpDrv[i]->pUpPort;
     281        }
     282        if (!pUpPort)
     283            return S_OK;       
     284
    261285        int vrc = pUpPort->pfnPutEvent(pUpPort, dx, dy, dz, dw, fButtons);
    262286
     
    279303                                    int32_t dz, int32_t dw, uint32_t fButtons)
    280304{
    281     if (   mouseXAbs != mLastAbsX
    282         || mouseYAbs != mLastAbsY
    283         || dz
    284         || dw
    285         || fButtons != mLastButtons)
    286     {
    287         int vrc = mpDrv->pUpPort->pfnPutEventAbs(mpDrv->pUpPort, mouseXAbs,
    288                                                  mouseYAbs, dz, dw, fButtons);
     305    if (   mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY
     306        || dz || dw || fButtons != mLastButtons)
     307    {
     308        PPDMIMOUSEPORT pUpPort = NULL;
     309        for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
     310        {
     311            if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
     312                pUpPort = mpDrv[i]->pUpPort;
     313        }
     314        if (!pUpPort)
     315            return S_OK;       
     316
     317        int vrc = pUpPort->pfnPutEventAbs(pUpPort, mouseXAbs, mouseYAbs, dz,
     318                                          dw, fButtons);
    289319        if (RT_FAILURE(vrc))
    290320            setError(VBOX_E_IPRT_ERROR,
     
    340370    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    341371
    342     CHECK_CONSOLE_DRV (mpDrv);
    343 
    344372    LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
    345373             dx, dy, dz, dw));
    346     if (!(uDevCaps & MOUSE_DEVCAP_ABSOLUTE))
    347     {
    348         /*
    349          * This method being called implies that the host no
    350          * longer wants to use absolute coordinates. If the VMM
    351          * device isn't aware of that yet, tell it.
    352          */
    353         uint32_t mouseCaps;
    354         rc = getVMMDevMouseCaps(&mouseCaps);
    355         ComAssertComRCRet(rc, rc);
    356 
    357         if (mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
    358             setVMMDevMouseCaps(uHostCaps);
     374    /*
     375     * This method being called implies that the host no
     376     * longer wants to use absolute coordinates. If the VMM
     377     * device isn't aware of that yet, tell it.
     378     */
     379    if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
     380    {
     381        uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     382        setVMMDevMouseCaps(uHostCaps);
    359383    }
    360384
     
    427451             __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
    428452
    429     CHECK_CONSOLE_DRV(mpDrv);
    430 
    431453    uint32_t mouseXAbs;
    432454    HRESULT rc = convertDisplayWidth(x, &mouseXAbs);
     
    434456    /**
    435457     * @todo multi-monitor Windows guests expect this to be unbounded.
    436      * Fix for the rest.
     458     * Understand the issues involved and fix for the rest.
    437459     */
    438460    /* if (mouseXAbs > 0xffff)
     
    447469    uint32_t fButtons = mouseButtonsToPDM(buttonState);
    448470
    449     /* Older guest additions rely on a small phony movement event on the
    450      * PS/2 device to notice absolute events. */
    451     bool fNeedsJiggle = false;
    452 
    453     if (uDevCaps & MOUSE_DEVCAP_ABSOLUTE)
    454         rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
    455     else
    456     {
    457         uint32_t mouseCaps;
    458         rc = getVMMDevMouseCaps(&mouseCaps);
    459         ComAssertComRCRet(rc, rc);
    460 
    461         /*
    462          * This method being called implies that the host wants
    463          * to use absolute coordinates. If the VMM device isn't
    464          * aware of that yet, tell it.
    465          */
    466         if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
    467             setVMMDevMouseCaps(uHostCaps | VMMDEV_MOUSE_HOST_CAN_ABSOLUTE);
    468 
     471    uint32_t mouseCaps;
     472    rc = getVMMDevMouseCaps(&mouseCaps);
     473    ComAssertComRCRet(rc, rc);
     474
     475    /*
     476     * This method being called implies that the host wants
     477     * to use absolute coordinates. If the VMM device isn't
     478     * aware of that yet, tell it.
     479     */
     480    if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
     481    {
     482        uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     483        setVMMDevMouseCaps(uHostCaps);
     484    }
     485
     486    if (mouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
     487    {
    469488        /*
    470489         * Send the absolute mouse position to the VMM device.
    471490         */
    472491        rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
    473         fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
    474     }
    475     ComAssertComRCRet(rc, rc);
    476 
    477     mLastAbsX = mouseXAbs;
    478     mLastAbsY = mouseYAbs;
    479 
    480     if (!(uDevCaps & MOUSE_DEVCAP_ABSOLUTE))
    481     {
    482         /* We may need to send a relative event for button information or to
    483          * wake the guest up to the changed absolute co-ordinates.
    484          * If the event is a pure wake up one, we make sure it contains some
    485          * (possibly phony) event data to make sure it isn't just discarded on
    486          * the way. */
     492        /* We may need to send an additional event for button information or
     493         * to wake up older guests to the changed absolute co-ordinates.  If
     494         * the event is a pure wake up one, we make sure it contains some
     495         * (possibly phony) event data to make sure it isn't just discarded
     496         * on the way. */
     497        bool fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
    487498        if (fNeedsJiggle || fButtons != mLastButtons || dz || dw)
    488499        {
     
    492503        }
    493504    }
     505    else
     506        rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
     507
     508    ComAssertComRCRet(rc, rc);
     509
     510    mLastAbsX = mouseXAbs;
     511    mLastAbsY = mouseYAbs;
     512
    494513    mLastButtons = fButtons;
    495514    return rc;
     
    500519
    501520
    502 void Mouse::sendMouseCapsCallback(void)
    503 {
    504     bool fAbsSupported =   uDevCaps & MOUSE_DEVCAP_ABSOLUTE
    505                          ? true : fVMMDevCanAbs;
    506     mParent->onMouseCapabilityChange(fAbsSupported, uDevCaps & MOUSE_DEVCAP_RELATIVE, fVMMDevNeedsHostCursor);
     521void Mouse::sendMouseCapsNotifications(void)
     522{
     523    bool fAbsDev = false;
     524    bool fRelDev = false;
     525    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
     526        if (mpDrv[i])
     527        {
     528           if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
     529               fAbsDev = true;
     530           if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
     531               fRelDev = true;
     532        }
     533    mParent->onMouseCapabilityChange(fAbsDev || fVMMDevCanAbs, fRelDev,
     534                                     fVMMDevNeedsHostCursor);
     535    /** @todo if this gets called during device initialisation we get an
     536     * error due to VMMDev not being initialised yet.  This is currently
     537     * worked around in DevPS2 (which doesn't need the capability anyway of
     538     * course), but it seems to me that Main should be initialised before
     539     * the devices are. */
     540    if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
     541        uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
     542    if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
     543        uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
     544    setVMMDevMouseCaps(uHostCaps);
    507545}
    508546
     
    515553    PDRVMAINMOUSE pDrv = RT_FROM_MEMBER(pInterface, DRVMAINMOUSE, IConnector);
    516554    if (fRel)
    517         pDrv->pMouse->uDevCaps |= MOUSE_DEVCAP_RELATIVE;
     555        pDrv->u32DevCaps |= MOUSE_DEVCAP_RELATIVE;
    518556    else
    519         pDrv->pMouse->uDevCaps &= ~MOUSE_DEVCAP_RELATIVE;
     557        pDrv->u32DevCaps &= ~MOUSE_DEVCAP_RELATIVE;
    520558    if (fAbs)
    521         pDrv->pMouse->uDevCaps |= MOUSE_DEVCAP_ABSOLUTE;
     559        pDrv->u32DevCaps |= MOUSE_DEVCAP_ABSOLUTE;
    522560    else
    523         pDrv->pMouse->uDevCaps &= ~MOUSE_DEVCAP_ABSOLUTE;
    524 
    525     pDrv->pMouse->sendMouseCapsCallback();
     561        pDrv->u32DevCaps &= ~MOUSE_DEVCAP_ABSOLUTE;
     562
     563    pDrv->pMouse->sendMouseCapsNotifications();
    526564}
    527565
     
    556594    {
    557595        AutoWriteLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS);
    558         pData->pMouse->mpDrv = NULL;
     596        RT_ZERO(pData->pMouse->mpDrv);
    559597    }
    560598}
     
    609647    }
    610648    pData->pMouse = (Mouse *)pv;        /** @todo Check this cast! */
    611     pData->pMouse->mpDrv = pData;
     649    unsigned cDev;
     650    for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
     651        if (!pData->pMouse->mpDrv[cDev])
     652        {
     653            pData->pMouse->mpDrv[cDev] = pData;
     654            break;
     655        }
     656    if (cDev == MOUSE_MAX_DEVICES)
     657        return VERR_NO_MORE_HANDLES;
    612658
    613659    return VINF_SUCCESS;
  • trunk/src/VBox/Main/include/MouseImpl.h

    r26982 r27060  
    2828#include <VBox/pdmdrv.h>
    2929
     30/** Maximum number of devices supported */
     31enum { MOUSE_MAX_DEVICES = 3 };
     32/** Mouse driver instance data. */
     33typedef struct DRVMAINMOUSE DRVMAINMOUSE, *PDRVMAINMOUSE;
     34
    3035/** Simple mouse event class. */
    3136class MouseEvent
     
    4550// template instantiation
    4651typedef ConsoleEventBuffer<MouseEvent> MouseEventBuffer;
    47 
    48 enum
    49 {
    50     MOUSE_DEVCAP_RELATIVE = 1,
    51     MOUSE_DEVCAP_ABSOLUTE = 2
    52 };
    5352
    5453class ATL_NO_VTABLE Mouse :
     
    109108    {
    110109        fVMMDevCanAbs = canAbs;
    111         sendMouseCapsCallback();
     110        sendMouseCapsNotifications();
    112111    }
    113112
     
    115114    {
    116115        fVMMDevNeedsHostCursor = needsHost;
    117         sendMouseCapsCallback();
     116        sendMouseCapsNotifications();
    118117    }
    119118
     
    135134    int convertDisplayHeight(LONG y, uint32_t *pcY);
    136135   
    137     void sendMouseCapsCallback(void);
     136    void sendMouseCapsNotifications(void);
    138137
    139138#ifdef VBOXBFE_WITHOUT_COM
     
    143142#endif
    144143    /** Pointer to the associated mouse driver. */
    145     struct DRVMAINMOUSE    *mpDrv;
     144    struct DRVMAINMOUSE    *mpDrv[MOUSE_MAX_DEVICES];
    146145
    147146    LONG uHostCaps;
    148     LONG uDevCaps;
    149147    bool fVMMDevCanAbs;
    150148    bool fVMMDevNeedsHostCursor;
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