1
0
Fork 0
forked from wry/wry

Merge pull request #749 from mahkoh/jorth/color-representation

color-representation-v1: initial implementation
This commit is contained in:
mahkoh 2026-02-21 12:06:14 +01:00 committed by GitHub
commit c6db02a43d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 282 additions and 0 deletions

View file

@ -176,6 +176,7 @@ Jay supports the following wayland protocols:
| wl_subcompositor | 1 | |
| wp_alpha_modifier_v1 | 1 | |
| wp_color_manager_v1 | 2 | |
| wp_color_representation_manager_v1 | 1 | |
| wp_commit_timing_manager_v1 | 1 | |
| wp_content_type_manager_v1 | 1 | |
| wp_cursor_shape_manager_v1 | 2 | |

View file

@ -47,6 +47,7 @@ use {
wlr_output_manager::zwlr_output_manager_v1::ZwlrOutputManagerV1Global,
workspace_manager::ext_workspace_manager_v1::ExtWorkspaceManagerV1Global,
wp_alpha_modifier_v1::WpAlphaModifierV1Global,
wp_color_representation_manager_v1::WpColorRepresentationManagerV1Global,
wp_commit_timing_manager_v1::WpCommitTimingManagerV1Global,
wp_content_type_manager_v1::WpContentTypeManagerV1Global,
wp_cursor_shape_manager_v1::WpCursorShapeManagerV1Global,
@ -235,6 +236,7 @@ impl Globals {
add_singleton!(WpPointerWarpV1Global);
add_singleton!(JayPopupExtManagerV1Global);
add_singleton!(ZwlrGammaControlManagerV1Global);
add_singleton!(WpColorRepresentationManagerV1Global);
}
pub fn add_backend_singletons(&self, backend: &Rc<dyn Backend>) {

View file

@ -56,6 +56,7 @@ pub mod wl_surface;
pub mod wlr_output_manager;
pub mod workspace_manager;
pub mod wp_alpha_modifier_v1;
pub mod wp_color_representation_manager_v1;
pub mod wp_commit_timing_manager_v1;
pub mod wp_content_type_manager_v1;
pub mod wp_content_type_v1;

View file

@ -6,6 +6,7 @@ pub mod tray;
pub mod wl_subsurface;
pub mod wp_alpha_modifier_surface_v1;
pub mod wp_color_management_surface_v1;
pub mod wp_color_representation_surface_v1;
pub mod wp_commit_timer_v1;
pub mod wp_fifo_v1;
pub mod wp_fractional_scale_v1;
@ -54,6 +55,7 @@ use {
tray::TrayItemId,
wl_subsurface::{PendingSubsurfaceData, SubsurfaceId, WlSubsurface},
wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1,
wp_color_representation_surface_v1::WpColorRepresentationSurfaceV1,
wp_commit_timer_v1::WpCommitTimerV1,
wp_fifo_v1::WpFifoV1,
wp_fractional_scale_v1::WpFractionalScaleV1,
@ -350,6 +352,7 @@ pub struct WlSurface {
color_management_feedback:
CopyHashMap<WpColorManagementSurfaceFeedbackV1Id, Rc<WpColorManagementSurfaceFeedbackV1>>,
color_description: CloneCell<Option<Rc<ColorDescription>>>,
color_representation_surface: CloneCell<Option<Rc<WpColorRepresentationSurfaceV1>>>,
}
impl Debug for WlSurface {
@ -704,6 +707,7 @@ impl WlSurface {
color_management_surface: Default::default(),
color_management_feedback: Default::default(),
color_description: Default::default(),
color_representation_surface: Default::default(),
}
}
@ -1786,6 +1790,7 @@ impl Object for WlSurface {
self.commit_timer.take();
self.color_management_surface.take();
self.color_management_feedback.clear();
self.color_representation_surface.take();
}
}

View file

@ -0,0 +1,105 @@
use {
crate::{
client::{Client, ClientError},
ifs::wl_surface::WlSurface,
leaks::Tracker,
object::{Object, Version},
wire::{
WpColorRepresentationSurfaceV1Id,
wp_color_representation_surface_v1::{
Destroy, SetAlphaMode, SetChromaLocation, SetCoefficientsAndRange,
WpColorRepresentationSurfaceV1RequestHandler,
},
},
},
std::rc::Rc,
thiserror::Error,
};
pub struct WpColorRepresentationSurfaceV1 {
pub id: WpColorRepresentationSurfaceV1Id,
pub client: Rc<Client>,
pub version: Version,
pub tracker: Tracker<Self>,
pub surface: Rc<WlSurface>,
}
pub const AM_PREMULTIPLIED_ELECTRICAL: u32 = 0;
#[expect(dead_code)]
pub const AM_PREMULTIPLIED_OPTICAL: u32 = 1;
#[expect(dead_code)]
pub const AM_STRAIGHT: u32 = 2;
impl WpColorRepresentationSurfaceV1 {
pub fn install(self: &Rc<Self>) -> Result<(), WpColorRepresentationSurfaceV1Error> {
if self.surface.color_representation_surface.is_some() {
return Err(WpColorRepresentationSurfaceV1Error::HasSurface);
}
self.surface
.color_representation_surface
.set(Some(self.clone()));
Ok(())
}
}
impl WpColorRepresentationSurfaceV1RequestHandler for WpColorRepresentationSurfaceV1 {
type Error = WpColorRepresentationSurfaceV1Error;
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.surface.color_representation_surface.take();
self.client.remove_obj(self)?;
Ok(())
}
fn set_alpha_mode(&self, req: SetAlphaMode, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if req.alpha_mode != AM_PREMULTIPLIED_ELECTRICAL {
return Err(WpColorRepresentationSurfaceV1Error::UnsupportedAlphaMode(
req.alpha_mode,
));
}
Ok(())
}
fn set_coefficients_and_range(
&self,
req: SetCoefficientsAndRange,
_slf: &Rc<Self>,
) -> Result<(), Self::Error> {
Err(
WpColorRepresentationSurfaceV1Error::UnsupportedCoefficientsAndRange(
req.coefficients,
req.range,
),
)
}
fn set_chroma_location(
&self,
_req: SetChromaLocation,
_slf: &Rc<Self>,
) -> Result<(), Self::Error> {
Ok(())
}
}
object_base! {
self = WpColorRepresentationSurfaceV1;
version = self.version;
}
impl Object for WpColorRepresentationSurfaceV1 {}
simple_add_obj!(WpColorRepresentationSurfaceV1);
#[derive(Debug, Error)]
pub enum WpColorRepresentationSurfaceV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
#[error("wl_surface already has a color-representation extension")]
HasSurface,
#[error("{0} is not a supported alpha mode")]
UnsupportedAlphaMode(u32),
#[error("{0}/{1} are not supported coefficients and range")]
UnsupportedCoefficientsAndRange(u32, u32),
}
efrom!(WpColorRepresentationSurfaceV1Error, ClientError);

