Changeset 32817 in vbox for trunk/src/VBox/Main
- Timestamp:
- Sep 29, 2010 2:30:07 PM (14 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MouseImpl.cpp
r30764 r32817 110 110 unconst(mParent) = parent; 111 111 112 #ifdef RT_OS_L4113 /* L4 console has no own mouse cursor */114 uHostCaps = VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER;115 #else116 112 uHostCaps = 0; 117 #endif118 113 119 114 /* Confirm a successful initialization */ … … 157 152 { 158 153 AssertPtrReturn(pfCaps, E_POINTER); 154 /** @todo does getting the VMMDev and the VMMDevPort like this guarantee 155 * they won't go away while we are using them? */ 159 156 VMMDev *pVMMDev = mParent->getVMMDev(); 160 157 ComAssertRet(pVMMDev, E_FAIL); … … 192 189 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 193 190 194 Auto WriteLock alock(this COMMA_LOCKVAL_SRC_POS);191 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 195 192 bool fAbs = false; 196 193 … … 221 218 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 222 219 223 Auto WriteLock alock(this COMMA_LOCKVAL_SRC_POS);220 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 224 221 bool fRel = false; 225 222 … … 245 242 AutoCaller autoCaller(this); 246 243 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 247 248 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);249 244 250 245 *pfNeedsHostCursor = fVMMDevNeedsHostCursor; … … 283 278 { 284 279 PPDMIMOUSEPORT pUpPort = NULL; 285 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)286 280 { 287 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)) 288 pUpPort = mpDrv[i]->pUpPort; 281 AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS); 282 283 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i) 284 { 285 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE)) 286 pUpPort = mpDrv[i]->pUpPort; 287 } 289 288 } 290 289 if (!pUpPort) … … 297 296 tr("Could not send the mouse event to the virtual mouse (%Rrc)"), 298 297 vrc); 298 mLastButtons = fButtons; 299 299 } 300 300 return S_OK; … … 314 314 { 315 315 PPDMIMOUSEPORT pUpPort = NULL; 316 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i)317 316 { 318 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)) 319 pUpPort = mpDrv[i]->pUpPort; 317 AutoReadLock aLock(this COMMA_LOCKVAL_SRC_POS); 318 319 for (unsigned i = 0; !pUpPort && i < MOUSE_MAX_DEVICES; ++i) 320 { 321 if (mpDrv[i] && (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE)) 322 pUpPort = mpDrv[i]->pUpPort; 323 } 320 324 } 321 325 if (!pUpPort) … … 328 332 tr("Could not send the mouse event to the virtual mouse (%Rrc)"), 329 333 vrc); 334 mLastButtons = fButtons; 330 335 } 331 336 return S_OK; … … 357 362 } 358 363 364 HRESULT Mouse::reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs, 365 int32_t dz, int32_t dw, uint32_t fButtons, 366 bool fUsesVMMDevEvent) 367 { 368 HRESULT rc; 369 /** If we are using the VMMDev to report absolute position but without 370 * VMMDev IRQ support then we need to send a small "jiggle" to the emulated 371 * relative mouse device to alert the guest to changes. */ 372 LONG cJiggle = 0; 373 374 if (fVMMDevCanAbs) 375 { 376 /* 377 * Send the absolute mouse position to the VMM device. 378 */ 379 if (mouseXAbs != mLastAbsX || mouseYAbs != mLastAbsY) 380 { 381 rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs); 382 cJiggle = 1; 383 } 384 rc = reportRelEventToMouseDev(cJiggle, 0, dz, dw, fButtons); 385 } 386 else 387 rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons); 388 389 mLastAbsX = mouseXAbs; 390 mLastAbsY = mouseYAbs; 391 return rc; 392 } 393 359 394 /** 360 395 * Send a mouse event. … … 368 403 STDMETHODIMP Mouse::PutMouseEvent(LONG dx, LONG dy, LONG dz, LONG dw, LONG buttonState) 369 404 { 370 HRESULT rc = S_OK; 405 HRESULT rc; 406 /** Do we need to send updated capabilities to the VMM device? */ 407 bool fUpdateCaps = FALSE; 408 uint32_t fButtons; 371 409 372 410 AutoCaller autoCaller(this); 373 411 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 374 412 375 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 376 377 LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__, 378 dx, dy, dz, dw)); 379 /* 380 * This method being called implies that the host no 381 * longer wants to use absolute coordinates. If the VMM 382 * device isn't aware of that yet, tell it. 383 */ 384 if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE) 385 { 386 uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE; 413 { 414 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 415 416 LogRel3(("%s: dx=%d, dy=%d, dz=%d, dw=%d\n", __PRETTY_FUNCTION__, 417 dx, dy, dz, dw)); 418 /* Make sure that the guest knows that we are sending real movement 419 * events to the PS/2 device and not just dummy wake-up ones. */ 420 if (uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE) 421 { 422 uHostCaps &= ~VMMDEV_MOUSE_HOST_CAN_ABSOLUTE; 423 fUpdateCaps = TRUE; 424 } 425 426 fButtons = mouseButtonsToPDM(buttonState); 427 } 428 if (fUpdateCaps) 387 429 setVMMDevMouseCaps(uHostCaps); 388 }389 390 uint32_t fButtons = mouseButtonsToPDM(buttonState);391 430 rc = reportRelEventToMouseDev(dx, dy, dz, dw, fButtons); 392 if (SUCCEEDED(rc))393 mLastButtons = fButtons;394 431 395 432 return rc; … … 397 434 398 435 /** 399 * Convert an X value in screen co-ordinates (starting from 1) to a value400 * from 0 to 0xffff.436 * Convert an (X, Y) value pair in screen co-ordinates (starting from 1) to a 437 * value from 0 to 0xffff. 401 438 * 402 439 * @returns COM status value 403 440 */ 404 HRESULT Mouse::convertDisplay Width(LONG x, uint32_t *pcX)441 HRESULT Mouse::convertDisplayRes(LONG x, LONG y, uint32_t *pcX, uint32_t *pcY) 405 442 { 406 443 AssertPtrReturn(pcX, E_POINTER); 407 Display *pDisplay = mParent->getDisplay();408 ComAssertRet(pDisplay, E_FAIL);409 410 ULONG displayWidth;411 HRESULT rc = pDisplay->GetScreenResolution (0, &displayWidth, NULL, NULL);412 if (FAILED(rc)) return rc;413 414 *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0;415 return S_OK;416 }417 418 /**419 * Convert a Y value in screen co-ordinates (starting from 1) to a value420 * from 0 to 0xffff.421 *422 * @returns COM status value423 */424 HRESULT Mouse::convertDisplayHeight(LONG y, uint32_t *pcY)425 {426 444 AssertPtrReturn(pcY, E_POINTER); 427 445 Display *pDisplay = mParent->getDisplay(); 428 446 ComAssertRet(pDisplay, E_FAIL); 429 447 430 ULONG displayHeight; 431 HRESULT rc = pDisplay->GetScreenResolution (0, NULL, &displayHeight, NULL); 432 if (FAILED(rc)) return rc; 433 448 ULONG displayWidth, displayHeight; 449 /* Takes the display lock */ 450 HRESULT rc = pDisplay->GetScreenResolution (0, &displayWidth, &displayHeight, 451 NULL); 452 if (FAILED(rc)) 453 return rc; 454 455 *pcX = displayWidth ? ((x - 1) * 0xFFFF) / displayWidth: 0; 434 456 *pcY = displayHeight ? ((y - 1) * 0xFFFF) / displayHeight: 0; 435 457 return S_OK; … … 438 460 439 461 /** 440 * Send an absolute mouse event to the VM. This only works 441 * when the required guest support has been installed. 462 * Send an absolute mouse event to the VM. This requires either VirtualBox- 463 * specific drivers installed in the guest or absolute pointing device 464 * emulation. 442 465 * 443 466 * @returns COM status code … … 453 476 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 454 477 455 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);456 457 478 LogRel3(("%s: x=%d, y=%d, dz=%d, dw=%d, buttonState=0x%x\n", 458 479 __PRETTY_FUNCTION__, x, y, dz, dw, buttonState)); 459 480 460 uint32_t mouseXAbs; 481 uint32_t mouseXAbs, mouseYAbs; 482 /** Do we need to send updated capabilities to the VMM device? */ 483 bool fUpdateCaps = FALSE; 484 461 485 /** @todo the front end should do this conversion to avoid races */ 462 HRESULT rc = convertDisplayWidth(x, &mouseXAbs); 486 /** @note Or maybe not... races are pretty inherent in everything done in 487 * this object and not really bad as far as I can see. */ 488 HRESULT rc = convertDisplayRes(x, y, &mouseXAbs, &mouseYAbs); 463 489 if (FAILED(rc)) return rc; 464 490 465 /** 466 * @todo multi-monitor Windows guests expect this to be unbounded. 467 * Understand the issues involved and fix for the rest. 468 */ 491 /** @todo multi-monitor Windows guests expect this to be unbounded. 492 * Understand the issues involved and fix for the rest. */ 469 493 /* if (mouseXAbs > 0xffff) 470 mouseXAbs = mLastAbsX; */ 471 472 uint32_t mouseYAbs; 473 rc = convertDisplayHeight(y, &mouseYAbs); 474 if (FAILED(rc)) return rc; 475 /* if (mouseYAbs > 0xffff) 494 mouseXAbs = mLastAbsX; 495 if (mouseYAbs > 0xffff) 476 496 mouseYAbs = mLastAbsY; */ 477 478 uint32_t fButtons = mouseButtonsToPDM(buttonState);479 497 480 498 uint32_t mouseCaps; 481 499 rc = getVMMDevMouseCaps(&mouseCaps); 482 500 if (FAILED(rc)) return rc; 483 484 /* 485 * This method being called implies that the host wants 486 * to use absolute coordinates. If the VMM device isn't 487 * aware of that yet, tell it. 488 */ 489 if (!(mouseCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)) 490 { 491 uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE; 501 uint32_t fButtons = mouseButtonsToPDM(buttonState); 502 503 /* If we are doing old-style (IRQ-less) absolute reporting to the VMM 504 * device then make sure the guest is aware of it, so that it knows to 505 * ignore relative movement on the PS/2 device. */ 506 { 507 AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS); 508 509 /** @todo rename that capability to VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE */ 510 if (fVMMDevCanAbs && !(uHostCaps & VMMDEV_MOUSE_HOST_CAN_ABSOLUTE)) 511 { 512 uHostCaps |= VMMDEV_MOUSE_HOST_CAN_ABSOLUTE; 513 fUpdateCaps = TRUE; 514 } 515 } 516 if (fUpdateCaps) 492 517 setVMMDevMouseCaps(uHostCaps); 493 } 494 495 if (fVMMDevCanAbs) 496 { 497 /* 498 * Send the absolute mouse position to the VMM device. 499 */ 500 rc = reportAbsEventToVMMDev(mouseXAbs, mouseYAbs); 501 /* We may need to send an additional event for button information or 502 * to wake up older guests to the changed absolute co-ordinates. If 503 * the event is a pure wake up one, we make sure it contains some 504 * (possibly phony) event data to make sure it isn't just discarded 505 * on the way. */ 506 bool fNeedsJiggle = !(mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV); 507 if (fNeedsJiggle || fButtons != mLastButtons || dz || dw) 508 { 509 rc = reportRelEventToMouseDev(fNeedsJiggle ? 1 : 0, 0, dz, dw, 510 fButtons); 511 } 512 } 513 else 514 rc = reportAbsEventToMouseDev(mouseXAbs, mouseYAbs, dz, dw, fButtons); 515 516 if (FAILED(rc)) return rc; 517 518 mLastAbsX = mouseXAbs; 519 mLastAbsY = mouseYAbs; 520 521 mLastButtons = fButtons; 518 519 /** @todo rename that capability to VMMDEV_MOUSE_GUEST_USES_EVENT */ 520 rc = reportAbsEvent(mouseXAbs, mouseYAbs, dz, dw, fButtons, 521 mouseCaps & VMMDEV_MOUSE_GUEST_USES_VMMDEV); 522 522 523 return rc; 523 524 } … … 532 533 bool fRelDev = false; 533 534 uint32_t u32MouseCaps; 534 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i) 535 if (mpDrv[i]) 536 { 537 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE) 538 fAbsDev = true; 539 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE) 540 fRelDev = true; 541 } 535 536 { 537 AutoWriteLock aLock(this COMMA_LOCKVAL_SRC_POS); 538 539 for (unsigned i = 0; i < MOUSE_MAX_DEVICES; ++i) 540 if (mpDrv[i]) 541 { 542 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_ABSOLUTE) 543 fAbsDev = true; 544 if (mpDrv[i]->u32DevCaps & MOUSE_DEVCAP_RELATIVE) 545 fRelDev = true; 546 } 547 if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)) 548 uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV; 549 if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)) 550 uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV; 551 } 542 552 if (SUCCEEDED(getVMMDevMouseCaps(&u32MouseCaps))) 543 553 fVMMDevCanAbs = (u32MouseCaps & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE) … … 545 555 else 546 556 fVMMDevCanAbs = false; 557 /** @todo this call takes the Console lock in order to update the cached 558 * callback data atomically. However I can't see any sign that the cached 559 * data is ever used again. */ 547 560 mParent->onMouseCapabilityChange(fAbsDev || fVMMDevCanAbs, fRelDev, 548 561 fVMMDevNeedsHostCursor); 549 562 /** @todo if this gets called during device initialisation we get an 550 563 * error due to VMMDev not being initialised yet. */ 551 if (fAbsDev && !(uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))552 uHostCaps |= VMMDEV_MOUSE_HOST_HAS_ABS_DEV;553 if (!fAbsDev && (uHostCaps & VMMDEV_MOUSE_HOST_HAS_ABS_DEV))554 uHostCaps &= ~VMMDEV_MOUSE_HOST_HAS_ABS_DEV;555 564 setVMMDevMouseCaps(uHostCaps); 556 565 } … … 664 673 pData->pMouse = (Mouse *)pv; /** @todo Check this cast! */ 665 674 unsigned cDev; 666 for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev) 667 if (!pData->pMouse->mpDrv[cDev]) 668 { 669 pData->pMouse->mpDrv[cDev] = pData; 670 break; 671 } 675 { 676 AutoReadLock mouseLock(pData->pMouse COMMA_LOCKVAL_SRC_POS); 677 678 for (cDev = 0; cDev < MOUSE_MAX_DEVICES; ++cDev) 679 if (!pData->pMouse->mpDrv[cDev]) 680 { 681 pData->pMouse->mpDrv[cDev] = pData; 682 break; 683 } 684 } 672 685 if (cDev == MOUSE_MAX_DEVICES) 673 686 return VERR_NO_MORE_HANDLES; -
trunk/src/VBox/Main/include/MouseImpl.h
r30764 r32817 120 120 int32_t dz, int32_t dw, uint32_t fButtons); 121 121 HRESULT reportAbsEventToVMMDev(uint32_t mouseXAbs, uint32_t mouseYAbs); 122 HRESULT convertDisplayWidth(LONG x, uint32_t *pcX); 123 HRESULT convertDisplayHeight(LONG y, uint32_t *pcY); 122 HRESULT reportAbsEvent(uint32_t mouseXAbs, uint32_t mouseYAbs, 123 int32_t dz, int32_t dw, uint32_t fButtons, 124 bool fUsesVMMDevEvent); 125 HRESULT convertDisplayRes(LONG x, LONG y, uint32_t *pcX, uint32_t *pcY); 124 126 125 127 void sendMouseCapsNotifications(void);
Note:
See TracChangeset
for help on using the changeset viewer.