From 048d3dd700602a91e7d33ec15f31836bb96e4728 Mon Sep 17 00:00:00 2001 From: TQ Hirsch Date: Tue, 3 May 2022 20:00:12 +0200 Subject: [PATCH] Got upower connection to compile, at least --- shell.nix | 5 ++ src/main.rs | 158 +++++++++++++++++++++++++++++++------------------- src/upower.rs | 64 +++++++++----------- 3 files changed, 129 insertions(+), 98 deletions(-) diff --git a/shell.nix b/shell.nix index 6bb4e70..ea4afd5 100644 --- a/shell.nix +++ b/shell.nix @@ -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 ]; diff --git a/src/main.rs b/src/main.rs index b08786f..3143a14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,53 +1,24 @@ - 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, }; - -default_environment!{ - MyEnv, - fields = [ - layer_shell: SimpleGlobal, - ], - singles = [ - ZwlrLayerShellV1 => layer_shell, - ], -} - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] -pub enum RenderEvent { - Closed, - Configure { - width: u32, - height: u32, - } -} - +#[derive(Copy, Clone, Debug)] pub struct PowerState { /// Level, between 0 and 1 level: f32, @@ -57,13 +28,35 @@ pub struct PowerState { time_remaining: f32, } +#[derive(Default, Clone)] +pub struct AppState { + display_status: Arc>>, +} + +default_environment! { + MyEnv, + fields = [ + layer_shell: SimpleGlobal, + ], + singles = [ + ZwlrLayerShellV1 => layer_shell, + ], +} + +#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] +pub enum RenderEvent { + Closed, + Configure { width: u32, height: u32 }, + DataChanged, +} + pub struct Surface { surface: WlSurface, layer_surface: Main, next_render_event: Rc>>, pool: AutoMemPool, dimensions: (u32, u32), - display_status: Arc> + display_status: Arc>>, } impl Surface { @@ -72,6 +65,7 @@ impl Surface { surface: WlSurface, layer_shell: &Attached, pool: AutoMemPool, + state: &AppState, ) -> Self { let layer_surface: Main = layer_shell.get_layer_surface( &surface, @@ -91,12 +85,17 @@ 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) => - { - layer_surface.ack_configure(serial); - nre_handle.set(Some(RenderEvent::Configure { width, height })); - } + ( + 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,20 +106,25 @@ impl Surface { layer_surface, next_render_event, pool, - dimensions: (0, 0) + dimensions: (0, 0), + display_status: Arc::clone(&state.display_status), } } fn handle_events(&mut self) -> bool { match self.next_render_event.take() { Some(RenderEvent::Closed) => true, - Some(RenderEvent::Configure {width, height}) => { + Some(RenderEvent::Configure { width, height }) => { if self.dimensions != (width, height) { self.dimensions = (width, height); self.draw(); } false } + Some(RenderEvent::DataChanged) => { + self.draw(); + false + } None => false, } } @@ -130,9 +134,10 @@ 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) - .unwrap(); + 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(); dst_pixel[0] = pixel[0]; @@ -156,13 +161,23 @@ 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(); let layer_shell = env.require_global::(); @@ -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); } diff --git a/src/upower.rs b/src/upower.rs index 332d731..8feea02 100644 --- a/src/upower.rs +++ b/src/upower.rs @@ -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>>, + pub sender: CalloopSender<()>, + pub status: Arc>>, } pub struct PowerReceiver { @@ -14,22 +19,16 @@ pub struct PowerReceiver { status: Arc>>, } -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>) { +fn upower_run( + reporter: PowerReporter, + start_send: &SyncSender>, +) -> 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 { - - futures::executor::block_on(async { - let dbus = zbus::Connection::system().await?; - - Ok(Self { - reporter, - dbus, - }) - }) - } - + + // TODO: actually watch for events + Ok(()) }