Changeset 71659 in vbox for trunk/src/VBox/Frontends/VirtualBox
- Timestamp:
- Apr 4, 2018 2:40:21 PM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.cpp
r71027 r71659 1 1 /* $Id$ */ 2 2 /** @file 3 * Common GUI Library - Darwin Keyboard routines. 4 * 5 * @todo Move this up somewhere so that the two SDL GUIs can use parts of this code too (-HID stuff). 3 * VBox Qt GUI - Declarations of utility functions for handling Darwin Keyboard specific tasks. 6 4 */ 7 5 8 6 /* 9 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 10 8 * 11 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 18 16 */ 19 17 20 21 /********************************************************************************************************************************* 22 * Header Files * 23 *********************************************************************************************************************************/ 18 /* Defines: */ 24 19 #define LOG_GROUP LOG_GROUP_GUI 25 26 20 #define VBOX_WITH_KBD_LEDS_SYNC 27 21 //#define VBOX_WITHOUT_KBD_LEDS_SYNC_FILTERING 28 22 23 /* GUI includes: */ 29 24 #include "DarwinKeyboard.h" 25 #ifndef USE_HID_FOR_MODIFIERS 26 # include "CocoaEventHelper.h" 27 #endif 28 29 /* Other VBox includes: */ 30 30 #include <iprt/assert.h> 31 31 #include <iprt/asm.h> 32 #include <iprt/mem.h> 32 33 #include <iprt/time.h> 33 #include <iprt/mem.h>34 34 #include <VBox/log.h> 35 35 #ifdef DEBUG_PRINTF 36 36 # include <iprt/stream.h> 37 37 #endif 38 39 38 #ifdef VBOX_WITH_KBD_LEDS_SYNC 40 39 # include <iprt/err.h> 41 40 # include <iprt/semaphore.h> 42 41 # include <VBox/sup.h> 42 #endif 43 44 /* External includes: */ 45 #include <ApplicationServices/ApplicationServices.h> 46 #include <Carbon/Carbon.h> 47 #include <IOKit/IOCFPlugIn.h> 48 #include <IOKit/IOKitLib.h> 49 #include <IOKit/hid/IOHIDLib.h> 50 #include <IOKit/usb/USB.h> 51 #ifdef USE_HID_FOR_MODIFIERS 52 # include <CoreFoundation/CoreFoundation.h> 53 # include <IOKit/hid/IOHIDUsageTables.h> 54 # include <mach/mach.h> 55 # include <mach/mach_error.h> 56 #endif 57 #ifdef VBOX_WITH_KBD_LEDS_SYNC 43 58 # include <IOKit/IOMessage.h> 44 59 # include <IOKit/usb/IOUSBLib.h> 45 # include <IOKit/IOMessage.h>46 #endif47 48 #ifdef USE_HID_FOR_MODIFIERS49 # include <mach/mach.h>50 # include <mach/mach_error.h>51 # include <IOKit/hid/IOHIDUsageTables.h>52 # include <CoreFoundation/CoreFoundation.h>53 #endif54 55 #include <IOKit/IOKitLib.h>56 #include <IOKit/IOCFPlugIn.h>57 #include <IOKit/usb/USB.h>58 #include <IOKit/hid/IOHIDLib.h>59 #include <ApplicationServices/ApplicationServices.h>60 #include <Carbon/Carbon.h>61 62 #ifndef USE_HID_FOR_MODIFIERS63 # include "CocoaEventHelper.h"64 60 #endif 65 61 … … 81 77 82 78 83 /********************************************************************************************************************************* 84 * Defined Constants And Macros * 85 *********************************************************************************************************************************/ 86 79 /* Defined Constants And Macros: */ 87 80 #define QZ_RMETA 0x36 88 81 #define QZ_LMETA 0x37 … … 94 87 #define QZ_RALT 0x3D 95 88 #define QZ_RCTRL 0x3E 96 / *Found the definition of the fn-key in:97 *http://stuff.mit.edu/afs/sipb/project/darwin/src/modules/IOHIDFamily/IOHIDSystem/IOHIKeyboardMapper.cpp &98 *http://stuff.mit.edu/afs/sipb/project/darwin/src/modules/AppleADBKeyboard/AppleADBKeyboard.cpp99 * Maybe we need this in the future.*/ 89 // Found the definition of the fn-key in: 90 // http://stuff.mit.edu/afs/sipb/project/darwin/src/modules/IOHIDFamily/IOHIDSystem/IOHIKeyboardMapper.cpp & 91 // http://stuff.mit.edu/afs/sipb/project/darwin/src/modules/AppleADBKeyboard/AppleADBKeyboard.cpp 92 // Maybe we need this in the future. 100 93 #define QZ_FN 0x3F 101 94 #define QZ_NUMLOCK 0x47 102 103 /** short hand for an extended key. */ 95 /** Short hand for an extended key. */ 104 96 #define K_EX VBOXKEY_EXTENDED 105 /** short hand for a modifier key. */97 /** Short hand for a modifier key. */ 106 98 #define K_MOD VBOXKEY_MODIFIER 107 /** short hand for a lock key. */99 /** Short hand for a lock key. */ 108 100 #define K_LOCK VBOXKEY_LOCK 109 110 101 #ifdef USE_HID_FOR_MODIFIERS 111 112 102 /** An attempt at catching reference leaks. */ 113 #define MY_CHECK_CREFS(cRefs) do { AssertMsg(cRefs < 25, ("%ld\n", cRefs)); NOREF(cRefs); } while (0) 114 103 # define MY_CHECK_CREFS(cRefs) do { AssertMsg(cRefs < 25, ("%ld\n", cRefs)); NOREF(cRefs); } while (0) 115 104 #endif 116 105 117 106 118 /********************************************************************************************************************************* 119 * Global Variables * 120 *********************************************************************************************************************************/ 121 /** 122 * This is derived partially from SDL_QuartzKeys.h and partially from testing. 123 * 124 * (The funny thing about the virtual scan codes on the mac is that they aren't 125 * offically documented, which is rather silly to say the least. Thus, the need 126 * for looking at SDL and other odd places for docs.) 127 */ 107 /** This is derived partially from SDL_QuartzKeys.h and partially from testing. 108 * (The funny thing about the virtual scan codes on the mac is that they aren't 109 * offically documented, which is rather silly to say the least. Thus, the need 110 * for looking at SDL and other odd places for docs.) */ 128 111 static const uint16_t g_aDarwinToSet1[] = 129 112 { 130 /* set-1 SDL_QuartzKeys.h*/113 /* set-1 SDL_QuartzKeys.h */ 131 114 0x1e, /* QZ_a 0x00 */ 132 115 0x1f, /* QZ_s 0x01 */ … … 263 246 264 247 265 /** Whether we've connected or not. */248 /** Holds whether we've connected or not. */ 266 249 static bool g_fConnectedToCGS = false; 267 /** Cached connection. */250 /** Holds the cached connection. */ 268 251 static CGSConnection g_CGSConnection; 269 252 … … 271 254 #ifdef USE_HID_FOR_MODIFIERS 272 255 273 /** The IO Master Port. */256 /** Holds the IO Master Port. */ 274 257 static mach_port_t g_MasterPort = NULL; 275 258 276 /** Keyboards in the cache. */259 /** Holds the amount of keyboards in the cache. */ 277 260 static unsigned g_cKeyboards = 0; 278 261 /** Array of cached keyboard data. */ … … 284 267 IOHIDQueueInterface **ppHidQueueInterface; 285 268 286 /* cookie translation array. */269 /** Cookie translation array. */ 287 270 struct KeyboardCacheCookie 288 271 { … … 295 278 unsigned cCookies; 296 279 } g_aKeyboards[128]; 297 /** The keyboard cache creation timestamp. */280 /** Holds the keyboard cache creation timestamp. */ 298 281 static uint64_t g_u64KeyboardTS = 0; 299 282 300 /** H ID queue status. */283 /** Holds the HID queue status. */ 301 284 static bool g_fHIDQueueEnabled; 302 /** The current modifier mask. */285 /** Holds the current modifier mask. */ 303 286 static uint32_t g_fHIDModifierMask; 304 /** The old modifier mask. */287 /** Holds the old modifier mask. */ 305 288 static uint32_t g_fOldHIDModifierMask; 306 289 307 290 #endif /* USE_HID_FOR_MODIFIERS */ 308 291 292 309 293 #ifdef VBOX_WITH_KBD_LEDS_SYNC 310 294 311 295 #define VBOX_BOOL_TO_STR_STATE(x) (x) ? "ON" : "OFF" 312 /* HID LEDs synchronization data: LED states. */ 313 typedef struct VBoxLedState_t { 314 bool fNumLockOn; /** A state of NUM LOCK */ 315 bool fCapsLockOn; /** A state of CAPS LOCK */ 316 bool fScrollLockOn; /** A state of SCROLL LOCK */ 296 /** HID LEDs synchronization data: LED states. */ 297 typedef struct VBoxLedState_t 298 { 299 /** Holds the state of NUM LOCK. */ 300 bool fNumLockOn; 301 /** Holds the state of CAPS LOCK. */ 302 bool fCapsLockOn; 303 /** Holds the state of SCROLL LOCK. */ 304 bool fScrollLockOn; 317 305 } VBoxLedState_t; 318 306 319 /* HID LEDs synchronization data: keyboard states. */ 320 typedef struct VBoxKbdState_t { 321 IOHIDDeviceRef pDevice; /** A reference to IOKit HID device */ 322 VBoxLedState_t LED; /** LED states */ 323 void *pParentContainer; /** A pointer to a VBoxHidsState_t instance where VBoxKbdState_t instance is stored */ 324 CFIndex idxPosition; /** Position in global storage (used to simplify CFArray navigation when removing detached device) */ 325 uint64_t cCapsLockTimeout; /** KBD CAPS LOCK key hold timeout (some Apple keyboards only) */ 326 uint32_t idLocation; /** HID Location ID: unique for an USB device registered in the system */ 307 /** HID LEDs synchronization data: keyboard states. */ 308 typedef struct VBoxKbdState_t 309 { 310 /** Holds the reference to IOKit HID device. */ 311 IOHIDDeviceRef pDevice; 312 /** Holds the LED states. */ 313 VBoxLedState_t LED; 314 /** Holds the pointer to a VBoxHidsState_t instance where VBoxKbdState_t instance is stored. */ 315 void *pParentContainer; 316 /** Holds the position in global storage (used to simplify CFArray navigation when removing detached device). */ 317 CFIndex idxPosition; 318 /** Holds the KBD CAPS LOCK key hold timeout (some Apple keyboards only). */ 319 uint64_t cCapsLockTimeout; 320 /** Holds the HID Location ID: unique for an USB device registered in the system. */ 321 uint32_t idLocation; 327 322 } VBoxKbdState_t; 328 323 329 /* A struct that used to pass input event info from IOKit callback to a Carbon one */ 330 typedef struct VBoxKbdEvent_t { 324 /** A struct that used to pass input event info from IOKit callback to a Carbon one */ 325 typedef struct VBoxKbdEvent_t 326 { 331 327 VBoxKbdState_t *pKbd; 332 328 uint32_t iKeyCode; … … 334 330 } VBoxKbdEvent_t; 335 331 336 /* HID LEDs synchronization data: IOKit specific data. */ 337 typedef struct VBoxHidsState_t { 338 IOHIDManagerRef hidManagerRef; /** IOKit HID manager reference */ 339 CFMutableArrayRef pDeviceCollection; /** This array consists of VBoxKbdState_t elements */ 340 VBoxLedState_t guestState; /** LED states that were stored during last broadcast and reflect a guest LED states */ 341 342 CFMutableArrayRef pFifoEventQueue; /** This queue will be appended in IOKit input callback. Carbon input callback will extract data from it */ 343 RTSEMMUTEX fifoEventQueueLock; /** Lock for pFifoEventQueue */ 344 345 io_iterator_t pUsbHidDeviceMatchNotify; /** IOService notification reference: USB HID device matching */ 346 io_iterator_t pUsbHidGeneralInterestNotify; /** IOService notification reference: USB HID general interest 347 notifications (IOService messages) */ 348 IONotificationPortRef pNotificationPrortRef; /** IOService notification port reference: used for both notification 349 types - device match and device general interest message */ 350 351 /* Carbon events data */ 332 /** HID LEDs synchronization data: IOKit specific data. */ 333 typedef struct VBoxHidsState_t 334 { 335 /** Holds the IOKit HID manager reference. */ 336 IOHIDManagerRef hidManagerRef; 337 /** Holds the array which consists of VBoxKbdState_t elements. */ 338 CFMutableArrayRef pDeviceCollection; 339 /** Holds the LED states that were stored during last broadcast and reflect a guest LED states. */ 340 VBoxLedState_t guestState; 341 342 /** Holds the queue which will be appended in IOKit input callback. Carbon input callback will extract data from it. */ 343 CFMutableArrayRef pFifoEventQueue; 344 /** Holds the lock for pFifoEventQueue. */ 345 RTSEMMUTEX fifoEventQueueLock; 346 347 /** Holds the IOService notification reference: USB HID device matching. */ 348 io_iterator_t pUsbHidDeviceMatchNotify; 349 /** Holds the IOService notification reference: USB HID general interest notifications (IOService messages). */ 350 io_iterator_t pUsbHidGeneralInterestNotify; 351 /** Holds the IOService notification port reference: device match and device general interest message. */ 352 IONotificationPortRef pNotificationPrortRef; 353 352 354 CFMachPortRef pTapRef; 353 355 CFRunLoopSourceRef pLoopSourceRef; 354 356 } VBoxHidsState_t; 355 #endif /* !VBOX_WITH_KBD_LEDS_SYNC */ 356 357 358 /********************************************************************************************************************************* 359 * Internal Functions * 360 *********************************************************************************************************************************/ 361 #ifdef USE_HID_FOR_MODIFIERS 362 static void darwinBruteForcePropertySearch(CFDictionaryRef DictRef, struct KeyboardCacheData *pKeyboardEntry); 363 #endif 364 365 366 /** 367 * Converts a darwin (virtual) key code to a set 1 scan code. 368 * 369 * @returns set 1 scan code. 370 * @param uKeyCode The darwin key code. 371 */ 357 358 #endif /* VBOX_WITH_KBD_LEDS_SYNC */ 359 360 372 361 unsigned DarwinKeycodeToSet1Scancode(unsigned uKeyCode) 373 362 { … … 377 366 } 378 367 379 380 /** 381 * Converts a single modifier to a set 1 scan code. 382 * 383 * @returns Set 1 scan code. 384 * @returns ~0U if more than one modifier is set. 385 * @param fModifiers The darwin modifier mask. 386 */ 368 UInt32 DarwinAdjustModifierMask(UInt32 fModifiers, const void *pvCocoaEvent) 369 { 370 /* Check if there is anything to adjust and perform the adjustment. */ 371 if (fModifiers & (shiftKey | rightShiftKey | controlKey | rightControlKey | optionKey | rightOptionKey | cmdKey | kEventKeyModifierRightCmdKeyMask)) 372 { 373 #ifndef USE_HID_FOR_MODIFIERS 374 // WORKAROUND: 375 // Convert the Cocoa modifiers to Carbon ones (the Cocoa modifier 376 // definitions are tucked away in Objective-C headers, unfortunately). 377 // 378 // Update: CGEventTypes.h includes what looks like the Cocoa modifiers 379 // and the NX_* defines should be available as well. We should look 380 // into ways to intercept the CG (core graphics) events in the Carbon 381 // based setup and get rid of all this HID mess. */ 382 AssertPtr(pvCocoaEvent); 383 //::darwinPrintEvent("dbg-adjMods: ", pvCocoaEvent); 384 uint32_t fAltModifiers = ::darwinEventModifierFlagsXlated(pvCocoaEvent); 385 #else /* USE_HID_FOR_MODIFIERS */ 386 /* Update the keyboard cache. */ 387 darwinHIDKeyboardCacheUpdate(); 388 const UInt32 fAltModifiers = g_fHIDModifierMask; 389 #endif /* USE_HID_FOR_MODIFIERS */ 390 391 #ifdef DEBUG_PRINTF 392 RTPrintf("dbg-fAltModifiers=%#x fModifiers=%#x", fAltModifiers, fModifiers); 393 #endif 394 if ( (fModifiers & (rightShiftKey | shiftKey)) 395 && (fAltModifiers & (rightShiftKey | shiftKey))) 396 { 397 fModifiers &= ~(rightShiftKey | shiftKey); 398 fModifiers |= fAltModifiers & (rightShiftKey | shiftKey); 399 } 400 401 if ( (fModifiers & (rightControlKey | controlKey)) 402 && (fAltModifiers & (rightControlKey | controlKey))) 403 { 404 fModifiers &= ~(rightControlKey | controlKey); 405 fModifiers |= fAltModifiers & (rightControlKey | controlKey); 406 } 407 408 if ( (fModifiers & (optionKey | rightOptionKey)) 409 && (fAltModifiers & (optionKey | rightOptionKey))) 410 { 411 fModifiers &= ~(optionKey | rightOptionKey); 412 fModifiers |= fAltModifiers & (optionKey | rightOptionKey); 413 } 414 415 if ( (fModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask)) 416 && (fAltModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask))) 417 { 418 fModifiers &= ~(cmdKey | kEventKeyModifierRightCmdKeyMask); 419 fModifiers |= fAltModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask); 420 } 421 #ifdef DEBUG_PRINTF 422 RTPrintf(" -> %#x\n", fModifiers); 423 #endif 424 } 425 return fModifiers; 426 } 427 387 428 unsigned DarwinModifierMaskToSet1Scancode(UInt32 fModifiers) 388 429 { … … 395 436 } 396 437 397 398 /**399 * Converts a single modifier to a darwin keycode.400 *401 * @returns Darwin keycode.402 * @returns 0 if none of the support masks were set.403 * @returns ~0U if more than one modifier is set.404 * @param fModifiers The darwin modifier mask.405 */406 438 unsigned DarwinModifierMaskToDarwinKeycode(UInt32 fModifiers) 407 439 { … … 440 472 } 441 473 442 443 /**444 * Converts a darwin keycode to a modifier mask.445 *446 * @returns Darwin modifier mask.447 * @returns 0 if the keycode isn't a modifier we know.448 * @param uKeyCode The darwin449 */450 474 UInt32 DarwinKeyCodeToDarwinModifierMask(unsigned uKeyCode) 451 475 { … … 481 505 482 506 483 /**484 * Disables or enabled global hot keys.485 *486 * @param fDisable Pass 'true' to disable the hot keys, pass 'false' to re-enable them.487 */488 507 void DarwinDisableGlobalHotKeys(bool fDisable) 489 508 { 490 509 static unsigned s_cComplaints = 0; 491 510 492 /* 493 * Lazy connect to the core graphics service. 494 */ 511 /* Lazy connect to the core graphics service. */ 495 512 if (!g_fConnectedToCGS) 496 513 { … … 499 516 } 500 517 501 /* 502 * Get the current mode. 503 */ 518 /* Get the current mode. */ 504 519 CGSGlobalHotKeyOperatingMode enmMode = kCGSGlobalHotKeyInvalid; 505 520 CGSGetGlobalHotKeyOperatingMode(g_CGSConnection, &enmMode); … … 514 529 } 515 530 516 /* 517 * Calc the new mode. 518 */ 531 /* Calc the new mode. */ 519 532 if (fDisable) 520 533 { … … 530 543 } 531 544 532 /* 533 * Try set it and check the actual result. 534 */ 545 /* Try set it and check the actual result. */ 535 546 CGSSetGlobalHotKeyOperatingMode(g_CGSConnection, enmMode); 536 547 CGSGlobalHotKeyOperatingMode enmNewMode = kCGSGlobalHotKeyInvalid; … … 545 556 } 546 557 558 547 559 #ifdef USE_HID_FOR_MODIFIERS 548 560 549 /** 550 * Callback function for consuming queued events. 551 * 552 * @param pvTarget queue? 553 * @param rcIn ? 554 * @param pvRefcon Pointer to the keyboard cache entry. 555 * @param pvSender ? 556 */ 561 /** Callback function for consuming queued events. 562 * @param pvTarget Brings the queue? 563 * @param rcIn Brigns what? 564 * @param pvRefcon Brings the pointer to the keyboard cache entry. 565 * @param pvSender Brings what? */ 557 566 static void darwinQueueCallback(void *pvTarget, IOReturn rcIn, void *pvRefcon, void *pvSender) 558 567 { … … 564 573 NOREF(pvSender); 565 574 566 /* 567 * Consume the events. 568 */ 575 /* Consume the events. */ 569 576 g_fOldHIDModifierMask = g_fHIDModifierMask; 570 577 for (;;) … … 592 599 } 593 600 594 /* 595 * Adjust the modifier mask. 596 * 597 * Note that we don't bother to deal with anyone pressing the same modifier 598 * on 2 or more keyboard. That's not worth the effort involved. 599 */ 601 /* Adjust the modifier mask. */ 600 602 if (Event.value) 601 603 g_fHIDModifierMask |= fMask; … … 611 613 } 612 614 613 614 615 /** 616 * Element enumeration callback. 617 */ 615 /* Forward declaration for darwinBruteForcePropertySearch. */ 616 static void darwinBruteForcePropertySearch(CFDictionaryRef DictRef, struct KeyboardCacheData *pKeyboardEntry); 617 618 /** Element enumeration callback. */ 618 619 static void darwinBruteForcePropertySearchApplier(const void *pvValue, void *pvCacheEntry) 619 620 { … … 622 623 } 623 624 624 625 /** 626 * Recurses thru the keyboard properties looking for certain keys. 627 * 628 * @remark Yes, this can probably be done in a more efficient way. If you 629 * know how to do this, don't hesitate to let us know! 630 */ 625 /** Recurses through the keyboard properties looking for certain keys. */ 631 626 static void darwinBruteForcePropertySearch(CFDictionaryRef DictRef, struct KeyboardCacheData *pKeyboardEntry) 632 627 { 633 628 CFTypeRef ObjRef; 634 629 635 /* 636 * Check for the usage page and usage key we want. 637 */ 630 /* Check for the usage page and usage key we want. */ 638 631 long lUsage; 639 632 ObjRef = CFDictionaryGetValue(DictRef, CFSTR(kIOHIDElementUsageKey)); … … 667 660 } 668 661 669 /* 670 * Get the cookie and modifier mask. 671 */ 662 /* Get the cookie and modifier mask. */ 672 663 long lCookie; 673 664 ObjRef = CFDictionaryGetValue(DictRef, CFSTR(kIOHIDElementCookieKey)); … … 691 682 } 692 683 693 /* 694 * If we've got a queue, add the cookie to the queue. 695 */ 684 /* If we've got a queue, add the cookie to the queue. */ 696 685 if (pKeyboardEntry->ppHidQueueInterface) 697 686 { … … 703 692 } 704 693 705 /* 706 * Add the cookie to the keyboard entry. 707 */ 694 /* Add the cookie to the keyboard entry. */ 708 695 pKeyboardEntry->aCookies[pKeyboardEntry->cCookies].Cookie = (IOHIDElementCookie)lCookie; 709 696 pKeyboardEntry->aCookies[pKeyboardEntry->cCookies].fMask = fMask; … … 715 702 716 703 717 /* 718 * Get the elements key and recursively iterate the elements looking 719 * for they key cookies. 720 */ 704 /* Get the elements key and recursively iterate the elements looking for they key cookies. */ 721 705 ObjRef = CFDictionaryGetValue(DictRef, CFSTR(kIOHIDElementKey)); 722 706 if ( ObjRef … … 729 713 } 730 714 731 732 /** 733 * Creates a keyboard cache entry. 734 * 735 * @returns true if the entry was created successfully, otherwise false. 736 * @param pKeyboardEntry Pointer to the entry. 737 * @param KeyboardDevice The keyboard device to create the entry for. 738 * 739 */ 715 /** Creates a keyboard cache entry. 716 * @param pKeyboardEntry Brings the pointer to the entry. 717 * @param KeyboardDevice Brings the keyboard device to create the entry for. */ 740 718 static bool darwinHIDKeyboardCacheCreateEntry(struct KeyboardCacheData *pKeyboardEntry, io_object_t KeyboardDevice) 741 719 { … … 743 721 memset(pKeyboardEntry, 0, sizeof(*pKeyboardEntry)); 744 722 745 /* 746 * Query the HIDDeviceInterface for this HID (keyboard) object. 747 */ 723 /* Query the HIDDeviceInterface for this HID (keyboard) object. */ 748 724 SInt32 Score = 0; 749 725 IOCFPlugInInterface **ppPlugInInterface = NULL; … … 763 739 if (rc == kIOReturnSuccess) 764 740 { 765 /* 766 * create a removal callback. 767 */ 741 /* Create a removal callback. */ 768 742 /** @todo */ 769 743 770 771 /* 772 * Create the queue so we can insert elements while searching the properties. 773 */ 744 /* Create the queue so we can insert elements while searching the properties. */ 774 745 IOHIDQueueInterface **ppHidQueueInterface = (*ppHidDeviceInterface)->allocQueue(ppHidDeviceInterface); 775 746 if (ppHidQueueInterface) … … 787 758 pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; 788 759 789 /* 790 * Brute force getting of attributes. 791 */ 760 /* Brute force getting of attributes. */ 792 761 /** @todo read up on how to do this in a less resource intensive way! Suggestions are welcome! */ 793 762 CFMutableDictionaryRef PropertiesRef = 0; … … 803 772 if (ppHidQueueInterface) 804 773 { 805 /* 806 * Now install our queue callback. 807 */ 774 /* Now install our queue callback. */ 808 775 CFRunLoopSourceRef RunLoopSrcRef = NULL; 809 776 rc = (*ppHidQueueInterface)->createAsyncEventSource(ppHidQueueInterface, &RunLoopSrcRef); … … 814 781 } 815 782 816 /* 817 * Now install our queue callback. 818 */ 783 /* Now install our queue callback. */ 819 784 rc = (*ppHidQueueInterface)->setEventCallout(ppHidQueueInterface, darwinQueueCallback, ppHidQueueInterface, pKeyboardEntry); 820 785 if (rc != kIOReturnSuccess) … … 822 787 } 823 788 824 /* 825 * Complete the new keyboard cache entry. 826 */ 789 /* Complete the new keyboard cache entry. */ 827 790 pKeyboardEntry->ppHidDeviceInterface = ppHidDeviceInterface; 828 791 pKeyboardEntry->ppHidQueueInterface = ppHidQueueInterface; … … 842 805 } 843 806 844 845 /** 846 * Destroys a keyboard cache entry. 847 * 848 * @param pKeyboardEntry The entry. 849 */ 807 /** Destroys a keyboard cache entry. */ 850 808 static void darwinHIDKeyboardCacheDestroyEntry(struct KeyboardCacheData *pKeyboardEntry) 851 809 { 852 810 unsigned long cRefs; 853 811 854 /* 855 * Destroy the queue 856 */ 812 /* Destroy the queue. */ 857 813 if (pKeyboardEntry->ppHidQueueInterface) 858 814 { … … 860 816 pKeyboardEntry->ppHidQueueInterface = NULL; 861 817 862 /* stop it just in case we haven't done so. doesn't really matter I think. */818 /* Stop it just in case we haven't done so. doesn't really matter I think. */ 863 819 (*ppHidQueueInterface)->stop(ppHidQueueInterface); 864 820 865 /* deal with the run loop source. */821 /* Deal with the run loop source. */ 866 822 CFRunLoopSourceRef RunLoopSrcRef = (*ppHidQueueInterface)->getAsyncEventSource(ppHidQueueInterface); 867 823 if (RunLoopSrcRef) … … 873 829 } 874 830 875 /* dispose of and release the queue. */831 /* Dispose of and release the queue. */ 876 832 (*ppHidQueueInterface)->dispose(ppHidQueueInterface); 877 833 cRefs = (*ppHidQueueInterface)->Release(ppHidQueueInterface); MY_CHECK_CREFS(cRefs); 878 834 } 879 835 880 /* 881 * Release the removal hook? 882 */ 836 /* Release the removal hook? */ 883 837 /** @todo */ 884 838 885 /* 886 * Close and release the device interface. 887 */ 839 /* Close and release the device interface. */ 888 840 if (pKeyboardEntry->ppHidDeviceInterface) 889 841 { … … 896 848 } 897 849 898 899 /** 900 * Zap the keyboard cache. 901 */ 850 /** Zap the keyboard cache. */ 902 851 static void darwinHIDKeyboardCacheZap(void) 903 852 { 904 /* 905 * Release the old cache data first. 906 */ 853 /* Release the old cache data first. */ 907 854 while (g_cKeyboards > 0) 908 855 { … … 912 859 } 913 860 914 915 /** 916 * Updates the cached keyboard data. 917 * 918 * @todo The current implementation is very brute force... 919 * Rewrite it so that it doesn't flush the cache completely but simply checks whether 920 * anything has changed in the HID config. With any luck, there might even be a callback 921 * or something we can poll for HID config changes... 922 * setRemovalCallback() is a start... 923 */ 861 /** Updates the cached keyboard data. 862 * @todo The current implementation is very brute force... 863 * Rewrite it so that it doesn't flush the cache completely but simply checks whether 864 * anything has changed in the HID config. With any luck, there might even be a callback 865 * or something we can poll for HID config changes... 866 * setRemovalCallback() is a start... */ 924 867 static void darwinHIDKeyboardCacheDoUpdate(void) 925 868 { 926 869 g_u64KeyboardTS = RTTimeMilliTS(); 927 870 928 /* 929 * Dispense with the old cache data. 930 */ 871 /* Dispense with the old cache data. */ 931 872 darwinHIDKeyboardCacheZap(); 932 873 933 /* 934 * Open the master port on the first invocation. 935 */ 874 /* Open the master port on the first invocation. */ 936 875 if (!g_MasterPort) 937 876 { … … 940 879 } 941 880 942 /* 943 * Create a matching dictionary for searching for keyboards devices. 944 */ 881 /* Create a matching dictionary for searching for keyboards devices. */ 945 882 static const UInt32 s_Page = kHIDPage_GenericDesktop; 946 883 static const UInt32 s_Usage = kHIDUsage_GD_Keyboard; … … 952 889 CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &s_Usage)); 953 890 954 /* 955 * Perform the search and get a collection of keyboard devices. 956 */ 891 /* Perform the search and get a collection of keyboard devices. */ 957 892 io_iterator_t Keyboards = NULL; 958 893 IOReturn rc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &Keyboards); … … 960 895 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */ 961 896 962 /* 963 * Enumerate the keyboards and query the cache data. 964 */ 897 /* Enumerate the keyboards and query the cache data. */ 965 898 unsigned i = 0; 966 899 io_object_t KeyboardDevice; … … 977 910 } 978 911 979 980 /** 981 * Updates the keyboard cache if it's time to do it again. 982 */ 912 /** Updates the keyboard cache if it's time to do it again. */ 983 913 static void darwinHIDKeyboardCacheUpdate(void) 984 914 { … … 988 918 } 989 919 990 991 /** 992 * Queries the modifier keys from the (IOKit) HID Manager. 993 * 994 * @returns Carbon modifier mask with right/left set correctly. 995 */ 920 /** Queries the modifier keys from the (IOKit) HID Manager. */ 996 921 static UInt32 darwinQueryHIDModifiers(void) 997 922 { 998 /* 999 * Iterate thru the keyboards collecting their modifier masks. 1000 */ 923 /* Iterate thru the keyboards collecting their modifier masks. */ 1001 924 UInt32 fHIDModifiers = 0; 1002 925 unsigned i = g_cKeyboards; … … 1029 952 #endif /* USE_HID_FOR_MODIFIERS */ 1030 953 1031 /** 1032 * Left / right adjust the modifier mask using the current 1033 * keyboard state. 1034 * 1035 * @returns left/right adjusted fModifiers. 1036 * @param fModifiers The mask to adjust. 1037 * @param pvCocoaEvent The associated Cocoa keyboard event. This is NULL 1038 * when using HID for modifier corrections. 1039 * 1040 */ 1041 UInt32 DarwinAdjustModifierMask(UInt32 fModifiers, const void *pvCocoaEvent) 1042 { 1043 /* 1044 * Check if there is anything to adjust and perform the adjustment. 1045 */ 1046 if (fModifiers & (shiftKey | rightShiftKey | controlKey | rightControlKey | optionKey | rightOptionKey | cmdKey | kEventKeyModifierRightCmdKeyMask)) 1047 { 1048 #ifndef USE_HID_FOR_MODIFIERS 1049 /* 1050 * Convert the Cocoa modifiers to Carbon ones (the Cocoa modifier 1051 * definitions are tucked away in Objective-C headers, unfortunately). 1052 * 1053 * Update: CGEventTypes.h includes what looks like the Cocoa modifiers 1054 * and the NX_* defines should be available as well. We should look 1055 * into ways to intercept the CG (core graphics) events in the Carbon 1056 * based setup and get rid of all this HID mess. 1057 */ 1058 AssertPtr(pvCocoaEvent); 1059 //::darwinPrintEvent("dbg-adjMods: ", pvCocoaEvent); 1060 uint32_t fAltModifiers = ::darwinEventModifierFlagsXlated(pvCocoaEvent); 1061 1062 #else /* USE_HID_FOR_MODIFIERS */ 1063 /* 1064 * Update the keyboard cache. 1065 */ 1066 darwinHIDKeyboardCacheUpdate(); 1067 const UInt32 fAltModifiers = g_fHIDModifierMask; 1068 1069 #endif /* USE_HID_FOR_MODIFIERS */ 1070 #ifdef DEBUG_PRINTF 1071 RTPrintf("dbg-fAltModifiers=%#x fModifiers=%#x", fAltModifiers, fModifiers); 1072 #endif 1073 if ( (fModifiers & (rightShiftKey | shiftKey)) 1074 && (fAltModifiers & (rightShiftKey | shiftKey))) 1075 { 1076 fModifiers &= ~(rightShiftKey | shiftKey); 1077 fModifiers |= fAltModifiers & (rightShiftKey | shiftKey); 1078 } 1079 1080 if ( (fModifiers & (rightControlKey | controlKey)) 1081 && (fAltModifiers & (rightControlKey | controlKey))) 1082 { 1083 fModifiers &= ~(rightControlKey | controlKey); 1084 fModifiers |= fAltModifiers & (rightControlKey | controlKey); 1085 } 1086 1087 if ( (fModifiers & (optionKey | rightOptionKey)) 1088 && (fAltModifiers & (optionKey | rightOptionKey))) 1089 { 1090 fModifiers &= ~(optionKey | rightOptionKey); 1091 fModifiers |= fAltModifiers & (optionKey | rightOptionKey); 1092 } 1093 1094 if ( (fModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask)) 1095 && (fAltModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask))) 1096 { 1097 fModifiers &= ~(cmdKey | kEventKeyModifierRightCmdKeyMask); 1098 fModifiers |= fAltModifiers & (cmdKey | kEventKeyModifierRightCmdKeyMask); 1099 } 1100 #ifdef DEBUG_PRINTF 1101 RTPrintf(" -> %#x\n", fModifiers); 1102 #endif 1103 } 1104 return fModifiers; 1105 } 1106 1107 1108 /** 1109 * Start grabbing keyboard events. 1110 * 1111 * This only concerns itself with modifiers and disabling global hotkeys (if requested). 1112 * 1113 * @param fGlobalHotkeys Whether to disable global hotkeys or not. 1114 */ 1115 void DarwinGrabKeyboard(bool fGlobalHotkeys) 954 955 void DarwinGrabKeyboard(bool fGlobalHotkeys) 1116 956 { 1117 957 LogFlow(("DarwinGrabKeyboard: fGlobalHotkeys=%RTbool\n", fGlobalHotkeys)); 1118 958 1119 959 #ifdef USE_HID_FOR_MODIFIERS 1120 /* 1121 * Update the keyboard cache. 1122 */ 960 /* Update the keyboard cache. */ 1123 961 darwinHIDKeyboardCacheUpdate(); 1124 962 1125 /* 1126 * Start the keyboard queues and query the current mask. 1127 */ 963 /* Start the keyboard queues and query the current mask. */ 1128 964 g_fHIDQueueEnabled = true; 1129 965 … … 1138 974 #endif /* USE_HID_FOR_MODIFIERS */ 1139 975 1140 /* 1141 * Disable hotkeys if requested. 1142 */ 976 /* Disable hotkeys if requested. */ 1143 977 if (fGlobalHotkeys) 1144 978 DarwinDisableGlobalHotKeys(true); 1145 979 } 1146 980 1147 1148 /** 1149 * Reverses the actions taken by DarwinGrabKeyboard. 1150 */ 1151 void DarwinReleaseKeyboard(void) 981 void DarwinReleaseKeyboard() 1152 982 { 1153 983 LogFlow(("DarwinReleaseKeyboard\n")); 1154 984 1155 /* 1156 * Re-enable hotkeys. 1157 */ 985 /* Re-enable hotkeys. */ 1158 986 DarwinDisableGlobalHotKeys(false); 1159 987 1160 988 #ifdef USE_HID_FOR_MODIFIERS 1161 /* 1162 * Stop and drain the keyboard queues. 1163 */ 989 /* Stop and drain the keyboard queues. */ 1164 990 g_fHIDQueueEnabled = false; 1165 991 … … 1187 1013 } 1188 1014 #else 1189 1190 /* 1191 * Kill the keyboard cache. 1192 * This will hopefully fix the crash in getElementValue()/fillElementValue()... 1193 */ 1015 /* Kill the keyboard cache. */ 1194 1016 darwinHIDKeyboardCacheZap(); 1195 1017 #endif … … 1200 1022 } 1201 1023 1024 1202 1025 #ifdef VBOX_WITH_KBD_LEDS_SYNC 1203 /** Prepare dictionary that will be used to match HID LED device(s) while discovering. */ 1026 1027 /** Prepares dictionary that will be used to match HID LED device(s) while discovering. */ 1204 1028 static CFDictionaryRef darwinQueryLedDeviceMatchingDictionary() 1205 1029 { 1206 1030 CFDictionaryRef deviceMatchingDictRef; 1207 1031 1208 / *Use two (key, value) pairs:1209 *- (kIOHIDDeviceUsagePageKey, kHIDPage_GenericDesktop),1210 *- (kIOHIDDeviceUsageKey, kHIDUsage_GD_Keyboard). */1032 // Use two (key, value) pairs: 1033 // - (kIOHIDDeviceUsagePageKey, kHIDPage_GenericDesktop), 1034 // - (kIOHIDDeviceUsageKey, kHIDUsage_GD_Keyboard). */ 1211 1035 1212 1036 CFNumberRef usagePageKeyCFNumberRef; int usagePageKeyCFNumberValue = kHIDPage_GenericDesktop; … … 1251 1075 CFDictionaryRef elementMatchingDictRef; 1252 1076 1253 / *Use only one (key, value) pair to match LED device element:1254 *- (kIOHIDElementUsagePageKey, kHIDPage_LEDs). */1077 // Use only one (key, value) pair to match LED device element: 1078 // - (kIOHIDElementUsagePageKey, kHIDPage_LEDs). */ 1255 1079 1256 1080 CFNumberRef usagePageKeyCFNumberRef; int usagePageKeyCFNumberValue = kHIDPage_LEDs; … … 1472 1296 1473 1297 /** Some keyboard devices might freeze after LEDs manipulation. We filter out such devices here. 1474 * In the list below, devices that known to have such issues. If you want to add new device,1475 * then add it here. Currently, we only filter devices by Vendor ID.1476 * In future it might make sense to take Product ID into account as well. */1298 * In the list below, devices that known to have such issues. If you want to add new device, 1299 * then add it here. Currently, we only filter devices by Vendor ID. 1300 * In future it might make sense to take Product ID into account as well. */ 1477 1301 static bool darwinHidDeviceSupported(IOHIDDeviceRef pHidDeviceRef) 1478 1302 { … … 1502 1326 1503 1327 /** IOKit key press callback helper: take care about key-down event. 1504 * This code should be executed within a critical section under pHidState->fifoEventQueueLock. */1328 * This code should be executed within a critical section under pHidState->fifoEventQueueLock. */ 1505 1329 static void darwinHidInputCbKeyDown(VBoxKbdState_t *pKbd, uint32_t iKeyCode, VBoxHidsState_t *pHidState) 1506 1330 { … … 1523 1347 1524 1348 /** IOkit and Carbon key press callbacks helper: CapsLock timeout checker. 1525 *1526 * Returns FALSE if CAPS LOCK timeout not occurred and its state still was not switched (Apple kbd).1527 * Returns TRUE if CAPS LOCK timeout occurred and its state was switched (Apple kbd).1528 * Returns TRUE for non-Apple kbd. */1349 * 1350 * Returns FALSE if CAPS LOCK timeout not occurred and its state still was not switched (Apple kbd). 1351 * Returns TRUE if CAPS LOCK timeout occurred and its state was switched (Apple kbd). 1352 * Returns TRUE for non-Apple kbd. */ 1529 1353 static bool darwinKbdCapsEventMatches(VBoxKbdEvent_t *pEvent, bool fCapsLed) 1530 1354 { 1531 /* CapsLock timeout is only applicable if conditions 1532 * below are satisfied: 1533 * 1534 * a) Key pressed on Apple keyboard 1535 * b) CapsLed is OFF at the moment when CapsLock key is pressed 1536 */ 1355 // CapsLock timeout is only applicable if conditions 1356 // below are satisfied: 1357 // 1358 // a) Key pressed on Apple keyboard 1359 // b) CapsLed is OFF at the moment when CapsLock key is pressed 1537 1360 1538 1361 bool fAppleKeyboard = (pEvent->pKbd->cCapsLockTimeout > 0); … … 1550 1373 1551 1374 /** IOKit key press callback helper: take care about key-up event. 1552 * This code should be executed within a critical section under pHidState->fifoEventQueueLock. */1375 * This code should be executed within a critical section under pHidState->fifoEventQueueLock. */ 1553 1376 static void darwinHidInputCbKeyUp(VBoxKbdState_t *pKbd, uint32_t iKeyCode, VBoxHidsState_t *pHidState) 1554 1377 { … … 1556 1379 VBoxKbdEvent_t *pEvent = NULL; 1557 1380 1558 / *Key-up event assumes that key-down event occured previously. If so, an event1559 * data should be in event queue. Attempt to find it. */1381 // Key-up event assumes that key-down event occured previously. If so, an event 1382 // data should be in event queue. Attempt to find it. 1560 1383 for (CFIndex i = 0; i < CFArrayGetCount(pHidState->pFifoEventQueue); i++) 1561 1384 { … … 1573 1396 if (pEvent) 1574 1397 { 1575 / *NUM LOCK should not have timeout and its press should immidiately trigger Carbon callback.1576 *Therefore, if it is still in queue this is a problem because it was not handled by Carbon callback.1577 * This mean that NUM LOCK is most likely out of sync. */1398 // NUM LOCK should not have timeout and its press should immidiately trigger Carbon callback. 1399 // Therefore, if it is still in queue this is a problem because it was not handled by Carbon callback. 1400 // This mean that NUM LOCK is most likely out of sync. 1578 1401 if (iKeyCode == kHIDUsage_KeypadNumLock) 1579 1402 { … … 1583 1406 else if (iKeyCode == kHIDUsage_KeyboardCapsLock) 1584 1407 { 1585 / *If CAPS LOCK key-press event still not match CAPS LOCK timeout criteria, Carbon callback1586 * should not be triggered for this event at all. Threfore, event should be removed from queue. */1408 // If CAPS LOCK key-press event still not match CAPS LOCK timeout criteria, Carbon callback 1409 // should not be triggered for this event at all. Threfore, event should be removed from queue. 1587 1410 if (!darwinKbdCapsEventMatches(pEvent, pHidState->guestState.fCapsLockOn)) 1588 1411 { … … 1596 1419 else 1597 1420 { 1598 / *CAPS LOCK key-press event matches to CAPS LOCK timeout criteria and still present in queue.1599 *This might mean that Carbon callback was triggered for this event, but cached keyboard state was not updated.1600 *It also might mean that Carbon callback still was not triggered, but it will be soon.1601 * Threfore, CAPS LOCK might be out of sync. */1421 // CAPS LOCK key-press event matches to CAPS LOCK timeout criteria and still present in queue. 1422 // This might mean that Carbon callback was triggered for this event, but cached keyboard state was not updated. 1423 // It also might mean that Carbon callback still was not triggered, but it will be soon. 1424 // Threfore, CAPS LOCK might be out of sync. 1602 1425 LogRel2(("IOHID: KBD %d: Modifier Key-Up event. Key-Down event was triggered %llu ms " 1603 1426 "ago and still was not handled by Carbon callback. CAPS LOCK might out of sync if " … … 1852 1675 1853 1676 /** Get pre-cached KBD device by its Location ID. */ 1854 static VBoxKbdState_t * 1677 static VBoxKbdState_t *darwinUsbHidQueryKbdByLocationId(uint32_t idLocation, VBoxHidsState_t *pHidState) 1855 1678 { 1856 1679 AssertReturn(pHidState, NULL); … … 1987 1810 } 1988 1811 1989 /* Check if we already cached given device */1812 /** Check if we already cached given device */ 1990 1813 static bool darwinIsDeviceInCache(VBoxHidsState_t *pState, IOHIDDeviceRef pDevice) 1991 1814 { … … 2021 1844 pKbd->idLocation = darwinHidLocationId(pDevice); 2022 1845 2023 / *Some Apple keyboards have CAPS LOCK key timeout. According to corresponding2024 *kext plist files, it is equals to 75 ms. For such devices we only add info into our FIFO event2025 * queue if the time between Key-Down and Key-Up events >= 75 ms. */1846 // Some Apple keyboards have CAPS LOCK key timeout. According to corresponding 1847 // kext plist files, it is equals to 75 ms. For such devices we only add info into our FIFO event 1848 // queue if the time between Key-Down and Key-Up events >= 75 ms. 2026 1849 pKbd->cCapsLockTimeout = (darwinHidVendorId(pKbd->pDevice) == kIOUSBVendorIDAppleComputer) ? 75 : 0; 2027 1850 … … 2035 1858 &pKbd->LED.fScrollLockOn); 2036 1859 2037 / *This should never happen, but if happened -- mark all the leds of current2038 * device as turned OFF. */1860 // This should never happen, but if happened -- mark all the leds of current 1861 // device as turned OFF. 2039 1862 if (rc != 0) 2040 1863 { … … 2158 1981 RTSemMutexDestroy(pHidState->fifoEventQueueLock); 2159 1982 } 1983 2160 1984 #endif /* !VBOX_WITH_KBD_LEDS_SYNC */ 2161 1985 2162 /** Save the states of leds for all HID devices attached to the system and return it. */ 2163 void * DarwinHidDevicesKeepLedsState(void)1986 1987 void *DarwinHidDevicesKeepLedsState() 2164 1988 { 2165 1989 #ifdef VBOX_WITH_KBD_LEDS_SYNC … … 2241 2065 } 2242 2066 2243 /** 2244 * Apply LEDs state stored in *pState and release resources aquired by *pState. 2245 * 2246 * @param pState Pointer to saved LEDs state 2247 * 2248 * @return 0 on success, error code otherwise. 2249 */ 2067 2250 2068 int DarwinHidDevicesApplyAndReleaseLedsState(void *pState) 2251 2069 { … … 2258 2076 darwinUsbHidUnsubscribeInterestNotifications(pHidState); 2259 2077 2260 /* Need to unregister Carbon stuff first */2078 /* Need to unregister Carbon stuff first: */ 2261 2079 darwinRemoveCarbonHandler(pHidState); 2262 2080 … … 2264 2082 if (elementMatchingDict) 2265 2083 { 2266 /* Restore LEDs */2084 /* Restore LEDs: */ 2267 2085 for (CFIndex i = 0; i < CFArrayGetCount(pHidState->pDeviceCollection); i++) 2268 2086 { … … 2297 2115 } 2298 2116 2299 /* Free resources */2117 /* Free resources: */ 2300 2118 CFRelease(pHidState->pDeviceCollection); 2301 2119 … … 2317 2135 (void)pState; 2318 2136 return 0; 2319 #endif 2320 } 2321 2322 /** 2323 * Set states for host keyboard LEDs. 2324 * 2325 * NOTE: This function will set led values for all 2326 * keyboard devices attached to the system. 2327 * 2328 * @param pState Pointer to saved LEDs state 2329 * @param fNumLockOn Turn on NumLock led if TRUE, turn off otherwise 2330 * @param fCapsLockOn Turn on CapsLock led if TRUE, turn off otherwise 2331 * @param fScrollLockOn Turn on ScrollLock led if TRUE, turn off otherwise 2332 */ 2137 #endif /* !VBOX_WITH_KBD_LEDS_SYNC */ 2138 } 2139 2333 2140 void DarwinHidDevicesBroadcastLeds(void *pState, bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn) 2334 2141 { 2335 /* Temporary disabled */2336 2142 #ifdef VBOX_WITH_KBD_LEDS_SYNC 2337 2143 VBoxHidsState_t *pHidState = (VBoxHidsState_t *)pState; … … 2370 2176 } 2371 2177 2372 /* Dynamically attached device will use these states */2178 /* Dynamically attached device will use these states: */ 2373 2179 pHidState->guestState.fNumLockOn = fNumLockOn; 2374 2180 pHidState->guestState.fCapsLockOn = fCapsLockOn; 2375 2181 pHidState->guestState.fScrollLockOn = fScrollLockOn; 2376 2377 2182 #else /* !VBOX_WITH_KBD_LEDS_SYNC */ 2378 2183 (void)fNumLockOn; 2379 2184 (void)fCapsLockOn; 2380 2185 (void)fScrollLockOn; 2381 #endif 2382 } 2186 #endif /* !VBOX_WITH_KBD_LEDS_SYNC */ 2187 } 2188 -
trunk/src/VBox/Frontends/VirtualBox/src/platform/darwin/DarwinKeyboard.h
r71027 r71659 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - Common GUI Library - Darwin Keyboard routines. 4 * 5 * @todo Move this up somewhere so that the two SDL GUIs can use this code too. 3 * VBox Qt GUI - Declarations of utility functions for handling Darwin Keyboard specific tasks. 6 4 */ 7 5 8 6 /* 9 * Copyright (C) 2006-201 7Oracle Corporation7 * Copyright (C) 2006-2018 Oracle Corporation 10 8 * 11 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 18 16 */ 19 17 20 21 18 #ifndef ___DarwinKeyboard_h___ 22 19 #define ___DarwinKeyboard_h___ 23 20 21 /* Other VBox includes: */ 24 22 #include <iprt/cdefs.h> 23 24 /* External includes: */ 25 25 #include <CoreFoundation/CFBase.h> 26 26 27 27 28 RT_C_DECLS_BEGIN … … 39 40 #define VBOXKEY_LOCK 0x0800 40 41 42 /** Converts a darwin (virtual) key code to a set 1 scan code. */ 41 43 unsigned DarwinKeycodeToSet1Scancode(unsigned uKeyCode); 44 /** Adjusts the modifier mask left / right using the current keyboard state. */ 42 45 UInt32 DarwinAdjustModifierMask(UInt32 fModifiers, const void *pvCocoaEvent); 46 /** Converts a single modifier to a set 1 scan code. */ 43 47 unsigned DarwinModifierMaskToSet1Scancode(UInt32 fModifiers); 48 /** Converts a single modifier to a darwin keycode. */ 44 49 unsigned DarwinModifierMaskToDarwinKeycode(UInt32 fModifiers); 50 /** Converts a darwin keycode to a modifier mask. */ 45 51 UInt32 DarwinKeyCodeToDarwinModifierMask(unsigned uKeyCode); 52 53 /** Disables or enabled global hot keys. */ 46 54 void DarwinDisableGlobalHotKeys(bool fDisable); 55 56 /** Start grabbing keyboard events. 57 * @param fGlobalHotkeys Brings whether to disable global hotkeys or not. */ 47 58 void DarwinGrabKeyboard(bool fGlobalHotkeys); 48 void DarwinReleaseKeyboard(void); 59 /** Reverses the actions taken by DarwinGrabKeyboard. */ 60 void DarwinReleaseKeyboard(); 49 61 50 void * DarwinHidDevicesKeepLedsState(void); 62 /** Saves the states of leds for all HID devices attached to the system and return it. */ 63 void *DarwinHidDevicesKeepLedsState(); 64 65 /** Applies LEDs @a pState release its resources afterwards. */ 51 66 int DarwinHidDevicesApplyAndReleaseLedsState(void *pState); 67 /** Set states for host keyboard LEDs. 68 * @note This function will set led values for all 69 * keyboard devices attached to the system. 70 * @param pState Brings the pointer to saved LEDs state. 71 * @param fNumLockOn Turns on NumLock led if TRUE, off otherwise 72 * @param fCapsLockOn Turns on CapsLock led if TRUE, off otherwise 73 * @param fScrollLockOn Turns on ScrollLock led if TRUE, off otherwise */ 52 74 void DarwinHidDevicesBroadcastLeds(void *pState, bool fNumLockOn, bool fCapsLockOn, bool fScrollLockOn); 53 75 54 76 RT_C_DECLS_END 55 77 56 #endif57 78 79 #endif /* !___DarwinKeyboard_h___ */ 80
Note:
See TracChangeset
for help on using the changeset viewer.