Index: /trunk/include/VBox/HGSMI/HGSMIChSetup.h
===================================================================
--- /trunk/include/VBox/HGSMI/HGSMIChSetup.h	(revision 53964)
+++ /trunk/include/VBox/HGSMI/HGSMIChSetup.h	(revision 53965)
@@ -58,4 +58,7 @@
 /** monitor hotplug flag, should be accessed under VGAState::lock only */
 #define HGSMIHOSTFLAGS_HOTPLUG             0x20
+/** Cursor capability state change flag, should be accessed under
+ * VGAState::lock only.  @see VBVACONF32. */
+#define HGSMIHOSTFLAGS_CURSOR_CAPABILITIES 0x40
 
 typedef struct _HGSMIHOSTFLAGS
Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 53964)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 53965)
@@ -857,4 +857,9 @@
 #define VBVA_CMDVBVA_CTL     18 /* G->H DMA command             */
 #define VBVA_QUERY_MODE_HINTS 19 /* Query most recent mode hints sent. */
+/** Report the guest virtual desktop position and size for mapping host and
+ * guest pointer positions. */
+#define VBVA_REPORT_INPUT_MAPPING 20
+/** Report the guest cursor position and query the host position. */
+#define VBVA_CURSOR_POSITION 21
 
 /* host->guest commands */
@@ -915,4 +920,11 @@
  * Set value to VERR_NOT_SUPPORTED before calling. */
 #define VBOX_VBVA_CONF32_MODE_HINT_REPORTING  2
+/** Returns VINF_SUCCESS if the host can receive guest cursor information via
+ * VBVA.  Set value to VERR_NOT_SUPPORTED before calling. */
+#define VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING  3
+/** Returns the currently available host cursor capabilities.  Available if
+ * VBVACONF32::VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING returns success.
+ * @see VMMDevReqMouseStatus::mouseFeatures. */
+#define VBOX_VBVA_CONF32_CURSOR_CAPABILITIES  4
 
 typedef struct VBVACONF32
@@ -1083,4 +1095,6 @@
 /** The guest can read video mode hints sent via VBVA. */
 #define VBVACAPS_VIDEO_MODE_HINTS       0x00000004
+/** The guest can switch to a software cursor on demand. */
+#define VBVACAPS_DISABLE_CURSOR_INTEGRATION 0x00000008
 typedef struct VBVACAPS
 {
@@ -1147,4 +1161,28 @@
 
 #define VBVAMODEHINT_MAGIC UINT32_C(0x0801add9)
+
+/** Report the rectangle relative to which absolute pointer events should be
+ *  expressed.  This information remains valid until the next VBVA resize event
+ *  for any screen, at which time it is reset to the bounding rectangle of all
+ *  virtual screens. 
+ *  @see VBVA_REPORT_INPUT_MAPPING. */
+typedef struct VBVAREPORTINPUTMAPPING
+{
+    int32_t x;    /**< Upper left X co-ordinate relative to the first screen. */
+    int32_t y;    /**< Upper left Y co-ordinate relative to the first screen. */
+    uint32_t cx;  /**< Rectangle width. */
+    uint32_t cy;  /**< Rectangle height. */
+} VBVAREPORTINPUTMAPPING;
+
+/** Report the guest cursor position and query the host one.  The host may wish
+ *  to use the guest information to re-position its own cursor (though this is
+ *  currently unlikely).
+ *  @see VBVA_CURSOR_POSITION */
+typedef struct VBVACURSORPOSITION
+{
+    uint32_t fReportPosition;  /**< Are we reporting a position? */
+    uint32_t x;                /**< Guest cursor X position */
+    uint32_t y;                /**< Guest cursor Y position */
+} VBVACURSORPOSITION;
 
 #pragma pack()
Index: /trunk/include/VBox/vmm/pdmifs.h
===================================================================
--- /trunk/include/VBox/vmm/pdmifs.h	(revision 53964)
+++ /trunk/include/VBox/vmm/pdmifs.h	(revision 53965)
@@ -680,10 +680,31 @@
                           uint32_t cBPP, uint32_t iDisplay, uint32_t dx,
                           uint32_t dy, uint32_t fEnabled, uint32_t fNotifyGuest));
