Index: /trunk/include/VBox/pdmifs.h
===================================================================
--- /trunk/include/VBox/pdmifs.h	(revision 33757)
+++ /trunk/include/VBox/pdmifs.h	(revision 33758)
@@ -1954,7 +1954,8 @@
      *
      * @returns VBox status code
-     * @param   capabilities  Capability mask
-     */
-    DECLR3CALLBACKMEMBER(int, pfnSetMouseCapabilities,(PPDMIVMMDEVPORT pInterface, uint32_t capabilities));
+     * @param   fCapsAdded    Mask of capabilities to add to the flag
+     * @param   fCapsRemoved  Mask of capabilities to remove from the flag
+     */
+    DECLR3CALLBACKMEMBER(int, pfnUpdateMouseCapabilities,(PPDMIVMMDEVPORT pInterface, uint32_t fCapsAdded, uint32_t fCapsremoved));
 
     /**
Index: /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 33757)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 33758)
@@ -2235,18 +2235,18 @@
  * @param   capabilities  Capability mask
  */
-static DECLCALLBACK(int) vmmdevSetMouseCapabilities(PPDMIVMMDEVPORT pInterface, uint32_t fCaps)
+static DECLCALLBACK(int) vmmdevUpdateMouseCapabilities(PPDMIVMMDEVPORT pInterface, uint32_t fCapsAdded, uint32_t fCapsRemoved)
 {
     VMMDevState *pThis = IVMMDEVPORT_2_VMMDEVSTATE(pInterface);
     PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
 
-    bool fNotify = (   (fCaps & VMMDEV_MOUSE_NOTIFY_GUEST_MASK)
-                    != (pThis->mouseCapabilities & VMMDEV_MOUSE_NOTIFY_GUEST_MASK));
-
-    LogRelFlowFunc(("fCaps=0x%x, fNotify %s\n", fCaps,
-                    fNotify ? "TRUE" : "FALSE"));
-
-    pThis->mouseCapabilities &=   ~VMMDEV_MOUSE_HOST_MASK
+    uint32_t fOldCaps = pThis->mouseCapabilities;
+    pThis->mouseCapabilities &= ~(fCapsRemoved & VMMDEV_MOUSE_HOST_MASK);
+    pThis->mouseCapabilities |=   (fCapsAdded & VMMDEV_MOUSE_HOST_MASK)
                                 | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR;
-    pThis->mouseCapabilities |= (fCaps & VMMDEV_MOUSE_HOST_MASK);
+    bool fNotify = fOldCaps != pThis->mouseCapabilities;
+
+    LogRelFlowFunc(("fCapsAdded=0x%x, fCapsRemoved=0x%x, fNotify %s\n",
+                    fCapsAdded, fCapsRemoved, fNotify ? "TRUE" : "FALSE"));
+
     if (fNotify)
         VMMDevNotifyGuest (pThis, VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED);
@@ -2895,28 +2895,28 @@
      */
     /* IBase */
-    pThis->IBase.pfnQueryInterface         = vmmdevPortQueryInterface;
+    pThis->IBase.pfnQueryInterface          = vmmdevPortQueryInterface;
 
     /* VMMDev port */
-    pThis->IPort.pfnQueryAbsoluteMouse     = vmmdevQueryAbsoluteMouse;
-    pThis->IPort.pfnSetAbsoluteMouse       = vmmdevSetAbsoluteMouse;
-    pThis->IPort.pfnQueryMouseCapabilities = vmmdevQueryMouseCapabilities;
-    pThis->IPort.pfnSetMouseCapabilities   = vmmdevSetMouseCapabilities;
-    pThis->IPort.pfnRequestDisplayChange   = vmmdevRequestDisplayChange;
-    pThis->IPort.pfnSetCredentials         = vmmdevSetCredentials;
-    pThis->IPort.pfnVBVAChange             = vmmdevVBVAChange;
-    pThis->IPort.pfnRequestSeamlessChange  = vmmdevRequestSeamlessChange;
-    pThis->IPort.pfnSetMemoryBalloon       = vmmdevSetMemoryBalloon;
-    pThis->IPort.pfnSetStatisticsInterval  = vmmdevSetStatisticsInterval;
-    pThis->IPort.pfnVRDPChange             = vmmdevVRDPChange;
-    pThis->IPort.pfnCpuHotUnplug           = vmmdevCpuHotUnplug;
-    pThis->IPort.pfnCpuHotPlug             = vmmdevCpuHotPlug;
+    pThis->IPort.pfnQueryAbsoluteMouse      = vmmdevQueryAbsoluteMouse;
+    pThis->IPort.pfnSetAbsoluteMouse        = vmmdevSetAbsoluteMouse;
+    pThis->IPort.pfnQueryMouseCapabilities  = vmmdevQueryMouseCapabilities;
+    pThis->IPort.pfnUpdateMouseCapabilities = vmmdevUpdateMouseCapabilities;
+    pThis->IPort.pfnRequestDisplayChange    = vmmdevRequestDisplayChange;
+    pThis->IPort.pfnSetCredentials          = vmmdevSetCredentials;
+    pThis->IPort.pfnVBVAChange              = vmmdevVBVAChange;
+    pThis->IPort.pfnRequestSeamlessChange   = vmmdevRequestSeamlessChange;
+    pThis->IPort.pfnSetMemoryBalloon        = vmmdevSetMemoryBalloon;
+    pThis->IPort.pfnSetStatisticsInterval   = vmmdevSetStatisticsInterval;
+    pThis->IPort.pfnVRDPChange              = vmmdevVRDPChange;
+    pThis->IPort.pfnCpuHotUnplug            = vmmdevCpuHotUnplug;
+    pThis->IPort.pfnCpuHotPlug              = vmmdevCpuHotPlug;
 
     /* Shared folder LED */
-    pThis->SharedFolders.Led.u32Magic      = PDMLED_MAGIC;
+    pThis->SharedFolders.Led.u32Magic       = PDMLED_MAGIC;
     pThis->SharedFolders.ILeds.pfnQueryStatusLed = vmmdevQueryStatusLed;
 
 #ifdef VBOX_WITH_HGCM
     /* HGCM port */
-    pThis->IHGCMPort.pfnCompleted          = hgcmCompleted;
+    pThis->IHGCMPort.pfnCompleted           = hgcmCompleted;
 #endif
 
Index: /trunk/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp	(revision 33757)
+++ /trunk/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp	(revision 33758)
@@ -156,5 +156,5 @@
  * @thread  The emulation thread.
  */
-DECLCALLBACK(void) VMMDev::UpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
+DECLCALLBACK(void) VMMDev::UpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t fNewCaps)
 {
     /*
@@ -163,12 +163,7 @@
 
     if (gMouse)
-    {
-        gMouse->onVMMDevCanAbsChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE));
-        gMouse->onVMMDevNeedsHostChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
-    }
+        gMouse->onVMMDevGuestCapsChange(fNewCaps & VMMDEV_MOUSE_GUEST_MASK);
     if (gConsole)
-    {
         gConsole->resetCursor();
-    }
 }
 
Index: /trunk/src/VBox/Main/MouseImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MouseImpl.cpp	(revision 33757)
+++ /trunk/src/VBox/Main/MouseImpl.cpp	(revision 33758)
@@ -26,8 +26,7 @@
 
 #include <VBox/pdmdrv.h>
+#include <VBox/VMMDev.h>
 
 #include <iprt/asm.h>
-
-#include <VBox/VMMDev.h>
 
 /** @name Mouse device capabilities bitfield
@@ -76,9 +75,7 @@
 {
     RT_ZERO(mpDrv);
-    mfVMMDevCanAbs = false;
-    mfVMMDevNeedsHostCursor = false;
-    mLastAbsX = 0x8000;
-    mLastAbsY = 0x8000;
-    mLastButtons = 0;
+    mcLastAbsX = 0x8000;
+    mcLastAbsY = 0x8000;
+    mfLastButtons = 0;
     return S_OK;
 }
@@ -118,6 +115,4 @@
 #endif
 
-    mfHostCaps = 0;
-
     /* Confirm a successful initialization */
     autoInitSpan.setSucceeded();
@@ -159,32 +154,19 @@
 /////////////////////////////////////////////////////////////////////////////
 
-/** Query the VMM device for the Guest Additions's (and the host front-end's)
- * mouse handling capabilities.
- * @note all calls out of this object are made with no locks held! */
-HRESULT Mouse::getVMMDevMouseCaps(uint32_t *pfCaps)
-{
-    AssertPtrReturn(pfCaps, E_POINTER);
-    /** @todo does getting the VMMDev and the VMMDevPort like this guarantee
-     * they won't go away while we are using them? */
-    VMMDev *pVMMDev = mParent->getVMMDev();
-    ComAssertRet(pVMMDev, E_FAIL);
-    PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
-    ComAssertRet(pVMMDevPort, E_FAIL);
-
-    int rc = pVMMDevPort->pfnQueryMouseCapabilities(pVMMDevPort, pfCaps);
-    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
-}
-
 /** Report the front-end's mouse handling capabilities to the VMM device and
  * thus to the guest.
  * @note all calls out of this object are made with no locks held! */
-HRESULT Mouse::setVMMDevMouseCaps(uint32_t fCaps)
+HRESULT Mouse::updateVMMDevMouseCaps(uint32_t fCapsAdded,
+                                     uint32_t fCapsRemoved)
 {
     VMMDev *pVMMDev = mParent->getVMMDev();
-    ComAssertRet(pVMMDev, E_FAIL);
+    if (!pVMMDev)
+        return E_FAIL;  /* No assertion, as the front-ends can send events
+                         * at all sorts of inconvenient times. */
     PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     ComAssertRet(pVMMDevPort, E_FAIL);
 
-    int rc = pVMMDevPort->pfnSetMouseCapabilities(pVMMDevPort, fCaps);
+    int rc = pVMMDevPort->pfnUpdateMouseCapabilities(pVMMDevPort, fCapsAdded,
+                                                     fCapsRemoved);
     return RT_SUCCESS(rc) ? S_OK : E_FAIL;
 }
@@ -206,15 +188,5 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-    bool fAbs = false;
-
-    if (mfVMMDevCanAbs)
-        fAbs = TRUE;
-
-    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
-        if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE))
-            fAbs = TRUE;
-
-    *absoluteSupported = fAbs;
+    *absoluteSupported = supportsAbs();
     return S_OK;
 }
