Bladeren bron

input: split out macOS implementation of device manager

rdb 7 jaren geleden
bovenliggende
commit
6ada306184

+ 4 - 58
panda/src/device/inputDeviceManager.cxx

@@ -12,77 +12,21 @@
  */
 
 #include "inputDeviceManager.h"
-#include "ioKitInputDevice.h"
+#include "ioKitInputDeviceManager.h"
 #include "linuxInputDeviceManager.h"
 #include "winInputDeviceManager.h"
 #include "throw_event.h"
 
-InputDeviceManager *InputDeviceManager::_global_ptr = NULL;
+InputDeviceManager *InputDeviceManager::_global_ptr = nullptr;
 
 /**
  * Initializes the input device manager by scanning which devices are currently
  * connected and setting up any platform-dependent structures necessary for
  * listening for future device connect events.
  */
-#if defined(__APPLE__)
-InputDeviceManager::
-InputDeviceManager() {
-  _hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-  if (!_hid_manager) {
-    device_cat.error()
-      << "Failed to create an IOHIDManager.\n";
-    return;
-  }
-
-  // The types of devices we're interested in.
-  int page = kHIDPage_GenericDesktop;
-  int usages[] = {kHIDUsage_GD_GamePad,
-                  kHIDUsage_GD_Joystick,
-                  kHIDUsage_GD_Mouse,
-                  kHIDUsage_GD_Keyboard,
-                  kHIDUsage_GD_MultiAxisController, 0};
-  int *usage = usages;
-
-  // This giant mess is necessary to create an array of match dictionaries
-  // that will match the devices we're interested in.
-  CFMutableArrayRef match = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-  nassertv(match);
-  while (*usage) {
-    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    CFNumberRef page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
-    CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), page_ref);
-    CFRelease(page_ref);
-    CFNumberRef usage_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, usage);
-    CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), usage_ref);
-    CFRelease(usage_ref);
-    CFArrayAppendValue(match, dict);
-    CFRelease(dict);
-    ++usage;
-  }
-  IOHIDManagerSetDeviceMatchingMultiple(_hid_manager, match);
-  CFRelease(match);
-
-  IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this);
-  IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
-  IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone);
-}
-#else
 InputDeviceManager::
 InputDeviceManager() : _lock("InputDeviceManager") {
 }
