diff --git a/.github/workflows/cid.yml b/.github/workflows/cid.yml index ea09120..9e09333 100644 --- a/.github/workflows/cid.yml +++ b/.github/workflows/cid.yml @@ -57,6 +57,7 @@ jobs: cargo publish --package clipboard-history-server cargo publish --package clipboard-history cargo publish --package clipboard-history-x11 + cargo publish --package wayland-interface-check cargo publish --package clipboard-history-egui cargo publish --package clipboard-history-tui @@ -126,6 +127,13 @@ jobs: file: target/${{ matrix.target }}/release/ringboard-x11 asset_name: ${{ matrix.target }}-ringboard-x11 tag: ${{ github.ref }} + - name: Upload binary + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: target/${{ matrix.target }}/release/wayland-interface-check + asset_name: ${{ matrix.target }}-wayland-interface-check + tag: ${{ github.ref }} - name: Upload binary uses: svenstaro/upload-release-action@v2 with: diff --git a/Cargo.toml b/Cargo.toml index 43a2141..9cd715d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "egui", "server", "tui", + "wayland-interface-check", "x11", ] diff --git a/wayland-interface-check/Cargo.toml b/wayland-interface-check/Cargo.toml new file mode 100644 index 0000000..ade0bc3 --- /dev/null +++ b/wayland-interface-check/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "wayland-interface-check" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +description = "Binary to answer the question, \"Is this Wayland interface available?\"" +repository.workspace = true +keywords = ["tools", "wayland", "cli"] +categories = ["command-line-utilities", "development-tools"] +license.workspace = true + +[dependencies] +rustc-hash = "2.0.0" +wayland-client = "0.31.7" diff --git a/wayland-interface-check/LICENSE b/wayland-interface-check/LICENSE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/wayland-interface-check/LICENSE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/wayland-interface-check/README.md b/wayland-interface-check/README.md new file mode 100644 index 0000000..70a2baf --- /dev/null +++ b/wayland-interface-check/README.md @@ -0,0 +1,13 @@ +# Wayland interface check + +![Crates.io Version](https://img.shields.io/crates/v/wayland-interface-check) + +This simple binary answers the question, "Is this Wayland interface available?" For example, + +```sh +$ wayland-interface-check zwlr_data_control_manager_v1 +$ echo $? +0 +``` + +means the interface is available. diff --git a/wayland-interface-check/src/main.rs b/wayland-interface-check/src/main.rs new file mode 100644 index 0000000..60549a1 --- /dev/null +++ b/wayland-interface-check/src/main.rs @@ -0,0 +1,68 @@ +#![feature(exitcode_exit_method)] + +use std::{ + collections::HashSet, env, ffi::OsString, hash::BuildHasherDefault, os::unix::ffi::OsStringExt, + process::ExitCode, +}; + +use rustc_hash::FxHasher; +use wayland_client::{ + Connection, Dispatch, QueueHandle, + protocol::{wl_registry, wl_registry::WlRegistry}, +}; + +fn main() -> ExitCode { + let interfaces = env::args_os() + .skip(1) + .map(OsString::into_vec) + .collect::>(); + if interfaces.is_empty() { + return ExitCode::SUCCESS; + } + + let Ok(conn) = Connection::connect_to_env() else { + return ExitCode::FAILURE; + }; + let display = conn.display(); + + let mut event_queue = conn.new_event_queue(); + let qh = event_queue.handle(); + + let mut state = State(interfaces); + + display.get_registry(&qh, ()); + let Ok(_) = event_queue.roundtrip(&mut state) else { + return ExitCode::FAILURE; + }; + + if state.0.is_empty() { + ExitCode::SUCCESS + } else { + ExitCode::FAILURE + } +} + +struct State(HashSet, BuildHasherDefault>); + +impl Dispatch for State { + fn event( + this: &mut Self, + _: &WlRegistry, + event: wl_registry::Event, + (): &(), + _: &Connection, + _: &QueueHandle, + ) { + if let wl_registry::Event::Global { + name: _, + interface, + version: _, + } = event + { + this.0.remove(interface.as_bytes()); + if this.0.is_empty() { + ExitCode::SUCCESS.exit_process() + } + } + } +}