From a3d9708d1e811f79c525014ba5359565e2cb912e Mon Sep 17 00:00:00 2001 From: nirenjan Date: Thu, 2 Apr 2026 23:17:07 -0700 Subject: [PATCH] feat: Add config parsing for profiles and layouts This change adds new configuration parameters to support profile inputs on Linux. --- daemon/layouts.d/.gitkeep | 0 daemon/meson.build | 3 +++ daemon/x52d.conf | 22 ++++++++++++++++++++++ daemon/x52d_config.c | 4 ++++ daemon/x52d_config.def | 20 ++++++++++++++++++++ daemon/x52d_config.h | 8 ++++++++ daemon/x52d_config_dump.c | 5 +++++ daemon/x52d_config_parser.c | 17 +++++++++++++++++ daemon/x52d_const.h | 2 ++ po/libx52.pot | 22 +++++++++++----------- po/xx_PL.po | 22 +++++++++++----------- 11 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 daemon/layouts.d/.gitkeep diff --git a/daemon/layouts.d/.gitkeep b/daemon/layouts.d/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/daemon/meson.build b/daemon/meson.build index ae8ac36..e9fd931 100644 --- a/daemon/meson.build +++ b/daemon/meson.build @@ -54,6 +54,9 @@ exe_x52ctl = executable('x52ctl', 'x52ctl.c', install_data('x52d.conf', install_dir: join_paths(get_option('sysconfdir'), 'x52d')) +install_subdir('layouts.d', + install_dir: join_paths(get_option('sysconfdir'), 'x52d')) + test('daemon-communication', files('test_daemon_comm.py')[0], depends: [exe_x52d, exe_x52ctl], protocol: 'tap') diff --git a/daemon/x52d.conf b/daemon/x52d.conf index bf6e464..76d1c33 100644 --- a/daemon/x52d.conf +++ b/daemon/x52d.conf @@ -120,6 +120,25 @@ CurveFactor=3 # you to push more to get any motion out of the virtual mouse. Deadzone=0 +###################################################################### +# Layouts - only valid on Linux +###################################################################### +[Layouts] + +# Directory containing .layout files (character → HID key recipes). +Directory=/etc/x52d/layouts.d + +###################################################################### +# Keyboard (profile input mapping) - only valid on Linux +###################################################################### +[Keyboard] + +# Base layout name: loads /.layout +DefaultKeymap=us + +# Enabled=no disables keyboard emulation from profiles (virtual keyboard). +Enabled=yes + ###################################################################### # Profiles - only valid on Linux ###################################################################### @@ -139,6 +158,9 @@ ClutchEnabled=no # be held down to remain in clutch mode. ClutchLatched=no +# Axis band hysteresis: expand/shrink band edges by this percentage (0-50). +AxisHysteresisPercent=0 + ################## #X52 Input Servic# #Version 0.3.3 # diff --git a/daemon/x52d_config.c b/daemon/x52d_config.c index a5bcff7..5705db6 100644 --- a/daemon/x52d_config.c +++ b/daemon/x52d_config.c @@ -85,9 +85,13 @@ const char *x52d_config_get(const char *section, const char *key) /* Callback stubs * TODO: Remove the ones below when their implementation is complete */ +void x52d_cfg_set_Layouts_Directory(char *param) { (void)param; } +void x52d_cfg_set_Keyboard_DefaultKeymap(char *param) { (void)param; } +void x52d_cfg_set_Keyboard_Enabled(bool param) { (void)param; } void x52d_cfg_set_Profiles_Directory(char* param) { (void)param; } void x52d_cfg_set_Profiles_ClutchEnabled(bool param) { (void)param; } void x52d_cfg_set_Profiles_ClutchLatched(bool param) { (void)param; } +void x52d_cfg_set_Profiles_AxisHysteresisPercent(int param) { (void)param; } void x52d_config_apply_immediate(const char *section, const char *key) { diff --git a/daemon/x52d_config.def b/daemon/x52d_config.def index 7517e2a..45741f6 100644 --- a/daemon/x52d_config.def +++ b/daemon/x52d_config.def @@ -91,6 +91,22 @@ CFG(Mouse, CurveFactor, mouse_curve_factor, int, 3) // Deadzone controls the deadzone range for the thumbstick CFG(Mouse, Deadzone, mouse_deadzone_factor, int, 0) +/********************************************************************** + * Layouts - keyboard layout files (.layout), only valid on Linux + *********************************************************************/ +// Directory is the location of the folder containing layout maps +// (e.g. us.layout for DefaultKeymap=us). +CFG(Layouts, Directory, layouts_dir, string, /etc/x52d/layouts.d) + +/********************************************************************** + * Keyboard / profile input mapping - only valid on Linux + *********************************************************************/ +// DefaultKeymap selects layouts.d/.layout (e.g. us -> us.layout). +CFG(Keyboard, DefaultKeymap, default_keymap, string, us) + +// Enabled controls whether keyboard emulation from profiles is active. +CFG(Keyboard, Enabled, keyboard_enabled, bool, true) + /********************************************************************** * Profiles - only valid on Linux *********************************************************************/ @@ -105,4 +121,8 @@ CFG(Profiles, ClutchEnabled, clutch_enabled, bool, false) // be held down to remain in clutch mode. CFG(Profiles, ClutchLatched, clutch_latched, bool, false) +// AxisHysteresisPercent expands axis band boundaries by this percentage (0-50) +// to reduce chatter at band edges. Profiles may override per-profile. +CFG(Profiles, AxisHysteresisPercent, axis_hysteresis_percent, axis_hysteresis, 0) + #undef CFG diff --git a/daemon/x52d_config.h b/daemon/x52d_config.h index 930f16c..8002b82 100644 --- a/daemon/x52d_config.h +++ b/daemon/x52d_config.h @@ -49,6 +49,10 @@ struct x52d_config { bool clutch_latched; char profiles_dir[NAME_MAX]; + char layouts_dir[NAME_MAX]; + char default_keymap[NAME_MAX]; + bool keyboard_enabled; + int axis_hysteresis_percent; }; /* Callback functions for configuration */ @@ -81,9 +85,13 @@ void x52d_cfg_set_Mouse_ReverseScroll(bool param); void x52d_cfg_set_Mouse_IsometricMode(bool param); void x52d_cfg_set_Mouse_CurveFactor(int param); void x52d_cfg_set_Mouse_Deadzone(int param); +void x52d_cfg_set_Layouts_Directory(char *param); +void x52d_cfg_set_Keyboard_DefaultKeymap(char *param); +void x52d_cfg_set_Keyboard_Enabled(bool param); void x52d_cfg_set_Profiles_Directory(char* param); void x52d_cfg_set_Profiles_ClutchEnabled(bool param); void x52d_cfg_set_Profiles_ClutchLatched(bool param); +void x52d_cfg_set_Profiles_AxisHysteresisPercent(int param); int x52d_config_process_kv(void *user, const char *section, const char *key, const char *value); const char *x52d_config_get_param(struct x52d_config *cfg, const char *section, const char *key); diff --git a/daemon/x52d_config_dump.c b/daemon/x52d_config_dump.c index ef68c83..0193f94 100644 --- a/daemon/x52d_config_dump.c +++ b/daemon/x52d_config_dump.c @@ -60,6 +60,11 @@ static const char * int_dumper(const char *section, const char *key, struct x52d return dump; } +static const char * axis_hysteresis_dumper(const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + return int_dumper(section, key, cfg, offset); +} + static const char * led_dumper(const char *section, const char *key, struct x52d_config *cfg, size_t offset) { CONFIG_PTR(libx52_led_state *, config); diff --git a/daemon/x52d_config_parser.c b/daemon/x52d_config_parser.c index 1afdf1d..d913efb 100644 --- a/daemon/x52d_config_parser.c +++ b/daemon/x52d_config_parser.c @@ -80,6 +80,23 @@ static int int_parser(struct x52d_config *cfg, size_t offset, const char *value) return 0; } +static int axis_hysteresis_parser(struct x52d_config *cfg, size_t offset, const char *value) +{ + int rc; + + rc = int_parser(cfg, offset, value); + if (rc != 0) { + return rc; + } + + CONFIG_PTR(int *, config); + if (*config < 0 || *config > 50) { + return EINVAL; + } + + return 0; +} + static int led_parser(struct x52d_config *cfg, size_t offset, const char *value) { CONFIG_PTR(libx52_led_state *, config); diff --git a/daemon/x52d_const.h b/daemon/x52d_const.h index 5a24e6b..985725b 100644 --- a/daemon/x52d_const.h +++ b/daemon/x52d_const.h @@ -15,6 +15,8 @@ #define X52D_SYS_CFG_FILE SYSCONFDIR "/" X52D_APP_NAME "/" X52D_APP_NAME ".conf" +#define X52D_SYS_LAYOUTS_DIR SYSCONFDIR "/" X52D_APP_NAME "/layouts.d" + #define X52D_PID_FILE RUNDIR "/" X52D_APP_NAME ".pid" #define X52D_SOCK_COMMAND RUNDIR "/" X52D_APP_NAME ".cmd" diff --git a/po/libx52.pot b/po/libx52.pot index 9cae6ce..8938a5c 100644 --- a/po/libx52.pot +++ b/po/libx52.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.3.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2026-04-01 20:47-0700\n" +"POT-Creation-Date: 2026-04-02 23:18-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -752,50 +752,50 @@ msgstr "" msgid "Error %d saving configuration file: %s" msgstr "" -#: daemon/x52d_config_dump.c:108 +#: daemon/x52d_config_dump.c:113 #, c-format msgid "Unable to save config file %s - code %d: %s" msgstr "" -#: daemon/x52d_config_dump.c:126 +#: daemon/x52d_config_dump.c:131 #, c-format msgid "Failed to dump %s.%s to config file %s" msgstr "" -#: daemon/x52d_config_parser.c:172 +#: daemon/x52d_config_parser.c:189 #, c-format msgid "Ignoring unknown key '%s.%s'" msgstr "" -#: daemon/x52d_config_parser.c:213 +#: daemon/x52d_config_parser.c:230 #, c-format msgid "Failed processing configuration file %s - code %d" msgstr "" -#: daemon/x52d_config_parser.c:243 +#: daemon/x52d_config_parser.c:260 msgid "Failed to allocate memory for override structure" msgstr "" -#: daemon/x52d_config_parser.c:252 +#: daemon/x52d_config_parser.c:269 msgid "Failed to allocate memory for override string" msgstr "" -#: daemon/x52d_config_parser.c:263 +#: daemon/x52d_config_parser.c:280 #, c-format msgid "No section found in override string '%s'" msgstr "" -#: daemon/x52d_config_parser.c:277 +#: daemon/x52d_config_parser.c:294 #, c-format msgid "No key found in override string '%s'" msgstr "" -#: daemon/x52d_config_parser.c:288 +#: daemon/x52d_config_parser.c:305 #, c-format msgid "No value found in override string '%s'" msgstr "" -#: daemon/x52d_config_parser.c:339 +#: daemon/x52d_config_parser.c:356 #, c-format msgid "Error processing override '%s.%s=%s'" msgstr "" diff --git a/po/xx_PL.po b/po/xx_PL.po index eae89f6..2258907 100644 --- a/po/xx_PL.po +++ b/po/xx_PL.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.2.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2026-04-01 20:47-0700\n" +"POT-Creation-Date: 2026-04-02 23:18-0700\n" "PO-Revision-Date: 2026-04-01 20:50-0700\n" "Last-Translator: Nirenjan Krishnan \n" "Language-Team: Dummy Language for testing i18n\n" @@ -805,50 +805,50 @@ msgstr "Erroray %d ettingsay onfigurationcay efaultsday: %s" msgid "Error %d saving configuration file: %s" msgstr "Erroray %d avingsay onfigurationcay ilefay: %s" -#: daemon/x52d_config_dump.c:108 +#: daemon/x52d_config_dump.c:113 #, c-format msgid "Unable to save config file %s - code %d: %s" msgstr "Unableay otay avesay onfigcay ilefay %s - odecay %d: %s" -#: daemon/x52d_config_dump.c:126 +#: daemon/x52d_config_dump.c:131 #, c-format msgid "Failed to dump %s.%s to config file %s" msgstr "Ailedfay otay umpday %s.%s otay onfigcay ilefay %s" -#: daemon/x52d_config_parser.c:172 +#: daemon/x52d_config_parser.c:189 #, c-format msgid "Ignoring unknown key '%s.%s'" msgstr "Ignoringay unknownay eykay '%s.%s'" -#: daemon/x52d_config_parser.c:213 +#: daemon/x52d_config_parser.c:230 #, c-format msgid "Failed processing configuration file %s - code %d" msgstr "Ailedfay ocessingpray onfigurationcay ilefay %s - odecay %d" -#: daemon/x52d_config_parser.c:243 +#: daemon/x52d_config_parser.c:260 msgid "Failed to allocate memory for override structure" msgstr "Ailedfay otay allocateay emorymay orfay overrideay ucturestray" -#: daemon/x52d_config_parser.c:252 +#: daemon/x52d_config_parser.c:269 msgid "Failed to allocate memory for override string" msgstr "Ailedfay otay allocateay emorymay orfay overrideay ingstray" -#: daemon/x52d_config_parser.c:263 +#: daemon/x52d_config_parser.c:280 #, c-format msgid "No section found in override string '%s'" msgstr "Onay ectionsay oundfay inay overrideay ingstray '%s'" -#: daemon/x52d_config_parser.c:277 +#: daemon/x52d_config_parser.c:294 #, c-format msgid "No key found in override string '%s'" msgstr "Onay eykay oundfay inay overrideay ingstray '%s'" -#: daemon/x52d_config_parser.c:288 +#: daemon/x52d_config_parser.c:305 #, c-format msgid "No value found in override string '%s'" msgstr "Onay aluevay oundfay inay overrideay ingstray '%s'" -#: daemon/x52d_config_parser.c:339 +#: daemon/x52d_config_parser.c:356 #, c-format msgid "Error processing override '%s.%s=%s'" msgstr "Erroray ocessingpray overriday '%s.%s=%s'"