22
33use cosmic_protocols:: a11y:: v1:: server:: cosmic_a11y_manager_v1;
44use smithay:: reexports:: wayland_server:: {
5- Client , DataInit , Dispatch , DisplayHandle , GlobalDispatch , New ,
5+ Client , DataInit , Dispatch , DisplayHandle , GlobalDispatch , New , Resource ,
66} ;
7- use wayland_backend:: server:: GlobalId ;
7+ use wayland_backend:: { protocol :: WEnum , server:: GlobalId } ;
88
99pub trait A11yHandler {
1010 fn a11y_state ( & mut self ) -> & mut A11yState ;
1111
1212 fn request_screen_magnifier ( & mut self , enabled : bool ) ;
13+ fn request_screen_invert ( & mut self , inverted : bool ) ;
14+ fn request_screen_filter ( & mut self , filter : Option < ColorFilter > ) ;
1315}
1416
1517#[ derive( Debug ) ]
@@ -18,6 +20,39 @@ pub struct A11yState {
1820 instances : Vec < cosmic_a11y_manager_v1:: CosmicA11yManagerV1 > ,
1921
2022 magnifier_state : bool ,
23+ screen_inverted : bool ,
24+ screen_filter : Option < ColorFilter > ,
25+ }
26+
27+ struct Unknown ;
28+
29+ fn protocol_to_color_filter (
30+ protocol : WEnum < cosmic_a11y_manager_v1:: Filter > ,
31+ ) -> Result < Option < ColorFilter > , Unknown > {
32+ match protocol {
33+ WEnum :: Value ( cosmic_a11y_manager_v1:: Filter :: Disabled ) => Ok ( None ) ,
34+ WEnum :: Value ( cosmic_a11y_manager_v1:: Filter :: Greyscale ) => Ok ( Some ( ColorFilter :: Greyscale ) ) ,
35+ WEnum :: Value ( cosmic_a11y_manager_v1:: Filter :: DaltonizeProtanopia ) => {
36+ Ok ( Some ( ColorFilter :: Protanopia ) )
37+ }
38+ WEnum :: Value ( cosmic_a11y_manager_v1:: Filter :: DaltonizeDeuteranopia ) => {
39+ Ok ( Some ( ColorFilter :: Deuteranopia ) )
40+ }
41+ WEnum :: Value ( cosmic_a11y_manager_v1:: Filter :: DaltonizeTritanopia ) => {
42+ Ok ( Some ( ColorFilter :: Tritanopia ) )
43+ }
44+ WEnum :: Unknown ( _) | WEnum :: Value ( _) => Err ( Unknown ) ,
45+ }
46+ }
47+
48+ fn color_filter_to_protocol ( filter : Option < ColorFilter > ) -> cosmic_a11y_manager_v1:: Filter {
49+ match filter {
50+ None => cosmic_a11y_manager_v1:: Filter :: Disabled ,
51+ Some ( ColorFilter :: Greyscale ) => cosmic_a11y_manager_v1:: Filter :: Greyscale ,
52+ Some ( ColorFilter :: Protanopia ) => cosmic_a11y_manager_v1:: Filter :: DaltonizeProtanopia ,
53+ Some ( ColorFilter :: Deuteranopia ) => cosmic_a11y_manager_v1:: Filter :: DaltonizeDeuteranopia ,
54+ Some ( ColorFilter :: Tritanopia ) => cosmic_a11y_manager_v1:: Filter :: DaltonizeTritanopia ,
55+ }
2156}
2257
2358impl A11yState {
@@ -27,7 +62,7 @@ impl A11yState {
2762 F : for < ' a > Fn ( & ' a Client ) -> bool + Send + Sync + ' static ,
2863 {
2964 let global = dh. create_global :: < D , cosmic_a11y_manager_v1:: CosmicA11yManagerV1 , _ > (
30- 1 ,
65+ 2 ,
3166 A11yGlobalData {
3267 filter : Box :: new ( client_filter) ,
3368 } ,
@@ -37,6 +72,8 @@ impl A11yState {
3772 instances : Vec :: new ( ) ,
3873
3974 magnifier_state : false ,
75+ screen_inverted : false ,
76+ screen_filter : None ,
4077 }
4178 }
4279
@@ -55,6 +92,31 @@ impl A11yState {
5592 } ) ;
5693 }
5794 }
95+
96+ pub fn set_screen_inverted ( & mut self , enabled : bool ) {
97+ self . screen_inverted = enabled;
98+ self . send_screen_filter ( ) ;
99+ }
100+
101+ pub fn set_screen_filter ( & mut self , state : Option < ColorFilter > ) {
102+ self . screen_filter = state;
103+ self . send_screen_filter ( ) ;
104+ }
105+
106+ fn send_screen_filter ( & self ) {
107+ for instance in & self . instances {
108+ if instance. version ( ) >= cosmic_a11y_manager_v1:: EVT_SCREEN_FILTER_SINCE {
109+ instance. screen_filter (
110+ if self . screen_inverted {
111+ cosmic_a11y_manager_v1:: ActiveState :: Enabled
112+ } else {
113+ cosmic_a11y_manager_v1:: ActiveState :: Disabled
114+ } ,
115+ color_filter_to_protocol ( self . screen_filter ) ,
116+ ) ;
117+ }
118+ }
119+ }
58120}
59121
60122pub struct A11yGlobalData {
@@ -85,6 +147,17 @@ where
85147 cosmic_a11y_manager_v1:: ActiveState :: Disabled
86148 } ) ;
87149
150+ if instance. version ( ) >= cosmic_a11y_manager_v1:: EVT_SCREEN_FILTER_SINCE {
151+ instance. screen_filter (
152+ if state. screen_inverted {
153+ cosmic_a11y_manager_v1:: ActiveState :: Enabled
154+ } else {
155+ cosmic_a11y_manager_v1:: ActiveState :: Disabled
156+ } ,
157+ color_filter_to_protocol ( state. screen_filter ) ,
158+ ) ;
159+ }
160+
88161 state. instances . push ( instance) ;
89162 }
90163
@@ -108,12 +181,30 @@ where
108181 ) {
109182 match request {
110183 cosmic_a11y_manager_v1:: Request :: SetMagnifier { active } => {
111- state. request_screen_magnifier (
112- active
113- . into_result ( )
114- . unwrap_or ( cosmic_a11y_manager_v1:: ActiveState :: Disabled )
115- == cosmic_a11y_manager_v1:: ActiveState :: Enabled ,
116- ) ;
184+ let enabled = active
185+ . into_result ( )
186+ . unwrap_or ( cosmic_a11y_manager_v1:: ActiveState :: Disabled )
187+ == cosmic_a11y_manager_v1:: ActiveState :: Enabled ;
188+ if enabled != state. a11y_state ( ) . magnifier_state {
189+ state. request_screen_magnifier ( enabled) ;
190+ }
191+ }
192+ cosmic_a11y_manager_v1:: Request :: SetScreenFilter { inverted, filter } => {
193+ let inverted = inverted
194+ . into_result ( )
195+ . unwrap_or ( cosmic_a11y_manager_v1:: ActiveState :: Disabled )
196+ == cosmic_a11y_manager_v1:: ActiveState :: Enabled ;
197+ let filter = protocol_to_color_filter ( filter) ;
198+
199+ if inverted != state. a11y_state ( ) . screen_inverted {
200+ state. request_screen_invert ( inverted) ;
201+ }
202+
203+ if let Ok ( filter) = filter {
204+ if filter != state. a11y_state ( ) . screen_filter {
205+ state. request_screen_filter ( filter) ;
206+ }
207+ }
117208 }
118209 _ => unreachable ! ( ) ,
119210 }
@@ -140,3 +231,5 @@ macro_rules! delegate_a11y {
140231 } ;
141232}
142233pub ( crate ) use delegate_a11y;
234+
235+ use crate :: config:: ColorFilter ;
0 commit comments