From acf30d100156964c9a68e796ae2c0fc555a272fb Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Sat, 21 May 2022 07:58:26 +0200 Subject: [PATCH] Initial version with a non-working example --- Cargo.lock | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 8 ++ src/main.rs | 154 +++++++++++++++++++++++++ 3 files changed, 483 insertions(+) create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..f8e9ef4 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,321 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "calloop" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82" +dependencies = [ + "log", + "nix", +] + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "libloading" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca" + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "proc-macro2" +version = "1.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "smithay-client-toolkit" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3" +dependencies = [ + "bitflags", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + +[[package]] +name = "wayland-client" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e" +dependencies = [ + "nix", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd" +dependencies = [ + "nix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wl-seasonal-hours-clock" +version = "0.1.0" +dependencies = [ + "calloop", + "smithay-client-toolkit", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..75d50a1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "wl-seasonal-hours-clock" +version = "0.1.0" +edition = "2021" + +[dependencies] +smithay-client-toolkit = "0.15" +calloop = "0.9" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..7d90a93 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,154 @@ +extern crate smithay_client_toolkit as sctk; + +use calloop::{timer::Timer, EventLoop}; +use sctk::reexports::client::protocol::{wl_shm, wl_surface}; +use sctk::shm::AutoMemPool; +use sctk::window::{Event as WEvent, FallbackFrame}; + +sctk::default_environment!(TimedRefresh, desktop); + +fn main() { + let (env, display, queue) = sctk::new_default_environment!(TimedRefresh, desktop) + .expect("Unable to connect to a Wayland compositor"); + + let surface = env + .create_surface_with_scale_callback(|dpi, _surface, _dispatch_data| { + println!("dpi changed to {}", dpi); + }) + .detach(); + + let mut next_action = None::; + + let mut window = env + .create_window::( + surface, + None, + (100, 100), + move |evt, mut dispatch_data| { + let next_action = dispatch_data.get::>().unwrap(); + let replace = matches!( + (&evt, &*next_action), + (_, &None) + | (_, &Some(WEvent::Refresh)) + | (&WEvent::Configure { .. }, &Some(WEvent::Configure { .. })) + | (&WEvent::Close, _) + ); + + if replace { + *next_action = Some(evt); + } + }, + ) + .expect("Failed to create a window !"); + + window.set_title("Seasonal Hours Clock".to_string()); + + let mut pool = env + .create_auto_pool() + .expect("Failed to create the memory pool."); + let mut need_redraw = false; + let mut dimensions = (700, 700); + + if !env.get_shell().unwrap().needs_configure() { + redraw(&mut pool, window.surface(), dimensions).expect("Failed to draw"); + window.refresh() + } + + let mut event_loop = EventLoop::>::try_new().unwrap(); + let handle = event_loop.handle(); + let source = Timer::new().expect("Failed to create timer event source!"); + let timer_handle = source.handle(); + timer_handle.add_timeout(std::time::Duration::from_secs(1), ""); + + handle.insert_source(source, |_, timer_handle, _| { + println!("Redraw!"); + redraw(&mut pool, window.surface(), dimensions).expect("Failed to draw"); + window.refresh(); + timer_handle.add_timeout(std::time::Duration::from_secs(1), ""); + }); + + sctk::WaylandSource::new(queue).quick_insert(handle).unwrap(); + + loop { + // Update every second + match next_action.take() { + Some(WEvent::Close) => break, + Some(WEvent::Refresh) => { + window.refresh(); + window.surface().commit(); + } + Some(WEvent::Configure { + new_size, + states: _, + }) => { + if let Some((w, h)) = new_size { + if dimensions != (w, h) { + dimensions = (w, h); + } + } + window.resize(dimensions.0, dimensions.1); + window.refresh(); + need_redraw = true; + } + None => {} + } + + if need_redraw { + need_redraw = false; + + redraw(&mut pool, window.surface(), dimensions).expect("Failed to draw") + } + + if let Err(e) = display.flush() { + if e.kind() != ::std::io::ErrorKind::WouldBlock { + eprintln!("Error while trying to flush the wayland socket: {:?}", e); + } + } + + event_loop.dispatch(None, &mut next_action).unwrap(); + } +} + +fn redraw( + pool: &mut AutoMemPool, + surface: &wl_surface::WlSurface, + (buf_x, buf_y): (u32, u32), +) -> Result<(), ::std::io::Error> { + let (canvas, new_buffer) = pool.buffer( + buf_x as i32, + buf_y as i32, + 4 * buf_x as i32, + wl_shm::Format::Argb8888, + )?; + + // We do not have anything to draw yet, so draw an empty surface + for dst_pixel in canvas.chunks_exact_mut(4) { + let r = 0u32; + let g = 0u32; + let b = 0u32; + let a = 255u32; + + let r = ::std::cmp::min(0xFF, (0xFF * (0xFF - a) + a * r) / 0xFF); + let g = ::std::cmp::min(0xFF, (0xFF * (0xFF - a) + a * g) / 0xFF); + let b = ::std::cmp::min(0xFF, (0xFF * (0xFF - a) + a * b) / 0xFF); + + let pixel: [u8; 4] = ((0xFF << 24) + (r << 16) + (g << 8) + b).to_ne_bytes(); + + dst_pixel[0] = pixel[0]; + dst_pixel[1] = pixel[1]; + dst_pixel[2] = pixel[2]; + dst_pixel[3] = pixel[3]; + } + + surface.attach(Some(&new_buffer), 0, 0); + + if surface.as_ref().version() >= 4 { + surface.damage_buffer(0, 0, buf_x as i32, buf_y as i32); + } else { + surface.damage(0, 0, buf_x as i32, buf_y as i32); + } + + surface.commit(); + + Ok(()) +}