diff --git a/src/wayland/buffer.rs b/src/wayland/buffer.rs index 5425a5f..9e5f381 100644 --- a/src/wayland/buffer.rs +++ b/src/wayland/buffer.rs @@ -8,14 +8,23 @@ use cctk::{ }, }; use cosmic::iced::widget::image; -use std::os::fd::{AsFd, OwnedFd}; +use std::{ + os::fd::{AsFd, OwnedFd}, + path::{Path, PathBuf}, +}; use wayland_protocols::wp::linux_dmabuf::zv1::client::zwp_linux_buffer_params_v1; use super::AppData; enum BufferBacking { - Shm { pool: RawPool }, - Dmabuf { fd: OwnedFd, stride: u32 }, + Shm { + pool: RawPool, + }, + Dmabuf { + fd: OwnedFd, + node: PathBuf, + stride: u32, + }, } pub struct Buffer { @@ -53,7 +62,7 @@ impl AppData { needs_linear: bool, ) -> Option<(BufferBacking, wl_buffer::WlBuffer)> { // TODO Handle errors in some way - let gbm = self.gbm.as_ref()?; + let (node, gbm) = self.gbm.as_ref()?; let feedback = self.dmabuf_feedback.as_ref()?; let formats = feedback.format_table(); let format_info = feedback @@ -90,7 +99,14 @@ impl AppData { ) .0; - Some((BufferBacking::Dmabuf { fd, stride }, buffer)) + Some(( + BufferBacking::Dmabuf { + fd, + node: node.clone(), + stride, + }, + buffer, + )) } pub fn create_buffer(&self, buffer_infos: &[BufferInfo]) -> Buffer { @@ -135,7 +151,11 @@ impl Buffer { let pixels = match &mut self.backing { BufferBacking::Shm { pool } => pool.mmap().to_vec(), // NOTE: Only will work with linear modifier - BufferBacking::Dmabuf { fd, stride } => { + BufferBacking::Dmabuf { + fd, + node: _, + stride, + } => { // XXX Error handling? let mmap = memmap2::Mmap::map(&*fd).unwrap(); if self.buffer_info.stride == self.buffer_info.width * 4 { @@ -156,6 +176,13 @@ impl Buffer { }; image::Handle::from_pixels(self.buffer_info.width, self.buffer_info.height, pixels) } + + pub fn node(&self) -> Option<&Path> { + match &self.backing { + BufferBacking::Shm { .. } => None, + BufferBacking::Dmabuf { node, .. } => Some(node), + } + } } impl Drop for Buffer { diff --git a/src/wayland/dmabuf.rs b/src/wayland/dmabuf.rs index 05f5bae..feb0a73 100644 --- a/src/wayland/dmabuf.rs +++ b/src/wayland/dmabuf.rs @@ -6,7 +6,7 @@ use cctk::{ wayland_client::{protocol::wl_buffer, Connection, QueueHandle}, }; -use std::{fs, io, os::unix::fs::MetadataExt}; +use std::{fs, io, os::unix::fs::MetadataExt, path::PathBuf}; use wayland_protocols::wp::linux_dmabuf::zv1::client::{ zwp_linux_buffer_params_v1::ZwpLinuxBufferParamsV1, @@ -65,13 +65,13 @@ impl DmabufHandler for AppData { } } -fn find_gbm_device(dev: u64) -> io::Result>> { +fn find_gbm_device(dev: u64) -> io::Result)>> { for i in std::fs::read_dir("/dev/dri")? { let i = i?; if i.metadata()?.rdev() == dev { let file = fs::File::options().read(true).write(true).open(i.path())?; eprintln!("Opened gbm main device '{}'", i.path().display()); - return Ok(Some(gbm::Device::new(file)?)); + return Ok(Some((i.path(), gbm::Device::new(file)?))); } } Ok(None) diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 45647c3..fb19859 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -40,6 +40,7 @@ use std::{ cell::RefCell, collections::{HashMap, HashSet}, fs, + path::PathBuf, sync::Arc, thread, }; @@ -108,7 +109,7 @@ pub struct AppData { capture_filter: CaptureFilter, captures: RefCell>>, dmabuf_feedback: Option, - gbm: Option>, + gbm: Option<(PathBuf, gbm::Device)>, } impl AppData { diff --git a/src/wayland/screencopy.rs b/src/wayland/screencopy.rs index acfd411..37e65d8 100644 --- a/src/wayland/screencopy.rs +++ b/src/wayland/screencopy.rs @@ -34,7 +34,10 @@ impl ScreencopyHandler for AppData { } let buffer = buffer.as_ref().unwrap(); - session.attach_buffer(&buffer.buffer, None, 0); // XXX age? + let node = buffer + .node() + .and_then(|x| x.to_str().map(|x| x.to_string())); + session.attach_buffer(&buffer.buffer, node, 0); // XXX age? if capture.first_frame() { session.commit(zcosmic_screencopy_session_v1::Options::empty()); } else {