+
+    /**
+     * Send the guest a notification about host cursor capabilities changes.
+     *
+     * @param   pInterface            Pointer to this interface.
+     * @param   fCapabilitiesAdded    New supported capabilities.
+     * @param   fCapabilitiesRemoved  No longer supported capabilities.
+     * @thread  Any.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnReportHostCursorCapabilities, (PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+                                                                 uint32_t fCapabilitiesRemoved));
+
+    /**
+     * Tell the graphics device about the host cursor position.
+     *
+     * @param   pInterface  Pointer to this interface.
+     * @param   x           X offset into the cursor range.
+     * @param   y           Y offset into the cursor range.
+     * @thread  Any.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnReportHostCursorPosition, (PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y));
 } PDMIDISPLAYPORT;
 /** PDMIDISPLAYPORT interface ID. */
 #ifdef VBOX_WITH_VMSVGA
-#define PDMIDISPLAYPORT_IID                     "f7ed5b9a-3940-4862-9310-1de7e3d118a4"
+#define PDMIDISPLAYPORT_IID                     "e8da6d7e-8490-11e4-91d8-ab609a010f13"
 #else
-#define PDMIDISPLAYPORT_IID                     "613ed6c0-817a-11e4-bc1e-931613071d2c"
+#define PDMIDISPLAYPORT_IID                     "db067c60-8490-11e4-8424-032afeb83818"
 #endif
 
@@ -849,5 +870,5 @@
      * @param   fRenderThreadMode   if true - the graphics device has a separate thread that does all rendering.
      *                              This means that:
-     *                              1. all pfnVBVAXxx callbacks (including the current pfnVBVAEnable call), except displayVBVAMousePointerShape
+     *                              1. most pfnVBVAXxx callbacks (see the individual documentation for each one)
      *                                 will be called in the context of the render thread rather than the emulation thread
      *                              2. PDMIDISPLAYCONNECTOR implementor (i.e. DisplayImpl) must NOT notify crogl backend
@@ -970,7 +991,19 @@
     uint32_t        cy;
     /** @} */
+
+    /**
+     * The guest display input mapping rectangle was updated.
+     *
+     * @param   pInterface  Pointer to this interface.
+     * @param   xOrigin     Upper left X co-ordinate relative to the first screen.
+     * @param   yOrigin     Upper left Y co-ordinate relative to the first screen.
+     * @param   cx          Rectangle width.
+     * @param   cy          Rectangle height.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnVBVAInputMappingUpdate,(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy));
 } PDMIDISPLAYCONNECTOR;
 /** PDMIDISPLAYCONNECTOR interface ID. */
-#define PDMIDISPLAYCONNECTOR_IID                "33a332b3-0850-4b0f-a697-dcc140bb2e05"
+#define PDMIDISPLAYCONNECTOR_IID                "e883a720-85fb-11e4-a307-0b06689c9661"
 
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 53964)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 53965)
@@ -6064,4 +6064,8 @@
 #endif
     pThis->IPort.pfnSendModeHint        = vbvaPortSendModeHint;
+    pThis->IPort.pfnReportHostCursorCapabilities
+                                        = vbvaPortReportHostCursorCapabilities;
+    pThis->IPort.pfnReportHostCursorPosition
+                                        = vbvaPortReportHostCursorPosition;
 
 #if defined(VBOX_WITH_HGSMI)
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 53964)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 53965)
@@ -557,5 +557,5 @@
     uint32_t                    fGuestCaps;
     uint32_t                    fScanLineCfg;
-    uint8_t                     Padding10[4];
+    uint32_t                    fHostCursorCapabilities;
 #  else
     uint8_t                     Padding10[14];
@@ -692,4 +692,7 @@
                                        uint32_t dy, uint32_t fEnabled,
                                        uint32_t fNotifyGuest);
+DECLCALLBACK(void) vbvaPortReportHostCursorCapabilities(PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+                                                        uint32_t fCapabilitiesRemoved);
+DECLCALLBACK(void) vbvaPortReportHostCursorPosition(PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y);
 
 # ifdef VBOX_WITH_VDMA
