Итак, я пытаюсь собрать простое полноэкранное приложение OpenGL, используя CGL и IOHIDManager, чтобы изучить API более низкого уровня. В настоящее время я создаю контекст OpenGL и запускаю его в полноэкранном режиме. Сейчас я пытаюсь добавить ввод с клавиатуры, чтобы выйти из приложения. Я нашел много подобных примеров использования IOHIDManager для чтения ключей, но независимо от того, что я делаю, мой обратный вызов не срабатывает.
Мой обратный вызов — это просто функция, которая печатает «здесь». Я не уверен, где я ошибаюсь - я пробовал и CFRunLoopGetCurrent(), и CFRunLoopMain(). Мой основной - это просто цикл while. Что дает?
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 CreateInputManager() {
IOHIDManagerRef hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
CFMutableDictionaryRef matching_dictionary = CreateMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
IOHIDManagerSetDeviceMatching(hid_manager, matching_dictionary);
IOHIDManagerRegisterInputValueCallback(hid_manager, KeyboardCallback, NULL);
IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
}
void KeyboardCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) {
puts("CALLBACK!");
}
int main() {
// Commented out CGL context & fullscreen window creation
CreateInputManager();
while(true) {
;
}
}
ОБНОВЛЕНИЕ
Если я помещу CFRunLoopRun() в конец функции CreateInputManager, мой обратный вызов будет вызван, но функция никогда не вернется. Как это должно работать в однопоточном приложении CGL? Является ли это строгим требованием, чтобы для работы IOHIDManager требовался цикл выполнения?