diff --git a/CHANGELOG.md b/CHANGELOG.md index b6b413c..cd36394 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Setting the parent of a toplevel surface is now possible with the `xdg::ToplevelSurface::set_parent` function. - Add support for the zxdg-foreign-v2 protocol. - Support for `xdg_wm_base` protocol version 3 +- Added the option to initialize the dmabuf global with a client filter ### Bugfixes diff --git a/src/wayland/dmabuf/mod.rs b/src/wayland/dmabuf/mod.rs index b9e6499..d4e4d23 100644 --- a/src/wayland/dmabuf/mod.rs +++ b/src/wayland/dmabuf/mod.rs @@ -54,7 +54,7 @@ use wayland_protocols::unstable::linux_dmabuf::v1::server::{ }, zwp_linux_dmabuf_v1, }; -use wayland_server::{protocol::wl_buffer, DispatchData, Display, Filter, Global, Main}; +use wayland_server::{protocol::wl_buffer, Client, DispatchData, Display, Filter, Global, Main}; use slog::{o, trace}; @@ -63,9 +63,7 @@ use crate::backend::allocator::{ Format, Fourcc, Modifier, }; -/// Handler trait for dmabuf validation -/// -/// You need to provide an implementation of this trait +const DMABUF_VERSION: u32 = 3; /// Initialize a dmabuf global. /// @@ -77,6 +75,37 @@ pub fn init_dmabuf_global( handler: F, logger: L, ) -> Global +where + L: Into>, + F: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static, +{ + display.create_global(DMABUF_VERSION, dmabuf_global(formats, handler, logger)) +} + +/// Initialize a dmabuf global with a client filter. +/// +/// You need to provide a vector of the supported formats, as well as a closure, +/// that will validate the parameters provided by the client and tests the import as a dmabuf. +pub fn init_dmabuf_global_with_filter( + display: &mut Display, + formats: Vec, + handler: H, + filter: F, + logger: L, +) -> Global +where + L: Into>, + H: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static, + F: FnMut(Client) -> bool + 'static, +{ + display.create_global_with_filter(DMABUF_VERSION, dmabuf_global(formats, handler, logger), filter) +} + +fn dmabuf_global( + formats: Vec, + handler: F, + logger: L, +) -> Filter<(Main, u32)> where L: Into>, F: for<'a> FnMut(&Dmabuf, DispatchData<'a>) -> bool + 'static, @@ -92,72 +121,67 @@ where formats.len() ); - display.create_global( - 3, - Filter::new( - move |(dmabuf, version): (Main, u32), _, _| { - let dma_formats = formats.clone(); - let dma_handler = handler.clone(); - let dma_log = log.clone(); - dmabuf.quick_assign(move |_, req, _| { - if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req { - let mut handler = ParamsHandler { - pending_planes: Vec::new(), - max_planes: 4, - used: false, - formats: dma_formats.clone(), - handler: dma_handler.clone(), - log: dma_log.clone(), - }; - params_id.quick_assign(move |params, req, ddata| match req { - ParamsRequest::Add { - fd, - plane_idx, - offset, - stride, - modifier_hi, - modifier_lo, - } => handler.add( - &*params, - fd, - plane_idx, - offset, - stride, - ((modifier_hi as u64) << 32) + (modifier_lo as u64), - ), - ParamsRequest::Create { - width, - height, - format, - flags, - } => handler.create(&*params, width, height, format, flags, ddata), - ParamsRequest::CreateImmed { - buffer_id, - width, - height, - format, - flags, - } => { - handler.create_immed(&*params, buffer_id, width, height, format, flags, ddata) - } - _ => {} - }); - } - }); - - // send the supported formats - for f in &*formats { - dmabuf.format(f.code as u32); - if version >= 3 { - dmabuf.modifier( - f.code as u32, - (Into::::into(f.modifier) >> 32) as u32, - Into::::into(f.modifier) as u32, - ); - } + Filter::new( + move |(dmabuf, version): (Main, u32), _, _| { + let dma_formats = formats.clone(); + let dma_handler = handler.clone(); + let dma_log = log.clone(); + dmabuf.quick_assign(move |_, req, _| { + if let zwp_linux_dmabuf_v1::Request::CreateParams { params_id } = req { + let mut handler = ParamsHandler { + pending_planes: Vec::new(), + max_planes: 4, + used: false, + formats: dma_formats.clone(), + handler: dma_handler.clone(), + log: dma_log.clone(), + }; + params_id.quick_assign(move |params, req, ddata| match req { + ParamsRequest::Add { + fd, + plane_idx, + offset, + stride, + modifier_hi, + modifier_lo, + } => handler.add( + &*params, + fd, + plane_idx, + offset, + stride, + ((modifier_hi as u64) << 32) + (modifier_lo as u64), + ), + ParamsRequest::Create { + width, + height, + format, + flags, + } => handler.create(&*params, width, height, format, flags, ddata), + ParamsRequest::CreateImmed { + buffer_id, + width, + height, + format, + flags, + } => handler.create_immed(&*params, buffer_id, width, height, format, flags, ddata), + _ => {} + }); } - }, - ), + }); + + // send the supported formats + for f in &*formats { + dmabuf.format(f.code as u32); + if version >= 3 { + dmabuf.modifier( + f.code as u32, + (Into::::into(f.modifier) >> 32) as u32, + Into::::into(f.modifier) as u32, + ); + } + } + }, ) }