Got upower connection to compile, at least

This commit is contained in:
2022-05-03 20:00:12 +02:00
parent 6629cc6058
commit 048d3dd700
3 changed files with 129 additions and 98 deletions

View File

@@ -3,6 +3,11 @@
pkgs.mkShell { pkgs.mkShell {
buildInputs = with pkgs; [ buildInputs = with pkgs; [
libxkbcommon libxkbcommon
cargo
rust-analyzer
rustc
rustfmt
cargo-fmt
# keep this line if you use bash # keep this line if you use bash
bashInteractive bashInteractive
]; ];

View File

@@ -1,53 +1,24 @@
pub mod upower; pub mod upower;
use std::{
cell::RefCell,
rc::Rc,
};
use std::cell::Cell; use std::cell::Cell;
use std::sync::RwLock; use std::sync::RwLock;
use wayland_client::{Attached, Main, protocol::{ use std::{cell::RefCell, rc::Rc, sync::Arc};
wl_shm, use wayland_client::{
wl_surface::WlSurface, protocol::{wl_output::WlOutput, wl_shm, wl_surface::WlSurface},
wl_output::WlOutput, Attached, Main,
}}; };
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{ use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
zwlr_layer_shell_v1::{self, ZwlrLayerShellV1}, zwlr_layer_shell_v1::{self, ZwlrLayerShellV1},
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
}; };
use smithay_client_toolkit::{ use smithay_client_toolkit::{
default_environment, default_environment, environment::SimpleGlobal, new_default_environment,
new_default_environment, output::with_output_info, output::OutputInfo, shm::AutoMemPool, WaylandSource,
environment::SimpleGlobal,
output::OutputInfo,
WaylandSource,
output::with_output_info,
shm::AutoMemPool
}; };
#[derive(Copy, Clone, Debug)]
default_environment!{
MyEnv,
fields = [
layer_shell: SimpleGlobal<ZwlrLayerShellV1>,
],
singles = [
ZwlrLayerShellV1 => layer_shell,
],
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum RenderEvent {
Closed,
Configure {
width: u32,
height: u32,
}
}
pub struct PowerState { pub struct PowerState {
/// Level, between 0 and 1 /// Level, between 0 and 1
level: f32, level: f32,
@@ -57,13 +28,35 @@ pub struct PowerState {
time_remaining: f32, time_remaining: f32,
} }
#[derive(Default, Clone)]
pub struct AppState {
display_status: Arc<RwLock<Option<PowerState>>>,
}
default_environment! {
MyEnv,
fields = [
layer_shell: SimpleGlobal<ZwlrLayerShellV1>,
],
singles = [
ZwlrLayerShellV1 => layer_shell,
],
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum RenderEvent {
Closed,
Configure { width: u32, height: u32 },
DataChanged,
}
pub struct Surface { pub struct Surface {
surface: WlSurface, surface: WlSurface,
layer_surface: Main<ZwlrLayerSurfaceV1>, layer_surface: Main<ZwlrLayerSurfaceV1>,
next_render_event: Rc<Cell<Option<RenderEvent>>>, next_render_event: Rc<Cell<Option<RenderEvent>>>,
pool: AutoMemPool, pool: AutoMemPool,
dimensions: (u32, u32), dimensions: (u32, u32),
display_status: Arc<RwLock<>> display_status: Arc<RwLock<Option<PowerState>>>,
} }
impl Surface { impl Surface {
@@ -72,6 +65,7 @@ impl Surface {
surface: WlSurface, surface: WlSurface,
layer_shell: &Attached<ZwlrLayerShellV1>, layer_shell: &Attached<ZwlrLayerShellV1>,
pool: AutoMemPool, pool: AutoMemPool,
state: &AppState,
) -> Self { ) -> Self {
let layer_surface: Main<ZwlrLayerSurfaceV1> = layer_shell.get_layer_surface( let layer_surface: Main<ZwlrLayerSurfaceV1> = layer_shell.get_layer_surface(
&surface, &surface,
@@ -91,12 +85,17 @@ impl Surface {
(zwlr_layer_surface_v1::Event::Closed, _) => { (zwlr_layer_surface_v1::Event::Closed, _) => {
nre_handle.set(Some(RenderEvent::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,
layer_surface.ack_configure(serial); width,
nre_handle.set(Some(RenderEvent::Configure { width, height })); 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, layer_surface,
next_render_event, next_render_event,
pool, pool,
dimensions: (0, 0) dimensions: (0, 0),
display_status: Arc::clone(&state.display_status),
} }
} }
fn handle_events(&mut self) -> bool { fn handle_events(&mut self) -> bool {
match self.next_render_event.take() { match self.next_render_event.take() {
Some(RenderEvent::Closed) => true, Some(RenderEvent::Closed) => true,
Some(RenderEvent::Configure {width, height}) => { Some(RenderEvent::Configure { width, height }) => {
if self.dimensions != (width, height) { if self.dimensions != (width, height) {
self.dimensions = (width, height); self.dimensions = (width, height);
self.draw(); self.draw();
} }
false false
} }
Some(RenderEvent::DataChanged) => {
self.draw();
false
}
None => false, None => false,
} }
} }
@@ -130,9 +134,10 @@ impl Surface {
let width = self.dimensions.0 as i32; let width = self.dimensions.0 as i32;
let height = self.dimensions.1 as i32; let height = self.dimensions.1 as i32;
let (canvas, buffer) = let (canvas, buffer) = self
self.pool.buffer(width, height, stride, wl_shm::Format::Argb8888) .pool
.unwrap(); .buffer(width, height, stride, wl_shm::Format::Argb8888)
.unwrap();
for dst_pixel in canvas.chunks_exact_mut(4) { for dst_pixel in canvas.chunks_exact_mut(4) {
let pixel = 0x01_00_8f_00u32.to_ne_bytes(); let pixel = 0x01_00_8f_00u32.to_ne_bytes();
dst_pixel[0] = pixel[0]; dst_pixel[0] = pixel[0];
@@ -156,13 +161,23 @@ impl Drop for Surface {
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let (env, display, queue) = new_default_environment!( let mut app_state = AppState::default();
MyEnv,
fields = [ // Spawn upower watcher
layer_shell: SimpleGlobal::new(), 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 env_handle = env.clone();
let layer_shell = env.require_global::<ZwlrLayerShellV1>(); let layer_shell = env.require_global::<ZwlrLayerShellV1>();
@@ -171,14 +186,20 @@ fn main() -> anyhow::Result<()> {
let surfaces = Rc::new(RefCell::new(Vec::new())); let surfaces = Rc::new(RefCell::new(Vec::new()));
let surfaces_handle = Rc::clone(&surfaces); let surfaces_handle = Rc::clone(&surfaces);
let app_state_handle = app_state.clone();
let output_handler = move |output: WlOutput, info: &OutputInfo| { let output_handler = move |output: WlOutput, info: &OutputInfo| {
if info.obsolete { if info.obsolete {
surfaces_handle.borrow_mut().retain(|(i, _)| *i != info.id); surfaces_handle.borrow_mut().retain(|(i, _)| *i != info.id);
output.release(); output.release();
} else { } else {
let surface = env_handle.create_surface().detach(); let surface = env_handle.create_surface().detach();
let pool = env_handle.create_auto_pool().expect("Failed to create a memeory pool!"); let pool = env_handle
surfaces_handle.borrow_mut().push((info.id, Surface::new(&output, surface, &layer_shell.clone(), pool))); .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"); 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 { loop {
{ {
let mut surfaces = surfaces.borrow_mut(); let mut surfaces = surfaces.borrow_mut();
@@ -209,5 +245,7 @@ fn main() -> anyhow::Result<()> {
display.flush().unwrap(); display.flush().unwrap();
event_loop.dispatch(None, &mut ()).unwrap(); event_loop.dispatch(None, &mut ()).unwrap();
} }
//println!("Registry: {:#?}", env); //println!("Registry: {:#?}", env);
} }

View File

@@ -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 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 { pub struct PowerReporter {
sender: Sender<()>, pub sender: CalloopSender<()>,
status: Arc<RwLock<Option<PowerState>>>, pub status: Arc<RwLock<Option<PowerState>>>,
} }
pub struct PowerReceiver { pub struct PowerReceiver {
@@ -14,22 +19,16 @@ pub struct PowerReceiver {
status: Arc<RwLock<Option<PowerState>>>, status: Arc<RwLock<Option<PowerState>>>,
} }
pub struct UPowerMonitor {
reporter: PowerReporter,
dbus: zbus::Connection,
}
macro_rules! catch { macro_rules! catch {
($expr:block) => { ($expr:block) => {
(|| { $expr })() (|| $expr)()
}; };
} }
pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> { pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> {
let (start_send, start_receive) = std::sync::mpsc::sync_channel(1); let (start_send, start_receive) = std::sync::mpsc::sync_channel(1);
std::thread::spawn(|| { std::thread::spawn(move || {
let failure = upower_run(reporter, &start_send);; let failure = upower_run(reporter, &start_send);
if failure.is_err() { if failure.is_err() {
start_send.send(failure); start_send.send(failure);
} }
@@ -38,32 +37,21 @@ pub fn spawn_upower(reporter: PowerReporter) -> anyhow::Result<()> {
start_receive.recv()? 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 dbus = zbus::blocking::Connection::system()?;
let display_device_path = upower_dbus::UPowerProxyBlocking::new(&connection).await? let display_device_path = upower_dbus::UPowerProxyBlocking::new(&dbus)?.get_display_device()?;
.get_display_device().await?; let display_proxy = zbus::blocking::fdo::PropertiesProxy::builder(&dbus)
zbus::blocking::fdo::PropertiesProxy::builder(&dbus) .destination("org.freedesktop.UPower")?
let display_proxy = upower_dbus::DeviceProxyBlocking::builder()
.path(display_device_path)? .path(display_device_path)?
.build().await?; .cache_properties(zbus::CacheProperties::No)
.build()?;
start_send.send(Ok(())).unwrap(); start_send.send(Ok(())).unwrap();
}
// TODO: actually watch for events
impl UPowerMonitor { Ok(())
fn spawn(reporter: PowerReporter) -> anyhow::Result<Self> {
futures::executor::block_on(async {
let dbus = zbus::Connection::system().await?;
Ok(Self {
reporter,
dbus,
})
})
}
} }