@@ -235,12 +207,5 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-    bool fRel = false;
-
-    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
-        if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE))
-            fRel = TRUE;
-
-    *relativeSupported = fRel;
+    *relativeSupported = supportsRel();
     return S_OK;
 }
@@ -261,5 +226,5 @@
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
 
-    *pfNeedsHostCursor = mfVMMDevNeedsHostCursor;
+    *pfNeedsHostCursor = guestNeedsHostCursor();
     return S_OK;
 }
@@ -311,5 +276,5 @@
                                         int32_t dw, uint32_t fButtons)
 {
-    if (dx || dy || dz || dw || fButtons != mLastButtons)
+    if (dx || dy || dz || dw || fButtons != mfLastButtons)
     {
         PPDMIMOUSEPORT pUpPort = NULL;
@@ -332,5 +297,5 @@
                             tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
                             vrc);
-        mLastButtons = fButtons;
+        mfLastButtons = fButtons;
     }
     return S_OK;
@@ -347,6 +312,6 @@
                                         int32_t dz, int32_t dw, uint32_t fButtons)
 {
-    if (   mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY
-        || dz || dw || fButtons != mLastButtons)
+    if (   mouseXAbs != mcLastAbsX || mouseYAbs != mcLastAbsY
+        || dz || dw || fButtons != mfLastButtons)
     {
         PPDMIMOUSEPORT pUpPort = NULL;
@@ -369,5 +334,5 @@
                             tr("Could not send the mouse event to the virtual mouse (%Rrc)"),
                             vrc);
-        mLastButtons = fButtons;
+        mfLastButtons = fButtons;
 
     }
