2023-02-09 14:10:31 -08:00
|
|
|
use cctk::{
|
2023-11-08 15:05:45 -08:00
|
|
|
cosmic_protocols::screencopy::v1::client::zcosmic_screencopy_session_v1::BufferType,
|
2023-02-09 14:10:31 -08:00
|
|
|
screencopy::BufferInfo,
|
2023-11-08 15:05:45 -08:00
|
|
|
sctk::shm::raw::RawPool,
|
2023-02-09 14:10:31 -08:00
|
|
|
wayland_client::{
|
|
|
|
|
protocol::{wl_buffer, wl_shm},
|
2023-11-08 15:05:45 -08:00
|
|
|
Connection, Dispatch, QueueHandle, WEnum,
|
2023-02-09 14:10:31 -08:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
use cosmic::iced::widget::image;
|
|
|
|
|
|
2023-02-09 16:04:36 -08:00
|
|
|
use super::AppData;
|
|
|
|
|
|
2023-02-09 14:10:31 -08:00
|
|
|
pub struct Buffer {
|
|
|
|
|
pub pool: RawPool,
|
|
|
|
|
pub buffer: wl_buffer::WlBuffer,
|
|
|
|
|
pub buffer_info: BufferInfo,
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-08 15:05:45 -08:00
|
|
|
impl AppData {
|
|
|
|
|
pub fn create_buffer(&self, buffer_infos: &[BufferInfo]) -> Buffer {
|
|
|
|
|
// XXX Handle other formats?
|
|
|
|
|
let format = wl_shm::Format::Abgr8888.into();
|
|
|
|
|
|
|
|
|
|
let buffer_info = buffer_infos
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|x| x.type_ == WEnum::Value(BufferType::WlShm) && x.format == format)
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
2023-02-09 14:10:31 -08:00
|
|
|
// Assume format is already known to be valid
|
2023-11-08 15:05:45 -08:00
|
|
|
let mut pool = RawPool::new(
|
|
|
|
|
(buffer_info.stride * buffer_info.height) as usize,
|
|
|
|
|
&self.shm_state,
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2023-02-09 14:10:31 -08:00
|
|
|
let format = wl_shm::Format::try_from(buffer_info.format).unwrap();
|
|
|
|
|
let buffer = pool.create_buffer(
|
|
|
|
|
0,
|
|
|
|
|
buffer_info.width as i32,
|
|
|
|
|
buffer_info.height as i32,
|
|
|
|
|
buffer_info.stride as i32,
|
|
|
|
|
format,
|
|
|
|
|
(),
|
2023-11-08 15:05:45 -08:00
|
|
|
&self.qh,
|
2023-02-09 14:10:31 -08:00
|
|
|
);
|
2023-11-08 15:05:45 -08:00
|
|
|
Buffer {
|
2023-02-09 14:10:31 -08:00
|
|
|
pool,
|
|
|
|
|
buffer,
|
2023-11-08 15:05:45 -08:00
|
|
|
buffer_info: buffer_info.clone(),
|
2023-02-09 14:10:31 -08:00
|
|
|
}
|
|
|
|
|
}
|
2023-11-08 15:05:45 -08:00
|
|
|
}
|
2023-02-09 14:10:31 -08:00
|
|
|
|
2023-11-08 15:05:45 -08:00
|
|
|
impl Buffer {
|
2023-02-09 14:10:31 -08:00
|
|
|
// Buffer must be released by server for safety
|
2023-02-09 14:29:34 -08:00
|
|
|
#[allow(clippy::wrong_self_convention)]
|
2023-02-09 14:10:31 -08:00
|
|
|
pub unsafe fn to_image(&mut self) -> image::Handle {
|
|
|
|
|
// XXX is this at all a performance issue?
|
|
|
|
|
image::Handle::from_pixels(
|
|
|
|
|
self.buffer_info.width,
|
|
|
|
|
self.buffer_info.height,
|
|
|
|
|
self.pool.mmap().to_vec(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for Buffer {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
self.buffer.destroy();
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-09 16:04:36 -08:00
|
|
|
|
|
|
|
|
impl Dispatch<wl_buffer::WlBuffer, ()> for AppData {
|
|
|
|
|
fn event(
|
|
|
|
|
_app_data: &mut Self,
|
|
|
|
|
_buffer: &wl_buffer::WlBuffer,
|
|
|
|
|
event: wl_buffer::Event,
|
|
|
|
|
_: &(),
|
|
|
|
|
_: &Connection,
|
|
|
|
|
_qh: &QueueHandle<Self>,
|
|
|
|
|
) {
|
|
|
|
|
match event {
|
|
|
|
|
wl_buffer::Event::Release => {}
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|