From 1b297251bc0a5f216dbcd4224c7877d6d15cc9b8 Mon Sep 17 00:00:00 2001 From: Bryan Ndjeutcha Date: Mon, 24 May 2021 16:04:28 -0400 Subject: [PATCH] initial commit, view-tags is incomplete --- .gitignore | 1 + Cargo.lock | 147 ++++ Cargo.toml | 15 + build.rs | 23 + protocol/river-status-unstable-v1.xml | 117 ++++ src/main.rs | 161 +++++ src/wayland/mod.rs | 36 + src/wayland/river_status_unstable_v1.rs | 873 ++++++++++++++++++++++++ 8 files changed, 1373 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 build.rs create mode 100644 protocol/river-status-unstable-v1.xml create mode 100644 src/main.rs create mode 100644 src/wayland/mod.rs create mode 100644 src/wayland/river_status_unstable_v1.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..092326f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,147 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "libc" +version = "0.2.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" + +[[package]] +name = "nix" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "status" +version = "0.1.0" +dependencies = [ + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wayland-client" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ca44d86554b85cf449f1557edc6cc7da935cc748c8e4bf1c507cbd43bae02c" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd75ae380325dbcff2707f0cd9869827ea1d2d6d534cff076858d3f0460fd5a" +dependencies = [ + "nix", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-scanner" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389d680d7bd67512dc9c37f39560224327038deb0f0e8d33f870900441b68720" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2907bd297eef464a95ba9349ea771611771aa285b932526c633dc94d5400a8e2" +dependencies = [ + "pkg-config", +] + +[[package]] +name = "xml-rs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..de2d09f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "status" +version = "0.1.0" +authors = ["Bryan Ndjeutcha "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +wayland-scanner = "0.28.5" + +[dependencies] +wayland-scanner = "0.28.5" +wayland-commons = "0.28.5" +wayland-client = "0.28.5" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..29df93f --- /dev/null +++ b/build.rs @@ -0,0 +1,23 @@ +extern crate wayland_scanner; + +use std::path::Path; +use wayland_scanner::{generate_code, Side}; + +pub fn main() { + generate("river_status_unstable_v1"); +} + +fn generate(protocol_name: &str) { + let out_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/src/wayland/")); + + let mut protocol_dir = String::from(concat!(env!("CARGO_MANIFEST_DIR"), "/protocol/")); + protocol_dir.push_str(protocol_name); + protocol_dir.push_str(".xml"); + protocol_dir = protocol_dir.replace("_", "-"); + + let protocol = Path::new(&protocol_dir); + let mut protocol_file = protocol_name.to_string(); + protocol_file.push_str(".rs"); + + generate_code(protocol, out_dir.join(protocol_file), Side::Client); +} diff --git a/protocol/river-status-unstable-v1.xml b/protocol/river-status-unstable-v1.xml new file mode 100644 index 0000000..e31da23 --- /dev/null +++ b/protocol/river-status-unstable-v1.xml @@ -0,0 +1,117 @@ + + + + Copyright 2020 The River Developers + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + + + + A global factory for objects that receive status information specific + to river. It could be used to implement, for example, a status bar. + + + + + This request indicates that the client will not use the + river_status_manager object any more. Objects that have been created + through this instance are not affected. + + + + + + This creates a new river_output_status object for the given wl_output. + + + + + + + + This creates a new river_seat_status object for the given wl_seat. + + + + + + + + + This interface allows clients to receive information about the current + windowing state of an output. + + + + + This request indicates that the client will not use the + river_output_status object any more. + + + + + + Sent once binding the interface and again whenever the tag focus of + the output changes. + + + + + + + Sent once on binding the interface and again whenever the tag state + of the output changes. + + + + + + + + This interface allows clients to receive information about the current + focus of a seat. Note that (un)focused_output events will only be sent + if the client has bound the relevant wl_output globals. + + + + + This request indicates that the client will not use the + river_seat_status object any more. + + + + + + Sent on binding the interface and again whenever an output gains focus. + + + + + + + Sent whenever an output loses focus. + + + + + + + Sent once on binding the interface and again whenever the focused + view or a property thereof changes. The title may be an empty string + if no view is focused or the focused view did not set a title. + + + + + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..1de8bcc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,161 @@ +mod wayland; + +use wayland_client::protocol::wl_output::WlOutput; +use crate::wayland::{ + river_status_unstable_v1::zriver_status_manager_v1::ZriverStatusManagerV1, + river_status_unstable_v1::zriver_output_status_v1::ZriverOutputStatusV1, +}; +use crate::wayland::river_status_unstable_v1::zriver_output_status_v1; +use wayland_client::{Display, GlobalManager, Main}; + +struct Globals { + outputs: Vec, + status_manager: Option> +} + +struct Output { + pub name: String, + pub output: WlOutput, + pub output_status: Option> +} + +impl Output { + pub fn new(output:WlOutput)->Output { + { Output { + name: String::new(), + output: output, + output_status: None, + } } + } +} + +fn main() { + let display = Display::connect_to_env().unwrap(); + + let mut event_queue = display.create_event_queue(); + + let mut globals = { Globals { + outputs: Vec::new(), + status_manager: None + } }; + + let mut args = std::env::args(); + let mut monitor = None; + let mut show_tags = false; + let mut view_tags = false; + args.next(); + loop { + match args.next() { + Some(flag) => match flag.as_str() { + "--monitor" | "-m" => monitor = match args.next().unwrap_or(String::new()).parse::() { + Ok(i) => Some(i), + Err(_) => None, + }, + "--tag" | "-t" => show_tags = true, + "--view-tags" | "-vt" => view_tags = true, + "--help" | "-h" | "--h" => { + println!("Usage: status [option]\n"); + println!(" --tag | -t : displays the focused tag"); + println!(" --view-tags | -vt : displays the tag of all views"); + println!(" --monitor | -m : select the monitor index"); + std::process::exit(0); + } + _ => break, + }, + None => break, + } + } + + let attached_display = (*display).clone().attach(event_queue.token()); + + let _ = GlobalManager::new_with_cb( + &attached_display, + wayland_client::global_filter!( + [ + ZriverStatusManagerV1, + 1, + |status_manager_obj: Main, mut globals: DispatchData| { + globals.get::().unwrap().status_manager = Some(status_manager_obj); + } + ], + [ + WlOutput, + 3, + |output: Main, mut globals: DispatchData| { + output.quick_assign(move |_, _, _| {}); + let output = Output::new(output.detach()); + globals.get::().unwrap().outputs.push(output); + } + ] + ), + ); + + event_queue + .sync_roundtrip(&mut globals, |_, _, _| unreachable!()) + .unwrap(); + + for (i, output) in globals.outputs.iter_mut().enumerate() { + let assign; + match monitor { + Some(monitor) => if i == monitor { + assign = true; + } else { assign = false }, + None => assign = true + } + if assign { + output.output_status = Some(globals.status_manager + .as_ref() + .expect("Compositor doesn't implement river_status_unstable_v1") + .get_river_output_status(&output.output)); + output.output_status.as_mut().unwrap().quick_assign(move |_, event, _| match event { + zriver_output_status_v1::Event::FocusedTags { tags } => { + if show_tags { + base10(tags); + println!(""); + } + } + zriver_output_status_v1::Event::ViewTags { tags } => { + if view_tags { + let mut tagmask:u32 = 1; + for (i, tag) in tags.iter().enumerate() { + if *tag != 0 { + tagmask *= *tag as u32; + } + if (i+1) % 4 == 0 { + base10(tagmask); + tagmask = 1; + } + } + println!(""); + } + } + }); + } + } + + loop { + event_queue + .dispatch(&mut (), |event, object, _| { + panic!( + "[callop] Encountered an orphan event: {}@{}: {}", + event.interface, + object.as_ref().id(), + event.name + ); + }) + .unwrap(); + } +} + +fn base10(tagmask: u32) { + let mut tag = 0; + let mut current: u32; + while {current = 1 << tag; current <= tagmask} { + tag += 1; + if current != tagmask && (tagmask/current) % 2 != 0 { + base10(tagmask-current); + break; + } else if tag == 32 { break } + } + print!("{} ", tag); +} diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs new file mode 100644 index 0000000..d380142 --- /dev/null +++ b/src/wayland/mod.rs @@ -0,0 +1,36 @@ +extern crate wayland_client; +extern crate wayland_commons; + +// Re-export only the actual code, and then only use this re-export +// The `generated` module below is just some boilerplate to properly isolate stuff +// and avoid exposing internal details. +// +// You can use all the types from my_protocol as if they went from `wayland_client::protocol`. +pub use wayland::client as river_status_unstable_v1; + +pub mod wayland { + // The generated code tends to trigger a lot of warnings + // so we isolate it into a very permissive module + #![allow(dead_code, non_camel_case_types, unused_unsafe, unused_variables)] + #![allow(non_upper_case_globals, non_snake_case, unused_imports)] + + pub mod client { + // These imports are used by the generated code + pub(crate) use wayland_client::protocol::wl_output; + pub(crate) use wayland_client::{protocol, sys}; + pub(crate) use wayland_client::{ + AnonymousObject, Attached, Display, GlobalManager, Main, Proxy, ProxyMap, + }; + pub(crate) use wayland_commons::map::{Object, ObjectMetadata}; + pub(crate) use wayland_commons::smallvec; + pub(crate) use wayland_commons::wire::{Argument, ArgumentType, Message, MessageDesc}; + pub(crate) use wayland_commons::{Interface, MessageGroup}; + // If you protocol interacts with objects from other protocols, you'll need to import + // their modules, like so: + pub(crate) use wayland_client::protocol::{wl_region, wl_seat, wl_surface}; + include!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/wayland/river_status_unstable_v1.rs" + )); + } +} diff --git a/src/wayland/river_status_unstable_v1.rs b/src/wayland/river_status_unstable_v1.rs new file mode 100644 index 0000000..b2113ce --- /dev/null +++ b/src/wayland/river_status_unstable_v1.rs @@ -0,0 +1,873 @@ +use std::os::raw::{c_char, c_void}; +const NULLPTR: *const c_void = 0 as *const c_void; +static mut types_null: [*const sys::common::wl_interface; 1] = + [NULLPTR as *const sys::common::wl_interface]; +#[doc = "manage river status objects\n\nA global factory for objects that receive status information specific\nto river. It could be used to implement, for example, a status bar."] +pub mod zriver_status_manager_v1 { + use super::sys::client::*; + use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message}; + use super::{ + smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, + MessageDesc, MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR, + }; + use std::os::raw::c_char; + #[derive(Debug)] + #[non_exhaustive] + pub enum Request { + #[doc = "destroy the river_status_manager object\n\nThis request indicates that the client will not use the\nriver_status_manager object any more. Objects that have been created\nthrough this instance are not affected.\n\nThis is a destructor, once sent this object cannot be used any longer."] + Destroy, + #[doc = "create an output status object\n\nThis creates a new river_output_status object for the given wl_output."] + GetRiverOutputStatus { output: super::wl_output::WlOutput }, + #[doc = "create a seat status object\n\nThis creates a new river_seat_status object for the given wl_seat."] + GetRiverSeatStatus { seat: super::wl_seat::WlSeat }, + } + impl super::MessageGroup for Request { + const MESSAGES: &'static [super::MessageDesc] = &[ + super::MessageDesc { + name: "destroy", + since: 1, + signature: &[], + destructor: true, + }, + super::MessageDesc { + name: "get_river_output_status", + since: 1, + signature: &[super::ArgumentType::NewId, super::ArgumentType::Object], + destructor: false, + }, + super::MessageDesc { + name: "get_river_seat_status", + since: 1, + signature: &[super::ArgumentType::NewId, super::ArgumentType::Object], + destructor: false, + }, + ]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self { + Request::Destroy => true, + _ => false, + } + } + fn opcode(&self) -> u16 { + match *self { + Request::Destroy => 0, + Request::GetRiverOutputStatus { .. } => 1, + Request::GetRiverSeatStatus { .. } => 2, + } + } + fn since(&self) -> u32 { + match *self { + Request::Destroy => 1, + Request::GetRiverOutputStatus { .. } => 1, + Request::GetRiverSeatStatus { .. } => 1, + } + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + 1 => Some(Object::from_interface::< + super::zriver_output_status_v1::ZriverOutputStatusV1, + >(version, meta.child())), + 2 => Some(Object::from_interface::< + super::zriver_seat_status_v1::ZriverSeatStatusV1, + >(version, meta.child())), + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + panic!("Request::from_raw can not be used Client-side.") + } + fn into_raw(self, sender_id: u32) -> Message { + match self { + Request::Destroy => Message { + sender_id: sender_id, + opcode: 0, + args: smallvec![], + }, + Request::GetRiverOutputStatus { output } => Message { + sender_id: sender_id, + opcode: 1, + args: smallvec![Argument::NewId(0), Argument::Object(output.as_ref().id()),], + }, + Request::GetRiverSeatStatus { seat } => Message { + sender_id: sender_id, + opcode: 2, + args: smallvec![Argument::NewId(0), Argument::Object(seat.as_ref().id()),], + }, + } + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + panic!("Request::from_raw_c can not be used Client-side.") + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + match self { + Request::Destroy => { + let mut _args_array: [wl_argument; 0] = unsafe { ::std::mem::zeroed() }; + f(0, &mut _args_array) + } + Request::GetRiverOutputStatus { output } => { + let mut _args_array: [wl_argument; 2] = unsafe { ::std::mem::zeroed() }; + _args_array[0].o = ::std::ptr::null_mut() as *mut _; + _args_array[1].o = output.as_ref().c_ptr() as *mut _; + f(1, &mut _args_array) + } + Request::GetRiverSeatStatus { seat } => { + let mut _args_array: [wl_argument; 2] = unsafe { ::std::mem::zeroed() }; + _args_array[0].o = ::std::ptr::null_mut() as *mut _; + _args_array[1].o = seat.as_ref().c_ptr() as *mut _; + f(2, &mut _args_array) + } + } + } + } + #[derive(Debug)] + #[non_exhaustive] + pub enum Event {} + impl super::MessageGroup for Event { + const MESSAGES: &'static [super::MessageDesc] = &[]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self {} + } + fn opcode(&self) -> u16 { + match *self {} + } + fn since(&self) -> u32 { + match *self {} + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + match msg.opcode { + _ => Err(()), + } + } + fn into_raw(self, sender_id: u32) -> Message { + panic!("Event::into_raw can not be used Client-side.") + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + match opcode { + _ => return Err(()), + } + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + panic!("Event::as_raw_c_in can not be used Client-side.") + } + } + #[derive(Clone, Eq, PartialEq)] + pub struct ZriverStatusManagerV1(Proxy); + impl AsRef> for ZriverStatusManagerV1 { + #[inline] + fn as_ref(&self) -> &Proxy { + &self.0 + } + } + impl From> for ZriverStatusManagerV1 { + #[inline] + fn from(value: Proxy) -> Self { + ZriverStatusManagerV1(value) + } + } + impl From for Proxy { + #[inline] + fn from(value: ZriverStatusManagerV1) -> Self { + value.0 + } + } + impl std::fmt::Debug for ZriverStatusManagerV1 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{:?}", self.0)) + } + } + impl Interface for ZriverStatusManagerV1 { + type Request = Request; + type Event = Event; + const NAME: &'static str = "zriver_status_manager_v1"; + const VERSION: u32 = 1; + fn c_interface() -> *const wl_interface { + unsafe { &zriver_status_manager_v1_interface } + } + } + impl ZriverStatusManagerV1 { + #[doc = "destroy the river_status_manager object\n\nThis request indicates that the client will not use the\nriver_status_manager object any more. Objects that have been created\nthrough this instance are not affected.\n\nThis is a destructor, you cannot send requests to this object any longer once this method is called."] + pub fn destroy(&self) -> () { + let msg = Request::Destroy; + self.0.send::(msg, None); + } + #[doc = "create an output status object\n\nThis creates a new river_output_status object for the given wl_output."] + pub fn get_river_output_status( + &self, + output: &super::wl_output::WlOutput, + ) -> Main { + let msg = Request::GetRiverOutputStatus { + output: output.clone(), + }; + self.0.send(msg, None).unwrap() + } + #[doc = "create a seat status object\n\nThis creates a new river_seat_status object for the given wl_seat."] + pub fn get_river_seat_status( + &self, + seat: &super::wl_seat::WlSeat, + ) -> Main { + let msg = Request::GetRiverSeatStatus { seat: seat.clone() }; + self.0.send(msg, None).unwrap() + } + } + #[doc = r" The minimal object version supporting this request"] + pub const REQ_DESTROY_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this request"] + pub const REQ_GET_RIVER_OUTPUT_STATUS_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this request"] + pub const REQ_GET_RIVER_SEAT_STATUS_SINCE: u32 = 1u32; + static mut zriver_status_manager_v1_requests_get_river_output_status_types: + [*const wl_interface; 2] = [ + unsafe { + &super::zriver_output_status_v1::zriver_output_status_v1_interface + as *const wl_interface + }, + unsafe { &super::wl_output::wl_output_interface as *const wl_interface }, + ]; + static mut zriver_status_manager_v1_requests_get_river_seat_status_types: + [*const wl_interface; 2] = [ + unsafe { + &super::zriver_seat_status_v1::zriver_seat_status_v1_interface as *const wl_interface + }, + unsafe { &super::wl_seat::wl_seat_interface as *const wl_interface }, + ]; + #[doc = r" C-representation of the messages of this interface, for interop"] + pub static mut zriver_status_manager_v1_requests: [wl_message; 3] = [ + wl_message { + name: b"destroy\0" as *const u8 as *const c_char, + signature: b"\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }, + wl_message { + name: b"get_river_output_status\0" as *const u8 as *const c_char, + signature: b"no\0" as *const u8 as *const c_char, + types: unsafe { + &zriver_status_manager_v1_requests_get_river_output_status_types as *const _ + }, + }, + wl_message { + name: b"get_river_seat_status\0" as *const u8 as *const c_char, + signature: b"no\0" as *const u8 as *const c_char, + types: unsafe { + &zriver_status_manager_v1_requests_get_river_seat_status_types as *const _ + }, + }, + ]; + #[doc = r" C representation of this interface, for interop"] + pub static mut zriver_status_manager_v1_interface: wl_interface = wl_interface { + name: b"zriver_status_manager_v1\0" as *const u8 as *const c_char, + version: 1, + request_count: 3, + requests: unsafe { &zriver_status_manager_v1_requests as *const _ }, + event_count: 0, + events: NULLPTR as *const wl_message, + }; +} +#[doc = "track output tags and focus\n\nThis interface allows clients to receive information about the current\nwindowing state of an output."] +pub mod zriver_output_status_v1 { + use super::sys::client::*; + use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message}; + use super::{ + smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, + MessageDesc, MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR, + }; + use std::os::raw::c_char; + #[derive(Debug)] + #[non_exhaustive] + pub enum Request { + #[doc = "destroy the river_output_status object\n\nThis request indicates that the client will not use the\nriver_output_status object any more.\n\nThis is a destructor, once sent this object cannot be used any longer."] + Destroy, + } + impl super::MessageGroup for Request { + const MESSAGES: &'static [super::MessageDesc] = &[super::MessageDesc { + name: "destroy", + since: 1, + signature: &[], + destructor: true, + }]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self { + Request::Destroy => true, + } + } + fn opcode(&self) -> u16 { + match *self { + Request::Destroy => 0, + } + } + fn since(&self) -> u32 { + match *self { + Request::Destroy => 1, + } + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + panic!("Request::from_raw can not be used Client-side.") + } + fn into_raw(self, sender_id: u32) -> Message { + match self { + Request::Destroy => Message { + sender_id: sender_id, + opcode: 0, + args: smallvec![], + }, + } + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + panic!("Request::from_raw_c can not be used Client-side.") + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + match self { + Request::Destroy => { + let mut _args_array: [wl_argument; 0] = unsafe { ::std::mem::zeroed() }; + f(0, &mut _args_array) + } + } + } + } + #[derive(Debug)] + #[non_exhaustive] + pub enum Event { + #[doc = "focused tags of the output\n\nSent once binding the interface and again whenever the tag focus of\nthe output changes."] + FocusedTags { tags: u32 }, + #[doc = "tag state of an output's views\n\nSent once on binding the interface and again whenever the tag state\nof the output changes."] + ViewTags { tags: Vec }, + } + impl super::MessageGroup for Event { + const MESSAGES: &'static [super::MessageDesc] = &[ + super::MessageDesc { + name: "focused_tags", + since: 1, + signature: &[super::ArgumentType::Uint], + destructor: false, + }, + super::MessageDesc { + name: "view_tags", + since: 1, + signature: &[super::ArgumentType::Array], + destructor: false, + }, + ]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self { + _ => false, + } + } + fn opcode(&self) -> u16 { + match *self { + Event::FocusedTags { .. } => 0, + Event::ViewTags { .. } => 1, + } + } + fn since(&self) -> u32 { + match *self { + Event::FocusedTags { .. } => 1, + Event::ViewTags { .. } => 1, + } + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + match msg.opcode { + 0 => { + let mut args = msg.args.into_iter(); + Ok(Event::FocusedTags { + tags: { + if let Some(Argument::Uint(val)) = args.next() { + val + } else { + return Err(()); + } + }, + }) + } + 1 => { + let mut args = msg.args.into_iter(); + Ok(Event::ViewTags { + tags: { + if let Some(Argument::Array(val)) = args.next() { + *val + } else { + return Err(()); + } + }, + }) + } + _ => Err(()), + } + } + fn into_raw(self, sender_id: u32) -> Message { + panic!("Event::into_raw can not be used Client-side.") + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + match opcode { + 0 => { + let _args = ::std::slice::from_raw_parts(args, 1); + Ok(Event::FocusedTags { tags: _args[0].u }) + } + 1 => { + let _args = ::std::slice::from_raw_parts(args, 1); + Ok(Event::ViewTags { + tags: { + let array = &*_args[0].a; + ::std::slice::from_raw_parts(array.data as *const u8, array.size) + .to_owned() + }, + }) + } + _ => return Err(()), + } + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + panic!("Event::as_raw_c_in can not be used Client-side.") + } + } + #[derive(Clone, Eq, PartialEq)] + pub struct ZriverOutputStatusV1(Proxy); + impl AsRef> for ZriverOutputStatusV1 { + #[inline] + fn as_ref(&self) -> &Proxy { + &self.0 + } + } + impl From> for ZriverOutputStatusV1 { + #[inline] + fn from(value: Proxy) -> Self { + ZriverOutputStatusV1(value) + } + } + impl From for Proxy { + #[inline] + fn from(value: ZriverOutputStatusV1) -> Self { + value.0 + } + } + impl std::fmt::Debug for ZriverOutputStatusV1 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{:?}", self.0)) + } + } + impl Interface for ZriverOutputStatusV1 { + type Request = Request; + type Event = Event; + const NAME: &'static str = "zriver_output_status_v1"; + const VERSION: u32 = 1; + fn c_interface() -> *const wl_interface { + unsafe { &zriver_output_status_v1_interface } + } + } + impl ZriverOutputStatusV1 { + #[doc = "destroy the river_output_status object\n\nThis request indicates that the client will not use the\nriver_output_status object any more.\n\nThis is a destructor, you cannot send requests to this object any longer once this method is called."] + pub fn destroy(&self) -> () { + let msg = Request::Destroy; + self.0.send::(msg, None); + } + } + #[doc = r" The minimal object version supporting this request"] + pub const REQ_DESTROY_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this event"] + pub const EVT_FOCUSED_TAGS_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this event"] + pub const EVT_VIEW_TAGS_SINCE: u32 = 1u32; + #[doc = r" C-representation of the messages of this interface, for interop"] + pub static mut zriver_output_status_v1_requests: [wl_message; 1] = [wl_message { + name: b"destroy\0" as *const u8 as *const c_char, + signature: b"\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }]; + #[doc = r" C-representation of the messages of this interface, for interop"] + pub static mut zriver_output_status_v1_events: [wl_message; 2] = [ + wl_message { + name: b"focused_tags\0" as *const u8 as *const c_char, + signature: b"u\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }, + wl_message { + name: b"view_tags\0" as *const u8 as *const c_char, + signature: b"a\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }, + ]; + #[doc = r" C representation of this interface, for interop"] + pub static mut zriver_output_status_v1_interface: wl_interface = wl_interface { + name: b"zriver_output_status_v1\0" as *const u8 as *const c_char, + version: 1, + request_count: 1, + requests: unsafe { &zriver_output_status_v1_requests as *const _ }, + event_count: 2, + events: unsafe { &zriver_output_status_v1_events as *const _ }, + }; +} +#[doc = "track seat focus\n\nThis interface allows clients to receive information about the current\nfocus of a seat. Note that (un)focused_output events will only be sent\nif the client has bound the relevant wl_output globals."] +pub mod zriver_seat_status_v1 { + use super::sys::client::*; + use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message}; + use super::{ + smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, + MessageDesc, MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR, + }; + use std::os::raw::c_char; + #[derive(Debug)] + #[non_exhaustive] + pub enum Request { + #[doc = "destroy the river_seat_status object\n\nThis request indicates that the client will not use the\nriver_seat_status object any more.\n\nThis is a destructor, once sent this object cannot be used any longer."] + Destroy, + } + impl super::MessageGroup for Request { + const MESSAGES: &'static [super::MessageDesc] = &[super::MessageDesc { + name: "destroy", + since: 1, + signature: &[], + destructor: true, + }]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self { + Request::Destroy => true, + } + } + fn opcode(&self) -> u16 { + match *self { + Request::Destroy => 0, + } + } + fn since(&self) -> u32 { + match *self { + Request::Destroy => 1, + } + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + panic!("Request::from_raw can not be used Client-side.") + } + fn into_raw(self, sender_id: u32) -> Message { + match self { + Request::Destroy => Message { + sender_id: sender_id, + opcode: 0, + args: smallvec![], + }, + } + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + panic!("Request::from_raw_c can not be used Client-side.") + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + match self { + Request::Destroy => { + let mut _args_array: [wl_argument; 0] = unsafe { ::std::mem::zeroed() }; + f(0, &mut _args_array) + } + } + } + } + #[derive(Debug)] + #[non_exhaustive] + pub enum Event { + #[doc = "the seat focused an output\n\nSent on binding the interface and again whenever an output gains focus."] + FocusedOutput { output: super::wl_output::WlOutput }, + #[doc = "the seat unfocused an output\n\nSent whenever an output loses focus."] + UnfocusedOutput { output: super::wl_output::WlOutput }, + #[doc = "information on the focused view\n\nSent once on binding the interface and again whenever the focused\nview or a property thereof changes. The title may be an empty string\nif no view is focused or the focused view did not set a title."] + FocusedView { title: String }, + } + impl super::MessageGroup for Event { + const MESSAGES: &'static [super::MessageDesc] = &[ + super::MessageDesc { + name: "focused_output", + since: 1, + signature: &[super::ArgumentType::Object], + destructor: false, + }, + super::MessageDesc { + name: "unfocused_output", + since: 1, + signature: &[super::ArgumentType::Object], + destructor: false, + }, + super::MessageDesc { + name: "focused_view", + since: 1, + signature: &[super::ArgumentType::Str], + destructor: false, + }, + ]; + type Map = super::ProxyMap; + fn is_destructor(&self) -> bool { + match *self { + _ => false, + } + } + fn opcode(&self) -> u16 { + match *self { + Event::FocusedOutput { .. } => 0, + Event::UnfocusedOutput { .. } => 1, + Event::FocusedView { .. } => 2, + } + } + fn since(&self) -> u32 { + match *self { + Event::FocusedOutput { .. } => 1, + Event::UnfocusedOutput { .. } => 1, + Event::FocusedView { .. } => 1, + } + } + fn child( + opcode: u16, + version: u32, + meta: &Meta, + ) -> Option> { + match opcode { + _ => None, + } + } + fn from_raw(msg: Message, map: &mut Self::Map) -> Result { + match msg.opcode { + 0 => { + let mut args = msg.args.into_iter(); + Ok(Event::FocusedOutput { + output: { + if let Some(Argument::Object(val)) = args.next() { + map.get_or_dead(val).into() + } else { + return Err(()); + } + }, + }) + } + 1 => { + let mut args = msg.args.into_iter(); + Ok(Event::UnfocusedOutput { + output: { + if let Some(Argument::Object(val)) = args.next() { + map.get_or_dead(val).into() + } else { + return Err(()); + } + }, + }) + } + 2 => { + let mut args = msg.args.into_iter(); + Ok(Event::FocusedView { + title: { + if let Some(Argument::Str(val)) = args.next() { + let s = String::from_utf8(val.into_bytes()).unwrap_or_else(|e| { + String::from_utf8_lossy(&e.into_bytes()).into() + }); + s + } else { + return Err(()); + } + }, + }) + } + _ => Err(()), + } + } + fn into_raw(self, sender_id: u32) -> Message { + panic!("Event::into_raw can not be used Client-side.") + } + unsafe fn from_raw_c( + obj: *mut ::std::os::raw::c_void, + opcode: u32, + args: *const wl_argument, + ) -> Result { + match opcode { + 0 => { + let _args = ::std::slice::from_raw_parts(args, 1); + Ok(Event::FocusedOutput { + output: Proxy::::from_c_ptr( + _args[0].o as *mut _, + ) + .into(), + }) + } + 1 => { + let _args = ::std::slice::from_raw_parts(args, 1); + Ok(Event::UnfocusedOutput { + output: Proxy::::from_c_ptr( + _args[0].o as *mut _, + ) + .into(), + }) + } + 2 => { + let _args = ::std::slice::from_raw_parts(args, 1); + Ok(Event::FocusedView { + title: ::std::ffi::CStr::from_ptr(_args[0].s) + .to_string_lossy() + .into_owned(), + }) + } + _ => return Err(()), + } + } + fn as_raw_c_in(self, f: F) -> T + where + F: FnOnce(u32, &mut [wl_argument]) -> T, + { + panic!("Event::as_raw_c_in can not be used Client-side.") + } + } + #[derive(Clone, Eq, PartialEq)] + pub struct ZriverSeatStatusV1(Proxy); + impl AsRef> for ZriverSeatStatusV1 { + #[inline] + fn as_ref(&self) -> &Proxy { + &self.0 + } + } + impl From> for ZriverSeatStatusV1 { + #[inline] + fn from(value: Proxy) -> Self { + ZriverSeatStatusV1(value) + } + } + impl From for Proxy { + #[inline] + fn from(value: ZriverSeatStatusV1) -> Self { + value.0 + } + } + impl std::fmt::Debug for ZriverSeatStatusV1 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{:?}", self.0)) + } + } + impl Interface for ZriverSeatStatusV1 { + type Request = Request; + type Event = Event; + const NAME: &'static str = "zriver_seat_status_v1"; + const VERSION: u32 = 1; + fn c_interface() -> *const wl_interface { + unsafe { &zriver_seat_status_v1_interface } + } + } + impl ZriverSeatStatusV1 { + #[doc = "destroy the river_seat_status object\n\nThis request indicates that the client will not use the\nriver_seat_status object any more.\n\nThis is a destructor, you cannot send requests to this object any longer once this method is called."] + pub fn destroy(&self) -> () { + let msg = Request::Destroy; + self.0.send::(msg, None); + } + } + #[doc = r" The minimal object version supporting this request"] + pub const REQ_DESTROY_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this event"] + pub const EVT_FOCUSED_OUTPUT_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this event"] + pub const EVT_UNFOCUSED_OUTPUT_SINCE: u32 = 1u32; + #[doc = r" The minimal object version supporting this event"] + pub const EVT_FOCUSED_VIEW_SINCE: u32 = 1u32; + #[doc = r" C-representation of the messages of this interface, for interop"] + pub static mut zriver_seat_status_v1_requests: [wl_message; 1] = [wl_message { + name: b"destroy\0" as *const u8 as *const c_char, + signature: b"\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }]; + static mut zriver_seat_status_v1_events_focused_output_types: [*const wl_interface; 1] = + [unsafe { &super::wl_output::wl_output_interface as *const wl_interface }]; + static mut zriver_seat_status_v1_events_unfocused_output_types: [*const wl_interface; 1] = + [unsafe { &super::wl_output::wl_output_interface as *const wl_interface }]; + #[doc = r" C-representation of the messages of this interface, for interop"] + pub static mut zriver_seat_status_v1_events: [wl_message; 3] = [ + wl_message { + name: b"focused_output\0" as *const u8 as *const c_char, + signature: b"o\0" as *const u8 as *const c_char, + types: unsafe { &zriver_seat_status_v1_events_focused_output_types as *const _ }, + }, + wl_message { + name: b"unfocused_output\0" as *const u8 as *const c_char, + signature: b"o\0" as *const u8 as *const c_char, + types: unsafe { &zriver_seat_status_v1_events_unfocused_output_types as *const _ }, + }, + wl_message { + name: b"focused_view\0" as *const u8 as *const c_char, + signature: b"s\0" as *const u8 as *const c_char, + types: unsafe { &types_null as *const _ }, + }, + ]; + #[doc = r" C representation of this interface, for interop"] + pub static mut zriver_seat_status_v1_interface: wl_interface = wl_interface { + name: b"zriver_seat_status_v1\0" as *const u8 as *const c_char, + version: 1, + request_count: 1, + requests: unsafe { &zriver_seat_status_v1_requests as *const _ }, + event_count: 3, + events: unsafe { &zriver_seat_status_v1_events as *const _ }, + }; +}