Got upower connection to compile, at least
This commit is contained in:
@@ -3,6 +3,11 @@
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
libxkbcommon
|
||||
cargo
|
||||
rust-analyzer
|
||||
rustc
|
||||
rustfmt
|
||||
cargo-fmt
|
||||
# keep this line if you use bash
|
||||
bashInteractive
|
||||
];
|
||||
|
||||
134
src/main.rs
134
src/main.rs
@@ -1,33 +1,37 @@
|
||||
|
||||
pub mod upower;
|
||||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::Rc,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
use std::sync::RwLock;
|
||||
use wayland_client::{Attached, Main, protocol::{
|
||||
wl_shm,
|
||||
wl_surface::WlSurface,
|
||||
wl_output::WlOutput,
|
||||
}};
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||
use wayland_client::{
|
||||
protocol::{wl_output::WlOutput, wl_shm, wl_surface::WlSurface},
|
||||
Attached, Main,
|
||||
};
|
||||
|
||||
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
|
||||
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
|
||||
zwlr_layer_shell_v1::{self, ZwlrLayerShellV1},
|
||||
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
|
||||
};
|
||||
|
||||
use smithay_client_toolkit::{
|
||||
default_environment,
|
||||
new_default_environment,
|
||||
environment::SimpleGlobal,
|
||||
output::OutputInfo,
|
||||
WaylandSource,
|
||||
output::with_output_info,
|
||||
shm::AutoMemPool
|
||||
default_environment, environment::SimpleGlobal, new_default_environment,
|
||||
output::with_output_info, output::OutputInfo, shm::AutoMemPool, WaylandSource,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PowerState {
|
||||
/// Level, between 0 and 1
|
||||
level: f32,
|
||||
/// True if line power is available.
|
||||
charging: bool,
|
||||
/// Time to full charge/empty, in seconds
|
||||
time_remaining: f32,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct AppState {
|
||||
display_status: Arc<RwLock<Option<PowerState>>>,
|
||||
}
|
||||
|
||||
default_environment! {
|
||||
MyEnv,
|
||||
@@ -42,19 +46,8 @@ default_environment!{
|
||||
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub enum RenderEvent {
|
||||
Closed,
|
||||
Configure {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PowerState {
|
||||
/// Level, between 0 and 1
|
||||
level: f32,
|
||||
/// True if line power is available.
|
||||
charging: bool,
|
||||
/// Time to full charge/empty, in seconds
|
||||
time_remaining: f32,
|
||||
Configure { width: u32, height: u32 },
|
||||
DataChanged,
|
||||
}
|
||||
|
||||
pub struct Surface {
|
||||
@@ -63,7 +56,7 @@ pub struct Surface {
|
||||
next_render_event: Rc<Cell<Option<RenderEvent>>>,
|
||||
pool: AutoMemPool,
|
||||
dimensions: (u32, u32),
|
||||
display_status: Arc<RwLock<>>
|
||||
display_status: Arc<RwLock<Option<PowerState>>>,
|
||||
}
|
||||
|
||||
impl Surface {
|
||||
@@ -72,6 +65,7 @@ impl Surface {
|
||||
surface: WlSurface,
|
||||
layer_shell: &Attached<ZwlrLayerShellV1>,
|
||||
pool: AutoMemPool,
|
||||
state: &AppState,
|
||||
) -> Self {
|
||||
let layer_surface: Main<ZwlrLayerSurfaceV1> = layer_shell.get_layer_surface(
|
||||
&surface,
|
||||
@@ -91,9 +85,14 @@ impl Surface {
|
||||
(zwlr_layer_surface_v1::Event::Closed, _) => {
|
||||
nre_handle.set(Some(RenderEvent::Closed));
|
||||
}
|
||||
(zwlr_layer_surface_v1::Event::Configure {serial, width, height}, next)
|
||||
if next != Some(RenderEvent::Closed) =>
|
||||
{
|
||||
(
|
||||
zwlr_layer_surface_v1::Event::Configure {
|
||||
serial,
|
||||
width,
|
||||
height,
|
||||
},
|
||||
next,
|
||||
) if next != Some(RenderEvent::Closed) => {
|
||||
layer_surface.ack_configure(serial);
|
||||
nre_handle.set(Some(RenderEvent::Configure { width, height }));
|
||||
}
|
||||
@@ -107,7 +106,8 @@ impl Surface {
|
||||
layer_surface,
|
||||
next_render_event,
|
||||
pool,
|
||||
dimensions: (0, 0)
|
||||
dimensions: (0, 0),
|
||||
display_status: Arc::clone(&state.display_status),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,10 @@ impl Surface {
|
||||
}
|
||||
false
|
||||
}
|
||||
Some(RenderEvent::DataChanged) => {
|
||||
self.draw();
|
||||
false
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
@@ -130,8 +134,9 @@ impl Surface {
|
||||
let width = self.dimensions.0 as i32;
|
||||
let height = self.dimensions.1 as i32;
|
||||
|
||||
let (canvas, buffer) =
|
||||
self.pool.buffer(width, height, stride, wl_shm::Format::Argb8888)
|
||||
let (canvas, buffer) = self
|
||||
.pool
|
||||
.buffer(width, height, stride, wl_shm::Format::Argb8888)
|
||||
.unwrap();
|
||||
for dst_pixel in canvas.chunks_exact_mut(4) {
|
||||
let pixel = 0x01_00_8f_00u32.to_ne_bytes();
|
||||
@@ -156,12 +161,22 @@ impl Drop for Surface {
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
|
||||
let (env, display, queue) = new_default_environment!(
|
||||
MyEnv,
|
||||
fields = [
|
||||
layer_shell: SimpleGlobal::new(),
|
||||
],
|
||||
)?;
|
||||
let mut app_state = AppState::default();
|
||||
|
||||
// Spawn upower watcher
|
||||
let upower_channel = {
|
||||
let (sender, channel) = calloop::channel::channel();
|
||||
let reporter = upower::PowerReporter {
|
||||
sender,
|
||||
status: Arc::clone(&app_state.display_status),
|
||||
};
|
||||
|
||||
upower::spawn_upower(reporter)?;
|
||||
channel
|
||||
};
|
||||
|
||||
let (env, display, queue) =
|
||||
new_default_environment!(MyEnv, fields = [layer_shell: SimpleGlobal::new(),],)?;
|
||||
|
||||
let env_handle = env.clone();
|
||||
|
||||
@@ -171,14 +186,20 @@ fn main() -> anyhow::Result<()> {
|
||||
let surfaces = Rc::new(RefCell::new(Vec::new()));
|
||||
|
||||
let surfaces_handle = Rc::clone(&surfaces);
|
||||
let app_state_handle = app_state.clone();
|
||||
let output_handler = move |output: WlOutput, info: &OutputInfo| {
|
||||
if info.obsolete {
|
||||
surfaces_handle.borrow_mut().retain(|(i, _)| *i != info.id);
|
||||
output.release();
|
||||
} else {
|
||||
let surface = env_handle.create_surface().detach();
|
||||
let pool = env_handle.create_auto_pool().expect("Failed to create a memeory pool!");
|
||||
surfaces_handle.borrow_mut().push((info.id, Surface::new(&output, surface, &layer_shell.clone(), pool)));
|
||||
let pool = env_handle
|
||||
.create_auto_pool()
|
||||
.expect("Failed to create a memeory pool!");
|
||||
surfaces_handle.borrow_mut().push((
|
||||
info.id,
|
||||
Surface::new(&output, surface, &layer_shell.clone(), pool, &app_state_handle),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -189,10 +210,25 @@ fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let _listener_handle = env.listen_for_outputs(move |output, info, _| output_handler(output, info));
|
||||
let _listener_handle =
|
||||
env.listen_for_outputs(move |output, info, _| output_handler(output, info));
|
||||
let mut event_loop = calloop::EventLoop::<()>::try_new().expect("Failed to start event loop");
|
||||
|
||||
WaylandSource::new(queue).quick_insert(event_loop.handle()).unwrap();
|
||||
let surfaces_handle = Rc::clone(&surfaces);
|
||||
event_loop.handle().insert_source(
|
||||
upower_channel,
|
||||
move |_, _, _| {
|
||||
for (_, surface) in surfaces_handle.borrow_mut().iter() {
|
||||
if surface.next_render_event.get().is_none() {
|
||||
surface.next_render_event.set(Some(RenderEvent::DataChanged));
|
||||
}
|
||||
}
|
||||
}
|
||||
).unwrap();
|
||||
|
||||
WaylandSource::new(queue)
|
||||
.quick_insert(event_loop.handle())
|
||||
.unwrap();
|
||||
loop {
|
||||
{
|
||||
let mut surfaces = surfaces.borrow_mut();
|
||||
@@ -209,5 +245,7 @@ fn main() -> anyhow::Result<()> {
|
||||
display.flush().unwrap();
|
||||
event_loop.dispatch(None, &mut ()).unwrap();
|
||||
}
|
||||
|
||||
|
||||
//println!("Registry: {:#?}", env);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
use zbus;
|
||||
use upower_dbus;
|
||||
use std::sync::{Arc, RwLock, mpsc::{Sender, Receiver}};
|
||||
use std::sync::mpsc::SyncSender;
|
||||
use crate::PowerState;
|
||||
use std::sync::mpsc::SyncSender;
|
||||
use std::sync::{
|
||||
mpsc::{Receiver, Sender},
|
||||
Arc, RwLock,
|
||||
};
|
||||
use upower_dbus;
|
||||
|
||||
use calloop::channel::Sender as CalloopSender;
|
||||
use zbus;
|
||||
|
||||
pub struct PowerReporter {
|
||||
sender: Sender<()>,
|
||||
status: Arc<RwLock<Option<PowerState>>>,
|
||||
pub sender: CalloopSender<()>,
|
||||
pub status: Arc<RwLock<Option<PowerState>>>,
|
||||
}
|
||||
|
||||
pub struct PowerReceiver {
|
||||
@@ -14,22 +19,16 @@ pub struct PowerReceiver {
|
||||
status: Arc<RwLock<Option<PowerState>>>,
|
||||
}
|
||||
|
||||
pub struct UPowerMonitor {
|
||||
reporter: PowerReporter,
|
||||
|
||||
dbus: zbus::Connection,
|
||||
}
|
||||
|
||||
macro_rules! catch {
|
||||
($expr:block) => {
|
||||
(|| { $expr })()
|
||||
(|| $expr)()
|
||||
};
|
||||
}
|
||||
|
||||
pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> {
|
||||
let (start_send, start_receive) = std::sync::mpsc::sync_channel(1);
|
||||
std::thread::spawn(|| {
|
||||
let failure = upower_run(reporter, &start_send);;
|
||||
std::thread::spawn(move || {
|
||||
let failure = upower_run(reporter, &start_send);
|
||||
if failure.is_err() {
|
||||
start_send.send(failure);
|
||||
}
|
||||
@@ -38,32 +37,21 @@ pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> {
|
||||
start_receive.recv()?
|
||||
}
|
||||
|
||||
async fn upower_run(reporter: PowerReporter, start_send: &SyncSender<anyhow::Result<()>>) {
|
||||
fn upower_run(
|
||||
reporter: PowerReporter,
|
||||
start_send: &SyncSender<anyhow::Result<()>>,
|
||||
) -> anyhow::Result<()> {
|
||||
let dbus = zbus::blocking::Connection::system()?;
|
||||
let display_device_path = upower_dbus::UPowerProxyBlocking::new(&connection).await?
|
||||
.get_display_device().await?;
|
||||
zbus::blocking::fdo::PropertiesProxy::builder(&dbus)
|
||||
|
||||
|
||||
let display_proxy = upower_dbus::DeviceProxyBlocking::builder()
|
||||
let display_device_path = upower_dbus::UPowerProxyBlocking::new(&dbus)?.get_display_device()?;
|
||||
let display_proxy = zbus::blocking::fdo::PropertiesProxy::builder(&dbus)
|
||||
.destination("org.freedesktop.UPower")?
|
||||
.path(display_device_path)?
|
||||
.build().await?;
|
||||
.cache_properties(zbus::CacheProperties::No)
|
||||
.build()?;
|
||||
|
||||
start_send.send(Ok(())).unwrap();
|
||||
}
|
||||
|
||||
impl UPowerMonitor {
|
||||
fn spawn(reporter: PowerReporter) -> anyhow::Result<Self> {
|
||||
|
||||
futures::executor::block_on(async {
|
||||
let dbus = zbus::Connection::system().await?;
|
||||
|
||||
Ok(Self {
|
||||
reporter,
|
||||
dbus,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// TODO: actually watch for events
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user