cosmic_client_toolkit/screencopy/
dispatch.rs

1use cosmic_protocols::image_capture_source::v1::client::zcosmic_workspace_image_capture_source_manager_v1;
2use std::time::Duration;
3use wayland_client::{Connection, Dispatch, QueueHandle, WEnum};
4use wayland_protocols::ext::{
5    image_capture_source::v1::client::{
6        ext_foreign_toplevel_image_capture_source_manager_v1, ext_image_capture_source_v1,
7        ext_output_image_capture_source_manager_v1,
8    },
9    image_copy_capture::v1::client::{
10        ext_image_copy_capture_cursor_session_v1, ext_image_copy_capture_frame_v1,
11        ext_image_copy_capture_manager_v1, ext_image_copy_capture_session_v1,
12    },
13};
14
15use super::{
16    CaptureCursorSession, CaptureFrame, CaptureSession, Rect, ScreencopyCursorSessionDataExt,
17    ScreencopyFrameDataExt, ScreencopyHandler, ScreencopySessionDataExt, ScreencopyState,
18};
19use crate::GlobalData;
20
21impl<D> Dispatch<ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1, GlobalData, D>
22    for ScreencopyState
23where
24    D: Dispatch<ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1, GlobalData>
25        + ScreencopyHandler,
26{
27    fn event(
28        _: &mut D,
29        _: &ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1,
30        _: ext_image_copy_capture_manager_v1::Event,
31        _: &GlobalData,
32        _: &Connection,
33        _: &QueueHandle<D>,
34    ) {
35        unreachable!()
36    }
37}
38
39impl<D, U> Dispatch<ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1, U, D>
40    for ScreencopyState
41where
42    D: Dispatch<ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1, U>
43        + ScreencopyHandler,
44    U: ScreencopySessionDataExt,
45{
46    fn event(
47        app_data: &mut D,
48        session: &ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1,
49        event: ext_image_copy_capture_session_v1::Event,
50        udata: &U,
51        conn: &Connection,
52        qh: &QueueHandle<D>,
53    ) {
54        let formats = &udata.screencopy_session_data().formats;
55        match event {
56            ext_image_copy_capture_session_v1::Event::BufferSize { width, height } => {
57                formats.lock().unwrap().buffer_size = (width, height);
58            }
59            ext_image_copy_capture_session_v1::Event::ShmFormat { format } => {
60                if let WEnum::Value(value) = format {
61                    formats.lock().unwrap().shm_formats.push(value);
62                }
63            }
64            ext_image_copy_capture_session_v1::Event::DmabufDevice { device } => {
65                let device = libc::dev_t::from_ne_bytes(device.try_into().unwrap());
66                formats.lock().unwrap().dmabuf_device = Some(device);
67            }
68            ext_image_copy_capture_session_v1::Event::DmabufFormat { format, modifiers } => {
69                let modifiers = modifiers
70                    .chunks_exact(8)
71                    .map(|x| u64::from_ne_bytes(x.try_into().unwrap()))
72                    .collect();
73                formats
74                    .lock()
75                    .unwrap()
76                    .dmabuf_formats
77                    .push((format, modifiers));
78            }
79            ext_image_copy_capture_session_v1::Event::Done => {
80                if let Some(session) = udata
81                    .screencopy_session_data()
82                    .session
83                    .get()
84                    .unwrap()
85                    .upgrade()
86                    .map(CaptureSession)
87                {
88                    app_data.init_done(conn, qh, &session, &formats.lock().unwrap());
89                }
90            }
91            ext_image_copy_capture_session_v1::Event::Stopped => {
92                if let Some(session) = udata
93                    .screencopy_session_data()
94                    .session
95                    .get()
96                    .unwrap()
97                    .upgrade()
98                    .map(CaptureSession)
99                {
100                    app_data.stopped(conn, qh, &session);
101                }
102                session.destroy();
103            }
104            _ => unreachable!(),
105        }
106    }
107}
108
109impl<D, U> Dispatch<ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1, U, D>
110    for ScreencopyState
111where
112    D: Dispatch<ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1, U> + ScreencopyHandler,
113    U: ScreencopyFrameDataExt,
114{
115    fn event(
116        app_data: &mut D,
117        screencopy_frame: &ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1,
118        event: ext_image_copy_capture_frame_v1::Event,
119        udata: &U,
120        conn: &Connection,
121        qh: &QueueHandle<D>,
122    ) {
123        let frame = &udata.screencopy_frame_data().frame;
124        match event {
125            ext_image_copy_capture_frame_v1::Event::Transform { transform } => {
126                frame.lock().unwrap().transform = transform;
127            }
128            ext_image_copy_capture_frame_v1::Event::Damage {
129                x,
130                y,
131                width,
132                height,
133            } => {
134                frame.lock().unwrap().damage.push(Rect {
135                    x,
136                    y,
137                    width,
138                    height,
139                });
140            }
141            ext_image_copy_capture_frame_v1::Event::PresentationTime {
142                tv_sec_hi,
143                tv_sec_lo,
144                tv_nsec,
145            } => {
146                let secs = (u64::from(tv_sec_hi) << 32) + u64::from(tv_sec_lo);
147                let duration = Duration::new(secs, tv_nsec);
148                frame.lock().unwrap().present_time = Some(duration);
149            }
150            ext_image_copy_capture_frame_v1::Event::Ready => {
151                let frame = frame.lock().unwrap().clone();
152                app_data.ready(
153                    conn,
154                    qh,
155                    &CaptureFrame {
156                        frame: screencopy_frame.clone(),
157                    },
158                    frame,
159                );
160                screencopy_frame.destroy();
161            }
162            ext_image_copy_capture_frame_v1::Event::Failed { reason } => {
163                app_data.failed(
164                    conn,
165                    qh,
166                    &CaptureFrame {
167                        frame: screencopy_frame.clone(),
168                    },
169                    reason,
170                );
171                screencopy_frame.destroy();
172            }
173            _ => unreachable!(),
174        }
175    }
176}
177
178impl<D, U>
179    Dispatch<ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1, U, D>
180    for ScreencopyState
181where
182    D: Dispatch<ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1, U>
183        + ScreencopyHandler,
184    U: ScreencopyCursorSessionDataExt,
185{
186    fn event(
187        app_data: &mut D,
188        _screencopy_cursor_session: &ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1,
189        event: ext_image_copy_capture_cursor_session_v1::Event,
190        udata: &U,
191        conn: &Connection,
192        qh: &QueueHandle<D>,
193    ) {
194        match event {
195            ext_image_copy_capture_cursor_session_v1::Event::Enter => {
196                if let Some(session) = udata
197                    .screencopy_cursor_session_data()
198                    .session
199                    .get()
200                    .unwrap()
201                    .upgrade()
202                    .map(CaptureCursorSession)
203                {
204                    app_data.cursor_enter(conn, qh, &session);
205                }
206            }
207            ext_image_copy_capture_cursor_session_v1::Event::Leave => {
208                if let Some(session) = udata
209                    .screencopy_cursor_session_data()
210                    .session
211                    .get()
212                    .unwrap()
213                    .upgrade()
214                    .map(CaptureCursorSession)
215                {
216                    app_data.cursor_leave(conn, qh, &session);
217                }
218            }
219            ext_image_copy_capture_cursor_session_v1::Event::Position { x, y } => {
220                if let Some(session) = udata
221                    .screencopy_cursor_session_data()
222                    .session
223                    .get()
224                    .unwrap()
225                    .upgrade()
226                    .map(CaptureCursorSession)
227                {
228                    app_data.cursor_position(conn, qh, &session, x, y);
229                }
230            }
231            ext_image_copy_capture_cursor_session_v1::Event::Hotspot { x, y } => {
232                if let Some(session) = udata
233                    .screencopy_cursor_session_data()
234                    .session
235                    .get()
236                    .unwrap()
237                    .upgrade()
238                    .map(CaptureCursorSession)
239                {
240                    app_data.cursor_hotspot(conn, qh, &session, x, y);
241                }
242            }
243            _ => unreachable!(),
244        }
245    }
246}
247
248impl<D> Dispatch<ext_image_capture_source_v1::ExtImageCaptureSourceV1, GlobalData, D>
249    for ScreencopyState
250where
251    D: Dispatch<ext_image_capture_source_v1::ExtImageCaptureSourceV1, GlobalData>
252        + ScreencopyHandler,
253{
254    fn event(
255        _app_data: &mut D,
256        _source: &ext_image_capture_source_v1::ExtImageCaptureSourceV1,
257        _event: ext_image_capture_source_v1::Event,
258        _udata: &GlobalData,
259        _conn: &Connection,
260        _qh: &QueueHandle<D>,
261    ) {
262        unreachable!()
263    }
264}
265
266impl<D>
267    Dispatch<
268        ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1,
269        GlobalData,
270        D,
271    > for ScreencopyState
272where
273    D: Dispatch<
274            ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1,
275            GlobalData,
276        > + ScreencopyHandler,
277{
278    fn event(
279        _app_data: &mut D,
280        _source: &ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1,
281        _event: ext_output_image_capture_source_manager_v1::Event,
282        _udata: &GlobalData,
283        _conn: &Connection,
284        _qh: &QueueHandle<D>,
285    ) {
286        unreachable!()
287    }
288}
289
290impl<D>
291    Dispatch<
292        ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1,
293        GlobalData,
294        D,
295    > for ScreencopyState
296where
297    D: Dispatch<
298            ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1,
299            GlobalData,
300        > + ScreencopyHandler,
301{
302    fn event(
303        _app_data: &mut D,
304        _source: &ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1,
305        _event: ext_foreign_toplevel_image_capture_source_manager_v1::Event,
306        _udata: &GlobalData,
307        _conn: &Connection,
308        _qh: &QueueHandle<D>,
309    ) {
310        unreachable!()
311    }
312}
313
314impl<D>
315    Dispatch<
316        zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1,
317        GlobalData,
318        D,
319    > for ScreencopyState
320where
321    D: Dispatch<
322            zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1,
323            GlobalData,
324        > + ScreencopyHandler,
325{
326    fn event(
327        _app_data: &mut D,
328        _source: &zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1,
329        _event: zcosmic_workspace_image_capture_source_manager_v1::Event,
330        _udata: &GlobalData,
331        _conn: &Connection,
332        _qh: &QueueHandle<D>,
333    ) {
334        unreachable!()
335    }
336}
337
338#[macro_export]
339macro_rules! delegate_screencopy {
340    ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
341        $crate::wayland_client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
342            $crate::wayland_protocols::ext::image_capture_source::v1::client::ext_output_image_capture_source_manager_v1::ExtOutputImageCaptureSourceManagerV1: $crate::GlobalData
343        ] => $crate::screencopy::ScreencopyState);
344        $crate::wayland_client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
345            $crate::wayland_protocols::ext::image_capture_source::v1::client::ext_foreign_toplevel_image_capture_source_manager_v1::ExtForeignToplevelImageCaptureSourceManagerV1: $crate::GlobalData
346        ] => $crate::screencopy::ScreencopyState);
347        $crate::wayland_client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
348            $crate::wayland_protocols::ext::image_capture_source::v1::client::ext_image_capture_source_v1::ExtImageCaptureSourceV1: $crate::GlobalData
349        ] => $crate::screencopy::ScreencopyState);
350        $crate::wayland_client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
351            $crate::cosmic_protocols::image_capture_source::v1::client::zcosmic_workspace_image_capture_source_manager_v1::ZcosmicWorkspaceImageCaptureSourceManagerV1: $crate::GlobalData
352        ] => $crate::screencopy::ScreencopyState);
353        $crate::wayland_client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
354            $crate::wayland_protocols::ext::image_copy_capture::v1::client::ext_image_copy_capture_manager_v1::ExtImageCopyCaptureManagerV1: $crate::GlobalData
355        ] => $crate::screencopy::ScreencopyState);
356        $crate::wayland_client::delegate_dispatch!(@<$( $lt $( : $clt $(+ $dlt )* )? ),* SessionData: ($crate::screencopy::ScreencopySessionDataExt)> $ty: [
357            $crate::wayland_protocols::ext::image_copy_capture::v1::client::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1: SessionData
358        ] => $crate::screencopy::ScreencopyState);
359        $crate::wayland_client::delegate_dispatch!(@<$( $lt $( : $clt $(+ $dlt )* )? ),* FrameData: ($crate::screencopy::ScreencopyFrameDataExt)> $ty: [
360            $crate::wayland_protocols::ext::image_copy_capture::v1::client::ext_image_copy_capture_frame_v1::ExtImageCopyCaptureFrameV1: FrameData
361        ] => $crate::screencopy::ScreencopyState);
362        $crate::wayland_client::delegate_dispatch!(@<$( $lt $( : $clt $(+ $dlt )* )? ),* CursorSessionData: ($crate::screencopy::ScreencopyCursorSessionDataExt)> $ty: [
363            $crate::wayland_protocols::ext::image_copy_capture::v1::client::ext_image_copy_capture_cursor_session_v1::ExtImageCopyCaptureCursorSessionV1: CursorSessionData
364        ] => $crate::screencopy::ScreencopyState);
365    };
366}