/** * Send an absolute pointer event to a pointing device (the VMM device if * possible or whatever emulated absolute device seems best to us if not). * * @returns COM status code */ HRESULT Mouse::reportAbsEvent(int32_t x, int32_t y, int32_t dz, int32_t dw, uint32_t fButtons, bool fUsesVMMDevEvent) { HRESULT rc = S_OK; /** If we are using the VMMDev to report absolute position but without * VMMDev IRQ support then we need to send a small "jiggle" to the emulated * relative mouse device to alert the guest to changes. */ LONG cJiggle = 0; /* * Send the absolute mouse position to the device. */ if (x != mcLastX || y != mcLastY) { if (vmmdevCanAbs()) { rc = reportAbsEventToVMMDev(x, y); cJiggle = !fUsesVMMDevEvent; } else { rc = reportAbsEventToMouseDev(x, y, 0, 0, fButtons); fButtons = 0; } } if (SUCCEEDED(rc)) rc = reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons); mcLastX = x; mcLastY = y; return rc; }
/** * Send an absolute pointer event to a pointing device (the VMM device if * possible or whatever emulated absolute device seems best to us if not). * * @returns COM status code */ HRESULT Mouse::reportAbsEvent(int32_t mouseXAbs, int32_t mouseYAbs, int32_t dz, int32_t dw, uint32_t fButtons, bool fUsesVMMDevEvent) { HRESULT rc; /** If we are using the VMMDev to report absolute position but without * VMMDev IRQ support then we need to send a small "jiggle" to the emulated * relative mouse device to alert the guest to changes. */ LONG cJiggle = 0; if (vmmdevCanAbs()) { /* * Send the absolute mouse position to the VMM device. */ if (mouseXAbs != mcLastAbsX || mouseYAbs != mcLastAbsY) { rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs); cJiggle = !fUsesVMMDevEvent; } rc = reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons); } else rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons); mcLastAbsX = mouseXAbs; mcLastAbsY = mouseYAbs; return rc; }
/** * Send a relative mouse event to the guest. * @note the VMMDev capability change is so that the guest knows we are sending * real events over the PS/2 device and not dummy events to signal the * arrival of new absolute pointer data * * @returns COM status code * @param dx X movement * @param dy Y movement * @param dz Z movement * @param buttonState The mouse button state */ STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG buttonState) { HRESULT rc; uint32_t fButtons; AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__, dx, dy, dz, dw)); 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); fireMouseEvent(false, dx, dy, dz, dw, buttonState); return rc; }