diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/sctd.rs | 10 | ||||
| -rw-r--r-- | src/lib.rs | 48 | ||||
| -rw-r--r-- | src/platform.rs | 5 | ||||
| -rw-r--r-- | src/platform/linux.rs | 34 | ||||
| -rw-r--r-- | src/platform/macos.rs | 44 |
5 files changed, 99 insertions, 42 deletions
diff --git a/src/bin/sctd.rs b/src/bin/sctd.rs index 81e65e5..9e648c3 100644 --- a/src/bin/sctd.rs +++ b/src/bin/sctd.rs @@ -48,19 +48,15 @@ fn main() { let new_temp = sctd::get_temp(utc, &ss, latitude, longitude) as u32; if new_temp != temp { temp = new_temp; - info!("setting temperature to {}", temp); + info!("setting temperature to {temp}"); sctd::set_temp(temp); } else { - debug!( - "skipping temperature change as it hasn't changed ({})", - temp - ); + debug!("skipping temperature change as it hasn't changed ({temp})"); } } Err(e) => { error!( - "error calculating sunrise and sunset for {}, {}: {:?}", - latitude, longitude, e + "error calculating sunrise and sunset for {latitude}, {longitude}: {e:?}" ); } } @@ -3,14 +3,16 @@ extern crate log; extern crate spa; +mod platform; + use chrono::prelude::*; use spa::{calc_solar_position, SunriseAndSet}; -use std::os::raw::{c_ushort, c_void}; -use std::ptr; -use x11::xlib::{XCloseDisplay, XDefaultScreen, XFree, XOpenDisplay, XRootWindow}; -use x11::xrandr::{ - XRRAllocGamma, XRRCrtcGamma, XRRGetCrtcGammaSize, XRRGetScreenResourcesCurrent, XRRSetCrtcGamma, -}; + +#[cfg(target_os = "linux")] +use platform::linux as os; + +#[cfg(target_os = "macos")] +use platform::macos as os; const LOW_TEMP: f64 = 3500f64; const HIGH_TEMP: f64 = 5500f64; @@ -26,44 +28,20 @@ pub struct WhitePoint { } pub fn set_temp(temp: u32) { - let ratio: f64 = (temp % 500) as f64 / 500f64; - unsafe { - let display = XOpenDisplay(ptr::null_mut()); - let screen = XDefaultScreen(display); - let root = XRootWindow(display, screen); - let resource = XRRGetScreenResourcesCurrent(display, root); - - for x in 0..(*resource).ncrtc { - let crtcxid = (*resource).crtcs.offset(x as isize); - let size = XRRGetCrtcGammaSize(display, *crtcxid); - let crtc_gamma: *mut XRRCrtcGamma = XRRAllocGamma(size); - let gamma = avg(temp, ratio); - - for i in 0..size { - let g = (65535f64 * i as f64) / size as f64; - *((*crtc_gamma).red as *mut c_ushort).offset(i as isize) = (g * gamma.red) as u16; - *((*crtc_gamma).green as *mut c_ushort).offset(i as isize) = - (g * gamma.green) as u16; - *((*crtc_gamma).blue as *mut c_ushort).offset(i as isize) = (g * gamma.blue) as u16; - } - XRRSetCrtcGamma(display, *crtcxid, crtc_gamma); - XFree(crtc_gamma as *mut c_void); - } - XCloseDisplay(display); - } + os::set_temp(temp); } pub fn reset_temp() { - set_temp(HIGH_TEMP as u32); + os::set_temp(HIGH_TEMP as u32); } fn get_transition_progress_from_elevation(elevation: f64) -> f64 { if elevation < TRANSITION_LOW { - return 0.0; + 0.0 } else if elevation < TRANSITION_HIGH { (TRANSITION_LOW - elevation) / (TRANSITION_LOW - TRANSITION_HIGH) } else { - return 1.0; + 1.0 } } @@ -71,7 +49,7 @@ pub fn get_temp(utc: DateTime<Utc>, ss: &SunriseAndSet, lat: f64, lon: f64) -> f match *ss { SunriseAndSet::Daylight(_, _) => { let elevation = 90f64 - calc_solar_position(utc, lat, lon).unwrap().zenith_angle; - debug!("elevation: {}", elevation); + debug!("elevation: {elevation}"); let progress = get_transition_progress_from_elevation(elevation); LOW_TEMP + (progress * (HIGH_TEMP - LOW_TEMP)) } diff --git a/src/platform.rs b/src/platform.rs new file mode 100644 index 0000000..204fd43 --- /dev/null +++ b/src/platform.rs @@ -0,0 +1,5 @@ +#[cfg(target_os = "linux")] +pub mod linux; + +#[cfg(target_os = "macos")] +pub mod macos; diff --git a/src/platform/linux.rs b/src/platform/linux.rs new file mode 100644 index 0000000..351bcb6 --- /dev/null +++ b/src/platform/linux.rs @@ -0,0 +1,34 @@ +use std::os::raw::{c_ushort, c_void}; +use std::ptr; +use x11::xlib::{XCloseDisplay, XDefaultScreen, XFree, XOpenDisplay, XRootWindow}; +use x11::xrandr::{ + XRRAllocGamma, XRRCrtcGamma, XRRGetCrtcGammaSize, XRRGetScreenResourcesCurrent, XRRSetCrtcGamma, +}; + +pub fn set_temp(temp: u32) { + let ratio: f64 = (temp % 500) as f64 / 500f64; + unsafe { + let display = XOpenDisplay(ptr::null_mut()); + let screen = XDefaultScreen(display); + let root = XRootWindow(display, screen); + let resource = XRRGetScreenResourcesCurrent(display, root); + + for x in 0..(*resource).ncrtc { + let crtcxid = (*resource).crtcs.offset(x as isize); + let size = XRRGetCrtcGammaSize(display, *crtcxid); + let crtc_gamma: *mut XRRCrtcGamma = XRRAllocGamma(size); + let gamma = avg(temp, ratio); + + for i in 0..size { + let g = (65535f64 * i as f64) / size as f64; + *((*crtc_gamma).red as *mut c_ushort).offset(i as isize) = (g * gamma.red) as u16; + *((*crtc_gamma).green as *mut c_ushort).offset(i as isize) = + (g * gamma.green) as u16; + *((*crtc_gamma).blue as *mut c_ushort).offset(i as isize) = (g * gamma.blue) as u16; + } + XRRSetCrtcGamma(display, *crtcxid, crtc_gamma); + XFree(crtc_gamma as *mut c_void); + } + XCloseDisplay(display); + } +} diff --git a/src/platform/macos.rs b/src/platform/macos.rs new file mode 100644 index 0000000..0292250 --- /dev/null +++ b/src/platform/macos.rs @@ -0,0 +1,44 @@ +use core_graphics::display::CGDisplay; + +pub fn set_temp(temp: u32) { + use std::os::raw::c_int; + + let ratio: f64 = (temp % 500) as f64 / 500f64; + let gamma = crate::avg(temp, ratio); + + let main_display = CGDisplay::main(); + + extern "C" { + fn CGSetDisplayTransferByTable( + display: u32, + table_size: u32, + red_table: *const f32, + green_table: *const f32, + blue_table: *const f32, + ) -> c_int; + fn CGDisplayGammaTableCapacity(display: u32) -> u32; + } + + let table_size = unsafe { CGDisplayGammaTableCapacity(main_display.id) } as usize; + + let mut red_table = vec![0.0; table_size]; + let mut green_table = vec![0.0; table_size]; + let mut blue_table = vec![0.0; table_size]; + + for i in 0..table_size { + let value = (i as f32) / (table_size as f32 - 1.0); + red_table[i] = (value * gamma.red as f32).min(1.0); + green_table[i] = (value * gamma.green as f32).min(1.0); + blue_table[i] = (value * gamma.blue as f32).min(1.0); + } + + unsafe { + CGSetDisplayTransferByTable( + main_display.id, + table_size as u32, + red_table.as_ptr(), + green_table.as_ptr(), + blue_table.as_ptr(), + ); + } +} |