View file

@ -0,0 +1,134 @@
use {
crate::{
client::{Client, ClientError},
globals::{Global, GlobalName},
ifs::wl_surface::wp_color_representation_surface_v1::{
AM_PREMULTIPLIED_ELECTRICAL, WpColorRepresentationSurfaceV1,
WpColorRepresentationSurfaceV1Error,
},
leaks::Tracker,
object::{Object, Version},
wire::{
WpColorRepresentationManagerV1Id,
wp_color_representation_manager_v1::{
Destroy, Done, GetSurface, SupportedAlphaMode,
WpColorRepresentationManagerV1RequestHandler,
},
},
},
std::rc::Rc,
thiserror::Error,
};
pub struct WpColorRepresentationManagerV1Global {
pub name: GlobalName,
}
impl WpColorRepresentationManagerV1Global {
pub fn new(name: GlobalName) -> Self {
Self { name }
}
fn bind_(
self: Rc<Self>,
id: WpColorRepresentationManagerV1Id,
client: &Rc<Client>,
version: Version,
) -> Result<(), WpColorRepresentationManagerV1Error> {
let obj = Rc::new(WpColorRepresentationManagerV1 {
id,
client: client.clone(),
tracker: Default::default(),
version,
});
track!(client, obj);
client.add_client_obj(&obj)?;
obj.send_capabilities();
Ok(())
}
}
pub struct WpColorRepresentationManagerV1 {
pub id: WpColorRepresentationManagerV1Id,
pub client: Rc<Client>,
pub version: Version,
pub tracker: Tracker<Self>,
}
impl WpColorRepresentationManagerV1 {
fn send_capabilities(&self) {
self.send_supported_alpha_mode(AM_PREMULTIPLIED_ELECTRICAL);
self.send_done();
}
fn send_supported_alpha_mode(&self, alpha_mode: u32) {
self.client.event(SupportedAlphaMode {
self_id: self.id,
alpha_mode,
});
}
fn send_done(&self) {
self.client.event(Done { self_id: self.id });
}
}
impl WpColorRepresentationManagerV1RequestHandler for WpColorRepresentationManagerV1 {
type Error = WpColorRepresentationManagerV1Error;
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.client.remove_obj(self)?;
Ok(())
}
fn get_surface(&self, req: GetSurface, _slf: &Rc<Self>) -> Result<(), Self::Error> {
let surface = self.client.lookup(req.surface)?;
let obj = Rc::new(WpColorRepresentationSurfaceV1 {
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)?;
obj.install()?;
Ok(())
}
}
global_base!(
WpColorRepresentationManagerV1Global,
WpColorRepresentationManagerV1,
WpColorRepresentationManagerV1Error
);
impl Global for WpColorRepresentationManagerV1Global {
fn singleton(&self) -> bool {
true
}
fn version(&self) -> u32 {
1
}
}
simple_add_global!(WpColorRepresentationManagerV1Global);
object_base! {
self = WpColorRepresentationManagerV1;
version = self.version;
}
impl Object for WpColorRepresentationManagerV1 {}
simple_add_obj!(WpColorRepresentationManagerV1);
#[derive(Debug, Error)]
pub enum WpColorRepresentationManagerV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
#[error(transparent)]
Surface(#[from] WpColorRepresentationSurfaceV1Error),
}
efrom!(WpColorRepresentationManagerV1Error, ClientError);

View file

@ -0,0 +1,19 @@
request destroy (destructor) {
}
request get_surface {
id: id(wp_color_representation_surface_v1) (new),
surface: id(wl_surface),
}
event supported_alpha_mode {
alpha_mode: u32,
}
event supported_coefficients_and_ranges {
coefficients: u32,
range: u32,
}
event done {
}

View file

@ -0,0 +1,15 @@
request destroy (destructor) {
}
request set_alpha_mode {
alpha_mode: u32,
}
request set_coefficients_and_range {
coefficients: u32,
range: u32,
}
request set_chroma_location {
chroma_location: u32,
}