1use super::{Screen, WindowHandle, XlibError, MAX_PROPERTY_VALUE_LEN, MOUSEMASK};
3use crate::{XWrap, XlibWindowHandle};
4use leftwm_core::models::{BBox, DockArea, WindowState, WindowType, XyhwChange};
5use std::ffi::{CStr, CString};
6use std::os::raw::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong};
7use std::slice;
8use x11_dl::xinerama::XineramaScreenInfo;
9use x11_dl::xlib::{self, XWindowAttributes};
10use x11_dl::xrandr::XRRCrtcInfo;
11
12impl XWrap {
13 pub fn get_all_windows(&self) -> Result<Vec<xlib::Window>, String> {
21 let mut all = Vec::new();
22 for root in self.get_roots() {
23 match self.get_windows_for_root(root) {
24 Ok(some_windows) => {
25 for w in some_windows {
26 all.push(*w);
27 }
28 }
29 Err(err) => return Err(err),
30 }
31 }
32 Ok(all)
33 }
34
35 #[must_use]
40 pub fn get_color(&self, color: String) -> c_ulong {
41 unsafe {
42 let screen = (self.xlib.XDefaultScreen)(self.display);
43 let cmap: xlib::Colormap = (self.xlib.XDefaultColormap)(self.display, screen);
44 let color_cstr = CString::new(color).unwrap_or_default().into_raw();
45 let mut color: xlib::XColor = std::mem::zeroed();
46 (self.xlib.XAllocNamedColor)(self.display, cmap, color_cstr, &mut color, &mut color);
47 color.pixel
48 }
49 }
50
51 pub fn get_cursor_point(&self) -> Result<(i32, i32), XlibError> {
57 let roots = self.get_roots();
58 for w in roots {
59 let mut root_return: xlib::Window = 0;
60 let mut child_return: xlib::Window = 0;
61 let mut root_x_return: c_int = 0;
62 let mut root_y_return: c_int = 0;
63 let mut win_x_return: c_int = 0;
64 let mut win_y_return: c_int = 0;
65 let mut mask_return: c_uint = 0;
66 let success = unsafe {
67 (self.xlib.XQueryPointer)(
68 self.display,
69 w,
70 &mut root_return,
71 &mut child_return,
72 &mut root_x_return,
73 &mut root_y_return,
74 &mut win_x_return,
75 &mut win_y_return,
76 &mut mask_return,
77 )
78 };
79 if success > 0 {
80 return Ok((win_x_return, win_y_return));
81 }
82 }
83 Err(XlibError::RootWindowNotFound)
84 }
85
86 pub fn get_cursor_window(&self) -> Result<WindowHandle<XlibWindowHandle>, XlibError> {
92 let roots = self.get_roots();
93 for w in roots {
94 let mut root_return: xlib::Window = 0;
95 let mut child_return: xlib::Window = 0;
96 let mut root_x_return: c_int = 0;
97 let mut root_y_return: c_int = 0;
98 let mut win_x_return: c_int = 0;
99 let mut win_y_return: c_int = 0;
100 let mut mask_return: c_uint = 0;
101 let success = unsafe {
102 (self.xlib.XQueryPointer)(
103 self.display,
104 w,
105 &mut root_return,
106 &mut child_return,
107 &mut root_x_return,
108 &mut root_y_return,
109 &mut win_x_return,
110 &mut win_y_return,
111 &mut mask_return,
112 )
113 };
114 if success > 0 {
115 return Ok(WindowHandle(XlibWindowHandle(child_return)));
116 }
117 }
118 Err(XlibError::RootWindowNotFound)
119 }
120
121 #[must_use]
123 pub const fn get_default_root_handle(&self) -> WindowHandle<XlibWindowHandle> {
124 WindowHandle(XlibWindowHandle(self.root))
125 }
126
127 #[must_use]
129 pub const fn get_default_root(&self) -> xlib::Window {
130 self.root
131 }
132
133 #[must_use]
135 pub fn get_hint_sizing_as_xyhw(&self, window: xlib::Window) -> Option<XyhwChange> {
136 let hint = self.get_hint_sizing(window);
137 if let Some(size) = hint {
138 let mut xyhw = XyhwChange::default();
139
140 if (size.flags & xlib::PSize) != 0 || (size.flags & xlib::USSize) != 0 {
141 xyhw.w = Some(size.width);
143 xyhw.h = Some(size.height);
144 } else if (size.flags & xlib::PBaseSize) != 0 {
145 xyhw.w = Some(size.base_width);
146 xyhw.h = Some(size.base_height);
147 }
148
149 if (size.flags & xlib::PResizeInc) != 0 {
150 xyhw.w = Some(size.width_inc);
151 xyhw.h = Some(size.height_inc);
152 }
153
154 if (size.flags & xlib::PMaxSize) != 0 {
155 xyhw.maxw = Some(size.max_width);
156 xyhw.maxh = Some(size.max_height);
157 }
158
159 if (size.flags & xlib::PMinSize) != 0 {
160 xyhw.minw = Some(size.min_width);
161 xyhw.minh = Some(size.min_height);
162 }
163 xyhw.w = std::cmp::max(xyhw.w, xyhw.minw);
165 xyhw.h = std::cmp::max(xyhw.h, xyhw.minh);
166 xyhw.w = xyhw.w.filter(|&w| w != 0);
168 xyhw.h = xyhw.h.filter(|&h| h != 0);
169
170 if (size.flags & xlib::PPosition) != 0 || (size.flags & xlib::USPosition) != 0 {
171 xyhw.x = Some(size.x);
173 xyhw.y = Some(size.y);
174 }
175 return Some(xyhw);
182 }
183 None
184 }
185
186 #[must_use]
189 pub fn get_mask_event(&self) -> xlib::XEvent {
190 unsafe {
191 let mut event: xlib::XEvent = std::mem::zeroed();
192 (self.xlib.XMaskEvent)(
193 self.display,
194 MOUSEMASK | xlib::SubstructureRedirectMask | xlib::ExposureMask,
195 &mut event,
196 );
197 event
198 }
199 }
200
201 #[must_use]
204 pub fn get_next_event(&self) -> xlib::XEvent {
205 unsafe {
206 let mut event: xlib::XEvent = std::mem::zeroed();
207 (self.xlib.XNextEvent)(self.display, &mut event);
208 event
209 }
210 }
211
212 #[must_use]
218 pub fn get_screens(&self) -> Vec<Screen<XlibWindowHandle>> {
219 use x11_dl::xinerama::Xlib;
220 use x11_dl::xrandr::Xrandr;
221 let xlib = Xlib::open().expect("Couldn't not connect to Xorg Server");
222
223 if let Ok(xrandr) = Xrandr::open() {
226 unsafe {
227 let screen_resources = (xrandr.XRRGetScreenResources)(self.display, self.root);
228 let outputs = slice::from_raw_parts(
229 (*screen_resources).outputs,
230 (*screen_resources).noutput as usize,
231 );
232
233 return outputs
234 .iter()
235 .map(|output| {
236 (xrandr.XRRGetOutputInfo)(self.display, screen_resources, *output)
237 })
238 .filter(|&output_info| (*output_info).crtc != 0)
239 .map(|output_info| {
240 let crtc_info = (xrandr.XRRGetCrtcInfo)(
241 self.display,
242 screen_resources,
243 (*output_info).crtc,
244 );
245 let mut s: Screen<XlibWindowHandle> =
246 XRRCrtcInfoIntoScreen(*crtc_info).into();
247 s.root = self.get_default_root_handle();
248 s.output = CStr::from_ptr((*output_info).name)
249 .to_string_lossy()
250 .into_owned();
251 s
252 })
253 .collect();
254 }
255 }
256
257 let xinerama = unsafe { (xlib.XineramaIsActive)(self.display) } > 0;
258 if xinerama {
259 let root = self.get_default_root_handle();
260 let mut screen_count = 0;
261 let info_array_raw =
262 unsafe { (xlib.XineramaQueryScreens)(self.display, &mut screen_count) };
263 let xinerama_infos: &[XineramaScreenInfo] =
265 unsafe { slice::from_raw_parts(info_array_raw, screen_count as usize) };
266 xinerama_infos
267 .iter()
268 .map(|i| {
269 let mut s: Screen<XlibWindowHandle> = XineramaScreenInfoIntoScreen(i).into();
270 s.root = root;
271 s
272 })
273 .collect()
274 } else {
275 let roots: Result<Vec<xlib::XWindowAttributes>, _> =
277 self.get_roots().map(|w| self.get_window_attrs(w)).collect();
278 let roots = roots.expect("Error: No screen were detected");
279 roots
280 .iter()
281 .map(|attrs| XWindowAttributesIntoScreen(attrs).into())
282 .collect()
283 }
284 }
285
286 #[must_use]
288 pub fn get_screens_area_dimensions(&self) -> (i32, i32) {
289 let mut height = 0;
290 let mut width = 0;
291 for s in self.get_screens() {
292 height = std::cmp::max(height, s.bbox.height + s.bbox.y);
293 width = std::cmp::max(width, s.bbox.width + s.bbox.x);
294 }
295 (height, width)
296 }
297
298 #[must_use]
301 pub fn get_transient_for(&self, window: xlib::Window) -> Option<xlib::Window> {
302 unsafe {
303 let mut transient: xlib::Window = std::mem::zeroed();
304 let status: c_int =
305 (self.xlib.XGetTransientForHint)(self.display, window, &mut transient);
306 if status > 0 {
307 Some(transient)
308 } else {
309 None
310 }
311 }
312 }
313
314 #[must_use]
317 pub fn get_window_actions_atoms(&self, window: xlib::Window) -> Vec<xlib::Atom> {
318 let mut format_return: i32 = 0;
319 let mut nitems_return: c_ulong = 0;
320 let mut bytes_remaining: c_ulong = 0;
321 let mut type_return: xlib::Atom = 0;
322 let mut prop_return: *mut c_uchar = unsafe { std::mem::zeroed() };
323 unsafe {
324 let status = (self.xlib.XGetWindowProperty)(
325 self.display,
326 window,
327 self.atoms.NetWMAction,
328 0,
329 MAX_PROPERTY_VALUE_LEN / 4,
330 xlib::False,
331 xlib::XA_ATOM,
332 &mut type_return,
333 &mut format_return,
334 &mut nitems_return,
335 &mut bytes_remaining,
336 &mut prop_return,
337 );
338 if status == i32::from(xlib::Success) && !prop_return.is_null() {
339 #[allow(clippy::cast_lossless, clippy::cast_ptr_alignment)]
340 let ptr = prop_return as *const c_ulong;
341 let results: &[xlib::Atom] = slice::from_raw_parts(ptr, nitems_return as usize);
342 return results.to_vec();
343 }
344 vec![]
345 }
346 }
347
348 pub fn get_window_attrs(
354 &self,
355 window: xlib::Window,
356 ) -> Result<xlib::XWindowAttributes, XlibError> {
357 let mut attrs: xlib::XWindowAttributes = unsafe { std::mem::zeroed() };
358 let status = unsafe { (self.xlib.XGetWindowAttributes)(self.display, window, &mut attrs) };
359 if status == 0 {
360 return Err(XlibError::FailedStatus);
361 }
362 Ok(attrs)
363 }
364
365 #[must_use]
368 pub fn get_window_class(&self, window: xlib::Window) -> Option<(String, String)> {
369 unsafe {
370 let mut class_return: xlib::XClassHint = std::mem::zeroed();
371 let status = (self.xlib.XGetClassHint)(self.display, window, &mut class_return);
372 if status == 0 {
373 return None;
374 }
375 let Ok(res_name) =
376 CString::from_raw(class_return.res_name.cast::<c_char>()).into_string()
377 else {
378 return None;
379 };
380 let Ok(res_class) =
381 CString::from_raw(class_return.res_class.cast::<c_char>()).into_string()
382 else {
383 return None;
384 };
385 Some((res_name, res_class))
386 }
387 }
388
389 pub fn get_window_geometry(&self, window: xlib::Window) -> Result<XyhwChange, XlibError> {
395 let mut root_return: xlib::Window = 0;
396 let mut x_return: c_int = 0;
397 let mut y_return: c_int = 0;
398 let mut width_return: c_uint = 0;
399 let mut height_return: c_uint = 0;
400 let mut border_width_return: c_uint = 0;
401 let mut depth_return: c_uint = 0;
402 unsafe {
403 let status = (self.xlib.XGetGeometry)(
404 self.display,
405 window,
406 &mut root_return,
407 &mut x_return,
408 &mut y_return,
409 &mut width_return,
410 &mut height_return,
411 &mut border_width_return,
412 &mut depth_return,
413 );
414 if status == 0 {
415 return Err(XlibError::FailedStatus);
416 }
417 }
418 Ok(XyhwChange {
419 x: Some(x_return),
420 y: Some(y_return),
421 w: Some(width_return as i32),
422 h: Some(height_return as i32),
423 ..XyhwChange::default()
424 })
425 }
426
427 #[must_use]
429 pub fn get_window_name(&self, window: xlib::Window) -> Option<String> {
430 if let Ok(text) = self.get_text_prop(window, self.atoms.NetWMName) {
431 return Some(text);
432 }
433 if let Ok(text) = self.get_text_prop(window, xlib::XA_WM_NAME) {
434 return Some(text);
435 }
436 None
437 }
438
439 #[must_use]
441 pub fn get_window_legacy_name(&self, window: xlib::Window) -> Option<String> {
442 if let Ok(text) = self.get_text_prop(window, xlib::XA_WM_NAME) {
443 return Some(text);
444 }
445 None
446 }
447
448 #[must_use]
450 pub fn get_window_pid(&self, window: xlib::Window) -> Option<u32> {
451 let (prop_return, _) = self
452 .get_property(window, self.atoms.NetWMPid, xlib::XA_CARDINAL)
453 .ok()?;
454 unsafe {
455 #[allow(clippy::cast_lossless, clippy::cast_ptr_alignment)]
456 let pid = *prop_return.cast::<u32>();
457 Some(pid)
458 }
459 }
460
461 #[must_use]
463 pub fn get_window_states(&self, window: xlib::Window) -> Vec<WindowState> {
464 let window_states_atoms = self.get_window_states_atoms(window);
465
466 let maximized = window_states_atoms.contains(&self.atoms.NetWMStateMaximizedVert)
470 && window_states_atoms.contains(&self.atoms.NetWMStateMaximizedHorz);
471
472 let mut window_states: Vec<WindowState> = window_states_atoms
473 .iter()
474 .map(|a| match a {
475 x if x == &self.atoms.NetWMStateModal => WindowState::Modal,
476 x if x == &self.atoms.NetWMStateSticky => WindowState::Sticky,
477 x if x == &self.atoms.NetWMStateMaximizedVert && !maximized => {
478 WindowState::MaximizedVert
479 }
480 x if x == &self.atoms.NetWMStateMaximizedHorz && !maximized => {
481 WindowState::MaximizedHorz
482 }
483 x if x == &self.atoms.NetWMStateShaded => WindowState::Shaded,
484 x if x == &self.atoms.NetWMStateSkipTaskbar => WindowState::SkipTaskbar,
485 x if x == &self.atoms.NetWMStateSkipPager => WindowState::SkipPager,
486 x if x == &self.atoms.NetWMStateHidden => WindowState::Hidden,
487 x if x == &self.atoms.NetWMStateFullscreen => WindowState::Fullscreen,
488 x if x == &self.atoms.NetWMStateAbove => WindowState::Above,
489 x if x == &self.atoms.NetWMStateBelow => WindowState::Below,
490 _ => WindowState::Modal,
491 })
492 .collect();
493
494 if maximized {
495 window_states.push(WindowState::Maximized);
496 }
497
498 window_states
499 }
500
501 #[must_use]
504 pub fn get_window_states_atoms(&self, window: xlib::Window) -> Vec<xlib::Atom> {
505 let mut format_return: i32 = 0;
506 let mut nitems_return: c_ulong = 0;
507 let mut bytes_remaining: c_ulong = 0;
508 let mut type_return: xlib::Atom = 0;
509 let mut prop_return: *mut c_uchar = unsafe { std::mem::zeroed() };
510 unsafe {
511 let status = (self.xlib.XGetWindowProperty)(
512 self.display,
513 window,
514 self.atoms.NetWMState,
515 0,
516 MAX_PROPERTY_VALUE_LEN / 4,
517 xlib::False,
518 xlib::XA_ATOM,
519 &mut type_return,
520 &mut format_return,
521 &mut nitems_return,
522 &mut bytes_remaining,
523 &mut prop_return,
524 );
525 if status == i32::from(xlib::Success) && !prop_return.is_null() {
526 #[allow(clippy::cast_lossless, clippy::cast_ptr_alignment)]
527 let ptr = prop_return as *const c_ulong;
528 let results: &[xlib::Atom] = slice::from_raw_parts(ptr, nitems_return as usize);
529 return results.to_vec();
530 }
531 vec![]
532 }
533 }
534
535 #[must_use]
537 pub fn get_window_strut_array(&self, window: xlib::Window) -> Option<DockArea> {
538 if let Some(d) = self.get_window_strut_array_strut_partial(window) {
540 tracing::trace!("STRUT:[{:?}] {:?}", window, d);
541 return Some(d);
542 }
543 if let Some(d) = self.get_window_strut_array_strut(window) {
545 tracing::trace!("STRUT:[{:?}] {:?}", window, d);
546 return Some(d);
547 }
548 None
549 }
550
551 #[must_use]
553 pub fn get_window_type(&self, window: xlib::Window) -> WindowType {
554 let mut atom = None;
555 if let Ok((prop_return, _)) =
556 self.get_property(window, self.atoms.NetWMWindowType, xlib::XA_ATOM)
557 {
558 #[allow(clippy::cast_lossless, clippy::cast_ptr_alignment)]
559 let atom_ = unsafe { *prop_return.cast::<xlib::Atom>() };
560 atom = Some(atom_);
561 }
562 match atom {
563 x if x == Some(self.atoms.NetWMWindowTypeDesktop) => WindowType::Desktop,
564 x if x == Some(self.atoms.NetWMWindowTypeDock) => WindowType::Dock,
565 x if x == Some(self.atoms.NetWMWindowTypeToolbar) => WindowType::Toolbar,
566 x if x == Some(self.atoms.NetWMWindowTypeMenu) => WindowType::Menu,
567 x if x == Some(self.atoms.NetWMWindowTypeUtility) => WindowType::Utility,
568 x if x == Some(self.atoms.NetWMWindowTypeSplash) => WindowType::Splash,
569 x if x == Some(self.atoms.NetWMWindowTypeDialog) => WindowType::Dialog,
570 _ => WindowType::Normal,
571 }
572 }
573
574 #[must_use]
577 pub fn get_wmhints(&self, window: xlib::Window) -> Option<xlib::XWMHints> {
578 unsafe {
579 let hints_ptr: *const xlib::XWMHints = (self.xlib.XGetWMHints)(self.display, window);
580 if hints_ptr.is_null() {
581 return None;
582 }
583 let hints: xlib::XWMHints = *hints_ptr;
584 Some(hints)
585 }
586 }
587
588 #[must_use]
590 pub fn get_wm_state(&self, window: xlib::Window) -> Option<c_long> {
591 let (prop_return, nitems_return) = self
592 .get_property(window, self.atoms.WMState, self.atoms.WMState)
593 .ok()?;
594 if nitems_return == 0 {
595 return None;
596 }
597 #[allow(clippy::cast_ptr_alignment)]
598 Some(unsafe { *prop_return.cast::<c_long>() })
599 }
600
601 pub fn get_xatom_name(&self, atom: xlib::Atom) -> Result<String, XlibError> {
607 unsafe {
608 let cstring = (self.xlib.XGetAtomName)(self.display, atom);
609 if let Ok(s) = CString::from_raw(cstring).into_string() {
610 return Ok(s);
611 }
612 };
613 Err(XlibError::InvalidXAtom)
614 }
615
616 #[must_use]
621 fn get_hint_sizing(&self, window: xlib::Window) -> Option<xlib::XSizeHints> {
622 let mut xsize: xlib::XSizeHints = unsafe { std::mem::zeroed() };
623 let mut msize: c_long = xlib::PSize;
624 let status =
625 unsafe { (self.xlib.XGetWMNormalHints)(self.display, window, &mut xsize, &mut msize) };
626 match status {
627 0 => None,
628 _ => Some(xsize),
629 }
630 }
631
632 fn get_property(
638 &self,
639 window: xlib::Window,
640 property: xlib::Atom,
641 r#type: xlib::Atom,
642 ) -> Result<(*const c_uchar, c_ulong), XlibError> {
643 let mut format_return: i32 = 0;
644 let mut nitems_return: c_ulong = 0;
645 let mut type_return: xlib::Atom = 0;
646 let mut bytes_after_return: xlib::Atom = 0;
647 let mut prop_return: *mut c_uchar = unsafe { std::mem::zeroed() };
648 unsafe {
649 let status = (self.xlib.XGetWindowProperty)(
650 self.display,
651 window,
652 property,
653 0,
654 MAX_PROPERTY_VALUE_LEN / 4,
655 xlib::False,
656 r#type,
657 &mut type_return,
658 &mut format_return,
659 &mut nitems_return,
660 &mut bytes_after_return,
661 &mut prop_return,
662 );
663 if status == i32::from(xlib::Success) && !prop_return.is_null() {
664 return Ok((prop_return, nitems_return));
665 }
666 };
667 Err(XlibError::FailedStatus)
668 }
669
670 fn get_roots(&self) -> impl Iterator<Item = xlib::Window> + '_ {
673 self.get_xscreens()
674 .map(|mut s| unsafe { (self.xlib.XRootWindowOfScreen)(&mut s) })
675 }
676
677 fn get_text_prop(&self, window: xlib::Window, atom: xlib::Atom) -> Result<String, XlibError> {
685 unsafe {
686 let mut text_prop: xlib::XTextProperty = std::mem::zeroed();
687 let status: c_int =
688 (self.xlib.XGetTextProperty)(self.display, window, &mut text_prop, atom);
689 if status == 0 {
690 return Err(XlibError::FailedStatus);
691 }
692 if let Ok(s) = CString::from_raw(text_prop.value.cast::<c_char>()).into_string() {
693 return Ok(s);
694 }
695 };
696 Err(XlibError::FailedStatus)
697 }
698
699 fn get_windows_for_root<'w>(&self, root: xlib::Window) -> Result<&'w [xlib::Window], String> {
705 unsafe {
706 let mut root_return: xlib::Window = std::mem::zeroed();
707 let mut parent_return: xlib::Window = std::mem::zeroed();
708 let mut array: *mut xlib::Window = std::mem::zeroed();
709 let mut length: c_uint = std::mem::zeroed();
710 let status: xlib::Status = (self.xlib.XQueryTree)(
711 self.display,
712 root,
713 &mut root_return,
714 &mut parent_return,
715 &mut array,
716 &mut length,
717 );
718 let windows: &[xlib::Window] = slice::from_raw_parts(array, length as usize);
719 match status {
720 0 => { Err("Could not load list of windows".to_string() ) }
721 1 | 2 => { Ok(windows) }
722 _ => { Err("Unknown return status".to_string() ) }
723 }
724 }
725 }
726
727 fn get_window_strut_array_strut(&self, window: xlib::Window) -> Option<DockArea> {
729 let (prop_return, nitems_return) = self
730 .get_property(window, self.atoms.NetWMStrut, xlib::XA_CARDINAL)
731 .ok()?;
732 unsafe {
733 #[allow(clippy::cast_ptr_alignment)]
734 let array_ptr = prop_return.cast::<c_long>();
735 let slice = slice::from_raw_parts(array_ptr, nitems_return as usize);
736 if slice.len() == 12 {
737 return Some(SliceIntoDockArea(slice).into());
738 }
739 None
740 }
741 }
742
743 fn get_window_strut_array_strut_partial(&self, window: xlib::Window) -> Option<DockArea> {
745 let (prop_return, nitems_return) = self
746 .get_property(window, self.atoms.NetWMStrutPartial, xlib::XA_CARDINAL)
747 .ok()?;
748 unsafe {
749 #[allow(clippy::cast_ptr_alignment)]
750 let array_ptr = prop_return.cast::<c_long>();
751 let slice = slice::from_raw_parts(array_ptr, nitems_return as usize);
752 if slice.len() == 12 {
753 return Some(SliceIntoDockArea(slice).into());
754 }
755 None
756 }
757 }
758
759 fn get_xscreens(&self) -> impl Iterator<Item = xlib::Screen> + '_ {
763 let screen_count = unsafe { (self.xlib.XScreenCount)(self.display) };
764
765 let screen_ids = 0..screen_count;
766
767 screen_ids
768 .map(|screen_id| unsafe { *(self.xlib.XScreenOfDisplay)(self.display, screen_id) })
769 }
770}
771
772struct XRRCrtcInfoIntoScreen(XRRCrtcInfo);
773
774impl From<XRRCrtcInfoIntoScreen> for Screen<XlibWindowHandle> {
775 fn from(val: XRRCrtcInfoIntoScreen) -> Self {
776 Screen {
777 bbox: BBox {
778 x: val.0.x,
779 y: val.0.y,
780 width: val.0.width as i32,
781 height: val.0.height as i32,
782 },
783 ..Default::default()
784 }
785 }
786}
787
788struct XineramaScreenInfoIntoScreen<'a>(&'a XineramaScreenInfo);
789
790impl From<XineramaScreenInfoIntoScreen<'_>> for Screen<XlibWindowHandle> {
791 fn from(val: XineramaScreenInfoIntoScreen<'_>) -> Self {
792 Screen {
793 bbox: BBox {
794 height: val.0.height.into(),
795 width: val.0.width.into(),
796 x: val.0.x_org.into(),
797 y: val.0.y_org.into(),
798 },
799 ..Default::default()
800 }
801 }
802}
803
804struct XWindowAttributesIntoScreen<'a>(&'a XWindowAttributes);
805
806impl From<XWindowAttributesIntoScreen<'_>> for Screen<XlibWindowHandle> {
807 fn from(val: XWindowAttributesIntoScreen<'_>) -> Self {
808 Screen {
809 root: WindowHandle(XlibWindowHandle(val.0.root)),
810 bbox: BBox {
811 height: val.0.height,
812 width: val.0.width,
813 x: val.0.x,
814 y: val.0.y,
815 },
816 ..Default::default()
817 }
818 }
819}
820
821#[cfg(target_pointer_width = "64")]
822struct SliceIntoDockArea<'a>(&'a [i64]);
823
824#[cfg(target_pointer_width = "32")]
825struct SliceIntoDockArea<'a>(&'a [i32]);
826
827impl From<SliceIntoDockArea<'_>> for DockArea {
828 fn from(val: SliceIntoDockArea<'_>) -> Self {
829 DockArea {
830 left: val.0[0] as i32,
831 right: val.0[1] as i32,
832 top: val.0[2] as i32,
833 bottom: val.0[3] as i32,
834 left_start_y: val.0[4] as i32,
835 left_end_y: val.0[5] as i32,
836 right_start_y: val.0[6] as i32,
837 right_end_y: val.0[7] as i32,
838 top_start_x: val.0[8] as i32,
839 top_end_x: val.0[9] as i32,
840 bottom_start_x: val.0[10] as i32,
841 bottom_end_x: val.0[11] as i32,
842 }
843 }
844}