VirtualBox

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


Ignore:
Timestamp:
Sep 29, 2010 2:30:07 PM (14 years ago)
Author:
vboxsync
Message:

Main: some locking and readability clean-up of MouseImpl

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

Legend:

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

    r30764 r32817  
    110110    unconst(mParent) = parent;
    111111
    112 #ifdef RT_OS_L4
    113     /* L4 console has no own mouse cursor */
    114     uHostCaps = VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER;
    115 #else
    116112    uHostCaps = 0;
    117 #endif
    118113
    119114    /* Confirm a successful initialization */
     
    157152{
    158153    AssertPtrReturn(pfCaps, E_POINTER);
     154    /** @todo does getting the VMMDev and the VMMDevPort like this guarantee
     155     * they won't go away while we are using them? */
    159156    VMMDev *pVMMDev = mParent->getVMMDev();
    160157    ComAssertRet(pVMMDev, E_FAIL);
     
    192189    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    193190
    194     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     191    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    195192    bool fAbs = false;
    196193
     
    221218    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    222219
    223     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     220    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    224221    bool fRel = false;
    225222
     
    245242    AutoCaller autoCaller(this);
    246243    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    247 
    248     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    249244
    250245    *pfNeedsHostCursor = fVMMDevNeedsHostCursor;
     
    283278    {
    284279        PPDMIMOUSEPORT pUpPort = NULL;
    285         for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
    286280        {
    287             if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
    288                 pUpPort = mpDrv[i]->pUpPort;
     281            AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS);
     282
     283            for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
     284            {
     285                if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
     286                    pUpPort = mpDrv[i]->pUpPort;
     287            }
    289288        }
    290289        if (!pUpPort)
     
    297296                            tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
    298297                            vrc);
     298        mLastButtons = fButtons;
    299299    }
    300300    return S_OK;
     
    314314    {
    315315        PPDMIMOUSEPORT pUpPort = NULL;
    316         for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
    317316        {
    318             if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
    319                 pUpPort = mpDrv[i]->pUpPort;
     317            AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS);
     318
     319            for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)
     320            {
     321                if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
     322                    pUpPort = mpDrv[i]->pUpPort;
     323            }
    320324        }
    321325        if (!pUpPort)
     
    328332                            tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
    329333                            vrc);
     334        mLastButtons = fButtons;
    330335    }
    331336    return S_OK;
     
    357362}
    358363
     364HRESULT Mouse::reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs,
     365                              int32_t dz, int32_t dw, uint32_t fButtons,
     366                              bool fUsesVMMDevEvent)
     367{
     368    HRESULT rc;
     369    /** If we are using the VMMDev to report absolute position but without
     370     * VMMDev IRQ support then we need to send a small "jiggle" to the emulated
     371     * relative mouse device to alert the guest to changes. */
     372    LONG cJiggle = 0;
     373
     374    if (fVMMDevCanAbs)
     375    {
     376        /*
     377         * Send the absolute mouse position to the VMM device.
     378         */
     379        if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY)
     380        {
     381            rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
     382            cJiggle = 1;
     383        }
     384        rc = reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons);
     385    }
     386    else
     387        rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
     388
     389    mLastAbsX = mouseXAbs;
     390    mLastAbsY = mouseYAbs;
     391    return rc;
     392}
     393
    359394/**
    360395 * Send a mouse event.
     
    368403STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG buttonState)
    369404{
    370     HRESULT rc = S_OK;
     405    HRESULT rc;
     406    /** Do we need to send updated capabilities to the VMM device? */
     407    bool fUpdateCaps = FALSE;
     408    uint32_t fButtons;
    371409
    372410    AutoCaller autoCaller(this);
    373411    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    374412
    375     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    376 
    377     LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
    378              dx, dy, dz, dw));
    379     /*
    380      * This method being called implies that the host no
    381      * longer wants to use absolute coordinates. If the VMM
    382      * device isn't aware of that yet, tell it.
    383      */
    384     if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
    385     {
    386         uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     413    {
     414        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     415
     416        LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
     417                 dx, dy, dz, dw));
     418        /* Make sure that the guest knows that we are sending real movement
     419         * events to the PS/2 device and not just dummy wake-up ones. */
     420        if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)
     421        {
     422            uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     423            fUpdateCaps = TRUE;
     424        }
     425
     426        fButtons = mouseButtonsToPDM(buttonState);
     427    }
     428    if (fUpdateCaps)
    387429        setVMMDevMouseCaps(uHostCaps);
    388     }
    389 
    390     uint32_t fButtons = mouseButtonsToPDM(buttonState);
    391430    rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons);
    392     if (SUCCEEDED(rc))
    393         mLastButtons = fButtons;
    394431
    395432    return rc;
     
    397434
    398435/**
    399  * Convert an X value in screen co-ordinates (starting from 1) to a value
    400  * from 0 to 0xffff.
     436 * Convert an (X, Y) value pair in screen co-ordinates (starting from 1) to a
     437 * value from 0 to 0xffff.
    401438 *
    402439 * @returns   COM status value
    403440 */
    404 HRESULT Mouse::convertDisplayWidth(LONG x, uint32_t *pcX)
     441HRESULT Mouse::convertDisplayRes(LONG x, LONG y, uint32_t *pcX, uint32_t *pcY)
    405442{
    406443    AssertPtrReturn(pcX, E_POINTER);
    407     Display *pDisplay = mParent->getDisplay();
    408     ComAssertRet(pDisplay, E_FAIL);
    409 
    410     ULONG displayWidth;
    411     HRESULT rc = pDisplay->GetScreenResolution (0, &displayWidth, NULL, NULL);
    412     if (FAILED(rc)) return rc;
    413 
    414     *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0;
    415     return S_OK;
    416 }
    417 
    418 /**
    419  * Convert a Y value in screen co-ordinates (starting from 1) to a value
    420  * from 0 to 0xffff.
    421  *
    422  * @returns   COM status value
    423  */
    424 HRESULT Mouse::convertDisplayHeight(LONG y, uint32_t *pcY)
    425 {
    426444    AssertPtrReturn(pcY, E_POINTER);
    427445    Display *pDisplay = mParent->getDisplay();
    428446    ComAssertRet(pDisplay, E_FAIL);
    429447
    430     ULONG displayHeight;
    431     HRESULT rc = pDisplay->GetScreenResolution (0, NULL, &displayHeight, NULL);
    432     if (FAILED(rc)) return rc;
    433 
     448    ULONG displayWidth, displayHeight;
     449    /* Takes the display lock */
     450    HRESULT rc = pDisplay->GetScreenResolution (0, &displayWidth, &displayHeight,
     451                                                NULL);
     452    if (FAILED(rc))
     453        return rc;
     454
     455    *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0;
    434456    *pcY = displayHeight ? ((y - 1) * 0xFFFF) / displayHeight: 0;
    435457    return S_OK;
     
    438460
    439461/**
    440  * Send an absolute mouse event to the VM. This only works
    441  * when the required guest support has been installed.
     462 * Send an absolute mouse event to the VM. This requires either VirtualBox-
     463 * specific drivers installed in the guest or absolute pointing device
     464 * emulation.
    442465 *
    443466 * @returns COM status code
     
    453476    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    454477
    455     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    456 
    457478    LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, buttonState=0x%x\n",
    458479             __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
    459480
    460     uint32_t mouseXAbs;
     481    uint32_t mouseXAbs, mouseYAbs;
     482    /** Do we need to send updated capabilities to the VMM device? */
     483    bool fUpdateCaps = FALSE;
     484
    461485    /** @todo the front end should do this conversion to avoid races */
    462     HRESULT rc = convertDisplayWidth(x, &mouseXAbs);
     486    /** @note Or maybe not... races are pretty inherent in everything done in
     487     *        this object and not really bad as far as I can see. */
     488    HRESULT rc = convertDisplayRes(x, y, &mouseXAbs, &mouseYAbs);
    463489    if (FAILED(rc)) return rc;
    464490
    465     /**
    466      * @todo multi-monitor Windows guests expect this to be unbounded.
    467      * Understand the issues involved and fix for the rest.
    468      */
     491    /** @todo multi-monitor Windows guests expect this to be unbounded.
     492     * Understand the issues involved and fix for the rest. */
    469493    /* if (mouseXAbs > 0xffff)
    470         mouseXAbs = mLastAbsX; */
    471 
    472     uint32_t mouseYAbs;
    473     rc = convertDisplayHeight(y, &mouseYAbs);
    474     if (FAILED(rc)) return rc;
    475     /* if (mouseYAbs > 0xffff)
     494        mouseXAbs = mLastAbsX;
     495    if (mouseYAbs > 0xffff)
    476496        mouseYAbs = mLastAbsY; */
    477 
    478     uint32_t fButtons = mouseButtonsToPDM(buttonState);
    479497
    480498    uint32_t mouseCaps;
    481499    rc = getVMMDevMouseCaps(&mouseCaps);
    482500    if (FAILED(rc)) return rc;
    483 
    484     /*
    485      * This method being called implies that the host wants
    486      * to use absolute coordinates. If the VMM device isn't
    487      * aware of that yet, tell it.
    488      */
    489     if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
    490     {
    491         uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     501    uint32_t fButtons = mouseButtonsToPDM(buttonState);
     502
     503    /* If we are doing old-style (IRQ-less) absolute reporting to the VMM
     504     * device then make sure the guest is aware of it, so that it knows to
     505     * ignore relative movement on the PS/2 device. */
     506    {
     507        AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS);
     508
     509        /** @todo rename that capability to VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE */
     510        if (fVMMDevCanAbs && !(uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE))
     511        {
     512            uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE;
     513            fUpdateCaps = TRUE;
     514        }
     515    }
     516    if (fUpdateCaps)
    492517        setVMMDevMouseCaps(uHostCaps);
    493     }
    494 
    495     if (fVMMDevCanAbs)
    496     {
    497         /*
    498          * Send the absolute mouse position to the VMM device.
    499          */
    500         rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
    501         /* We may need to send an additional event for button information or
    502          * to wake up older guests to the changed absolute co-ordinates.  If
    503          * the event is a pure wake up one, we make sure it contains some
    504          * (possibly phony) event data to make sure it isn't just discarded
    505          * on the way. */
    506         bool fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
    507         if (fNeedsJiggle || fButtons != mLastButtons || dz || dw)
    508         {
    509             rc = reportRelEventToMouseDev(fNeedsJiggle ? 1 : 0, 0, dz, dw,
    510                                           fButtons);
    511         }
    512     }
    513     else
    514         rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
    515 
    516     if (FAILED(rc)) return rc;
    517 
    518     mLastAbsX = mouseXAbs;
    519     mLastAbsY = mouseYAbs;
    520 
    521     mLastButtons = fButtons;
     518
     519    /** @todo rename that capability to VMMDEV_MOUSE_GUEST_USES_EVENT */
     520    rc = reportAbsEvent(mouseXAbs, mouseYAbs, dz, dw, fButtons,
     521                        mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV);
     522
    522523    return rc;
    523524}
     
    532533    bool fRelDev = false;
    533534    uint32_t u32MouseCaps;
    534     for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
    535         if (mpDrv[i])
    536         {
    537            if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
    538                fAbsDev = true;
    539            if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
    540                fRelDev = true;
    541         }
     535   
     536    {
     537        AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS);
     538
     539        for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
     540            if (mpDrv[i])
     541            {
     542               if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
     543                   fAbsDev = true;
     544               if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
     545                   fRelDev = true;
     546            }
     547        if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
     548            uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
     549        if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
     550            uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
     551    }
    542552    if (SUCCEEDED(getVMMDevMouseCaps(&u32MouseCaps)))
    543553        fVMMDevCanAbs =    (u32MouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
     
    545555    else
    546556        fVMMDevCanAbs = false;
     557    /** @todo this call takes the Console lock in order to update the cached
     558     * callback data atomically.  However I can't see any sign that the cached
     559     * data is ever used again. */
    547560    mParent->onMouseCapabilityChange(fAbsDev || fVMMDevCanAbs, fRelDev,
    548561                                     fVMMDevNeedsHostCursor);
    549562    /** @todo if this gets called during device initialisation we get an
    550563     * error due to VMMDev not being initialised yet. */
    551     if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
    552         uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
    553     if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
    554         uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
    555564    setVMMDevMouseCaps(uHostCaps);
    556565}
     
    664673    pData->pMouse = (Mouse *)pv;        /** @todo Check this cast! */
    665674    unsigned cDev;
    666     for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
    667         if (!pData->pMouse->mpDrv[cDev])
    668         {
    669             pData->pMouse->mpDrv[cDev] = pData;
    670             break;
    671         }
     675    {
     676        AutoReadLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS);
     677
     678        for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev)
     679            if (!pData->pMouse->mpDrv[cDev])
     680            {
     681                pData->pMouse->mpDrv[cDev] = pData;
     682                break;
     683            }
     684    }
    672685    if (cDev == MOUSE_MAX_DEVICES)
    673686        return VERR_NO_MORE_HANDLES;
  • trunk/src/VBox/Main/include/MouseImpl.h

    r30764 r32817  
    120120                                 int32_t dz, int32_t dw, uint32_t fButtons);
    121121    HRESULT reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs);
    122     HRESULT convertDisplayWidth(LONG x, uint32_t *pcX);
    123     HRESULT convertDisplayHeight(LONG y, uint32_t *pcY);
     122    HRESULT reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs,
     123                           int32_t dz, int32_t dw, uint32_t fButtons,
     124                           bool fUsesVMMDevEvent);
     125    HRESULT convertDisplayRes(LONG x, LONG y, uint32_t *pcX, uint32_t *pcY);
    124126
    125127    void sendMouseCapsNotifications(void);
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