cosmic_client_toolkit/screencopy/
capture_source.rs1use std::{error::Error, fmt};
2use wayland_client::{Dispatch, QueueHandle, protocol::wl_output};
3use wayland_protocols::ext::{
4 foreign_toplevel_list::v1::client::ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
5 image_capture_source::v1::client::ext_image_capture_source_v1,
6 workspace::v1::client::ext_workspace_handle_v1::ExtWorkspaceHandleV1,
7};
8
9use super::Capturer;
10use crate::GlobalData;
11
12#[derive(Debug)]
13pub struct CaptureSourceError(CaptureSourceKind);
14
15impl fmt::Display for CaptureSourceError {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
17 write!(f, "capture kind '{:?}' unsupported by compositor", self.0)
18 }
19}
20
21impl Error for CaptureSourceError {}
22
23#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
24pub enum CaptureSourceKind {
25 Output,
26 Toplevel,
27 Workspace,
28}
29
30#[derive(Clone, Debug, Hash, PartialEq, Eq)]
31pub enum CaptureSource {
32 Output(wl_output::WlOutput),
33 Toplevel(ExtForeignToplevelHandleV1),
34 Workspace(ExtWorkspaceHandleV1),
35}
36
37impl CaptureSource {
38 pub fn kind(&self) -> CaptureSourceKind {
39 match self {
40 Self::Output(_) => CaptureSourceKind::Output,
41 Self::Toplevel(_) => CaptureSourceKind::Toplevel,
42 Self::Workspace(_) => CaptureSourceKind::Workspace,
43 }
44 }
45
46 pub(crate) fn create_source<D>(
47 &self,
48 capturer: &Capturer,
49 qh: &QueueHandle<D>,
50 ) -> Result<WlCaptureSource, CaptureSourceError>
51 where
52 D: 'static,
53 D: Dispatch<ext_image_capture_source_v1::ExtImageCaptureSourceV1, GlobalData>,
54 {
55 match self {
56 CaptureSource::Output(output) => {
57 if let Some(manager) = &capturer.0.output_source_manager {
58 return Ok(WlCaptureSource(
59 manager.create_source(output, qh, GlobalData),
60 ));
61 }
62 }
63 CaptureSource::Toplevel(toplevel) => {
64 if let Some(manager) = &capturer.0.foreign_toplevel_source_manager {
65 return Ok(WlCaptureSource(
66 manager.create_source(toplevel, qh, GlobalData),
67 ));
68 }
69 }
70 CaptureSource::Workspace(workspace) => {
71 if let Some(manager) = &capturer.0.workspace_source_manager {
72 return Ok(WlCaptureSource(
73 manager.create_source(workspace, qh, GlobalData),
74 ));
75 }
76 }
77 }
78 Err(CaptureSourceError(self.kind()))
79 }
80}
81
82pub(crate) struct WlCaptureSource(pub ext_image_capture_source_v1::ExtImageCaptureSourceV1);
84
85impl Drop for WlCaptureSource {
86 fn drop(&mut self) {
87 self.0.destroy();
88 }
89}