webp_screenshot_rust/capture/linux/
mod.rs1#[cfg(target_os = "linux")]
4mod x11_capture;
5
6#[cfg(all(target_os = "linux", feature = "wayland"))]
7mod wayland_capture;
8
9#[cfg(target_os = "linux")]
10use crate::{
11 capture::traits::{CaptureCapabilities, ScreenCapture},
12 error::{CaptureError, CaptureResult},
13 types::{CaptureRegion, DisplayInfo, RawImage},
14};
15
16#[cfg(target_os = "linux")]
18pub struct LinuxCapture {
19 backend: LinuxBackend,
20}
21
22#[cfg(target_os = "linux")]
23enum LinuxBackend {
24 X11(x11_capture::X11Capture),
25 #[cfg(feature = "wayland")]
26 Wayland(wayland_capture::WaylandCapture),
27}
28
29#[cfg(target_os = "linux")]
30impl LinuxCapture {
31 pub fn new() -> CaptureResult<Box<dyn ScreenCapture>> {
33 let backend = Self::detect_backend()?;
35
36 Ok(Box::new(Self { backend }))
37 }
38
39 fn detect_backend() -> CaptureResult<LinuxBackend> {
41 #[cfg(feature = "wayland")]
43 {
44 if std::env::var("WAYLAND_DISPLAY").is_ok() {
45 if let Ok(wayland) = wayland_capture::WaylandCapture::new() {
46 return Ok(LinuxBackend::Wayland(wayland));
47 }
48 }
49 }
50
51 if std::env::var("DISPLAY").is_ok() {
53 let x11 = x11_capture::X11Capture::new()?;
54 return Ok(LinuxBackend::X11(x11));
55 }
56
57 Err(CaptureError::PlatformError(
58 "No X11 or Wayland display found".to_string(),
59 ))
60 }
61}
62
63#[cfg(target_os = "linux")]
64impl ScreenCapture for LinuxCapture {
65 fn get_displays(&self) -> CaptureResult<Vec<DisplayInfo>> {
66 match &self.backend {
67 LinuxBackend::X11(x11) => x11.get_displays(),
68 #[cfg(feature = "wayland")]
69 LinuxBackend::Wayland(wayland) => wayland.get_displays(),
70 }
71 }
72
73 fn capture_display(&self, display_index: usize) -> CaptureResult<RawImage> {
74 match &self.backend {
75 LinuxBackend::X11(x11) => x11.capture_display(display_index),
76 #[cfg(feature = "wayland")]
77 LinuxBackend::Wayland(wayland) => wayland.capture_display(display_index),
78 }
79 }
80
81 fn capture_region(&self, region: CaptureRegion) -> CaptureResult<RawImage> {
82 match &self.backend {
83 LinuxBackend::X11(x11) => x11.capture_region(region),
84 #[cfg(feature = "wayland")]
85 LinuxBackend::Wayland(wayland) => wayland.capture_region(region),
86 }
87 }
88
89 fn implementation_name(&self) -> String {
90 match &self.backend {
91 LinuxBackend::X11(_) => "Linux X11".to_string(),
92 #[cfg(feature = "wayland")]
93 LinuxBackend::Wayland(_) => "Linux Wayland".to_string(),
94 }
95 }
96
97 fn capabilities(&self) -> CaptureCapabilities {
98 CaptureCapabilities {
99 supports_cursor: true,
100 supports_window_capture: true,
101 supports_hdr: false,
102 max_resolution: (0, 0), supports_multi_display: true,
104 supports_gpu_acceleration: false,
105 estimated_latency_ms: 20,
106 }
107 }
108}
109
110#[cfg(not(target_os = "linux"))]
112pub struct LinuxCapture;
113
114#[cfg(not(target_os = "linux"))]
115impl LinuxCapture {
116 pub fn new() -> CaptureResult<Box<dyn ScreenCapture>> {
117 Err(CaptureError::PlatformError(
118 "Linux capture is only available on Linux".to_string(),
119 ))
120 }
121}