commit 9e231676f739ab5ee390ace2c1438c2d9aba02ad Author: lelgenio Date: Wed May 31 20:11:10 2023 -0300 Initial Commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..c4b17d7 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use_flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e71e34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +.direnv/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..4dd837c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,486 @@ +# 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 = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[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 = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "log" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", + "static_assertions", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro2" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-xml" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "unicode-ident" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "wayland-backend" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b48e27457e8da3b2260ac60d0a94512f5cba36448679f3747c0865b7893ed8" +dependencies = [ + "cc", + "downcast-rs", + "io-lifetimes", + "nix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.30.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489c9654770f674fc7e266b3c579f4053d7551df0ceb392f153adb1f9ed06ac8" +dependencies = [ + "bitflags", + "nix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fefbeb8a360abe67ab7c2efe1d297a1a50ee011f5460791bc18870c26bb84e2" +dependencies = [ + "bitflags", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce991093320e4a6a525876e6b629ab24da25f9baef0c2e0080ad173ec89588a" +dependencies = [ + "bitflags", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4834c14b3edf1d9986c83ca79b1e7e3afbe9874c7c144702f6467063259ce45d" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" +dependencies = [ + "dlib", + "log", + "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 = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "wl-crosshair" +version = "0.1.0" +dependencies = [ + "log", + "tempfile", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f8d66ce --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "wl-crosshair" +version = "0.1.0" +edition = "2021" + +[dependencies] +wayland-client = "0.30.2" +wayland-protocols = { version = "0.30.0", features = ["client"] } +wayland-protocols-wlr = { version = "0.1.0", features = ["client"] } + +log = { version = "0.4", optional = true } +tempfile = "3.2" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0cdbed2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1684242266, + "narHash": "sha256-uaCQ2k1bmojHKjWQngvnnnxQJMY8zi1zq527HdWgQf8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7e0743a5aea1dc755d4b761daf75b20aa486fdad", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..7d951c9 --- /dev/null +++ b/flake.nix @@ -0,0 +1,40 @@ +{ + description = "A crosshair overlay for wlroots compositor"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + in + { + packages = { + default = self.packages.${system}.wl-crosshair; + wl-crosshair = pkgs.rustPlatform.buildRustPackage { + pname = "wl-crosshair"; + version = "0.1.0"; + src = ./.; + cargoLock.lockFile = ./Cargo.lock; + }; + }; + + apps = { + default = self.apps.${system}.wl-crosshair; + wl-crosshair = flake-utils.lib.mkApp { + drv = self.packages.${system}.default; + }; + }; + + devShells.default = pkgs.mkShell { + nativeBuildInputs = with pkgs; [ + cargo + rustc + rustfmt + ]; + }; + }); +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..5feff70 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,253 @@ +use std::{fs::File, io::Write, os::unix::prelude::AsRawFd}; + +use wayland_client::{ + protocol::{ + wl_buffer, wl_compositor, wl_keyboard, wl_pointer, wl_registry, wl_seat, wl_shm, + wl_shm_pool, wl_surface, + }, + Connection, Dispatch, Proxy, QueueHandle, +}; + +use wayland_protocols_wlr::layer_shell::v1::client::{ + zwlr_layer_shell_v1::{self, Layer}, + zwlr_layer_surface_v1::{self, Anchor}, +}; + +use wayland_protocols::xdg::shell::client::xdg_wm_base; + +struct State { + running: bool, + + cursor_size: u32, + + compositor: Option, + base_surface: Option, + layer_shell: Option, + layer_surface: Option, + buffer: Option, + wm_base: Option, + pointer: Option, +} + +fn main() { + let conn = Connection::connect_to_env().unwrap(); + + let mut event_queue = conn.new_event_queue(); + let qhandle = event_queue.handle(); + + let display = conn.display(); + display.get_registry(&qhandle, ()); + + let mut state = State { + running: true, + cursor_size: 10, + compositor: None, + base_surface: None, + layer_shell: None, + layer_surface: None, + buffer: None, + wm_base: None, + pointer: None, + }; + + event_queue.blocking_dispatch(&mut state).unwrap(); + + if state.layer_shell.is_some() && state.wm_base.is_some() { + state.init_layer_surface(&qhandle); + } + + while state.running { + event_queue.blocking_dispatch(&mut state).unwrap(); + } +} + +impl Dispatch for State { + fn event( + state: &mut Self, + registry: &wl_registry::WlRegistry, + event: wl_registry::Event, + _: &(), + _: &Connection, + qh: &QueueHandle, + ) { + eprintln!("WlRegistry event {event:#?}"); + if let wl_registry::Event::Global { + name, + interface, + version, + } = event + { + if interface == zwlr_layer_shell_v1::ZwlrLayerShellV1::interface().name { + let wl_layer = registry.bind::( + name, + version, + qh, + (), + ); + state.layer_shell = Some(wl_layer); + } else if interface == wl_compositor::WlCompositor::interface().name { + let compositor = + registry.bind::(name, version, qh, ()); + let surface = compositor.create_surface(qh, ()); + state.base_surface = Some(surface); + state.compositor = Some(compositor); + } else if interface == wl_shm::WlShm::interface().name { + let shm = registry.bind::(name, version, qh, ()); + + let (init_w, init_h) = (state.cursor_size, state.cursor_size); + + let mut file = tempfile::tempfile().unwrap(); + draw(&mut file, (init_w, init_h)); + let pool = shm.create_pool(file.as_raw_fd(), (init_w * init_h * 4) as i32, qh, ()); + let buffer = pool.create_buffer( + 0, + init_w as i32, + init_h as i32, + (init_w * 4) as i32, + wl_shm::Format::Argb8888, + qh, + (), + ); + state.buffer = Some(buffer); + } else if interface == wl_seat::WlSeat::interface().name { + let seat = registry.bind::(name, version, qh, ()); + state.pointer = Some(seat.get_pointer(qh, ())); + } else if interface == xdg_wm_base::XdgWmBase::interface().name { + let wm_base = registry.bind::(name, 1, qh, ()); + state.wm_base = Some(wm_base); + } + } + } +} + +impl Dispatch for State { + fn event( + state: &mut Self, + _: &wl_pointer::WlPointer, + event: wl_pointer::Event, + _: &(), + _: &Connection, + qh: &QueueHandle, + ) { + eprintln!("WlPointer event {event:#?}"); + match event { + wl_pointer::Event::Enter { .. } => { + if let Some(surface) = &state.base_surface { + surface.destroy(); + } + state.base_surface = None; + } + wl_pointer::Event::Leave { .. } => { + let surface = state.compositor.as_ref().unwrap().create_surface(qh, ()); + state.base_surface = Some(surface); + + state.init_layer_surface(qh); + } + _ => {} + } + } +} + +fn draw(tmp: &mut File, (buf_x, buf_y): (u32, u32)) { + let mut buf = std::io::BufWriter::new(tmp); + for y in 0..buf_y { + for x in 0..buf_x { + let ix = x as i32; + let iy = y as i32; + + let dist = if x <= (buf_x / 2) { + ix + iy - (buf_y as i32) + } else { + iy - ix + }; + + let a: u32 = match dist.abs() { + 0 => 0xFF, + 1 => 0x88, + _ => 0x00, + }; + + let c: u32 = match dist.abs() { + 0 => 0xFF, + 1 => 0x88, + _ => 0x00, + }; + + let color = (a << 24) + (c << 16) + (c << 8) + c; + buf.write_all(&color.to_ne_bytes()).unwrap(); + } + } + buf.flush().unwrap(); +} + +impl State { + fn init_layer_surface(&mut self, qh: &QueueHandle) { + let layer = self.layer_shell.as_ref().unwrap().get_layer_surface( + self.base_surface.as_ref().unwrap(), + None, + Layer::Overlay, + "crosshair".to_string(), + qh, + (), + ); + // Center the window + layer.set_anchor(Anchor::Top | Anchor::Right | Anchor::Bottom | Anchor::Left); + layer.set_keyboard_interactivity(zwlr_layer_surface_v1::KeyboardInteractivity::None); + layer.set_size(self.cursor_size, self.cursor_size); + // A negative value means we will be centered on the screen + // independently of any other xdg_layer_shell + layer.set_exclusive_zone(-1); + self.base_surface.as_ref().unwrap().commit(); + + self.layer_surface = Some(layer); + } +} + +impl Dispatch for State { + fn event( + state: &mut Self, + surface: &zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, + event: ::Event, + _data: &(), + _conn: &Connection, + _qhandle: &QueueHandle, + ) { + eprintln!("ZwlrLayerSurfaceV1 event {event:#?}"); + if let zwlr_layer_surface_v1::Event::Configure { serial, .. } = event { + surface.ack_configure(serial); + if let (Some(surface), Some(buffer)) = (&state.base_surface, &state.buffer) { + surface.attach(Some(buffer), 0, 0); + surface.commit(); + } + } + } +} + +// ignored + +macro_rules! impl_dispatch_log { + ($DispatchStruct: path) => { + impl Dispatch<$DispatchStruct, ()> for State { + fn event( + _: &mut Self, + _: &$DispatchStruct, + event: <$DispatchStruct as Proxy>::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + eprintln!("{} event {:#?}", stringify!($DispatchStruct), event); + } + } + }; +} + +impl_dispatch_log!(wl_buffer::WlBuffer); +impl_dispatch_log!(wl_compositor::WlCompositor); +impl_dispatch_log!(wl_keyboard::WlKeyboard); +impl_dispatch_log!(wl_seat::WlSeat); +impl_dispatch_log!(wl_shm_pool::WlShmPool); +impl_dispatch_log!(wl_shm::WlShm); +impl_dispatch_log!(wl_surface::WlSurface); +impl_dispatch_log!(xdg_wm_base::XdgWmBase); +impl_dispatch_log!(zwlr_layer_shell_v1::ZwlrLayerShellV1);