- Timestamp:
- Dec 9, 2013 5:24:01 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
r49811 r49850 40 40 # include <iprt/semaphore.h> 41 41 # include <VBox/sup.h> 42 # include <IOKit/IOMessage.h> 42 43 #endif 43 44 … … 315 316 CFIndex idxPosition; /** Position in global storage (used to simplify CFArray navigation when removing detached device) */ 316 317 uint64_t cCapsLockTimeout; /** KBD CAPS LOCK key hold timeout (some Apple keyboards only) */ 318 319 io_object_t notification; /** General interest notification stuff: notification reference */ 320 IONotificationPortRef notificationPortRef; /** General interest notification stuff: notification port reference */ 321 317 322 } VBoxKbdState_t; 318 323 … … 1718 1723 } 1719 1724 1725 /** IOHID Device general interest notification callback. We are interested in kIOMessageDeviceHasPoweredOn message. 1726 * When we receive it, we do silently resync kbd which was just resumed. The rest of messages are for debugging 1727 * purpose. */ 1728 static void darwinHidNotificationCb(void *pData, io_service_t unused1, natural_t msg, void *unused2) 1729 { 1730 NOREF(unused1); 1731 NOREF(unused2); 1732 1733 AssertReturnVoid(pData); 1734 VBoxKbdState_t *pKbd = (VBoxKbdState_t *)pData; 1735 1736 switch (msg) 1737 { 1738 case kIOMessageDeviceHasPoweredOn: 1739 { 1740 LogRel2(("HID general interest notification kIOMessageDeviceHasPoweredOn for KBD %d\n", (int)(pKbd->idxPosition))); 1741 1742 VBoxHidsState_t *pHidState = (VBoxHidsState_t *)pKbd->pParentContainer; 1743 CFDictionaryRef elementMatchingDict = darwinQueryLedElementMatchingDictionary(); 1744 if (elementMatchingDict) 1745 { 1746 (void)darwinSetDeviceLedsState(pKbd->pDevice, elementMatchingDict, 1747 pHidState->guestState.fNumLockOn, pHidState->guestState.fCapsLockOn, pHidState->guestState.fScrollLockOn); 1748 CFRelease(elementMatchingDict); 1749 } 1750 break; 1751 } 1752 1753 case kIOMessageDeviceWillPowerOff: 1754 { 1755 LogRel2(("HID general interest notification kIOMessageDeviceWillPowerOff for KBD %d\n", (int)(pKbd->idxPosition))); 1756 break; 1757 } 1758 1759 case kIOMessageCanDevicePowerOff: 1760 { 1761 LogRel2(("HID general interest notification kIOMessageCanDevicePowerOff for KBD %d\n", (int)(pKbd->idxPosition))); 1762 break; 1763 } 1764 1765 default: 1766 LogRel2(("HID general interest notification 0x%X for KBD %d\n", (int)msg, (int)(pKbd->idxPosition))); 1767 } 1768 } 1769 1770 /** Battle against automatic power management for KBD devices. Register general interest notification 1771 * callback in order to recync KBD device when its driver report that it has been resumed from auto-sleep. */ 1772 static int darwinHidSubscribeInterestNotification(VBoxKbdState_t *pKbd) 1773 { 1774 AssertReturn(pKbd, kIOReturnError); 1775 AssertReturn(pKbd->pDevice, kIOReturnError); 1776 1777 io_service_t service; 1778 kern_return_t rc = kIOReturnError; 1779 1780 service = IOHIDDeviceGetService(pKbd->pDevice); 1781 if (service) 1782 { 1783 pKbd->notificationPortRef = IONotificationPortCreate(kIOMasterPortDefault); 1784 if (pKbd->notificationPortRef) 1785 { 1786 rc = IOServiceAddInterestNotification(pKbd->notificationPortRef, service, kIOGeneralInterest, darwinHidNotificationCb, pKbd, &(pKbd->notification)); 1787 if (rc == kIOReturnSuccess) 1788 { 1789 LogRel2(("Interest notification has been registeted for KBD %d\n", (int)(pKbd->idxPosition))); 1790 CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(pKbd->notificationPortRef), kCFRunLoopDefaultMode); 1791 return 0; 1792 } 1793 } 1794 } 1795 1796 return rc; 1797 } 1798 1799 /** Remove general interest notification subscription. */ 1800 static void darwinHidUnsubscribeInterestNotification(VBoxKbdState_t *pKbd) 1801 { 1802 AssertReturnVoid(pKbd); 1803 AssertReturnVoid(pKbd->notificationPortRef); 1804 1805 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(pKbd->notificationPortRef), kCFRunLoopDefaultMode); 1806 IONotificationPortDestroy(pKbd->notificationPortRef); 1807 pKbd->notificationPortRef = 0; 1808 1809 LogRel2(("Interest notification has been removed for KBD %d\n", (int)(pKbd->idxPosition))); 1810 } 1811 1720 1812 /** This callback is called when user physically removes HID device. We remove device from cache here. */ 1721 1813 static void darwinHidRemovalCallback(void *pData, IOReturn unused, void *unused1) … … 1733 1825 //if (RT_FAILURE(RTSemMutexRequest(pHidState->fifoEventQueueLock, RT_INDEFINITE_WAIT))) 1734 1826 // return ; 1827 1828 darwinHidUnsubscribeInterestNotification(pKbd); 1735 1829 1736 1830 CFArrayRemoveValueAtIndex(pHidState->pDeviceCollection, pKbd->idxPosition); … … 1797 1891 } 1798 1892 1799 /* Register per-device removal callback */ 1800 IOHIDDeviceRegisterRemovalCallback(pKbd->pDevice, darwinHidRemovalCallback, (void *)pKbd); 1801 1802 /* Register per-device input callback */ 1803 IOHIDDeviceRegisterInputValueCallback(pKbd->pDevice, darwinHidInputCallback, (void *)pKbd); 1804 IOHIDDeviceScheduleWithRunLoop(pKbd->pDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 1805 1806 CFArrayAppendValue(pHidState->pDeviceCollection, (void *)pKbd); 1807 1808 LogRel2(("Saved LEDs for KBD %d (%p): fNumLockOn=%s, fCapsLockOn=%s, fScrollLockOn=%s\n", 1809 (int)pKbd->idxPosition, pKbd, VBOX_BOOL_TO_STR_STATE(pKbd->LED.fNumLockOn), VBOX_BOOL_TO_STR_STATE(pKbd->LED.fCapsLockOn), 1810 VBOX_BOOL_TO_STR_STATE(pKbd->LED.fScrollLockOn))); 1811 1812 if (fApplyLedState) 1893 rc = darwinHidSubscribeInterestNotification(pKbd); 1894 if (rc == 0) 1813 1895 { 1814 rc = darwinSetDeviceLedsState(pKbd->pDevice, elementMatchingDict, pHidState->guestState.fNumLockOn, 1815 pHidState->guestState.fCapsLockOn, pHidState->guestState.fScrollLockOn); 1816 if (rc != 0) 1817 LogRel2(("Unable to apply guest state to newly attached device\n")); 1896 /* Register per-device removal callback */ 1897 IOHIDDeviceRegisterRemovalCallback(pKbd->pDevice, darwinHidRemovalCallback, (void *)pKbd); 1898 1899 /* Register per-device input callback */ 1900 IOHIDDeviceRegisterInputValueCallback(pKbd->pDevice, darwinHidInputCallback, (void *)pKbd); 1901 IOHIDDeviceScheduleWithRunLoop(pKbd->pDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 1902 1903 CFArrayAppendValue(pHidState->pDeviceCollection, (void *)pKbd); 1904 1905 LogRel2(("Saved LEDs for KBD %d (%p): fNumLockOn=%s, fCapsLockOn=%s, fScrollLockOn=%s\n", 1906 (int)pKbd->idxPosition, pKbd, VBOX_BOOL_TO_STR_STATE(pKbd->LED.fNumLockOn), VBOX_BOOL_TO_STR_STATE(pKbd->LED.fCapsLockOn), 1907 VBOX_BOOL_TO_STR_STATE(pKbd->LED.fScrollLockOn))); 1908 1909 if (fApplyLedState) 1910 { 1911 rc = darwinSetDeviceLedsState(pKbd->pDevice, elementMatchingDict, pHidState->guestState.fNumLockOn, 1912 pHidState->guestState.fCapsLockOn, pHidState->guestState.fScrollLockOn); 1913 if (rc != 0) 1914 LogRel2(("Unable to apply guest state to newly attached device\n")); 1915 } 1916 1917 CFRelease(elementMatchingDict); 1918 return; 1818 1919 } 1819 1820 CFRelease(elementMatchingDict); 1821 return; 1920 else 1921 LogRel2(("Unable to subscribe to IOService interest notification for KBD %d. Disable sync for this keyboard.\n", (int)(pKbd->idxPosition))); 1822 1922 } 1823 1923 … … 2037 2137 VBOX_BOOL_TO_STR_STATE(pKbd->LED.fScrollLockOn))); 2038 2138 2139 darwinHidUnsubscribeInterestNotification(pKbd); 2140 2039 2141 free(pKbd); 2040 2142 }
Note:
See TracChangeset
for help on using the changeset viewer.