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>
20 #include <AvailabilityMacros.h>
33 #define REMOTE_SWITCH_COOKIE 19
34 #define REMOTE_COOKIE_STR "19_"
35 #define LONG_PRESS_COUNT 10
37 #define LOC QString("AppleRemote::")
87 LOG(VB_GENERAL, LOG_ERR,
LOC +
"startListening() failed");
92 IOObjectRelease(hidDevice);
99 (*queue)->stop(
queue);
100 (*queue)->dispose(
queue);
101 (*queue)->Release(
queue);
121 CFRunLoopStop(CFRunLoopGetCurrent());
187 CFMutableDictionaryRef hidMatchDictionary =
nullptr;
188 io_iterator_t hidObjectIterator = 0;
189 io_object_t hidDevice = 0;
190 IOReturn ioReturnValue;
193 hidMatchDictionary = IOServiceMatching(devName);
200 if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0))
201 hidDevice = IOIteratorNext(hidObjectIterator);
203 LOG(VB_GENERAL, LOG_ERR,
LOC +
204 QString(
"_findAppleRemoteDevice(%1) failed").arg(devName));
208 hidMatchDictionary =
nullptr;
214 IOHIDDeviceInterface122** handle;
219 success = (*handle)->copyMatchingElements(handle,
221 (CFArrayRef*)&elements);
223 if (success == kIOReturnSuccess)
225 for (CFIndex i = 0; i < CFArrayGetCount(elements); ++i)
227 CFDictionaryRef element;
230 IOHIDElementCookie cookie;
232 element = (CFDictionaryRef)CFArrayGetValueAtIndex(elements, i);
233 object = CFDictionaryGetValue(element,
234 CFSTR(kIOHIDElementCookieKey));
236 if (
object ==
nullptr || CFGetTypeID(
object) != CFNumberGetTypeID())
239 if (!CFNumberGetValue((CFNumberRef)
object,
240 kCFNumberLongType, &number))
243 cookie = (IOHIDElementCookie)number;
245 cookies.push_back((
int)cookie);
254 IOReturn ioReturnValue;
255 IOCFPlugInInterface** plugInInterface =
nullptr;
260 = IOCreatePlugInInterfaceForService(hidDevice,
261 kIOHIDDeviceUserClientTypeID,
262 kIOCFPlugInInterfaceID,
263 &plugInInterface, &score);
265 if ((kIOReturnSuccess == ioReturnValue) &&
266 plugInInterface && *plugInInterface)
268 HRESULT plugInResult = (*plugInInterface)->QueryInterface
270 CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
273 if (plugInResult != S_OK)
274 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_createDeviceInterface() failed");
276 (*plugInInterface)->Release(plugInInterface);
283 CFRunLoopSourceRef eventSource;
284 IOReturn ioReturnValue;
285 IOHIDOptionsType openMode;
289 openMode = kIOHIDOptionsTypeSeizeDevice;
291 openMode = kIOHIDOptionsTypeNone;
295 if (ioReturnValue != KERN_SUCCESS)
297 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_openDevice() failed");
303 LOG(VB_GENERAL, LOG_ERR,
LOC +
304 "_openDevice() - error allocating queue");
308 HRESULT result = (*queue)->create(
queue, 0, 12);
309 if (result != S_OK || !
queue)
310 LOG(VB_GENERAL, LOG_ERR,
LOC +
"_openDevice() - error creating queue");
314 auto cookie = (IOHIDElementCookie)iter;
315 (*queue)->addElement(
queue, cookie, 0);
318 ioReturnValue = (*queue)->createAsyncEventSource(
queue, &eventSource);
319 if (ioReturnValue != KERN_SUCCESS)
321 LOG(VB_GENERAL, LOG_ERR,
LOC +
322 "_openDevice() - failed to create async event source");
328 if (ioReturnValue != KERN_SUCCESS)
330 LOG(VB_GENERAL, LOG_ERR,
LOC +
331 "_openDevice() - error registering callback");
335 CFRunLoopAddSource(CFRunLoopGetCurrent(),
336 eventSource, kCFRunLoopDefaultMode);
337 (*queue)->start(
queue);
342 void* refcon,
void* sender)
352 AbsoluteTime zeroTime = {0,0};
353 SInt32 sumOfValues = 0;
354 std::stringstream cookieString;
356 while (result == kIOReturnSuccess)
358 IOHIDEventStruct event;
360 result = (*queue)->getNextEvent(
queue, &event, zeroTime, 0);
361 if (result != kIOReturnSuccess)
371 sumOfValues+=
event.value;
372 cookieString << std::dec << (int)event.elementCookie <<
"_";
382 std::map<std::string,AppleRemote::Event>::iterator ii;