Index: /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 53964)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 53965)
@@ -83,4 +83,6 @@
     VBVAMOUSESHAPEINFO mouseShapeInfo;
     bool fPaused;
+    uint32_t xCursor;
+    uint32_t yCursor;
     VBVAMODEHINT aModeHints[VBOX_VIDEO_MAX_SCREENS];
 } VBVACONTEXT;
@@ -2179,7 +2181,12 @@
                 pConf32->u32Value = 64*_1K;
             }
-            else if (pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING)
+            else if (   pConf32->u32Index == VBOX_VBVA_CONF32_MODE_HINT_REPORTING
+                     || pConf32->u32Index == VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING)
             {
                 pConf32->u32Value = VINF_SUCCESS;
+            }
+            else if (pConf32->u32Index == VBOX_VBVA_CONF32_CURSOR_CAPABILITIES)
+            {
+                pConf32->u32Value = pVGAState->fHostCursorCapabilities;
             }
             else
@@ -2483,4 +2490,37 @@
                 Assert(pbHint - (uint8_t *)pvBuffer <= cbBuffer);
             }
+        } break;
+
+        case VBVA_REPORT_INPUT_MAPPING:
+        {
+            if (cbBuffer != sizeof(VBVAREPORTINPUTMAPPING))
+            {
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+            VBVAREPORTINPUTMAPPING *pReport = (VBVAREPORTINPUTMAPPING *)pvBuffer;
+            LogRelFlowFunc(("VBVA_REPORT_INPUT_MAPPING: x=%u, y=%u, cx=%u, cy=%u\n", (unsigned)pReport->x, (unsigned)pReport->y,
+                            (unsigned)pReport->cx, (unsigned)pReport->cy));
+            pVGAState->pDrv->pfnVBVAInputMappingUpdate(pVGAState->pDrv, pReport->x, pReport->y, pReport->cx, pReport->cy);
+        } break;
+
+        case VBVA_CURSOR_POSITION:
+        {
+            if (cbBuffer != sizeof(VBVACURSORPOSITION))
+            {
+                rc = VERR_INVALID_PARAMETER;
+                break;
+            }
+            VBVACURSORPOSITION *pReport
+                = (VBVACURSORPOSITION *)pvBuffer;
+            LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=%RTbool",
+                            RT_BOOL(pReport->fReportPosition)));
+            if (RT_BOOL(pReport->fReportPosition))
+                LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=true, x=%u, y=%u\n",
+                               (unsigned)pReport->x, (unsigned)pReport->y));
+            else
+                LogRelFlowFunc(("VBVA_CURSOR_POSITION: fReportPosition=false\n"));
+            pReport->x = pCtx->xCursor;
+            pReport->y = pCtx->yCursor;
         } break;
 
@@ -2622,4 +2662,29 @@
 }
 
+DECLCALLBACK(void) vbvaPortReportHostCursorCapabilities(PPDMIDISPLAYPORT pInterface, uint32_t fCapabilitiesAdded,
+                                                        uint32_t fCapabilitiesRemoved)
+{
+    PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+    AssertRC(rc);
+    pThis->fHostCursorCapabilities |= fCapabilitiesAdded;
+    pThis->fHostCursorCapabilities &= ~fCapabilitiesRemoved;
+    if (pThis->fGuestCaps & VBVACAPS_IRQ)
+        VBVARaiseIrqNoWait(pThis, HGSMIHOSTFLAGS_CURSOR_CAPABILITIES);
+    PDMCritSectLeave(&pThis->CritSect);
+}
+
+DECLCALLBACK(void) vbvaPortReportHostCursorPosition
+                       (PPDMIDISPLAYPORT pInterface, uint32_t x, uint32_t y)
+{
+    PVGASTATE pThis = IDISPLAYPORT_2_VGASTATE(pInterface);
+    VBVACONTEXT *pCtx = (VBVACONTEXT *)HGSMIContext(pThis->pHGSMI);
+    int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);
+    AssertRC(rc);
+    pCtx->xCursor = x;
+    pCtx->yCursor = y;
+    PDMCritSectLeave(&pThis->CritSect);
+}
+
 static HGSMICHANNELHANDLER sOldChannelHandler;
 
@@ -2653,4 +2718,5 @@
              pCtx->fPaused = true;
              memset(pCtx->aModeHints, ~0, sizeof(*pCtx->aModeHints));
+             pVGAState->fHostCursorCapabilities = 0;
          }
      }
Index: /trunk/src/VBox/Main/include/DisplayImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 53964)
+++ /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 53965)
@@ -124,4 +124,6 @@
     virtual void i_getFramebufferDimensions(int32_t *px1, int32_t *py1,
                                             int32_t *px2, int32_t *py2) = 0;
+    virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved) = 0;
+    virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y) = 0;
 };
 
@@ -150,4 +152,5 @@
     void i_handleUpdateVMMDevSupportsGraphics(bool fSupportsGraphics);
     void i_handleUpdateGuestVBVACapabilities(uint32_t fNewCapabilities);
+    void i_handleUpdateVBVAInputMapping(int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy);
 #ifdef VBOX_WITH_VIDEOHWACCEL
     int  i_handleVHWACommandProcess(PVBOXVHWACMD pCommand);
@@ -200,4 +203,6 @@
     virtual void i_getFramebufferDimensions(int32_t *px1, int32_t *py1,
                                             int32_t *px2, int32_t *py2);
+    virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved);
+    virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y);
 
     static const PDMDRVREG  DrvReg;
@@ -333,4 +338,7 @@
                                                               const void *pvShape);
     static DECLCALLBACK(void)  i_displayVBVAGuestCapabilityUpdate(PPDMIDISPLAYCONNECTOR pInterface, uint32_t fCapabilities);
+
+    static DECLCALLBACK(void)  i_displayVBVAInputMappingUpdate(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin,
+                                                               uint32_t cx, uint32_t cy);
 #endif
 
@@ -362,4 +370,10 @@
 
     unsigned mcMonitors;
+    /** Input mapping rectangle top left X relative to the first screen. */
+    int32_t     xInputMappingOrigin;
+    /** Input mapping rectangle top left Y relative to the first screen. */
+    int32_t     yInputMappingOrigin;
+    uint32_t    cxInputMapping;  /**< Input mapping rectangle width. */
+    uint32_t    cyInputMapping;  /**< Input mapping rectangle height. */
     DISPLAYFBINFO maFramebuffers[SchemaDefs::MaxGuestMonitors];
     /** Does the VMM device have the "supports graphics" capability set?
@@ -369,4 +383,7 @@
      *  Does not go into the saved state as it is refreshed on restore. */
     uint32_t    mfGuestVBVACapabilities;
+    /** Mirror of the current host cursor integration support capability.
+     *  Does not go into the saved state as it is refreshed on restore. */
+    uint32_t    mfHostSupportsCursorIntegration;
 
     bool mfSourceBitmapEnabled;
Index: /trunk/src/VBox/Main/include/DisplayUtils.h
===================================================================
--- /trunk/src/VBox/Main/include/DisplayUtils.h	(revision 53964)
+++ /trunk/src/VBox/Main/include/DisplayUtils.h	(revision 53965)
@@ -23,4 +23,5 @@
 #define sSSMDisplayVer2 0x00010002
 #define sSSMDisplayVer3 0x00010003
+#define sSSMDisplayVer4 0x00010004
 
 int readSavedGuestScreenInfo(const Utf8Str &strStateFilePath, uint32_t u32ScreenId,
Index: /trunk/src/VBox/Main/include/MouseImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/MouseImpl.h	(revision 53964)
+++ /trunk/src/VBox/Main/include/MouseImpl.h	(revision 53965)
@@ -104,6 +104,7 @@
     HRESULT i_reportMultiTouchEventToDevice(uint8_t cContacts, const uint64_t *pau64Contacts, uint32_t u32ScanTime);
     HRESULT i_reportAbsEventToVMMDev(int32_t x, int32_t y);
-    HRESULT i_reportAbsEvent(int32_t x, int32_t y, int32_t dz, int32_t dw,
-                             uint32_t fButtons, bool fUsesVMMDevEvent);
+    HRESULT i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
+                                           bool fUsesVMMDevEvent);
+    HRESULT i_reportAbsEventToDisplayDevice(int32_t x, int32_t y);
     HRESULT i_convertDisplayRes(LONG x, LONG y, int32_t *pxAdj, int32_t *pyAdj,
                                  bool *pfValid);
