1use super::bindings;
2use super::core::{Point, Size};
3use super::host::*;
4use super::workspace::*;
5
6#[derive(Debug, Clone)]
7pub struct Output {
8 pub position: Point,
10 pub size: Size,
12 pub name: String,
14 pub is_primary: bool,
16 pub num_workspaces: u32,
18 internal: u64,
20}
21
22impl Output {
23 pub fn id(&self) -> u64 {
24 self.internal
25 }
26
27 pub fn from_c_with_name(value: &bindings::miracle_output_t, name: String) -> Self {
32 Self {
33 position: value.position.into(),
34 size: value.size.into(),
35 name,
36 is_primary: value.is_primary != 0,
37 num_workspaces: value.num_workspaces,
38 internal: value.internal,
39 }
40 }
41
42 pub fn workspaces(&self) -> Vec<Workspace> {
43 (0..self.num_workspaces)
44 .filter_map(|i| self.workspace(i))
45 .collect()
46 }
47
48 pub fn workspace(&self, index: u32) -> Option<Workspace> {
49 if index >= self.num_workspaces {
50 return None;
51 }
52
53 const NAME_BUF_LEN: usize = 256;
54 let mut workspace = std::mem::MaybeUninit::<crate::bindings::miracle_workspace_t>::uninit();
55 let mut name_buf: [u8; NAME_BUF_LEN] = [0; NAME_BUF_LEN];
56
57 unsafe {
58 let result = miracle_output_get_workspace(
59 self.internal as i64,
60 index,
61 workspace.as_mut_ptr() as i32,
62 name_buf.as_mut_ptr() as i32,
63 NAME_BUF_LEN as i32,
64 );
65
66 if result != 0 {
67 return None;
68 }
69
70 let workspace = workspace.assume_init();
71
72 let name_len = name_buf
74 .iter()
75 .position(|&c| c == 0)
76 .unwrap_or(NAME_BUF_LEN);
77 let name = String::from_utf8_lossy(&name_buf[..name_len]).into_owned();
78
79 Some(Workspace::from_c_with_name(&workspace, name))
80 }
81 }
82}