Permalink
Browse files

[osx] add HID device detect for dynamic keymap changing

  • Loading branch information...
1 parent 4275160 commit 2bb8fc140851b0fd488a68c415a08c36c08dd0a2 @davilla davilla committed Jun 17, 2011
@@ -506,12 +506,6 @@
43EA42B0136C2274002C82A5 /* InputOperations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C807114B135DB5CC002F601B /* InputOperations.cpp */; };
7C0A7EC013A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7EBE13A5DBCE00AFC2BD /* AppParamParser.cpp */; };
7C0A7EC113A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7EBE13A5DBCE00AFC2BD /* AppParamParser.cpp */; };
- 7C0A7F7C13A9E69A00AFC2BD /* DirtyRegionSolvers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F7813A9E69A00AFC2BD /* DirtyRegionSolvers.cpp */; };
- 7C0A7F7D13A9E69A00AFC2BD /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F7A13A9E69A00AFC2BD /* DirtyRegionTracker.cpp */; };
- 7C0A7F7E13A9E69A00AFC2BD /* DirtyRegionSolvers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F7813A9E69A00AFC2BD /* DirtyRegionSolvers.cpp */; };
- 7C0A7F7F13A9E69A00AFC2BD /* DirtyRegionTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F7A13A9E69A00AFC2BD /* DirtyRegionTracker.cpp */; };
- 7C0A7F8213A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F8013A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp */; };
- 7C0A7F8313A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C0A7F8013A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp */; };
7C2D6AE40F35453E00DD2E85 /* SpecialProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C2D6AE20F35453E00DD2E85 /* SpecialProtocol.cpp */; };
7C45DBE910F325C400D4BBF3 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */; };
7C45DBEA10F325C400D4BBF3 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */; };
@@ -1159,6 +1153,8 @@
F551107F0F5C424700955236 /* htsmsg_binary.c in Sources */ = {isa = PBXBuildFile; fileRef = F55110730F5C424700955236 /* htsmsg_binary.c */; };
F55110800F5C424700955236 /* htsstr.c in Sources */ = {isa = PBXBuildFile; fileRef = F55110760F5C424700955236 /* htsstr.c */; };
F55110820F5C424700955236 /* net_posix.c in Sources */ = {isa = PBXBuildFile; fileRef = F551107B0F5C424700955236 /* net_posix.c */; };
+ F558F25613ABCF7800631E12 /* WinEventsOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = F558F25513ABCF7800631E12 /* WinEventsOSX.mm */; };
+ F558F25713ABCF7800631E12 /* WinEventsOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = F558F25513ABCF7800631E12 /* WinEventsOSX.mm */; };
F56579AF13060D1E0085ED7F /* RenderCapture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56579AD13060D1E0085ED7F /* RenderCapture.cpp */; };
F56A084B0F4A18FB003F9F87 /* karaokewindowbackground.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F56A084A0F4A18FB003F9F87 /* karaokewindowbackground.cpp */; };
F56C8CE2131F5DAF000AD0F6 /* libc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F56C8CE1131F5DAF000AD0F6 /* libc.dylib */; };
@@ -2384,13 +2380,6 @@
6E97BDC40DA2B620003A2A89 /* Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Socket.h; sourceTree = "<group>"; };
7C0A7EBE13A5DBCE00AFC2BD /* AppParamParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AppParamParser.cpp; sourceTree = "<group>"; };
7C0A7EBF13A5DBCE00AFC2BD /* AppParamParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppParamParser.h; sourceTree = "<group>"; };
- 7C0A7F7713A9E69A00AFC2BD /* DirtyRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirtyRegion.h; sourceTree = "<group>"; };
- 7C0A7F7813A9E69A00AFC2BD /* DirtyRegionSolvers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirtyRegionSolvers.cpp; sourceTree = "<group>"; };
- 7C0A7F7913A9E69A00AFC2BD /* DirtyRegionSolvers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirtyRegionSolvers.h; sourceTree = "<group>"; };
- 7C0A7F7A13A9E69A00AFC2BD /* DirtyRegionTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirtyRegionTracker.cpp; sourceTree = "<group>"; };
- 7C0A7F7B13A9E69A00AFC2BD /* DirtyRegionTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirtyRegionTracker.h; sourceTree = "<group>"; };
- 7C0A7F8013A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIWindowDebugInfo.cpp; sourceTree = "<group>"; };
- 7C0A7F8113A9E6C600AFC2BD /* GUIWindowDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIWindowDebugInfo.h; sourceTree = "<group>"; };
7C2D6AE20F35453E00DD2E85 /* SpecialProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialProtocol.cpp; sourceTree = "<group>"; };
7C2D6AE30F35453E00DD2E85 /* SpecialProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialProtocol.h; sourceTree = "<group>"; };
7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DAVDirectory.cpp; sourceTree = "<group>"; };
@@ -3664,6 +3653,8 @@
F55110770F5C424700955236 /* htsstr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = htsstr.h; sourceTree = "<group>"; };
F551107A0F5C424700955236 /* net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = net.h; sourceTree = "<group>"; };
F551107B0F5C424700955236 /* net_posix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = net_posix.c; sourceTree = "<group>"; };
+ F558F25413ABCF7800631E12 /* WinEventsOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WinEventsOSX.h; sourceTree = "<group>"; };
+ F558F25513ABCF7800631E12 /* WinEventsOSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WinEventsOSX.mm; sourceTree = "<group>"; };
F56579AD13060D1E0085ED7F /* RenderCapture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderCapture.cpp; sourceTree = "<group>"; };
F56579AE13060D1E0085ED7F /* RenderCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderCapture.h; sourceTree = "<group>"; };
F56A08490F4A18FB003F9F87 /* karaokewindowbackground.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = karaokewindowbackground.h; sourceTree = "<group>"; };
@@ -4010,11 +4001,6 @@
18B7C6F81294222D009E7A26 /* D3DResource.h */,
18B7C6F91294222D009E7A26 /* DDSImage.h */,
18B7C6FA1294222D009E7A26 /* DirectXGraphics.h */,
- 7C0A7F7713A9E69A00AFC2BD /* DirtyRegion.h */,
- 7C0A7F7813A9E69A00AFC2BD /* DirtyRegionSolvers.cpp */,
- 7C0A7F7913A9E69A00AFC2BD /* DirtyRegionSolvers.h */,
- 7C0A7F7A13A9E69A00AFC2BD /* DirtyRegionTracker.cpp */,
- 7C0A7F7B13A9E69A00AFC2BD /* DirtyRegionTracker.h */,
18B7C6FB1294222D009E7A26 /* FrameBufferObject.h */,
18B7C6FC1294222D009E7A26 /* Geometry.h */,
18B7C6FD1294222D009E7A26 /* GraphicContext.h */,
@@ -4681,8 +4667,6 @@
children = (
E38E17F00D25F9FA00618676 /* GUIMediaWindow.cpp */,
E38E17F10D25F9FA00618676 /* GUIMediaWindow.h */,
- 7C0A7F8013A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp */,
- 7C0A7F8113A9E6C600AFC2BD /* GUIWindowDebugInfo.h */,
E38E18030D25F9FA00618676 /* GUIWindowFileManager.cpp */,
E38E18040D25F9FA00618676 /* GUIWindowFileManager.h */,
E38E18090D25F9FA00618676 /* GUIWindowHome.cpp */,
@@ -4865,6 +4849,8 @@
43FAC8CE12D63CA800F67914 /* osx */ = {
isa = PBXGroup;
children = (
+ F558F25413ABCF7800631E12 /* WinEventsOSX.h */,
+ F558F25513ABCF7800631E12 /* WinEventsOSX.mm */,
7C779E2C104A57E500F444C4 /* WinSystemOSX.h */,
7C779E2B104A57E500F444C4 /* WinSystemOSX.mm */,
7C779E2E104A57E500F444C4 /* WinSystemOSXGL.h */,
@@ -8053,9 +8039,7 @@
7C0A7EC013A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */,
18B7006113A697270009C1AF /* KeymapLoader.cpp in Sources */,
18B700E113A6A5750009C1AF /* AddonVersion.cpp in Sources */,
- 7C0A7F7C13A9E69A00AFC2BD /* DirtyRegionSolvers.cpp in Sources */,
- 7C0A7F7D13A9E69A00AFC2BD /* DirtyRegionTracker.cpp in Sources */,
- 7C0A7F8213A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp in Sources */,
+ F558F25613ABCF7800631E12 /* WinEventsOSX.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -8946,9 +8930,7 @@
7C0A7EC113A5DBCE00AFC2BD /* AppParamParser.cpp in Sources */,
18B7006213A697270009C1AF /* KeymapLoader.cpp in Sources */,
18B700E213A6A5750009C1AF /* AddonVersion.cpp in Sources */,
- 7C0A7F7E13A9E69A00AFC2BD /* DirtyRegionSolvers.cpp in Sources */,
- 7C0A7F7F13A9E69A00AFC2BD /* DirtyRegionTracker.cpp in Sources */,
- 7C0A7F8313A9E6C600AFC2BD /* GUIWindowDebugInfo.cpp in Sources */,
+ F558F25713ABCF7800631E12 /* WinEventsOSX.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -41,10 +41,15 @@ class CWinEventsBase
#endif
#ifdef _LINUX
-#if defined(__APPLE__) && defined(__arm__)
+#if defined(__APPLE__)
+#if defined(__arm__)
#include "osx/WinEventsIOS.h"
#define CWinEvents CWinEventsIOS
#else
+#include "osx/WinEventsOSX.h"
+#define CWinEvents CWinEventsOSX
+#endif
+#else
#include "WinEventsSDL.h"
#define CWinEvents CWinEventsSDL
#endif
@@ -21,6 +21,7 @@
#include "system.h"
#include "WinEvents.h"
+#include "WinEventsSDL.h"
#include "Application.h"
#ifdef HAS_SDL_JOYSTICK
#include "input/SDLJoystick.h"
@@ -1,4 +1,5 @@
SRCS= \
+ WinEventsOSX \
WinSystemOSX.mm \
WinSystemOSXGL.mm
@@ -0,0 +1,36 @@
+#pragma once
+
+/*
+* Copyright (C) 2011 Team XBMC
+* http://www.xbmc.org
+*
+* This Program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This Program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with XBMC; see the file COPYING. If not, write to
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+* http://www.gnu.org/copyleft/gpl.html
+*
+*/
+
+#include "windowing/WinEvents.h"
+
+class CWinEventsOSX : public CWinEventsBase
+{
+public:
+ CWinEventsOSX();
+ ~CWinEventsOSX();
+
+ static bool MessagePump();
+private:
+ void Initialize(void);
+
+};
@@ -0,0 +1,231 @@
+/*
+* Copyright (C) 2011 Team XBMC
+* http://www.xbmc.org
+*
+* This Program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2, or (at your option)
+* any later version.
+*
+* This Program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with XBMC; see the file COPYING. If not, write to
+* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+* http://www.gnu.org/copyleft/gpl.html
+*
+*/
+
+#include "system.h"
+
+#include "utils/log.h"
+#include "input/KeymapLoader.h"
+#include "windowing/WinEventsSDL.h"
+#include "windowing/osx/WinEventsOSX.h"
+
+#import <CoreFoundation/CFNumber.h>
+#import <IOKit/IOKitLib.h>
+#import <IOKit/IOMessage.h>
+#import <IOKit/IOCFPlugIn.h>
+#import <IOKit/usb/IOUSBLib.h>
+#import <IOKit/hid/IOHIDLib.h>
+#import <IOKit/hid/IOHIDKeys.h>
+#import <libkern/OSTypes.h>
+#import <Carbon/Carbon.h>
+
+// place holder for future native osx event handler
+
+typedef struct USBDevicePrivateData {
+ UInt16 vendorId;
+ UInt16 productId;
+ CStdString deviceName;
+ CStdString keymapDeviceId;
+ io_object_t notification;
+} USBDevicePrivateData;
+
+static IONotificationPortRef g_notify_port = 0;
+static io_iterator_t g_attach_iterator = 0;
+
+CWinEventsOSX::CWinEventsOSX()
+{
+ Initialize();
+}
+
+CWinEventsOSX::~CWinEventsOSX()
+{
+ if (g_notify_port)
+ {
+ // remove the sleep notification port from the application runloop
+ CFRunLoopRemoveSource( CFRunLoopGetCurrent(),
+ IONotificationPortGetRunLoopSource(g_notify_port), kCFRunLoopDefaultMode );
+ IONotificationPortDestroy(g_notify_port);
+ g_notify_port = 0;
+ }
+ if (g_attach_iterator)
+ {
+ IOObjectRelease(g_attach_iterator);
+ g_attach_iterator = 0;
+ }
+}
+
+bool CWinEventsOSX::MessagePump()
+{
+ return CWinEventsSDL::MessagePump();
+}
+
+static void DeviceDetachCallback(void *refCon, io_service_t service, natural_t messageType, void *messageArgument)
+{
+ if (messageType == kIOMessageServiceIsTerminated)
+ {
+ IOReturn result;
+
+ USBDevicePrivateData *privateDataRef = (USBDevicePrivateData*)refCon;
+ CKeymapLoader().DeviceRemoved(privateDataRef->keymapDeviceId);
+ CLog::Log(LOGDEBUG, "HID Device Detach:%s, %s\n",
+ privateDataRef->deviceName.c_str(), privateDataRef->keymapDeviceId.c_str());
+ result = IOObjectRelease(privateDataRef->notification);
+ delete privateDataRef;
+ //release the service
+ result = IOObjectRelease(service);
+ }
+}
+
+static void DeviceAttachCallback(void* refCon, io_iterator_t iterator)
+{
+ io_service_t usbDevice;
+ while ((usbDevice = IOIteratorNext(iterator)))
+ {
+ IOReturn result;
+
+ io_name_t deviceName;
+ result = IORegistryEntryGetName(usbDevice, deviceName);
+ if (result != KERN_SUCCESS)
+ deviceName[0] = '\0';
+
+ SInt32 deviceScore;
+ IOCFPlugInInterface **devicePlugin;
+ result = IOCreatePlugInInterfaceForService(usbDevice,
+ kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &devicePlugin, &deviceScore);
+ if (result != kIOReturnSuccess)
+ {
+ IOObjectRelease(usbDevice);
+ continue;
+ }
+
+ IOUSBDeviceInterface **deviceInterface;
+ // Use the plugin interface to retrieve the device interface.
+ result = (*devicePlugin)->QueryInterface(devicePlugin,
+ CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*)&deviceInterface);
+ if (result != kIOReturnSuccess)
+ {
+ IODestroyPlugInInterface(devicePlugin);
+ IOObjectRelease(usbDevice);
+ continue;
+ }
+
+ // get vendor/product ids
+ UInt16 vendorId;
+ UInt16 productId;
+ result = (*deviceInterface)->GetDeviceVendor( deviceInterface, &vendorId);
+ result = (*deviceInterface)->GetDeviceProduct(deviceInterface, &productId);
+
+ // we only care about usb devices with an HID interface class
+ io_service_t usbInterface;
+ io_iterator_t interface_iterator;
+ IOUSBFindInterfaceRequest request;
+ request.bInterfaceClass = kUSBHIDInterfaceClass;
+ request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
+ request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
+ request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
+ result = (*deviceInterface)->CreateInterfaceIterator(deviceInterface, &request, &interface_iterator);
+ while ((usbInterface = IOIteratorNext(interface_iterator)))
+ {
+ SInt32 interfaceScore;
+ IOCFPlugInInterface **interfacePlugin;
+ //create intermediate plugin for interface access
+ result = IOCreatePlugInInterfaceForService(usbInterface,
+ kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &interfacePlugin, &interfaceScore);
+ if (result != kIOReturnSuccess)
+ {
+ IOObjectRelease(usbInterface);
+ continue;
+ }
+ IOUSBInterfaceInterface** interfaceInterface;
+ result = (*interfacePlugin)->QueryInterface(interfacePlugin,
+ CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), (void**)&interfaceInterface);
+ if (result != kIOReturnSuccess)
+ {
+ IODestroyPlugInInterface(interfacePlugin);
+ IOObjectRelease(usbInterface);
+ continue;
+ }
+
+ // finally we can get to bInterfaceClass/bInterfaceProtocol
+ // we should also check for kHIDKeyboardInterfaceProtocol but
+ // some IR remotes that emulate an HID keyboard do not report this.
+ UInt8 bInterfaceClass;
+ result = (*interfaceInterface)->GetInterfaceClass(interfaceInterface, &bInterfaceClass);
+ if (bInterfaceClass == kUSBHIDInterfaceClass)
+ {
+ USBDevicePrivateData *privateDataRef;
+ privateDataRef = new USBDevicePrivateData;
+ // save some device info to our private data.
+ privateDataRef->vendorId = vendorId;
+ privateDataRef->productId = productId;
+ privateDataRef->deviceName = deviceName;
+ privateDataRef->keymapDeviceId.Format("HID#VID_%04X&PID_%04X", vendorId, productId);
+ // register this usb device for an interest notification callback.
+ result = IOServiceAddInterestNotification(g_notify_port,
+ usbDevice, // service
+ kIOGeneralInterest, // interestType
+ DeviceDetachCallback, // callback
+ privateDataRef, // refCon
+ &privateDataRef->notification // notification
+ );
+ if (result == kIOReturnSuccess)
+ {
+ CKeymapLoader().DeviceAdded(privateDataRef->keymapDeviceId);
+ CLog::Log(LOGDEBUG, "HID Device Attach:%s, %s\n",
+ deviceName, privateDataRef->keymapDeviceId.c_str());
+ }
+
+ // done with this device, only need one notification per device.
+ IODestroyPlugInInterface(interfacePlugin);
+ IOObjectRelease(usbInterface);
+ break;
+ }
+ IODestroyPlugInInterface(interfacePlugin);
+ IOObjectRelease(usbInterface);
+ }
+ IODestroyPlugInInterface(devicePlugin);
+ IOObjectRelease(usbDevice);
+ }
+}
+
+void CWinEventsOSX::Initialize(void)
+{
+ IOReturn result;
+
+ //set up the matching criteria for the devices we're interested in
+ //interested in instances of class IOUSBDevice and its subclasses
+ // match any usb device by not creating matching values in the dict
+ CFMutableDictionaryRef matching_dict = IOServiceMatching(kIOUSBDeviceClassName);
+
+ g_notify_port = IONotificationPortCreate(kIOMasterPortDefault);
+ CFRunLoopSourceRef run_loop_source = IONotificationPortGetRunLoopSource(g_notify_port);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source, kCFRunLoopCommonModes);
+
+ //add a notification callback for attach event
+ result = IOServiceAddMatchingNotification(g_notify_port,
+ kIOFirstMatchNotification, matching_dict, DeviceAttachCallback, NULL, &g_attach_iterator);
+ if (result == kIOReturnSuccess)
+ {
+ //call the callback to 'arm' the notification
+ DeviceAttachCallback(NULL, g_attach_iterator);
+ }
+}
+
+
Oops, something went wrong.

0 comments on commit 2bb8fc1

Please sign in to comment.