rustdesk/src/platform/macos.mm

152 lines
5.6 KiB
Plaintext
Raw Normal View History

#import <AVFoundation/AVFoundation.h>
#import <AppKit/AppKit.h>
#import <IOKit/hidsystem/IOHIDLib.h>
2023-01-06 12:42:16 +08:00
// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm
extern "C" bool InputMonitoringAuthStatus(bool prompt) {
2023-01-06 15:37:15 +08:00
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_15) {
IOHIDAccessType theType = IOHIDCheckAccess(kIOHIDRequestTypeListenEvent);
2023-01-06 13:19:08 +08:00
NSLog(@"IOHIDCheckAccess = %d, kIOHIDAccessTypeGranted = %d", theType, kIOHIDAccessTypeGranted);
switch (theType) {
case kIOHIDAccessTypeGranted:
return true;
break;
case kIOHIDAccessTypeDenied: {
if (prompt) {
NSString *urlString = @"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent";
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:urlString]];
}
break;
}
case kIOHIDAccessTypeUnknown: {
if (prompt) {
bool result = IOHIDRequestAccess(kIOHIDRequestTypeListenEvent);
NSLog(@"IOHIDRequestAccess result = %d", result);
}
break;
}
default:
break;
}
} else {
return true;
}
return false;
}
2023-01-11 15:35:35 +08:00
extern "C" float BackingScaleFactor() {
NSScreen* s = [NSScreen mainScreen];
if (s) return [s backingScaleFactor];
return 1;
}
// https://github.com/jhford/screenresolution/blob/master/cg_utils.c
// https://github.com/jdoupe/screenres/blob/master/setgetscreen.m
extern "C" bool MacGetModeNum(CGDirectDisplayID display, uint32_t *numModes) {
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
return false;
}
*numModes = CFArrayGetCount(allModes);
CFRelease(allModes);
return true;
}
extern "C" bool MacGetModes(CGDirectDisplayID display, uint32_t *widths, uint32_t *heights, uint32_t max, uint32_t *numModes) {
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
return false;
}
*numModes = CFArrayGetCount(allModes);
for (uint32_t i = 0; i < *numModes && i < max; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
widths[i] = (uint32_t)CGDisplayModeGetWidth(mode);
heights[i] = (uint32_t)CGDisplayModeGetHeight(mode);
}
CFRelease(allModes);
return true;
}
extern "C" bool MacGetMode(CGDirectDisplayID display, uint32_t *width, uint32_t *height) {
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(display);
if (mode == NULL) {
return false;
}
*width = (uint32_t)CGDisplayModeGetWidth(mode);
*height = (uint32_t)CGDisplayModeGetHeight(mode);
CGDisplayModeRelease(mode);
return true;
}
size_t bitDepth(CGDisplayModeRef mode) {
size_t depth = 0;
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
// are made up and possibly non-sensical
if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO32BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 96;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO64BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 64;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO16BitFloatPixels), kCFCompareCaseInsensitive)) {
depth = 48;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 32;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 30;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive)) {
depth = 16;
} else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive)) {
depth = 8;
}
CFRelease(pixelEncoding);
return depth;
}
bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
CGError rc;
CGDisplayConfigRef config;
rc = CGBeginDisplayConfiguration(&config);
if (rc != kCGErrorSuccess) {
return false;
}
rc = CGConfigureDisplayWithDisplayMode(config, display, mode, NULL);
if (rc != kCGErrorSuccess) {
return false;
}
rc = CGCompleteDisplayConfiguration(config, kCGConfigureForSession);
if (rc != kCGErrorSuccess) {
return false;
}
return true;
}
extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t height)
{
bool ret = false;
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
if (currentMode == NULL) {
return ret;
}
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
if (allModes == NULL) {
CGDisplayModeRelease(currentMode);
return ret;
}
int numModes = CFArrayGetCount(allModes);
for (int i = 0; i < numModes; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
if (width == CGDisplayModeGetWidth(mode) &&
height == CGDisplayModeGetHeight(mode) &&
bitDepth(currentMode) == bitDepth(mode) &&
CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode)) {
ret = setDisplayToMode(display, mode);
break;
}
}
CGDisplayModeRelease(currentMode);
CFRelease(allModes);
return ret;
}