config: split output handling
This commit is contained in:
parent
6393fdf3c0
commit
1d739ac4b6
2 changed files with 500 additions and 474 deletions
|
|
@ -89,6 +89,7 @@ use {
|
|||
|
||||
mod dispatch;
|
||||
mod matchers;
|
||||
mod outputs;
|
||||
mod windows;
|
||||
|
||||
pub(super) struct ConfigProxyHandler {
|
||||
|
|
@ -319,79 +320,6 @@ impl ConfigProxyHandler {
|
|||
res
|
||||
}
|
||||
|
||||
fn handle_get_connectors(
|
||||
&self,
|
||||
dev: Option<DrmDevice>,
|
||||
connected_only: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let datas: Vec<_>;
|
||||
if let Some(dev) = dev {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
datas = dev.connectors.lock().values().cloned().collect();
|
||||
} else {
|
||||
datas = self.state.connectors.lock().values().cloned().collect();
|
||||
}
|
||||
let connectors = datas
|
||||
.iter()
|
||||
.flat_map(|d| match (connected_only, d.connected.get()) {
|
||||
(false, _) | (true, true) => Some(Connector(d.connector.id().raw() as _)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
self.respond(Response::GetConnectors { connectors });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_device_syspath(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let syspath = dev.syspath.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceSyspath { syspath });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_device_devnode(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let devnode = dev.devnode.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceDevnode { devnode });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_device_vendor(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let vendor = dev.vendor.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceVendor { vendor });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_devices(&self) {
|
||||
let devs = self.state.drm_devs.lock();
|
||||
let mut res = vec![];
|
||||
for dev in devs.values() {
|
||||
res.push(DrmDevice(dev.dev.id().raw() as _));
|
||||
}
|
||||
self.respond(Response::GetDrmDevices { devices: res });
|
||||
}
|
||||
|
||||
fn handle_make_render_device(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
dev.make_render_device();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_device_model(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let model = dev.model.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceModel { model });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_drm_device_pci_id(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let pci_id = dev.pci_id.unwrap_or_default();
|
||||
self.respond(Response::GetDrmDevicePciId { pci_id });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_reload(&self) {
|
||||
self.state.reload_config();
|
||||
}
|
||||
|
|
@ -1158,112 +1086,6 @@ impl ConfigProxyHandler {
|
|||
self.state.set_color_management_enabled(enabled);
|
||||
}
|
||||
|
||||
fn handle_connector_connected(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::ConnectorConnected {
|
||||
connected: connector.connected.get(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_type(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::ConnectorType {
|
||||
ty: connector.connector.kernel_id().ty.to_config(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_mode(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let mode = connector.global.mode.get();
|
||||
self.respond(Response::ConnectorMode {
|
||||
width: mode.width,
|
||||
height: mode.height,
|
||||
refresh_millihz: mode.refresh_rate_millihz,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_mode(
|
||||
&self,
|
||||
connector: Connector,
|
||||
mode: WireMode,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.mode = backend::Mode {
|
||||
width: mode.width,
|
||||
height: mode.height,
|
||||
refresh_rate_millihz: mode.refresh_millihz,
|
||||
};
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_modes(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorModes {
|
||||
modes: connector
|
||||
.global
|
||||
.modes
|
||||
.iter()
|
||||
.flatten()
|
||||
.map(|m| WireMode {
|
||||
width: m.width,
|
||||
height: m.height,
|
||||
refresh_millihz: m.refresh_rate_millihz,
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_supports_arbitrary_modes(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorSupportsArbitraryModes {
|
||||
supports_arbitrary_modes: connector.global.modes.is_none(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_name(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::GetConnectorName {
|
||||
name: connector.name.deref().clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_model(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorModel {
|
||||
model: connector.monitor_info.output_id.model.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_manufacturer(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorManufacturer {
|
||||
manufacturer: connector.monitor_info.output_id.manufacturer.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_serial_number(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorSerialNumber {
|
||||
serial_number: connector.monitor_info.output_id.serial_number.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_cursor_size(&self, seat: Seat, size: i32) -> Result<(), CphError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
if size < 0 {
|
||||
|
|
@ -1290,113 +1112,6 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_size(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let pos = connector.global.pos.get();
|
||||
self.respond(Response::ConnectorSize {
|
||||
width: pos.width(),
|
||||
height: pos.height(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorGetScale {
|
||||
scale: connector.global.persistent.scale.get().to_f64(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_scale(&self, connector: Connector, scale: f64) -> Result<(), CphError> {
|
||||
if scale < 0.1 {
|
||||
return Err(CphError::ScaleTooSmall(scale));
|
||||
}
|
||||
if scale > 1000.0 {
|
||||
return Err(CphError::ScaleTooLarge(scale));
|
||||
}
|
||||
let scale = Scale::from_f64(scale);
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_preferred_scale(scale);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_format(
|
||||
&self,
|
||||
connector: Connector,
|
||||
format: ConfigFormat,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(&format) = config_formats().get(&format) else {
|
||||
return Err(CphError::UnknownFormat(format));
|
||||
};
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| s.format = format)
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_colors(
|
||||
&self,
|
||||
connector: Connector,
|
||||
color_space: ColorSpace,
|
||||
eotf: ConfigEotf,
|
||||
) -> Result<(), CphError> {
|
||||
let bcs = match color_space {
|
||||
ColorSpace::DEFAULT => BackendColorSpace::Default,
|
||||
ColorSpace::BT2020 => BackendColorSpace::Bt2020,
|
||||
_ => return Err(CphError::UnknownColorSpace(color_space)),
|
||||
};
|
||||
let btf = match eotf {
|
||||
ConfigEotf::DEFAULT => BackendEotfs::Default,
|
||||
ConfigEotf::PQ => BackendEotfs::Pq,
|
||||
_ => return Err(CphError::UnknownEotf(eotf)),
|
||||
};
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.color_space = bcs;
|
||||
s.eotf = btf;
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_blend_space(
|
||||
&self,
|
||||
connector: Connector,
|
||||
blend_space: ConfigBlendSpace,
|
||||
) -> Result<(), CphError> {
|
||||
let blend_space = match blend_space {
|
||||
ConfigBlendSpace::SRGB => BlendSpace::Srgb,
|
||||
ConfigBlendSpace::LINEAR => BlendSpace::Linear,
|
||||
_ => return Err(CphError::UnknownBlendSpace(blend_space)),
|
||||
};
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_blend_space(blend_space);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_brightness(
|
||||
&self,
|
||||
connector: Connector,
|
||||
brightness: Option<f64>,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_brightness(brightness);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_use_native_gamut(
|
||||
&self,
|
||||
connector: Connector,
|
||||
use_native_gamut: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_use_native_gamut(use_native_gamut);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_float_above_fullscreen(&self, above: bool) {
|
||||
self.state.set_float_above_fullscreen(above);
|
||||
}
|
||||
|
|
@ -1499,194 +1214,6 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_vrr_mode(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
mode: ConfigVrrMode,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(mode) = VrrMode::from_config(mode) else {
|
||||
return Err(CphError::UnknownVrrMode(mode));
|
||||
};
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.set_vrr_mode(mode);
|
||||
}
|
||||
_ => self.state.default_vrr_mode.set(*mode),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_vrr_cursor_hz(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
hz: f64,
|
||||
) -> Result<(), CphError> {
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.schedule.set_cursor_hz(hz);
|
||||
}
|
||||
_ => {
|
||||
let Some((hz, _)) = map_cursor_hz(hz) else {
|
||||
return Err(CphError::InvalidCursorHz(hz));
|
||||
};
|
||||
self.state.default_vrr_cursor_hz.set(hz)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_set_tearing_mode(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
mode: ConfigTearingMode,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(mode) = TearingMode::from_config(mode) else {
|
||||
return Err(CphError::UnknownTearingMode(mode));
|
||||
};
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.set_tearing_mode(mode);
|
||||
}
|
||||
_ => self.state.default_tearing_mode.set(*mode),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_transform(
|
||||
&self,
|
||||
connector: Connector,
|
||||
transform: Transform,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.update_transform(transform.into());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_position(
|
||||
&self,
|
||||
connector: Connector,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
if x < 0 || y < 0 || x > MAX_EXTENTS || y > MAX_EXTENTS {
|
||||
return Err(CphError::InvalidConnectorPosition(x, y));
|
||||
}
|
||||
connector.set_position(x, y);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_get_position(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let (x, y) = connector.global.pos.get().position();
|
||||
self.respond(Response::ConnectorGetPosition { x, y });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_connector_set_enabled(
|
||||
&self,
|
||||
connector: Connector,
|
||||
enabled: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.enabled = enabled;
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector(
|
||||
&self,
|
||||
ty: jay_config::video::connector_type::ConnectorType,
|
||||
idx: u32,
|
||||
) -> Result<(), CphError> {
|
||||
let connectors = self.state.connectors.lock();
|
||||
let connector = 'get_connector: {
|
||||
for connector in connectors.values() {
|
||||
let kid = connector.connector.kernel_id();
|
||||
if ty == kid.ty.to_config() && idx == kid.idx {
|
||||
break 'get_connector Connector(connector.connector.id().raw() as _);
|
||||
}
|
||||
}
|
||||
Connector(0)
|
||||
};
|
||||
self.respond(Response::GetConnector { connector });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector_by_name(&self, name: &str) {
|
||||
let connector = self
|
||||
.state
|
||||
.connectors
|
||||
.lock()
|
||||
.values()
|
||||
.find(|c| *c.name == name)
|
||||
.map(|c| c.connector.id().raw() as _)
|
||||
.map(Connector)
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetConnector { connector });
|
||||
}
|
||||
|
||||
fn handle_create_virtual_output(&self, name: &str) {
|
||||
self.state.virtual_outputs.get_or_create(&self.state, name);
|
||||
}
|
||||
|
||||
fn handle_remove_virtual_output(&self, name: &str) {
|
||||
self.state.virtual_outputs.remove_output(&self.state, name);
|
||||
}
|
||||
|
||||
fn handle_get_connector_active_workspace(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspace = output
|
||||
.workspace
|
||||
.get()
|
||||
.map_or(Workspace(0), |ws| self.get_workspace_by_name(&ws.name));
|
||||
self.respond(Response::GetConnectorActiveWorkspace { workspace });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector_workspaces(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspaces = output
|
||||
.workspaces
|
||||
.iter()
|
||||
.map(|ws| self.get_workspace_by_name(&ws.name))
|
||||
.collect::<Vec<_>>();
|
||||
self.respond(Response::GetConnectorWorkspaces { workspaces });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_workspace_connector(&self, workspace: Workspace) -> Result<(), CphError> {
|
||||
let connector = self
|
||||
.get_existing_workspace(workspace)?
|
||||
.map(|ws| ws.output.get())
|
||||
.filter(|o| !o.is_dummy)
|
||||
.map(|o| Connector(o.global.connector.id.raw() as _))
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetWorkspaceConnector { connector });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_connector_in_direction(
|
||||
&self,
|
||||
connector: Connector,
|
||||
direction: Direction,
|
||||
) -> Result<(), CphError> {
|
||||
let source_output = self.get_output_node(connector)?;
|
||||
let connector = self
|
||||
.state
|
||||
.find_output_in_direction(&source_output, direction.into())
|
||||
.map(|o| Connector(o.global.connector.id.raw() as u64))
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetConnectorInDirection { connector });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_has_capability(&self, device: InputDevice, cap: Capability) -> Result<(), CphError> {
|
||||
let dev = self.get_device_handler_data(device)?;
|
||||
let mut is_unknown = false;
|
||||
|
|
|
|||
499
src/config/handler/outputs.rs
Normal file
499
src/config/handler/outputs.rs
Normal file
|
|
@ -0,0 +1,499 @@
|
|||
use super::*;
|
||||
|
||||
impl ConfigProxyHandler {
|
||||
pub(super) fn handle_get_connectors(
|
||||
&self,
|
||||
dev: Option<DrmDevice>,
|
||||
connected_only: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let datas: Vec<_>;
|
||||
if let Some(dev) = dev {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
datas = dev.connectors.lock().values().cloned().collect();
|
||||
} else {
|
||||
datas = self.state.connectors.lock().values().cloned().collect();
|
||||
}
|
||||
let connectors = datas
|
||||
.iter()
|
||||
.flat_map(|d| match (connected_only, d.connected.get()) {
|
||||
(false, _) | (true, true) => Some(Connector(d.connector.id().raw() as _)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
self.respond(Response::GetConnectors { connectors });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_device_syspath(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let syspath = dev.syspath.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceSyspath { syspath });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_device_devnode(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let devnode = dev.devnode.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceDevnode { devnode });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_device_vendor(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let vendor = dev.vendor.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceVendor { vendor });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_devices(&self) {
|
||||
let devs = self.state.drm_devs.lock();
|
||||
let mut res = vec![];
|
||||
for dev in devs.values() {
|
||||
res.push(DrmDevice(dev.dev.id().raw() as _));
|
||||
}
|
||||
self.respond(Response::GetDrmDevices { devices: res });
|
||||
}
|
||||
|
||||
pub(super) fn handle_make_render_device(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
dev.make_render_device();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_device_model(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let model = dev.model.clone().unwrap_or_default();
|
||||
self.respond(Response::GetDrmDeviceModel { model });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_drm_device_pci_id(&self, dev: DrmDevice) -> Result<(), CphError> {
|
||||
let dev = self.get_drm_device(dev)?;
|
||||
let pci_id = dev.pci_id.unwrap_or_default();
|
||||
self.respond(Response::GetDrmDevicePciId { pci_id });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_connected(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::ConnectorConnected {
|
||||
connected: connector.connected.get(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_type(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::ConnectorType {
|
||||
ty: connector.connector.kernel_id().ty.to_config(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_mode(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let mode = connector.global.mode.get();
|
||||
self.respond(Response::ConnectorMode {
|
||||
width: mode.width,
|
||||
height: mode.height,
|
||||
refresh_millihz: mode.refresh_rate_millihz,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_mode(
|
||||
&self,
|
||||
connector: Connector,
|
||||
mode: WireMode,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.mode = backend::Mode {
|
||||
width: mode.width,
|
||||
height: mode.height,
|
||||
refresh_rate_millihz: mode.refresh_millihz,
|
||||
};
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_modes(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorModes {
|
||||
modes: connector
|
||||
.global
|
||||
.modes
|
||||
.iter()
|
||||
.flatten()
|
||||
.map(|m| WireMode {
|
||||
width: m.width,
|
||||
height: m.height,
|
||||
refresh_millihz: m.refresh_rate_millihz,
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_supports_arbitrary_modes(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorSupportsArbitraryModes {
|
||||
supports_arbitrary_modes: connector.global.modes.is_none(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_name(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
self.respond(Response::GetConnectorName {
|
||||
name: connector.name.deref().clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_model(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorModel {
|
||||
model: connector.monitor_info.output_id.model.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_manufacturer(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorManufacturer {
|
||||
manufacturer: connector.monitor_info.output_id.manufacturer.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_serial_number(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output(connector)?;
|
||||
self.respond(Response::GetConnectorSerialNumber {
|
||||
serial_number: connector.monitor_info.output_id.serial_number.clone(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_size(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let pos = connector.global.pos.get();
|
||||
self.respond(Response::ConnectorSize {
|
||||
width: pos.width(),
|
||||
height: pos.height(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_get_scale(&self, connector: Connector) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
self.respond(Response::ConnectorGetScale {
|
||||
scale: connector.global.persistent.scale.get().to_f64(),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_scale(
|
||||
&self,
|
||||
connector: Connector,
|
||||
scale: f64,
|
||||
) -> Result<(), CphError> {
|
||||
if scale < 0.1 {
|
||||
return Err(CphError::ScaleTooSmall(scale));
|
||||
}
|
||||
if scale > 1000.0 {
|
||||
return Err(CphError::ScaleTooLarge(scale));
|
||||
}
|
||||
let scale = Scale::from_f64(scale);
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_preferred_scale(scale);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_format(
|
||||
&self,
|
||||
connector: Connector,
|
||||
format: ConfigFormat,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(&format) = config_formats().get(&format) else {
|
||||
return Err(CphError::UnknownFormat(format));
|
||||
};
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| s.format = format)
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_colors(
|
||||
&self,
|
||||
connector: Connector,
|
||||
color_space: ColorSpace,
|
||||
eotf: ConfigEotf,
|
||||
) -> Result<(), CphError> {
|
||||
let bcs = match color_space {
|
||||
ColorSpace::DEFAULT => BackendColorSpace::Default,
|
||||
ColorSpace::BT2020 => BackendColorSpace::Bt2020,
|
||||
_ => return Err(CphError::UnknownColorSpace(color_space)),
|
||||
};
|
||||
let btf = match eotf {
|
||||
ConfigEotf::DEFAULT => BackendEotfs::Default,
|
||||
ConfigEotf::PQ => BackendEotfs::Pq,
|
||||
_ => return Err(CphError::UnknownEotf(eotf)),
|
||||
};
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.color_space = bcs;
|
||||
s.eotf = btf;
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_blend_space(
|
||||
&self,
|
||||
connector: Connector,
|
||||
blend_space: ConfigBlendSpace,
|
||||
) -> Result<(), CphError> {
|
||||
let blend_space = match blend_space {
|
||||
ConfigBlendSpace::SRGB => BlendSpace::Srgb,
|
||||
ConfigBlendSpace::LINEAR => BlendSpace::Linear,
|
||||
_ => return Err(CphError::UnknownBlendSpace(blend_space)),
|
||||
};
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_blend_space(blend_space);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_brightness(
|
||||
&self,
|
||||
connector: Connector,
|
||||
brightness: Option<f64>,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_brightness(brightness);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_use_native_gamut(
|
||||
&self,
|
||||
connector: Connector,
|
||||
use_native_gamut: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.set_use_native_gamut(use_native_gamut);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_set_vrr_mode(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
mode: ConfigVrrMode,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(mode) = VrrMode::from_config(mode) else {
|
||||
return Err(CphError::UnknownVrrMode(mode));
|
||||
};
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.set_vrr_mode(mode);
|
||||
}
|
||||
_ => self.state.default_vrr_mode.set(*mode),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_set_vrr_cursor_hz(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
hz: f64,
|
||||
) -> Result<(), CphError> {
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.schedule.set_cursor_hz(hz);
|
||||
}
|
||||
_ => {
|
||||
let Some((hz, _)) = map_cursor_hz(hz) else {
|
||||
return Err(CphError::InvalidCursorHz(hz));
|
||||
};
|
||||
self.state.default_vrr_cursor_hz.set(hz)
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_set_tearing_mode(
|
||||
&self,
|
||||
connector: Option<Connector>,
|
||||
mode: ConfigTearingMode,
|
||||
) -> Result<(), CphError> {
|
||||
let Some(mode) = TearingMode::from_config(mode) else {
|
||||
return Err(CphError::UnknownTearingMode(mode));
|
||||
};
|
||||
match connector {
|
||||
Some(c) => {
|
||||
let connector = self.get_output_node(c)?;
|
||||
connector.set_tearing_mode(mode);
|
||||
}
|
||||
_ => self.state.default_tearing_mode.set(*mode),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_transform(
|
||||
&self,
|
||||
connector: Connector,
|
||||
transform: Transform,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
connector.update_transform(transform.into());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_position(
|
||||
&self,
|
||||
connector: Connector,
|
||||
x: i32,
|
||||
y: i32,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
if x < 0 || y < 0 || x > MAX_EXTENTS || y > MAX_EXTENTS {
|
||||
return Err(CphError::InvalidConnectorPosition(x, y));
|
||||
}
|
||||
connector.set_position(x, y);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_get_position(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_output_node(connector)?;
|
||||
let (x, y) = connector.global.pos.get().position();
|
||||
self.respond(Response::ConnectorGetPosition { x, y });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_connector_set_enabled(
|
||||
&self,
|
||||
connector: Connector,
|
||||
enabled: bool,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self.get_connector(connector)?;
|
||||
connector
|
||||
.modify_state(&self.state, |s| {
|
||||
s.enabled = enabled;
|
||||
})
|
||||
.map_err(CphError::ModifyConnectorState)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_connector(
|
||||
&self,
|
||||
ty: jay_config::video::connector_type::ConnectorType,
|
||||
idx: u32,
|
||||
) -> Result<(), CphError> {
|
||||
let connectors = self.state.connectors.lock();
|
||||
let connector = 'get_connector: {
|
||||
for connector in connectors.values() {
|
||||
let kid = connector.connector.kernel_id();
|
||||
if ty == kid.ty.to_config() && idx == kid.idx {
|
||||
break 'get_connector Connector(connector.connector.id().raw() as _);
|
||||
}
|
||||
}
|
||||
Connector(0)
|
||||
};
|
||||
self.respond(Response::GetConnector { connector });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_connector_by_name(&self, name: &str) {
|
||||
let connector = self
|
||||
.state
|
||||
.connectors
|
||||
.lock()
|
||||
.values()
|
||||
.find(|c| *c.name == name)
|
||||
.map(|c| c.connector.id().raw() as _)
|
||||
.map(Connector)
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetConnector { connector });
|
||||
}
|
||||
|
||||
pub(super) fn handle_create_virtual_output(&self, name: &str) {
|
||||
self.state.virtual_outputs.get_or_create(&self.state, name);
|
||||
}
|
||||
|
||||
pub(super) fn handle_remove_virtual_output(&self, name: &str) {
|
||||
self.state.virtual_outputs.remove_output(&self.state, name);
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_connector_active_workspace(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspace = output
|
||||
.workspace
|
||||
.get()
|
||||
.map_or(Workspace(0), |ws| self.get_workspace_by_name(&ws.name));
|
||||
self.respond(Response::GetConnectorActiveWorkspace { workspace });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_connector_workspaces(
|
||||
&self,
|
||||
connector: Connector,
|
||||
) -> Result<(), CphError> {
|
||||
let output = self.get_output_node(connector)?;
|
||||
let workspaces = output
|
||||
.workspaces
|
||||
.iter()
|
||||
.map(|ws| self.get_workspace_by_name(&ws.name))
|
||||
.collect::<Vec<_>>();
|
||||
self.respond(Response::GetConnectorWorkspaces { workspaces });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_workspace_connector(
|
||||
&self,
|
||||
workspace: Workspace,
|
||||
) -> Result<(), CphError> {
|
||||
let connector = self
|
||||
.get_existing_workspace(workspace)?
|
||||
.map(|ws| ws.output.get())
|
||||
.filter(|o| !o.is_dummy)
|
||||
.map(|o| Connector(o.global.connector.id.raw() as _))
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetWorkspaceConnector { connector });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn handle_get_connector_in_direction(
|
||||
&self,
|
||||
connector: Connector,
|
||||
direction: Direction,
|
||||
) -> Result<(), CphError> {
|
||||
let source_output = self.get_output_node(connector)?;
|
||||
let connector = self
|
||||
.state
|
||||
.find_output_in_direction(&source_output, direction.into())
|
||||
.map(|o| Connector(o.global.connector.id.raw() as u64))
|
||||
.unwrap_or(Connector(0));
|
||||
self.respond(Response::GetConnectorInDirection { connector });
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue