waylite

2 commits
Updated 2026-04-23 15:23:13
examples
examples/hello.rs
use std::io::{Read, Write};
use std::os::unix::net::UnixStream;
use std::path::PathBuf;

use waylite::{DISPLAY, event, request};

fn main() {
    let mut stream = UnixStream::connect(PathBuf::new().join("/run/user/1000/wayland-0"))
        .expect("failed to connect");

    const MY_REGISTRY: u32 = 2;

    let mut buf = vec![0u8; 4096];

    let mut w = &mut buf[..];
    request::display::get_registry(&mut w, MY_REGISTRY).unwrap();
    request::display::sync(&mut w, 3).unwrap();
    let l = 4096 - w.len();
    stream.write_all(&buf[..l]).unwrap();

    let mut registry = (None::<(u32, u32)>, None::<(u32, u32)>, None::<(u32, u32)>);

    pump(
        &mut stream,
        &mut registry,
        &mut buf[..],
        |_, id, op, mut payload, registry| {
            match (id, op) {
                (MY_REGISTRY, event::registry::GLOBAL) => {
                    let (id, iface, version) = event::registry::global(&mut payload).unwrap();
                    match iface {
                        "wl_compositor" => {
                            registry.0.replace((version, id));
                        }
                        "xdg_wm_base" => {
                            registry.1.replace((version, id));
                        }
                        "wl_shm" => {
                            registry.2.replace((version, id));
                        }
                        _ => {}
                    };
                }
                (3, event::callback::DONE) => {
                    let data = event::callback::done(&mut payload).unwrap();
                    println!("{data}");

                    return true;
                }
                (DISPLAY, event::display::ERROR) => {
                    let (id, code, msg) = event::display::error(&mut payload).unwrap();
                    println!("[{id}:{code}]: {msg}");
                }
                _ => {
                    println!("Unexpected {id}-{op}");
                }
            }

            false
        },
    );

    let (cmp, xdg, shm) = (
        registry.0.unwrap(),
        registry.1.unwrap(),
        registry.2.unwrap(),
    );

    println!(
        "Getting interfaces: \n - wl_compositor(v{}): {}\n - xdg_wm_base(v{}): {}\n - wl_shm(v{}): {}",
        cmp.0, cmp.1, xdg.0, xdg.1, shm.0, shm.1,
    );

    const MY_CMP: u32 = 4;
    const MY_XDG: u32 = 5;
    const MY_SHM: u32 = 6;

    let mut w = &mut buf[..];
    request::registry::bind(&mut w, MY_REGISTRY, cmp.1, ("wl_compositor", cmp.0, MY_CMP)).unwrap();
    request::registry::bind(&mut w, MY_REGISTRY, xdg.1, ("xdg_wm_base", xdg.0, MY_XDG)).unwrap();
    request::registry::bind(&mut w, MY_REGISTRY, shm.1, ("wl_shm", shm.0, MY_SHM)).unwrap();
    request::display::sync(&mut w, 7).unwrap();
    let l = 4096 - w.len();
    stream.write_all(&buf[..l]).unwrap();

    pump(
        &mut stream,
        &mut registry,
        &mut buf[..],
        |_, id, op, mut payload, _| {
            match (id, op) {
                (7, event::callback::DONE) => {
                    let data = event::callback::done(&mut payload).unwrap();
                    println!("{data}");

                    return true;
                }
                (DISPLAY, event::display::ERROR) => {
                    let (id, code, msg) = event::display::error(&mut payload).unwrap();
                    println!("[{id}:{code}]: {msg}");
                }
                _ => {
                    println!("Unexpected {id}-{op}");
                }
            }

            false
        },
    );

    println!("done")
}

fn pump<S>(
    stream: &mut UnixStream,
    state: &mut S,
    buf: &mut [u8],
    mut on_msg: impl FnMut(&mut UnixStream, u32, u16, &[u8], &mut S) -> bool,
) {
    loop {
        let n = stream.read(buf).expect("read");
        let mut r = &buf[..n];
        while let Ok((id, op, payload)) = waylite::msg::read_msg(&mut r) {
            let stop = on_msg(stream, id, op, payload, state);
            if stop {
                return;
            }
        }
    }
}