1
0
Fork 0
forked from wry/wry

config: split output handling

This commit is contained in:
kossLAN 2026-05-29 19:00:12 -04:00
parent 6393fdf3c0
commit 1d739ac4b6
No known key found for this signature in database
2 changed files with 500 additions and 474 deletions

View file

@ -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;

View 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(())
}
}