Move WlHeader trait and impl from main.rs to vec_utils.rs
This commit is contained in:
97
src/main.rs
97
src/main.rs
@@ -1,15 +1,22 @@
|
|||||||
#![feature(unix_socket_ancillary_data)]
|
#![feature(unix_socket_ancillary_data)]
|
||||||
use std::{env, error::Error, io::{Read, Write}, os::unix::net::{UnixStream, SocketAncillary}, u32};
|
use std::{env, error::Error, io::{Read, Write}, os::unix::net::{UnixStream, SocketAncillary}, u32};
|
||||||
|
|
||||||
use shm::shm::ShmPool;
|
|
||||||
mod shm;
|
mod shm;
|
||||||
|
mod vec_utils;
|
||||||
|
pub use vec_utils::WlMessage;
|
||||||
|
|
||||||
|
struct WlHeader {
|
||||||
|
object: u32,
|
||||||
|
opcode: u16,
|
||||||
|
size: u16
|
||||||
|
}
|
||||||
|
|
||||||
struct WlClient {
|
struct WlClient {
|
||||||
socket: UnixStream,
|
socket: UnixStream,
|
||||||
current_id: u32,
|
current_id: u32,
|
||||||
registry_id: Option<u32>,
|
registry_id: Option<u32>,
|
||||||
shm_id: Option<u32>,
|
shm_id: Option<u32>,
|
||||||
shm_pool: Option<ShmPool>
|
shm_pool: Option<shm::ShmPool>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlClient {
|
impl WlClient {
|
||||||
@@ -149,7 +156,7 @@ impl WlClient {
|
|||||||
|
|
||||||
fn wl_shm_create_pool(&mut self) -> Result<(), String> {
|
fn wl_shm_create_pool(&mut self) -> Result<(), String> {
|
||||||
self.current_id += 1;
|
self.current_id += 1;
|
||||||
self.shm_pool = Some(match ShmPool::new(4096, self.current_id) {
|
self.shm_pool = Some(match shm::ShmPool::new(4096, self.current_id) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(err.to_string());
|
return Err(err.to_string());
|
||||||
@@ -226,8 +233,6 @@ impl WlClient {
|
|||||||
request.write_u32(&stride, &mut offset);
|
request.write_u32(&stride, &mut offset);
|
||||||
request.write_u32(&format, &mut offset);
|
request.write_u32(&format, &mut offset);
|
||||||
|
|
||||||
println!("Creating wl_buffer: {:?}", request);
|
|
||||||
|
|
||||||
self.socket.write(&request)?;
|
self.socket.write(&request)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -265,88 +270,6 @@ impl WlClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WlHeader {
|
|
||||||
object: u32,
|
|
||||||
opcode: u16,
|
|
||||||
size: u16
|
|
||||||
}
|
|
||||||
|
|
||||||
trait WlMessage {
|
|
||||||
/// Write a u32 to self at offset and increment offset by four
|
|
||||||
fn write_u32(&mut self, value: &u32, offset: &mut usize);
|
|
||||||
/// Write a u16 to self at offset and increment offset by four
|
|
||||||
fn write_u16(&mut self, value: &u16, offset: &mut usize);
|
|
||||||
/// Write a string to self at offset
|
|
||||||
/// and increment offset by string length rounded up to four bytes
|
|
||||||
fn write_string(&mut self, str: &String, offset: &mut usize);
|
|
||||||
/// Read a u32 from self at offset and increment offset by four
|
|
||||||
fn read_u32(&self, offset: &mut usize) -> u32;
|
|
||||||
/// Read a u16 from self at offset and increment offset by two
|
|
||||||
fn read_u16(&self, offset: &mut usize) -> u16;
|
|
||||||
/// Read a string from self at offset
|
|
||||||
/// and increment offset by string length rounded up to four bytes
|
|
||||||
fn read_string(&self, offset: &mut usize) -> String;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WlMessage for Vec<u8> {
|
|
||||||
fn write_u32(&mut self, value: &u32, offset: &mut usize) {
|
|
||||||
self[*offset..*offset+4].copy_from_slice(&value.to_ne_bytes());
|
|
||||||
*offset += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_u16(&mut self, value: &u16, offset: &mut usize) {
|
|
||||||
self[*offset..*offset+2].copy_from_slice(&value.to_ne_bytes());
|
|
||||||
*offset += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_string(&mut self, str: &String, offset: &mut usize) {
|
|
||||||
let mut str = str.clone();
|
|
||||||
str.push('\0');
|
|
||||||
let rounded_len: u32 = (str.len()+3) as u32 & (u32::MAX-3);
|
|
||||||
self.write_u32(&rounded_len, offset);
|
|
||||||
self[*offset..*offset+str.len()].copy_from_slice(str.as_bytes());
|
|
||||||
*offset += rounded_len as usize;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u32(&self, offset: &mut usize) -> u32 {
|
|
||||||
let res = u32::from_ne_bytes(
|
|
||||||
self[*offset..*offset+4]
|
|
||||||
.try_into()
|
|
||||||
.expect("u32::from_ne_bytes failed in WlEvent::read_u32")
|
|
||||||
);
|
|
||||||
*offset += 4;
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u16(&self, offset: &mut usize) -> u16 {
|
|
||||||
let res = u16::from_ne_bytes(
|
|
||||||
self[*offset..*offset+2]
|
|
||||||
.try_into()
|
|
||||||
.expect("u32::from_ne_bytes failed in WlEvent::read_u32")
|
|
||||||
);
|
|
||||||
*offset += 2;
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_string(&self, offset: &mut usize) -> String {
|
|
||||||
let str_len = u32::from_ne_bytes(
|
|
||||||
self[*offset..*offset+4]
|
|
||||||
.try_into()
|
|
||||||
.expect("u32::from_ne_bytes failed in WlEvent::read_string")
|
|
||||||
);
|
|
||||||
*offset += 4;
|
|
||||||
let str = String::from_utf8(
|
|
||||||
self[*offset..*offset+((str_len-1) as usize)]
|
|
||||||
.to_vec())
|
|
||||||
.expect("String::from_utf8 failed in WlEvent::read_string()"
|
|
||||||
);
|
|
||||||
*offset += (str_len+3 & u32::MAX-3) as usize;
|
|
||||||
str
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let mut wl_client = WlClient::new()?;
|
let mut wl_client = WlClient::new()?;
|
||||||
|
|
||||||
|
|||||||
116
src/shm.rs
116
src/shm.rs
@@ -1,62 +1,58 @@
|
|||||||
pub mod shm {
|
use libc::{c_void, ftruncate, mmap, munmap, shm_open, shm_unlink, MAP_FAILED, MAP_SHARED, O_CREAT, O_EXCL, O_RDWR, PROT_READ};
|
||||||
|
|
||||||
use libc::{c_void, ftruncate, mmap, munmap, shm_open, shm_unlink, MAP_FAILED, MAP_SHARED, O_CREAT, O_EXCL, O_RDWR, PROT_READ};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ShmPool {
|
|
||||||
pub fd: i32,
|
|
||||||
pub id: u32,
|
|
||||||
pub addr: *mut c_void,
|
|
||||||
pub size: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShmPool {
|
|
||||||
pub fn new(size: usize, id: u32) -> std::io::Result<ShmPool> {
|
|
||||||
let shm_path: *const i8 = b"/chlorostart\0".as_ptr() as *const i8;
|
|
||||||
let fd = unsafe { shm_open(shm_path, O_RDWR | O_EXCL | O_CREAT, 0o600) };
|
|
||||||
if fd == -1 {
|
|
||||||
eprint!("shm_open in ShmPool::new() failed: ");
|
|
||||||
return Err(std::io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
if unsafe { shm_unlink(shm_path) } == -1 {
|
|
||||||
eprint!("shm_unlink in ShmPool::new() failed: ");
|
|
||||||
return Err(std::io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
if unsafe { ftruncate(fd, size as i64) } == -1 {
|
|
||||||
eprint!("ftruncate in ShmPool::new() failed: ");
|
|
||||||
return Err(std::io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
let addr = unsafe {
|
|
||||||
mmap(std::ptr::null_mut(), size, PROT_READ | PROT_READ, MAP_SHARED, fd, 0)
|
|
||||||
};
|
|
||||||
|
|
||||||
if addr == MAP_FAILED {
|
|
||||||
eprint!("mmap in ShmPool::new() failed: ");
|
|
||||||
return Err(std::io::Error::last_os_error())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ShmPool {
|
|
||||||
fd,
|
|
||||||
id,
|
|
||||||
addr,
|
|
||||||
size
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn resize(&mut self, size: usize) -> std::io::Result<()> {
|
|
||||||
if unsafe { ftruncate(self.fd, size as i64) } == -1 {
|
|
||||||
return Err(std::io::Error::last_os_error())
|
|
||||||
};
|
|
||||||
self.size = size;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for ShmPool {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { munmap(self.addr, self.size); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ShmPool {
|
||||||
|
pub fd: i32,
|
||||||
|
pub id: u32,
|
||||||
|
pub addr: *mut c_void,
|
||||||
|
pub size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShmPool {
|
||||||
|
pub fn new(size: usize, id: u32) -> std::io::Result<ShmPool> {
|
||||||
|
let shm_path: *const i8 = b"/chlorostart\0".as_ptr() as *const i8;
|
||||||
|
let fd = unsafe { shm_open(shm_path, O_RDWR | O_EXCL | O_CREAT, 0o600) };
|
||||||
|
if fd == -1 {
|
||||||
|
eprint!("shm_open in ShmPool::new() failed: ");
|
||||||
|
return Err(std::io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
if unsafe { shm_unlink(shm_path) } == -1 {
|
||||||
|
eprint!("shm_unlink in ShmPool::new() failed: ");
|
||||||
|
return Err(std::io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
if unsafe { ftruncate(fd, size as i64) } == -1 {
|
||||||
|
eprint!("ftruncate in ShmPool::new() failed: ");
|
||||||
|
return Err(std::io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
let addr = unsafe {
|
||||||
|
mmap(std::ptr::null_mut(), size, PROT_READ | PROT_READ, MAP_SHARED, fd, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
if addr == MAP_FAILED {
|
||||||
|
eprint!("mmap in ShmPool::new() failed: ");
|
||||||
|
return Err(std::io::Error::last_os_error())
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ShmPool {
|
||||||
|
fd,
|
||||||
|
id,
|
||||||
|
addr,
|
||||||
|
size
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, size: usize) -> std::io::Result<()> {
|
||||||
|
if unsafe { ftruncate(self.fd, size as i64) } == -1 {
|
||||||
|
return Err(std::io::Error::last_os_error())
|
||||||
|
};
|
||||||
|
self.size = size;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for ShmPool {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe { munmap(self.addr, self.size); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
74
src/vec_utils.rs
Normal file
74
src/vec_utils.rs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
|
||||||
|
pub trait WlMessage {
|
||||||
|
/// Write a u32 to self at offset and increment offset by four
|
||||||
|
fn write_u32(&mut self, value: &u32, offset: &mut usize);
|
||||||
|
/// Write a u16 to self at offset and increment offset by four
|
||||||
|
fn write_u16(&mut self, value: &u16, offset: &mut usize);
|
||||||
|
/// Write a string to self at offset
|
||||||
|
/// and increment offset by string length rounded up to four bytes
|
||||||
|
fn write_string(&mut self, str: &String, offset: &mut usize);
|
||||||
|
/// Read a u32 from self at offset and increment offset by four
|
||||||
|
fn read_u32(&self, offset: &mut usize) -> u32;
|
||||||
|
/// Read a u16 from self at offset and increment offset by two
|
||||||
|
fn read_u16(&self, offset: &mut usize) -> u16;
|
||||||
|
/// Read a string from self at offset
|
||||||
|
/// and increment offset by string length rounded up to four bytes
|
||||||
|
fn read_string(&self, offset: &mut usize) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WlMessage for Vec<u8> {
|
||||||
|
fn write_u32(&mut self, value: &u32, offset: &mut usize) {
|
||||||
|
self[*offset..*offset+4].copy_from_slice(&value.to_ne_bytes());
|
||||||
|
*offset += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_u16(&mut self, value: &u16, offset: &mut usize) {
|
||||||
|
self[*offset..*offset+2].copy_from_slice(&value.to_ne_bytes());
|
||||||
|
*offset += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_string(&mut self, str: &String, offset: &mut usize) {
|
||||||
|
let mut str = str.clone();
|
||||||
|
str.push('\0');
|
||||||
|
let rounded_len: u32 = (str.len()+3) as u32 & (u32::MAX-3);
|
||||||
|
self.write_u32(&rounded_len, offset);
|
||||||
|
self[*offset..*offset+str.len()].copy_from_slice(str.as_bytes());
|
||||||
|
*offset += rounded_len as usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(&self, offset: &mut usize) -> u32 {
|
||||||
|
let res = u32::from_ne_bytes(
|
||||||
|
self[*offset..*offset+4]
|
||||||
|
.try_into()
|
||||||
|
.expect("u32::from_ne_bytes failed in WlEvent::read_u32")
|
||||||
|
);
|
||||||
|
*offset += 4;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u16(&self, offset: &mut usize) -> u16 {
|
||||||
|
let res = u16::from_ne_bytes(
|
||||||
|
self[*offset..*offset+2]
|
||||||
|
.try_into()
|
||||||
|
.expect("u32::from_ne_bytes failed in WlEvent::read_u32")
|
||||||
|
);
|
||||||
|
*offset += 2;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_string(&self, offset: &mut usize) -> String {
|
||||||
|
let str_len = u32::from_ne_bytes(
|
||||||
|
self[*offset..*offset+4]
|
||||||
|
.try_into()
|
||||||
|
.expect("u32::from_ne_bytes failed in WlEvent::read_string")
|
||||||
|
);
|
||||||
|
*offset += 4;
|
||||||
|
let str = String::from_utf8(
|
||||||
|
self[*offset..*offset+((str_len-1) as usize)]
|
||||||
|
.to_vec())
|
||||||
|
.expect("String::from_utf8 failed in WlEvent::read_string()"
|
||||||
|
);
|
||||||
|
*offset += (str_len+3 & u32::MAX-3) as usize;
|
||||||
|
str
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user