@@ -18,11 +18,23 @@ static bool is_valid_horizontal_align(const char *val) {
1818 return (strcmp (val , "left" ) == 0 || strcmp (val , "right" ) == 0 || strcmp (val , "center" ) == 0 );
1919}
2020
21- bool catConf (const char * filename , Config * config ) {
21+ static bool is_valid_tool (const char * val , const char * type ) {
22+ if (strcmp (type , "volume" ) == 0 || strcmp (type , "mic" ) == 0 )
23+ return (strcmp (val , "pactl" ) == 0 || strcmp (val , "wpctl" ) == 0 );
24+ if (strcmp (type , "brightness" ) == 0 )
25+ return (strcmp (val , "brightnessctl" ) == 0 );
26+ return false;
27+ }
28+
29+ static int clamp_step (int val ) {
30+ return (val >= 0 && val <= 50 ) ? val : -1 ;
31+ }
32+
33+ bool catConf (const char * path , Config * config ) {
2234 GError * error = NULL ;
2335 JsonParser * parser = json_parser_new ();
2436
25- if (!json_parser_load_from_file (parser , filename , & error )) {
37+ if (!json_parser_load_from_file (parser , path , & error )) {
2638 fprintf (stderr , RED "[ERROR]" RESET " Failed to load JSON file: %s\n" , error -> message );
2739 g_error_free (error );
2840 g_object_unref (parser );
@@ -38,78 +50,149 @@ bool catConf(const char *filename, Config *config) {
3850
3951 JsonObject * root_obj = json_node_get_object (root );
4052
41- if (!json_object_has_member (root_obj , "orientation" )) {
42- fprintf (stderr , RED "[ERROR]" RESET " Missing 'orientation' field\n" );
43- g_object_unref (parser );
44- return false;
53+ const char * orientation = json_object_has_member (root_obj , "orientation" ) ?
54+ json_object_get_string_member (root_obj , "orientation" ) : "horizontal" ;
55+ if (!is_valid_orientation (orientation )) orientation = "horizontal" ;
56+ strncpy (config -> orientation , orientation , sizeof (config -> orientation ) - 1 );
57+ config -> orientation [sizeof (config -> orientation ) - 1 ] = '\0' ;
58+
59+ config -> invertDirection = json_object_has_member (root_obj , "invert-direction" ) ?
60+ json_object_get_boolean_member (root_obj , "invert-direction" ) : false;
61+
62+ if (json_object_has_member (root_obj , "window_position" )) {
63+ JsonObject * pos_obj = json_object_get_object_member (root_obj , "window_position" );
64+ if (json_object_has_member (pos_obj , "x" ) && json_object_has_member (pos_obj , "y" )) {
65+ config -> has_explicit_pos = true;
66+ config -> x = json_object_get_int_member (pos_obj , "x" );
67+ config -> y = json_object_get_int_member (pos_obj , "y" );
68+ } else {
69+ config -> has_explicit_pos = false;
70+
71+ const char * v_align = json_object_has_member (pos_obj , "vertical" ) ?
72+ json_object_get_string_member (pos_obj , "vertical" ) : "top" ;
73+ if (!is_valid_vertical_align (v_align )) v_align = "top" ;
74+ strncpy (config -> vertical_align , v_align , sizeof (config -> vertical_align ) - 1 );
75+ config -> vertical_align [sizeof (config -> vertical_align ) - 1 ] = '\0' ;
76+
77+ const char * h_align = json_object_has_member (pos_obj , "horizontal" ) ?
78+ json_object_get_string_member (pos_obj , "horizontal" ) : "center" ;
79+ if (!is_valid_horizontal_align (h_align )) h_align = "center" ;
80+ strncpy (config -> horizontal_align , h_align , sizeof (config -> horizontal_align ) - 1 );
81+ config -> horizontal_align [sizeof (config -> horizontal_align ) - 1 ] = '\0' ;
82+
83+ config -> margin = json_object_has_member (pos_obj , "margin" ) ?
84+ json_object_get_int_member (pos_obj , "margin" ) : 0 ;
85+ if (config -> margin < 0 ) config -> margin = 0 ;
86+ }
87+ } else {
88+ config -> has_explicit_pos = false;
89+ strncpy (config -> vertical_align , "top" , sizeof (config -> vertical_align ) - 1 );
90+ config -> vertical_align [sizeof (config -> vertical_align ) - 1 ] = '\0' ;
91+ strncpy (config -> horizontal_align , "center" , sizeof (config -> horizontal_align ) - 1 );
92+ config -> horizontal_align [sizeof (config -> horizontal_align ) - 1 ] = '\0' ;
93+ config -> margin = 0 ;
4594 }
4695
47- const char * orientation = json_object_get_string_member (root_obj , "orientation" );
48- if (!is_valid_orientation (orientation )) {
49- fprintf (stderr , RED "[ERROR]" RESET " Invalid orientation: '%s'. Must be 'horizontal' or 'vertical'.\n" , orientation );
96+ if (json_object_has_member (root_obj , "icon" )) {
97+ JsonObject * icon_obj = json_object_get_object_member (root_obj , "icon" );
98+
99+ const char * sound = json_object_has_member (icon_obj , "sound" ) ?
100+ json_object_get_string_member (icon_obj , "sound" ) : "" ;
101+ strncpy (config -> icon .sound , sound , sizeof (config -> icon .sound ) - 1 );
102+ config -> icon .sound [sizeof (config -> icon .sound ) - 1 ] = '\0' ;
103+
104+ const char * mute = json_object_has_member (icon_obj , "mute" ) ?
105+ json_object_get_string_member (icon_obj , "mute" ) : "" ;
106+ strncpy (config -> icon .mute , mute , sizeof (config -> icon .mute ) - 1 );
107+ config -> icon .mute [sizeof (config -> icon .mute ) - 1 ] = '\0' ;
108+
109+ const char * brightness = json_object_has_member (icon_obj , "brightness" ) ?
110+ json_object_get_string_member (icon_obj , "brightness" ) : "" ;
111+ strncpy (config -> icon .brightness , brightness , sizeof (config -> icon .brightness ) - 1 );
112+ config -> icon .brightness [sizeof (config -> icon .brightness ) - 1 ] = '\0' ;
113+
114+ const char * mic = json_object_has_member (icon_obj , "mic" ) ?
115+ json_object_get_string_member (icon_obj , "mic" ) : "" ;
116+ strncpy (config -> icon .mic , mic , sizeof (config -> icon .mic ) - 1 );
117+ config -> icon .mic [sizeof (config -> icon .mic ) - 1 ] = '\0' ;
118+
119+ const char * mic_off = json_object_has_member (icon_obj , "mic_off" ) ?
120+ json_object_get_string_member (icon_obj , "mic_off" ) : "" ;
121+ strncpy (config -> icon .mic_off , mic_off , sizeof (config -> icon .mic_off ) - 1 );
122+ config -> icon .mic_off [sizeof (config -> icon .mic_off ) - 1 ] = '\0' ;
123+ }
124+
125+ g_object_unref (parser );
126+ return true;
127+ }
128+
129+ bool catSys (const char * path , Sys * sys ) {
130+ // Set default values before JSON parsing
131+ strncpy (sys -> volume_tool , "wpctl" , sizeof (sys -> volume_tool ) - 1 );
132+ sys -> volume_tool [sizeof (sys -> volume_tool ) - 1 ] = '\0' ;
133+
134+ strncpy (sys -> brightness_tool , "brightnessctl" , sizeof (sys -> brightness_tool ) - 1 );
135+ sys -> brightness_tool [sizeof (sys -> brightness_tool ) - 1 ] = '\0' ;
136+
137+ strncpy (sys -> mic_tool , "pactl" , sizeof (sys -> mic_tool ) - 1 );
138+ sys -> mic_tool [sizeof (sys -> mic_tool ) - 1 ] = '\0' ;
139+
140+ sys -> volume_step = 5 ;
141+ sys -> brightness_step = 10 ;
142+ sys -> mic_step = 3 ;
143+
144+ // Now load JSON and override if valid
145+ GError * error = NULL ;
146+ JsonParser * parser = json_parser_new ();
147+
148+ if (!json_parser_load_from_file (parser , path , & error )) {
149+ fprintf (stderr , RED "[ERROR]" RESET " Failed to load JSON file: %s\n" , error -> message );
150+ g_error_free (error );
50151 g_object_unref (parser );
51152 return false;
52153 }
53- if (json_object_has_member (root_obj , "invert-direction" )) {
54- config -> invertDirection = json_object_get_boolean_member (root_obj , "invert-direction" );
55- } else {
56- config -> invertDirection = false; // Default
57- }
58- strncpy (config -> orientation , orientation , sizeof (config -> orientation ));
59- config -> orientation [sizeof (config -> orientation )- 1 ] = '\0' ;
60154
61- if (!json_object_has_member (root_obj , "window_position" )) {
62- fprintf (stderr , RED "[ERROR]" RESET " Missing 'window_position' field\n" );
155+ JsonNode * root = json_parser_get_root (parser );
156+ if (!JSON_NODE_HOLDS_OBJECT (root )) {
157+ fprintf (stderr , RED "[ERROR]" RESET " Root element is not an object\n" );
63158 g_object_unref (parser );
64159 return false;
65160 }
66161
67- JsonObject * pos_obj = json_object_get_object_member ( root_obj , "window_position" );
162+ JsonObject * root_obj = json_node_get_object ( root );
68163
69- if (json_object_has_member (pos_obj , "x" ) && json_object_has_member (pos_obj , "y" )) {
70- config -> has_explicit_pos = true;
71- config -> x = json_object_get_int_member (pos_obj , "x" );
72- config -> y = json_object_get_int_member (pos_obj , "y" );
73- } else {
74- config -> has_explicit_pos = false;
164+ if (json_object_has_member (root_obj , "system_info" )) {
165+ JsonObject * sys_obj = json_object_get_object_member (root_obj , "system_info" );
75166
76- if (json_object_has_member (pos_obj , "vertical" )) {
77- const char * v_align = json_object_get_string_member (pos_obj , "vertical" );
78- if (!is_valid_vertical_align (v_align )) {
79- fprintf (stderr , RED "[ERROR]" RESET " Invalid vertical alignment: '%s'. Must be 'top', 'bottom' or 'center'.\n" , v_align );
80- g_object_unref (parser );
81- return false;
82- }
83- strncpy (config -> vertical_align , v_align , sizeof (config -> vertical_align ));
84- config -> vertical_align [sizeof (config -> vertical_align )- 1 ] = '\0' ;
85- } else {
86- strcpy (config -> vertical_align , "top" );
167+ const char * vol_tool = json_object_get_string_member_with_default (sys_obj , "volume_tool" , sys -> volume_tool );
168+ if (is_valid_tool (vol_tool , "volume" )) {
169+ strncpy (sys -> volume_tool , vol_tool , sizeof (sys -> volume_tool ) - 1 );
170+ sys -> volume_tool [sizeof (sys -> volume_tool ) - 1 ] = '\0' ;
87171 }
88172
89- if (json_object_has_member (pos_obj , "horizontal" )) {
90- const char * h_align = json_object_get_string_member (pos_obj , "horizontal" );
91- if (!is_valid_horizontal_align (h_align )) {
92- fprintf (stderr , RED "[ERROR]" RESET " Invalid horizontal alignment: '%s'. Must be 'left', 'right' or 'center'.\n" , h_align );
93- g_object_unref (parser );
94- return false;
95- }
96- strncpy (config -> horizontal_align , h_align , sizeof (config -> horizontal_align ));
97- config -> horizontal_align [sizeof (config -> horizontal_align )- 1 ] = '\0' ;
98- } else {
99- strcpy (config -> horizontal_align , "center" );
173+ const char * bri_tool = json_object_get_string_member_with_default (sys_obj , "brightness_tool" , sys -> brightness_tool );
174+ if (is_valid_tool (bri_tool , "brightness" )) {
175+ strncpy (sys -> brightness_tool , bri_tool , sizeof (sys -> brightness_tool ) - 1 );
176+ sys -> brightness_tool [sizeof (sys -> brightness_tool ) - 1 ] = '\0' ;
100177 }
101178
102- if (json_object_has_member (pos_obj , "margin" )) {
103- int margin = json_object_get_int_member (pos_obj , "margin" );
104- if (margin < 0 ) {
105- fprintf (stderr , RED "[ERROR]" RESET " Invalid margin value: %d. Must be >= 0.\n" , margin );
106- g_object_unref (parser );
107- return false;
108- }
109- config -> margin = margin ;
110- } else {
111- config -> margin = 0 ;
179+ const char * mic_tool = json_object_get_string_member_with_default (sys_obj , "mic_tool" , sys -> mic_tool );
180+ if (is_valid_tool (mic_tool , "mic" )) {
181+ strncpy (sys -> mic_tool , mic_tool , sizeof (sys -> mic_tool ) - 1 );
182+ sys -> mic_tool [sizeof (sys -> mic_tool ) - 1 ] = '\0' ;
112183 }
184+
185+ int v_step = json_object_get_int_member (sys_obj , "volume_step" );
186+ if (json_object_has_member (sys_obj , "volume_step" ) && clamp_step (v_step ) != -1 )
187+ sys -> volume_step = v_step ;
188+
189+ int b_step = json_object_get_int_member (sys_obj , "brightness_step" );
190+ if (json_object_has_member (sys_obj , "brightness_step" ) && clamp_step (b_step ) != -1 )
191+ sys -> brightness_step = b_step ;
192+
193+ int m_step = json_object_get_int_member (sys_obj , "mic_step" );
194+ if (json_object_has_member (sys_obj , "mic_step" ) && clamp_step (m_step ) != -1 )
195+ sys -> mic_step = m_step ;
113196 }
114197
115198 g_object_unref (parser );
0 commit comments