From 558bea47b7da15a6e7d017a9b4388390962fd862 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 4 Mar 2024 16:09:53 +0100 Subject: [PATCH] config: allow retrieving the modes --- jay-config/src/_private.rs | 24 +++++++++++++++++++++++- jay-config/src/_private/client.rs | 8 +++++++- jay-config/src/_private/ipc.rs | 7 +++++++ jay-config/src/video.rs | 10 +++++++++- src/compositor.rs | 1 + src/config/handler.rs | 22 ++++++++++++++++++++++ src/ifs/wl_output.rs | 3 +++ src/tasks/connector.rs | 1 + 8 files changed, 73 insertions(+), 3 deletions(-) diff --git a/jay-config/src/_private.rs b/jay-config/src/_private.rs index d85d10c5..7e7da600 100644 --- a/jay-config/src/_private.rs +++ b/jay-config/src/_private.rs @@ -2,7 +2,12 @@ pub mod client; pub mod ipc; mod logging; -use {bincode::Options, std::marker::PhantomData}; +use { + crate::video::Mode, + bincode::Options, + serde::{Deserialize, Serialize}, + std::marker::PhantomData, +}; pub const VERSION: u32 = 1; @@ -36,3 +41,20 @@ pub fn bincode_ops() -> impl Options { pub trait Config { extern "C" fn configure(); } + +#[derive(Serialize, Deserialize, Debug)] +pub struct WireMode { + pub width: i32, + pub height: i32, + pub refresh_millihz: u32, +} + +impl WireMode { + pub fn to_mode(self) -> Mode { + Mode { + width: self.width, + height: self.height, + refresh_millihz: self.refresh_millihz, + } + } +} diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index bf120466..749ad37f 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -5,7 +5,7 @@ use { _private::{ bincode_ops, ipc::{ClientMessage, InitMessage, Response, ServerMessage}, - logging, Config, ConfigEntry, ConfigEntryGen, VERSION, + logging, Config, ConfigEntry, ConfigEntryGen, WireMode, VERSION, }, exec::Command, input::{acceleration::AccelProfile, capability::Capability, InputDevice, Seat}, @@ -570,6 +570,12 @@ impl Client { } } + pub fn connector_modes(&self, connector: Connector) -> Vec { + let res = self.send_with_response(&ClientMessage::ConnectorModes { connector }); + get_response!(res, Vec::new(), ConnectorModes { modes }); + modes.into_iter().map(WireMode::to_mode).collect() + } + pub fn connector_size(&self, connector: Connector) -> (i32, i32) { let res = self.send_with_response(&ClientMessage::ConnectorSize { connector }); get_response!(res, (0, 0), ConnectorSize { width, height }); diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 779288cb..02e3e65c 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -7,6 +7,7 @@ use { timer::Timer, video::{connector_type::ConnectorType, Connector, DrmDevice, GfxApi, Transform}, Axis, Direction, PciId, Workspace, + _private::WireMode, }, serde::{Deserialize, Serialize}, std::time::Duration, @@ -352,6 +353,9 @@ pub enum ClientMessage<'a> { SetDoubleClickDistance { dist: i32, }, + ConnectorModes { + connector: Connector, + }, } #[derive(Serialize, Deserialize, Debug)] @@ -454,6 +458,9 @@ pub enum Response { GetWorkspaceCapture { capture: bool, }, + ConnectorModes { + modes: Vec, + }, } #[derive(Serialize, Deserialize, Debug)] diff --git a/jay-config/src/video.rs b/jay-config/src/video.rs index 92c4248e..cb4da383 100644 --- a/jay-config/src/video.rs +++ b/jay-config/src/video.rs @@ -21,7 +21,7 @@ use { /// - width in pixels /// - height in pixels /// - refresh rate in mhz. -#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq)] pub struct Mode { pub(crate) width: i32, pub(crate) height: i32, @@ -112,6 +112,14 @@ impl Connector { get!(Mode::zeroed()).connector_mode(self) } + /// Returns the available modes of the connector. + pub fn modes(self) -> Vec { + if !self.exists() { + return Vec::new(); + } + get!(Vec::new()).connector_modes(self) + } + /// Returns the logical width of the connector. /// /// The returned value will be different from `mode().width()` if the scale is not 1. diff --git a/src/compositor.rs b/src/compositor.rs index d65b81c4..dc3681a4 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -375,6 +375,7 @@ fn create_dummy_output(state: &Rc) { async_event: Default::default(), }), 0, + Vec::new(), &backend::Mode { width: 0, height: 0, diff --git a/src/config/handler.rs b/src/config/handler.rs index 168e5786..a1612c2b 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -27,6 +27,7 @@ use { _private::{ bincode_ops, ipc::{ClientMessage, Response, ServerMessage}, + WireMode, }, input::{ acceleration::{AccelProfile, ACCEL_PROFILE_ADAPTIVE, ACCEL_PROFILE_FLAT}, @@ -694,6 +695,24 @@ impl ConfigProxyHandler { Ok(()) } + fn handle_connector_modes(&self, connector: Connector) -> Result<(), CphError> { + let connector = self.get_output(connector)?; + self.respond(Response::ConnectorModes { + modes: connector + .node + .global + .modes + .iter() + .map(|m| WireMode { + width: m.width, + height: m.height, + refresh_millihz: m.refresh_rate_millihz, + }) + .collect(), + }); + Ok(()) + } + fn handle_set_cursor_size(&self, seat: Seat, size: i32) -> Result<(), CphError> { let seat = self.get_seat(seat)?; if size < 0 { @@ -1369,6 +1388,9 @@ impl ConfigProxyHandler { ClientMessage::SetDoubleClickDistance { dist } => { self.handle_set_double_click_distance(dist) } + ClientMessage::ConnectorModes { connector } => self + .handle_connector_modes(connector) + .wrn("connector_modes")?, } Ok(()) } diff --git a/src/ifs/wl_output.rs b/src/ifs/wl_output.rs index dbe8a9e8..d93f3b50 100644 --- a/src/ifs/wl_output.rs +++ b/src/ifs/wl_output.rs @@ -66,6 +66,7 @@ pub struct WlOutputGlobal { pub pos: Cell, pub output_id: Rc, pub mode: Cell, + pub modes: Vec, pub node: CloneCell>>, pub width_mm: i32, pub height_mm: i32, @@ -96,6 +97,7 @@ impl WlOutputGlobal { state: &Rc, connector: &Rc, x1: i32, + modes: Vec, mode: &backend::Mode, manufacturer: &str, product: &str, @@ -122,6 +124,7 @@ impl WlOutputGlobal { pos: Cell::new(Rect::new_sized(x1, 0, width, height).unwrap()), output_id, mode: Cell::new(*mode), + modes, node: Default::default(), width_mm, height_mm, diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index c0bbc22f..5c1df848 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -94,6 +94,7 @@ impl ConnectorHandler { &self.state, &self.data, x1, + info.modes.clone(), &info.initial_mode, &info.manufacturer, &info.product,