Changeset 48741 in vbox
- Timestamp:
- Sep 27, 2013 3:09:56 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
r48677 r48741 300 300 /* HID LEDs synchronization data: IOKit specific data. */ 301 301 typedef struct VBoxHidsState_t { 302 IOHIDManagerRef hidManagerRef; 303 IOHIDDeviceRef *hidDevicesCollection; 304 VBoxHidLeds_t *hidLedsCollection; 305 CFIndex cDevices; 302 IOHIDManagerRef hidManagerRef; 303 IOHIDDeviceRef *hidDevicesCollection; 304 VBoxHidLeds_t *hidLedsCollection; 305 CFIndex cDevices; 306 CFMachPortRef pTapRef; 307 CFRunLoopSourceRef pLoopSourceRef; 306 308 } VBoxHidsState_t; 309 310 /* A *sync* between IOKit and Carbon callbacks. */ 311 static VBoxHidLeds_t *g_LastTouchedState; 307 312 #endif // !VBOX_WITH_KBD_LEDS_SYNC 308 313 … … 1358 1363 return rc2; 1359 1364 } 1365 1366 1367 1368 static void darwinHidInputCallback(void *pData, IOReturn unused, void *unused1, IOHIDValueRef valueRef) 1369 { 1370 (void)unused; 1371 (void)unused1; 1372 1373 IOHIDElementRef pElementRef = IOHIDValueGetElement(valueRef); 1374 1375 if (IOHIDElementGetUsagePage(pElementRef) == kHIDPage_KeyboardOrKeypad) /* Keyboard or keypad event */ 1376 if (IOHIDValueGetIntegerValue(valueRef) == 1) /* key has been pressed down */ 1377 if (IOHIDElementGetUsage(pElementRef) == kHIDUsage_KeyboardCapsLock || /* CapsLock key has been pressed */ 1378 IOHIDElementGetUsage(pElementRef) == kHIDUsage_KeypadNumLock) /* ... or NumLock key has been pressed */ 1379 { 1380 Log2(("A modifier key has been pressed\n")); 1381 g_LastTouchedState = (VBoxHidLeds_t *)pData; 1382 } 1383 } 1384 1385 #define VBOX_BOOL_TO_STR_STATE(x) (x) ? "ON" : "OFF" 1386 static CGEventRef darwinCarbonGlobalKeyPressCallback(CGEventTapProxy unused, CGEventType type, CGEventRef pEventRef, void *unused1) 1387 { 1388 (void)unused; 1389 (void)unused1; 1390 1391 /* Skip events we are not interested in. */ 1392 if (type != kCGEventKeyDown && type != kCGEventFlagsChanged) 1393 return pEventRef; 1394 1395 CGEventFlags fMask = CGEventGetFlags(pEventRef); 1396 bool fCaps = (bool)(fMask & NX_ALPHASHIFTMASK); 1397 bool fNum = (bool)(fMask & NX_NUMERICPADMASK); 1398 CGKeyCode key = CGEventGetIntegerValueField(pEventRef, kCGKeyboardEventKeycode); 1399 1400 if (key == kHIDUsage_KeyboardCapsLock || 1401 key == kHIDUsage_KeypadNumLock) 1402 { 1403 Log2(("carbon event: caps=%s, num=%s\n", VBOX_BOOL_TO_STR_STATE(fCaps), VBOX_BOOL_TO_STR_STATE(fNum))); 1404 if (g_LastTouchedState) 1405 { 1406 g_LastTouchedState->fCapsLockOn = fCaps; 1407 g_LastTouchedState->fNumLockOn = fNum; 1408 } 1409 } 1410 1411 return pEventRef; 1412 } 1413 #undef VBOX_BOOL_TO_STR_STATE 1414 1415 static int darwinAddCarbonGlobalKeyPressHandler(VBoxHidsState_t *pState) 1416 { 1417 CFMachPortRef pTapRef; 1418 CGEventMask fMask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventFlagsChanged); 1419 1420 g_LastTouchedState = NULL; 1421 1422 pTapRef = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0, fMask, darwinCarbonGlobalKeyPressCallback, NULL); 1423 if (pTapRef) 1424 { 1425 CFRunLoopSourceRef pLoopSourceRef; 1426 pLoopSourceRef = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, pTapRef, 0); 1427 if (pLoopSourceRef) 1428 { 1429 CFRunLoopAddSource(CFRunLoopGetCurrent(), pLoopSourceRef, kCFRunLoopCommonModes); 1430 CGEventTapEnable(pTapRef, true); 1431 1432 pState->pTapRef = pTapRef; 1433 pState->pLoopSourceRef = pLoopSourceRef; 1434 1435 return 0; 1436 } 1437 else 1438 Log2(("Unable to create a loop source\n")); 1439 1440 CFRelease(pTapRef); 1441 } 1442 else 1443 Log2(("Unable to create an event tap\n")); 1444 1445 return kIOReturnError; 1446 } 1447 1448 static void darwinRemoveCarbonGlobalKeyPressHandler(VBoxHidsState_t *pState) 1449 { 1450 AssertReturnVoid(pState); 1451 AssertReturnVoid(pState->pTapRef); 1452 AssertReturnVoid(pState->pLoopSourceRef); 1453 1454 g_LastTouchedState = NULL; 1455 1456 CGEventTapEnable(pState->pTapRef, false); 1457 CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pState->pLoopSourceRef, kCFRunLoopCommonModes); 1458 CFRelease(pState->pLoopSourceRef); 1459 } 1460 1360 1461 #endif // !VBOX_WITH_KBD_LEDS_SYNC 1361 1462 … … 1419 1520 } 1420 1521 1522 /* Register per-device input callback */ 1523 IOHIDDeviceRegisterInputValueCallback(hidsState->hidDevicesCollection[i], darwinHidInputCallback, (void *)&hidsState->hidLedsCollection[i]); 1524 IOHIDDeviceScheduleWithRunLoop(hidsState->hidDevicesCollection[i], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 1421 1525 } 1422 1526 } 1423 1527 1424 CFRelease(deviceMatchingDictRef);1425 1528 CFRelease(elementMatchingDict); 1426 1529 1427 return hidsState; 1530 if (darwinAddCarbonGlobalKeyPressHandler(hidsState) == 0) 1531 { 1532 CFRelease(deviceMatchingDictRef); 1533 return hidsState; 1534 } 1428 1535 } 1429 1536 … … 1472 1579 if (hidsState) 1473 1580 { 1581 /* Need to unregister Carbon stuff first */ 1582 darwinRemoveCarbonGlobalKeyPressHandler(hidsState); 1583 1474 1584 CFDictionaryRef elementMatchingDict = darwinGetLedElementMatchingDictionary(); 1475 1585 if (elementMatchingDict) … … 1488 1598 rc2 = kIOReturnError; 1489 1599 } 1600 1601 IOHIDDeviceRegisterInputValueCallback(hidsState->hidDevicesCollection[i], NULL, NULL); 1602 IOHIDDeviceUnscheduleFromRunLoop(hidsState->hidDevicesCollection[i], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); 1490 1603 } 1491 1604 }
Note:
See TracChangeset
for help on using the changeset viewer.