1 use crate::color::Color;
2 use crate::wayland::Request;
3 use anyhow::Result;
4 use tokio::sync::mpsc;
5 use zbus::dbus_interface;
6 
7 #[derive(Debug)]
8 struct Server {
9     tx: mpsc::Sender<Request>,
10     color: Color,
11 }
12 
run(tx: mpsc::Sender<Request>) -> Result<bool>13 pub async fn run(tx: mpsc::Sender<Request>) -> Result<bool> {
14     let _conn = match zbus::ConnectionBuilder::session()?
15         .serve_at(
16             "/",
17             Server {
18                 tx,
19                 color: Default::default(),
20             },
21         )?
22         .name("rs.wl-gammarelay")?
23         .build()
24         .await
25     {
26         Err(zbus::Error::NameTaken) => return Ok(false),
27         other => other?,
28     };
29     Ok(true)
30 }
31 
32 impl Server {
send_color(&self)33     async fn send_color(&self) {
34         let _ = self.tx.send(Request::SetColor(self.color)).await;
35     }
36 }
37 
38 #[dbus_interface(name = "rs.wl.gammarelay")]
39 impl Server {
40     #[dbus_interface(property)]
temperature(&self) -> u1641     async fn temperature(&self) -> u16 {
42         self.color.temp
43     }
44 
45     #[dbus_interface(property)]
set_temperature(&mut self, temp: u16) -> Result<(), zbus::fdo::Error>46     async fn set_temperature(&mut self, temp: u16) -> Result<(), zbus::fdo::Error> {
47         if (1000..=10000).contains(&temp) {
48             self.color.temp = temp;
49             self.send_color().await;
50             Ok(())
51         } else {
52             Err(zbus::fdo::Error::InvalidArgs(
53                 "temperature must be in range [1000,10000]".into(),
54             ))
55         }
56     }
57 
update_temperature( &mut self, #[zbus(signal_context)] cx: zbus::SignalContext<'_>, delta_temp: i16, ) -> Result<(), zbus::fdo::Error>58     async fn update_temperature(
59         &mut self,
60         #[zbus(signal_context)] cx: zbus::SignalContext<'_>,
61         delta_temp: i16,
62     ) -> Result<(), zbus::fdo::Error> {
63         self.color.temp = (self.color.temp as i16 + delta_temp).clamp(1_000, 10_000) as _;
64         self.send_color().await;
65         self.temperature_changed(&cx).await?;
66         Ok(())
67     }
68 
69     #[dbus_interface(property)]
brightness(&self) -> f6470     async fn brightness(&self) -> f64 {
71         self.color.brightness
72     }
73 
74     #[dbus_interface(property)]
set_brightness(&mut self, brightness: f64) -> Result<(), zbus::fdo::Error>75     async fn set_brightness(&mut self, brightness: f64) -> Result<(), zbus::fdo::Error> {
76         if (0.0..=1.0).contains(&brightness) {
77             self.color.brightness = brightness;
78             self.send_color().await;
79             Ok(())
80         } else {
81             Err(zbus::fdo::Error::InvalidArgs(
82                 "brightness must be in range [0,1]".into(),
83             ))
84         }
85     }
86 
update_brightness( &mut self, #[zbus(signal_context)] cx: zbus::SignalContext<'_>, delta_brightness: f64, ) -> Result<(), zbus::fdo::Error>87     async fn update_brightness(
88         &mut self,
89         #[zbus(signal_context)] cx: zbus::SignalContext<'_>,
90         delta_brightness: f64,
91     ) -> Result<(), zbus::fdo::Error> {
92         self.color.brightness = (self.color.brightness + delta_brightness).clamp(0.0, 1.0) as _;
93         self.send_color().await;
94         self.brightness_changed(&cx).await?;
95         Ok(())
96     }
97 
98     #[dbus_interface(property)]
inverted(&self) -> bool99     async fn inverted(&self) -> bool {
100         self.color.inverted
101     }
102 
103     #[dbus_interface(property)]
set_inverted(&mut self, value: bool)104     async fn set_inverted(&mut self, value: bool) {
105         self.color.inverted = value;
106         self.send_color().await;
107     }
108 
toggle_inverted( &mut self, #[zbus(signal_context)] cx: zbus::SignalContext<'_>, ) -> Result<(), zbus::fdo::Error>109     async fn toggle_inverted(
110         &mut self,
111         #[zbus(signal_context)] cx: zbus::SignalContext<'_>,
112     ) -> Result<(), zbus::fdo::Error> {
113         self.color.inverted = !self.color.inverted;
114         self.send_color().await;
115         self.brightness_changed(&cx).await?;
116         Ok(())
117     }
118 }
119