#![allow(dead_code)]
use std::os::raw::c_int;
use std::os::raw::c_void;
use std::ptr::{null, null_mut};
use static_assertions::const_assert;
type CGDirectDisplayID = u32;
#[derive(Debug, Default, Hash, Eq, PartialEq, Clone, Copy)]
#[repr(C)]
pub struct DisplayID {
id: CGDirectDisplayID,
}
#[derive(Debug, Default, Clone)]
#[repr(C)]
pub struct CGSDisplayModeDescription {
pub mode: i32,
flags: u32,
pub width: u32,
pub height: u32,
pub depth: u32,
dc2: [u32; 21],
dc3: [u32; 21],
dc4: u16,
pub freq: u16,
dc5: [u8; 16], pub scale: f32,
}
const_assert!(std::mem::size_of::<CGSDisplayModeDescription>() == 0xD4);
#[derive(Debug)]
#[repr(C)]
pub struct CGPoint {
pub x: f64,
pub y: f64,
}
#[derive(Debug)]
#[repr(C)]
pub struct CGRect {
pub origin: CGPoint,
pub size: CGPoint,
}
#[derive(Debug, Eq, PartialEq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum CGError {
cannotComplete = 1004,
failure = 1000,
illegalArgument = 1001,
invalidConnection = 1002,
invalidContext = 1003,
invalidOperation = 1010,
noneAvailable = 1011,
notImplemented = 1006,
rangeCheck = 1007,
success = 0,
typeCheck = 1008,
}
#[derive(Debug)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum CGConfigureOption {
#[allow(unused)]
kCGConfigureForAppOnly = 0,
#[allow(unused)]
kCGConfigureForSession = 1,
kCGConfigurePermanently = 2,
}
#[allow(non_upper_case_globals)]
pub const kCFAllocatorDefault: *const c_void = null();
pub type CGDisplayConfigRef = *mut c_void;
pub type CGDisplayModeRef = *const c_void;
pub type CGDisplayFadeInterval = f32;
pub type CGDisplayModeArray = *const c_void;
pub type CFArray = *const c_void;
pub type CFTypeRef = *const c_void;
pub type CFAllocator = *const c_void;
pub type CFUUID = *const c_void;
pub type CFIndex = c_int;
pub type CFString = *const c_void;
pub type CFDictionary = *const c_void;
pub type CFStringEncoding = u32;
#[derive(Debug)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum CFStringBuiltInEncodings {
ASCII = 1536,
UTF8 = 134217984,
}
impl From<CFStringBuiltInEncodings> for CFStringEncoding {
fn from(value: CFStringBuiltInEncodings) -> Self {
value as Self
}
}
#[link(name = "AppKit", kind = "framework")]
#[link(name = "IOKit", kind = "framework")]
#[link(name = "ApplicationServices", kind = "framework")]
#[link(name = "DisplayServices", kind = "framework")]
#[link(name = "CoreDisplay", kind = "framework")]
#[link(name = "OSD", kind = "framework")]
#[link(name = "MonitorPanel", kind = "framework")]
#[link(name = "SkyLight", kind = "framework")]
unsafe extern "C" {
fn CFRelease(cf: CFTypeRef);
fn CFStringGetCString(
string: CFString,
buffer: *mut u8,
buffer_size: CFIndex,
encoding: CFStringEncoding,
) -> bool;
fn CFUUIDCreateString(allocator: CFAllocator, uuid: CFUUID) -> CFString;
fn CFArrayGetCount(array: CFArray) -> usize;
fn CFArrayGetValueAtIndex(array: CFArray, idx: CFIndex) -> *const c_void;
fn CGGetOnlineDisplayList(
max_displays: u32,
online_displays: *mut CGDirectDisplayID,
display_count: *mut u32,
) -> CGError;
fn CGGetActiveDisplayList(
max_displays: u32,
active_displays: *mut CGDirectDisplayID,
display_count: *mut u32,
) -> CGError;
fn CGDisplaySerialNumber(display_id: CGDirectDisplayID) -> u32;
fn CGDisplayModelNumber(display_id: CGDirectDisplayID) -> u32;
fn CGDisplayVendorNumber(display_id: CGDirectDisplayID) -> u32;
fn CGDisplayRotation(display_id: CGDirectDisplayID) -> f64;
fn CGDisplayBounds(display_id: CGDirectDisplayID) -> CGRect;
fn CGDisplayIsActive(display_id: CGDirectDisplayID) -> bool;
fn CGDisplayIsInMirrorSet(display_id: CGDirectDisplayID) -> bool;
fn CGDisplayCreateUUIDFromDisplayID(display_id: CGDirectDisplayID) -> CFUUID;
fn CGDisplayModeRelease(mode: CGDisplayModeRef);
fn CGDisplayCopyAllDisplayModes(
display_id: CGDirectDisplayID,
options: CFDictionary,
) -> CFArray;
fn CGDisplayCopyDisplayMode(display_id: CGDirectDisplayID) -> CGDisplayModeRef;
fn CGDisplayModeGetWidth(mode: CGDisplayModeRef) -> usize;
fn CGDisplayModeGetHeight(mode: CGDisplayModeRef) -> usize;
fn CGDisplayModeGetRefreshRate(mode: CGDisplayModeRef) -> f64;
fn CGDisplayModeGetIOFlags(mode: CGDisplayModeRef) -> u32;
fn CGDisplayModeGetIODisplayModeID(mode: CGDisplayModeRef) -> i32;
fn CGDisplayModeGetPixelWidth(mode: CGDisplayModeRef) -> usize;
fn CGDisplayModeGetPixelHeight(mode: CGDisplayModeRef) -> usize;
fn CGDisplayModeIsUsableForDesktopGUI(mode: CGDisplayModeRef) -> bool;
fn CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError;
fn CGCompleteDisplayConfiguration(
config: CGDisplayConfigRef,
option: CGConfigureOption,
) -> CGError;
fn CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError;
fn CGConfigureDisplayFadeEffect(
config: CGDisplayConfigRef,
fade_out_seconds: CGDisplayFadeInterval,
fade_in_seconds: CGDisplayFadeInterval,
fade_red: f32,
fade_green: f32,
fade_blue: f32,
) -> CGError;
fn CGConfigureDisplayOrigin(
config: CGDisplayConfigRef,
display_id: CGDirectDisplayID,
x: i32,
y: i32,
) -> CGError;
fn CGConfigureDisplayWithDisplayMode(
config: CGDisplayConfigRef,
display_id: CGDirectDisplayID,
mode: CGDisplayModeRef,
options: CFDictionary,
) -> CGError;
fn CGConfigureDisplayMirrorOfDisplay(
config: CGDisplayConfigRef,
display_id: CGDirectDisplayID,
master_id: CGDirectDisplayID,
) -> CGError;
fn CGDisplayRegisterReconfigurationCallback(
callback: extern "C" fn(),
user_info: *mut c_void,
) -> CGError;
fn CGDisplayMirrorsDisplay(display_id: CGDirectDisplayID) -> CGDirectDisplayID;
pub fn NSApplicationLoad() -> bool;
pub fn CFRunLoopRun();
fn CGSGetCurrentDisplayMode(display: CGDirectDisplayID, mode_num: *mut c_int) -> CGError;
fn CGSGetNumberOfDisplayModes(display: CGDirectDisplayID, num_modes: *mut c_int) -> CGError;
fn CGSGetDisplayModeDescriptionOfLength(
display_id: CGDirectDisplayID,
index: c_int,
mode: *mut CGSDisplayModeDescription,
length: c_int,
) -> CGError;
fn CGSConfigureDisplayMode(
config: CGDisplayConfigRef,
display_id: CGDirectDisplayID,
mode_num: c_int,
) -> CGError;
fn CGSConfigureDisplayEnabled(
config: CGDisplayConfigRef,
display_id: CGDirectDisplayID,
enabled: bool,
) -> CGError;
fn SLSSetDisplayRotation(display_id: CGDirectDisplayID, rotation: i32) -> CGError;
fn SLSSetDisplayBrightness(display_id: CGDirectDisplayID, brightness: i32) -> CGError;
fn DisplayServicesGetBrightness(display_id: CGDirectDisplayID, brightness: *mut f32)
-> CGError;
fn DisplayServicesSetBrightness(display_id: CGDirectDisplayID, brightness: f32) -> CGError;
}
pub fn cf_release(cf: CFTypeRef) {
unsafe { CFRelease(cf) }
}
pub fn cf_string_get_cstring(
string: CFString,
buffer: &mut [u8],
encoding: CFStringEncoding,
) -> bool {
unsafe { CFStringGetCString(string, buffer.as_mut_ptr(), buffer.len() as c_int, encoding) }
}
pub fn cf_uuid_create_string(allocator: CFAllocator, uuid: CFUUID) -> CFString {
unsafe { CFUUIDCreateString(allocator, uuid) }
}
pub fn cg_get_online_display_list(
online_displays: &mut [DisplayID],
display_count: &mut u32,
) -> CGError {
unsafe {
CGGetOnlineDisplayList(
online_displays.len() as u32,
online_displays.as_mut_ptr() as *mut CGDirectDisplayID,
display_count,
)
}
}
pub fn cg_get_active_display_list(
active_displays: &mut [DisplayID],
display_count: &mut u32,
) -> CGError {
unsafe {
CGGetActiveDisplayList(
active_displays.len() as u32,
active_displays.as_mut_ptr() as *mut CGDirectDisplayID,
display_count,
)
}
}
pub fn cg_display_serial_number(display_id: DisplayID) -> u32 {
unsafe { CGDisplaySerialNumber(display_id.id) }
}
pub fn cg_display_model_number(display_id: DisplayID) -> u32 {
unsafe { CGDisplayModelNumber(display_id.id) }
}
pub fn cg_display_vendor_number(display_id: DisplayID) -> u32 {
unsafe { CGDisplayModelNumber(display_id.id) }
}
pub fn cg_display_rotation(display_id: DisplayID) -> f64 {
unsafe { CGDisplayRotation(display_id.id) }
}
pub fn cg_display_bounds(display_id: DisplayID) -> CGRect {
unsafe { CGDisplayBounds(display_id.id) }
}
pub fn cg_display_is_active(display_id: DisplayID) -> bool {
unsafe { CGDisplayIsActive(display_id.id) }
}
pub fn cg_display_is_in_mirror_set(display_id: DisplayID) -> bool {
unsafe { CGDisplayIsInMirrorSet(display_id.id) }
}
pub fn cg_display_create_uuid_from_display_id(display_id: DisplayID) -> CFUUID {
unsafe { CGDisplayCreateUUIDFromDisplayID(display_id.id) }
}
pub fn cg_display_mode_release(mode: CGDisplayModeRef) {
unsafe { CGDisplayModeRelease(mode) }
}
pub fn cg_display_copy_all_display_modes(display_id: DisplayID) -> CGDisplayModeArray {
unsafe { CGDisplayCopyAllDisplayModes(display_id.id, null()) }
}
pub fn cg_display_modes_get_count(modes: CGDisplayModeArray) -> usize {
unsafe { CFArrayGetCount(modes) }
}
pub fn cg_display_modes_at_index(modes: CGDisplayModeArray, idx: CFIndex) -> CGDisplayModeRef {
unsafe { CFArrayGetValueAtIndex(modes, idx) }
}
pub fn cg_display_copy_display_mode(display_id: DisplayID) -> Option<CGDisplayModeRef> {
unsafe {
let mode = CGDisplayCopyDisplayMode(display_id.id);
if !mode.is_null() { Some(mode) } else { None }
}
}
pub fn cg_display_mode_get_width(mode: &CGDisplayModeRef) -> usize {
unsafe { CGDisplayModeGetWidth(*mode) }
}
pub fn cg_display_mode_get_height(mode: &CGDisplayModeRef) -> usize {
unsafe { CGDisplayModeGetHeight(*mode) }
}
pub fn cg_display_mode_get_pixel_width(mode: &CGDisplayModeRef) -> usize {
unsafe { CGDisplayModeGetPixelWidth(*mode) }
}
pub fn cg_display_mode_get_pixel_height(mode: &CGDisplayModeRef) -> usize {
unsafe { CGDisplayModeGetPixelHeight(*mode) }
}
pub fn cg_display_mode_get_refresh_rate(mode: &CGDisplayModeRef) -> f64 {
unsafe { CGDisplayModeGetRefreshRate(*mode) }
}
pub fn cg_display_mode_get_io_flags(mode: &CGDisplayModeRef) -> u32 {
unsafe { CGDisplayModeGetIOFlags(*mode) }
}
pub fn cg_display_mode_get_io_display_mode_id(mode: &CGDisplayModeRef) -> i32 {
unsafe { CGDisplayModeGetIODisplayModeID(*mode) }
}
pub fn cg_display_mode_is_usable_for_desktop_gui(mode: &CGDisplayModeRef) -> bool {
unsafe { CGDisplayModeIsUsableForDesktopGUI(*mode) }
}
pub fn cg_begin_display_configuration() -> Result<CGDisplayConfigRef, CGError> {
unsafe {
let mut config_ref: CGDisplayConfigRef = null_mut();
let error = CGBeginDisplayConfiguration(&mut config_ref);
match error {
CGError::success => Ok(config_ref),
_ => Err(error),
}
}
}
pub fn cg_complete_display_configuration(
config_ref: CGDisplayConfigRef,
option: CGConfigureOption,
) -> CGError {
unsafe { CGCompleteDisplayConfiguration(config_ref, option) }
}
pub fn cg_cancel_display_configuration(config_ref: CGDisplayConfigRef) -> CGError {
unsafe { CGCancelDisplayConfiguration(config_ref) }
}
pub fn cg_configure_display_origin(
config_ref: &CGDisplayConfigRef,
display_id: DisplayID,
x: i32,
y: i32,
) -> CGError {
unsafe { CGConfigureDisplayOrigin(*config_ref, display_id.id, x, y) }
}
pub fn cg_configure_display_with_display_mode(
config_ref: &CGDisplayConfigRef,
display_id: DisplayID,
mode: &CGDisplayModeRef,
) -> CGError {
unsafe { CGConfigureDisplayWithDisplayMode(*config_ref, display_id.id, *mode, null()) }
}
pub fn cg_configure_display_fade_effect(
config_ref: &CGDisplayConfigRef,
fade_out_seconds: CGDisplayFadeInterval,
fade_in_seconds: CGDisplayFadeInterval,
fade_red: f32,
fade_green: f32,
fade_blue: f32,
) -> CGError {
unsafe {
CGConfigureDisplayFadeEffect(
*config_ref,
fade_out_seconds,
fade_in_seconds,
fade_red,
fade_green,
fade_blue,
)
}
}
pub fn cg_configure_display_mirror_of_display(
config_ref: &CGDisplayConfigRef,
display_id: DisplayID,
master_id: Option<DisplayID>,
) -> CGError {
let target_id = master_id.map(|d| d.id).unwrap_or(0);
unsafe { CGConfigureDisplayMirrorOfDisplay(*config_ref, display_id.id, target_id) }
}
pub fn cg_display_register_reconfiguration_callback(cb: extern "C" fn()) -> CGError {
unsafe { CGDisplayRegisterReconfigurationCallback(cb, null_mut()) }
}
pub fn ns_application_load() -> bool {
unsafe { NSApplicationLoad() }
}
pub fn cf_run_loop_run() {
unsafe { CFRunLoopRun() }
}
pub fn cgs_get_current_display_mode(display: DisplayID, mode: &mut i32) -> CGError {
unsafe { CGSGetCurrentDisplayMode(display.id, mode) }
}
pub fn cgs_get_number_of_display_modes(display: DisplayID, num: &mut i32) -> CGError {
unsafe { CGSGetNumberOfDisplayModes(display.id, num) }
}
pub fn cgs_get_display_mode_description(
display_id: DisplayID,
index: i32,
mode_desc: &mut CGSDisplayModeDescription,
) -> CGError {
unsafe {
CGSGetDisplayModeDescriptionOfLength(
display_id.id,
index,
mode_desc,
std::mem::size_of::<CGSDisplayModeDescription>() as c_int,
)
}
}
pub fn cgs_configure_display_mode(
config_ref: &CGDisplayConfigRef,
display_id: DisplayID,
mode_num: i32,
) -> CGError {
unsafe { CGSConfigureDisplayMode(*config_ref, display_id.id, mode_num) }
}
pub fn cgs_configure_display_enabled(
config_ref: &CGDisplayConfigRef,
display_id: DisplayID,
enabled: bool,
) -> CGError {
unsafe { CGSConfigureDisplayEnabled(*config_ref, display_id.id, enabled) }
}
pub fn cg_display_mirrors_display(display_id: DisplayID) -> Option<DisplayID> {
let mirrored_id = unsafe { CGDisplayMirrorsDisplay(display_id.id) };
if mirrored_id == 0 {
None
} else {
Some(DisplayID { id: mirrored_id })
}
}
pub fn sls_set_display_rotation(display_id: DisplayID, rotation: i32) -> CGError {
unsafe { SLSSetDisplayRotation(display_id.id, rotation) }
}
pub fn display_services_get_brightness(display_id: DisplayID, brightness: &mut f32) -> CGError {
unsafe { DisplayServicesGetBrightness(display_id.id, brightness) }
}
pub fn display_services_set_brightness(display_id: DisplayID, brightness: f32) -> CGError {
unsafe { DisplayServicesSetBrightness(display_id.id, brightness) }
}