- Timestamp:
- Sep 18, 2013 1:43:27 PM (11 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
r48502 r48517 288 288 #endif /* USE_HID_FOR_MODIFIERS */ 289 289 290 /* HID LEDs synchronization data: LED states. */ 291 typedef struct VBoxHidLeds_t { 292 bool fNumLockOn; 293 bool fCapsLockOn; 294 bool fScrollLockOn; 295 } VBoxHidLeds_t; 296 297 /* HID LEDs synchronization data: IOKit specific data. */ 298 typedef struct VBoxHidsState_t { 299 IOHIDManagerRef hidManagerRef; 300 IOHIDDeviceRef *hidDevicesCollection; 301 VBoxHidLeds_t *hidLedsCollection; 302 CFIndex cDevices; 303 } VBoxHidsState_t; 304 290 305 291 306 /******************************************************************************* … … 1204 1219 1205 1220 /** Turn ON or OFF a particular LED. */ 1206 static voiddarwinLedElementSetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool fEnabled)1221 static int darwinLedElementSetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool fEnabled) 1207 1222 { 1208 1223 IOHIDValueRef valueRef; 1209 IOReturn rc ;1224 IOReturn rc = kIOReturnError; 1210 1225 1211 1226 valueRef = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, (fEnabled) ? 1 : 0); … … 1220 1235 CFRelease(valueRef); 1221 1236 } 1237 1238 return rc; 1239 } 1240 1241 /** Get state of a particular led. */ 1242 static int darwinLedElementGetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool *fEnabled) 1243 { 1244 IOHIDValueRef valueRef; 1245 IOReturn rc; 1246 CFIndex integerValue; 1247 1248 rc = IOHIDDeviceGetValue(hidDevice, element, &valueRef); 1249 if (rc == kIOReturnSuccess) 1250 { 1251 integerValue = IOHIDValueGetIntegerValue(valueRef); 1252 switch (integerValue) 1253 { 1254 case 0: 1255 *fEnabled = false; 1256 break; 1257 case 1: 1258 *fEnabled = true; 1259 break; 1260 default: 1261 rc = kIOReturnError; 1262 } 1263 } 1264 1265 return rc; 1222 1266 } 1223 1267 1224 1268 /** Set corresponding states from NumLock, CapsLock and ScrollLock leds. */ 1225 static void darwinUpdateHostLedDeviceElements(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict,1226 1269 static int darwinSetDeviceLedsState(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict, 1270 bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn) 1227 1271 { 1228 1272 CFArrayRef matchingElementsArrayRef; 1273 int rc2 = 0; 1229 1274 1230 1275 matchingElementsArrayRef = IOHIDDeviceCopyMatchingElements(hidDevice, elementMatchingDict, 0); … … 1238 1283 IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(matchingElementsArrayRef, i); 1239 1284 uint32_t usage = IOHIDElementGetUsage(element); 1285 int rc = 0; 1240 1286 1241 1287 switch (usage) 1242 1288 { 1243 1289 case kHIDUsage_LED_NumLock: 1244 darwinLedElementSetValue(hidDevice, element, fNumLockOn);1290 rc = darwinLedElementSetValue(hidDevice, element, fNumLockOn); 1245 1291 break; 1246 1292 1247 1293 case kHIDUsage_LED_CapsLock: 1248 darwinLedElementSetValue(hidDevice, element, fCapsLockOn);1294 rc = darwinLedElementSetValue(hidDevice, element, fCapsLockOn); 1249 1295 break; 1250 1296 1251 1297 case kHIDUsage_LED_ScrollLock: 1252 darwinLedElementSetValue(hidDevice, element, fScrollLockOn);1298 rc = darwinLedElementSetValue(hidDevice, element, fScrollLockOn); 1253 1299 break; 1254 1300 } 1255 1256 } 1257 } 1301 if (rc != 0) 1302 { 1303 Log2(("Failed to set led (%d) state\n", (int)IOHIDElementGetUsage(element))); 1304 rc2 = kIOReturnError; 1305 } 1306 1307 } 1308 } 1309 1310 return rc2; 1311 } 1312 1313 /** Get corresponding states for NumLock, CapsLock and ScrollLock leds. */ 1314 static int darwinGetDeviceLedsState(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict, 1315 bool *fNumLockOn, bool *fCapsLockOn, bool *fScrollLockOn) 1316 { 1317 CFArrayRef matchingElementsArrayRef; 1318 int rc2 = 0; 1319 1320 matchingElementsArrayRef = IOHIDDeviceCopyMatchingElements(hidDevice, elementMatchingDict, 0); 1321 if (matchingElementsArrayRef) 1322 { 1323 CFIndex cElements = CFArrayGetCount(matchingElementsArrayRef); 1324 1325 /* Cycle though all the elements we found */ 1326 for (CFIndex i = 0; i < cElements; i++) 1327 { 1328 IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(matchingElementsArrayRef, i); 1329 uint32_t usage = IOHIDElementGetUsage(element); 1330 int rc = 0; 1331 1332 switch (usage) 1333 { 1334 case kHIDUsage_LED_NumLock: 1335 rc = darwinLedElementGetValue(hidDevice, element, fNumLockOn); 1336 break; 1337 1338 case kHIDUsage_LED_CapsLock: 1339 rc = darwinLedElementGetValue(hidDevice, element, fCapsLockOn); 1340 break; 1341 1342 case kHIDUsage_LED_ScrollLock: 1343 rc = darwinLedElementGetValue(hidDevice, element, fScrollLockOn); 1344 break; 1345 } 1346 if (rc != 0) 1347 { 1348 Log2(("Failed to get led (%d) state\n", (int)IOHIDElementGetUsage(element))); 1349 rc2 = kIOReturnError; 1350 } 1351 } 1352 } 1353 1354 return rc2; 1355 } 1356 1357 /** Save the states of leds for all HID devices attached to the system and return it. */ 1358 void * DarwinHidDevicesKeepLedsState(void) 1359 { 1360 IOReturn rc; 1361 VBoxHidsState_t *hidsState; 1362 1363 hidsState = (VBoxHidsState_t *)RTMemAllocZ(sizeof(VBoxHidsState_t)); 1364 if (hidsState) 1365 { 1366 hidsState->hidManagerRef = IOHIDManagerCreate(kCFAllocatorDefault, 0); 1367 if (hidsState->hidManagerRef) 1368 { 1369 1370 CFDictionaryRef deviceMatchingDictRef = darwinGetLedDeviceMatchingDictionary(); 1371 if (deviceMatchingDictRef) 1372 { 1373 IOHIDManagerSetDeviceMatching(hidsState->hidManagerRef, deviceMatchingDictRef); 1374 1375 rc = IOHIDManagerOpen(hidsState->hidManagerRef, kIOHIDOptionsTypeNone); 1376 if (rc == kIOReturnSuccess) 1377 { 1378 CFSetRef hidDevicesSetRef; 1379 1380 hidDevicesSetRef = IOHIDManagerCopyDevices(hidsState->hidManagerRef); 1381 if (hidDevicesSetRef) 1382 { 1383 /* Get all the available devices and cycle through them. */ 1384 hidsState->cDevices = CFSetGetCount(hidDevicesSetRef); 1385 hidsState->hidDevicesCollection = (IOHIDDeviceRef *)RTMemAllocZ((size_t)hidsState->cDevices * sizeof(IOHIDDeviceRef)); 1386 if (hidsState->hidDevicesCollection) 1387 { 1388 hidsState->hidLedsCollection = (VBoxHidLeds_t *)RTMemAllocZ((size_t)hidsState->cDevices * sizeof(VBoxHidLeds_t)); 1389 if (hidsState->hidLedsCollection) 1390 { 1391 CFSetGetValues(hidDevicesSetRef, (const void **)hidsState->hidDevicesCollection); 1392 1393 CFDictionaryRef elementMatchingDict = darwinGetLedElementMatchingDictionary(); 1394 if (elementMatchingDict) 1395 { 1396 for (CFIndex i = 0; i < hidsState->cDevices; i++) 1397 { 1398 if (IOHIDDeviceConformsTo(hidsState->hidDevicesCollection[i], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) 1399 { 1400 rc = darwinGetDeviceLedsState(hidsState->hidDevicesCollection[i], 1401 elementMatchingDict, 1402 &hidsState->hidLedsCollection[i].fNumLockOn, 1403 &hidsState->hidLedsCollection[i].fCapsLockOn, 1404 &hidsState->hidLedsCollection[i].fScrollLockOn); 1405 /* This should never happen, but if happened -- mark all the leds of current 1406 * device as turned OFF. */ 1407 if (rc != 0) 1408 { 1409 Log2(("Unable to get leds state for device %d. Mark leds as turned off\n", (int)i)); 1410 hidsState->hidLedsCollection[i].fNumLockOn = 1411 hidsState->hidLedsCollection[i].fCapsLockOn = 1412 hidsState->hidLedsCollection[i].fScrollLockOn = false; 1413 } 1414 1415 } 1416 } 1417 1418 CFRelease(deviceMatchingDictRef); 1419 CFRelease(elementMatchingDict); 1420 1421 return hidsState; 1422 } 1423 1424 RTMemFree(hidsState->hidLedsCollection); 1425 } 1426 1427 RTMemFree(hidsState->hidDevicesCollection); 1428 } 1429 } 1430 1431 rc = IOHIDManagerClose(hidsState->hidManagerRef, 0); 1432 if (rc != kIOReturnSuccess) 1433 LogRelFlow(("Warning! Something went wrong in attempt to close HID device manager!\n")); 1434 } 1435 1436 CFRelease(deviceMatchingDictRef); 1437 } 1438 1439 CFRelease(hidsState->hidManagerRef); 1440 } 1441 1442 RTMemFree(hidsState); 1443 } 1444 1445 return NULL; 1446 } 1447 1448 /** 1449 * Apply LEDs state stored in *pState and release resources aquired by *pState. 1450 * 1451 * @param pState Pointer to saved LEDs state 1452 * 1453 * @return 0 on success, error code otherwise. 1454 */ 1455 int DarwinHidDevicesApplyAndReleaseLedsState(void *pState) 1456 { 1457 VBoxHidsState_t *hidsState = (VBoxHidsState_t *)pState; 1458 1459 CFIndex i; 1460 IOReturn rc, rc2 = 0; 1461 1462 if (hidsState) 1463 { 1464 CFDictionaryRef elementMatchingDict = darwinGetLedElementMatchingDictionary(); 1465 if (elementMatchingDict) 1466 { 1467 /* Restore LEDs */ 1468 for (i = 0; i < hidsState->cDevices; i++) 1469 { 1470 rc = darwinSetDeviceLedsState(hidsState->hidDevicesCollection[i], 1471 elementMatchingDict, 1472 hidsState->hidLedsCollection[i].fNumLockOn, 1473 hidsState->hidLedsCollection[i].fCapsLockOn, 1474 hidsState->hidLedsCollection[i].fScrollLockOn); 1475 if (rc != 0) 1476 { 1477 Log2(("Unable to restore led states for device (%d)!\n", (int)i)); 1478 rc2 = kIOReturnError; 1479 } 1480 } 1481 } 1482 1483 /* Free resources */ 1484 1485 RTMemFree(hidsState->hidLedsCollection); 1486 RTMemFree(hidsState->hidDevicesCollection); 1487 1488 rc = IOHIDManagerClose(hidsState->hidManagerRef, 0); 1489 if (rc != kIOReturnSuccess) 1490 LogRelFlow(("Warning! Something went wrong in attempt to close HID device manager!\n")); 1491 1492 CFRelease(hidsState->hidManagerRef); 1493 1494 RTMemFree(hidsState); 1495 } 1496 1497 return rc2; 1258 1498 } 1259 1499 … … 1268 1508 * @param fScrollLockOn Turn on ScrollLock led if TRUE, turn off otherwise 1269 1509 */ 1270 void Darwin UpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)1510 void DarwinHidDevicesBroadcastLeds(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn) 1271 1511 { 1272 1512 IOReturn rc; … … 1301 1541 for (CFIndex i = 0; i < cDevices; i++) 1302 1542 { 1303 if ( hidDevicesCollection[i])1543 if (IOHIDDeviceConformsTo(hidDevicesCollection[i], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) 1304 1544 { 1305 if (IOHIDDeviceConformsTo(hidDevicesCollection[i], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)) 1306 { 1307 darwinUpdateHostLedDeviceElements(hidDevicesCollection[i], elementMatchingDict, 1308 fNumLockOn, fCapsLockOn, fScrollLockOn); 1309 } 1545 rc = darwinSetDeviceLedsState(hidDevicesCollection[i], elementMatchingDict, 1546 fNumLockOn, fCapsLockOn, fScrollLockOn); 1547 if (rc != 0) 1548 Log2(("Unable to broadcast LEDs state to device (%d)\n", (int)i)); 1310 1549 } 1311 1550 } -
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.h
r48496 r48517 47 47 void DarwinReleaseKeyboard(void); 48 48 49 void DarwinUpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn); 49 void * DarwinHidDevicesKeepLedsState(void); 50 int DarwinHidDevicesApplyAndReleaseLedsState(void *pState); 51 void DarwinHidDevicesBroadcastLeds(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn); 50 52 51 53 RT_C_DECLS_END -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp
r48516 r48517 490 490 LogRelFlow(("UIMachineLogic::sltKeyboardLedsChanged: Updating host LED lock states (NOT IMPLEMENTED).\n")); 491 491 #ifdef Q_WS_MAC 492 //DarwinUpdateHostLedDevices(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock());492 DarwinHidDevicesBroadcastLeds(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock()); 493 493 #endif 494 494 } … … 567 567 , m_pDockPreviewSelectMonitorGroup(0) 568 568 , m_DockIconPreviewMonitor(0) 569 , m_hostLedsState(NULL) 569 570 #endif /* Q_WS_MAC */ 570 571 { … … 2190 2191 /* Here we have to update host LED lock states using values provided by UISession registry. 2191 2192 * [bool] uisession() -> isNumLock(), isCapsLock(), isScrollLock() can be used for that. */ 2193 #ifdef Q_WS_MAC 2194 if (m_hostLedsState == NULL) 2195 m_hostLedsState = DarwinHidDevicesKeepLedsState(); 2196 DarwinHidDevicesBroadcastLeds(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock()); 2197 #endif /* Q_WS_MAC */ 2192 2198 } 2193 2199 … … 2201 2207 2202 2208 /* Here we have to restore host LED lock states. */ 2209 #ifdef Q_WS_MAC 2210 if (m_hostLedsState) 2211 { 2212 DarwinHidDevicesApplyAndReleaseLedsState(m_hostLedsState); 2213 m_hostLedsState = NULL; 2214 } 2215 #endif /* Q_WS_MAC */ 2203 2216 } 2204 2217 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h
r48504 r48517 268 268 QActionGroup *m_pDockPreviewSelectMonitorGroup; 269 269 int m_DockIconPreviewMonitor; 270 void *m_hostLedsState; 270 271 #endif /* Q_WS_MAC */ 271 272
Note:
See TracChangeset
for help on using the changeset viewer.