@@ -389,5 +354,5 @@
     ComAssertRet(pVMMDevPort, E_FAIL);
 
-    if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY)
+    if (mouseXAbs != mcLastAbsX || mouseYAbs != mcLastAbsY)
     {
         int vrc = pVMMDevPort->pfnSetAbsoluteMouse(pVMMDevPort,
@@ -418,10 +383,10 @@
     LONG cJiggle = 0;
 
-    if (mfVMMDevCanAbs)
+    if (vmmdevCanAbs())
     {
         /*
          * Send the absolute mouse position to the VMM device.
          */
-        if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY)
+        if (mouseXAbs != mcLastAbsX || mouseYAbs != mcLastAbsY)
         {
             rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs);
@@ -433,6 +398,6 @@
         rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons);
 
-    mLastAbsX = mouseXAbs;
-    mLastAbsY = mouseYAbs;
+    mcLastAbsX = mouseXAbs;
+    mcLastAbsY = mouseYAbs;
     return rc;
 }
@@ -453,29 +418,15 @@
 {
     HRESULT rc;
-    /** Do we need to send updated capabilities to the VMM device? */
-    bool fUpdateCaps = FALSE;
     uint32_t fButtons;
 
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
-
-    {
-        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-        LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
+    LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__,
                  dx, dy, dz, dw));
