* Use Deskflow Name * Remove business-oriented options from issue templates * Remove business-oriented workflow * Bump version to 3.0.0 (to avoid confusion with previously used version numbers 1.x & 2.x) * Update readme to reflect new project name and goals * Found some more "synergy" to rename * Rename `synlib` to `app` * Rename `syntool` to `deskflow-legacy` * Rename `synwinhk` to `dfwhook` * Rename dirs from synergy to deskflow * Rename more "Synergy" files * Rename app bundle ID * Fixed copyright typo * Rename only title in serial key dialog (to be moved downstream later) * Preserve original serial key window for moving downstream * Restore dialogs ready for moving downstream * Rename `QDeskflowApplication` to `DeskflowApplication` (the Q is confusing) * Restore Volker's original project name * Fixed mimetype * Fixed weird grammar * Fixed (more) weird grammar * Broken link, restoring (but we should move all links out of source) * Broken link, restoring (but we should move all links out of source) * Add write permission to valgrind-analysis.yml * Restore AUR conflicts * Apply Clang format * Update ChangeLog * Back out version change --------- Co-authored-by: Nick Bolton <nick@symless.com>
158 lines
3.4 KiB
Objective-C
158 lines
3.4 KiB
Objective-C
/*
|
|
* Deskflow -- 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>
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
|
|
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(0, downEvent);
|
|
CGEventPost(0, upEvent);
|
|
|
|
return true;
|
|
}
|