Panda3D
ioKitInputDeviceManager.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file ioKitInputDeviceManager.cxx
10  * @author rdb
11  * @date 2018-02-04
12  */
13 
15 #include "ioKitInputDevice.h"
16 
17 #if defined(__APPLE__) && !defined(CPPPARSER)
18 
19 /**
20  * Initializes the input device manager by scanning which devices are currently
21  * connected and setting up any platform-dependent structures necessary for
22  * listening for future device connect events.
23  */
24 IOKitInputDeviceManager::
25 IOKitInputDeviceManager() {
26  _hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
27  if (!_hid_manager) {
28  device_cat.error()
29  << "Failed to create an IOHIDManager.\n";
30  return;
31  }
32 
33  // The types of devices we're interested in.
34  int page = kHIDPage_GenericDesktop;
35  int usages[] = {kHIDUsage_GD_GamePad,
36  kHIDUsage_GD_Joystick,
37  kHIDUsage_GD_Mouse,
38  kHIDUsage_GD_Keyboard,
39  kHIDUsage_GD_MultiAxisController, 0};
40  int *usage = usages;
41 
42  // This giant mess is necessary to create an array of match dictionaries
43  // that will match the devices we're interested in.
44  CFMutableArrayRef match = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
45  nassertv(match);
46  while (*usage) {
47  CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
48  CFNumberRef page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
49  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), page_ref);
50  CFRelease(page_ref);
51  CFNumberRef usage_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, usage);
52  CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), usage_ref);
53  CFRelease(usage_ref);
54  CFArrayAppendValue(match, dict);
55  CFRelease(dict);
56  ++usage;
57  }
58  IOHIDManagerSetDeviceMatchingMultiple(_hid_manager, match);
59  CFRelease(match);
60 
61  IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this);
62  IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
63  IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone);
64 }
65 
66 /**
67  * Closes any resources that the device manager was using to listen for events.
68  */
69 IOKitInputDeviceManager::
70 ~IOKitInputDeviceManager() {
71  IOHIDManagerUnscheduleFromRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
72  IOHIDManagerClose(_hid_manager, kIOHIDOptionsTypeNone);
73  CFRelease(_hid_manager);
74 }
75 
76 /**
77  * Called by IOKit when an input device matching our filters has been found.
78  */
79 void IOKitInputDeviceManager::
80 on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) {
82  nassertv(mgr != nullptr);
83  nassertv(device);
84 
85  PT(InputDevice) input_device = new IOKitInputDevice(device);
86  if (device_cat.is_debug()) {
87  device_cat.debug()
88  << "Discovered input device " << *input_device << "\n";
89  }
90  mgr->add_device(input_device);
91 }
92 
93 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class keeps track of all the devices on a system, and sends out events when a device has been ho...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a structure representing a single input device.
Definition: inputDevice.h:53
void add_device(InputDevice *device)
Called when a new device has been discovered.