Index: trunk/src/VBox/Devices/Input/DevPS2.cpp
===================================================================
--- trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 26624)
+++ trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 26638)
@@ -230,6 +230,6 @@
     int32_t mouse_dw;
     int32_t mouse_flags;
-    int32_t mouse_cx;
-    int32_t mouse_cy;
+    uint32_t mouse_cx;
+    uint32_t mouse_cy;
     uint8_t mouse_buttons;
     uint8_t mouse_buttons_reported;
@@ -847,22 +847,28 @@
 {
     int aux = fToCmdQueue ? 1 : 2;
-    int cx1 = s->mouse_cx * 4096 / 0xffff;
-    int cy1 = 4096 - (s->mouse_cy * 4096 / 0xffff);
+    unsigned cx1 = s->mouse_cx * 4095 / 0xffff;
+    unsigned cy1 = 4095 - (s->mouse_cy * 4095 / 0xffff);
     unsigned fButtons = s->mouse_buttons & 0x03;
-    unsigned int b;
+    unsigned int b[6];
 
     LogRel3(("%s: cx1=%d, cy1=%d, fButtons=0x%x\n", __PRETTY_FUNCTION__,
              cx1, cy1, fButtons));
-    b = 4 /* Screen is being touched */ | fButtons;
-    kbd_queue(s, b, aux);
-    b = ((cy1 << 2) & 0xc0) | (cx1 >> 6);
-    kbd_queue(s, b, aux);
-    b = ((cx1 << 2) & 0xc0) | (cx1 & 0x3f);
-    kbd_queue(s, b, aux);
-    kbd_queue(s, 0xc0, aux);  /* This byte is really wasted in the protocol */
-    b = ((cx1 << 2) & 0xc0) | (cy1 >> 6);
-    kbd_queue(s, b, aux);
-    b = ((cy1 << 2) & 0xc0) | (cy1 & 0x3f);
-    kbd_queue(s, b, aux);
+    b[0] = 4 /* Screen is being touched */ | fButtons;
+    Assert((b[0] & 0xf8) == 0);
+    kbd_queue(s, b[0], aux);
+    b[1] = ((cy1 << 2) & 0xc0) | (cx1 >> 6);
+    kbd_queue(s, b[1], aux);
+    b[2] = ((cx1 << 2) & 0xc0) | (cx1 & 0x3f);
+    Assert(((b[2] & 0x30) << 2) == (b[2] & 0xc0));
+    kbd_queue(s, b[2], aux);
+    b[3] = 0xc0;
+    kbd_queue(s, b[3], aux);  /* This byte is really wasted in the protocol */
+    b[4] = ((cx1 << 2) & 0xc0) | (cy1 >> 6);
+    Assert((b[4] & 0xc0) == (b[2] & 0xc0));
+    kbd_queue(s, b[4], aux);
+    b[5] = ((cy1 << 2) & 0xc0) | (cy1 & 0x3f);
+    Assert(   (((b[5] & 0x30) << 2) == (b[1] & 0xc0))
+           && ((b[5] & 0xc0) == (b[1] & 0xc0)));
+    kbd_queue(s, b[5], aux);
 }
 
@@ -1339,6 +1345,6 @@
     if (version_id > 3)
     {
-        SSMR3GetS32(f, &s->mouse_cx);
-        SSMR3GetS32(f, &s->mouse_cy);
+        SSMR3GetU32(f, &s->mouse_cx);
+        SSMR3GetU32(f, &s->mouse_cy);
         SSMR3GetU8(f, &s->mouse_buttons_reported);
         SSMR3GetU8(f, &s->mouse_last_button);
@@ -1681,5 +1687,5 @@
  * @param   i32cY           The Y value.
  */
-static DECLCALLBACK(int) kbdMousePutEventAbs(PPDMIMOUSEPORT pInterface, int32_t i32cX, int32_t i32cY)
+static DECLCALLBACK(int) kbdMousePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t u32cX, uint32_t u32cY, int32_t dz, int32_t dw, uint32_t fButtons)
 {
     KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Mouse.IPort);
@@ -1687,5 +1693,8 @@
     AssertReleaseRC(rc);
 
-    pc_kbd_mouse_event_abs(pThis, i32cX, i32cY);
+    if (u32cX != pThis->mouse_cx || u32cY != pThis->mouse_cy)
+        pc_kbd_mouse_event_abs(pThis, u32cX, u32cY);
+    if (dz || dw || fButtons != pThis->mouse_buttons)
+        pc_kbd_mouse_event(pThis, 0, 0, dz, dw, fButtons);
 
     PDMCritSectLeave(&pThis->CritSect);
Index: trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp
===================================================================
--- trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp	(revision 26624)
+++ trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp	(revision 26638)
@@ -75,6 +75,6 @@
     int32_t             i32DeltaW;
     uint32_t            fButtonStates;
-    int32_t             i32cX;
-    int32_t             i32cY;
+    uint32_t            u32cX;
+    uint32_t            u32cY;
 } DRVMOUSEQUEUEITEM, *PDRVMOUSEQUEUEITEM;
 
@@ -112,4 +112,5 @@
  * @param   i32DeltaY       The Y delta.
  * @param   i32DeltaZ       The Z delta.
+ * @param   i32DeltaW       The W delta.
  * @param   fButtonStates   The button states.
  * @thread  Any thread.
@@ -142,9 +143,12 @@
  * @returns VBox status code.
  * @param   pInterface      Pointer to interface structure.
- * @param   i32cX           The X value.
- * @param   i32cY           The Y value.
+ * @param   u32cX           The X value.
+ * @param   u32cY           The Y value.
+ * @param   i32DeltaZ       The Z delta.
+ * @param   i32DeltaW       The W delta.
+ * @param   fButtonStates   The button states.
  * @thread  Any thread.
  */
-static DECLCALLBACK(int) drvMouseQueuePutEventAbs(PPDMIMOUSEPORT pInterface, int32_t i32cX, int32_t i32cY)
+static DECLCALLBACK(int) drvMouseQueuePutEventAbs(PPDMIMOUSEPORT pInterface, uint32_t u32cX, uint32_t u32cY, int32_t i32DeltaZ, int32_t i32DeltaW, uint32_t fButtonStates)
 {
     PDRVMOUSEQUEUE pDrv = IMOUSEPORT_2_DRVMOUSEQUEUE(pInterface);
@@ -156,6 +160,9 @@
     {
         pItem->fAbs = 1;
-        pItem->i32cX = i32cX;
-        pItem->i32cY = i32cY;
+        pItem->u32cX = u32cX;
+        pItem->u32cY = u32cY;
+        pItem->i32DeltaZ = i32DeltaZ;
+        pItem->i32DeltaW = i32DeltaW;
+        pItem->fButtonStates = fButtonStates;
         PDMQueueInsert(pDrv->pQueue, &pItem->Core);
         return VINF_SUCCESS;
@@ -203,5 +210,5 @@
         rc = pThis->pUpPort->pfnPutEvent(pThis->pUpPort, pItem->i32DeltaX, pItem->i32DeltaY, pItem->i32DeltaZ, pItem->i32DeltaW, pItem->fButtonStates);
     else
-        rc = pThis->pUpPort->pfnPutEventAbs(pThis->pUpPort, pItem->i32cX, pItem->i32cY);
+        rc = pThis->pUpPort->pfnPutEventAbs(pThis->pUpPort, pItem->u32cX, pItem->u32cY, pItem->i32DeltaZ, pItem->i32DeltaW, pItem->fButtonStates);
     return RT_SUCCESS(rc);
 }
