commit 980c53eb435023fca0137328ba15733a7833463e
parent fc509edbb718faf3a71d6e1b2d310570777dbf8d
Author: Bastien Dejean <nihilhill@gmail.com>
Date: Sun, 6 Jan 2013 11:12:46 +0100
Support optional extra configurations
Diffstat:
4 files changed, 54 insertions(+), 33 deletions(-)
diff --git a/README.md b/README.md
@@ -6,13 +6,13 @@ sxhkd is a simple X hotkey daemon.
### Synopsis
- sxhkd [OPTIONS]
+ sxhkd [OPTIONS] [EXTRA_CONFIG ...]
### Options
* `-h`: Print the synopsis to standard output and exit.
* `-v`: Print the version information to standard output and exit.
-* `-c CONFIG_FILE`: Read the configuration from the given file.
+* `-c CONFIG_FILE`: Read the main configuration from the given file.
## Configuration
diff --git a/sxhkd.1 b/sxhkd.1
@@ -3,7 +3,7 @@
Simple X HotKey Daemon.
.SH SYNOPSIS
.SY sxhkd
-.RI [ OPTIONS ]
+.RI [ OPTIONS "] [" EXTRA_CONFIG " ...]"
.YS
.SH DESCRIPTION
.PP
diff --git a/sxhkd.c b/sxhkd.c
@@ -50,23 +50,28 @@ void cleanup(void)
}
}
-void load_config(void)
+void reload_all(void)
{
- PUTS("load configuration");
- if (hotkeys != NULL) {
- cleanup();
- hotkeys = NULL;
- }
+ PUTS("reload all");
+ signal(SIGUSR1, hold);
+ cleanup();
+ hotkeys = NULL;
+ load_config(config_file);
+ for (int i = 0; i < num_extra_confs; i++)
+ load_config(extra_confs[i]);
+ ungrab();
+ grab();
+ reload = false;
+}
+
+void load_config(char *config_file)
+{
+ PRINTF("load configuration '%s'\n", config_file);
- char path[MAXLEN];
- if (config_file == NULL)
- snprintf(path, sizeof(path), "%s/%s", getenv("XDG_CONFIG_HOME"), CONFIG_PATH);
- else
- strncpy(path, config_file, sizeof(path));
- FILE *cfg = fopen(path, "r");
+ FILE *cfg = fopen(config_file, "r");
if (cfg == NULL)
- err("Can't open configuration file.\n");
+ err("Can't open configuration file: '%s'.\n", config_file);
char line[MAXLEN];
xcb_keysym_t keysym = XCB_NO_SYMBOL;
@@ -177,7 +182,7 @@ void key_button_event(xcb_generic_event_t *evt, xcb_event_mask_t event_mask)
int main(int argc, char *argv[])
{
char opt;
- config_file = NULL;
+ config_path = NULL;
while ((opt = getopt(argc, argv, "vhc:")) != -1) {
switch (opt) {
@@ -186,15 +191,28 @@ int main(int argc, char *argv[])
exit(EXIT_SUCCESS);
break;
case 'h':
- printf("sxhkd [-h|-v|-c CONFIG_FILE]\n");
+ printf("sxhkd [-h|-v|-c CONFIG_FILE] [EXTRA_CONFIG ...]\n");
exit(EXIT_SUCCESS);
break;
case 'c':
- config_file = optarg;
+ config_path = optarg;
break;
}
}
+ num_extra_confs = argc - optind;
+ extra_confs = argv + optind;
+
+ if (config_path == NULL) {
+ char *config_home = getenv(CONFIG_HOME_ENV);
+ if (config_home == NULL)
+ err("The following environment variable is not defined: '%s'.\n", CONFIG_HOME_ENV);
+ else
+ snprintf(config_file, sizeof(config_file), "%s/%s", config_home, CONFIG_PATH);
+ } else {
+ strncpy(config_file, config_path, sizeof(config_file));
+ }
+
signal(SIGINT, hold);
signal(SIGHUP, hold);
signal(SIGTERM, hold);
@@ -202,7 +220,9 @@ int main(int argc, char *argv[])
setup();
get_lock_fields();
- load_config();
+ load_config(config_file);
+ for (int i = 0; i < num_extra_confs; i++)
+ load_config(extra_confs[i]);
grab();
xcb_generic_event_t *evt;
@@ -240,14 +260,8 @@ int main(int argc, char *argv[])
}
}
- if (reload) {
- PUTS("reload configuration");
- signal(SIGUSR1, hold);
- load_config();
- ungrab();
- grab();
- reload = false;
- }
+ if (reload)
+ reload_all();
if (xcb_connection_has_error(dpy)) {
warn("One of the previous requests failed.\n");
diff --git a/sxhkd.h b/sxhkd.h
@@ -6,9 +6,10 @@
#include <stdbool.h>
#include "helpers.h"
-#define CONFIG_PATH "sxhkd/sxhkdrc"
-#define TOK_SEP "+ \n"
-#define NUM_MOD 8
+#define CONFIG_HOME_ENV "XDG_CONFIG_HOME"
+#define CONFIG_PATH "sxhkd/sxhkdrc"
+#define TOK_SEP "+ \n"
+#define NUM_MOD 8
typedef struct hotkey_t hotkey_t;
struct hotkey_t {
@@ -29,7 +30,12 @@ xcb_connection_t *dpy;
xcb_window_t root;
xcb_key_symbols_t *symbols;
hotkey_t *hotkeys;
-char *config_file;
+
+char config_file[MAXLEN];
+char *config_path;
+char **extra_confs;
+int num_extra_confs;
+
bool running, reload;
uint16_t num_lock;
@@ -39,7 +45,8 @@ uint16_t scroll_lock;
void hold(int);
void setup(void);
void cleanup(void);
-void load_config(void);
+void reload_all(void);
+void load_config(char *config_file);
void mapping_notify(xcb_generic_event_t *);
void key_event(xcb_generic_event_t *, xcb_event_mask_t);