Replace screencopy with ext-image-copy-capture-v1

This commit is contained in:
Ian Douglas Scott 2025-03-03 16:19:41 -08:00 committed by Victoria Brekenfeld
parent fec4b3c235
commit 2fe5897db0
10 changed files with 545 additions and 575 deletions

View file

@ -0,0 +1,372 @@
use super::{
toplevel_info::window_from_ext_handle,
workspace::{WorkspaceHandle, WorkspaceHandler},
};
use crate::{
shell::CosmicSurface,
wayland::protocols::toplevel_info::ToplevelInfoHandler,
};
use cosmic_protocols::image_capture_source::v1::server::{
zcosmic_workspace_image_capture_source_manager_v1::{
Request as CosmicWorkspaceSourceRequest, ZcosmicWorkspaceImageCaptureSourceManagerV1,
},
};
use smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::{
ext_foreign_toplevel_image_capture_source_manager_v1::{
Request as ToplevelSourceRequest, ExtForeignToplevelImageCaptureSourceManagerV1,
},
ext_image_capture_source_v1::ExtImageCaptureSourceV1,
ext_output_image_capture_source_manager_v1::{
Request as OutputSourceRequest, ExtOutputImageCaptureSourceManagerV1,
},
};
use smithay::{
output::{Output, WeakOutput},
reexports::wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
},
};
use wayland_backend::server::GlobalId;
#[derive(Debug)]
pub struct ImageCaptureSourceState {
output_source_global: GlobalId,
workspace_source_global: GlobalId,
toplevel_source_global: GlobalId,
}
pub struct OutputImageCaptureSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
pub struct WorkspaceImageCaptureSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
pub struct ToplevelImageCaptureSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ImageCaptureSourceData {
Output(WeakOutput),
Workspace(WorkspaceHandle),
Toplevel(CosmicSurface),
Destroyed,
}
impl ImageCaptureSourceState {
pub fn new<D, F>(display: &DisplayHandle, client_filter: F) -> ImageCaptureSourceState
where
D: GlobalDispatch<
ExtOutputImageCaptureSourceManagerV1,
OutputImageCaptureSourceManagerGlobalData,
> + Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicWorkspaceImageCaptureSourceManagerV1,
WorkspaceImageCaptureSourceManagerGlobalData,
> + Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, ()>
+ GlobalDispatch<
ExtForeignToplevelImageCaptureSourceManagerV1,
ToplevelImageCaptureSourceManagerGlobalData,
> + Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ WorkspaceHandler
+ 'static,
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static,
{
ImageCaptureSourceState {
output_source_global: display
.create_global::<D, ExtOutputImageCaptureSourceManagerV1, _>(
1,
OutputImageCaptureSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
workspace_source_global: display
.create_global::<D, ZcosmicWorkspaceImageCaptureSourceManagerV1, _>(
1,
WorkspaceImageCaptureSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
toplevel_source_global: display
.create_global::<D, ExtForeignToplevelImageCaptureSourceManagerV1, _>(
1,
ToplevelImageCaptureSourceManagerGlobalData {
filter: Box::new(client_filter),
},
),
}
}
pub fn output_source_id(&self) -> &GlobalId {
&self.output_source_global
}
pub fn workspace_source_id(&self) -> &GlobalId {
&self.workspace_source_global
}
pub fn toplevel_source_id(&self) -> &GlobalId {
&self.toplevel_source_global
}
}
impl<D>
GlobalDispatch<
ExtOutputImageCaptureSourceManagerV1,
OutputImageCaptureSourceManagerGlobalData,
D,
> for ImageCaptureSourceState
where
D: GlobalDispatch<
ExtOutputImageCaptureSourceManagerV1,
OutputImageCaptureSourceManagerGlobalData,
> + Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ExtOutputImageCaptureSourceManagerV1>,
_global_data: &OutputImageCaptureSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &OutputImageCaptureSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D>
GlobalDispatch<
ZcosmicWorkspaceImageCaptureSourceManagerV1,
WorkspaceImageCaptureSourceManagerGlobalData,
D,
> for ImageCaptureSourceState
where
D: GlobalDispatch<
ZcosmicWorkspaceImageCaptureSourceManagerV1,
WorkspaceImageCaptureSourceManagerGlobalData,
> + Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicWorkspaceImageCaptureSourceManagerV1>,
_global_data: &WorkspaceImageCaptureSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(
client: Client,
global_data: &WorkspaceImageCaptureSourceManagerGlobalData,
) -> bool {
(global_data.filter)(&client)
}
}
impl<D>
GlobalDispatch<
ExtForeignToplevelImageCaptureSourceManagerV1,
ToplevelImageCaptureSourceManagerGlobalData,
D,
> for ImageCaptureSourceState
where
D: GlobalDispatch<
ExtForeignToplevelImageCaptureSourceManagerV1,
ToplevelImageCaptureSourceManagerGlobalData,
> + Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ExtForeignToplevelImageCaptureSourceManagerV1>,
_global_data: &ToplevelImageCaptureSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &ToplevelImageCaptureSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D> Dispatch<ExtOutputImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
where
D: Dispatch<ExtOutputImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
_resource: &ExtOutputImageCaptureSourceManagerV1,
request: <ExtOutputImageCaptureSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
OutputSourceRequest::CreateSource { source, output } => {
let data = match Output::from_resource(&output) {
Some(output) => ImageCaptureSourceData::Output(output.downgrade()),
None => ImageCaptureSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ExtOutputImageCaptureSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
where
D: Dispatch<ZcosmicWorkspaceImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ WorkspaceHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ZcosmicWorkspaceImageCaptureSourceManagerV1,
request: <ZcosmicWorkspaceImageCaptureSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
CosmicWorkspaceSourceRequest::CreateSource { source, output } => {
let data = match state.workspace_state().get_ext_workspace_handle(&output) {
Some(workspace) => ImageCaptureSourceData::Workspace(workspace),
None => ImageCaptureSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicWorkspaceImageCaptureSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, (), D> for ImageCaptureSourceState
where
D: Dispatch<ExtForeignToplevelImageCaptureSourceManagerV1, ()>
+ Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData>
+ ToplevelInfoHandler<Window = CosmicSurface>
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ExtForeignToplevelImageCaptureSourceManagerV1,
request: <ExtForeignToplevelImageCaptureSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ToplevelSourceRequest::CreateSource {
source,
toplevel_handle,
} => {
let data = match window_from_ext_handle(state, &toplevel_handle) {
Some(toplevel) => ImageCaptureSourceData::Toplevel(toplevel.clone()),
None => ImageCaptureSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ExtForeignToplevelImageCaptureSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData, D> for ImageCaptureSourceState
where
D: Dispatch<ExtImageCaptureSourceV1, ImageCaptureSourceData> + 'static,
{
fn request(
_state: &mut D,
_client: &Client,
_resource: &ExtImageCaptureSourceV1,
request: <ExtImageCaptureSourceV1 as Resource>::Request,
_data: &ImageCaptureSourceData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ExtImageCaptureSourceV1,
_data: &ImageCaptureSourceData,
) {
}
}
macro_rules! delegate_image_capture_source {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::OutputImageCaptureSourceManagerGlobalData
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1: ()
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_capture_source::v1::server::zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::WorkspaceImageCaptureSourceManagerGlobalData
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_capture_source::v1::server::zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1: ()
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1: $crate::wayland::protocols::image_capture_source::ToplevelImageCaptureSourceManagerGlobalData
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1: ()
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
smithay::reexports::wayland_protocols::ext::image_capture_source::v1::server::ext_image_capture_source_v1::ExtImageCaptureSourceV1: $crate::wayland::protocols::image_capture_source::ImageCaptureSourceData
] => $crate::wayland::protocols::image_capture_source::ImageCaptureSourceState);
};
}
pub(crate) use delegate_image_capture_source;

View file

@ -1,435 +0,0 @@
use super::{
toplevel_info::window_from_handle,
workspace::{WorkspaceHandle, WorkspaceHandler},
};
use crate::shell::CosmicSurface;
use cosmic_protocols::image_source::v1::server::{
zcosmic_ext_workspace_image_source_manager_v1::{
Request as ExtWorkspaceSourceRequest, ZcosmicExtWorkspaceImageSourceManagerV1,
},
zcosmic_image_source_v1::ZcosmicImageSourceV1,
zcosmic_output_image_source_manager_v1::{
Request as OutputSourceRequest, ZcosmicOutputImageSourceManagerV1,
},
zcosmic_toplevel_image_source_manager_v1::{
Request as ToplevelSourceRequest, ZcosmicToplevelImageSourceManagerV1,
},
zcosmic_workspace_image_source_manager_v1::{
Request as WorkspaceSourceRequest, ZcosmicWorkspaceImageSourceManagerV1,
},
};
use smithay::{
output::{Output, WeakOutput},
reexports::wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
},
};
use wayland_backend::server::GlobalId;
#[derive(Debug)]
pub struct ImageSourceState {
output_source_global: GlobalId,
workspace_source_global: GlobalId,
ext_workspace_source_global: GlobalId,
toplevel_source_global: GlobalId,
}
pub struct OutputImageSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
pub struct WorkspaceImageSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
pub struct ToplevelImageSourceManagerGlobalData {
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ImageSourceData {
Output(WeakOutput),
Workspace(WorkspaceHandle),
Toplevel(CosmicSurface),
Destroyed,
}
impl ImageSourceState {
pub fn new<D, F>(display: &DisplayHandle, client_filter: F) -> ImageSourceState
where
D: GlobalDispatch<ZcosmicOutputImageSourceManagerV1, OutputImageSourceManagerGlobalData>
+ Dispatch<ZcosmicOutputImageSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicWorkspaceImageSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ GlobalDispatch<
ZcosmicToplevelImageSourceManagerV1,
ToplevelImageSourceManagerGlobalData,
> + Dispatch<ZcosmicToplevelImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ WorkspaceHandler
+ 'static,
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + Clone + 'static,
{
ImageSourceState {
output_source_global: display.create_global::<D, ZcosmicOutputImageSourceManagerV1, _>(
1,
OutputImageSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
workspace_source_global: display
.create_global::<D, ZcosmicWorkspaceImageSourceManagerV1, _>(
1,
WorkspaceImageSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
ext_workspace_source_global: display
.create_global::<D, ZcosmicExtWorkspaceImageSourceManagerV1, _>(
1,
WorkspaceImageSourceManagerGlobalData {
filter: Box::new(client_filter.clone()),
},
),
toplevel_source_global: display
.create_global::<D, ZcosmicToplevelImageSourceManagerV1, _>(
1,
ToplevelImageSourceManagerGlobalData {
filter: Box::new(client_filter),
},
),
}
}
pub fn output_source_id(&self) -> &GlobalId {
&self.output_source_global
}
pub fn workspace_source_id(&self) -> &GlobalId {
&self.workspace_source_global
}
pub fn ext_workspace_source_id(&self) -> &GlobalId {
&self.ext_workspace_source_global
}
pub fn toplevel_source_id(&self) -> &GlobalId {
&self.toplevel_source_global
}
}
impl<D> GlobalDispatch<ZcosmicOutputImageSourceManagerV1, OutputImageSourceManagerGlobalData, D>
for ImageSourceState
where
D: GlobalDispatch<ZcosmicOutputImageSourceManagerV1, OutputImageSourceManagerGlobalData>
+ Dispatch<ZcosmicOutputImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicOutputImageSourceManagerV1>,
_global_data: &OutputImageSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &OutputImageSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D>
GlobalDispatch<ZcosmicWorkspaceImageSourceManagerV1, WorkspaceImageSourceManagerGlobalData, D>
for ImageSourceState
where
D: GlobalDispatch<ZcosmicWorkspaceImageSourceManagerV1, WorkspaceImageSourceManagerGlobalData>
+ Dispatch<ZcosmicWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicWorkspaceImageSourceManagerV1>,
_global_data: &WorkspaceImageSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &WorkspaceImageSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D>
GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
D,
> for ImageSourceState
where
D: GlobalDispatch<
ZcosmicExtWorkspaceImageSourceManagerV1,
WorkspaceImageSourceManagerGlobalData,
> + Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicExtWorkspaceImageSourceManagerV1>,
_global_data: &WorkspaceImageSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &WorkspaceImageSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D> GlobalDispatch<ZcosmicToplevelImageSourceManagerV1, ToplevelImageSourceManagerGlobalData, D>
for ImageSourceState
where
D: GlobalDispatch<ZcosmicToplevelImageSourceManagerV1, ToplevelImageSourceManagerGlobalData>
+ Dispatch<ZcosmicToplevelImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn bind(
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicToplevelImageSourceManagerV1>,
_global_data: &ToplevelImageSourceManagerGlobalData,
data_init: &mut DataInit<'_, D>,
) {
data_init.init(resource, ());
}
fn can_view(client: Client, global_data: &ToplevelImageSourceManagerGlobalData) -> bool {
(global_data.filter)(&client)
}
}
impl<D> Dispatch<ZcosmicOutputImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicOutputImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
_resource: &ZcosmicOutputImageSourceManagerV1,
request: <ZcosmicOutputImageSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
OutputSourceRequest::CreateSource { source, output } => {
let data = match Output::from_resource(&output) {
Some(output) => ImageSourceData::Output(output.downgrade()),
None => ImageSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicOutputImageSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicWorkspaceImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ WorkspaceHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ZcosmicWorkspaceImageSourceManagerV1,
request: <ZcosmicWorkspaceImageSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
WorkspaceSourceRequest::CreateSource { source, output } => {
let data = match state.workspace_state().workspace_handle(&output) {
Some(workspace) => ImageSourceData::Workspace(workspace),
None => ImageSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicWorkspaceImageSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicExtWorkspaceImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ WorkspaceHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ZcosmicExtWorkspaceImageSourceManagerV1,
request: <ZcosmicExtWorkspaceImageSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ExtWorkspaceSourceRequest::CreateSource { source, output } => {
let data = match state.workspace_state().get_ext_workspace_handle(&output) {
Some(workspace) => ImageSourceData::Workspace(workspace),
None => ImageSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicExtWorkspaceImageSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicToplevelImageSourceManagerV1, (), D> for ImageSourceState
where
D: Dispatch<ZcosmicToplevelImageSourceManagerV1, ()>
+ Dispatch<ZcosmicImageSourceV1, ImageSourceData>
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
_resource: &ZcosmicToplevelImageSourceManagerV1,
request: <ZcosmicToplevelImageSourceManagerV1 as Resource>::Request,
_data: &(),
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
ToplevelSourceRequest::CreateSource {
source,
toplevel_handle,
} => {
let data = match window_from_handle(toplevel_handle) {
Some(toplevel) => ImageSourceData::Toplevel(toplevel),
None => ImageSourceData::Destroyed,
};
data_init.init(source, data);
}
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicToplevelImageSourceManagerV1,
_data: &(),
) {
}
}
impl<D> Dispatch<ZcosmicImageSourceV1, ImageSourceData, D> for ImageSourceState
where
D: Dispatch<ZcosmicImageSourceV1, ImageSourceData> + 'static,
{
fn request(
_state: &mut D,
_client: &Client,
_resource: &ZcosmicImageSourceV1,
request: <ZcosmicImageSourceV1 as Resource>::Request,
_data: &ImageSourceData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
_ => {}
}
}
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicImageSourceV1,
_data: &ImageSourceData,
) {
}
}
macro_rules! delegate_image_source {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_output_image_source_manager_v1::ZcosmicOutputImageSourceManagerV1: $crate::wayland::protocols::image_source::OutputImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_output_image_source_manager_v1::ZcosmicOutputImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_workspace_image_source_manager_v1::ZcosmicWorkspaceImageSourceManagerV1: $crate::wayland::protocols::image_source::WorkspaceImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_workspace_image_source_manager_v1::ZcosmicWorkspaceImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_ext_workspace_image_source_manager_v1::ZcosmicExtWorkspaceImageSourceManagerV1: $crate::wayland::protocols::image_source::WorkspaceImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_ext_workspace_image_source_manager_v1::ZcosmicExtWorkspaceImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_toplevel_image_source_manager_v1::ZcosmicToplevelImageSourceManagerV1: $crate::wayland::protocols::image_source::ToplevelImageSourceManagerGlobalData
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_toplevel_image_source_manager_v1::ZcosmicToplevelImageSourceManagerV1: ()
] => $crate::wayland::protocols::image_source::ImageSourceState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::image_source::v1::server::zcosmic_image_source_v1::ZcosmicImageSourceV1: $crate::wayland::protocols::image_source::ImageSourceData
] => $crate::wayland::protocols::image_source::ImageSourceState);
};
}
pub(crate) use delegate_image_source;

View file

@ -3,7 +3,7 @@
pub mod a11y;
pub mod atspi;
pub mod drm;
pub mod image_source;
pub mod image_capture_source;
pub mod output_configuration;
pub mod output_power;
pub mod overlap_notify;

View file

@ -3,12 +3,14 @@ use std::{
time::Duration,
};
pub use cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_frame_v2::FailureReason;
use cosmic_protocols::screencopy::v2::server::{
zcosmic_screencopy_cursor_session_v2::{self, ZcosmicScreencopyCursorSessionV2},
zcosmic_screencopy_frame_v2::{self, ZcosmicScreencopyFrameV2},
zcosmic_screencopy_manager_v2::{self, ZcosmicScreencopyManagerV2},
zcosmic_screencopy_session_v2::{self, ZcosmicScreencopySessionV2},
pub use smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::{
ext_image_copy_capture_frame_v1::FailureReason,
};
use smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::{
ext_image_copy_capture_cursor_session_v1::{self, ExtImageCopyCaptureCursorSessionV1},
ext_image_copy_capture_frame_v1::{self, ExtImageCopyCaptureFrameV1},
ext_image_copy_capture_manager_v1::{self, ExtImageCopyCaptureManagerV1},
ext_image_copy_capture_session_v1::{self, ExtImageCopyCaptureSessionV1},
};
use smithay::{
backend::{
@ -30,7 +32,7 @@ use smithay::{
use tracing::debug;
use wayland_backend::server::GlobalId;
use super::image_source::ImageSourceData;
use super::image_capture_source::ImageCaptureSourceData;
#[derive(Debug)]
pub struct ScreencopyState {
@ -42,18 +44,18 @@ pub struct ScreencopyState {
impl ScreencopyState {
pub fn new<D, F>(display: &DisplayHandle, client_filter: F) -> ScreencopyState
where
D: GlobalDispatch<ZcosmicScreencopyManagerV2, ScreencopyGlobalData>
+ Dispatch<ZcosmicScreencopyManagerV2, ScreencopyData>
+ Dispatch<ZcosmicScreencopySessionV2, SessionData>
+ Dispatch<ZcosmicScreencopySessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyCursorSessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: GlobalDispatch<ExtImageCopyCaptureManagerV1, ScreencopyGlobalData>
+ Dispatch<ExtImageCopyCaptureManagerV1, ScreencopyData>
+ Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
{
ScreencopyState {
global: display.create_global::<D, ZcosmicScreencopyManagerV2, _>(
global: display.create_global::<D, ExtImageCopyCaptureManagerV1, _>(
1,
ScreencopyGlobalData {
filter: Box::new(client_filter),
@ -84,7 +86,7 @@ pub struct DmabufConstraints {
#[derive(Debug, Clone)]
pub struct Session {
obj: ZcosmicScreencopySessionV2,
obj: ExtImageCopyCaptureSessionV1,
inner: Arc<Mutex<SessionInner>>,
user_data: Arc<UserDataMap>,
}
@ -100,12 +102,12 @@ struct SessionInner {
stopped: bool,
constraints: Option<BufferConstraints>,
draw_cursors: bool,
source: ImageSourceData,
source: ImageCaptureSourceData,
active_frames: Vec<Frame>,
}
impl SessionInner {
fn new(source: ImageSourceData, draw_cursors: bool) -> SessionInner {
fn new(source: ImageCaptureSourceData, draw_cursors: bool) -> SessionInner {
SessionInner {
stopped: false,
constraints: None,
@ -133,7 +135,7 @@ impl Session {
self.obj
.buffer_size(constraints.size.w as u32, constraints.size.h as u32);
for fmt in &constraints.shm {
self.obj.shm_format(*fmt as u32);
self.obj.shm_format(*fmt);
}
if let Some(dma) = constraints.dma.as_ref() {
let node = Vec::from(dma.node.dev_id().to_ne_bytes());
@ -155,7 +157,7 @@ impl Session {
self.inner.lock().unwrap().constraints.clone()
}
pub fn source(&self) -> ImageSourceData {
pub fn source(&self) -> ImageCaptureSourceData {
self.inner.lock().unwrap().source.clone()
}
@ -186,7 +188,7 @@ impl Session {
#[derive(Debug, Clone)]
pub struct CursorSession {
obj: ZcosmicScreencopyCursorSessionV2,
obj: ExtImageCopyCaptureCursorSessionV1,
inner: Arc<Mutex<CursorSessionInner>>,
user_data: Arc<UserDataMap>,
}
@ -199,17 +201,17 @@ impl PartialEq for CursorSession {
#[derive(Debug)]
struct CursorSessionInner {
session: Option<ZcosmicScreencopySessionV2>,
session: Option<ExtImageCopyCaptureSessionV1>,
stopped: bool,
constraints: Option<BufferConstraints>,
source: ImageSourceData,
source: ImageCaptureSourceData,
position: Option<Point<i32, BufferCoords>>,
hotspot: Point<i32, BufferCoords>,
active_frames: Vec<Frame>,
}
impl CursorSessionInner {
fn new(source: ImageSourceData) -> CursorSessionInner {
fn new(source: ImageCaptureSourceData) -> CursorSessionInner {
CursorSessionInner {
session: None,
stopped: false,
@ -239,7 +241,7 @@ impl CursorSession {
if let Some(session_obj) = inner.session.as_ref() {
session_obj.buffer_size(constrains.size.w as u32, constrains.size.h as u32);
for fmt in &constrains.shm {
session_obj.shm_format(*fmt as u32);
session_obj.shm_format(*fmt);
}
if let Some(dma) = constrains.dma.as_ref() {
let node = Vec::from(dma.node.dev_id().to_ne_bytes());
@ -262,7 +264,7 @@ impl CursorSession {
self.inner.lock().unwrap().constraints.clone()
}
pub fn source(&self) -> ImageSourceData {
pub fn source(&self) -> ImageCaptureSourceData {
self.inner.lock().unwrap().source.clone()
}
@ -340,7 +342,7 @@ impl CursorSession {
#[derive(Debug)]
pub struct Frame {
obj: ZcosmicScreencopyFrameV2,
obj: ExtImageCopyCaptureFrameV1,
inner: Arc<Mutex<FrameInner>>,
}
@ -404,7 +406,7 @@ struct FrameInner {
damage: Vec<Rectangle<i32, BufferCoords>>,
// `SessionInner` contains a `Vec<Frame>`, so use a weak reference here to
// avoid a cycle.
obj: Weak<ZcosmicScreencopySessionV2>,
obj: Weak<ExtImageCopyCaptureSessionV1>,
capture_requested: bool,
failed: Option<FailureReason>,
ready: bool,
@ -412,7 +414,7 @@ struct FrameInner {
impl FrameInner {
fn new(
obj: ZcosmicScreencopySessionV2,
obj: ExtImageCopyCaptureSessionV1,
constraints: impl Into<Option<BufferConstraints>>,
) -> Self {
FrameInner {
@ -426,7 +428,7 @@ impl FrameInner {
}
}
fn fail(&mut self, frame: &ZcosmicScreencopyFrameV2, reason: FailureReason) {
fn fail(&mut self, frame: &ExtImageCopyCaptureFrameV1, reason: FailureReason) {
if self.ready || self.failed.is_some() {
return;
}
@ -440,8 +442,11 @@ impl FrameInner {
pub trait ScreencopyHandler {
fn screencopy_state(&mut self) -> &mut ScreencopyState;
fn capture_source(&mut self, source: &ImageSourceData) -> Option<BufferConstraints>;
fn capture_cursor_source(&mut self, source: &ImageSourceData) -> Option<BufferConstraints>;
fn capture_source(&mut self, source: &ImageCaptureSourceData) -> Option<BufferConstraints>;
fn capture_cursor_source(
&mut self,
source: &ImageCaptureSourceData,
) -> Option<BufferConstraints>;
fn new_session(&mut self, session: Session);
fn new_cursor_session(&mut self, session: CursorSession);
@ -475,14 +480,14 @@ pub struct FrameData {
inner: Arc<Mutex<FrameInner>>,
}
impl<D> GlobalDispatch<ZcosmicScreencopyManagerV2, ScreencopyGlobalData, D> for ScreencopyState
impl<D> GlobalDispatch<ExtImageCopyCaptureManagerV1, ScreencopyGlobalData, D> for ScreencopyState
where
D: GlobalDispatch<ZcosmicScreencopyManagerV2, ScreencopyGlobalData>
+ Dispatch<ZcosmicScreencopyManagerV2, ScreencopyData>
+ Dispatch<ZcosmicScreencopySessionV2, SessionData>
+ Dispatch<ZcosmicScreencopySessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyCursorSessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: GlobalDispatch<ExtImageCopyCaptureManagerV1, ScreencopyGlobalData>
+ Dispatch<ExtImageCopyCaptureManagerV1, ScreencopyData>
+ Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
{
@ -490,7 +495,7 @@ where
_state: &mut D,
_handle: &DisplayHandle,
_client: &Client,
resource: New<ZcosmicScreencopyManagerV2>,
resource: New<ExtImageCopyCaptureManagerV1>,
_global_data: &ScreencopyGlobalData,
data_init: &mut DataInit<'_, D>,
) {
@ -502,33 +507,33 @@ where
}
}
impl<D> Dispatch<ZcosmicScreencopyManagerV2, ScreencopyData, D> for ScreencopyState
impl<D> Dispatch<ExtImageCopyCaptureManagerV1, ScreencopyData, D> for ScreencopyState
where
D: Dispatch<ZcosmicScreencopyManagerV2, ScreencopyData>
+ Dispatch<ZcosmicScreencopySessionV2, SessionData>
+ Dispatch<ZcosmicScreencopySessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyCursorSessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: Dispatch<ExtImageCopyCaptureManagerV1, ScreencopyData>
+ Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
{
fn request(
state: &mut D,
_client: &Client,
_resource: &ZcosmicScreencopyManagerV2,
request: <ZcosmicScreencopyManagerV2 as Resource>::Request,
_resource: &ExtImageCopyCaptureManagerV1,
request: <ExtImageCopyCaptureManagerV1 as Resource>::Request,
_data: &ScreencopyData,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_screencopy_manager_v2::Request::CreateSession {
ext_image_copy_capture_manager_v1::Request::CreateSession {
session,
source,
options,
} => {
if let Some(src) = source.data::<ImageSourceData>() {
if *src != ImageSourceData::Destroyed {
if let Some(src) = source.data::<ImageCaptureSourceData>() {
if *src != ImageCaptureSourceData::Destroyed {
if let Some(buffer_constraints) = state.capture_source(src) {
let session_data = Arc::new(Mutex::new(SessionInner::new(
src.clone(),
@ -558,7 +563,7 @@ where
}
let session_data = Arc::new(Mutex::new(SessionInner::new(
ImageSourceData::Destroyed,
ImageCaptureSourceData::Destroyed,
false,
)));
let obj = data_init.init(
@ -574,16 +579,15 @@ where
};
session.stop();
}
zcosmic_screencopy_manager_v2::Request::CreatePointerCursorSession {
ext_image_copy_capture_manager_v1::Request::CreatePointerCursorSession {
session,
source,
pointer: _,
options: _,
} => {
// TODO: use pointer, but we need new smithay api for that.
if let Some(src) = source.data::<ImageSourceData>() {
if *src != ImageSourceData::Destroyed {
if let Some(src) = source.data::<ImageCaptureSourceData>() {
if *src != ImageCaptureSourceData::Destroyed {
if let Some(buffer_constraints) = state.capture_cursor_source(src) {
let session_data =
Arc::new(Mutex::new(CursorSessionInner::new(src.clone())));
@ -611,7 +615,7 @@ where
}
let session_data = Arc::new(Mutex::new(CursorSessionInner::new(
ImageSourceData::Destroyed,
ImageCaptureSourceData::Destroyed,
)));
let obj = data_init.init(
session,
@ -633,30 +637,30 @@ where
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicScreencopyManagerV2,
_resource: &ExtImageCopyCaptureManagerV1,
_data: &ScreencopyData,
) {
}
}
impl<D> Dispatch<ZcosmicScreencopySessionV2, SessionData, D> for ScreencopyState
impl<D> Dispatch<ExtImageCopyCaptureSessionV1, SessionData, D> for ScreencopyState
where
D: Dispatch<ZcosmicScreencopySessionV2, SessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
resource: &ZcosmicScreencopySessionV2,
request: <ZcosmicScreencopySessionV2 as Resource>::Request,
resource: &ExtImageCopyCaptureSessionV1,
request: <ExtImageCopyCaptureSessionV1 as Resource>::Request,
data: &SessionData,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_screencopy_session_v2::Request::CreateFrame { frame } => {
ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => {
let inner = Arc::new(Mutex::new(FrameInner::new(
resource.clone(),
data.inner.lock().unwrap().constraints.clone(),
@ -680,7 +684,7 @@ where
fn destroyed(
state: &mut D,
_client: wayland_backend::server::ClientId,
resource: &ZcosmicScreencopySessionV2,
resource: &ExtImageCopyCaptureSessionV1,
_data: &SessionData,
) {
let scpy = state.screencopy_state();
@ -695,25 +699,25 @@ where
}
}
impl<D> Dispatch<ZcosmicScreencopyCursorSessionV2, CursorSessionData, D> for ScreencopyState
impl<D> Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData, D> for ScreencopyState
where
D: Dispatch<ZcosmicScreencopyCursorSessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopySessionV2, CursorSessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: Dispatch<ExtImageCopyCaptureCursorSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
resource: &ZcosmicScreencopyCursorSessionV2,
request: <ZcosmicScreencopyCursorSessionV2 as Resource>::Request,
resource: &ExtImageCopyCaptureCursorSessionV1,
request: <ExtImageCopyCaptureCursorSessionV1 as Resource>::Request,
data: &CursorSessionData,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_screencopy_cursor_session_v2::Request::GetScreencopySession { session } => {
ext_image_copy_capture_cursor_session_v1::Request::GetCaptureSession { session } => {
let new_data = CursorSessionData {
inner: data.inner.clone(),
};
@ -722,7 +726,7 @@ where
let mut inner = data.inner.lock().unwrap();
if inner.session.is_some() {
resource.post_error(
zcosmic_screencopy_cursor_session_v2::Error::DuplicateSession,
ext_image_copy_capture_cursor_session_v1::Error::DuplicateSession,
"Duplicate session",
);
return;
@ -733,7 +737,7 @@ where
} else if let Some(constraints) = inner.constraints.as_ref() {
session.buffer_size(constraints.size.w as u32, constraints.size.h as u32);
for fmt in &constraints.shm {
session.shm_format(*fmt as u32);
session.shm_format(*fmt);
}
if let Some(dma) = constraints.dma.as_ref() {
let node = Vec::from(dma.node.dev_id().to_ne_bytes());
@ -757,7 +761,7 @@ where
fn destroyed(
state: &mut D,
_client: wayland_backend::server::ClientId,
resource: &ZcosmicScreencopyCursorSessionV2,
resource: &ExtImageCopyCaptureCursorSessionV1,
_data: &CursorSessionData,
) {
let scpy = state.screencopy_state();
@ -772,24 +776,24 @@ where
}
}
impl<D> Dispatch<ZcosmicScreencopySessionV2, CursorSessionData, D> for ScreencopyState
impl<D> Dispatch<ExtImageCopyCaptureSessionV1, CursorSessionData, D> for ScreencopyState
where
D: Dispatch<ZcosmicScreencopySessionV2, SessionData>
+ Dispatch<ZcosmicScreencopyFrameV2, FrameData>
D: Dispatch<ExtImageCopyCaptureSessionV1, SessionData>
+ Dispatch<ExtImageCopyCaptureFrameV1, FrameData>
+ ScreencopyHandler
+ 'static,
{
fn request(
_state: &mut D,
_client: &Client,
resource: &ZcosmicScreencopySessionV2,
request: <ZcosmicScreencopySessionV2 as Resource>::Request,
resource: &ExtImageCopyCaptureSessionV1,
request: <ExtImageCopyCaptureSessionV1 as Resource>::Request,
data: &CursorSessionData,
_dhandle: &DisplayHandle,
data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_screencopy_session_v2::Request::CreateFrame { frame } => {
ext_image_copy_capture_session_v1::Request::CreateFrame { frame } => {
let inner = Arc::new(Mutex::new(FrameInner::new(
resource.clone(),
data.inner.lock().unwrap().constraints.clone(),
@ -813,39 +817,39 @@ where
fn destroyed(
_state: &mut D,
_client: wayland_backend::server::ClientId,
_resource: &ZcosmicScreencopySessionV2,
_resource: &ExtImageCopyCaptureSessionV1,
_data: &CursorSessionData,
) {
}
}
impl<D> Dispatch<ZcosmicScreencopyFrameV2, FrameData, D> for ScreencopyState
impl<D> Dispatch<ExtImageCopyCaptureFrameV1, FrameData, D> for ScreencopyState
where
D: Dispatch<ZcosmicScreencopyFrameV2, FrameData> + ScreencopyHandler + 'static,
D: Dispatch<ExtImageCopyCaptureFrameV1, FrameData> + ScreencopyHandler + 'static,
{
fn request(
state: &mut D,
_client: &Client,
resource: &ZcosmicScreencopyFrameV2,
request: <ZcosmicScreencopyFrameV2 as Resource>::Request,
resource: &ExtImageCopyCaptureFrameV1,
request: <ExtImageCopyCaptureFrameV1 as Resource>::Request,
data: &FrameData,
_dhandle: &DisplayHandle,
_data_init: &mut DataInit<'_, D>,
) {
match request {
zcosmic_screencopy_frame_v2::Request::AttachBuffer { buffer } => {
ext_image_copy_capture_frame_v1::Request::AttachBuffer { buffer } => {
let mut inner = data.inner.lock().unwrap();
if inner.capture_requested {
resource.post_error(
zcosmic_screencopy_frame_v2::Error::AlreadyCaptured,
ext_image_copy_capture_frame_v1::Error::AlreadyCaptured,
"Frame was captured previously",
);
}
inner.buffer = Some(buffer);
}
zcosmic_screencopy_frame_v2::Request::DamageBuffer {
ext_image_copy_capture_frame_v1::Request::DamageBuffer {
x,
y,
width,
@ -855,14 +859,14 @@ where
if inner.capture_requested {
resource.post_error(
zcosmic_screencopy_frame_v2::Error::AlreadyCaptured,
ext_image_copy_capture_frame_v1::Error::AlreadyCaptured,
"Frame was captured previously",
);
}
if x < 0 || y < 0 || width <= 0 || height <= 0 {
resource.post_error(
zcosmic_screencopy_frame_v2::Error::InvalidBufferDamage,
ext_image_copy_capture_frame_v1::Error::InvalidBufferDamage,
"Coordinates negative or size equal to zero",
);
return;
@ -872,19 +876,19 @@ where
.damage
.push(Rectangle::new((x, y).into(), (width, height).into()));
}
zcosmic_screencopy_frame_v2::Request::Capture => {
ext_image_copy_capture_frame_v1::Request::Capture => {
let mut inner = data.inner.lock().unwrap();
if inner.capture_requested {
resource.post_error(
zcosmic_screencopy_frame_v2::Error::AlreadyCaptured,
ext_image_copy_capture_frame_v1::Error::AlreadyCaptured,
"Frame was captured previously",
);
}
if inner.buffer.is_none() {
resource.post_error(
zcosmic_screencopy_frame_v2::Error::NoBuffer,
ext_image_copy_capture_frame_v1::Error::NoBuffer,
"Attempting to capture frame without a buffer",
);
}
@ -1031,7 +1035,7 @@ where
fn destroyed(
state: &mut D,
_client: wayland_backend::server::ClientId,
resource: &ZcosmicScreencopyFrameV2,
resource: &ExtImageCopyCaptureFrameV1,
data: &FrameData,
) {
{
@ -1064,22 +1068,22 @@ where
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::v2::server::zcosmic_screencopy_manager_v2::ZcosmicScreencopyManagerV2: $crate::wayland::protocols::screencopy::ScreencopyGlobalData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1: $crate::wayland::protocols::screencopy::ScreencopyGlobalData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_manager_v2::ZcosmicScreencopyManagerV2: $crate::wayland::protocols::screencopy::ScreencopyData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1: $crate::wayland::protocols::screencopy::ScreencopyData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_session_v2::ZcosmicScreencopySessionV2: $crate::wayland::protocols::screencopy::SessionData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1: $crate::wayland::protocols::screencopy::SessionData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_cursor_session_v2::ZcosmicScreencopyCursorSessionV2: $crate::wayland::protocols::screencopy::CursorSessionData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1: $crate::wayland::protocols::screencopy::CursorSessionData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_session_v2::ZcosmicScreencopySessionV2: $crate::wayland::protocols::screencopy::CursorSessionData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1: $crate::wayland::protocols::screencopy::CursorSessionData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
cosmic_protocols::screencopy::v2::server::zcosmic_screencopy_frame_v2::ZcosmicScreencopyFrameV2: $crate::wayland::protocols::screencopy::FrameData
smithay::reexports::wayland_protocols::ext::image_copy_capture::v1::server::ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1: $crate::wayland::protocols::screencopy::FrameData
] => $crate::wayland::protocols::screencopy::ScreencopyState);
};
}

View file

@ -4,10 +4,13 @@ use std::{collections::HashSet, sync::Mutex};
use smithay::{
output::Output,
reexports::wayland_server::{
backend::{ClientId, GlobalId},
protocol::{wl_output::WlOutput, wl_surface::WlSurface},
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak,
reexports::{
wayland_protocols::ext::foreign_toplevel_list::v1::server::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
wayland_server::{
backend::{ClientId, GlobalId},
protocol::{wl_output::WlOutput, wl_surface::WlSurface},
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Weak,
},
},
utils::{user_data::UserDataMap, IsAlive, Logical, Rectangle},
wayland::foreign_toplevel_list::{
@ -633,6 +636,26 @@ pub fn window_from_handle<W: Window + 'static>(handle: ZcosmicToplevelHandleV1)
.and_then(|state| state.lock().unwrap().window.clone())
}
pub fn window_from_ext_handle<'a, W: Window + 'static, D>(
state: &'a D,
foreign_toplevel: &ExtForeignToplevelHandleV1,
) -> Option<&'a W>
where
D: ToplevelInfoHandler<Window = W>,
{
let handle = ForeignToplevelHandle::from_resource(foreign_toplevel)?;
state.toplevel_info_state().toplevels.iter().find(|w| {
w.user_data().get::<ToplevelState>().and_then(|inner| {
inner
.lock()
.unwrap()
.foreign_handle
.as_ref()
.map(|handle| handle.identifier())
}) == Some(handle.identifier())
})
}
macro_rules! delegate_toplevel_info {
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty, $window: ty) => {
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [