Changeset 45763 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Apr 26, 2013 7:42:25 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r45703 r45763 81 81 static HANDLE vboxDtGetNotifyEvent(); 82 82 83 /* caps API */ 84 #define VBOXCAPS_ENTRY_IDX_SEAMLESS 0 85 #define VBOXCAPS_ENTRY_IDX_GRAPHICS 1 86 #define VBOXCAPS_ENTRY_IDX_COUNT 2 87 88 typedef enum VBOXCAPS_ENTRY_FUNCSTATE 89 { 90 /* the cap is unsupported */ 91 VBOXCAPS_ENTRY_FUNCSTATE_UNSUPPORTED = 0, 92 /* the cap is supported */ 93 VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED, 94 /* the cap functionality is started, it can be disabled however if its AcState is not ACQUIRED */ 95 VBOXCAPS_ENTRY_FUNCSTATE_STARTED, 96 } VBOXCAPS_ENTRY_FUNCSTATE; 97 98 99 static void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState); 100 static int VBoxCapsInit(); 101 static int VBoxCapsReleaseAll(); 102 static void VBoxCapsTerm(); 103 static BOOL VBoxCapsEntryIsAcquired(uint32_t iCap); 104 static BOOL VBoxCapsEntryIsEnabled(uint32_t iCap); 105 static BOOL VBoxCapsCheckTimer(WPARAM wParam); 106 static int VBoxCapsEntryRelease(uint32_t iCap); 107 static int VBoxCapsEntryAcquire(uint32_t iCap); 108 static int VBoxCapsAcquireAllSupported(); 109 110 /* console-related caps API */ 111 static BOOL VBoxConsoleIsAllowed(); 112 static void VBoxConsoleEnable(BOOL fEnable); 113 static void VBoxConsoleCapSetSupported(uint32_t iCap, BOOL fSupported); 114 115 static void VBoxGrapicsSetSupported(BOOL fSupported); 83 116 84 117 /******************************************************************************* … … 105 138 NOTIFYICONDATA gNotifyIconData; 106 139 DWORD gMajorVersion; 107 BOOL gfIsSeamlessOn = FALSE;108 140 109 141 … … 657 689 */ 658 690 659 HANDLE hWaitEvent[3] = { ghStopSem, ghSeamlessWtNotifyEvent, vboxDtGetNotifyEvent() }; 660 DWORD dwEventCount = RT_ELEMENTS(hWaitEvent); 661 662 if (0 == ghSeamlessWtNotifyEvent) /* If seamless mode is not active / supported, reduce event array count. */ 663 dwEventCount = 1; 691 HANDLE hWaitEvent[3] = {0}; 692 DWORD dwEventCount = 0; 693 694 hWaitEvent[dwEventCount++] = ghStopSem; 695 696 /* Check if seamless mode is not active and add seamless event to the list */ 697 if (0 != ghSeamlessWtNotifyEvent) 698 { 699 hWaitEvent[dwEventCount++] = ghSeamlessWtNotifyEvent; 700 } 701 702 if (0 != vboxDtGetNotifyEvent()) 703 { 704 hWaitEvent[dwEventCount++] = vboxDtGetNotifyEvent(); 705 } 664 706 665 707 Log(("VBoxTray: Number of events to wait in main loop: %ld\n", dwEventCount)); … … 678 720 break; 679 721 } 680 else if ( waitResult == 1 681 && ghSeamlessWtNotifyEvent != 0) /* Only jump in, if seamless is active! */ 722 else 682 723 { 683 Log(("VBoxTray: Event 'Seamless' triggered\n")); 684 685 /* seamless window notification */ 686 VBoxSeamlessCheckWindows(); 687 } 688 else if ( waitResult == 2 689 && vboxDtGetNotifyEvent() != 0) /* Only jump in, if Dt is active! */ 690 { 691 BOOL fOldSeamlessAllowedState = VBoxSeamlessIsAllowed(); 692 if (vboxDtHandleEvent()) 724 BOOL fHandled = FALSE; 725 if (waitResult < RT_ELEMENTS(hWaitEvent)) 693 726 { 694 if ( !VBoxSeamlessIsAllowed() != !fOldSeamlessAllowedState)727 if (hWaitEvent[waitResult]) 695 728 { 696 rc = VBoxSeamlessOnAllowChange(!fOldSeamlessAllowedState); 697 if (!RT_SUCCESS(rc)) 698 Log(("VBoxTray: WndProc: Failed to set seamless capability\n")); 729 if (hWaitEvent[waitResult] == ghSeamlessWtNotifyEvent) 730 { 731 Log(("VBoxTray: Event 'Seamless' triggered\n")); 732 733 /* seamless window notification */ 734 VBoxSeamlessCheckWindows(); 735 fHandled = TRUE; 736 } 737 else if (hWaitEvent[waitResult] == vboxDtGetNotifyEvent()) 738 { 739 Log(("VBoxTray: Event 'Dt' triggered\n")); 740 BOOL fOldAllowedState = VBoxConsoleIsAllowed(); 741 if (vboxDtHandleEvent()) 742 { 743 if (!VBoxConsoleIsAllowed() != !fOldAllowedState) 744 VBoxConsoleEnable(!fOldAllowedState); 745 } 746 fHandled = TRUE; 747 } 699 748 } 700 749 } 701 } 702 else 703 { 704 /* timeout or a window message, handle it */ 705 MSG msg; 706 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 750 751 if (!fHandled) 707 752 { 708 Log(("VBoxTray: msg %p\n", msg.message)); 709 if (msg.message == WM_QUIT) 753 /* timeout or a window message, handle it */ 754 MSG msg; 755 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 710 756 { 711 Log(("VBoxTray: WM_QUIT!\n")); 712 SetEvent(ghStopSem); 713 continue; 757 Log(("VBoxTray: msg %p\n", msg.message)); 758 if (msg.message == WM_QUIT) 759 { 760 Log(("VBoxTray: WM_QUIT!\n")); 761 SetEvent(ghStopSem); 762 } 763 TranslateMessage(&msg); 764 DispatchMessage(&msg); 714 765 } 715 TranslateMessage(&msg);716 DispatchMessage(&msg);717 766 } 718 767 } … … 767 816 if (RT_SUCCESS(rc)) 768 817 { 818 VBoxCapsInit(); 819 769 820 rc = vboxStInit(ghwndToolWindow); 770 821 if (!RT_SUCCESS(rc)) … … 803 854 vboxStTerm(); 804 855 856 VBoxCapsTerm(); 857 805 858 vboxTrayDestroyToolWindow(); 806 859 } … … 854 907 855 908 case WM_TIMER: 909 if (VBoxCapsCheckTimer(wParam)) 910 return 0; 911 856 912 switch (wParam) 857 913 { … … 881 937 882 938 case WM_VBOX_SEAMLESS_ENABLE: 883 gfIsSeamlessOn = TRUE; 884 if (VBoxSeamlessIsAllowed()) 885 VBoxSeamlessInstallHook(); 939 VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 886 940 return 0; 887 941 888 942 case WM_VBOX_SEAMLESS_DISABLE: 889 gfIsSeamlessOn = FALSE; 890 if (VBoxSeamlessIsAllowed()) 891 VBoxSeamlessRemoveHook(); 943 VBoxCapsEntryFuncStateSet(VBOXCAPS_ENTRY_IDX_SEAMLESS, VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED); 892 944 return 0; 893 945 894 946 case WM_VBOX_SEAMLESS_UPDATE: 895 if ( gfIsSeamlessOn && VBoxSeamlessIsAllowed())947 if (VBoxCapsEntryIsEnabled(VBOXCAPS_ENTRY_IDX_SEAMLESS)) 896 948 VBoxSeamlessCheckWindows(); 949 return 0; 950 951 case WM_VBOX_GRAPHICS_SUPPORTED: 952 VBoxGrapicsSetSupported(TRUE); 953 return 0; 954 955 case WM_VBOX_GRAPHICS_UNSUPPORTED: 956 VBoxGrapicsSetSupported(FALSE); 897 957 return 0; 898 958 … … 907 967 case WM_WTSSESSION_CHANGE: 908 968 { 909 BOOL fOld SeamlessAllowedState = VBoxSeamlessIsAllowed();969 BOOL fOldAllowedState = VBoxConsoleIsAllowed(); 910 970 if (vboxStHandleEvent(wParam, lParam)) 911 971 { 912 if (!VBoxSeamlessIsAllowed() != !fOldSeamlessAllowedState) 913 { 914 int rc = VBoxSeamlessOnAllowChange(!fOldSeamlessAllowedState); 915 if (!RT_SUCCESS(rc)) 916 Log(("VBoxTray: WndProc: Failed to set seamless capability\n")); 917 } 972 if (!VBoxConsoleIsAllowed() != !fOldAllowedState) 973 VBoxConsoleEnable(!fOldAllowedState); 918 974 } 919 975 return 0; … … 1302 1358 1303 1359 1304 /* helper state tracking API */ 1305 BOOL VBoxSeamlessIsAllowed() 1360 /* we need to perform Acquire/Release using the file handled we use for rewuesting events from VBoxGuest 1361 * otherwise Acquisition mechanism will treat us as different client and will not propagate necessary requests 1362 * */ 1363 static int VBoxAcquireGuestCaps(uint32_t fOr, uint32_t fNot) 1364 { 1365 DWORD cbReturned = 0; 1366 VBoxGuestCapsAquire Info; 1367 Info.rc = VERR_NOT_IMPLEMENTED; 1368 Info.u32OrMask = fOr; 1369 Info.u32NotMask = fNot; 1370 if (!DeviceIoControl(ghVBoxDriver, VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE, &Info, sizeof(Info), &Info, sizeof(Info), &cbReturned, NULL)) 1371 { 1372 DWORD LastErr = GetLastError(); 1373 WARN(("DeviceIoControl VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE failed LastErr %d", LastErr)); 1374 return RTErrConvertFromWin32(LastErr); 1375 } 1376 1377 int rc = Info.rc; 1378 if (!RT_SUCCESS(rc)) 1379 { 1380 WARN(("VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE failed rc %d", rc)); 1381 return rc; 1382 } 1383 1384 return rc; 1385 } 1386 1387 typedef enum VBOXCAPS_ENTRY_ACSTATE 1388 { 1389 /* the given cap is released */ 1390 VBOXCAPS_ENTRY_ACSTATE_RELEASED = 0, 1391 /* the given cap acquisition is in progress */ 1392 VBOXCAPS_ENTRY_ACSTATE_ACQUIRING, 1393 /* the given cap is acquired */ 1394 VBOXCAPS_ENTRY_ACSTATE_ACQUIRED 1395 } VBOXCAPS_ENTRY_ACSTATE; 1396 1397 1398 struct VBOXCAPS_ENTRY; 1399 struct VBOXCAPS; 1400 1401 typedef DECLCALLBACKPTR(void, PFNVBOXCAPS_ENTRY_ON_ENABLE)(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled); 1402 1403 typedef struct VBOXCAPS_ENTRY 1404 { 1405 uint32_t fCap; 1406 uint32_t iCap; 1407 /* the functionality is supported by the guest */ 1408 BOOL fIsSupported; 1409 /* */ 1410 BOOL fIsOn; 1411 VBOXCAPS_ENTRY_FUNCSTATE enmFuncState; 1412 VBOXCAPS_ENTRY_ACSTATE enmAcState; 1413 PFNVBOXCAPS_ENTRY_ON_ENABLE pfnOnEnable; 1414 } VBOXCAPS_ENTRY; 1415 1416 1417 typedef struct VBOXCAPS 1418 { 1419 UINT_PTR idTimer; 1420 VBOXCAPS_ENTRY aCaps[VBOXCAPS_ENTRY_IDX_COUNT]; 1421 } VBOXCAPS; 1422 1423 static VBOXCAPS gVBoxCaps; 1424 1425 static DECLCALLBACK(void) vboxCapsOnEnableSeamles(struct VBOXCAPS *pConsole, struct VBOXCAPS_ENTRY *pCap, BOOL fEnabled) 1426 { 1427 if (fEnabled) 1428 { 1429 Assert(pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1430 Assert(pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1431 VBoxSeamlessInstallHook(); 1432 } 1433 else 1434 { 1435 Assert(pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRED || pCap->enmFuncState != VBOXCAPS_ENTRY_FUNCSTATE_STARTED); 1436 VBoxSeamlessRemoveHook(); 1437 } 1438 } 1439 1440 static void vboxCapsEntryAcStateSet(VBOXCAPS_ENTRY *pCap, VBOXCAPS_ENTRY_ACSTATE enmAcState) 1441 { 1442 VBOXCAPS *pConsole = &gVBoxCaps; 1443 if (pCap->enmAcState == enmAcState) 1444 return; 1445 1446 VBOXCAPS_ENTRY_ACSTATE enmOldAcState = pCap->enmAcState; 1447 pCap->enmAcState = enmAcState; 1448 1449 if (enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED) 1450 { 1451 if (pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED) 1452 { 1453 if (pCap->pfnOnEnable) 1454 pCap->pfnOnEnable(pConsole, pCap, TRUE); 1455 } 1456 } 1457 else if (enmOldAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED && pCap->enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED) 1458 { 1459 if (pCap->pfnOnEnable) 1460 pCap->pfnOnEnable(pConsole, pCap, FALSE); 1461 } 1462 } 1463 1464 static void vboxCapsEntryFuncStateSet(VBOXCAPS_ENTRY *pCap, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState) 1465 { 1466 VBOXCAPS *pConsole = &gVBoxCaps; 1467 if (pCap->enmFuncState == enmFuncState) 1468 return; 1469 1470 VBOXCAPS_ENTRY_FUNCSTATE enmOldFuncState = pCap->enmFuncState; 1471 1472 pCap->enmFuncState = enmFuncState; 1473 1474 if (enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED) 1475 { 1476 Assert(enmOldFuncState == VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED); 1477 if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED) 1478 { 1479 if (pCap->pfnOnEnable) 1480 pCap->pfnOnEnable(pConsole, pCap, TRUE); 1481 } 1482 } 1483 else if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED && enmOldFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED) 1484 { 1485 if (pCap->pfnOnEnable) 1486 pCap->pfnOnEnable(pConsole, pCap, FALSE); 1487 } 1488 } 1489 1490 static void VBoxCapsEntryFuncStateSet(uint32_t iCup, VBOXCAPS_ENTRY_FUNCSTATE enmFuncState) 1491 { 1492 VBOXCAPS *pConsole = &gVBoxCaps; 1493 VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCup]; 1494 vboxCapsEntryFuncStateSet(pCap, enmFuncState); 1495 } 1496 1497 static int VBoxCapsInit() 1498 { 1499 VBOXCAPS *pConsole = &gVBoxCaps; 1500 memset(pConsole, 0, sizeof (*pConsole)); 1501 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].fCap = VMMDEV_GUEST_SUPPORTS_SEAMLESS; 1502 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].iCap = VBOXCAPS_ENTRY_IDX_SEAMLESS; 1503 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_SEAMLESS].pfnOnEnable = vboxCapsOnEnableSeamles; 1504 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].fCap = VMMDEV_GUEST_SUPPORTS_GRAPHICS; 1505 pConsole->aCaps[VBOXCAPS_ENTRY_IDX_GRAPHICS].iCap = VBOXCAPS_ENTRY_IDX_GRAPHICS; 1506 return VINF_SUCCESS; 1507 } 1508 1509 static int VBoxCapsReleaseAll() 1510 { 1511 VBOXCAPS *pConsole = &gVBoxCaps; 1512 int rc = VBoxAcquireGuestCaps(0, VMMDEV_GUEST_SUPPORTS_SEAMLESS | VMMDEV_GUEST_SUPPORTS_GRAPHICS); 1513 if (!RT_SUCCESS(rc)) 1514 { 1515 WARN(("VBoxTray: vboxCapsEntryReleaseAll VBoxAcquireGuestCaps failed rc %d\n", rc)); 1516 return rc; 1517 } 1518 1519 if (pConsole->idTimer) 1520 { 1521 KillTimer(ghwndToolWindow, pConsole->idTimer); 1522 pConsole->idTimer = 0; 1523 } 1524 1525 for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i) 1526 { 1527 vboxCapsEntryAcStateSet(&pConsole->aCaps[i], VBOXCAPS_ENTRY_ACSTATE_RELEASED); 1528 } 1529 1530 return rc; 1531 } 1532 1533 static void VBoxCapsTerm() 1534 { 1535 VBOXCAPS *pConsole = &gVBoxCaps; 1536 VBoxCapsReleaseAll(); 1537 memset(pConsole, 0, sizeof (*pConsole)); 1538 } 1539 1540 static BOOL VBoxCapsEntryIsAcquired(uint32_t iCap) 1541 { 1542 VBOXCAPS *pConsole = &gVBoxCaps; 1543 return pConsole->aCaps[iCap].enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED; 1544 } 1545 1546 static BOOL VBoxCapsEntryIsEnabled(uint32_t iCap) 1547 { 1548 VBOXCAPS *pConsole = &gVBoxCaps; 1549 return pConsole->aCaps[iCap].enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED 1550 && pConsole->aCaps[iCap].enmFuncState == VBOXCAPS_ENTRY_FUNCSTATE_STARTED; 1551 } 1552 1553 static BOOL VBoxCapsCheckTimer(WPARAM wParam) 1554 { 1555 VBOXCAPS *pConsole = &gVBoxCaps; 1556 if (wParam != pConsole->idTimer) 1557 return FALSE; 1558 1559 uint32_t u32AcquiredCaps = 0; 1560 BOOL fNeedNewTimer = FALSE; 1561 1562 for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i) 1563 { 1564 VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[i]; 1565 if (pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_ACQUIRING) 1566 continue; 1567 1568 int rc = VBoxAcquireGuestCaps(pCap->fCap, 0); 1569 if (RT_SUCCESS(rc)) 1570 { 1571 vboxCapsEntryAcStateSet(&pConsole->aCaps[i], VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1572 u32AcquiredCaps |= pCap->fCap; 1573 } 1574 else 1575 { 1576 Assert(rc == VERR_RESOURCE_BUSY); 1577 fNeedNewTimer = TRUE; 1578 } 1579 } 1580 1581 if (!fNeedNewTimer) 1582 { 1583 KillTimer(ghwndToolWindow, pConsole->idTimer); 1584 /* cleanup timer data */ 1585 pConsole->idTimer = 0; 1586 } 1587 1588 return TRUE; 1589 } 1590 1591 static int VBoxCapsEntryRelease(uint32_t iCap) 1592 { 1593 VBOXCAPS *pConsole = &gVBoxCaps; 1594 VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCap]; 1595 if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_RELEASED) 1596 { 1597 WARN(("invalid cap[%d] state[%d] on release\n", iCap, pCap->enmAcState)); 1598 return VERR_INVALID_STATE; 1599 } 1600 1601 if (pCap->enmAcState == VBOXCAPS_ENTRY_ACSTATE_ACQUIRED) 1602 { 1603 int rc = VBoxAcquireGuestCaps(0, pCap->fCap); 1604 AssertRC(rc); 1605 } 1606 1607 vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_RELEASED); 1608 1609 return VINF_SUCCESS; 1610 } 1611 1612 static int VBoxCapsEntryAcquire(uint32_t iCap) 1613 { 1614 VBOXCAPS *pConsole = &gVBoxCaps; 1615 Assert(VBoxConsoleIsAllowed()); 1616 VBOXCAPS_ENTRY *pCap = &pConsole->aCaps[iCap]; 1617 if (pCap->enmAcState != VBOXCAPS_ENTRY_ACSTATE_RELEASED) 1618 { 1619 WARN(("invalid cap[%d] state[%d] on acquire\n", iCap, pCap->enmAcState)); 1620 return VERR_INVALID_STATE; 1621 } 1622 1623 vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_ACQUIRING); 1624 int rc = VBoxAcquireGuestCaps(pCap->fCap, 0); 1625 if (RT_SUCCESS(rc)) 1626 { 1627 vboxCapsEntryAcStateSet(pCap, VBOXCAPS_ENTRY_ACSTATE_ACQUIRED); 1628 return VINF_SUCCESS; 1629 } 1630 1631 if (rc != VERR_RESOURCE_BUSY) 1632 { 1633 WARN(("VBoxTray: vboxCapsEntryReleaseAll VBoxAcquireGuestCaps failed rc %d\n", rc)); 1634 return rc; 1635 } 1636 1637 WARN(("VBoxTray: iCap %d is busy!\n", iCap)); 1638 1639 /* the cap was busy, most likely it is still used by other VBoxTray instance running in another session, 1640 * queue the retry timer */ 1641 if (!pConsole->idTimer) 1642 { 1643 pConsole->idTimer = SetTimer(ghwndToolWindow, TIMERID_VBOXTRAY_CAPS_TIMER, 100, (TIMERPROC)NULL); 1644 if (!pConsole->idTimer) 1645 { 1646 DWORD dwErr = GetLastError(); 1647 WARN(("VBoxTray: SetTimer error %08X\n", dwErr)); 1648 return RTErrConvertFromWin32(dwErr); 1649 } 1650 } 1651 1652 return rc; 1653 } 1654 1655 static int VBoxCapsAcquireAllSupported() 1656 { 1657 VBOXCAPS *pConsole = &gVBoxCaps; 1658 for (int i = 0; i < RT_ELEMENTS(pConsole->aCaps); ++i) 1659 { 1660 if (pConsole->aCaps[i].enmFuncState >= VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED) 1661 VBoxCapsEntryAcquire(i); 1662 } 1663 return VINF_SUCCESS; 1664 } 1665 1666 static BOOL VBoxConsoleIsAllowed() 1306 1667 { 1307 1668 return vboxDtIsInputDesktop() && vboxStIsActiveConsole(); 1308 1669 } 1309 1670 1310 int VBoxSeamlessOnAllowChange(BOOL fAllowed) 1311 { 1312 int rc; 1313 if (fAllowed) 1314 { 1315 rc = VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_SEAMLESS, 0); 1316 if (gfIsSeamlessOn) 1317 VBoxSeamlessInstallHook(); 1318 } 1671 static void VBoxConsoleEnable(BOOL fEnable) 1672 { 1673 if (fEnable) 1674 VBoxCapsAcquireAllSupported(); 1319 1675 else 1320 { 1321 if (gfIsSeamlessOn) 1322 VBoxSeamlessRemoveHook(); 1323 rc = VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_SEAMLESS); 1324 } 1325 if (!RT_SUCCESS(rc)) 1326 WARN(("VBoxTray: VMMDEV_GUEST_SUPPORTS_SEAMLESS: Failed to %s seamless capability\n", fAllowed ? "set" : "clear" )); 1327 1328 return rc; 1329 } 1676 VBoxCapsReleaseAll(); 1677 } 1678 1679 static void VBoxConsoleCapSetSupported(uint32_t iCap, BOOL fSupported) 1680 { 1681 if (fSupported) 1682 { 1683 VBoxCapsEntryFuncStateSet(iCap, VBOXCAPS_ENTRY_FUNCSTATE_SUPPORTED); 1684 1685 if (VBoxConsoleIsAllowed()) 1686 VBoxCapsEntryAcquire(iCap); 1687 } 1688 else 1689 { 1690 VBoxCapsEntryFuncStateSet(iCap, VBOXCAPS_ENTRY_FUNCSTATE_UNSUPPORTED); 1691 1692 VBoxCapsEntryRelease(iCap); 1693 } 1694 } 1695 1696 void VBoxSeamlessSetSupported(BOOL fSupported) 1697 { 1698 VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_SEAMLESS, fSupported); 1699 } 1700 1701 static void VBoxGrapicsSetSupported(BOOL fSupported) 1702 { 1703 VBoxConsoleCapSetSupported(VBOXCAPS_ENTRY_IDX_GRAPHICS, fSupported); 1704 }
Note:
See TracChangeset
for help on using the changeset viewer.