From 9f1284b981ff388242b8f5c77bcea9b3bbffe979 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 3 Nov 2022 21:19:41 +0100 Subject: [PATCH] wayland: Working screencopy implementation --- src/state.rs | 10 +++++++++- src/wayland/handlers/screencopy.rs | 24 +++++++++++++----------- src/wayland/protocols/screencopy.rs | 26 +++++++++++++++++++++----- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/state.rs b/src/state.rs index 4734a1f3..e04c8cc4 100644 --- a/src/state.rs +++ b/src/state.rs @@ -9,10 +9,11 @@ use crate::{ wayland::protocols::{ drm::WlDrmState, output_configuration::OutputConfigurationState, - screencopy::{BufferParams, Session as ScreencopySession}, + screencopy::{BufferParams, ScreencopyState, Session as ScreencopySession}, workspace::WorkspaceClientState, }, }; +use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_manager_v1::CursorMode; use smithay::{ backend::{ drm::DrmNode, @@ -94,6 +95,7 @@ pub struct Common { pub output_state: OutputManagerState, pub output_configuration_state: OutputConfigurationState, pub primary_selection_state: PrimarySelectionState, + pub screencopy_state: ScreencopyState, pub seat_state: SeatState, pub shm_state: ShmState, pub wl_drm_state: WlDrmState, @@ -228,6 +230,11 @@ impl State { let output_state = OutputManagerState::new_with_xdg_output::(dh); let output_configuration_state = OutputConfigurationState::new(dh, |_| true); let primary_selection_state = PrimarySelectionState::new::(dh, None); + let screencopy_state = ScreencopyState::new::( + dh, + vec![CursorMode::Embedded, CursorMode::Hidden], + |_| true, + ); // TODO: privileged let shm_state = ShmState::new::(dh, vec![], None); let seat_state = SeatState::::new(); let viewporter_state = ViewporterState::new::(dh, None); @@ -275,6 +282,7 @@ impl State { compositor_state, data_device_state, dmabuf_state, + screencopy_state, shm_state, seat_state, keyboard_shortcuts_inhibit_state, diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index 80cc9627..6706e009 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -41,8 +41,8 @@ use crate::{ utils::prelude::OutputExt, wayland::protocols::{ screencopy::{ - BufferInfo, BufferParams, CursorMode as ScreencopyCursorMode, CursorSession, - ScreencopyHandler, Session, SessionType, + delegate_screencopy, BufferInfo, BufferParams, CursorMode as ScreencopyCursorMode, + CursorSession, ScreencopyHandler, Session, SessionType, }, workspace::WorkspaceHandle, }, @@ -177,14 +177,14 @@ impl ScreencopyHandler for State { let mut formats = vec![ BufferInfo::Shm { - format: ShmFormat::Abgr8888, + format: ShmFormat::Argb8888, size, - stride: 0, + stride: size.w as u32 * 4, }, BufferInfo::Shm { - format: ShmFormat::Xbgr8888, + format: ShmFormat::Xrgb8888, size, - stride: 0, + stride: size.w as u32 * 4, }, ]; @@ -276,7 +276,7 @@ impl ScreencopyHandler for State { if let Some(BufferType::Shm) = buffer_type(¶ms.buffer) { if with_buffer_contents(¶ms.buffer, |_, info| { - info.format != ShmFormat::Abgr8888 && info.format != ShmFormat::Xbgr8888 + info.format != ShmFormat::Argb8888 && info.format != ShmFormat::Xrgb8888 }) .unwrap() { @@ -415,14 +415,14 @@ fn formats_for_output( let mut formats = vec![ BufferInfo::Shm { - format: ShmFormat::Abgr8888, + format: ShmFormat::Argb8888, size: mode, - stride: 0, + stride: mode.w as u32 * 4, }, BufferInfo::Shm { - format: ShmFormat::Xbgr8888, + format: ShmFormat::Xrgb8888, size: mode, - stride: 0, + stride: mode.w as u32 * 4, }, ]; @@ -793,3 +793,5 @@ impl UserdataExt for Window { .flatten() } } + +delegate_screencopy!(State); diff --git a/src/wayland/protocols/screencopy.rs b/src/wayland/protocols/screencopy.rs index 677ee2ea..376936ad 100644 --- a/src/wayland/protocols/screencopy.rs +++ b/src/wayland/protocols/screencopy.rs @@ -57,7 +57,7 @@ impl ScreencopyState { where D: GlobalDispatch + Dispatch - + Dispatch + + Dispatch + ScreencopyHandler + WorkspaceHandler + 'static, @@ -799,15 +799,16 @@ where data.inner.lock().unwrap().pending_buffer = Some(params); } zcosmic_screencopy_session_v1::Request::Commit { options } => { - { - let resource_data = data.inner.lock().unwrap(); + let buffer = { + let mut resource_data = data.inner.lock().unwrap(); if resource_data.is_cursor() || resource_data.gone { resource.failed(FailureReason::Unspec); 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 { obj: SessionResource::Alive(resource.clone()), data: data.clone(), @@ -889,3 +890,18 @@ fn send_formats(session: &SessionResource, formats: Vec) { 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;