-        /* Make sure that the guest knows that we are sending real movement
-         * events to the PS/2 device and not just dummy wake-up ones. */
-        if (mfHostCaps & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
-        {
-            mfHostCaps &= ~VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;
-            fUpdateCaps = TRUE;
-        }
-
-        fButtons = mouseButtonsToPDM(buttonState);
-    }
-    /** @note we drop the lock before calling out of the object! */
-    if (fUpdateCaps)
-        setVMMDevMouseCaps(mfHostCaps);
+
+    fButtons = mouseButtonsToPDM(buttonState);
+    /* Make sure that the guest knows that we are sending real movement
+     * events to the PS/2 device and not just dummy wake-up ones. */
+    updateVMMDevMouseCaps(0, VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE);
     rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons);
 
@@ -538,7 +489,5 @@
              __PRETTY_FUNCTION__, x, y, dz, dw, buttonState));
 
-    uint32_t mouseXAbs, mouseYAbs;
-    /** Do we need to send updated capabilities to the VMM device? */
-    bool fUpdateCaps = FALSE;
+    uint32_t mouseXAbs, mouseYAbs, fButtons;
 
     /** @todo the front end should do this conversion to avoid races */
@@ -551,31 +500,16 @@
      * Understand the issues involved and fix for the rest. */
     /* if (mouseXAbs > 0xffff)
-        mouseXAbs = mLastAbsX;
+        mouseXAbs = mcLastAbsX;
     if (mouseYAbs > 0xffff)
-        mouseYAbs = mLastAbsY; */
-
-    uint32_t mouseCaps;
-    rc = getVMMDevMouseCaps(&mouseCaps);
-    if (FAILED(rc)) return rc;
-    uint32_t fButtons = mouseButtonsToPDM(buttonState);
-
+        mouseYAbs = mcLastAbsY; */
+
+    fButtons = mouseButtonsToPDM(buttonState);
     /* If we are doing old-style (IRQ-less) absolute reporting to the VMM
      * device then make sure the guest is aware of it, so that it knows to
      * ignore relative movement on the PS/2 device. */
-    {
-        AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS);
-
-        if (!(mfHostCaps & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
-        {
-            mfHostCaps |= VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;
-            fUpdateCaps = TRUE;
-        }
-    }
-    /** @note we drop the lock again before calling out! */
-    if (fUpdateCaps)
-        setVMMDevMouseCaps(mfHostCaps);
-
+    updateVMMDevMouseCaps(VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE, 0);
     rc = reportAbsEvent(mouseXAbs, mouseYAbs, dz, dw, fButtons,
-                        !!(mouseCaps & VMMDEV_MOUSE_GUEST_USES_EVENT));
+                        RT_BOOL(  mfVMMDevGuestCaps
+                                & VMMDEV_MOUSE_GUEST_USES_EVENT));
 
 #ifndef VBOXBFE_WITHOUT_COM
