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}