@@ -205,7 +205,8 @@ static void execute_action(const char* direction) {
205205}
206206
207207/**
208- * @brief Reads the config file and populates all global setting variables.
208+ * @brief Reads the config file and populates all global setting variables,
209+ * using environment variables as fallbacks for function keys.
209210 */
210211static void load_configuration () {
211212 char * temp_setting ;
@@ -217,27 +218,58 @@ static void load_configuration() {
217218 }
218219 free (temp_setting );
219220
220- temp_setting = get_setting ("key.volume.up" );
221- if (temp_setting ) { KEY_VOLUME_UP_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
222-
223- temp_setting = get_setting ("key.volume.down" );
224- if (temp_setting ) { KEY_VOLUME_DOWN_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
225-
226- temp_setting = get_setting ("key.function.a" );
227- if (temp_setting ) { KEYA_MODIFIER_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
228-
229- temp_setting = get_setting ("key.function.b" );
230- if (temp_setting ) { KEYB_MODIFIER_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
231-
232- temp_setting = get_setting ("key.hotkey.a" );
233- if (temp_setting ) { BTN_HOTKEY_A_MODIFIER_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
234-
235- temp_setting = get_setting ("key.hotkey.b" );
236- if (temp_setting ) { BTN_HOTKEY_B_MODIFIER_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
237-
238- temp_setting = get_setting ("key.hotkey.c" );
239- if (temp_setting ) { BTN_HOTKEY_C_MODIFIER_CODE = get_code_from_name (temp_setting ); free (temp_setting ); }
240-
221+ // --- Macro Definitions ---
222+
223+ // Macro for keys that ONLY read from the config file.
224+ #define LOAD_KEY (config_key , var_name ) \
225+ do { \
226+ temp_setting = get_setting(config_key); \
227+ if (temp_setting) { \
228+ var_name = get_code_from_name(temp_setting); \
229+ log_msg("Loaded %s: %s -> %d\n", config_key, temp_setting, var_name); \
230+ free(temp_setting); \
231+ } \
232+ } while (0)
233+
234+ // Macro for keys that check config file FIRST, then an environment variable.
235+ #define LOAD_KEY_WITH_ENV_FALLBACK (config_key , var_name , env_var_name ) \
236+ do { \
237+ char* key_name_str = NULL; \
238+ temp_setting = get_setting(config_key); \
239+ if (temp_setting && strlen(temp_setting) > 0) { \
240+ key_name_str = temp_setting; \
241+ } else { \
242+ free(temp_setting); \
243+ char* env_val = getenv(env_var_name); \
244+ if (env_val && strlen(env_val) > 0) { \
245+ key_name_str = strdup(env_val); \
246+ } \
247+ } \
248+ if (key_name_str) { \
249+ var_name = get_code_from_name(key_name_str); \
250+ log_msg("Loaded %s (fallback %s): %s -> %d\n", config_key, env_var_name, key_name_str, var_name); \
251+ free(key_name_str); \
252+ } \
253+ } while (0)
254+
255+ // --- Key Loading ---
256+
257+ // Load standard keys (no fallback)
258+ LOAD_KEY ("key.volume.up" , KEY_VOLUME_UP_CODE );
259+ LOAD_KEY ("key.volume.down" , KEY_VOLUME_DOWN_CODE );
260+ LOAD_KEY ("key.hotkey.a" , BTN_HOTKEY_A_MODIFIER_CODE );
261+ LOAD_KEY ("key.hotkey.b" , BTN_HOTKEY_B_MODIFIER_CODE );
262+ LOAD_KEY ("key.hotkey.c" , BTN_HOTKEY_C_MODIFIER_CODE );
263+
264+ // Load function keys WITH environment variable fallbacks
265+ LOAD_KEY_WITH_ENV_FALLBACK ("key.function.a" , KEYA_MODIFIER_CODE , "DEVICE_FUNC_KEYA_MODIFIER" );
266+ LOAD_KEY_WITH_ENV_FALLBACK ("key.function.b" , KEYB_MODIFIER_CODE , "DEVICE_FUNC_KEYB_MODIFIER" );
267+
268+ // Undefine the macros to keep the namespace clean
269+ #undef LOAD_KEY
270+ #undef LOAD_KEY_WITH_ENV_FALLBACK
271+
272+ // Load feature flags
241273 temp_setting = get_setting ("key.touchscreen.events" );
242274 if (temp_setting && strcmp (temp_setting , "0" ) != 0 ) TOUCHSCREEN_EVENTS_ENABLED = true;
243275 free (temp_setting );
0 commit comments