From 30aa6de35c19dd671602a683cfd66ef186432373 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 26 Jul 2022 21:52:52 +0200 Subject: [PATCH] config: add Connector::set_enabled --- jay-config/src/_private/client.rs | 4 ++++ jay-config/src/_private/ipc.rs | 4 ++++ jay-config/src/video.rs | 11 +++++++++++ src/backend.rs | 1 + src/backends/dummy.rs | 4 ++++ src/backends/metal/video.rs | 24 ++++++++++++++++++++---- src/backends/x.rs | 4 ++++ src/config/handler.rs | 13 +++++++++++++ 8 files changed, 61 insertions(+), 4 deletions(-) diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index cbf40c1d..21190d19 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -440,6 +440,10 @@ impl Client { self.send(&ClientMessage::ConnectorSetPosition { connector, x, y }); } + pub fn connector_set_enabled(&self, connector: Connector, enabled: bool) { + self.send(&ClientMessage::ConnectorSetEnabled { connector, enabled }); + } + pub fn device_connectors(&self, device: DrmDevice) -> Vec { let res = self.send_with_response(&ClientMessage::GetDeviceConnectors { device }); get_response!(res, vec![], GetDeviceConnectors { connectors }); diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 5c2de064..60f66396 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -308,6 +308,10 @@ pub enum ClientMessage<'a> { DisablePointerConstraint { seat: Seat, }, + ConnectorSetEnabled { + connector: Connector, + enabled: bool, + }, } #[derive(Encode, Decode, Debug)] diff --git a/jay-config/src/video.rs b/jay-config/src/video.rs index c0647440..25076f61 100644 --- a/jay-config/src/video.rs +++ b/jay-config/src/video.rs @@ -147,6 +147,17 @@ impl Connector { } get!().connector_set_position(self, x, y); } + + /// Enables or disables the connector. + /// + /// By default, all connectors are enabled. + pub fn set_enabled(self, enabled: bool) { + if !self.exists() { + log::warn!("set_enabled called on a connector that does not exist"); + return; + } + get!().connector_set_enabled(self, enabled); + } } /// Returns all available DRM devices. diff --git a/src/backend.rs b/src/backend.rs index 546597a0..dab3c2de 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -81,6 +81,7 @@ pub trait Connector { fn on_change(&self, cb: Rc); fn damage(&self); fn drm_dev(&self) -> Option; + fn set_enabled(&self, enabled: bool); } #[derive(Debug)] diff --git a/src/backends/dummy.rs b/src/backends/dummy.rs index ace3dbfa..542b8e90 100644 --- a/src/backends/dummy.rs +++ b/src/backends/dummy.rs @@ -52,4 +52,8 @@ impl Connector for DummyOutput { fn drm_dev(&self) -> Option { None } + + fn set_enabled(&self, _enabled: bool) { + // nothing + } } diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index b5c271ec..f3c80e07 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -153,6 +153,8 @@ pub struct MetalConnector { pub buffers: CloneCell>>, pub next_buffer: NumCell, + pub enabled: Cell, + pub can_present: Cell, pub has_damage: Cell, pub cursor_changed: Cell, @@ -300,7 +302,7 @@ impl MetalConnector { fn connected(&self) -> bool { let dd = self.display.borrow_mut(); - dd.connection == ConnectorStatus::Connected && self.primary_plane.get().is_some() + self.enabled.get() && dd.connection == ConnectorStatus::Connected && self.primary_plane.get().is_some() } fn send_event(&self, event: ConnectorEvent) { @@ -434,6 +436,19 @@ impl Connector for MetalConnector { fn drm_dev(&self) -> Option { Some(self.dev.id) } + + fn set_enabled(&self, enabled: bool) { + if self.enabled.replace(enabled) != enabled { + if self.display.borrow_mut().connection == ConnectorStatus::Connected { + if let Some(dev) = self.backend.device_holder.drm_devices.get(&self.dev.devnum) { + if let Err(e) = self.backend.handle_drm_change_(&dev, true) { + dev.unprocessed_change.set(true); + log::error!("Could not dis/enable connector: {}", ErrorFmt(e)); + } + } + } + } + } } #[derive(Debug)] @@ -533,6 +548,7 @@ fn create_connector( events: Default::default(), buffers: Default::default(), next_buffer: Default::default(), + enabled: Cell::new(true), can_present: Cell::new(true), has_damage: Cell::new(true), primary_plane: Default::default(), @@ -959,7 +975,7 @@ impl MetalBackend { let mut old = c.display.borrow_mut(); mem::swap(old.deref_mut(), &mut dd); if c.connect_sent.get() { - if old.connection != ConnectorStatus::Connected || !old.is_same_monitor(&dd) { + if !c.enabled.get() || old.connection != ConnectorStatus::Connected || !old.is_same_monitor(&dd) { c.send_event(ConnectorEvent::Disconnected); c.connect_sent.set(false); } else if preserve_any { @@ -1451,7 +1467,7 @@ impl MetalBackend { for connector in dev.connectors.lock().values() { let dd = connector.display.borrow_mut(); - if dd.connection != ConnectorStatus::Connected { + if !connector.enabled.get() || dd.connection != ConnectorStatus::Connected { if dd.crtc_id.value.get().is_some() { log::debug!("Connector is not connected but has an assigned crtc"); return false; @@ -1586,7 +1602,7 @@ impl MetalBackend { changes: &mut Change, ) -> Result<(), MetalError> { let dd = connector.display.borrow_mut(); - if dd.connection != ConnectorStatus::Connected { + if !connector.enabled.get() || dd.connection != ConnectorStatus::Connected { return Ok(()); } let crtc = 'crtc: { diff --git a/src/backends/x.rs b/src/backends/x.rs index a1085620..4a600f79 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -968,6 +968,10 @@ impl Connector for XOutput { fn drm_dev(&self) -> Option { None } + + fn set_enabled(&self, _enabled: bool) { + // nothing + } } struct XSeat { diff --git a/src/config/handler.rs b/src/config/handler.rs index 5f8f73f2..159fec80 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -686,6 +686,16 @@ impl ConfigProxyHandler { Ok(()) } + fn handle_connector_set_enabled( + &self, + connector: Connector, + enabled: bool, + ) -> Result<(), CphError> { + let connector = self.get_connector(connector)?; + connector.connector.set_enabled(enabled); + Ok(()) + } + fn handle_get_connector( &self, ty: jay_config::video::connector_type::ConnectorType, @@ -1125,6 +1135,9 @@ impl ConfigProxyHandler { ClientMessage::ConnectorSetPosition { connector, x, y } => self .handle_connector_set_position(connector, x, y) .wrn("connector_set_position")?, + ClientMessage::ConnectorSetEnabled { connector, enabled } => self + .handle_connector_set_enabled(connector, enabled) + .wrn("connector_set_enabled")?, ClientMessage::Close { seat } => self.handle_close(seat).wrn("close")?, ClientMessage::SetStatus { status } => self.handle_set_status(status), ClientMessage::GetTimer { name } => self.handle_get_timer(name).wrn("get_timer")?,