private static void toggleKeyCode(uint code, bool down, KeyModifiers flags) { const uint NX_SYSDEFINED = 14; const short NX_SUBTYPE_AUX_CONTROL_BUTTONS = 8; const uint kNXEventDataVersion = 2; /* The media keys all have 1000 added to them to help us detect them. */ if (code >= 1000) { code = code - 1000; /* Get the real keycode. */ NXEventData eventData = new NXEventData(); // kern_return_t kr; IOGPoint loc = new IOGPoint() { x = 0, y = 0 }; uint evtInfo = code << 16 | (down ? OSXDefinitions.kCGEventKeyDown : OSXDefinitions.kCGEventKeyUp) << 8; // bzero(&event, sizeof(NXEventData)); eventData.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS; eventData.compound.misc.L[0] = evtInfo; int kr = IOHIDPostEvent(getAuxiliaryKeyDriver(), NX_SYSDEFINED, loc, eventData, kNXEventDataVersion, 0, 0); if (kr != 0) { throw new Exception($"IOKit returned error: 0x{kr:x8}."); } } else { IntPtr keyEvent = CGEventCreateKeyboardEvent(IntPtr.Zero, (ushort)code, down); // assert(keyEvent != NULL); CGEventSetType(keyEvent, down ? OSXDefinitions.kCGEventKeyDown : OSXDefinitions.kCGEventKeyUp); CGEventSetFlags(keyEvent, flags.ToCGEventFlags()); CGEventPost(OSXDefinitions.kCGSessionEventTap, keyEvent); CFRelease(keyEvent); } }
private static extern int IOHIDPostEvent(IntPtr connect, uint eventType, IOGPoint location, NXEventData eventData, uint eventDataVersion, uint eventFlags, uint options);