wayrs-client 1.3.1

A simple wayland library
Documentation
use std::ffi::CString;

use wayrs_client::global::GlobalExt;
use wayrs_client::protocol::wl_output::{self, WlOutput};
use wayrs_client::protocol::wl_registry::{self, GlobalArgs};
use wayrs_client::{Connection, EventCtx, IoMode};

fn main() {
    let mut conn = Connection::connect().unwrap();
    let mut state = State::default();

    conn.add_registry_cb(wl_registry_cb);

    loop {
        conn.flush(IoMode::Blocking).unwrap();
        conn.recv_events(IoMode::Blocking).unwrap();
        conn.dispatch_events(&mut state);
    }
}

#[derive(Default)]
struct State {
    outputs: Vec<Output>,
}

#[derive(Debug)]
struct Output {
    registry_name: u32,
    wl_output: WlOutput,
    name: Option<CString>,
    desc: Option<CString>,
    scale: Option<i32>,
    mode: Option<String>,
}

impl Output {
    fn bind(conn: &mut Connection<State>, global: &GlobalArgs) -> Self {
        Self {
            registry_name: global.name,
            wl_output: global.bind_with_cb(conn, 3..=4, wl_output_cb).unwrap(),
            name: None,
            desc: None,
            scale: None,
            mode: None,
        }
    }
}

fn wl_registry_cb(conn: &mut Connection<State>, state: &mut State, event: &wl_registry::Event) {
    match event {
        wl_registry::Event::Global(global) if global.is::<WlOutput>() => {
            state.outputs.push(Output::bind(conn, global));
        }
        wl_registry::Event::GlobalRemove(name) => {
            if let Some(i) = state.outputs.iter().position(|o| o.registry_name == *name) {
                let output = state.outputs.swap_remove(i);
                eprintln!("removed output: {}", output.name.unwrap().to_str().unwrap());
                output.wl_output.release(conn);
            }
        }
        _ => (),
    }
}

fn wl_output_cb(ctx: EventCtx<State, WlOutput>) {
    let output = &mut ctx
        .state
        .outputs
        .iter_mut()
        .find(|o| o.wl_output == ctx.proxy)
        .unwrap();
    match ctx.event {
        wl_output::Event::Geometry(_) => (),
        wl_output::Event::Mode(mode) => {
            output.mode = Some(format!(
                "{}x{} @ {}Hz",
                mode.width,
                mode.height,
                mode.refresh as f64 * 1e-3
            ))
        }
        wl_output::Event::Done => {
            dbg!(output);
        }
        wl_output::Event::Scale(scale) => output.scale = Some(scale),
        wl_output::Event::Name(name) => output.name = Some(name),
        wl_output::Event::Description(desc) => output.desc = Some(desc),
        _ => (),
    }
}