-#endif
-
-/**
- * Closes any resources that the device manager was using to listen for events.
- */
-InputDeviceManager::
-~InputDeviceManager() {
-#if defined(__APPLE__)
-  IOHIDManagerUnscheduleFromRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
-  IOHIDManagerClose(_hid_manager, kIOHIDOptionsTypeNone);
-  CFRelease(_hid_manager);
-#endif
-}
 
 /**
  * Creates the global input manager.
@@ -91,6 +35,8 @@ void InputDeviceManager::
 make_global_ptr() {
 #ifdef _WIN32
   _global_ptr = new WinInputDeviceManager;
+#elif defined(__APPLE__)
+  _global_ptr = new IOKitInputDeviceManager;
 #elif defined(PHAVE_LINUX_INPUT_H)
   _global_ptr = new LinuxInputDeviceManager;
 #else

+ 0 - 16
panda/src/device/inputDeviceManager.h

@@ -24,10 +24,6 @@
 class WinRawInputDevice;
 #endif
 
-#ifdef __APPLE__
-#include <IOKit/hid/IOHIDManager.h>
-#endif
-
 /**
  * This class keeps track of all the devices on a system, and sends out events
  * when a device has been hot-plugged.
@@ -35,15 +31,9 @@ class WinRawInputDevice;
 class EXPCL_PANDA_DEVICE InputDeviceManager {
 protected:
   InputDeviceManager();
-  ~InputDeviceManager();
 
   static void make_global_ptr();
 
-#ifdef PHAVE_LINUX_INPUT_H
-  InputDevice *consider_add_evdev_device(int index);
-  InputDevice *consider_add_js_device(int index);
-#endif
-
 PUBLISHED:
   InputDeviceSet get_devices() const;
   InputDeviceSet get_devices(InputDevice::DeviceClass device_class) const;
@@ -65,12 +55,6 @@ protected:
   InputDeviceSet _inactive_devices;
 #endif
 
-#if defined(__APPLE__) && !defined(CPPPARSER)
-  IOHIDManagerRef _hid_manager;
-
-  static void on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device);
-#endif
-
   InputDeviceSet _connected_devices;
 
   static InputDeviceManager *_global_ptr;

+ 93 - 0
panda/src/device/ioKitInputDeviceManager.cxx

@@ -0,0 +1,93 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file ioKitInputDeviceManager.cxx
+ * @author rdb
+ * @date 2018-02-04
+ */
+
+#include "ioKitInputDeviceManager.h"
+#include "ioKitInputDevice.h"
+
+#if defined(__APPLE__) && !defined(CPPPARSER)
+
+/**
+ * Initializes the input device manager by scanning which devices are currently
+ * connected and setting up any platform-dependent structures necessary for
+ * listening for future device connect events.
+ */
+IOKitInputDeviceManager::
+IOKitInputDeviceManager() {
+  _hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+  if (!_hid_manager) {
+    device_cat.error()
+      << "Failed to create an IOHIDManager.\n";
+    return;
+  }
+
+  // The types of devices we're interested in.
+  int page = kHIDPage_GenericDesktop;
+  int usages[] = {kHIDUsage_GD_GamePad,
+                  kHIDUsage_GD_Joystick,
+                  kHIDUsage_GD_Mouse,
+                  kHIDUsage_GD_Keyboard,
+                  kHIDUsage_GD_MultiAxisController, 0};
+  int *usage = usages;
+
+  // This giant mess is necessary to create an array of match dictionaries
+  // that will match the devices we're interested in.
+  CFMutableArrayRef match = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+  nassertv(match);
+  while (*usage) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFNumberRef page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
+    CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), page_ref);
+    CFRelease(page_ref);
+    CFNumberRef usage_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, usage);
+    CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), usage_ref);
+    CFRelease(usage_ref);
+    CFArrayAppendValue(match, dict);
+    CFRelease(dict);
+    ++usage;
+  }
+  IOHIDManagerSetDeviceMatchingMultiple(_hid_manager, match);
+  CFRelease(match);
+
+  IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this);
+  IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
+  IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone);
+}
+
+/**
+ * Closes any resources that the device manager was using to listen for events.
+ */
+IOKitInputDeviceManager::
+~IOKitInputDeviceManager() {
+  IOHIDManagerUnscheduleFromRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
+  IOHIDManagerClose(_hid_manager, kIOHIDOptionsTypeNone);
+  CFRelease(_hid_manager);
+}
+
+/**
+ * Called by IOKit when an input device matching our filters has been found.
+ */
+void IOKitInputDeviceManager::
+on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) {
+  InputDeviceManager *mgr = (InputDeviceManager *)ctx;
+  nassertv(mgr != nullptr);
+  nassertv(device);
+
+  PT(InputDevice) input_device = new IOKitInputDevice(device);
+  if (device_cat.is_debug()) {
+    device_cat.debug()
+      << "Discovered input device " << *input_device << "\n";
+  }
+  mgr->add_device(input_device);
+}
+
+#endif

+ 40 - 0
panda/src/device/ioKitInputDeviceManager.h

@@ -0,0 +1,40 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file ioKitInputDeviceManager.h
+ * @author rdb
+ * @date 2018-02-04
+ */
+
+#ifndef IOKITINPUTDEVICEMANAGER_H
+#define IOKITINPUTDEVICEMANAGER_H
+
+#include "inputDeviceManager.h"
+
+#if defined(__APPLE__) && !defined(CPPPARSER)
+#include <IOKit/hid/IOHIDManager.h>
+
+/**
+ * The macOS implementation of InputDeviceManager.
+ */
+class EXPCL_PANDA_DEVICE IOKitInputDeviceManager FINAL : public InputDeviceManager {
+protected:
+  IOKitInputDeviceManager();
+  ~IOKitInputDeviceManager();
+
+protected:
+  IOHIDManagerRef _hid_manager;
+
+  static void on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device);
+
+  friend class InputDeviceManager;
+};
+
+#endif
+
+#endif

+ 1 - 0
panda/src/device/p3device_composite1.cxx

@@ -11,6 +11,7 @@
 #include "inputDeviceNode.cxx"
 #include "inputDeviceSet.cxx"
 #include "ioKitInputDevice.cxx"
+#include "ioKitInputDeviceManager.cxx"
 #include "linuxInputDeviceManager.cxx"
 #include "linuxJoystickDevice.cxx"
 #include "winInputDeviceManager.cxx"