Initial commit
This commit is contained in:
commit
b4b803eed0
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
275
Cargo.lock
generated
Normal file
275
Cargo.lock
generated
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.89"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.158"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "poppable"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "git+https://git.kealoha.me/lks/poppable.git#5f238c7bc42e4abc2c72fb1f93e623934487ff99"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"poppable-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "poppable-derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.kealoha.me/lks/poppable.git#5f238c7bc42e4abc2c72fb1f93e623934487ff99"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ppv-lite86"
|
||||||
|
version = "0.2.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.77"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "waycli"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"poppable",
|
||||||
|
"rand",
|
||||||
|
"rustix",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "waycli"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.89"
|
||||||
|
poppable = { git = "https://git.kealoha.me/lks/poppable.git", version = "0.0.1" }
|
||||||
|
rand = "0.8.5"
|
||||||
|
rustix = { version = "0.38.37", features = ["mm", "shm"] }
|
||||||
390
src/main.rs
Normal file
390
src/main.rs
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
//https://gaultier.github.io/blog/wayland_from_scratch.html
|
||||||
|
use std::{ffi::CStr, io::Read, ptr::null_mut, u32};
|
||||||
|
|
||||||
|
use poppable::Poppable;
|
||||||
|
use rustix::{
|
||||||
|
fs::{ftruncate, Mode},
|
||||||
|
mm::{mmap, MapFlags, ProtFlags},
|
||||||
|
shm,
|
||||||
|
};
|
||||||
|
use wayland::WAYLAND_XDG_BASE_EVENT_PING;
|
||||||
|
|
||||||
|
mod wayland {
|
||||||
|
use anyhow::Result;
|
||||||
|
use poppable::{PopFromNE, Pushable};
|
||||||
|
use rustix::fd::OwnedFd;
|
||||||
|
use std::ffi::c_void;
|
||||||
|
use std::{env, io::Write, os::unix::net::UnixStream};
|
||||||
|
|
||||||
|
pub const WAYLAND_DISPLAY_OBJECT_ID: u32 = 1;
|
||||||
|
pub const WAYLAND_WL_DISPLAY_GET_REGISTRY_OPCODE: u16 = 1;
|
||||||
|
pub const WAYLAND_WL_REGISTRY_BIND_OPCODE: u16 = 0;
|
||||||
|
pub const COLOR_CHANNELS: u32 = 4;
|
||||||
|
pub const WAYLAND_WL_REGISTRY_EVENT_GLOBAL: u16 = 0;
|
||||||
|
pub const WAYLAND_WL_DISPLAY_ERROR_EVENT: u16 = 0;
|
||||||
|
pub const WAYLAND_XDG_BASE_EVENT_PING: u16 = 0;
|
||||||
|
pub const WAYLAND_XDG_SURFACE_EVENT_CONFIGURE: u16 = 0;
|
||||||
|
|
||||||
|
pub fn write_string(buf: &mut Vec<u8>, src: &str) -> Result<usize> {
|
||||||
|
let mut n_write = 0;
|
||||||
|
(src.len() as u32 + 1).push_ne_into(buf)?;
|
||||||
|
for b in src.bytes().chain([0_u8]) {
|
||||||
|
buf.push(b);
|
||||||
|
n_write += 1;
|
||||||
|
}
|
||||||
|
let required_size = nearest_multiple_4(n_write as i32) as usize;
|
||||||
|
while n_write < required_size {
|
||||||
|
buf.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(n_write);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn nearest_multiple_4(n: i32) -> i32 {
|
||||||
|
return ((n) + 3) & -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq)]
|
||||||
|
pub enum StateEnum {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
SurfaceAckedConfigure,
|
||||||
|
SurfaceAttached,
|
||||||
|
}
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct State {
|
||||||
|
pub wl_registry: u32,
|
||||||
|
pub wl_shm: u32,
|
||||||
|
pub wl_shm_pool: u32,
|
||||||
|
pub wl_buffer: u32,
|
||||||
|
pub xdg_wm_base: u32,
|
||||||
|
pub xdg_surface: u32,
|
||||||
|
pub wl_compositor: u32,
|
||||||
|
pub wl_surface: u32,
|
||||||
|
pub xdg_toplevel: u32,
|
||||||
|
pub stride: u32,
|
||||||
|
pub w: u32,
|
||||||
|
pub h: u32,
|
||||||
|
pub shm_pool_size: u32,
|
||||||
|
pub shm_fd: Option<OwnedFd>,
|
||||||
|
pub shm_pool_data: Option<*mut c_void>,
|
||||||
|
|
||||||
|
pub state: StateEnum,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Wayland {
|
||||||
|
pub sock: UnixStream,
|
||||||
|
pub resource_counter: u32,
|
||||||
|
}
|
||||||
|
pub fn connect() -> Result<Wayland> {
|
||||||
|
let xdg_runtime_dir = env::var("XDG_RUNTIME_DIR")?;
|
||||||
|
let wayland_display = env::var("WAYLAND_DISPLAY").unwrap_or("wayland-0".into());
|
||||||
|
let wayland_path = xdg_runtime_dir + &wayland_display;
|
||||||
|
let sock = UnixStream::connect(&wayland_path)?;
|
||||||
|
Ok(Wayland {
|
||||||
|
sock,
|
||||||
|
resource_counter: 2,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RawWaylandMsg {
|
||||||
|
resource_id: u32,
|
||||||
|
opcode: u16,
|
||||||
|
size: u16,
|
||||||
|
payload: Vec<u8>,
|
||||||
|
}
|
||||||
|
impl RawWaylandMsg {
|
||||||
|
const HEADER_SIZE: u16 =
|
||||||
|
(std::mem::size_of::<u32>() + (2 * std::mem::size_of::<u16>())) as u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Wayland {
|
||||||
|
pub fn wl_compositor_create_surface(&mut self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
pub fn xdg_wm_base_get_xdg_surface(&mut self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
pub fn xdg_surface_get_toplevel(&mut self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
pub fn wl_surface_commit(&mut self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn raw_send(&mut self, msg: RawWaylandMsg) -> Result<()> {
|
||||||
|
let mut buffer = vec![];
|
||||||
|
msg.resource_id.push_ne_into(&mut buffer)?;
|
||||||
|
msg.opcode.push_ne_into(&mut buffer)?;
|
||||||
|
msg.size.push_ne_into(&mut buffer)?;
|
||||||
|
buffer.push_vec(msg.payload)?;
|
||||||
|
self.sock.write(&buffer)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_registry(&mut self) -> Result<u32> {
|
||||||
|
let mut payload: Vec<u8> = Vec::new();
|
||||||
|
self.resource_counter += 1;
|
||||||
|
self.resource_counter.push_ne_into(&mut payload)?;
|
||||||
|
let size = RawWaylandMsg::HEADER_SIZE + payload.len() as u16;
|
||||||
|
let msg = RawWaylandMsg {
|
||||||
|
resource_id: WAYLAND_DISPLAY_OBJECT_ID,
|
||||||
|
opcode: WAYLAND_WL_DISPLAY_GET_REGISTRY_OPCODE,
|
||||||
|
size,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
|
||||||
|
return Ok(self.resource_counter);
|
||||||
|
}
|
||||||
|
pub fn registry_bind(
|
||||||
|
&mut self,
|
||||||
|
wl_registry: u32,
|
||||||
|
name: u32,
|
||||||
|
interface: &str,
|
||||||
|
version: u32,
|
||||||
|
) -> Result<u32> {
|
||||||
|
println!(
|
||||||
|
"-> wl_registry@{}.bind: name={} interface={} version={}",
|
||||||
|
wl_registry, name, interface, version
|
||||||
|
);
|
||||||
|
let resource_id = wl_registry;
|
||||||
|
let opcode = WAYLAND_WL_REGISTRY_BIND_OPCODE;
|
||||||
|
|
||||||
|
let mut payload = vec![];
|
||||||
|
name.push_ne_into(&mut payload)?;
|
||||||
|
write_string(&mut payload, interface)?;
|
||||||
|
version.push_ne_into(&mut payload)?;
|
||||||
|
self.resource_counter += 1;
|
||||||
|
self.resource_counter.push_ne_into(&mut payload)?;
|
||||||
|
|
||||||
|
let size = RawWaylandMsg::HEADER_SIZE + payload.len() as u16;
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg {
|
||||||
|
resource_id,
|
||||||
|
opcode,
|
||||||
|
size,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
return Ok(self.resource_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xdg_wm_base_pong(&self, state: &mut State, ping: u32) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xdg_surface_ack_configure(&self, state: &mut State, configure: u32) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wl_shm_create_pool(&self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wl_shm_pool_create_buffer(&self, state: &mut State) -> Result<u32> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn wl_surface_attach(&self, state: &mut State) -> Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_rand_name(len: usize) -> String {
|
||||||
|
let mut s = String::from("/");
|
||||||
|
for _ in 0..(len - 1) {
|
||||||
|
let mut r: f64 = rand::random();
|
||||||
|
let a = ('a' as u8) as f64;
|
||||||
|
r = (r * 26.0) + a;
|
||||||
|
let c: char = r as u8 as char;
|
||||||
|
s.push(c);
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wayland_handle_message(
|
||||||
|
fd: &mut wayland::Wayland,
|
||||||
|
state: &mut wayland::State,
|
||||||
|
msg: &mut &[u8],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if msg.len() < 8 {
|
||||||
|
anyhow::bail!("msg too small for mesage header");
|
||||||
|
}
|
||||||
|
let object_id: u32 = msg.try_pop_ne()?;
|
||||||
|
let opcode: u16 = msg.try_pop_ne()?;
|
||||||
|
let msglen: u16 = msg.try_pop_ne()?;
|
||||||
|
let payloadlen = msglen as usize - 8;
|
||||||
|
|
||||||
|
let mut payload = &msg[0..payloadlen as usize];
|
||||||
|
*msg = &msg[payloadlen..];
|
||||||
|
|
||||||
|
if object_id == state.wl_registry && opcode == wayland::WAYLAND_WL_REGISTRY_EVENT_GLOBAL {
|
||||||
|
let name: u32 = payload.try_pop_ne()?;
|
||||||
|
let interface_len: u32 = payload.try_pop_ne()?;
|
||||||
|
let padded_interface_len = wayland::nearest_multiple_4(interface_len as i32) as usize;
|
||||||
|
|
||||||
|
let interface = CStr::from_bytes_until_nul(&payload[..padded_interface_len])?.to_str()?;
|
||||||
|
payload = &payload[padded_interface_len..];
|
||||||
|
|
||||||
|
let version: u32 = payload.try_pop_ne()?;
|
||||||
|
println!(
|
||||||
|
"<- wl_registry@{}.global: name={name} interface={interface} version={version}",
|
||||||
|
state.wl_registry
|
||||||
|
);
|
||||||
|
|
||||||
|
use std::mem::size_of_val;
|
||||||
|
assert_eq!(
|
||||||
|
msglen as usize,
|
||||||
|
size_of_val(&object_id)
|
||||||
|
+ size_of_val(&opcode)
|
||||||
|
+ size_of_val(&msglen)
|
||||||
|
+ size_of_val(&name)
|
||||||
|
+ size_of_val(&interface_len)
|
||||||
|
+ padded_interface_len
|
||||||
|
+ size_of_val(&version)
|
||||||
|
);
|
||||||
|
|
||||||
|
match interface {
|
||||||
|
"wl_shm" => {
|
||||||
|
state.wl_shm = fd.registry_bind(state.wl_registry, name, interface, version)?;
|
||||||
|
}
|
||||||
|
"xdg_wm_base" => {
|
||||||
|
state.xdg_wm_base =
|
||||||
|
fd.registry_bind(state.wl_registry, name, interface, version)?;
|
||||||
|
}
|
||||||
|
"wl_compositor" => {
|
||||||
|
state.wl_compositor =
|
||||||
|
fd.registry_bind(state.wl_registry, name, interface, version)?;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
} else if object_id == wayland::WAYLAND_DISPLAY_OBJECT_ID
|
||||||
|
&& opcode == wayland::WAYLAND_WL_DISPLAY_ERROR_EVENT
|
||||||
|
{
|
||||||
|
let target_object_id: u32 = payload.try_pop_ne()?;
|
||||||
|
let code: u32 = payload.try_pop_ne()?;
|
||||||
|
let error_len: u32 = payload.try_pop_ne()?;
|
||||||
|
let padded_err_len: usize = wayland::nearest_multiple_4(error_len as i32) as usize;
|
||||||
|
|
||||||
|
let error = CStr::from_bytes_until_nul(&payload[..padded_err_len])?.to_str()?;
|
||||||
|
//payload = &payload[padded_err_len..];
|
||||||
|
anyhow::bail!(
|
||||||
|
"fatal error: target_object_id={} code={} error={}",
|
||||||
|
target_object_id,
|
||||||
|
code,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
} else if object_id == state.xdg_wm_base && opcode == WAYLAND_XDG_BASE_EVENT_PING {
|
||||||
|
let ping: u32 = payload.try_pop_ne()?;
|
||||||
|
println!("<- xdg_wm_base@{}.ping: ping={}", state.xdg_wm_base, ping);
|
||||||
|
fd.xdg_wm_base_pong(state, ping)?;
|
||||||
|
} else if object_id == state.xdg_surface
|
||||||
|
&& opcode == wayland::WAYLAND_XDG_SURFACE_EVENT_CONFIGURE
|
||||||
|
{
|
||||||
|
let configure: u32 = payload.try_pop_ne()?;
|
||||||
|
println!(
|
||||||
|
"<- xdg_surface@{}.configure: configure={}",
|
||||||
|
state.xdg_surface, configure
|
||||||
|
);
|
||||||
|
fd.xdg_surface_ack_configure(state, configure)?;
|
||||||
|
// TODO: move into xdg_surface_ack_configure
|
||||||
|
state.state = wayland::StateEnum::SurfaceAckedConfigure;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> anyhow::Result<()> {
|
||||||
|
let mut display = wayland::connect()?;
|
||||||
|
let reg = display.get_registry()?;
|
||||||
|
|
||||||
|
let mut state = wayland::State::default();
|
||||||
|
state.wl_registry = reg;
|
||||||
|
state.w = 117;
|
||||||
|
state.h = 150;
|
||||||
|
state.stride = state.w * wayland::COLOR_CHANNELS;
|
||||||
|
|
||||||
|
// Single buffering.
|
||||||
|
state.shm_pool_size = state.h * state.stride;
|
||||||
|
|
||||||
|
let shm_path = gen_rand_name(255);
|
||||||
|
let fd = shm::open(
|
||||||
|
&shm_path,
|
||||||
|
shm::OFlags::RDWR | shm::OFlags::EXCL | shm::OFlags::CREATE,
|
||||||
|
Mode::WUSR | Mode::RUSR,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// file descriptor remains valid since our process still has the file open
|
||||||
|
shm::unlink(shm_path)?;
|
||||||
|
ftruncate(&fd, state.shm_pool_size as u64)?;
|
||||||
|
|
||||||
|
let ptr = unsafe {
|
||||||
|
mmap(
|
||||||
|
null_mut(),
|
||||||
|
state.shm_pool_size as usize,
|
||||||
|
ProtFlags::READ | ProtFlags::WRITE,
|
||||||
|
MapFlags::SHARED,
|
||||||
|
&fd,
|
||||||
|
0,
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
state.shm_pool_data = Some(ptr);
|
||||||
|
state.shm_fd = Some(fd);
|
||||||
|
|
||||||
|
let mut buf = [0_u8; 4096];
|
||||||
|
loop {
|
||||||
|
let read_bytes = display.sock.read(&mut buf)?;
|
||||||
|
let mut msgs = &buf[..read_bytes];
|
||||||
|
while msgs.len() > 0 {
|
||||||
|
wayland_handle_message(&mut display, &mut state, &mut msgs)?;
|
||||||
|
|
||||||
|
if state.wl_compositor != 0
|
||||||
|
&& state.wl_shm != 0
|
||||||
|
&& state.xdg_wm_base != 0
|
||||||
|
&& state.wl_surface == 0
|
||||||
|
{
|
||||||
|
assert_eq!(state.state, wayland::StateEnum::None);
|
||||||
|
|
||||||
|
state.wl_surface = display.wl_compositor_create_surface(&mut state)?;
|
||||||
|
state.xdg_surface = display.xdg_wm_base_get_xdg_surface(&mut state)?;
|
||||||
|
state.xdg_toplevel = display.xdg_surface_get_toplevel(&mut state)?;
|
||||||
|
display.wl_surface_commit(&mut state)?;
|
||||||
|
}
|
||||||
|
if state.state == wayland::StateEnum::SurfaceAckedConfigure {
|
||||||
|
assert_ne!(state.wl_surface, 0);
|
||||||
|
assert_ne!(state.xdg_surface, 0);
|
||||||
|
assert_ne!(state.xdg_toplevel, 0);
|
||||||
|
|
||||||
|
if state.wl_shm_pool == 0 {
|
||||||
|
state.wl_shm_pool = display.wl_shm_create_pool(&mut state)?;
|
||||||
|
}
|
||||||
|
if state.wl_buffer == 0 {
|
||||||
|
state.wl_buffer = display.wl_shm_pool_create_buffer(&mut state)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let n_pixels = state.w as usize * state.h as usize;
|
||||||
|
let pixels;
|
||||||
|
let ptr = state.shm_pool_data.unwrap() as *mut u32;
|
||||||
|
unsafe {
|
||||||
|
pixels = std::slice::from_raw_parts_mut(ptr, n_pixels);
|
||||||
|
}
|
||||||
|
for pixel in pixels {
|
||||||
|
let r: u32 = 255;
|
||||||
|
let g: u32 = 0;
|
||||||
|
let b: u32 = 0;
|
||||||
|
*pixel = (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
display.wl_surface_attach(&mut state)?;
|
||||||
|
display.wl_surface_commit(&mut state)?;
|
||||||
|
state.state = wayland::StateEnum::SurfaceAttached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ok(())
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user