Skip to content

Instantly share code, notes, and snippets.

@dnicolson
Last active December 3, 2020 14:34
Show Gist options
  • Save dnicolson/4c095d5f7662cfe0fb84c60c55fbc6e3 to your computer and use it in GitHub Desktop.
Save dnicolson/4c095d5f7662cfe0fb84c60c55fbc6e3 to your computer and use it in GitHub Desktop.
Airoha (DuraGadet/OMOTON/etc.) iOS Bluetooth keyboards produce an HID value of 0x10101010101 instead of 1 when pressing Control-Command-Up or Control-Command-Space
// clang -framework IOKit -framework Carbon iOS-keyboard-issue.c -o iOS-keyboard-issue && ./iOS-keyboard-issue
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDValue.h>
CFMutableDictionaryRef CreateMatchingDictionary(UInt32 usage_page, UInt32 usage)
{
CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFNumberRef page_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page);
CFDictionarySetValue(dictionary, CFSTR(kIOHIDDeviceUsagePageKey), page_number);
CFRelease(page_number);
CFNumberRef usage_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
CFDictionarySetValue(dictionary, CFSTR(kIOHIDDeviceUsageKey), usage_number);
CFRelease(usage_number);
return dictionary;
}
void HIDKeyboardCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
{
IOHIDElementRef elem = IOHIDValueGetElement(value);
uint32_t usage_page = IOHIDElementGetUsagePage(elem);
uint32_t usage = IOHIDElementGetUsage(elem);
long pressed = IOHIDValueGetIntegerValue(value);
if (usage_page == kHIDPage_KeyboardOrKeypad) {
if (pressed == 1 || pressed == 0x10101010101) { //1103823438081
printf("\n\nKey code: %d (0x%04lx)\n", usage, pressed);
if (pressed == 0x10101010101) {
printf("Control-Command-Space or Control-Command-Up was pressed.\n");
}
}
}
}
int main()
{
IOHIDManagerRef hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
CFMutableDictionaryRef matching_dictionary = CreateMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
IOHIDManagerSetDeviceMatching(hid_manager, matching_dictionary);
IOHIDManagerRegisterInputValueCallback(hid_manager, HIDKeyboardCallback, NULL);
IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
CFRunLoopRun();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment