mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-14 08:01:14 +01:00
Add most of the output stuff
This commit is contained in:
parent
2c3fb2dbd7
commit
c62d090f9f
2 changed files with 117 additions and 0 deletions
|
@ -1,5 +1,6 @@
|
||||||
mod input;
|
mod input;
|
||||||
mod msg;
|
mod msg;
|
||||||
|
mod output;
|
||||||
mod process;
|
mod process;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
|
@ -7,6 +8,7 @@ use input::Input;
|
||||||
pub use input::MouseButton;
|
pub use input::MouseButton;
|
||||||
pub use msg::Modifier;
|
pub use msg::Modifier;
|
||||||
pub use msg::MouseEdge;
|
pub use msg::MouseEdge;
|
||||||
|
use output::Output;
|
||||||
use window::Window;
|
use window::Window;
|
||||||
pub use xkbcommon::xkb::keysyms;
|
pub use xkbcommon::xkb::keysyms;
|
||||||
pub use xkbcommon::xkb::Keysym;
|
pub use xkbcommon::xkb::Keysym;
|
||||||
|
@ -46,6 +48,7 @@ pub fn setup(config_func: impl FnOnce(Pinnacle)) -> anyhow::Result<()> {
|
||||||
process: Process,
|
process: Process,
|
||||||
input: Input,
|
input: Input,
|
||||||
window: Window,
|
window: Window,
|
||||||
|
output: Output,
|
||||||
};
|
};
|
||||||
|
|
||||||
config_func(pinnacle);
|
config_func(pinnacle);
|
||||||
|
@ -170,4 +173,5 @@ pub struct Pinnacle {
|
||||||
pub process: Process,
|
pub process: Process,
|
||||||
pub window: Window,
|
pub window: Window,
|
||||||
pub input: Input,
|
pub input: Input,
|
||||||
|
pub output: Output,
|
||||||
}
|
}
|
||||||
|
|
113
api/rust/src/output.rs
Normal file
113
api/rust/src/output.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
use crate::{
|
||||||
|
msg::{OutputName, Request, RequestResponse},
|
||||||
|
request,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Output management.
|
||||||
|
pub struct Output;
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
/// Get an [`OutputHandle`] by its name.
|
||||||
|
///
|
||||||
|
/// `name` is the name of the port the output is plugged in to.
|
||||||
|
/// This is something like `HDMI-1` or `eDP-0`.
|
||||||
|
pub fn get_by_name(&self, name: &str) -> Option<OutputHandle> {
|
||||||
|
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
output_names
|
||||||
|
.into_iter()
|
||||||
|
.find(|s| s == name)
|
||||||
|
.map(|s| OutputHandle(OutputName(s)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a handle to all connected outputs.
|
||||||
|
pub fn get_all(&self) -> impl Iterator<Item = OutputHandle> {
|
||||||
|
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
output_names
|
||||||
|
.into_iter()
|
||||||
|
.map(|name| OutputHandle(OutputName(name)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the currently focused output.
|
||||||
|
///
|
||||||
|
/// This is currently defined as the one with the cursor on it.
|
||||||
|
pub fn get_focused(&self) -> Option<OutputHandle> {
|
||||||
|
let RequestResponse::Outputs { output_names } = request(Request::GetOutputs) else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
output_names
|
||||||
|
.into_iter()
|
||||||
|
.map(|s| OutputHandle(OutputName(s)))
|
||||||
|
.find(|op| op.properties().focused == Some(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An output handle.
|
||||||
|
///
|
||||||
|
/// This is a handle to one of your monitors.
|
||||||
|
/// It serves to make it easier to deal with them, defining methods for getting properties and
|
||||||
|
/// helpers for things like positioning multiple monitors.
|
||||||
|
pub struct OutputHandle(OutputName);
|
||||||
|
|
||||||
|
/// Properties of an output.
|
||||||
|
pub struct OutputProperties {
|
||||||
|
/// The make.
|
||||||
|
make: Option<String>,
|
||||||
|
/// The model.
|
||||||
|
///
|
||||||
|
/// This is something like `27GL850` or whatever gibberish monitor manufacturers name their
|
||||||
|
/// displays.
|
||||||
|
model: Option<String>,
|
||||||
|
/// The location of the output in the global space.
|
||||||
|
loc: Option<(i32, i32)>,
|
||||||
|
/// The resolution of the output in pixels, where `res.0` is the width and `res.1` is the
|
||||||
|
/// height.
|
||||||
|
res: Option<(i32, i32)>,
|
||||||
|
/// The refresh rate of the output in millihertz.
|
||||||
|
///
|
||||||
|
/// For example, 60Hz is returned as 60000.
|
||||||
|
refresh_rate: Option<i32>,
|
||||||
|
/// The physical size of the output in millimeters.
|
||||||
|
physical_size: Option<(i32, i32)>,
|
||||||
|
/// Whether or not the output is focused.
|
||||||
|
focused: Option<bool>,
|
||||||
|
// TODO: tags
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputHandle {
|
||||||
|
// TODO: Make OutputProperties an option, make non null fields not options
|
||||||
|
/// Get all properties of this output.
|
||||||
|
pub fn properties(&self) -> OutputProperties {
|
||||||
|
let RequestResponse::OutputProps {
|
||||||
|
make,
|
||||||
|
model,
|
||||||
|
loc,
|
||||||
|
res,
|
||||||
|
refresh_rate,
|
||||||
|
physical_size,
|
||||||
|
focused,
|
||||||
|
tag_ids,
|
||||||
|
} = request(Request::GetOutputProps {
|
||||||
|
output_name: self.0 .0.clone(),
|
||||||
|
})
|
||||||
|
else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
OutputProperties {
|
||||||
|
make,
|
||||||
|
model,
|
||||||
|
loc,
|
||||||
|
res,
|
||||||
|
refresh_rate,
|
||||||
|
physical_size,
|
||||||
|
focused,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue