155 lines
3.3 KiB
Plaintext
155 lines
3.3 KiB
Plaintext
/*
|
|
* barrier -- mouse and keyboard sharing utility
|
|
* Copyright (C) 2016 Symless.
|
|
*
|
|
* This package is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* found in the file COPYING that should have accompanied this file.
|
|
*
|
|
* This package is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#import "platform/OSXMediaKeySupport.h"
|
|
#import <Cocoa/Cocoa.h>
|
|
#import <IOKit/hidsystem/ev_keymap.h>
|
|
|
|
int convertKeyIDToNXKeyType(KeyID id)
|
|
{
|
|
int type = -1;
|
|
|
|
switch (id) {
|
|
case kKeyAudioUp:
|
|
type = NX_KEYTYPE_SOUND_UP;
|
|
break;
|
|
case kKeyAudioDown:
|
|
type = NX_KEYTYPE_SOUND_DOWN;
|
|
break;
|
|
case kKeyBrightnessUp:
|
|
type = NX_KEYTYPE_BRIGHTNESS_UP;
|
|
break;
|
|
case kKeyBrightnessDown:
|
|
type = NX_KEYTYPE_BRIGHTNESS_DOWN;
|
|
break;
|
|
case kKeyAudioMute:
|
|
type = NX_KEYTYPE_MUTE;
|
|
break;
|
|
case kKeyEject:
|
|
type = NX_KEYTYPE_EJECT;
|
|
break;
|
|
case kKeyAudioPlay:
|
|
type = NX_KEYTYPE_PLAY;
|
|
break;
|
|
case kKeyAudioNext:
|
|
type = NX_KEYTYPE_NEXT;
|
|
break;
|
|
case kKeyAudioPrev:
|
|
type = NX_KEYTYPE_PREVIOUS;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
static KeyID
|
|
convertNXKeyTypeToKeyID(uint32_t const type)
|
|
{
|
|
KeyID id = 0;
|
|
|
|
switch (type) {
|
|
case NX_KEYTYPE_SOUND_UP:
|
|
id = kKeyAudioUp;
|
|
break;
|
|
case NX_KEYTYPE_SOUND_DOWN:
|
|
id = kKeyAudioDown;
|
|
break;
|
|
case NX_KEYTYPE_MUTE:
|
|
id = kKeyAudioMute;
|
|
break;
|
|
case NX_KEYTYPE_EJECT:
|
|
id = kKeyEject;
|
|
break;
|
|
case NX_KEYTYPE_PLAY:
|
|
id = kKeyAudioPlay;
|
|
break;
|
|
case NX_KEYTYPE_FAST:
|
|
case NX_KEYTYPE_NEXT:
|
|
id = kKeyAudioNext;
|
|
break;
|
|
case NX_KEYTYPE_REWIND:
|
|
case NX_KEYTYPE_PREVIOUS:
|
|
id = kKeyAudioPrev;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
bool
|
|
isMediaKeyEvent(CGEventRef event) {
|
|
NSEvent* nsEvent = nil;
|
|
@try {
|
|
nsEvent = [NSEvent eventWithCGEvent: event];
|
|
if ([nsEvent subtype] != 8) {
|
|
return false;
|
|
}
|
|
uint32_t const nxKeyId = ([nsEvent data1] & 0xFFFF0000) >> 16;
|
|
if (convertNXKeyTypeToKeyID (nxKeyId)) {
|
|
return true;
|
|
}
|
|
} @catch (NSException* e) {
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
getMediaKeyEventInfo(CGEventRef event, KeyID* const keyId,
|
|
bool* const down, bool* const isRepeat) {
|
|
NSEvent* nsEvent = nil;
|
|
@try {
|
|
nsEvent = [NSEvent eventWithCGEvent: event];
|
|
} @catch (NSException* e) {
|
|
return false;
|
|
}
|
|
if (keyId) {
|
|
*keyId = convertNXKeyTypeToKeyID (([nsEvent data1] & 0xFFFF0000) >> 16);
|
|
}
|
|
if (down) {
|
|
*down = !([nsEvent data1] & 0x100);
|
|
}
|
|
if (isRepeat) {
|
|
*isRepeat = [nsEvent data1] & 0x1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
fakeNativeMediaKey(KeyID id)
|
|
{
|
|
|
|
NSEvent* downRef = [NSEvent otherEventWithType:NSSystemDefined
|
|
location: NSMakePoint(0, 0) modifierFlags:0xa00
|
|
timestamp:0 windowNumber:0 context:0 subtype:8
|
|
data1:(convertKeyIDToNXKeyType(id) << 16) | ((0xa) << 8)
|
|
data2:-1];
|
|
CGEventRef downEvent = [downRef CGEvent];
|
|
|
|
NSEvent* upRef = [NSEvent otherEventWithType:NSSystemDefined
|
|
location: NSMakePoint(0, 0) modifierFlags:0xa00
|
|
timestamp:0 windowNumber:0 context:0 subtype:8
|
|
data1:(convertKeyIDToNXKeyType(id) << 16) | ((0xb) << 8)
|
|
data2:-1];
|
|
CGEventRef upEvent = [upRef CGEvent];
|
|
|
|
CGEventPost(kCGHIDEventTap, downEvent);
|
|
CGEventPost(kCGHIDEventTap, upEvent);
|
|
|
|
return true;
|
|
}
|