1
0
Fork 0
forked from wry/wry

metal: allow configuring color space and transfer function

This commit is contained in:
Julian Orth 2025-03-11 14:54:35 +01:00
parent 04f280aabe
commit bb56efb968
38 changed files with 1365 additions and 160 deletions

View file

@ -1,7 +1,10 @@
use {
crate::{
client::{Client, ClientError},
ifs::color_management::wp_image_description_v1::WpImageDescriptionV1,
ifs::{
color_management::{CAUSE_NO_OUTPUT, wp_image_description_v1::WpImageDescriptionV1},
wl_output::OutputGlobalOpt,
},
leaks::Tracker,
object::{Object, Version},
wire::{WpColorManagementOutputV1Id, wp_color_management_output_v1::*},
@ -15,20 +18,29 @@ pub struct WpColorManagementOutputV1 {
pub client: Rc<Client>,
pub version: Version,
pub tracker: Tracker<Self>,
pub output: Rc<OutputGlobalOpt>,
}
impl WpColorManagementOutputV1 {
#[expect(dead_code)]
pub fn send_image_description_changed(&self) {
self.client
.event(ImageDescriptionChanged { self_id: self.id });
}
fn detach(&self) {
if let Some(output) = self.output.get() {
output
.color_description_listeners
.remove(&(self.client.id, self.id));
}
}
}
impl WpColorManagementOutputV1RequestHandler for WpColorManagementOutputV1 {
type Error = WpColorManagementOutputV1Error;
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.detach();
self.client.remove_obj(self)?;
Ok(())
}
@ -43,11 +55,15 @@ impl WpColorManagementOutputV1RequestHandler for WpColorManagementOutputV1 {
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
description: self.client.state.color_manager.srgb_srgb().clone(),
description: self.output.get().map(|o| o.color_description.get()),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;
obj.send_ready();
if obj.description.is_some() {
obj.send_ready();
} else {
obj.send_failed(CAUSE_NO_OUTPUT, "the output no longer exists");
}
Ok(())
}
}
@ -57,7 +73,11 @@ object_base! {
version = self.version;
}
impl Object for WpColorManagementOutputV1 {}
impl Object for WpColorManagementOutputV1 {
fn break_loops(&self) {
self.detach();
}
}
simple_add_obj!(WpColorManagementOutputV1);

View file

@ -1,7 +1,10 @@
use {
crate::{
client::{Client, ClientError},
ifs::color_management::wp_image_description_v1::WpImageDescriptionV1,
cmm::cmm_description::ColorDescription,
ifs::{
color_management::wp_image_description_v1::WpImageDescriptionV1, wl_surface::WlSurface,
},
leaks::Tracker,
object::{Object, Version},
wire::{
@ -18,6 +21,7 @@ pub struct WpColorManagementSurfaceFeedbackV1 {
pub client: Rc<Client>,
pub version: Version,
pub tracker: Tracker<Self>,
pub surface: Rc<WlSurface>,
}
impl WpColorManagementSurfaceFeedbackV1 {
@ -30,13 +34,20 @@ impl WpColorManagementSurfaceFeedbackV1 {
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
description: self.client.state.color_manager.srgb_srgb().clone(),
description: Some(self.surface.get_output().global.color_description.get()),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;
obj.send_ready();
Ok(())
}
pub fn send_preferred_changed(&self, cd: &ColorDescription) {
self.client.event(PreferredChanged {
self_id: self.id,
identity: cd.id.raw(),
});
}
}
impl WpColorManagementSurfaceFeedbackV1RequestHandler for WpColorManagementSurfaceFeedbackV1 {
@ -44,6 +55,7 @@ impl WpColorManagementSurfaceFeedbackV1RequestHandler for WpColorManagementSurfa
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.client.remove_obj(self)?;
self.surface.remove_color_management_feedback(self);
Ok(())
}

View file

@ -147,15 +147,21 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
}
fn get_output(&self, req: GetOutput, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let _ = self.client.lookup(req.output)?;
let output = self.client.lookup(req.output)?;
let obj = Rc::new(WpColorManagementOutputV1 {
id: req.id,
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
output: output.global.clone(),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;
if let Some(global) = output.global.get() {
global
.color_description_listeners
.set((self.client.id, req.id), obj);
}
Ok(())
}
@ -179,15 +185,17 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
req: GetSurfaceFeedback,
_slf: &Rc<Self>,
) -> Result<(), Self::Error> {
let _ = self.client.lookup(req.surface)?;
let surface = self.client.lookup(req.surface)?;
let obj = Rc::new(WpColorManagementSurfaceFeedbackV1 {
id: req.id,
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
surface: surface.clone(),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;
surface.add_color_management_feedback(&obj);
Ok(())
}
@ -232,7 +240,7 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
description: self.client.state.color_manager.windows_scrgb().clone(),
description: Some(self.client.state.color_manager.windows_scrgb().clone()),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;

View file

@ -91,7 +91,7 @@ impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreat
client: self.client.clone(),
version: self.version,
tracker: Default::default(),
description,
description: Some(description),
});
track!(self.client, obj);
self.client.add_client_obj(&obj)?;

View file

@ -16,11 +16,10 @@ pub struct WpImageDescriptionV1 {
pub client: Rc<Client>,
pub version: Version,
pub tracker: Tracker<Self>,
pub description: Rc<ColorDescription>,
pub description: Option<Rc<ColorDescription>>,
}
impl WpImageDescriptionV1 {
#[expect(dead_code)]
pub fn send_failed(&self, cause: u32, msg: &str) {
self.client.event(Failed {
self_id: self.id,
@ -32,7 +31,7 @@ impl WpImageDescriptionV1 {
pub fn send_ready(&self) {
self.client.event(Ready {
self_id: self.id,
identity: self.description.id.into(),
identity: self.description.as_ref().unwrap().id.raw(),
});
}
}
@ -46,6 +45,9 @@ impl WpImageDescriptionV1RequestHandler for WpImageDescriptionV1 {
}
fn get_information(&self, req: GetInformation, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let Some(desc) = &self.description else {
return Err(WpImageDescriptionV1Error::NotReady);
};
let obj = Rc::new(WpImageDescriptionInfoV1 {
id: req.information,
client: self.client.clone(),
@ -54,7 +56,7 @@ impl WpImageDescriptionV1RequestHandler for WpImageDescriptionV1 {
});
self.client.add_client_obj(&obj)?;
track!(self.client, obj);
obj.send_description(self.client.state.color_manager.srgb_srgb());
obj.send_description(desc);
self.client.remove_obj(&*obj)?;
Ok(())
}
@ -77,5 +79,7 @@ dedicated_add_obj!(
pub enum WpImageDescriptionV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
#[error("The description is not ready")]
NotReady,
}
efrom!(WpImageDescriptionV1Error, ClientError);