VirtualBox

Changeset 97790 in vbox


Ignore:
Timestamp:
Dec 13, 2022 1:06:03 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154862
Message:

VMMDev mouse: bugref:10285: Introduce extended host mouse pointer state.

Provide VMMDev mouse with buttons and H/V wheel movement state. Extended
state can be now fetched from host in scope of VMMDevReqMouseStatusEx request.
Currently only Linux Additions utilize this functionality.

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VMMDev.h

    r96407 r97790  
    203203    VMMDevReq_NtBugCheck                 = 221,
    204204    VMMDevReq_VideoUpdateMonitorPositions= 222,
     205    VMMDevReq_GetMouseStatusEx           = 223,
    205206    VMMDevReq_SizeHack                   = 0x7fffffff
    206207} VMMDevRequestType;
     
    360361AssertCompileSize(VMMDevReqMouseStatus, 24+12);
    361362
     363
     364/** @name Mouse buttons state bits for VMMDevReqMouseStatusEx::fButtons (identical to PDMIMOUSEPORT_BUTTON_XXX).
     365 * @{ */
     366/** Left mouse button pressed. */
     367#define VMMDEV_MOUSE_BUTTON_LEFT   RT_BIT(0)
     368/** Right mouse button pressed. */
     369#define VMMDEV_MOUSE_BUTTON_RIGHT  RT_BIT(1)
     370/** Middle mouse button pressed. */
     371#define VMMDEV_MOUSE_BUTTON_MIDDLE RT_BIT(2)
     372/** X1 mouse button pressed. */
     373#define VMMDEV_MOUSE_BUTTON_X1     RT_BIT(3)
     374/** X2 mouse button pressed. */
     375#define VMMDEV_MOUSE_BUTTON_X2     RT_BIT(4)
     376/** @} */
     377
     378
     379/**
     380 * Extended mouse status request structure.
     381 *
     382 * Used by VMMDevReq_GetMouseStatusEx.
     383 */
     384typedef struct
     385{
     386    /** Legacy mouse status request structure. */
     387    VMMDevReqMouseStatus Core;
     388    /** Mouse wheel vertical mvement. */
     389    int32_t dz;
     390    /** Mouse wheel horizontal movement. */
     391    int32_t dw;
     392    /** Mouse buttons state. */
     393    uint32_t fButtons;
     394} VMMDevReqMouseStatusEx;
     395AssertCompileSize(VMMDevReqMouseStatusEx, 24+24);
     396
     397
    362398/** @name Mouse capability bits (VMMDevReqMouseStatus::mouseFeatures).
    363399 * @{ */
     
    384420 * wish to use this to decide whether to install their own driver */
    385421#define VMMDEV_MOUSE_HOST_HAS_ABS_DEV                       RT_BIT(6)
     422/** The guest can read VMMDev events to find out about full mouse state */
     423#define VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL         RT_BIT(7)
     424/** The host can provide full mouse state over VMMDev events */
     425#define VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL          RT_BIT(8)
    386426/** The mask of all VMMDEV_MOUSE_* flags */
    387 #define VMMDEV_MOUSE_MASK                                   UINT32_C(0x0000007f)
     427#define VMMDEV_MOUSE_MASK                                   UINT32_C(0x000001ff)
    388428/** The mask of guest capability changes for which notification events should
    389429 * be sent */
     
    392432/** The mask of all capabilities which the guest can legitimately change */
    393433#define VMMDEV_MOUSE_GUEST_MASK \
    394       (VMMDEV_MOUSE_NOTIFY_HOST_MASK | VMMDEV_MOUSE_NEW_PROTOCOL)
     434      (VMMDEV_MOUSE_NOTIFY_HOST_MASK | VMMDEV_MOUSE_NEW_PROTOCOL | VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL)
    395435/** The mask of host capability changes for which notification events should
    396436 * be sent */
     
    402442       | VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER \
    403443       | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR \
    404        | VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
     444       | VMMDEV_MOUSE_HOST_HAS_ABS_DEV \
     445       | VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL)
    405446/** @} */
    406447
     
    17381779        case VMMDevReq_SetMouseStatus:
    17391780            return sizeof(VMMDevReqMouseStatus);
     1781        case VMMDevReq_GetMouseStatusEx:
     1782            return sizeof(VMMDevReqMouseStatusEx);
    17401783        case VMMDevReq_SetPointerShape:
    17411784            return sizeof(VMMDevReqMousePointer);
  • trunk/include/VBox/vmm/pdmifs.h

    r96407 r97790  
    15371537     * @param   xAbs            New absolute X position
    15381538     * @param   yAbs            New absolute Y position
    1539      */
    1540     DECLR3CALLBACKMEMBER(int, pfnSetAbsoluteMouse,(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs));
     1539     * @param   dz              New mouse wheel vertical movement offset
     1540     * @param   dw              New mouse wheel horizontal movement offset
     1541     * @param   fButtons        New buttons state
     1542     */
     1543    DECLR3CALLBACKMEMBER(int, pfnSetAbsoluteMouse,(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs,
     1544                                                   int32_t dz, int32_t dw, uint32_t fButtons));
    15411545
    15421546    /**
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c

    r96407 r97790  
    103103# define kgid_t gid_t
    104104# define kuid_t uid_t
     105#endif
     106
     107#ifdef VBOXGUEST_WITH_INPUT_DRIVER
     108/** The name of input pointing device for mouse integration. */
     109# define VBOX_INPUT_DEVICE_NAME  "VirtualBox mouse integration"
    105110#endif
    106111
     
    148153static struct fasync_struct    *g_pFAsyncQueue;
    149154#ifdef VBOXGUEST_WITH_INPUT_DRIVER
    150 /** Pre-allocated mouse status VMMDev request for use in the IRQ
    151  * handler. */
    152 static VMMDevReqMouseStatus    *g_pMouseStatusReq;
     155/** Pre-allocated mouse status VMMDev requests for use in the IRQ handler. */
     156static VMMDevReqMouseStatusEx  *g_pMouseStatusReqEx;
    153157#endif
    154158#if RTLNX_VER_MIN(2,6,0)
     
    421425
    422426#ifdef VBOXGUEST_WITH_INPUT_DRIVER
     427/**
     428 * Check if extended mouse pointer state request protocol is currently used by driver.
     429 *
     430 * @returns True if extended protocol is used, False otherwise.
     431 */
     432static bool vgdrvLinuxUsesMouseStatusEx(void)
     433{
     434    return g_pMouseStatusReqEx->Core.header.requestType == VMMDevReq_GetMouseStatusEx;
     435}
    423436
    424437/**
     
    450463static int vboxguestOpenInputDevice(struct input_dev *pDev)
    451464{
    452     int rc = vgdrvLinuxSetMouseStatus(VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_NEW_PROTOCOL);
     465    int rc = vgdrvLinuxSetMouseStatus(  VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
     466                                      | VMMDEV_MOUSE_NEW_PROTOCOL
     467                                      | (vgdrvLinuxUsesMouseStatusEx() ? VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL : 0));
    453468    if (RT_FAILURE(rc))
    454469        return ENODEV;
     
    471486
    472487/**
     488 * Free corresponding mouse status request structure.
     489 */
     490static void vgdrvLinuxFreeMouseStatusReq(void)
     491{
     492    VbglR0GRFree(&g_pMouseStatusReqEx->Core.header);
     493    g_pMouseStatusReqEx = NULL;
     494}
     495
     496/**
    473497 * Creates the kernel input device.
    474498 */
    475499static int __init vgdrvLinuxCreateInputDevice(void)
    476500{
    477     int rc = VbglR0GRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReq, sizeof(*g_pMouseStatusReq), VMMDevReq_GetMouseStatus);
     501    /* Try to allocate legacy request data first, and check if host supports extended protocol. */
     502    int rc = VbglR0GRAlloc((VMMDevRequestHeader **)&g_pMouseStatusReqEx, sizeof(VMMDevReqMouseStatus), VMMDevReq_GetMouseStatus);
     503    if (RT_SUCCESS(rc))
     504    {
     505        /* Check if host supports extended mouse state reporting. */
     506        g_pMouseStatusReqEx->Core.mouseFeatures = 0;
     507        rc = VbglR0GRPerform(&g_pMouseStatusReqEx->Core.header);
     508        if (RT_SUCCESS(rc))
     509        {
     510            if (g_pMouseStatusReqEx->Core.mouseFeatures & VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL)
     511            {
     512                VMMDevReqMouseStatusEx *pReqEx = NULL;
     513                rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pReqEx, sizeof(*pReqEx), VMMDevReq_GetMouseStatusEx);
     514                if (RT_SUCCESS(rc))
     515                {
     516                    /* De-allocate legacy request data, */
     517                    VbglR0GRFree(&g_pMouseStatusReqEx->Core.header);
     518                    /* ..and switch to extended requests. */
     519                    g_pMouseStatusReqEx = pReqEx;
     520                    LogRel(("Host supports full mouse state reporting, switching to extended mouse integration protocol\n"));
     521                }
     522                else
     523                    LogRel(("Host supports full mouse state reporting, but feature cannot be initialized, switching to legacy mouse integration protocol\n"));
     524            }
     525            else
     526                LogRel(("Host does not support full mouse state reporting, switching to legacy mouse integration protocol\n"));
     527        }
     528        else
     529            LogRel(("Unable to get host mouse capabilities, switching to legacy mouse integration protocol\n"));
     530    }
     531    else
     532        rc = -ENOMEM;
     533
    478534    if (RT_SUCCESS(rc))
    479535    {
     
    481537        if (g_pInputDevice)
    482538        {
     539            g_pInputDevice->name       = VBOX_INPUT_DEVICE_NAME;
    483540            g_pInputDevice->id.bustype = BUS_PCI;
    484541            g_pInputDevice->id.vendor  = VMMDEV_VENDORID;
     
    492549            g_pInputDevice->dev.parent = &g_pPciDev->dev;
    493550# endif
     551            /* Set up input device capabilities. */
     552            ASMBitSet(g_pInputDevice->evbit, EV_ABS);
     553# ifdef EV_SYN
     554            ASMBitSet(g_pInputDevice->evbit, EV_SYN);
     555# endif
     556            ASMBitSet(g_pInputDevice->absbit, ABS_X);
     557            ASMBitSet(g_pInputDevice->absbit, ABS_Y);
     558
     559            input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
     560            input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
     561
     562            /* Report extra capabilities to input layer if extended mouse state protocol
     563             * will be used in communication with host. */
     564            if (vgdrvLinuxUsesMouseStatusEx())
     565            {
     566                ASMBitSet(g_pInputDevice->evbit, EV_REL);
     567                ASMBitSet(g_pInputDevice->evbit, EV_KEY);
     568
     569                ASMBitSet(g_pInputDevice->relbit, REL_WHEEL);
     570                ASMBitSet(g_pInputDevice->relbit, REL_HWHEEL);
     571
     572                ASMBitSet(g_pInputDevice->keybit, BTN_LEFT);
     573                ASMBitSet(g_pInputDevice->keybit, BTN_RIGHT);
     574                ASMBitSet(g_pInputDevice->keybit, BTN_MIDDLE);
     575                ASMBitSet(g_pInputDevice->keybit, BTN_SIDE);
     576                ASMBitSet(g_pInputDevice->keybit, BTN_EXTRA);
     577            }
     578
    494579            rc = input_register_device(g_pInputDevice);
    495580            if (rc == 0)
    496             {
    497                 /* Do what one of our competitors apparently does as that works. */
    498                 ASMBitSet(g_pInputDevice->evbit, EV_ABS);
    499                 ASMBitSet(g_pInputDevice->evbit, EV_KEY);
    500 # ifdef EV_SYN
    501                 ASMBitSet(g_pInputDevice->evbit, EV_SYN);
    502 # endif
    503                 input_set_abs_params(g_pInputDevice, ABS_X, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
    504                 input_set_abs_params(g_pInputDevice, ABS_Y, VMMDEV_MOUSE_RANGE_MIN, VMMDEV_MOUSE_RANGE_MAX, 0, 0);
    505                 ASMBitSet(g_pInputDevice->keybit, BTN_MOUSE);
    506                 /** @todo this string should be in a header file somewhere. */
    507                 g_pInputDevice->name = "VirtualBox mouse integration";
    508581                return 0;
    509             }
    510582
    511583            input_free_device(g_pInputDevice);
     
    513585        else
    514586            rc = -ENOMEM;
    515         VbglR0GRFree(&g_pMouseStatusReq->header);
    516         g_pMouseStatusReq = NULL;
    517     }
    518     else
    519         rc = -ENOMEM;
     587
     588        vgdrvLinuxFreeMouseStatusReq();
     589    }
     590
    520591    return rc;
    521592}
     
    527598static void vgdrvLinuxTermInputDevice(void)
    528599{
    529     VbglR0GRFree(&g_pMouseStatusReq->header);
    530     g_pMouseStatusReq = NULL;
     600    /* Notify host that mouse integration is no longer available. */
     601    vgdrvLinuxSetMouseStatus(0);
     602
     603    vgdrvLinuxFreeMouseStatusReq();
    531604
    532605    /* See documentation of input_register_device(): input_free_device()
     
    11551228
    11561229
     1230#ifdef VBOXGUEST_WITH_INPUT_DRIVER
     1231/**
     1232 * Get host mouse state.
     1233 *
     1234 * @returns                 IPRT status code.
     1235 * @param pfMouseFeatures   Where to store host mouse capabilities.
     1236 * @param pX                Where to store X axis coordinate.
     1237 * @param pY                Where to store Y axis coordinate.
     1238 * @param pDz               Where to store vertical wheel movement offset (only set if in case of VMMDevReq_GetMouseStatusEx request).
     1239 * @param pDw               Where to store horizontal wheel movement offset (only set if in case of VMMDevReq_GetMouseStatusEx request).
     1240 * @param pfButtons         Where to store mouse buttons state (only set if in case of VMMDevReq_GetMouseStatusEx request).
     1241 */
     1242static int vgdrvLinuxGetHostMouseState(uint32_t *pfMouseFeatures, int32_t *pX, int32_t *pY, int32_t *pDz, int32_t *pDw, uint32_t *pfButtons)
     1243{
     1244    int rc = VERR_INVALID_PARAMETER;
     1245
     1246    Assert(pfMouseFeatures);
     1247    Assert(pX);
     1248    Assert(pY);
     1249    Assert(pDz);
     1250    Assert(pDw);
     1251    Assert(pfButtons);
     1252
     1253    /* Initialize legacy request data. */
     1254    g_pMouseStatusReqEx->Core.mouseFeatures = 0;
     1255    g_pMouseStatusReqEx->Core.pointerXPos = 0;
     1256    g_pMouseStatusReqEx->Core.pointerYPos = 0;
     1257
     1258    /* Initialize extended request data if VMMDevReq_GetMouseStatusEx is used. */
     1259    if (vgdrvLinuxUsesMouseStatusEx())
     1260    {
     1261        g_pMouseStatusReqEx->dz = 0;
     1262        g_pMouseStatusReqEx->dw = 0;
     1263        g_pMouseStatusReqEx->fButtons = 0;
     1264    }
     1265
     1266    /* Get host mouse state - either lagacy or extended version. */
     1267    rc = VbglR0GRPerform(&g_pMouseStatusReqEx->Core.header);
     1268    if (RT_SUCCESS(rc))
     1269    {
     1270        *pfMouseFeatures = g_pMouseStatusReqEx->Core.mouseFeatures;
     1271        *pX = g_pMouseStatusReqEx->Core.pointerXPos;
     1272        *pY = g_pMouseStatusReqEx->Core.pointerYPos;
     1273
     1274        /* Get extended mouse state data in case of VMMDevReq_GetMouseStatusEx. */
     1275        if (vgdrvLinuxUsesMouseStatusEx())
     1276        {
     1277            *pDz = g_pMouseStatusReqEx->dz;
     1278            *pDw = g_pMouseStatusReqEx->dw;
     1279            *pfButtons = g_pMouseStatusReqEx->fButtons;
     1280        }
     1281    }
     1282
     1283    return rc;
     1284}
     1285#endif /* VBOXGUEST_WITH_INPUT_DRIVER */
     1286
     1287
    11571288void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
    11581289{
    11591290#ifdef VBOXGUEST_WITH_INPUT_DRIVER
    11601291    int rc;
     1292    uint32_t fMouseFeatures = 0;
     1293    int32_t x = 0;
     1294    int32_t y = 0;
     1295    int32_t dz = 0;
     1296    int32_t dw = 0;
     1297    uint32_t fButtons = 0;
    11611298#endif
    11621299    NOREF(pDevExt);
     
    11711308    kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN);
    11721309#ifdef VBOXGUEST_WITH_INPUT_DRIVER
    1173     /* Report events to the kernel input device */
    1174     g_pMouseStatusReq->mouseFeatures = 0;
    1175     g_pMouseStatusReq->pointerXPos = 0;
    1176     g_pMouseStatusReq->pointerYPos = 0;
    1177     rc = VbglR0GRPerform(&g_pMouseStatusReq->header);
     1310    rc = vgdrvLinuxGetHostMouseState(&fMouseFeatures, &x, &y, &dz, &dw, &fButtons);
    11781311    if (RT_SUCCESS(rc))
    11791312    {
    1180         input_report_abs(g_pInputDevice, ABS_X,
    1181                          g_pMouseStatusReq->pointerXPos);
    1182         input_report_abs(g_pInputDevice, ABS_Y,
    1183                          g_pMouseStatusReq->pointerYPos);
     1313        input_report_abs(g_pInputDevice, ABS_X, x);
     1314        input_report_abs(g_pInputDevice, ABS_Y, y);
     1315
     1316        if (   vgdrvLinuxUsesMouseStatusEx()
     1317            && fMouseFeatures & VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL
     1318            && fMouseFeatures & VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL)
     1319        {
     1320            input_report_rel(g_pInputDevice, REL_WHEEL,  dz);
     1321            input_report_rel(g_pInputDevice, REL_HWHEEL, dw);
     1322
     1323            input_report_key(g_pInputDevice, BTN_LEFT,   RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_LEFT));
     1324            input_report_key(g_pInputDevice, BTN_RIGHT,  RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_RIGHT));
     1325            input_report_key(g_pInputDevice, BTN_MIDDLE, RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_MIDDLE));
     1326            input_report_key(g_pInputDevice, BTN_SIDE,   RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_X1));
     1327            input_report_key(g_pInputDevice, BTN_EXTRA,  RT_BOOL(fButtons & VMMDEV_MOUSE_BUTTON_X2));
     1328        }
     1329
    11841330# ifdef EV_SYN
    11851331        input_sync(g_pInputDevice);
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r96407 r97790  
    11471147
    11481148/**
     1149 * Handles VMMDevReq_GetMouseStatusEx.
     1150 *
     1151 * @returns VBox status code that the guest should see.
     1152 * @param   pThis           The VMMDev shared instance data.
     1153 * @param   pReqHdr         The header of the request to handle.
     1154 */
     1155static int vmmdevReqHandler_GetMouseStatusEx(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
     1156{
     1157    VMMDevReqMouseStatusEx *pReq = (VMMDevReqMouseStatusEx *)pReqHdr;
     1158    AssertMsgReturn(pReq->Core.header.size == sizeof(*pReq), ("%u\n", pReq->Core.header.size), VERR_INVALID_PARAMETER);
     1159
     1160    /* Main will convert host mouse buttons state obtained from GUI
     1161     * into PDMIMOUSEPORT_BUTTON_XXX representation. Guest will expect it
     1162     * to VMMDEV_MOUSE_BUTTON_XXX representaion. Make sure both
     1163     * representations are identical.  */
     1164    AssertCompile(VMMDEV_MOUSE_BUTTON_LEFT   == PDMIMOUSEPORT_BUTTON_LEFT);
     1165    AssertCompile(VMMDEV_MOUSE_BUTTON_RIGHT  == PDMIMOUSEPORT_BUTTON_RIGHT);
     1166    AssertCompile(VMMDEV_MOUSE_BUTTON_MIDDLE == PDMIMOUSEPORT_BUTTON_MIDDLE);
     1167    AssertCompile(VMMDEV_MOUSE_BUTTON_X1     == PDMIMOUSEPORT_BUTTON_X1);
     1168    AssertCompile(VMMDEV_MOUSE_BUTTON_X2     == PDMIMOUSEPORT_BUTTON_X2);
     1169
     1170    pReq->Core.mouseFeatures = pThis->fMouseCapabilities & VMMDEV_MOUSE_MASK;
     1171    pReq->Core.pointerXPos   = pThis->xMouseAbs;
     1172    pReq->Core.pointerYPos   = pThis->yMouseAbs;
     1173    pReq->dz                 = pThis->dzMouse;
     1174    pReq->dw                 = pThis->dwMouse;
     1175    pReq->fButtons           = pThis->fMouseButtons;
     1176    LogRel2(("VMMDev: vmmdevReqHandler_GetMouseStatusEx: mouseFeatures=%#x, xAbs=%d, yAbs=%d, zAbs=%d, wMouseRel=%d, fButtons=0x%x\n",
     1177             pReq->Core.mouseFeatures, pReq->Core.pointerXPos, pReq->Core.pointerYPos, pReq->dz, pReq->dw, pReq->fButtons));
     1178    return VINF_SUCCESS;
     1179}
     1180
     1181
     1182/**
    11491183 * Handles VMMDevReq_SetMouseStatus.
    11501184 *
     
    27982832        case VMMDevReq_GetMouseStatus:
    27992833            pReqHdr->rc = vmmdevReqHandler_GetMouseStatus(pThis, pReqHdr);
     2834            break;
     2835
     2836        case VMMDevReq_GetMouseStatusEx:
     2837            pReqHdr->rc = vmmdevReqHandler_GetMouseStatusEx(pThis, pReqHdr);
    28002838            break;
    28012839
     
    36233661 * @interface_method_impl{PDMIVMMDEVPORT,pfnSetAbsoluteMouse}
    36243662 */
    3625 static DECLCALLBACK(int) vmmdevIPort_SetAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs)
     3663static DECLCALLBACK(int) vmmdevIPort_SetAbsoluteMouse(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs,
     3664                                                      int32_t dz, int32_t dw, uint32_t fButtons)
    36263665{
    36273666    PVMMDEVCC  pThisCC = RT_FROM_MEMBER(pInterface, VMMDEVCC, IPort);
     
    36323671
    36333672    if (   pThis->xMouseAbs != xAbs
    3634         || pThis->yMouseAbs != yAbs)
    3635     {
    3636         Log2(("vmmdevIPort_SetAbsoluteMouse : settings absolute position to x = %d, y = %d\n", xAbs, yAbs));
     3673        || pThis->yMouseAbs != yAbs
     3674        || dz
     3675        || dw
     3676        || pThis->fMouseButtons != fButtons)
     3677    {
     3678        Log2(("vmmdevIPort_SetAbsoluteMouse : settings absolute position to x = %d, y = %d, z = %d, w = %d, fButtons = 0x%x\n",
     3679              xAbs, yAbs, dz, dw, fButtons));
     3680
    36373681        pThis->xMouseAbs = xAbs;
    36383682        pThis->yMouseAbs = yAbs;
     3683        pThis->dzMouse = -dz; /* Inverted! */
     3684        pThis->dwMouse = -dw; /* Inverted! */
     3685        pThis->fMouseButtons = fButtons;
     3686
    36393687        VMMDevNotifyGuest(pDevIns, pThis, pThisCC, VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
    36403688    }
     
    36723720    pThis->fMouseCapabilities &= ~(fCapsRemoved & VMMDEV_MOUSE_HOST_MASK);
    36733721    pThis->fMouseCapabilities |= (fCapsAdded & VMMDEV_MOUSE_HOST_MASK)
    3674                               | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR;
     3722                              | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR
     3723                              | VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL;
    36753724    bool fNotify = fOldCaps != pThis->fMouseCapabilities;
    36763725
     
    40644113    pHlp->pfnSSMPutS32(pSSM, pThis->xMouseAbs);
    40654114    pHlp->pfnSSMPutS32(pSSM, pThis->yMouseAbs);
     4115    pHlp->pfnSSMPutS32(pSSM, pThis->dzMouse);
     4116    pHlp->pfnSSMPutS32(pSSM, pThis->dwMouse);
     4117    pHlp->pfnSSMPutU32(pSSM, pThis->fMouseButtons);
    40664118
    40674119    pHlp->pfnSSMPutBool(pSSM, pThis->fNewGuestFilterMaskValid);
     
    41564208    pHlp->pfnSSMGetS32(pSSM, &pThis->xMouseAbs);
    41574209    pHlp->pfnSSMGetS32(pSSM, &pThis->yMouseAbs);
     4210    if (uVersion >= VMMDEV_SAVED_STATE_VERSION_VMM_MOUSE_EXTENDED_DATA)
     4211    {
     4212        pHlp->pfnSSMGetS32(pSSM, &pThis->dzMouse);
     4213        pHlp->pfnSSMGetS32(pSSM, &pThis->dwMouse);
     4214        pHlp->pfnSSMGetU32(pSSM, &pThis->fMouseButtons);
     4215    }
    41584216
    41594217    pHlp->pfnSSMGetBool(pSSM, &pThis->fNewGuestFilterMaskValid);
     
    49995057     */
    50005058    pThis->fMouseCapabilities |= VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR;
     5059
     5060    /*
     5061     * In this version of VirtualBox full mouse state can be provided to the guest over DevVMM.
     5062     */
     5063    pThis->fMouseCapabilities |= VMMDEV_MOUSE_HOST_USES_FULL_STATE_PROTOCOL;
    50015064
    50025065    /*
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r96407 r97790  
    145145    /** mouse capabilities of host and guest */
    146146    uint32_t            fMouseCapabilities;
    147     /** @name Absolute mouse position in pixels
     147    /** @name Absolute mouse position in pixels, relative wheel movement and buttons state.
    148148     * @{ */
    149149    int32_t             xMouseAbs;
    150150    int32_t             yMouseAbs;
     151    int32_t             dzMouse;
     152    int32_t             dwMouse;
     153    uint32_t            fMouseButtons;
    151154    /** @} */
    152155    /** Does the guest currently want the host pointer to be shown? */
     
    564567
    565568/** The saved state version. */
    566 #define VMMDEV_SAVED_STATE_VERSION                              VMMDEV_SAVED_STATE_VERSION_DISPLAY_CHANGE_DATA
     569#define VMMDEV_SAVED_STATE_VERSION                              VMMDEV_SAVED_STATE_VERSION_VMM_MOUSE_EXTENDED_DATA
     570/** The saved state version with VMMDev mouse buttons state and wheel movement data. */
     571#define VMMDEV_SAVED_STATE_VERSION_VMM_MOUSE_EXTENDED_DATA      19
    567572/** The saved state version with display change data state. */
    568573#define VMMDEV_SAVED_STATE_VERSION_DISPLAY_CHANGE_DATA          18
  • trunk/src/VBox/Main/include/MouseImpl.h

    r96909 r97790  
    119119                                    uint32_t fContact);
    120120    HRESULT i_reportMultiTouchEventToDevice(uint8_t cContacts, const uint64_t *pau64Contacts, bool fTouchScreen, uint32_t u32ScanTime);
    121     HRESULT i_reportAbsEventToVMMDev(int32_t x, int32_t y);
     121    HRESULT i_reportAbsEventToVMMDev(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons);
    122122    HRESULT i_reportAbsEventToInputDevices(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons,
    123123                                           bool fUsesVMMDevEvent);
  • trunk/src/VBox/Main/src-client/MouseImpl.cpp

    r97558 r97790  
    631631 * @returns   COM status code
    632632 */
    633 HRESULT Mouse::i_reportAbsEventToVMMDev(int32_t x, int32_t y)
     633HRESULT Mouse::i_reportAbsEventToVMMDev(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons)
    634634{
    635635    VMMDevMouseInterface *pVMMDev = mParent->i_getVMMDevMouseInterface();
     
    638638    ComAssertRet(pVMMDevPort, E_FAIL);
    639639
    640     if (x != mcLastX || y != mcLastY)
    641     {
    642         int vrc = pVMMDevPort->pfnSetAbsoluteMouse(pVMMDevPort,
    643                                                    x, y);
     640    if (x != mcLastX || y != mcLastY || dz || dw || fButtons != mfLastButtons)
     641    {
     642        int vrc = pVMMDevPort->pfnSetAbsoluteMouse(pVMMDevPort, x, y, dz, dw, fButtons);
    644643        if (RT_FAILURE(vrc))
    645644            return setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
     
    671670         * Send the absolute mouse position to the VMM device.
    672671         */
    673         if (x != mcLastX || y != mcLastY)
     672        if (x != mcLastX || y != mcLastY || dz || dw || fButtons != mfLastButtons)
    674673        {
    675             hrc = i_reportAbsEventToVMMDev(x, y);
     674            hrc = i_reportAbsEventToVMMDev(x, y, dz, dw, fButtons);
    676675            cJiggle = !fUsesVMMDevEvent;
    677676        }
    678         hrc = i_reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons);
     677
     678        /* If guest cannot yet read full mouse state from DevVMM (i.e.,
     679         * only 'x' and 'y' coordinates will be read) we need to pass buttons
     680         * state as well as horizontal and vertical wheel movement over ever-present PS/2
     681         * emulated mouse device. */
     682        if (!(mfVMMDevGuestCaps & VMMDEV_MOUSE_GUEST_USES_FULL_STATE_PROTOCOL))
     683            hrc = i_reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons);
    679684    }
    680685    else
     
    683688    mcLastX = x;
    684689    mcLastY = y;
     690    mfLastButtons = fButtons;
    685691    return hrc;
    686692}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette