Create and map shared memory pool with libc

This commit is contained in:
2025-04-03 13:38:12 -07:00
parent 07e8089787
commit 7369c5f813
5 changed files with 143 additions and 3 deletions

View File

@@ -1,14 +1,19 @@
use std::{env, error::Error, io::{Read, Write}, os::unix::net::UnixStream, u32};
#![feature(unix_socket_ancillary_data)]
use std::{env, error::Error, io::{Read, Write}, os::unix::net::{UnixStream, SocketAncillary, AncillaryData}, u32};
use shm::shm::ShmPool;
mod shm;
struct WlState {
socket: UnixStream,
current_id: u32,
registry_id: Option<u32>,
shm_id: Option<u32>
shm_id: Option<u32>,
shm_pool: Option<ShmPool>
}
struct WlHeader {
object: u32,30334241
object: u32,
opcode: u16,
size: u16
}
@@ -171,6 +176,63 @@ fn wl_shm_format(event: &Vec<u8>) {
println!("Received pixel format: {:x}", event.read_u32(&mut offset));
}
fn wl_shm_create_pool(wl_state: &mut WlState) -> Result<(), String> {
wl_state.current_id += 1;
wl_state.shm_pool = Some(match ShmPool::new(4096, wl_state.current_id) {
Ok(val) => val,
Err(err) => {
return Err(err.to_string());
}
});
let object = match wl_state.shm_id {
Some(val) => val,
None => {
return Err("error in wl_shm_create_pool: shm_id not set!".to_string());
}
};
const OPCODE: u16 = 0;
const REQ_SIZE: u16 = 16;
let id = wl_state.shm_pool.as_ref().unwrap().id;
let fds = [wl_state.shm_pool.as_ref().unwrap().fd];
let shm_size = wl_state.shm_pool.as_ref().unwrap().size;
let mut request = vec![0u8; REQ_SIZE as usize];
let mut offset: usize = 0;
// Request header
request.write_u32(&object, &mut offset);
request.write_u16(&OPCODE, &mut offset);
request.write_u16(&REQ_SIZE, &mut offset);
// Id, size of shm pool
request.write_u32(&id, &mut offset);
request.write_u32(&(shm_size as u32), &mut offset);
println!("{:?}", request);
let mut ancillary_buf = [0u8; 32];
let mut ancillary = SocketAncillary::new(&mut ancillary_buf[..]);
assert!(ancillary.add_fds(&fds[..]));
match wl_state.socket.send_vectored_with_ancillary(&[std::io::IoSlice::new(&request)], &mut ancillary) {
Ok(bytes) => {
assert!(bytes == REQ_SIZE as usize);
}
Err(err) => {
return Err(err.to_string());
}
};
Ok(())
}
fn wl_shm_pool_resize(event: &Vec<u8>, wl_state: &mut WlState) -> std::io::Result<()> {
let mut offset: usize = 0;
let size = event.read_u32(&mut offset);
wl_state.shm_pool.as_mut().unwrap().resize(size as usize)
}
fn wl_registry_global(event: &Vec<u8>, wl_state: &mut WlState) -> Result<(), Box<dyn Error>> {
let mut offset: usize = 0;
@@ -195,6 +257,7 @@ fn wl_registry_global(event: &Vec<u8>, wl_state: &mut WlState) -> Result<(), Box
&wl_state.current_id.clone()
)?;
wl_state.shm_id = Some(wl_state.current_id);
wl_shm_create_pool(wl_state)?;
}
Ok(())
@@ -215,6 +278,7 @@ fn main() -> Result<(), Box<dyn Error>> {
current_id: 1,
registry_id: None,
shm_id: None,
shm_pool: None,
};
wl_display_get_registry(&mut wl_state)?;
@@ -243,6 +307,9 @@ fn main() -> Result<(), Box<dyn Error>> {
else if wl_state.shm_id.is_some() && header.object == wl_state.shm_id.unwrap() && header.opcode == 0 { // wl_shm::format
wl_shm_format(&event);
}
else if wl_state.shm_pool.is_some() && header.object == wl_state.shm_pool.as_ref().unwrap().id && header.opcode == 2 {
wl_shm_pool_resize(&event, &mut wl_state)?;
}
else {
println!(
"Received event:\n\tObject: {}\n\tOpcode: {}\n\tSize: {}",