Skip to content

Commit

Permalink
Merge pull request #52 from SimonBrandner/feat/monochrome
Browse files Browse the repository at this point in the history
Fix: properly handle monochrome devices
  • Loading branch information
AaronErhardt authored Dec 28, 2023
2 parents 96e4003 + f48fcdb commit 977bab6
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 48 deletions.
42 changes: 23 additions & 19 deletions tailor_api/src/color.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::led::LedControllerMode;
use atoi::FromRadix16;
use std::{fmt::Display, io, str::FromStr};

Expand All @@ -22,25 +23,28 @@ pub enum ColorProfile {
Multiple(Vec<ColorPoint>),
}

impl Default for ColorProfile {
fn default() -> Self {
Self::Multiple(vec![
ColorPoint {
color: Color { r: 255, g: 0, b: 0 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
ColorPoint {
color: Color { r: 0, g: 255, b: 0 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
ColorPoint {
color: Color { r: 0, g: 0, b: 255 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
])
impl ColorProfile {
pub fn default(mode: LedControllerMode) -> Self {
match mode {
LedControllerMode::Monochrome => Self::None,
LedControllerMode::Rgb => Self::Multiple(vec![
ColorPoint {
color: Color { r: 255, g: 0, b: 0 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
ColorPoint {
color: Color { r: 0, g: 255, b: 0 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
ColorPoint {
color: Color { r: 0, g: 0, b: 255 },
transition: ColorTransition::Linear,
transition_time: 6000,
},
]),
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions tailor_api/src/led.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum LedControllerMode {
Rgb,
Monochrome,
}

#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct LedDeviceInfo {
pub device_name: String,
pub function: String,
pub mode: LedControllerMode,
}

impl LedDeviceInfo {
pub fn device_id(&self) -> String {
let Self {
device_name,
function,
mode: _mode,
} = self;
format!("{device_name}::{function}")
}
Expand Down
2 changes: 1 addition & 1 deletion tailor_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ mod profile;

pub use color::{Color, ColorPoint, ColorProfile, ColorTransition};
pub use fan::FanProfilePoint;
pub use led::LedDeviceInfo;
pub use led::{LedControllerMode, LedDeviceInfo};
pub use profile::{LedProfile, ProfileInfo};
3 changes: 3 additions & 0 deletions tailor_api/src/profile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::LedControllerMode;

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub struct ProfileInfo {
pub fans: Vec<String>,
Expand All @@ -20,4 +22,5 @@ pub struct LedProfile {
pub device_name: String,
pub function: String,
pub profile: String,
pub mode: LedControllerMode,
}
3 changes: 2 additions & 1 deletion tailord/src/dbus/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ impl LedInterface {
None
}
})
.unwrap_or_default();
.unwrap_or_else(|| ColorProfile::default(handle.info.mode));

handle.profile_sender.send(profile).await.unwrap();
}
}
Expand Down
7 changes: 5 additions & 2 deletions tailord/src/dbus/profiles.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use tailor_api::{LedDeviceInfo, ProfileInfo};
use tailor_api::{ColorProfile, LedDeviceInfo, ProfileInfo};
use zbus::{dbus_interface, fdo};

use crate::{
Expand Down Expand Up @@ -92,7 +92,10 @@ impl ProfileInterface {
}

for led_handle in &self.led_handles {
let profile = leds.get(&led_handle.info).cloned().unwrap_or_default();
let profile = match leds.get(&led_handle.info).cloned() {
Some(color_profile) => color_profile,
None => ColorProfile::default(led_handle.info.mode),
};
led_handle
.profile_sender
.send(profile)
Expand Down
1 change: 1 addition & 0 deletions tailord/src/led/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl LedRuntime {
info: LedDeviceInfo {
device_name: data.controller.device_name.clone(),
function: data.controller.function.clone(),
mode: data.controller.mode().clone(),
},
profile_sender,
color_sender,
Expand Down
21 changes: 15 additions & 6 deletions tailord/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::future::pending;

use dbus::{FanInterface, PerformanceInterface, ProfileInterface};
use profiles::Profile;
use tailor_api::{ColorProfile, LedControllerMode};
use tuxedo_ioctl::hal::IoInterface;
use zbus::ConnectionBuilder;

Expand All @@ -19,6 +20,7 @@ use crate::{
fancontrol::FanRuntime,
led::{LedRuntime, LedRuntimeData},
performance::PerformanceProfileRuntime,
profiles::SupportedFeatures,
};

const DBUS_NAME: &str = "com.tux.Tailor";
Expand All @@ -45,6 +47,18 @@ async fn start_runtime() {
// Setup shutdown
let mut shutdown_receiver = shutdown::setup();

let led_devices = tuxedo_sysfs::led::Collection::new()
.await
.map(|c| c.into_inner())
.unwrap_or_default();

let mut mode = LedControllerMode::Rgb;
for device in &led_devices {
if device.mode() == LedControllerMode::Monochrome {
mode = LedControllerMode::Monochrome;
}
}
Profile::init_if_necessary(SupportedFeatures { mode });
let profile = Profile::load();

let (device, _webcam, _tdp) = match IoInterface::new() {
Expand Down Expand Up @@ -81,11 +95,6 @@ async fn start_runtime() {
}
}

let led_devices = tuxedo_sysfs::led::Collection::new()
.await
.map(|c| c.into_inner())
.unwrap_or_default();

let mut led_handles = Vec::new();
let mut led_runtimes = Vec::new();
for led_device in led_devices {
Expand All @@ -101,7 +110,7 @@ async fn start_runtime() {
None
}
})
.unwrap_or_default();
.unwrap_or_else(|| ColorProfile::default(led_device.mode()));

let (handle, runtime) = LedRuntime::new(LedRuntimeData {
controller: led_device,
Expand Down
25 changes: 17 additions & 8 deletions tailord/src/profiles.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{collections::HashMap, path::Component, path::Path};

use crate::{fancontrol::profile::FanProfile, performance::PerformanceProfile};
use tailor_api::{ColorProfile, LedDeviceInfo, LedProfile, ProfileInfo};
use tailor_api::{ColorProfile, LedControllerMode, LedDeviceInfo, LedProfile, ProfileInfo};
use zbus::fdo;

use super::util;
Expand All @@ -20,14 +20,14 @@ fn init_paths() {
})
}

fn init_profiles() {
fn init_profiles(supported_features: SupportedFeatures) {
fn default_profile_exists(base_path: &str) -> bool {
Path::new(base_path).join(DEFAULT_PROFILE_NAME).exists()
}

tracing::debug!("Initialising profiles.");
if !default_profile_exists(KEYBOARD_DIR) {
let profile = ColorProfile::default();
let profile = ColorProfile::default(supported_features.mode);
util::write_json_sync(KEYBOARD_DIR, DEFAULT_PROFILE_NAME, &profile).ok();
}
if !default_profile_exists(FAN_DIR) {
Expand All @@ -50,9 +50,9 @@ fn init_profiles() {
std::os::unix::fs::symlink(default_profile, ACTIVE_PROFILE_PATH).ok();
}

fn init_profiles_if_necessary() {
fn init_profiles_if_necessary(supported_features: SupportedFeatures) {
if !Path::new(ACTIVE_PROFILE_PATH).exists() {
init_profiles();
init_profiles(supported_features);
}
}

Expand All @@ -75,6 +75,11 @@ fn load_fan_profile(name: &str) -> fdo::Result<FanProfile> {
FanProfile::load_config(fan_path(name)?)
}

#[derive(Debug, Clone, Copy)]
pub struct SupportedFeatures {
pub mode: LedControllerMode,
}

#[derive(Debug)]
pub struct Profile {
pub fans: Vec<FanProfile>,
Expand All @@ -83,10 +88,12 @@ pub struct Profile {
}

impl Profile {
pub fn load() -> Self {
pub fn init_if_necessary(supported_features: SupportedFeatures) {
init_paths();
init_profiles_if_necessary();
init_profiles_if_necessary(supported_features);
}

pub fn load() -> Self {
let profile_info = Self::get_active_profile_info().unwrap_or_else(|err| {
tracing::warn!("Failed to load active profile at `{ACTIVE_PROFILE_PATH}`: {err:?}");
ProfileInfo::default()
Expand All @@ -99,10 +106,12 @@ impl Profile {
device_name,
function,
profile,
mode,
} = data;
let info = LedDeviceInfo {
device_name,
function,
mode,
};
let profile = match load_led_profile(&profile) {
Ok(keyboard) => keyboard,
Expand All @@ -112,7 +121,7 @@ impl Profile {
info.device_id(),
err.to_string(),
);
ColorProfile::default()
ColorProfile::default(mode)
}
};
led.insert(info, profile);
Expand Down
9 changes: 5 additions & 4 deletions tuxedo_sysfs/src/led/controller.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::io;

use tailor_api::Color;
use tailor_api::LedControllerMode;

use crate::sysfs_util::{read_int_list, write_string};

use super::{Controller, ControllerMode};
use super::Controller;

impl Controller {
pub async fn new_rgb(
Expand Down Expand Up @@ -91,11 +92,11 @@ impl Controller {
&self.function
}

pub fn mode(&self) -> ControllerMode {
pub fn mode(&self) -> LedControllerMode {
if self.intensities_file.is_some() {
ControllerMode::Rgb
LedControllerMode::Rgb
} else {
ControllerMode::Monochrome
LedControllerMode::Monochrome
}
}
}
7 changes: 0 additions & 7 deletions tuxedo_sysfs/src/led/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,3 @@ pub struct Controller {
brightness_file: tokio_uring::fs::File,
intensities_file: Option<tokio_uring::fs::File>,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ControllerMode {
Rgb,
Monochrome,
}

0 comments on commit 977bab6

Please sign in to comment.