wayland: Working screencopy implementation

This commit is contained in:
Victoria Brekenfeld 2022-11-03 21:19:41 +01:00
parent 5a4df346a8
commit 9f1284b981
3 changed files with 43 additions and 17 deletions

View file

@ -9,10 +9,11 @@ use crate::{
wayland::protocols::{ wayland::protocols::{
drm::WlDrmState, drm::WlDrmState,
output_configuration::OutputConfigurationState, output_configuration::OutputConfigurationState,
screencopy::{BufferParams, Session as ScreencopySession}, screencopy::{BufferParams, ScreencopyState, Session as ScreencopySession},
workspace::WorkspaceClientState, workspace::WorkspaceClientState,
}, },
}; };
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::CursorMode;
use smithay::{ use smithay::{
backend::{ backend::{
drm::DrmNode, drm::DrmNode,
@ -94,6 +95,7 @@ pub struct Common {
pub output_state: OutputManagerState, pub output_state: OutputManagerState,
pub output_configuration_state: OutputConfigurationState<State>, pub output_configuration_state: OutputConfigurationState<State>,
pub primary_selection_state: PrimarySelectionState, pub primary_selection_state: PrimarySelectionState,
pub screencopy_state: ScreencopyState,
pub seat_state: SeatState<State>, pub seat_state: SeatState<State>,
pub shm_state: ShmState, pub shm_state: ShmState,
pub wl_drm_state: WlDrmState, pub wl_drm_state: WlDrmState,
@ -228,6 +230,11 @@ impl State {
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh); let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
let output_configuration_state = OutputConfigurationState::new(dh, |_| true); let output_configuration_state = OutputConfigurationState::new(dh, |_| true);
let primary_selection_state = PrimarySelectionState::new::<Self, _>(dh, None); let primary_selection_state = PrimarySelectionState::new::<Self, _>(dh, None);
let screencopy_state = ScreencopyState::new::<Self, _, _>(
dh,
vec![CursorMode::Embedded, CursorMode::Hidden],
|_| true,
); // TODO: privileged
let shm_state = ShmState::new::<Self, _>(dh, vec![], None); let shm_state = ShmState::new::<Self, _>(dh, vec![], None);
let seat_state = SeatState::<Self>::new(); let seat_state = SeatState::<Self>::new();
let viewporter_state = ViewporterState::new::<Self, _>(dh, None); let viewporter_state = ViewporterState::new::<Self, _>(dh, None);
@ -275,6 +282,7 @@ impl State {
compositor_state, compositor_state,
data_device_state, data_device_state,
dmabuf_state, dmabuf_state,
screencopy_state,
shm_state, shm_state,
seat_state, seat_state,
keyboard_shortcuts_inhibit_state, keyboard_shortcuts_inhibit_state,

View file

@ -41,8 +41,8 @@ use crate::{
utils::prelude::OutputExt, utils::prelude::OutputExt,
wayland::protocols::{ wayland::protocols::{
screencopy::{ screencopy::{
BufferInfo, BufferParams, CursorMode as ScreencopyCursorMode, CursorSession, delegate_screencopy, BufferInfo, BufferParams, CursorMode as ScreencopyCursorMode,
ScreencopyHandler, Session, SessionType, CursorSession, ScreencopyHandler, Session, SessionType,
}, },
workspace::WorkspaceHandle, workspace::WorkspaceHandle,
}, },
@ -177,14 +177,14 @@ impl ScreencopyHandler for State {
let mut formats = vec![ let mut formats = vec![
BufferInfo::Shm { BufferInfo::Shm {
format: ShmFormat::Abgr8888, format: ShmFormat::Argb8888,
size, size,
stride: 0, stride: size.w as u32 * 4,
}, },
BufferInfo::Shm { BufferInfo::Shm {
format: ShmFormat::Xbgr8888, format: ShmFormat::Xrgb8888,
size, size,
stride: 0, stride: size.w as u32 * 4,
}, },
]; ];
@ -276,7 +276,7 @@ impl ScreencopyHandler for State {
if let Some(BufferType::Shm) = buffer_type(&params.buffer) { if let Some(BufferType::Shm) = buffer_type(&params.buffer) {
if with_buffer_contents(&params.buffer, |_, info| { if with_buffer_contents(&params.buffer, |_, info| {
info.format != ShmFormat::Abgr8888 && info.format != ShmFormat::Xbgr8888 info.format != ShmFormat::Argb8888 && info.format != ShmFormat::Xrgb8888
}) })
.unwrap() .unwrap()
{ {
@ -415,14 +415,14 @@ fn formats_for_output(
let mut formats = vec![ let mut formats = vec![
BufferInfo::Shm { BufferInfo::Shm {
format: ShmFormat::Abgr8888, format: ShmFormat::Argb8888,
size: mode, size: mode,
stride: 0, stride: mode.w as u32 * 4,
}, },
BufferInfo::Shm { BufferInfo::Shm {
format: ShmFormat::Xbgr8888, format: ShmFormat::Xrgb8888,
size: mode, size: mode,
stride: 0, stride: mode.w as u32 * 4,
}, },
]; ];
@ -793,3 +793,5 @@ impl UserdataExt for Window {
.flatten() .flatten()
} }
} }
delegate_screencopy!(State);

View file

@ -57,7 +57,7 @@ impl ScreencopyState {
where where
D: GlobalDispatch<ZcosmicScreencopyManagerV1, ScreencopyGlobalData> D: GlobalDispatch<ZcosmicScreencopyManagerV1, ScreencopyGlobalData>
+ Dispatch<ZcosmicScreencopyManagerV1, ()> + Dispatch<ZcosmicScreencopyManagerV1, ()>
+ Dispatch<ZcosmicScreencopySessionV1, ()> + Dispatch<ZcosmicScreencopySessionV1, SessionData>
+ ScreencopyHandler + ScreencopyHandler
+ WorkspaceHandler + WorkspaceHandler
+ 'static, + 'static,
@ -799,15 +799,16 @@ where
data.inner.lock().unwrap().pending_buffer = Some(params); data.inner.lock().unwrap().pending_buffer = Some(params);
} }
zcosmic_screencopy_session_v1::Request::Commit { options } => { zcosmic_screencopy_session_v1::Request::Commit { options } => {
{ let buffer = {
let resource_data = data.inner.lock().unwrap(); let mut resource_data = data.inner.lock().unwrap();
if resource_data.is_cursor() || resource_data.gone { if resource_data.is_cursor() || resource_data.gone {
resource.failed(FailureReason::Unspec); resource.failed(FailureReason::Unspec);
return; return;
} }
} resource_data.pending_buffer.take()
};
if let Some(buffer) = data.inner.lock().unwrap().pending_buffer.take() { if let Some(buffer) = buffer {
let session = Session { let session = Session {
obj: SessionResource::Alive(resource.clone()), obj: SessionResource::Alive(resource.clone()),
data: data.clone(), data: data.clone(),
@ -889,3 +890,18 @@ fn send_formats(session: &SessionResource, formats: Vec<BufferInfo>) {
session.init_done(); session.init_done();
} }
macro_rules! delegate_screencopy {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::ZcosmicScreencopyManagerV1: $crate::wayland::protocols::screencopy::ScreencopyGlobalData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::ZcosmicScreencopyManagerV1: ()
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::ZcosmicScreencopySessionV1: $crate::wayland::protocols::screencopy::SessionData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
};
}
pub(crate) use delegate_screencopy;