@@ -6,7 +6,8 @@ use std::{
66 } ,
77 path:: Path ,
88 collections:: HashMap ,
9- cmp:: min
9+ cmp:: min,
10+ mem
1011} ;
1112use std:: os:: fd:: AsFd ;
1213use cairo:: { ImageSurface , Format , Context , Surface , Rectangle , FontFace } ;
@@ -55,18 +56,28 @@ struct ConfigProxy {
5556 media_layer_default : Option < bool > ,
5657 show_button_outlines : Option < bool > ,
5758 enable_pixel_shift : Option < bool > ,
58- font_template : Option < String >
59+ font_template : Option < String > ,
60+ primary_layer_keys : Option < Vec < ButtonConfig > > ,
61+ media_layer_keys : Option < Vec < ButtonConfig > >
62+ }
63+
64+ #[ derive( Deserialize ) ]
65+ #[ serde( rename_all = "PascalCase" ) ]
66+ struct ButtonConfig {
67+ svg : Option < String > ,
68+ text : Option < String > ,
69+ action : Key
5970}
6071
6172struct Config {
62- media_layer_default : bool ,
6373 show_button_outlines : bool ,
6474 enable_pixel_shift : bool ,
65- font_face : FontFace
75+ font_face : FontFace ,
76+ layers : [ FunctionLayer ; 2 ]
6677}
6778
6879enum ButtonImage {
69- Text ( & ' static str ) ,
80+ Text ( String ) ,
7081 Svg ( SvgHandle )
7182}
7283
@@ -78,16 +89,27 @@ struct Button {
7889}
7990
8091impl Button {
81- fn new_text ( text : & ' static str , action : Key ) -> Button {
92+ fn with_config ( cfg : ButtonConfig ) -> Button {
93+ if let Some ( text) = cfg. text {
94+ Button :: new_text ( text, cfg. action )
95+ } else if let Some ( svg) = cfg. svg {
96+ Button :: new_svg ( & svg, cfg. action )
97+ } else {
98+ panic ! ( "Invalid config, a button must have either Text or Svg" )
99+ }
100+ }
101+ fn new_text ( text : String , action : Key ) -> Button {
82102 Button {
83103 action,
84104 active : false ,
85105 changed : false ,
86106 image : ButtonImage :: Text ( text)
87107 }
88108 }
89- fn new_svg ( path : & ' static str , action : Key ) -> Button {
90- let svg = Loader :: new ( ) . read_path ( format ! ( "/usr/share/tiny-dfr/{}.svg" , path) ) . unwrap ( ) ;
109+ fn new_svg ( path : & str , action : Key ) -> Button {
110+ let svg = Loader :: new ( ) . read_path ( format ! ( "/etc/tiny-dfr/{}.svg" , path) ) . or_else ( |_| {
111+ Loader :: new ( ) . read_path ( format ! ( "/usr/share/tiny-dfr/{}.svg" , path) )
112+ } ) . unwrap ( ) ;
91113 Button {
92114 action,
93115 active : false ,
@@ -126,11 +148,20 @@ impl Button {
126148 }
127149}
128150
151+ #[ derive( Default ) ]
129152struct FunctionLayer {
130153 buttons : Vec < Button >
131154}
132155
133156impl FunctionLayer {
157+ fn with_config ( cfg : Vec < ButtonConfig > ) -> FunctionLayer {
158+ if cfg. is_empty ( ) {
159+ panic ! ( "Invalid configuration, layer has 0 buttons" ) ;
160+ }
161+ FunctionLayer {
162+ buttons : cfg. into_iter ( ) . map ( Button :: with_config) . collect ( )
163+ }
164+ }
134165 fn draw ( & mut self , config : & Config , surface : & Surface , pixel_shift : ( f64 , f64 ) , complete_redraw : bool ) -> Vec < ClipRect > {
135166 let c = Context :: new ( & surface) . unwrap ( ) ;
136167 let mut modified_regions = if complete_redraw {
@@ -293,19 +324,24 @@ fn load_config() -> Config {
293324 base. show_button_outlines = user. show_button_outlines . or ( base. show_button_outlines ) ;
294325 base. enable_pixel_shift = user. enable_pixel_shift . or ( base. enable_pixel_shift ) ;
295326 base. font_template = user. font_template . or ( base. font_template ) ;
327+ base. media_layer_keys = user. media_layer_keys . or ( base. media_layer_keys ) ;
328+ base. primary_layer_keys = user. primary_layer_keys . or ( base. primary_layer_keys ) ;
296329 } ;
330+ let media_layer = FunctionLayer :: with_config ( base. media_layer_keys . unwrap ( ) ) ;
331+ let fkey_layer = FunctionLayer :: with_config ( base. primary_layer_keys . unwrap ( ) ) ;
332+ let layers = if base. media_layer_default . unwrap ( ) { [ media_layer, fkey_layer] } else { [ fkey_layer, media_layer] } ;
297333 Config {
298- media_layer_default : base. media_layer_default . unwrap ( ) ,
299334 show_button_outlines : base. show_button_outlines . unwrap ( ) ,
300335 enable_pixel_shift : base. enable_pixel_shift . unwrap ( ) ,
301- font_face : load_font ( & base. font_template . unwrap ( ) )
336+ font_face : load_font ( & base. font_template . unwrap ( ) ) ,
337+ layers
302338 }
303339}
304340
305341fn main ( ) {
306342 let mut uinput = UInputHandle :: new ( OpenOptions :: new ( ) . write ( true ) . open ( "/dev/uinput" ) . unwrap ( ) ) ;
307343 let mut backlight = BacklightManager :: new ( ) ;
308- let config = load_config ( ) ;
344+ let mut cfg = load_config ( ) ;
309345 let mut pixel_shift = PixelShiftManager :: new ( ) ;
310346
311347 // drop privileges to input and video group
@@ -319,39 +355,6 @@ fn main() {
319355
320356 let mut surface = ImageSurface :: create ( Format :: ARgb32 , DFR_STRIDE , DFR_WIDTH ) . unwrap ( ) ;
321357 let mut active_layer = 0 ;
322- let fkey_layer = FunctionLayer {
323- buttons : vec ! [
324- Button :: new_text( "F1" , Key :: F1 ) ,
325- Button :: new_text( "F2" , Key :: F2 ) ,
326- Button :: new_text( "F3" , Key :: F3 ) ,
327- Button :: new_text( "F4" , Key :: F4 ) ,
328- Button :: new_text( "F5" , Key :: F5 ) ,
329- Button :: new_text( "F6" , Key :: F6 ) ,
330- Button :: new_text( "F7" , Key :: F7 ) ,
331- Button :: new_text( "F8" , Key :: F8 ) ,
332- Button :: new_text( "F9" , Key :: F9 ) ,
333- Button :: new_text( "F10" , Key :: F10 ) ,
334- Button :: new_text( "F11" , Key :: F11 ) ,
335- Button :: new_text( "F12" , Key :: F12 )
336- ]
337- } ;
338- let media_layer = FunctionLayer {
339- buttons : vec ! [
340- Button :: new_svg( "brightness_low" , Key :: BrightnessDown ) ,
341- Button :: new_svg( "brightness_high" , Key :: BrightnessUp ) ,
342- Button :: new_svg( "mic_off" , Key :: MicMute ) ,
343- Button :: new_svg( "search" , Key :: Search ) ,
344- Button :: new_svg( "backlight_low" , Key :: IllumDown ) ,
345- Button :: new_svg( "backlight_high" , Key :: IllumUp ) ,
346- Button :: new_svg( "fast_rewind" , Key :: PreviousSong ) ,
347- Button :: new_svg( "play_pause" , Key :: PlayPause ) ,
348- Button :: new_svg( "fast_forward" , Key :: NextSong ) ,
349- Button :: new_svg( "volume_off" , Key :: Mute ) ,
350- Button :: new_svg( "volume_down" , Key :: VolumeDown ) ,
351- Button :: new_svg( "volume_up" , Key :: VolumeUp )
352- ]
353- } ;
354- let mut layers = if config. media_layer_default { [ media_layer, fkey_layer] } else { [ fkey_layer, media_layer] } ;
355358 let mut needs_complete_redraw = true ;
356359 let mut drm = DrmBackend :: open_card ( ) . unwrap ( ) ;
357360 let fb_info = drm. fb_info ( ) . unwrap ( ) ;
@@ -365,6 +368,7 @@ fn main() {
365368 let pollfd_tb = PollFd :: new ( & fd_tb, PollFlags :: POLLIN ) ;
366369 let pollfd_main = PollFd :: new ( & fd_main, PollFlags :: POLLIN ) ;
367370 uinput. set_evbit ( EventKind :: Key ) . unwrap ( ) ;
371+ let mut layers = mem:: take ( & mut cfg. layers ) ;
368372 for layer in & layers {
369373 for button in & layer. buttons {
370374 uinput. set_keybit ( button. action ) . unwrap ( ) ;
@@ -392,7 +396,7 @@ fn main() {
392396 loop {
393397 let mut next_timeout_ms = TIMEOUT_MS ;
394398
395- if config . enable_pixel_shift {
399+ if cfg . enable_pixel_shift {
396400 let ( pixel_shift_needs_redraw, pixel_shift_next_timeout_ms) = pixel_shift. update ( ) ;
397401 if pixel_shift_needs_redraw {
398402 needs_complete_redraw = true ;
@@ -401,12 +405,12 @@ fn main() {
401405 }
402406
403407 if needs_complete_redraw || layers[ active_layer] . buttons . iter ( ) . any ( |b| b. changed ) {
404- let shift = if config . enable_pixel_shift {
408+ let shift = if cfg . enable_pixel_shift {
405409 pixel_shift. get ( )
406410 } else {
407411 ( 0.0 , 0.0 )
408412 } ;
409- let clips = layers[ active_layer] . draw ( & config , & surface, shift, needs_complete_redraw) ;
413+ let clips = layers[ active_layer] . draw ( & cfg , & surface, shift, needs_complete_redraw) ;
410414 let data = surface. data ( ) . unwrap ( ) ;
411415 drm. map ( ) . unwrap ( ) . as_mut ( ) [ ..data. len ( ) ] . copy_from_slice ( & data) ;
412416 drm. dirty ( & clips) . unwrap ( ) ;
0 commit comments