2016-06-16 15:18:31 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2025-01-24 00:11:17 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2016 Symless Ltd.
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
2016-06-16 15:18:31 +00:00
|
|
|
*/
|
|
|
|
|
|
2016-09-16 16:20:31 +00:00
|
|
|
#import "platform/OSXMediaKeySupport.h"
|
2024-08-07 17:11:29 +00:00
|
|
|
|
2016-06-16 15:18:31 +00:00
|
|
|
#import <Cocoa/Cocoa.h>
|
2016-09-15 15:39:10 +00:00
|
|
|
#import <IOKit/hidsystem/ev_keymap.h>
|
2016-06-16 15:18:31 +00:00
|
|
|
|
2024-08-07 17:11:29 +00:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
|
|
2016-06-16 15:18:31 +00:00
|
|
|
int convertKeyIDToNXKeyType(KeyID id)
|
|
|
|
|
{
|
2024-12-18 01:42:03 +00:00
|
|
|
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;
|
2016-06-16 15:18:31 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-18 01:42:03 +00:00
|
|
|
static KeyID convertNXKeyTypeToKeyID(uint32_t const type)
|
2016-09-15 15:39:10 +00:00
|
|
|
{
|
2024-12-18 01:42:03 +00:00
|
|
|
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;
|
2016-09-15 15:39:10 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-18 01:42:03 +00:00
|
|
|
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;
|
2016-09-15 15:39:10 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-18 01:42:03 +00:00
|
|
|
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;
|
2016-09-15 15:39:10 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-18 01:42:03 +00:00
|
|
|
bool fakeNativeMediaKey(KeyID id)
|
2016-06-16 15:18:31 +00:00
|
|
|
{
|
2024-12-18 01:42:03 +00:00
|
|
|
|
|
|
|
|
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(0, downEvent);
|
|
|
|
|
CGEventPost(0, upEvent);
|
|
|
|
|
|
|
|
|
|
return true;
|
2016-06-16 15:18:31 +00:00
|
|
|
}
|