Skip to content

Instantly share code, notes, and snippets.

@mtvee
Last active November 21, 2020 00:53
Show Gist options
  • Save mtvee/e82ef146e7f1ef6c816e27d7a16a7a79 to your computer and use it in GitHub Desktop.
Save mtvee/e82ef146e7f1ef6c816e27d7a16a7a79 to your computer and use it in GitHub Desktop.
SFML Big Sur trouble
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(mactest)
find_library(IOKIT_LIBRARY IOKit)
find_library(FOUNDATION_LIBRARY Foundation)
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
FIND_LIBRARY(COCOA_LIBRARY Cocoa)
set(SOURCES main.cpp)
add_executable(mactest ${SOURCES})
target_link_libraries(mactest ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COCOA_LIBRARY} ${APPKIT_LIBRARY})
#include <iostream>
#include <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDLib.h>
IOHIDManagerRef m_manager;
////////////////////////////////////////////////////////////
CFDictionaryRef copyDevicesMask(UInt32 page, UInt32 usage)
{
// Create the dictionary.
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
// Add the page value.
CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), value);
CFRelease(value);
// Add the usage value (which is only valid if page value exists).
value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), value);
CFRelease(value);
return dict;
}
////////////////////////////////////////////////////////////
CFSetRef copyDevices(UInt32 page, UInt32 usage)
{
// Filter and keep only the requested devices
CFDictionaryRef mask = copyDevicesMask(page, usage);
IOHIDManagerSetDeviceMatching(m_manager, mask);
CFRelease(mask);
mask = 0;
CFSetRef devices = IOHIDManagerCopyDevices(m_manager);
if (devices == NULL)
return NULL;
// Is there at least one device?
CFIndex deviceCount = CFSetGetCount(devices);
if (deviceCount < 1)
{
CFRelease(devices);
return NULL;
}
return devices;
}
////////////////////////////////////////////////////////////
void loadKeyboard(IOHIDDeviceRef keyboard)
{
std::cerr << "Keyboard: " << keyboard << std::endl;
CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard,
NULL,
kIOHIDOptionsTypeNone);
if (keys == NULL)
{
std::cerr << "We got a keyboard without any keys (1)" << std::endl;
return;
}
// How many elements are there?
CFIndex keysCount = CFArrayGetCount(keys);
if (keysCount == 0)
{
std::cerr << "We got a keyboard without any keys (2)" << std::endl;
CFRelease(keys);
return;
}
// Go through all connected elements.
for (CFIndex i = 0; i < keysCount; ++i)
{
IOHIDElementRef aKey = (IOHIDElementRef) CFArrayGetValueAtIndex(keys, i);
// Skip non-matching keys elements
if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad)
continue;
//loadKey(aKey);
}
// Release unused stuff
CFRelease(keys);
std::cout << "success" << std::endl;
}
int main()
{
// Create an HID Manager reference
m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
// Open the HID Manager reference
IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone);
if (openStatus != kIOReturnSuccess)
{
std::cerr << "Error when opening the HID manager" << std::endl;
if (m_manager != 0)
CFRelease(m_manager);
return 1;
}
// Get only keyboards
CFSetRef keyboards = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
if (keyboards == NULL)
{
std::cerr << "No keyboard detected by the HID manager!" << std::endl;
if (m_manager != 0)
CFRelease(m_manager);
return 2;
}
CFIndex keyboardCount = CFSetGetCount(keyboards); // >= 1 (asserted by copyDevices)
// Get an iterable array
CFTypeRef devicesArray[keyboardCount];
CFSetGetValues(keyboards, devicesArray);
for (CFIndex i = 0; i < keyboardCount; ++i)
{
IOHIDDeviceRef keyboard = (IOHIDDeviceRef)devicesArray[i];
loadKeyboard(keyboard);
}
// Release unused stuff
CFRelease(keyboards);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment