implement more functions
This commit is contained in:
parent
b4b803eed0
commit
ea9bd53755
248
src/main.rs
248
src/main.rs
@ -23,7 +23,17 @@ mod wayland {
|
|||||||
pub const WAYLAND_WL_REGISTRY_EVENT_GLOBAL: u16 = 0;
|
pub const WAYLAND_WL_REGISTRY_EVENT_GLOBAL: u16 = 0;
|
||||||
pub const WAYLAND_WL_DISPLAY_ERROR_EVENT: u16 = 0;
|
pub const WAYLAND_WL_DISPLAY_ERROR_EVENT: u16 = 0;
|
||||||
pub const WAYLAND_XDG_BASE_EVENT_PING: u16 = 0;
|
pub const WAYLAND_XDG_BASE_EVENT_PING: u16 = 0;
|
||||||
|
pub const WAYLAND_WL_COMPOSITOR_CREATE_SURFACE_OPCODE: u16 = 0;
|
||||||
pub const WAYLAND_XDG_SURFACE_EVENT_CONFIGURE: u16 = 0;
|
pub const WAYLAND_XDG_SURFACE_EVENT_CONFIGURE: u16 = 0;
|
||||||
|
pub const WAYLAND_WL_SURFACE_COMMIT_OPCODE: u16 = 6;
|
||||||
|
pub const WAYLAND_XDG_WM_BASE_GET_XDG_SURFACE_OPCODE: u16 = 2;
|
||||||
|
pub const WAYLAND_XDG_SURFACE_GET_TOPLEVEL_OPCODE: u16 = 1;
|
||||||
|
pub const WAYLAND_XDG_WM_BASE_PONG_OPCODE: u16 = 3;
|
||||||
|
pub const WAYLAND_XDG_SURFACE_ACK_CONFIGURE_OPCODE: u16 = 4;
|
||||||
|
pub const WAYLAND_WL_SHM_POOL_CREATE_BUFFER_OPCODE: u16 = 0;
|
||||||
|
pub const WAYLAND_FORMAT_XRGB8888: u32 = 1;
|
||||||
|
pub const WAYLAND_WL_SURFACE_ATTACH_OPCODE: u16 = 1;
|
||||||
|
pub const WAYLAND_WL_SHM_CREATE_POOL_OPCODE: u16 = 0;
|
||||||
|
|
||||||
pub fn write_string(buf: &mut Vec<u8>, src: &str) -> Result<usize> {
|
pub fn write_string(buf: &mut Vec<u8>, src: &str) -> Result<usize> {
|
||||||
let mut n_write = 0;
|
let mut n_write = 0;
|
||||||
@ -35,6 +45,7 @@ mod wayland {
|
|||||||
let required_size = nearest_multiple_4(n_write as i32) as usize;
|
let required_size = nearest_multiple_4(n_write as i32) as usize;
|
||||||
while n_write < required_size {
|
while n_write < required_size {
|
||||||
buf.push(0);
|
buf.push(0);
|
||||||
|
n_write += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(n_write);
|
return Ok(n_write);
|
||||||
@ -78,15 +89,18 @@ mod wayland {
|
|||||||
}
|
}
|
||||||
pub fn connect() -> Result<Wayland> {
|
pub fn connect() -> Result<Wayland> {
|
||||||
let xdg_runtime_dir = env::var("XDG_RUNTIME_DIR")?;
|
let xdg_runtime_dir = env::var("XDG_RUNTIME_DIR")?;
|
||||||
|
println!("Using xdg runtime dir: {}", xdg_runtime_dir);
|
||||||
let wayland_display = env::var("WAYLAND_DISPLAY").unwrap_or("wayland-0".into());
|
let wayland_display = env::var("WAYLAND_DISPLAY").unwrap_or("wayland-0".into());
|
||||||
let wayland_path = xdg_runtime_dir + &wayland_display;
|
let wayland_path = xdg_runtime_dir + "/" + &wayland_display;
|
||||||
|
println!("Opening UnixStream: {wayland_path}");
|
||||||
let sock = UnixStream::connect(&wayland_path)?;
|
let sock = UnixStream::connect(&wayland_path)?;
|
||||||
Ok(Wayland {
|
Ok(Wayland {
|
||||||
sock,
|
sock,
|
||||||
resource_counter: 2,
|
resource_counter: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct RawWaylandMsg {
|
struct RawWaylandMsg {
|
||||||
resource_id: u32,
|
resource_id: u32,
|
||||||
opcode: u16,
|
opcode: u16,
|
||||||
@ -96,27 +110,103 @@ mod wayland {
|
|||||||
impl RawWaylandMsg {
|
impl RawWaylandMsg {
|
||||||
const HEADER_SIZE: u16 =
|
const HEADER_SIZE: u16 =
|
||||||
(std::mem::size_of::<u32>() + (2 * std::mem::size_of::<u16>())) as u16;
|
(std::mem::size_of::<u32>() + (2 * std::mem::size_of::<u16>())) as u16;
|
||||||
|
pub fn new(resource_id: u32, opcode: u16, payload: Vec<u8>) -> Self {
|
||||||
|
RawWaylandMsg {
|
||||||
|
resource_id,
|
||||||
|
opcode,
|
||||||
|
size: Self::HEADER_SIZE + payload.len() as u16,
|
||||||
|
payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wayland {
|
impl Wayland {
|
||||||
pub fn wl_compositor_create_surface(&mut self, state: &mut State) -> Result<u32> {
|
pub fn wl_compositor_create_surface(&mut self, state: &mut State) -> Result<u32> {
|
||||||
todo!()
|
assert!(state.wl_compositor > 0);
|
||||||
|
let resource_id = state.wl_compositor;
|
||||||
|
let opcode = WAYLAND_WL_COMPOSITOR_CREATE_SURFACE_OPCODE;
|
||||||
|
|
||||||
|
self.resource_counter += 1;
|
||||||
|
let object_id = self.resource_counter;
|
||||||
|
let mut payload = Vec::new();
|
||||||
|
object_id.push_ne_into(&mut payload)?;
|
||||||
|
|
||||||
|
let size = RawWaylandMsg::HEADER_SIZE + payload.len() as u16;
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg {
|
||||||
|
resource_id,
|
||||||
|
opcode,
|
||||||
|
size,
|
||||||
|
payload,
|
||||||
|
};
|
||||||
|
println!(
|
||||||
|
"-> wl_compositor@{}.create_surface: wl_surface={}",
|
||||||
|
state.wl_compositor, object_id
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(object_id)
|
||||||
}
|
}
|
||||||
pub fn xdg_wm_base_get_xdg_surface(&mut self, state: &mut State) -> Result<u32> {
|
pub fn xdg_wm_base_get_xdg_surface(&mut self, state: &mut State) -> Result<u32> {
|
||||||
todo!()
|
assert!(state.xdg_wm_base > 0);
|
||||||
|
assert!(state.wl_surface > 0);
|
||||||
|
|
||||||
|
self.resource_counter += 1;
|
||||||
|
let object_id = self.resource_counter;
|
||||||
|
let mut payload = object_id.to_ne_bytes().to_vec();
|
||||||
|
state.wl_surface.push_ne_into(&mut payload)?;
|
||||||
|
let msg: RawWaylandMsg = RawWaylandMsg::new(
|
||||||
|
state.xdg_wm_base,
|
||||||
|
WAYLAND_XDG_WM_BASE_GET_XDG_SURFACE_OPCODE,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"-> xdg_wm_base@{}.get_xdg_surface: xdg_surface={} wl_surface={}",
|
||||||
|
state.xdg_wm_base, object_id, state.wl_surface
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(object_id)
|
||||||
}
|
}
|
||||||
pub fn xdg_surface_get_toplevel(&mut self, state: &mut State) -> Result<u32> {
|
pub fn xdg_surface_get_toplevel(&mut self, state: &mut State) -> Result<u32> {
|
||||||
todo!()
|
assert!(state.xdg_surface > 0);
|
||||||
|
self.resource_counter += 1;
|
||||||
|
let payload = self.resource_counter.to_ne_bytes().to_vec();
|
||||||
|
let msg = RawWaylandMsg::new(
|
||||||
|
state.xdg_surface,
|
||||||
|
WAYLAND_XDG_SURFACE_GET_TOPLEVEL_OPCODE,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"-> xdg_surface@{}.get_toplevel: xdg_toplevel={}",
|
||||||
|
state.xdg_surface, self.resource_counter
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(self.resource_counter)
|
||||||
}
|
}
|
||||||
pub fn wl_surface_commit(&mut self, state: &mut State) -> Result<u32> {
|
pub fn wl_surface_commit(&mut self, state: &mut State) -> Result<()> {
|
||||||
todo!()
|
assert!(state.wl_surface > 0);
|
||||||
|
let msg =
|
||||||
|
RawWaylandMsg::new(state.wl_surface, WAYLAND_WL_SURFACE_COMMIT_OPCODE, vec![]);
|
||||||
|
println!("-> wl_surface@{}.commit: ", state.wl_surface);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
fn raw_send(&mut self, msg: RawWaylandMsg) -> Result<()> {
|
fn raw_send(&mut self, msg: RawWaylandMsg) -> Result<()> {
|
||||||
|
//println!("msg: {msg:?}");
|
||||||
let mut buffer = vec![];
|
let mut buffer = vec![];
|
||||||
msg.resource_id.push_ne_into(&mut buffer)?;
|
msg.resource_id.push_ne_into(&mut buffer)?;
|
||||||
msg.opcode.push_ne_into(&mut buffer)?;
|
msg.opcode.push_ne_into(&mut buffer)?;
|
||||||
msg.size.push_ne_into(&mut buffer)?;
|
msg.size.push_ne_into(&mut buffer)?;
|
||||||
buffer.push_vec(msg.payload)?;
|
buffer.push_vec(msg.payload)?;
|
||||||
|
|
||||||
|
/*
|
||||||
|
println!("msg_size: {}", buffer.len());
|
||||||
|
println!("msg_announced_size: {}", msg.size);
|
||||||
|
for i in buffer.iter() {
|
||||||
|
print!("{} ", *i);
|
||||||
|
}
|
||||||
|
println!("");
|
||||||
|
*/
|
||||||
|
|
||||||
self.sock.write(&buffer)?;
|
self.sock.write(&buffer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -133,6 +223,10 @@ mod wayland {
|
|||||||
payload,
|
payload,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"-> wl_display@{WAYLAND_DISPLAY_OBJECT_ID}.get_registry: wl_registry={}",
|
||||||
|
self.resource_counter
|
||||||
|
);
|
||||||
self.raw_send(msg)?;
|
self.raw_send(msg)?;
|
||||||
|
|
||||||
return Ok(self.resource_counter);
|
return Ok(self.resource_counter);
|
||||||
@ -170,24 +264,139 @@ mod wayland {
|
|||||||
return Ok(self.resource_counter);
|
return Ok(self.resource_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn xdg_wm_base_pong(&self, state: &mut State, ping: u32) -> Result<()> {
|
pub fn xdg_wm_base_pong(&mut self, state: &mut State, ping: u32) -> Result<()> {
|
||||||
|
assert!(state.xdg_wm_base > 0);
|
||||||
|
assert!(state.wl_surface > 0);
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg::new(
|
||||||
|
state.xdg_wm_base,
|
||||||
|
WAYLAND_XDG_WM_BASE_PONG_OPCODE,
|
||||||
|
ping.to_ne_bytes().to_vec(),
|
||||||
|
);
|
||||||
|
println!("-> xdg_wm_base@{}.pong: ping={}", state.xdg_wm_base, ping);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xdg_surface_ack_configure(
|
||||||
|
&mut self,
|
||||||
|
state: &mut State,
|
||||||
|
configure: u32,
|
||||||
|
) -> Result<()> {
|
||||||
|
assert!(state.xdg_surface > 0);
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg::new(
|
||||||
|
state.xdg_surface,
|
||||||
|
WAYLAND_XDG_SURFACE_ACK_CONFIGURE_OPCODE,
|
||||||
|
configure.to_ne_bytes().to_vec(),
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"-> xdg_surface@{}.ack_configure: configure={}",
|
||||||
|
state.xdg_surface, configure
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn wl_shm_create_pool(&mut self, state: &mut State) -> Result<u32> {
|
||||||
|
assert!(state.shm_pool_size > 0);
|
||||||
|
let _resource_id = state.wl_shm;
|
||||||
|
let _opcode = WAYLAND_WL_SHM_CREATE_POOL_OPCODE;
|
||||||
|
self.resource_counter += 1;
|
||||||
|
let _object_id = self.resource_counter;
|
||||||
|
/*
|
||||||
|
uint16_t msg_announced_size = wayland_header_size +
|
||||||
|
sizeof(wayland_current_id) +
|
||||||
|
sizeof(state->shm_pool_size);
|
||||||
|
|
||||||
|
assert(roundup_4(msg_announced_size) == msg_announced_size);
|
||||||
|
buf_write_u16(msg, &msg_size, sizeof(msg), msg_announced_size);
|
||||||
|
|
||||||
|
wayland_current_id++;
|
||||||
|
buf_write_u32(msg, &msg_size, sizeof(msg), wayland_current_id);
|
||||||
|
|
||||||
|
buf_write_u32(msg, &msg_size, sizeof(msg), state->shm_pool_size);
|
||||||
|
|
||||||
|
assert(roundup_4(msg_size) == msg_size);
|
||||||
|
|
||||||
|
// Send the file descriptor as ancillary data.
|
||||||
|
// UNIX/Macros monstrosities ahead.
|
||||||
|
char buf[CMSG_SPACE(sizeof(state->shm_fd))] = "";
|
||||||
|
|
||||||
|
struct iovec io = {.iov_base = msg, .iov_len = msg_size};
|
||||||
|
struct msghdr socket_msg = {
|
||||||
|
.msg_iov = &io,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
.msg_control = buf,
|
||||||
|
.msg_controllen = sizeof(buf),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&socket_msg);
|
||||||
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
|
cmsg->cmsg_len = CMSG_LEN(sizeof(state->shm_fd));
|
||||||
|
|
||||||
|
*((int *)CMSG_DATA(cmsg)) = state->shm_fd;
|
||||||
|
socket_msg.msg_controllen = CMSG_SPACE(sizeof(state->shm_fd));
|
||||||
|
|
||||||
|
if (sendmsg(fd, &socket_msg, 0) == -1)
|
||||||
|
exit(errno);
|
||||||
|
|
||||||
|
printf("-> wl_shm@%u.create_pool: wl_shm_pool=%u\n", state->wl_shm,
|
||||||
|
wayland_current_id);
|
||||||
|
|
||||||
|
return wayland_current_id;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// FIXME:
|
||||||
|
println!("-x wl_shm@{}.create_pool: NOT IMPLEMENTED", state.wl_shm);
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn xdg_surface_ack_configure(&self, state: &mut State, configure: u32) -> Result<()> {
|
pub fn wl_shm_pool_create_buffer(&mut self, state: &mut State) -> Result<u32> {
|
||||||
todo!()
|
assert!(state.wl_shm_pool > 0);
|
||||||
|
let resource_id = state.wl_shm_pool;
|
||||||
|
let opcode = WAYLAND_WL_SHM_POOL_CREATE_BUFFER_OPCODE;
|
||||||
|
|
||||||
|
self.resource_counter += 1;
|
||||||
|
let mut payload = self.resource_counter.to_ne_bytes().to_vec();
|
||||||
|
0_u32.push_ne_into(&mut payload)?;
|
||||||
|
state.w.push_ne_into(&mut payload)?;
|
||||||
|
state.h.push_ne_into(&mut payload)?;
|
||||||
|
state.stride.push_ne_into(&mut payload)?;
|
||||||
|
WAYLAND_FORMAT_XRGB8888.push_ne_into(&mut payload)?;
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg::new(resource_id, opcode, payload);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"-> wl_shm_pool@{}.create_buffer: wl_buffer={}",
|
||||||
|
state.wl_shm_pool, self.resource_counter
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
Ok(self.resource_counter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wl_shm_create_pool(&self, state: &mut State) -> Result<u32> {
|
pub fn wl_surface_attach(&mut self, state: &mut State) -> Result<()> {
|
||||||
todo!()
|
assert!(state.wl_surface > 0);
|
||||||
}
|
assert!(state.wl_buffer > 0);
|
||||||
|
|
||||||
pub fn wl_shm_pool_create_buffer(&self, state: &mut State) -> Result<u32> {
|
let resource_id = state.wl_surface;
|
||||||
todo!()
|
let opcode = WAYLAND_WL_SURFACE_ATTACH_OPCODE;
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn wl_surface_attach(&self, state: &mut State) -> Result<()> {
|
let mut payload = Vec::new();
|
||||||
todo!()
|
state.wl_buffer.push_ne_into(&mut payload)?;
|
||||||
|
let (x, y) = (0_u32, 0_u32);
|
||||||
|
x.push_ne_into(&mut payload)?;
|
||||||
|
y.push_ne_into(&mut payload)?;
|
||||||
|
|
||||||
|
let msg = RawWaylandMsg::new(resource_id, opcode, payload);
|
||||||
|
println!(
|
||||||
|
"-> wl_surface@{}.attach: wl_buffer={}",
|
||||||
|
resource_id, state.wl_buffer
|
||||||
|
);
|
||||||
|
self.raw_send(msg)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +410,7 @@ fn gen_rand_name(len: usize) -> String {
|
|||||||
let c: char = r as u8 as char;
|
let c: char = r as u8 as char;
|
||||||
s.push(c);
|
s.push(c);
|
||||||
}
|
}
|
||||||
todo!()
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wayland_handle_message(
|
fn wayland_handle_message(
|
||||||
@ -300,6 +509,7 @@ fn wayland_handle_message(
|
|||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let mut display = wayland::connect()?;
|
let mut display = wayland::connect()?;
|
||||||
|
println!("Connected to wayland display");
|
||||||
let reg = display.get_registry()?;
|
let reg = display.get_registry()?;
|
||||||
|
|
||||||
let mut state = wayland::State::default();
|
let mut state = wayland::State::default();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user