Index: /trunk/src/VBox/Main/src-client/DisplayImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 53964)
+++ /trunk/src/VBox/Main/src-client/DisplayImpl.cpp	(revision 53965)
@@ -507,4 +507,8 @@
         SSMR3PutU32(pSSM, that->maFramebuffers[i].flags);
     }
+    SSMR3PutS32(pSSM, that->xInputMappingOrigin);
+    SSMR3PutS32(pSSM, that->yInputMappingOrigin);
+    SSMR3PutU32(pSSM, that->cxInputMapping);
+    SSMR3PutU32(pSSM, that->cyInputMapping);
 }
 
@@ -516,5 +520,6 @@
     if (!(   uVersion == sSSMDisplayVer
           || uVersion == sSSMDisplayVer2
-          || uVersion == sSSMDisplayVer3))
+          || uVersion == sSSMDisplayVer3
+          || uVersion == sSSMDisplayVer4))
         return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
@@ -531,5 +536,6 @@
         SSMR3GetU32(pSSM, &that->maFramebuffers[i].u32InformationSize);
         if (   uVersion == sSSMDisplayVer2
-            || uVersion == sSSMDisplayVer3)
+            || uVersion == sSSMDisplayVer3
+            || uVersion == sSSMDisplayVer4)
         {
             uint32_t w;
@@ -540,5 +546,6 @@
             that->maFramebuffers[i].h = h;
         }
-        if (uVersion == sSSMDisplayVer3)
+        if (   uVersion == sSSMDisplayVer3
+            || uVersion == sSSMDisplayVer4)
         {
             int32_t xOrigin;
@@ -554,4 +561,11 @@
         }
     }
+    if (uVersion == sSSMDisplayVer4)
+    {
+        SSMR3GetS32(pSSM, &that->xInputMappingOrigin);
+        SSMR3GetS32(pSSM, &that->yInputMappingOrigin);
+        SSMR3GetU32(pSSM, &that->cxInputMapping);
+        SSMR3GetU32(pSSM, &that->cyInputMapping);
+    }
 
     return VINF_SUCCESS;
@@ -694,5 +708,5 @@
      * the framebuffer offset in the virtual desktop and the framebuffer flags.
      */
