VirtualBox

Changeset 48517 in vbox for trunk


Ignore:
Timestamp:
Sep 18, 2013 1:43:27 PM (11 years ago)
Author:
vboxsync
Message:

Mac OS host LEDs sync: when in VM - broadcast LEDs state to all attached KBDs, when switching to host - restore aech KBD leds separately.

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  
    288288#endif /* USE_HID_FOR_MODIFIERS */
    289289
     290/* HID LEDs synchronization data: LED states. */
     291typedef struct VBoxHidLeds_t {
     292    bool             fNumLockOn;
     293    bool             fCapsLockOn;
     294    bool             fScrollLockOn;
     295} VBoxHidLeds_t;
     296
     297/* HID LEDs synchronization data: IOKit specific data. */
     298typedef struct VBoxHidsState_t {
     299    IOHIDManagerRef  hidManagerRef;
     300    IOHIDDeviceRef  *hidDevicesCollection;
     301    VBoxHidLeds_t   *hidLedsCollection;
     302    CFIndex          cDevices;
     303} VBoxHidsState_t;
     304
    290305
    291306/*******************************************************************************
     
    12041219
    12051220/** Turn ON or OFF a particular LED. */
    1206 static void darwinLedElementSetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool fEnabled)
     1221static int darwinLedElementSetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool fEnabled)
    12071222{
    12081223    IOHIDValueRef valueRef;
    1209     IOReturn      rc;
     1224    IOReturn      rc = kIOReturnError;
    12101225
    12111226    valueRef = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, (fEnabled) ? 1 : 0);
     
    12201235        CFRelease(valueRef);
    12211236    }
     1237
     1238    return rc;
     1239}
     1240
     1241/** Get state of a particular led. */
     1242static 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;
    12221266}
    12231267
    12241268/** Set corresponding states from NumLock, CapsLock and ScrollLock leds. */
    1225 static void darwinUpdateHostLedDeviceElements(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict,
    1226                                               bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
     1269static int darwinSetDeviceLedsState(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict,
     1270                                    bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
    12271271{
    12281272    CFArrayRef matchingElementsArrayRef;
     1273    int        rc2 = 0;
    12291274
    12301275    matchingElementsArrayRef = IOHIDDeviceCopyMatchingElements(hidDevice, elementMatchingDict, 0);
     
    12381283            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(matchingElementsArrayRef, i);
    12391284            uint32_t        usage   = IOHIDElementGetUsage(element);
     1285            int             rc = 0;
    12401286
    12411287            switch (usage)
    12421288            {
    12431289                case kHIDUsage_LED_NumLock:
    1244                     darwinLedElementSetValue(hidDevice, element, fNumLockOn);
     1290                    rc = darwinLedElementSetValue(hidDevice, element, fNumLockOn);
    12451291                    break;
    12461292
    12471293                case kHIDUsage_LED_CapsLock:
    1248                     darwinLedElementSetValue(hidDevice, element, fCapsLockOn);
     1294                    rc = darwinLedElementSetValue(hidDevice, element, fCapsLockOn);
    12491295                    break;
    12501296
    12511297                case kHIDUsage_LED_ScrollLock:
    1252                     darwinLedElementSetValue(hidDevice, element, fScrollLockOn);
     1298                    rc = darwinLedElementSetValue(hidDevice, element, fScrollLockOn);
    12531299                    break;
    12541300            }
    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. */
     1314static 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. */
     1358void * 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 */
     1455int 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;
    12581498}
    12591499
     
    12681508 * @param fScrollLockOn     Turn on ScrollLock led if TRUE, turn off otherwise
    12691509 */
    1270 void DarwinUpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
     1510void DarwinHidDevicesBroadcastLeds(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
    12711511{
    12721512    IOReturn        rc;
     
    13011541                            for (CFIndex i = 0; i < cDevices; i++)
    13021542                            {
    1303                                 if (hidDevicesCollection[i])
     1543                                if (IOHIDDeviceConformsTo(hidDevicesCollection[i], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
    13041544                                {
    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));
    13101549                                }
    13111550                            }
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.h

    r48496 r48517  
    4747void     DarwinReleaseKeyboard(void);
    4848
    49 void     DarwinUpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn);
     49void   * DarwinHidDevicesKeepLedsState(void);
     50int      DarwinHidDevicesApplyAndReleaseLedsState(void *pState);
     51void     DarwinHidDevicesBroadcastLeds(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn);
    5052
    5153RT_C_DECLS_END
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r48516 r48517  
    490490    LogRelFlow(("UIMachineLogic::sltKeyboardLedsChanged: Updating host LED lock states (NOT IMPLEMENTED).\n"));
    491491#ifdef Q_WS_MAC
    492     //DarwinUpdateHostLedDevices(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock());
     492    DarwinHidDevicesBroadcastLeds(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock());
    493493#endif
    494494}
     
    567567    , m_pDockPreviewSelectMonitorGroup(0)
    568568    , m_DockIconPreviewMonitor(0)
     569    , m_hostLedsState(NULL)
    569570#endif /* Q_WS_MAC */
    570571{
     
    21902191    /* Here we have to update host LED lock states using values provided by UISession registry.
    21912192     * [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 */
    21922198}
    21932199
     
    22012207
    22022208    /* 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 */
    22032216}
    22042217
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.h

    r48504 r48517  
    268268    QActionGroup *m_pDockPreviewSelectMonitorGroup;
    269269    int m_DockIconPreviewMonitor;
     270    void *m_hostLedsState;
    270271#endif /* Q_WS_MAC */
    271272
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette