VirtualBox

Ignore:
Timestamp:
Sep 16, 2013 4:55:57 PM (11 years ago)
Author:
vboxsync
Message:

OS X specfic code for setting keyboard LEDs, disabled obsolete fixModifierState() for Mac platform.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r48495 r48496  
    206206
    207207VirtualBox_LDFLAGS.darwin = \
    208         -framework AppKit -framework Carbon \
     208        -framework AppKit -framework Carbon -framework IOKit \
    209209        $(if $(VBOX_WITH_HARDENING),-install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VirtualBox.dylib)
    210210ifdef VBOX_WITH_ICHAT_THEATER
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp

    r44528 r48496  
    77
    88/*
    9  * Copyright (C) 2006-2011 Oracle Corporation
     9 * Copyright (C) 2006-2013 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2626#include <iprt/asm.h>
    2727#include <iprt/time.h>
     28#include <iprt/mem.h>
    2829#include <VBox/log.h>
    2930#ifdef DEBUG_PRINTF
     
    3637# include <IOKit/IOKitLib.h>
    3738# include <IOKit/IOCFPlugIn.h>
    38 # include <IOKit/hid/IOHIDLib.h>
    3939# include <IOKit/hid/IOHIDUsageTables.h>
    4040# include <IOKit/usb/USB.h>
    4141# include <CoreFoundation/CoreFoundation.h>
    4242#endif
     43#include <IOKit/hid/IOHIDLib.h>
    4344#include <ApplicationServices/ApplicationServices.h>
    4445#include <Carbon/Carbon.h>
     
    11321133}
    11331134
     1135/** Prepare dictionary that will be used to match HID LED device(s) while discovering. */
     1136static CFDictionaryRef darwinGetLedDeviceMatchingDictionary()
     1137{
     1138    CFDictionaryRef deviceMatchingDictRef;
     1139
     1140    /* Use two (key, value) pairs:
     1141     *      - (kIOHIDDeviceUsagePageKey, kHIDPage_GenericDesktop),
     1142     *      - (kIOHIDDeviceUsageKey,     kHIDUsage_GD_Keyboard). */
     1143
     1144    CFNumberRef usagePageKeyCFNumberRef; int usagePageKeyCFNumberValue = kHIDPage_GenericDesktop;
     1145    CFNumberRef usageKeyCFNumberRef;     int usageKeyCFNumberValue     = kHIDUsage_GD_Keyboard;
     1146
     1147    usagePageKeyCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePageKeyCFNumberValue);
     1148    if (usagePageKeyCFNumberRef)
     1149    {
     1150        usageKeyCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usageKeyCFNumberValue);
     1151        if (usageKeyCFNumberRef)
     1152        {
     1153            CFStringRef dictionaryKeys[2] = { CFSTR(kIOHIDDeviceUsagePageKey), CFSTR(kIOHIDDeviceUsageKey) };
     1154            CFNumberRef dictionaryVals[2] = { usagePageKeyCFNumberRef,         usageKeyCFNumberRef         };
     1155
     1156            deviceMatchingDictRef = CFDictionaryCreate(kCFAllocatorDefault,
     1157                                                       (const void **)dictionaryKeys,
     1158                                                       (const void **)dictionaryVals,
     1159                                                       2, /** two (key, value) pairs */
     1160                                                       &kCFTypeDictionaryKeyCallBacks,
     1161                                                       &kCFTypeDictionaryValueCallBacks);
     1162
     1163            CFRelease(usageKeyCFNumberRef);
     1164            CFRelease(usagePageKeyCFNumberRef);
     1165
     1166            return deviceMatchingDictRef;
     1167        }
     1168
     1169        CFRelease(usagePageKeyCFNumberRef);
     1170    }
     1171
     1172    return NULL;
     1173}
     1174
     1175/** Prepare dictionary that will be used to match HID LED device element(s) while discovering. */
     1176static CFDictionaryRef darwinGetLedElementMatchingDictionary()
     1177{
     1178    CFDictionaryRef elementMatchingDictRef;
     1179
     1180    /* Use only one (key, value) pair to match LED device element:
     1181     *      - (kIOHIDElementUsagePageKey, kHIDPage_LEDs).  */
     1182
     1183    CFNumberRef usagePageKeyCFNumberRef; int usagePageKeyCFNumberValue = kHIDPage_LEDs;
     1184
     1185    usagePageKeyCFNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePageKeyCFNumberValue);
     1186    if (usagePageKeyCFNumberRef)
     1187    {
     1188        CFStringRef dictionaryKeys[1] = { CFSTR(kIOHIDElementUsagePageKey), };
     1189        CFNumberRef dictionaryVals[1] = { usagePageKeyCFNumberRef,          };
     1190
     1191        elementMatchingDictRef = CFDictionaryCreate(kCFAllocatorDefault,
     1192                                                    (const void **)dictionaryKeys,
     1193                                                    (const void **)dictionaryVals,
     1194                                                    1, /** one (key, value) pair */
     1195                                                    &kCFTypeDictionaryKeyCallBacks,
     1196                                                    &kCFTypeDictionaryValueCallBacks);
     1197
     1198        CFRelease(usagePageKeyCFNumberRef);
     1199        return elementMatchingDictRef;
     1200    }
     1201
     1202    return NULL;
     1203}
     1204
     1205/** Turn ON or OFF a particular LED. */
     1206static void darwinLedElementSetValue(IOHIDDeviceRef hidDevice, IOHIDElementRef element, bool fEnabled)
     1207{
     1208    IOHIDValueRef valueRef;
     1209    IOReturn      rc;
     1210
     1211    valueRef = IOHIDValueCreateWithIntegerValue(kCFAllocatorDefault, element, 0, (fEnabled) ? 1 : 0);
     1212    if (valueRef)
     1213    {
     1214        rc = IOHIDDeviceSetValue(hidDevice, element, valueRef);
     1215        if (rc != kIOReturnSuccess)
     1216        {
     1217            LogRelFlow(("Warning! Something went wrong in attempt to turn %s HID device led (error %d)!\n", ((fEnabled) ? "on" : "off"), rc));
     1218        }
     1219        else
     1220        {
     1221            LogRelFlow(("Led (%d) is turned %s\n", (int)IOHIDElementGetUsage(element), ((fEnabled) ? "on" : "off")));
     1222        }
     1223
     1224        CFRelease(valueRef);
     1225    }
     1226}
     1227
     1228/** Set corresponding states from NumLock, CapsLock and ScrollLock leds. */
     1229static void darwinUpdateHostLedDeviceElements(IOHIDDeviceRef hidDevice, CFDictionaryRef elementMatchingDict,
     1230                                              bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
     1231{
     1232    CFArrayRef matchingElementsArrayRef;
     1233
     1234    matchingElementsArrayRef = IOHIDDeviceCopyMatchingElements(hidDevice, elementMatchingDict, 0);
     1235    if (matchingElementsArrayRef)
     1236    {
     1237        CFIndex cElements = CFArrayGetCount(matchingElementsArrayRef);
     1238
     1239        /* Cycle though all the elements we found */
     1240        for (CFIndex i = 0; i < cElements; i++)
     1241        {
     1242            IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(matchingElementsArrayRef, i);
     1243            uint32_t        usage   = IOHIDElementGetUsage(element);
     1244
     1245            switch (usage)
     1246            {
     1247                case kHIDUsage_LED_NumLock:
     1248                {
     1249                    darwinLedElementSetValue(hidDevice, element, fNumLockOn);
     1250                    break;
     1251                }
     1252
     1253                case kHIDUsage_LED_CapsLock:
     1254                {
     1255                    darwinLedElementSetValue(hidDevice, element, fCapsLockOn);
     1256                    break;
     1257                }
     1258
     1259                case kHIDUsage_LED_ScrollLock:
     1260                {
     1261                    darwinLedElementSetValue(hidDevice, element, fScrollLockOn);
     1262                    break;
     1263                }
     1264            }
     1265
     1266        }
     1267    }
     1268}
     1269
     1270/**
     1271 * Set states for host keyboard LEDs.
     1272 *
     1273 * NOTE: This function will set led values for all
     1274 * keyboard devices attached to the system.
     1275 *
     1276 * @param fNumLockOn        Turn on NumLock led if TRUE, turn off otherwise
     1277 * @param fCapsLockOn       Turn on CapsLock led if TRUE, turn off otherwise
     1278 * @param fScrollLockOn     Turn on ScrollLock led if TRUE, turn off otherwise
     1279 */
     1280void DarwinUpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn)
     1281{
     1282    IOReturn        rc;
     1283    IOHIDManagerRef hidManagerRef;
     1284
     1285    hidManagerRef = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDManagerOptionNone);
     1286    if (hidManagerRef)
     1287    {
     1288        CFDictionaryRef deviceMatchingDictRef = darwinGetLedDeviceMatchingDictionary();
     1289        if (deviceMatchingDictRef)
     1290        {
     1291            IOHIDManagerSetDeviceMatching(hidManagerRef, deviceMatchingDictRef);
     1292
     1293            rc = IOHIDManagerOpen(hidManagerRef, kIOHIDOptionsTypeNone);
     1294            if (rc == kIOReturnSuccess)
     1295            {
     1296                CFSetRef hidDevicesSetRef;
     1297
     1298                hidDevicesSetRef = IOHIDManagerCopyDevices(hidManagerRef);
     1299                if (hidDevicesSetRef)
     1300                {
     1301                    /* Get all the available devices and cycle through them. */
     1302                    CFIndex cDevices = CFSetGetCount(hidDevicesSetRef);
     1303                    IOHIDDeviceRef *hidDevicesCollection = (IOHIDDeviceRef *)RTMemAllocZ((size_t)cDevices * sizeof(IOHIDDeviceRef));
     1304                    if (hidDevicesCollection)
     1305                    {
     1306                        CFSetGetValues(hidDevicesSetRef, (const void **)hidDevicesCollection);
     1307
     1308                        CFDictionaryRef elementMatchingDict = darwinGetLedElementMatchingDictionary();
     1309                        if (elementMatchingDict)
     1310                        {
     1311                            for (CFIndex i = 0; i < cDevices; i++)
     1312                            {
     1313                                if (hidDevicesCollection[i])
     1314                                {
     1315                                    if (IOHIDDeviceConformsTo(hidDevicesCollection[i], kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard))
     1316                                    {
     1317                                        darwinUpdateHostLedDeviceElements(hidDevicesCollection[i], elementMatchingDict,
     1318                                                                          fNumLockOn, fCapsLockOn, fScrollLockOn);
     1319                                    }
     1320                                }
     1321                            }
     1322
     1323                            CFRelease(elementMatchingDict);
     1324                        }
     1325
     1326                        RTMemFree(hidDevicesCollection);
     1327                    }
     1328                }
     1329
     1330                rc = IOHIDManagerClose(hidManagerRef, 0);
     1331                if (rc != kIOReturnSuccess)
     1332                {
     1333                    LogRelFlow(("Warning! Something went wrong in attempt to close HID device manager!\n"));
     1334                }
     1335            }
     1336
     1337            CFRelease(deviceMatchingDictRef);
     1338        }
     1339
     1340        CFRelease(hidManagerRef);
     1341    }
     1342}
  • trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.h

    r44528 r48496  
    4747void     DarwinReleaseKeyboard(void);
    4848
     49void     DarwinUpdateHostLedDevices(bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn);
     50
    4951RT_C_DECLS_END
    5052
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIKeyboardHandler.cpp

    r47511 r48496  
    11981198         * (NumLock, CapsLock, ScrollLock) as the X server.
    11991199         * If not, send KeyPress events to synchronize the state: */
     1200#if !defined(Q_WS_MAC)
    12001201        if (fFlags & KeyPressed)
    12011202            fixModifierState(pCodes, puCodesCount);
     1203#endif
    12021204
    12031205        /* Prepend 'extended' scancode if needed: */
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineLogic.cpp

    r48386 r48496  
    8080# include <iprt/ldr.h>
    8181#endif /* VBOX_WITH_DEBUGGER_GUI */
     82#ifdef Q_WS_MAC
     83# include "DarwinKeyboard.h"
     84#endif
    8285
    8386/* External includes: */
     
    481484     * [bool] uisession() -> isNumLock(), isCapsLock(), isScrollLock() can be used for that. */
    482485    LogRelFlow(("UIMachineLogic::sltKeyboardLedsChanged: Updating host LED lock states (NOT IMPLEMENTED).\n"));
     486#ifdef Q_WS_MAC
     487    //DarwinUpdateHostLedDevices(uisession()->isNumLock(), uisession()->isCapsLock(), uisession()->isScrollLock());
     488#endif
    483489}
    484490
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