8 #include <sys/sysctl.h>
12 #include <mach/mach.h>
13 #include <mach/mach_error.h>
14 #include <IOKit/IOKitLib.h>
15 #include <IOKit/IOCFPlugIn.h>
16 #include <IOKit/hid/IOHIDLib.h>
17 #include <IOKit/hid/IOHIDKeys.h>
18 #include <CoreFoundation/CoreFoundation.h>
19 #include <CoreServices/CoreServices.h>
28 #define REMOTE_SWITCH_COOKIE 19
29 #define REMOTE_COOKIE_STR "19_"
30 #define LONG_PRESS_COUNT 10
32 #define LOC QString("AppleRemote::")
82 LOG(VB_GENERAL, LOG_ERR,
LOC +
"startListening() failed");
87 IOObjectRelease(hidDevice);
94 (*queue)->stop(
queue);
95 (*queue)->dispose(
queue);
96 (*queue)->Release(
queue);
116 CFRunLoopStop(CFRunLoopGetCurrent());
182 CFMutableDictionaryRef hidMatchDictionary =
nullptr;
183 io_iterator_t hidObjectIterator = 0;
184 io_object_t hidDevice = 0;
185 IOReturn ioReturnValue;
188 hidMatchDictionary = IOServiceMatching(devName);
191 ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault,
195 if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0))
196 hidDevice = IOIteratorNext(hidObjectIterator);
198 LOG(VB_GENERAL, LOG_ERR,
LOC +
199 QString(
"_findAppleRemoteDevice(%1) failed").
arg(devName));
203 hidMatchDictionary =
nullptr;
209 IOHIDDeviceInterface122** handle;
214 success = (*handle)->copyMatchingElements(handle,
216 (CFArrayRef*)&elements);
218 if (success == kIOReturnSuccess)
220 for (CFIndex i = 0; i < CFArrayGetCount(elements); ++i)
222 CFDictionaryRef element;
225 IOHIDElementCookie cookie;
227 element = (CFDictionaryRef)CFArrayGetValueAtIndex(elements, i);
228 object = CFDictionaryGetValue(element,
229 CFSTR(kIOHIDElementCookieKey));
231 if (
object ==
nullptr || CFGetTypeID(
object) != CFNumberGetTypeID())
234 if (!CFNumberGetValue((CFNumberRef)
object,
235 kCFNumberLongType, &number))
238 cookie = (IOHIDElementCookie)number;
240 cookies.push_back((
int)cookie);
249 IOReturn ioReturnValue;
250 IOCFPlugInInterface** plugInInterface =
nullptr;
255 = IOCreatePlugInInterfaceForService(hidDevice,
256 kIOHIDDeviceUserClientTypeID,
257 kIOCFPlugInInterfaceID,
258 &plugInInterface, &score);
260 if ((kIOReturnSuccess == ioReturnValue) &&
261 plugInInterface && *plugInInterface)
263 HRESULT plugInResult = (*plugInInterface)->QueryInterface
265 CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
268 if (plugInResult != S_OK)
269 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_createDeviceInterface() failed");
271 (*plugInInterface)->Release(plugInInterface);
278 CFRunLoopSourceRef eventSource;
279 IOReturn ioReturnValue;
280 IOHIDOptionsType openMode;
284 openMode = kIOHIDOptionsTypeSeizeDevice;
286 openMode = kIOHIDOptionsTypeNone;
290 if (ioReturnValue != KERN_SUCCESS)
292 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_openDevice() failed");
298 LOG(VB_GENERAL, LOG_ERR,
LOC +
299 "_openDevice() - error allocating queue");
303 HRESULT result = (*queue)->create(
queue, 0, 12);
304 if (result != S_OK || !
queue)
305 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_openDevice() - error creating queue");
309 auto cookie = (IOHIDElementCookie)iter;
310 (*queue)->addElement(
queue, cookie, 0);
313 ioReturnValue = (*queue)->createAsyncEventSource(
queue, &eventSource);
314 if (ioReturnValue != KERN_SUCCESS)
316 LOG(VB_GENERAL, LOG_ERR,
LOC +
317 "_openDevice() - failed to create async event source");
323 if (ioReturnValue != KERN_SUCCESS)
325 LOG(VB_GENERAL, LOG_ERR,
LOC +
326 "_openDevice() - error registering callback");
330 CFRunLoopAddSource(CFRunLoopGetCurrent(),
331 eventSource, kCFRunLoopDefaultMode);
332 (*queue)->start(
queue);
337 void* refcon,
void* sender)
347 AbsoluteTime zeroTime = {0,0};
348 SInt32 sumOfValues = 0;
349 std::stringstream cookieString;
351 while (result == kIOReturnSuccess)
353 IOHIDEventStruct event;
355 result = (*queue)->getNextEvent(
queue, &event, zeroTime, 0);
356 if (result != kIOReturnSuccess)
366 sumOfValues+=
event.value;
367 cookieString << std::dec << (int)event.elementCookie <<
"_";
377 std::map<std::string,AppleRemote::Event>::iterator ii;