commit
6048efe02b
@ -1,6 +1,9 @@
|
|||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
#import <IOKit/hidsystem/IOHIDLib.h>
|
#import <IOKit/hidsystem/IOHIDLib.h>
|
||||||
|
#include <Security/Authorization.h>
|
||||||
|
#include <Security/AuthorizationTags.h>
|
||||||
|
|
||||||
|
|
||||||
// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm
|
// https://github.com/codebytere/node-mac-permissions/blob/main/permissions.mm
|
||||||
|
|
||||||
@ -35,6 +38,33 @@ extern "C" bool InputMonitoringAuthStatus(bool prompt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" bool MacCheckAdminAuthorization() {
|
||||||
|
AuthorizationRef authRef;
|
||||||
|
OSStatus status;
|
||||||
|
|
||||||
|
status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
|
||||||
|
kAuthorizationFlagDefaults, &authRef);
|
||||||
|
if (status != errAuthorizationSuccess) {
|
||||||
|
printf("Failed to create AuthorizationRef\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthorizationItem authItem = {kAuthorizationRightExecute, 0, NULL, 0};
|
||||||
|
AuthorizationRights authRights = {1, &authItem};
|
||||||
|
AuthorizationFlags flags = kAuthorizationFlagDefaults |
|
||||||
|
kAuthorizationFlagInteractionAllowed |
|
||||||
|
kAuthorizationFlagPreAuthorize |
|
||||||
|
kAuthorizationFlagExtendRights;
|
||||||
|
status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, flags, NULL);
|
||||||
|
if (status != errAuthorizationSuccess) {
|
||||||
|
printf("Failed to authorize\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthorizationFree(authRef, kAuthorizationFlagDefaults);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" float BackingScaleFactor() {
|
extern "C" float BackingScaleFactor() {
|
||||||
NSScreen* s = [NSScreen mainScreen];
|
NSScreen* s = [NSScreen mainScreen];
|
||||||
if (s) return [s backingScaleFactor];
|
if (s) return [s backingScaleFactor];
|
||||||
@ -44,44 +74,11 @@ extern "C" float BackingScaleFactor() {
|
|||||||
// https://github.com/jhford/screenresolution/blob/master/cg_utils.c
|
// https://github.com/jhford/screenresolution/blob/master/cg_utils.c
|
||||||
// https://github.com/jdoupe/screenres/blob/master/setgetscreen.m
|
// 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 bitDepth(CGDisplayModeRef mode) {
|
||||||
size_t depth = 0;
|
size_t depth = 0;
|
||||||
|
// Deprecated, same display same bpp?
|
||||||
|
// https://stackoverflow.com/questions/8210824/how-to-avoid-cgdisplaymodecopypixelencoding-to-get-bpp
|
||||||
|
// https://github.com/libsdl-org/SDL/pull/6628
|
||||||
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
|
CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
|
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
|
||||||
// are made up and possibly non-sensical
|
// are made up and possibly non-sensical
|
||||||
@ -104,7 +101,56 @@ size_t bitDepth(CGDisplayModeRef mode) {
|
|||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
|
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) {
|
||||||
|
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
|
||||||
|
if (currentMode == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
|
||||||
|
if (allModes == NULL) {
|
||||||
|
CGDisplayModeRelease(currentMode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint32_t allModeCount = CFArrayGetCount(allModes);
|
||||||
|
uint32_t realNum = 0;
|
||||||
|
for (uint32_t i = 0; i < allModeCount && realNum < max; i++) {
|
||||||
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
|
||||||
|
if (CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode) &&
|
||||||
|
bitDepth(currentMode) == bitDepth(mode)) {
|
||||||
|
widths[realNum] = (uint32_t)CGDisplayModeGetWidth(mode);
|
||||||
|
heights[realNum] = (uint32_t)CGDisplayModeGetHeight(mode);
|
||||||
|
realNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*numModes = realNum;
|
||||||
|
CGDisplayModeRelease(currentMode);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
|
||||||
CGError rc;
|
CGError rc;
|
||||||
CGDisplayConfigRef config;
|
CGDisplayConfigRef config;
|
||||||
rc = CGBeginDisplayConfiguration(&config);
|
rc = CGBeginDisplayConfiguration(&config);
|
||||||
@ -122,7 +168,6 @@ bool setDisplayToMode(CGDirectDisplayID display, CGDisplayModeRef mode) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t height)
|
extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@ -140,8 +185,8 @@ extern "C" bool MacSetMode(CGDirectDisplayID display, uint32_t width, uint32_t h
|
|||||||
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
|
||||||
if (width == CGDisplayModeGetWidth(mode) &&
|
if (width == CGDisplayModeGetWidth(mode) &&
|
||||||
height == CGDisplayModeGetHeight(mode) &&
|
height == CGDisplayModeGetHeight(mode) &&
|
||||||
bitDepth(currentMode) == bitDepth(mode) &&
|
CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode) &&
|
||||||
CGDisplayModeGetRefreshRate(currentMode) == CGDisplayModeGetRefreshRate(mode)) {
|
bitDepth(currentMode) == bitDepth(mode)) {
|
||||||
ret = setDisplayToMode(display, mode);
|
ret = setDisplayToMode(display, mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ extern "C" {
|
|||||||
static kAXTrustedCheckOptionPrompt: CFStringRef;
|
static kAXTrustedCheckOptionPrompt: CFStringRef;
|
||||||
fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> BOOL;
|
fn AXIsProcessTrustedWithOptions(options: CFDictionaryRef) -> BOOL;
|
||||||
fn InputMonitoringAuthStatus(_: BOOL) -> BOOL;
|
fn InputMonitoringAuthStatus(_: BOOL) -> BOOL;
|
||||||
|
fn MacCheckAdminAuthorization() -> BOOL;
|
||||||
fn MacGetModeNum(display: u32, numModes: *mut u32) -> BOOL;
|
fn MacGetModeNum(display: u32, numModes: *mut u32) -> BOOL;
|
||||||
fn MacGetModes(
|
fn MacGetModes(
|
||||||
display: u32,
|
display: u32,
|
||||||
@ -665,3 +666,10 @@ pub fn change_resolution(name: &str, width: usize, height: usize) -> ResultType<
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn check_super_user_permission() -> ResultType<bool> {
|
||||||
|
unsafe {
|
||||||
|
Ok(MacCheckAdminAuthorization() == YES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -707,10 +707,10 @@ pub fn is_root() -> bool {
|
|||||||
pub fn check_super_user_permission() -> bool {
|
pub fn check_super_user_permission() -> bool {
|
||||||
#[cfg(feature = "flatpak")]
|
#[cfg(feature = "flatpak")]
|
||||||
return true;
|
return true;
|
||||||
#[cfg(any(windows, target_os = "linux"))]
|
#[cfg(any(windows, target_os = "linux", target_os = "macos"))]
|
||||||
return crate::platform::check_super_user_permission().unwrap_or(false);
|
return crate::platform::check_super_user_permission().unwrap_or(false);
|
||||||
#[cfg(not(any(windows, target_os = "linux")))]
|
#[cfg(not(any(windows, target_os = "linux", target_os = "macos")))]
|
||||||
true
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user