1. Implement new layout API, replacing previous hard-coded layout. 2. Make the widgets (previously modules) configurable. 3. Split some widgets into smaller modules. 4. Configuration file (reluctantly JSON at time of writing). 5. More correct damage handling, copying damage to next buffer.
140 lines
3.9 KiB
Rust
140 lines
3.9 KiB
Rust
use crate::color::Color;
|
|
use crate::widgets::bar_widget::{BarWidget, BarWidgetImpl};
|
|
|
|
use std::fs::OpenOptions;
|
|
use std::io::{Error, ErrorKind};
|
|
use std::io::{Read, Write};
|
|
use std::path::{Path, PathBuf};
|
|
|
|
pub struct Backlight {
|
|
device_path: PathBuf,
|
|
cur_brightness: u64,
|
|
max_brightness: u64,
|
|
}
|
|
|
|
fn read_file_as_u64(path: &Path) -> Result<u64, Error> {
|
|
let mut file = OpenOptions::new().read(true).open(path)?;
|
|
let mut str = String::new();
|
|
file.read_to_string(&mut str)?;
|
|
str.pop();
|
|
str.parse::<u64>()
|
|
.map_err(|_e| Error::new(ErrorKind::Other, "unable to parse value"))
|
|
}
|
|
|
|
fn write_file_as_u64(path: &Path, value: u64) -> Result<(), Error> {
|
|
let mut file = OpenOptions::new().write(true).open(path)?;
|
|
file.write_fmt(format_args!("{}", value))
|
|
}
|
|
|
|
impl Backlight {
|
|
pub fn update(&mut self) -> Result<(), Error> {
|
|
self.cur_brightness = read_file_as_u64(self.device_path.join("brightness").as_path())?;
|
|
self.max_brightness = read_file_as_u64(self.device_path.join("max_brightness").as_path())?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn sync(&mut self) -> Result<(), Error> {
|
|
write_file_as_u64(
|
|
self.device_path.join("brightness").as_path(),
|
|
self.cur_brightness,
|
|
)?;
|
|
self.update()?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn brightness(&self) -> f32 {
|
|
if self.cur_brightness > self.max_brightness {
|
|
// what.
|
|
return 1.0;
|
|
}
|
|
|
|
(self.cur_brightness as f32 / self.max_brightness as f32)
|
|
}
|
|
|
|
pub fn set(&mut self, val: f32) -> Result<(), Error> {
|
|
self.cur_brightness = (self.max_brightness as f32 * val) as u64;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn add(&mut self, diff: f32) -> Result<(), Error> {
|
|
let inc = (self.max_brightness as f32 * diff) as i64;
|
|
|
|
self.cur_brightness = if self.cur_brightness as i64 + inc < 1 {
|
|
1
|
|
} else if self.cur_brightness as i64 + inc > self.max_brightness as i64 {
|
|
self.max_brightness
|
|
} else {
|
|
(self.cur_brightness as i64 + inc) as u64
|
|
};
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn new(font_size: f32, length: u32) -> Result<Box<BarWidget>, Error> {
|
|
let devices = Path::new("/sys/class/backlight").read_dir()?;
|
|
|
|
let first_device = match devices.take(1).next() {
|
|
Some(v) => match v {
|
|
Ok(v) => v,
|
|
Err(_) => return Err(Error::new(ErrorKind::Other, "no backlight device")),
|
|
},
|
|
None => return Err(Error::new(ErrorKind::Other, "no backlight device")),
|
|
};
|
|
let mut dev = Backlight {
|
|
device_path: first_device.path(),
|
|
cur_brightness: 0,
|
|
max_brightness: 0,
|
|
};
|
|
|
|
dev.update()?;
|
|
|
|
Ok(BarWidget::new_simple(font_size, length, Box::new(dev)))
|
|
}
|
|
}
|
|
|
|
impl BarWidgetImpl for Backlight {
|
|
fn name(&self) -> &str {
|
|
"backlight"
|
|
}
|
|
fn value(&self) -> f32 {
|
|
self.brightness()
|
|
}
|
|
fn color(&self) -> Color {
|
|
Color::new(1.0, 1.0, 1.0, 1.0)
|
|
}
|
|
fn inc(&mut self, inc: f32) {
|
|
self.add(inc).unwrap();
|
|
match self.sync() {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
eprintln!("Error while trying to change brightness: {}", err);
|
|
()
|
|
}
|
|
}
|
|
}
|
|
fn set(&mut self, val: f32) {
|
|
self.set(val).unwrap();
|
|
match self.sync() {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
eprintln!("Error while trying to change brightness: {}", err);
|
|
()
|
|
}
|
|
}
|
|
}
|
|
fn toggle(&mut self) {
|
|
self.cur_brightness = if self.cur_brightness == 1 {
|
|
self.max_brightness
|
|
} else {
|
|
1
|
|
};
|
|
match self.sync() {
|
|
Ok(val) => val,
|
|
Err(err) => {
|
|
eprintln!("Error while trying to change brightness: {}", err);
|
|
()
|
|
}
|
|
}
|
|
}
|
|
}
|