use { crate::{ backend::{ BackendConnectorState, BackendDrmDevice, Connector, ConnectorId, MonitorInfo, transaction::BackendConnectorTransactionError, }, ifs::{ head_management::HeadManagers, wlr_output_manager::{ zwlr_output_head_v1::ZwlrOutputHeadV1, zwlr_output_manager_v1::WlrOutputManagerId, }, wp_drm_lease_connector_v1::WpDrmLeaseConnectorV1, wp_drm_lease_device_v1::WpDrmLeaseDeviceV1Global, }, rect::Rect, tree::OutputNode, utils::{ asyncevent::AsyncEvent, bindings::Bindings, copyhashmap::CopyHashMap, }, }, jay_config::PciId, std::{ cell::{Cell, RefCell}, rc::Rc, }, }; use super::State; pub struct ConnectorData { pub id: ConnectorId, pub connector: Rc, pub handler: Cell>>, pub connected: Cell, pub name: Rc, pub description: RefCell, pub drm_dev: Option>, pub async_event: Rc, pub damaged: Cell, pub damage: RefCell>, pub needs_vblank_emulation: Cell, pub damage_intersect: Cell, pub state: RefCell, pub head_managers: HeadManagers, pub wlr_output_heads: CopyHashMap>, } pub struct OutputData { pub connector: Rc, pub monitor_info: Rc, pub node: Option>, pub lease_connectors: Rc>, } pub struct DrmDevData { pub dev: Rc, pub handler: Cell>>, pub connectors: CopyHashMap>, pub syspath: Option, pub devnode: Option, pub vendor: Option, pub model: Option, pub pci_id: Option, pub lease_global: Rc, } impl ConnectorData { pub fn damage(&self) { if !self.damaged.replace(true) { self.connector.damage(); } } pub fn modify_state( &self, state: &State, f: impl FnOnce(&mut BackendConnectorState), ) -> Result<(), BackendConnectorTransactionError> { let old = self.state.borrow().clone(); let mut s = old.clone(); f(&mut s); if old == s { return Ok(()); } s.serial = state.backend_connector_state_serials.next(); let mut tran = self.connector.create_transaction()?; tran.add(&self.connector, s.clone())?; tran.prepare()?.apply()?.commit(); self.set_state(state, s); Ok(()) } pub fn set_state(&self, state: &State, s: BackendConnectorState) { let old = self.state.borrow().clone(); if old.serial >= s.serial { return; } *self.state.borrow_mut() = s.clone(); if old.enabled != s.enabled { self.head_managers.handle_enabled_change(state, s.enabled); } if old.active != s.active { self.head_managers.handle_active_change(s.active); } if old.non_desktop_override != s.non_desktop_override { self.head_managers .handle_non_desktop_override_changed(s.non_desktop_override); } if old.vrr != s.vrr { self.head_managers.handle_vrr_change(s.vrr); } if old.tearing != s.tearing { self.head_managers.handle_tearing_enabled_change(s.tearing); } if old.format != s.format { self.head_managers.handle_format_change(s.format); } if (old.color_space, old.eotf) != (s.color_space, s.eotf) { self.head_managers .handle_colors_change(s.color_space, s.eotf); } if old.mode != s.mode { self.head_managers.handle_mode_change(s.mode); for head in self.wlr_output_heads.lock().values() { head.handle_mode_change(s.mode); } } if let Some(output) = state.outputs.get(&self.connector.id()) && let Some(node) = &output.node { node.update_state(old, s); } } } impl DrmDevData { pub fn make_render_device(&self) { log::info!( "Making {} the render device", self.devnode.as_deref().unwrap_or("unknown"), ); self.dev.clone().make_render_device(); } pub fn set_direct_scanout_enabled(&self, _state: &State, enabled: bool) { self.dev.set_direct_scanout_enabled(enabled); } pub fn set_flip_margin(&self, _state: &State, margin: u64) { self.dev.set_flip_margin(margin); } }