-    int rc = SSMR3RegisterExternal(pUVM, "DisplayData", 0, sSSMDisplayVer3,
+    int rc = SSMR3RegisterExternal(pUVM, "DisplayData", 0, sSSMDisplayVer4,
                                    mcMonitors * sizeof(uint32_t) * 8 + sizeof(uint32_t),
                                    NULL, NULL, NULL,
@@ -1082,4 +1096,14 @@
 }
 
+void Display::i_handleUpdateVBVAInputMapping(int32_t xOrigin, int32_t yOrigin, uint32_t cx, uint32_t cy)
+{
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    xInputMappingOrigin = xOrigin;
+    yInputMappingOrigin = yOrigin;
+    cxInputMapping      = cx;
+    cyInputMapping      = cy;
+}
+
 /**
  * Returns the upper left and lower right corners of the virtual framebuffer.
@@ -1110,20 +1134,65 @@
         y2 = mpDrv->IConnector.cy + (int32_t)maFramebuffers[0].yOrigin;
     }
-    for (unsigned i = 1; i < mcMonitors; ++i)
-    {
-        if (!maFramebuffers[i].fDisabled)
-        {
-            x1 = RT_MIN(x1, maFramebuffers[i].xOrigin);
-            y1 = RT_MIN(y1, maFramebuffers[i].yOrigin);
-            x2 = RT_MAX(x2,   maFramebuffers[i].xOrigin
-                            + (int32_t)maFramebuffers[i].w);
-            y2 = RT_MAX(y2,   maFramebuffers[i].yOrigin
-                            + (int32_t)maFramebuffers[i].h);
-        }
-    }
+    if (cxInputMapping && cyInputMapping)
+    {
+        x1 = xInputMappingOrigin;
+        y1 = yInputMappingOrigin;
+        x2 = xInputMappingOrigin + cxInputMapping;
+        y2 = xInputMappingOrigin + cyInputMapping;
+    }
+    else
+        for (unsigned i = 1; i < mcMonitors; ++i)
+        {
+            if (!maFramebuffers[i].fDisabled)
+            {
+                x1 = RT_MIN(x1, maFramebuffers[i].xOrigin);
+                y1 = RT_MIN(y1, maFramebuffers[i].yOrigin);
+                x2 = RT_MAX(x2, maFramebuffers[i].xOrigin + (int32_t)maFramebuffers[i].w);
+                y2 = RT_MAX(y2, maFramebuffers[i].yOrigin + (int32_t)maFramebuffers[i].h);
+            }
+        }
     *px1 = x1;
     *py1 = y1;
     *px2 = x2;
     *py2 = y2;
+}
+
+HRESULT Display::i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved)
+{
+    /* Do we need this to access mParent?  I presume that the safe VM pointer
+     * ensures that mpDrv will remain valid. */
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    Console::SafeVMPtr ptrVM(mParent);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+    CHECK_CONSOLE_DRV(mpDrv);
+    alock.release();  /* Release before calling up for lock order reasons. */
+    mpDrv->pUpPort->pfnReportHostCursorCapabilities (mpDrv->pUpPort, fCapabilitiesAdded, fCapabilitiesRemoved);
+    if (   mfGuestVBVACapabilities & VBVACAPS_DISABLE_CURSOR_INTEGRATION
+        && !(mfGuestVBVACapabilities & VBVACAPS_IRQ))
+    {
+        HRESULT hrc = mParent->i_sendACPIMonitorHotPlugEvent();
+        if (FAILED(hrc))
+            return hrc;
+    }
+    return S_OK;
+}
+
+HRESULT Display::i_reportHostCursorPosition(int32_t x, int32_t y)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    uint32_t xAdj = (uint32_t)RT_MAX(x - xInputMappingOrigin, 0);
+    uint32_t yAdj = (uint32_t)RT_MAX(y - yInputMappingOrigin, 0);
+    xAdj = RT_MIN(xAdj, cxInputMapping);
+    yAdj = RT_MIN(yAdj, cyInputMapping);
+
+    Console::SafeVMPtr ptrVM(mParent);
+    if (!ptrVM.isOk())
+        return ptrVM.rc();
+    CHECK_CONSOLE_DRV(mpDrv);
+    alock.release();  /* Release before calling up for lock order reasons. */
+    mpDrv->pUpPort->pfnReportHostCursorPosition(mpDrv->pUpPort, xAdj, yAdj);
+    return S_OK;
 }
 
@@ -3836,4 +3905,9 @@
     pFBInfo->flags = pScreen->u16Flags;
 
+    pThis->xInputMappingOrigin = 0;
+    pThis->yInputMappingOrigin = 0;
+    pThis->cxInputMapping = 0;
+    pThis->cyInputMapping = 0;
+
     if (fNewOrigin)
     {
@@ -3896,4 +3970,16 @@
     pThis->i_handleUpdateGuestVBVACapabilities(fCapabilities);
 }
+
+DECLCALLBACK(void) Display::i_displayVBVAInputMappingUpdate(PPDMIDISPLAYCONNECTOR pInterface, int32_t xOrigin, int32_t yOrigin,
+                                                            uint32_t cx, uint32_t cy)
+{
+    LogFlowFunc(("\n"));
+
+    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
+    Display *pThis = pDrv->pDisplay;
+
+    pThis->i_handleUpdateVBVAInputMapping(xOrigin, yOrigin, cx, cy);
+}
+
 #endif /* VBOX_WITH_HGSMI */
 
@@ -3997,4 +4083,5 @@
     pThis->IConnector.pfnVBVAMousePointerShape = Display::i_displayVBVAMousePointerShape;
     pThis->IConnector.pfnVBVAGuestCapabilityUpdate = Display::i_displayVBVAGuestCapabilityUpdate;
+    pThis->IConnector.pfnVBVAInputMappingUpdate = Display::i_displayVBVAInputMappingUpdate;
 #endif
 
Index: /trunk/src/VBox/Main/src-client/MouseImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/MouseImpl.cpp	(revision 53964)
+++ /trunk/src/VBox/Main/src-client/MouseImpl.cpp	(revision 53965)
@@ -347,4 +347,7 @@
         return E_FAIL;  /* No assertion, as the front-ends can send events
                          * at all sorts of inconvenient times. */
+    DisplayMouseInterface *pDisplay = mParent->i_getDisplayMouseInterface();
+    if (pDisplay == NULL)
+        return E_FAIL;
     PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     if (!pVMMDevPort)
@@ -353,5 +356,7 @@
     int rc = pVMMDevPort->pfnUpdateMouseCapabilities(pVMMDevPort, fCapsAdded,
                                                      fCapsRemoved);
-    return RT_SUCCESS(rc) ? S_OK : E_FAIL;
+    if (RT_FAILURE(rc))
+        return E_FAIL;
+    return pDisplay->i_reportHostCursorCapabilities(fCapsAdded, fCapsRemoved);
 }
 
@@ -619,7 +624,6 @@
  * @returns   COM status code
  */
-HRESULT Mouse::i_reportAbsEvent(int32_t x, int32_t y,
-                                int32_t dz, int32_t dw, uint32_t fButtons,
-                                bool fUsesVMMDevEvent)
+HRESULT Mouse::i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
+                                              bool fUsesVMMDevEvent)
 {
     HRESULT rc;
@@ -648,4 +652,26 @@
     return rc;
 }
+
+
+/**
+ * Send an absolute position event to the display device.
+ * @note all calls out of this object are made with no locks held!
+ * @param  x  Cursor X position in pixels relative to the first screen, where
+ *            (1, 1) is the upper left corner.
+ * @param  y  Cursor Y position in pixels relative to the first screen, where
+ *            (1, 1) is the upper left corner.
+ */
+HRESULT Mouse::i_reportAbsEventToDisplayDevice(int32_t x, int32_t y)
+{
+    DisplayMouseInterface *pDisplay = mParent->i_getDisplayMouseInterface();
+    ComAssertRet(pDisplay, E_FAIL);
+
+    if (x != mcLastX || y != mcLastY)
+    {
+        pDisplay->i_reportHostCursorPosition(x - 1, y - 1);
+    }
+    return S_OK;
+}
+
 
 void Mouse::i_fireMouseEvent(bool fAbsolute, LONG x, LONG y, LONG dz, LONG dw,
@@ -838,10 +864,11 @@
     if (fValid)
     {
-        rc = i_reportAbsEvent(xAdj, yAdj, dz, dw, fButtonsAdj,
-                              RT_BOOL(  mfVMMDevGuestCaps
-                                      & VMMDEV_MOUSE_NEW_PROTOCOL));
+        rc = i_reportAbsEventToInputDevices(xAdj, yAdj, dz, dw, fButtonsAdj,
+                                            RT_BOOL(mfVMMDevGuestCaps & VMMDEV_MOUSE_NEW_PROTOCOL));
+        if (FAILED(rc)) return rc;
 
         i_fireMouseEvent(true, x, y, dz, dw, aButtonState);
     }
+    rc = i_reportAbsEventToDisplayDevice(x, y);
 
     return rc;
Index: /trunk/src/VBox/Main/testcase/tstMouseImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/testcase/tstMouseImpl.cpp	(revision 53964)
+++ /trunk/src/VBox/Main/testcase/tstMouseImpl.cpp	(revision 53965)
@@ -44,4 +44,7 @@
     virtual void i_getFramebufferDimensions(int32_t *px1, int32_t *py1,
                                             int32_t *px2, int32_t *py2);
+    virtual HRESULT i_reportHostCursorCapabilities(uint32_t fCapabilitiesAdded, uint32_t fCapabilitiesRemoved)
+    { return S_OK; }
+    virtual HRESULT i_reportHostCursorPosition(int32_t x, int32_t y) {}
 };
 
