From 82185c062c7e037516c9b791a5c8a29a5a55581c Mon Sep 17 00:00:00 2001 From: Felix Palmen Date: Thu, 25 Jul 2024 15:22:30 +0200 Subject: [PATCH] Config: Runtime configuration for Xmoji For now, only provide an EmojiHistory instance. --- src/bin/xmoji/config.c | 123 +++++++++++++++++++++++++++++++++++++++++ src/bin/xmoji/config.h | 24 ++++++++ src/bin/xmoji/xmoji.mk | 1 + 3 files changed, 148 insertions(+) create mode 100644 src/bin/xmoji/config.c create mode 100644 src/bin/xmoji/config.h diff --git a/src/bin/xmoji/config.c b/src/bin/xmoji/config.c new file mode 100644 index 0000000..6411534 --- /dev/null +++ b/src/bin/xmoji/config.c @@ -0,0 +1,123 @@ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" + +#include "configfile.h" +#include "emojihistory.h" + +#include +#include +#include +#include +#include +#include + +#define CFGDEFNAME "/xmoji.cfg" +#define CFGDEFPATH "/.config" + +enum ConfigKey +{ + CFG_HISTORY +}; + +static const char *keys[] = { + "history" +}; + +struct Config +{ + char *cfgfile; + ConfigFile *cfg; + EmojiHistory *history; + int reading; +}; + +static void filechanged(void *receiver, void *sender, void *args) +{ + (void)sender; + + Config *self = receiver; + ConfigFileChangedEventArgs *ea = args; + + self->reading = 1; + if (!strcmp(ea->key, keys[CFG_HISTORY])) + { + EmojiHistory_deserialize(self->history, + ConfigFile_get(self->cfg, keys[CFG_HISTORY])); + } + self->reading = 0; +} + +static void historychanged(void *receiver, void *sender, void *args) +{ + (void)sender; + (void)args; + + Config *self = receiver; + if (self->reading) return; + ConfigFile_set(self->cfg, keys[CFG_HISTORY], + EmojiHistory_serialize(self->history)); + ConfigFile_write(self->cfg); +} + +Config *Config_create(const char *path) +{ + Config *self = PSC_malloc(sizeof *self); + if (path) + { + self->cfgfile = PSC_copystr(path); + } + else + { + const char *home = getenv("XDG_CONFIG_HOME"); + if (home) + { + size_t homelen = strlen(home); + self->cfgfile = PSC_malloc(homelen + sizeof CFGDEFNAME); + memcpy(self->cfgfile, home, homelen); + memcpy(self->cfgfile+homelen, CFGDEFNAME, sizeof CFGDEFNAME); + } + else + { + home = getenv("HOME"); + if (!home) + { + struct passwd *pw = getpwuid(getuid()); + home = pw->pw_dir; + } + size_t homelen = strlen(home); + self->cfgfile = PSC_malloc(homelen + sizeof CFGDEFPATH + + sizeof CFGDEFNAME - 1); + memcpy(self->cfgfile, home, homelen); + memcpy(self->cfgfile+homelen, CFGDEFPATH, sizeof CFGDEFPATH - 1); + memcpy(self->cfgfile+homelen + sizeof CFGDEFPATH - 1, + CFGDEFNAME, sizeof CFGDEFNAME); + } + } + self->cfg = ConfigFile_create(self->cfgfile, + sizeof keys / sizeof *keys, keys); + self->history = EmojiHistory_create(HISTSIZE); + self->reading = 0; + EmojiHistory_deserialize(self->history, + ConfigFile_get(self->cfg, keys[CFG_HISTORY])); + ConfigFile_write(self->cfg); + PSC_Event_register(ConfigFile_changed(self->cfg), self, filechanged, 0); + PSC_Event_register(EmojiHistory_changed(self->history), self, + historychanged, 0); + return self; +} + +EmojiHistory *Config_history(Config *self) +{ + return self->history; +} + +void Config_destroy(Config *self) +{ + if (!self) return; + EmojiHistory_destroy(self->history); + ConfigFile_destroy(self->cfg); + free(self->cfgfile); + free(self); +} + diff --git a/src/bin/xmoji/config.h b/src/bin/xmoji/config.h new file mode 100644 index 0000000..5746117 --- /dev/null +++ b/src/bin/xmoji/config.h @@ -0,0 +1,24 @@ +#ifndef XMOJI_CONFIG_H +#define XMOJI_CONFIG_H + +#include + +#define HISTSIZE 64 + +C_CLASS_DECL(Config); +C_CLASS_DECL(EmojiHistory); +C_CLASS_DECL(PSC_Event); + +typedef struct ConfigChangedEventArgs +{ + int external; +} ConfigChangedEventArgs; + +Config *Config_create(const char *path); + +EmojiHistory *Config_history(Config *self) + CMETHOD; + +void Config_destroy(Config *self); + +#endif diff --git a/src/bin/xmoji/xmoji.mk b/src/bin/xmoji/xmoji.mk index 0a58337..a89d39b 100644 --- a/src/bin/xmoji/xmoji.mk +++ b/src/bin/xmoji/xmoji.mk @@ -7,6 +7,7 @@ xmoji_DEFINES= -DVERSION=\"$(xmoji_VERSION)\" xmoji_MODULES= button \ colorset \ command \ + config \ configfile \ emoji \ emojibutton \