use std::fs::File;
use std::io;
use std::os::unix::io::AsRawFd;
use tempfile::tempfile;
use wayland_client::protocol::{wl_buffer, wl_shm, wl_shm_pool};
use wayland_client::{NewProxy, Proxy};
use wayland_client::protocol::wl_shm::RequestsTrait as ShmRequests;
use wayland_client::protocol::wl_shm_pool::RequestsTrait as PoolRequests;
pub struct DoubleMemPool {
pool1: MemPool,
pool2: MemPool,
}
impl DoubleMemPool {
pub fn new(shm: &Proxy<wl_shm::WlShm>) -> io::Result<DoubleMemPool> {
let pool1 = MemPool::new(shm)?;
let pool2 = MemPool::new(shm)?;
Ok(DoubleMemPool { pool1, pool2 })
}
pub fn pool(&mut self) -> &mut MemPool {
&mut self.pool1
}
pub fn swap(&mut self) {
::std::mem::swap(&mut self.pool1, &mut self.pool2);
}
}
pub struct MemPool {
file: File,
len: usize,
pool: Proxy<wl_shm_pool::WlShmPool>,
}
impl MemPool {
pub fn new(shm: &Proxy<wl_shm::WlShm>) -> io::Result<MemPool> {
let tempfile = tempfile()?;
tempfile.set_len(128)?;
let pool = shm.create_pool(tempfile.as_raw_fd(), 128)
.unwrap()
.implement(|e, _| match e {});
Ok(MemPool {
file: tempfile,
len: 128,
pool: pool,
})
}
pub fn resize(&mut self, newsize: usize) -> io::Result<()> {
if newsize > self.len {
self.file.set_len(newsize as u64)?;
self.pool.resize(newsize as i32);
self.len = newsize;
}
Ok(())
}
pub fn buffer(
&self,
offset: i32,
width: i32,
height: i32,
stride: i32,
format: wl_shm::Format,
) -> NewProxy<wl_buffer::WlBuffer> {
self.pool
.create_buffer(offset, width, height, stride, format)
.unwrap()
}
}
impl Drop for MemPool {
fn drop(&mut self) {
self.pool.destroy();
}
}
impl io::Write for MemPool {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
io::Write::write(&mut self.file, buf)
}
fn flush(&mut self) -> io::Result<()> {
io::Write::flush(&mut self.file)
}
}
impl io::Seek for MemPool {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
io::Seek::seek(&mut self.file, pos)
}
}