Skip to content

Commit 163feb5

Browse files
committed
This commit fixes #148: Volume keys don't work on Mac.
Also added brightness, keyboard illumination, play/pause, next/previous
1 parent d2d859a commit 163feb5

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

src/keycode.h

+14-13
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ extern "C"
1313

1414
#include <Carbon/Carbon.h> /* Really only need <HIToolbox/Events.h> */
1515
#include <ApplicationServices/ApplicationServices.h>
16-
16+
#import <IOKit/hidsystem/ev_keymap.h>
17+
1718
enum _MMKeyCode {
1819
K_NOT_A_KEY = 9999,
1920
K_BACKSPACE = kVK_Delete,
@@ -49,24 +50,24 @@ enum _MMKeyCode {
4950
K_SPACE = kVK_Space,
5051
K_PRINTSCREEN = K_NOT_A_KEY,
5152

52-
K_AUDIO_VOLUME_MUTE = kVK_Mute,
53-
K_AUDIO_VOLUME_DOWN = kVK_VolumeDown,
54-
K_AUDIO_VOLUME_UP = kVK_VolumeUp,
55-
K_AUDIO_PLAY = K_NOT_A_KEY,
53+
K_AUDIO_VOLUME_MUTE = NX_KEYTYPE_MUTE,
54+
K_AUDIO_VOLUME_DOWN = NX_KEYTYPE_SOUND_DOWN,
55+
K_AUDIO_VOLUME_UP = NX_KEYTYPE_SOUND_UP,
56+
K_AUDIO_PLAY = NX_KEYTYPE_PLAY,
5657
K_AUDIO_STOP = K_NOT_A_KEY,
57-
K_AUDIO_PAUSE = K_NOT_A_KEY,
58-
K_AUDIO_PREV = K_NOT_A_KEY,
59-
K_AUDIO_NEXT = K_NOT_A_KEY,
58+
K_AUDIO_PAUSE = NX_KEYTYPE_PLAY,
59+
K_AUDIO_PREV = NX_KEYTYPE_PREVIOUS,
60+
K_AUDIO_NEXT = NX_KEYTYPE_NEXT,
6061
K_AUDIO_REWIND = K_NOT_A_KEY,
6162
K_AUDIO_FORWARD = K_NOT_A_KEY,
6263
K_AUDIO_REPEAT = K_NOT_A_KEY,
6364
K_AUDIO_RANDOM = K_NOT_A_KEY,
6465

65-
K_LIGHTS_MON_UP = K_NOT_A_KEY,
66-
K_LIGHTS_MON_DOWN = K_NOT_A_KEY,
67-
K_LIGHTS_KBD_TOGGLE = K_NOT_A_KEY,
68-
K_LIGHTS_KBD_UP = K_NOT_A_KEY,
69-
K_LIGHTS_KBD_DOWN = K_NOT_A_KEY
66+
K_LIGHTS_MON_UP = NX_KEYTYPE_BRIGHTNESS_UP,
67+
K_LIGHTS_MON_DOWN = NX_KEYTYPE_BRIGHTNESS_DOWN,
68+
K_LIGHTS_KBD_TOGGLE = NX_KEYTYPE_ILLUMINATION_TOGGLE,
69+
K_LIGHTS_KBD_UP = NX_KEYTYPE_ILLUMINATION_UP,
70+
K_LIGHTS_KBD_DOWN = NX_KEYTYPE_ILLUMINATION_DOWN
7071
};
7172

7273
typedef CGKeyCode MMKeyCode;

src/keypress.c

+61-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#if defined(IS_MACOSX)
88
#include <ApplicationServices/ApplicationServices.h>
9+
#import <IOKit/hidsystem/IOHIDLib.h>
10+
#import <IOKit/hidsystem/ev_keymap.h>
911
#elif defined(USE_X11)
1012
#include <X11/extensions/XTest.h>
1113
#include "xdisplay.h"
@@ -26,6 +28,45 @@
2628
microsleep(DEADBEEF_UNIFORM(0.0, 62.5)))
2729
#endif
2830

31+
#if defined(IS_MACOSX)
32+
bool keyCodeRequiresSystemDefinedEvent(MMKeyCode code) {
33+
return code == NX_KEYTYPE_SOUND_UP ||
34+
code == NX_KEYTYPE_SOUND_DOWN ||
35+
code == NX_KEYTYPE_MUTE ||
36+
code == NX_KEYTYPE_PLAY ||
37+
code == NX_KEYTYPE_BRIGHTNESS_UP ||
38+
code == NX_KEYTYPE_BRIGHTNESS_DOWN ||
39+
code == NX_KEYTYPE_PLAY ||
40+
code == NX_KEYTYPE_PREVIOUS ||
41+
code == NX_KEYTYPE_NEXT ||
42+
code == NX_KEYTYPE_ILLUMINATION_UP ||
43+
code == NX_KEYTYPE_ILLUMINATION_DOWN ||
44+
code == NX_KEYTYPE_ILLUMINATION_TOGGLE
45+
;
46+
}
47+
static io_connect_t _getAuxiliaryKeyDriver(void)
48+
{
49+
static mach_port_t sEventDrvrRef = 0;
50+
mach_port_t masterPort, service, iter;
51+
kern_return_t kr;
52+
53+
if (!sEventDrvrRef)
54+
{
55+
kr = IOMasterPort( bootstrap_port, &masterPort );
56+
assert(KERN_SUCCESS == kr);
57+
kr = IOServiceGetMatchingServices(masterPort, IOServiceMatching( kIOHIDSystemClass), &iter );
58+
assert(KERN_SUCCESS == kr);
59+
service = IOIteratorNext( iter );
60+
assert(service);
61+
kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, &sEventDrvrRef );
62+
assert(KERN_SUCCESS == kr);
63+
IOObjectRelease(service);
64+
IOObjectRelease(iter);
65+
}
66+
return sEventDrvrRef;
67+
}
68+
#endif
69+
2970
#if defined(IS_WINDOWS)
3071
void win32KeyEvent(int key, MMKeyFlags flags)
3172
{
@@ -43,14 +84,26 @@ void win32KeyEvent(int key, MMKeyFlags flags)
4384
void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags)
4485
{
4586
#if defined(IS_MACOSX)
46-
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL,
47-
(CGKeyCode)code, down);
48-
assert(keyEvent != NULL);
49-
50-
CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp);
51-
CGEventSetFlags(keyEvent, flags);
52-
CGEventPost(kCGSessionEventTap, keyEvent);
53-
CFRelease(keyEvent);
87+
if (keyCodeRequiresSystemDefinedEvent(code)) {
88+
NXEventData event;
89+
kern_return_t kr;
90+
IOGPoint loc = { 0, 0 };
91+
UInt32 evtInfo = code << 16 | (down?NX_KEYDOWN:NX_KEYUP) << 8;
92+
bzero(&event, sizeof(NXEventData));
93+
event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
94+
event.compound.misc.L[0] = evtInfo;
95+
kr = IOHIDPostEvent( _getAuxiliaryKeyDriver(), NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE );
96+
assert( KERN_SUCCESS == kr );
97+
} else {
98+
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL,
99+
(CGKeyCode)code, down);
100+
assert(keyEvent != NULL);
101+
102+
CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp);
103+
CGEventSetFlags(keyEvent, flags);
104+
CGEventPost(kCGSessionEventTap, keyEvent);
105+
CFRelease(keyEvent);
106+
}
54107
#elif defined(IS_WINDOWS)
55108
const DWORD dwFlags = down ? 0 : KEYEVENTF_KEYUP;
56109

0 commit comments

Comments
 (0)