@@ -591,44 +525,99 @@
 
 
-/** Work out what mouse capabilities the guest and the front-end have to offer,
- * based on the state of the available emulated devices and the capabilities
- * the guest has signalled to the VMM device, and notify the guest and the
- * Console respectively about what the other can do. */
-void Mouse::sendMouseCapsNotifications(void)
+/** Does the guest currently rely on the host to draw the mouse cursor or
+ * can it switch to doing it itself in software? */
+bool Mouse::guestNeedsHostCursor(void)
+{
+    return RT_BOOL(mfVMMDevGuestCaps & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR);
+}
+
+
+/** Check what sort of reporting can be done using the devices currently
+ * enabled.  Does not consider the VMM device. */
+void Mouse::getDeviceCaps(bool *pfAbs, bool *pfRel)
 {
     bool fAbsDev = false;
     bool fRelDev = false;
-    uint32_t u32MouseCaps;
-
-    {
-        AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS);
-
-        for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
-            if (mpDrv[i])
-            {
-               if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
-                   fAbsDev = true;
-               if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
-                   fRelDev = true;
-            }
-        if (fAbsDev && !(mfHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
-            mfHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
-        if (!fAbsDev && (mfHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))
-            mfHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;
-    }
-    /** @note we drop the lock again before calling out! */
-    if (SUCCEEDED(getVMMDevMouseCaps(&u32MouseCaps)))
-        mfVMMDevCanAbs =    (u32MouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
-                        && fRelDev;
+
+    AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS);
+
+    for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i)
+        if (mpDrv[i])
+        {
+           if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)
+               fAbsDev = true;
+           if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)
+               fRelDev = true;
+        }
+    if (pfAbs)
+        *pfAbs = fAbsDev;
+    if (pfRel)
+        *pfRel = fRelDev;
+}
+
+
+/** Does the VMM device currently support absolute reporting? */
+bool Mouse::vmmdevCanAbs(void)
+{
+    bool fRelDev;
+
+    getDeviceCaps(NULL, &fRelDev);
+    return    (mfVMMDevGuestCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
+           && fRelDev;
+}
+
+
+/** Does the VMM device currently support absolute reporting? */
+bool Mouse::deviceCanAbs(void)
+{
+    bool fAbsDev;
+
+    getDeviceCaps(&fAbsDev, NULL);
+    return fAbsDev;
+}
+
+
+/** Can we currently send relative events to the guest? */
+bool Mouse::supportsRel(void)
+{
+    bool fRelDev;
+
+    getDeviceCaps(NULL, &fRelDev);
+    return fRelDev;
+}
+
+
+/** Can we currently send absolute events to the guest? */
+bool Mouse::supportsAbs(void)
+{
+    bool fAbsDev;
+
+    getDeviceCaps(&fAbsDev, NULL);
+    return fAbsDev || vmmdevCanAbs();
+}
+
+
+/** Check what sort of reporting can be done using the devices currently
+ * enabled (including the VMM device) and notify the guest and the front-end.
+ */
+void Mouse::sendMouseCapsNotifications(void)
+{
+    bool fAbsDev, fRelDev, fCanAbs, fNeedsHostCursor;
+
+    {
+        AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS);
+
+        getDeviceCaps(&fAbsDev, &fRelDev);
+        fCanAbs = supportsAbs();
+        fNeedsHostCursor = guestNeedsHostCursor();
+    }
+    if (fAbsDev)
+        updateVMMDevMouseCaps(VMMDEV_MOUSE_HOST_HAS_ABS_DEV, 0);
     else
-        mfVMMDevCanAbs = false;
+        updateVMMDevMouseCaps(0, VMMDEV_MOUSE_HOST_HAS_ABS_DEV);
     /** @todo this call takes the Console lock in order to update the cached
      * callback data atomically.  However I can't see any sign that the cached
      * data is ever used again. */
-    mParent->onMouseCapabilityChange(fAbsDev || mfVMMDevCanAbs, fRelDev,
-                                     mfVMMDevNeedsHostCursor);
-    /** @todo if this gets called during device initialisation we get an
-     * error due to VMMDev not being initialised yet. */
-    setVMMDevMouseCaps(mfHostCaps);
+    mParent->onMouseCapabilityChange(fCanAbs, fRelDev, fNeedsHostCursor);
 }
 
Index: /trunk/src/VBox/Main/VMMDevInterface.cpp
===================================================================
--- /trunk/src/VBox/Main/VMMDevInterface.cpp	(revision 33757)
+++ /trunk/src/VBox/Main/VMMDevInterface.cpp	(revision 33758)
@@ -323,5 +323,5 @@
  * @thread  The emulation thread.
  */
-DECLCALLBACK(void) vmmdevUpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
+DECLCALLBACK(void) vmmdevUpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t fNewCaps)
 {
     PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
@@ -334,8 +334,5 @@
     Mouse *pMouse = pConsole->getMouse();
     if (pMouse)  /** @todo and if not?  Can that actually happen? */
-    {
-        pMouse->onVMMDevCanAbsChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE));
-        pMouse->onVMMDevNeedsHostChange(!!(newCapabilities & VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR));
-    }
+        pMouse->onVMMDevGuestCapsChange(fNewCaps & VMMDEV_MOUSE_GUEST_MASK);
 }
 
Index: /trunk/src/VBox/Main/include/MouseImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MouseImpl.h	(revision 33757)
+++ /trunk/src/VBox/Main/include/MouseImpl.h	(revision 33758)
@@ -82,15 +82,8 @@
     }
 
-    /** notify the front-end that the guest now supports absolute reporting */
-    void onVMMDevCanAbsChange(bool)
+    /** notify the front-end of guest capability changes */
+    void onVMMDevGuestCapsChange(uint32_t fCaps)
     {
-        sendMouseCapsNotifications();
-    }
-
-    /** notify the front-end as to whether the guest can start drawing its own
-     * cursor on demand */
-    void onVMMDevNeedsHostChange(bool needsHost)
-    {
-        mfVMMDevNeedsHostCursor = needsHost;
+        mfVMMDevGuestCaps = fCaps;
         sendMouseCapsNotifications();
     }
@@ -103,6 +96,5 @@
     static DECLCALLBACK(void)   drvDestruct(PPDMDRVINS pDrvIns);
 
-    HRESULT getVMMDevMouseCaps(uint32_t *pfCaps);
-    HRESULT setVMMDevMouseCaps(uint32_t fCaps);
+    HRESULT updateVMMDevMouseCaps(uint32_t fCapsAdded, uint32_t fCapsRemoved);
     HRESULT reportRelEventToMouseDev(int32_t dx, int32_t dy, int32_t dz,
                                  int32_t dw, uint32_t fButtons);
@@ -115,5 +107,11 @@
     HRESULT convertDisplayRes(LONG x, LONG y, uint32_t *pcX, uint32_t *pcY);
 
+    void getDeviceCaps(bool *pfAbs, bool *pfRel);
     void sendMouseCapsNotifications(void);
+    bool guestNeedsHostCursor(void);
+    bool vmmdevCanAbs(void);
+    bool deviceCanAbs(void);
+    bool supportsAbs(void);
+    bool supportsRel(void);
 
 #ifdef VBOXBFE_WITHOUT_COM
@@ -125,10 +123,8 @@
     struct DRVMAINMOUSE    *mpDrv[MOUSE_MAX_DEVICES];
 
-    LONG mfHostCaps;
-    bool mfVMMDevCanAbs;
-    bool mfVMMDevNeedsHostCursor;
-    uint32_t mLastAbsX;
-    uint32_t mLastAbsY;
-    uint32_t mLastButtons;
+    uint32_t mfVMMDevGuestCaps;  /** We cache this to avoid access races */
+    uint32_t mcLastAbsX;
+    uint32_t mcLastAbsY;
+    uint32_t mfLastButtons;
 
 #ifndef VBOXBFE_WITHOUT_COM
