Initial commit

Signed-off-by: Marko Korhonen <marko.korhonen@reekynet.com>
This commit is contained in:
Marko Korhonen 2020-01-19 21:33:52 +02:00
commit 5f81577b83
No known key found for this signature in database
GPG key ID: 911B85FBC6003FE5
7 changed files with 398 additions and 0 deletions

31
src/cli.rs Normal file
View file

@ -0,0 +1,31 @@
extern crate clap;
use clap::{App, Arg};
pub fn get_args() -> clap::ArgMatches<'static> {
App::new("LiQuid Screen Dim")
.version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.arg(
Arg::with_name("dim")
.long("dim")
.short("d")
.takes_value(false)
.help("Dims the screen to idle level set in configuration"),
)
.arg(
Arg::with_name("resume")
.long("resume")
.short("r")
.takes_value(false)
.help("Sets the backlight to the value it was before dimming"),
)
.arg(
Arg::with_name("config")
.long("config")
.short("c")
.takes_value(true)
.help("Sets a custom config file"),
)
.get_matches()
}

52
src/config.rs Normal file
View file

@ -0,0 +1,52 @@
use super::fs;
use super::Config;
use std::path::PathBuf;
use xdg::BaseDirectories;
extern crate xdg;
fn default_config() -> Config {
Config {
resume_file_path: PathBuf::from("/tmp/lqsd-resume"),
idle_level: 0,
dim_speed: 50,
resume_speed: 25,
}
}
fn xdg_config() -> PathBuf {
BaseDirectories::with_prefix("lqsd")
.expect("cannot create configuration directory")
.place_config_file("config.toml")
.unwrap()
}
pub fn load_xdg() -> Config {
let path = xdg_config();
if !path.exists() {
println!(
"{} does not exist, writing default configuration",
path.display()
);
match fs::write(&path, toml::to_string(&default_config()).unwrap()) {
Ok(()) => println!("Default config saved to {}", path.display()),
Err(err) => eprintln!("Failed to write default config: {}", err),
};
default_config()
} else {
let toml = fs::read(&path).unwrap();
let config: Config = toml::from_str(&toml).unwrap();
config
}
}
pub fn load_user(path: PathBuf) -> Config {
if !path.exists() {
panic!("{} does not exist", path.display());
} else {
let toml = fs::read(&path).unwrap();
let config: Config = toml::from_str(&toml).unwrap();
config
}
}

22
src/fs.rs Normal file
View file

@ -0,0 +1,22 @@
use std::fs::{remove_file, File};
use std::io::prelude::*;
use std::path::PathBuf;
pub fn write(path: &PathBuf, contents: String) -> std::io::Result<()> {
let mut file = File::create(path)?;
file.write_all(contents.as_bytes())?;
file.sync_data()?;
Ok(())
}
pub fn read(path: &PathBuf) -> std::io::Result<String> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
pub fn remove(path: &PathBuf) -> std::io::Result<()> {
remove_file(path)?;
Ok(())
}

88
src/main.rs Normal file
View file

@ -0,0 +1,88 @@
extern crate clap;
mod cli;
mod config;
mod fs;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::process::Command;
use std::{thread, time};
#[derive(Deserialize, Serialize)]
pub struct Config {
resume_file_path: PathBuf,
idle_level: i32,
dim_speed: u64,
resume_speed: u64,
}
fn transition(w_brightness: i32, speed: time::Duration) {
let c_brightness = get_brightness();
println!("Transitioning from {}% to {}%", c_brightness, w_brightness);
if c_brightness < w_brightness {
for n in c_brightness..w_brightness {
if n != c_brightness {
set_brightness(n);
thread::sleep(speed);
}
}
} else {
for n in (w_brightness..c_brightness).rev() {
if n != c_brightness {
set_brightness(n);
thread::sleep(speed);
}
}
}
}
fn set_brightness(brightness: i32) {
Command::new("light")
.args(&["-S", &brightness.to_string()])
.spawn()
.expect("Failed to execute command 'light'");
}
fn get_brightness() -> i32 {
let output = Command::new("light")
.arg("-G")
.output()
.expect("Failed to execute command 'light'");
let string = String::from_utf8_lossy(&output.stdout);
let float: f32 = string.trim().parse().unwrap();
float.round() as i32
}
fn main() {
let args = cli::get_args();
let conf: Config;
if args.is_present("config") {
let config_path = PathBuf::from(args.value_of("config").unwrap());
conf = config::load_user(config_path);
} else {
conf = config::load_xdg();
}
let dim_speed = time::Duration::from_millis(conf.dim_speed);
let resume_speed = time::Duration::from_millis(conf.resume_speed);
if args.is_present("dim") {
let current_brightness = get_brightness().to_string();
match fs::write(&conf.resume_file_path, current_brightness) {
Ok(()) => println!("Current brightness written to resume file"),
Err(err) => eprintln!("Error writing brightness to resume file: {}", err),
}
transition(conf.idle_level, dim_speed);
}
if args.is_present("resume") {
let old_brightness: i32 = fs::read(&conf.resume_file_path).unwrap().parse().unwrap();
transition(old_brightness, resume_speed);
match fs::remove(&conf.resume_file_path) {
Ok(()) => println!("Resume file removed"),
Err(err) => eprintln!("Failed to remove resume file: {}", err),
}
}
}