From 528ec0558b31b2ebb5a31a7082d6db00eec90d54 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 13 Oct 2012 19:54:42 +0200 Subject: [PATCH 01/51] Make clean remove core --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index fb717f8..acb5361 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ clean: @rm -f dunst @rm -f dunst.1 @rm -f org.knopwob.dunst.service + @rm -f core doc: dunst.1 dunst.1: README.pod From 66a5845ecc8b3a8653e7bb09d6e23893bd13c0a8 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 08:49:18 +0200 Subject: [PATCH 02/51] make default for ini_get_double a double --- options.c | 2 +- options.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/options.c b/options.c index 78b0c55..8d528d7 100644 --- a/options.c +++ b/options.c @@ -112,7 +112,7 @@ int ini_get_int(char *section, char *key, int def) return atoi(value); } -double ini_get_double(char *section, char *key, int def) +double ini_get_double(char *section, char *key, double def) { char *value = get_value(section, key); if (value == NULL) diff --git a/options.h b/options.h index 2d2d968..1c8aa71 100644 --- a/options.h +++ b/options.h @@ -7,7 +7,7 @@ int load_ini_file(FILE *); char *ini_get_string(char *section, char *key, const char *def); int ini_get_int(char *section, char *key, int def); -double ini_get_double(char *section, char *key, int def); +double ini_get_double(char *section, char *key, double def); int ini_get_bool(char *section, char *key, int def); void free_ini(void); From 1b2b1d2f03d002d63d3a0f9ef66ccf0cefe1f23c Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 09:35:58 +0200 Subject: [PATCH 03/51] add cmdline_get* and options_get* --- options.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ options.h | 12 +++++ 2 files changed, 153 insertions(+) diff --git a/options.c b/options.c index 8d528d7..3a466b1 100644 --- a/options.c +++ b/options.c @@ -32,6 +32,11 @@ static void add_entry(char *section_name, char *key, char *value); static char *get_value(char *section, char *key); static char *clean_value(char *value); +static int cmdline_argc; +static char **cmdline_argv; + +static int cmdline_find_option(char *key); + section_t *new_section(char *name) { section_count++; @@ -255,4 +260,140 @@ int load_ini_file(FILE *fp) free(current_section); return 0; } + +void cmdline_load(int argc, char *argv[]) +{ + cmdline_argc = argc; + cmdline_argv = argv; +} + +int cmdline_find_option(char *key) +{ + char *key1 = strdup(key); + char *key2 = strstr(key1, "/"); + + if (key2) { + *key2 = '\0'; + key2++; + } + + /* look for first key */ + for (int i = 0; i < cmdline_argc; i++) { + if (strcmp(key1, cmdline_argv[i]) == 0) { + free(key1); + return i; + } + } + + /* look for second key if one was specified */ + if (key2) { + for (int i = 0; i < cmdline_argc; i++) { + if (strcmp(key2, cmdline_argv[i]) == 0) { + free(key1); + return i; + } + } + } + + free(key1); + return -1; +} + +char *cmdline_get_string(char *key, char *def) +{ + int idx = cmdline_find_option(key); + if (idx == 0) { + return def; + } + + if (idx + 1 <= cmdline_argc || cmdline_argv[idx+1][0] == '-') { + /* the argument is missing */ + fprintf(stderr, "Warning: %s, missing argument. Ignoring", key); + return def; + } + + return cmdline_argv[idx+1]; +} + +int cmdline_get_int(char *key, int def) +{ + char *str = cmdline_get_string(key, NULL); + if (str == NULL) + return def; + else + return atoi(str); +} + +double cmdline_get_double(char *key, double def) +{ + char *str = cmdline_get_string(key, NULL); + if (str == NULL) + return def; + else + return atof(str); +} + +int cmdline_get_bool(char *key, int def) +{ + int idx = cmdline_find_option(key); + if (idx > 0) + return true; + else + return def; +} + +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def) +{ + char *val = cmdline_get_string(cmdline_key, NULL); + if (val) { + return val; + } else { + return ini_get_string(ini_section, ini_key, def); + } + +} + +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def) +{ + /* we have to get this twice in order to check wether the actual value + * is the same as the first default value + */ + int val = cmdline_get_int(cmdline_key, 1); + int val2 = cmdline_get_int(cmdline_key, 0); + + if (val == val2) { + /* the cmdline option has been set */ + return val; + } else { + return ini_get_int(ini_section, ini_key, def); + } +} + +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def) +{ + /* see option_get_int */ + double val = cmdline_get_double(cmdline_key, 1); + double val2 = cmdline_get_double(cmdline_key, 0); + + if (val == val2) { + return val; + } else { + return ini_get_double(ini_section, ini_key, def); + } + +} + +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def) +{ + int val = cmdline_get_bool(cmdline_key, false); + + if (val) { + /* this can only be true if the value has been set, + * so we can return */ + return true; + } + + return ini_get_bool(ini_section, ini_key, def); +} + /* vim: set ts=8 sw=8 tw=0: */ diff --git a/options.h b/options.h index 1c8aa71..6337744 100644 --- a/options.h +++ b/options.h @@ -11,6 +11,18 @@ double ini_get_double(char *section, char *key, double def); int ini_get_bool(char *section, char *key, int def); void free_ini(void); +void cmdline_load(int argc, char *argv[]); +/* for all cmdline_get_* key can be either "-key" or "-key/-longkey" */ +char *cmdline_get_string(char *key, char *def); +int cmdline_get_int(char *key, int def); +double cmdline_get_double(char *key, double def); +int cmdline_get_bool(char *key, int def); + +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def); +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def); +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def); +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def); + /* returns the next known section. * if section == NULL returns first section. * returns NULL if no more sections are available From 568c15c73f39907642b75d512a7d793729e87e65 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 09:43:11 +0200 Subject: [PATCH 04/51] option_get* handle empty cmdline_key --- options.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/options.c b/options.c index 3a466b1..ddfccaa 100644 --- a/options.c +++ b/options.c @@ -269,6 +269,9 @@ void cmdline_load(int argc, char *argv[]) int cmdline_find_option(char *key) { + if (!key) { + return -1; + } char *key1 = strdup(key); char *key2 = strstr(key1, "/"); @@ -344,7 +347,12 @@ int cmdline_get_bool(char *key, int def) char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def) { - char *val = cmdline_get_string(cmdline_key, NULL); + char *val = NULL; + + if (cmdline_key) { + val = cmdline_get_string(cmdline_key, NULL); + } + if (val) { return val; } else { @@ -358,10 +366,13 @@ int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def) /* we have to get this twice in order to check wether the actual value * is the same as the first default value */ - int val = cmdline_get_int(cmdline_key, 1); - int val2 = cmdline_get_int(cmdline_key, 0); + int val, val2; + if (cmdline_key) { + val = cmdline_get_int(cmdline_key, 1); + val2 = cmdline_get_int(cmdline_key, 0); + } - if (val == val2) { + if (cmdline_key && val == val2) { /* the cmdline option has been set */ return val; } else { @@ -372,10 +383,13 @@ int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def) double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def) { /* see option_get_int */ - double val = cmdline_get_double(cmdline_key, 1); - double val2 = cmdline_get_double(cmdline_key, 0); + double val, val2; + if (cmdline_key) { + val = cmdline_get_double(cmdline_key, 1); + val2 = cmdline_get_double(cmdline_key, 0); + } - if (val == val2) { + if (cmdline_key && val == val2) { return val; } else { return ini_get_double(ini_section, ini_key, def); @@ -385,9 +399,12 @@ double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, do int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def) { - int val = cmdline_get_bool(cmdline_key, false); + int val; - if (val) { + if (cmdline_key) + val = cmdline_get_bool(cmdline_key, false); + + if (cmdline_key && val) { /* this can only be true if the value has been set, * so we can return */ return true; From 46861cd4aedbeb953ad57c24551ed20829931b10 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 10:12:15 +0200 Subject: [PATCH 05/51] minor fixes in options.c --- options.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/options.c b/options.c index ddfccaa..f94a47b 100644 --- a/options.c +++ b/options.c @@ -305,13 +305,13 @@ int cmdline_find_option(char *key) char *cmdline_get_string(char *key, char *def) { int idx = cmdline_find_option(key); - if (idx == 0) { + if (idx < 0) { return def; } - if (idx + 1 <= cmdline_argc || cmdline_argv[idx+1][0] == '-') { + if (idx + 1 >= cmdline_argc || cmdline_argv[idx+1][0] == '-') { /* the argument is missing */ - fprintf(stderr, "Warning: %s, missing argument. Ignoring", key); + fprintf(stderr, "Warning: %s, missing argument. Ignoring\n", key); return def; } From c192b962e549c80a682ca25f41bfef2eb1992f43 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 10:14:02 +0200 Subject: [PATCH 06/51] dunst.c: switch to options_get_* --- dunst.c | 243 ++++++++++++-------------------------------------------- 1 file changed, 50 insertions(+), 193 deletions(-) diff --git a/dunst.c b/dunst.c index f44f762..50c62f8 100644 --- a/dunst.c +++ b/dunst.c @@ -29,9 +29,7 @@ #include "list.h" #include "utils.h" -#ifndef STATIC_CONFIG #include "options.h" -#endif #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -1347,145 +1345,6 @@ void parse_follow_mode(const char *mode) } -void parse_cmdline(int argc, char *argv[]) -{ - int c; - while (1) { - static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"fn", required_argument, NULL, 'F'}, - {"nb", required_argument, NULL, 'n'}, - {"nf", required_argument, NULL, 'N'}, - {"lb", required_argument, NULL, 'l'}, - {"lf", required_argument, NULL, 'L'}, - {"cb", required_argument, NULL, 'c'}, - {"cf", required_argument, NULL, 'C'}, - {"to", required_argument, NULL, 't'}, - {"lto", required_argument, NULL, '0'}, - {"nto", required_argument, NULL, '1'}, - {"cto", required_argument, NULL, '2'}, - {"format", required_argument, NULL, 'f'}, - {"key", required_argument, NULL, 'k'}, - {"history_key", required_argument, NULL, 'K'}, - {"all_key", required_argument, NULL, 'A'}, - {"geometry", required_argument, NULL, 'g'}, - {"config", required_argument, NULL, 'r'}, - {"mod", required_argument, NULL, 'M'}, - {"mon", required_argument, NULL, 'm'}, - {"ns", no_argument, NULL, 'x'}, - {"follow", required_argument, NULL, 'o'}, - {"line_height", required_argument, NULL, 'H'}, - {"lh", required_argument, NULL, 'H'}, - {"print", no_argument, NULL, 'V'}, - {"version", no_argument, NULL, 'v'}, - {0, 0, 0, 0} - }; - - int option_index = 0; - - c = getopt_long_only(argc, argv, "bhsv", long_options, - &option_index); - - if (c == -1) { - break; - } - - KeySym mod = 0; - switch (c) { - case 0: - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'F': - font = optarg; - break; - case 'n': - normbgcolor = optarg; - break; - case 'N': - normfgcolor = optarg; - break; - case 'l': - lowbgcolor = optarg; - break; - case 'L': - lowfgcolor = optarg; - break; - case 'c': - critbgcolor = optarg; - break; - case 'C': - critfgcolor = optarg; - break; - case 't': - timeouts[0] = atoi(optarg); - timeouts[1] = timeouts[0]; - break; - case '0': - timeouts[0] = atoi(optarg); - break; - case '1': - timeouts[1] = atoi(optarg); - break; - case '2': - timeouts[2] = atoi(optarg); - break; - case 'm': - scr.scr = atoi(optarg); - break; - case 'f': - format = optarg; - break; - case 'M': - deprecated_mod = True; - mod = string_to_mask(optarg); - close_ks.mask = mod; - close_all_ks.mask = mod; - history_ks.mask = mod; - break; - case 'k': - close_ks.str = optarg; - break; - case 'K': - history_ks.str = optarg; - break; - case 'A': - close_all_ks.str = optarg; - break; - case 'g': - geom = optarg; - break; - case 's': - sort = True; - break; - case 'r': - /* this option is parsed elsewhere. This is just to supress - * error message */ - break; - case 'x': - sort = False; - break; - case 'o': - parse_follow_mode(optarg); - break; - case 'H': - line_height = atoi(optarg); - break; - case 'v': - print_version(); - break; - case 'V': - print_notifications = True; - break; - default: - usage(EXIT_FAILURE); - break; - } - } -} - -#ifndef STATIC_CONFIG static rule_t *dunst_rules_find_or_create(const char *section) { l_node *iter; @@ -1507,7 +1366,7 @@ static rule_t *dunst_rules_find_or_create(const char *section) return rule; } -void parse_dunstrc(char *cmdline_config_path) +void load_options(char *cmdline_config_path) { xdgHandle xdg; @@ -1534,24 +1393,24 @@ void parse_dunstrc(char *cmdline_config_path) load_ini_file(config_file); - font = ini_get_string("global", "font", font); - format = ini_get_string("global", "format", format); - sort = ini_get_bool("global", "sort", sort); - indicate_hidden = ini_get_bool("global", "indicate_hidden", indicate_hidden); - word_wrap = ini_get_bool("global", "word_wrap", word_wrap); - idle_threshold = ini_get_int("global", "idle_threshold", idle_threshold); - monitor = ini_get_int("global", "monitor", monitor); + font = option_get_string("global", "font", "-fn", font); + format = option_get_string("global", "format", "-format", format); + sort = option_get_bool("global", "sort", "-sort", sort); + indicate_hidden = option_get_bool("global", "indicate_hidden", "-indicate_hidden", indicate_hidden); + word_wrap = option_get_bool("global", "word_wrap", "-word_wrap", word_wrap); + idle_threshold = option_get_int("global", "idle_threshold", "-idle_threshold", idle_threshold); + monitor = option_get_int("global", "monitor", "-mon", monitor); { - char *c = ini_get_string("global", "follow", ""); + char *c = option_get_string("global", "follow", "-follow", ""); if (strlen(c) > 0) { parse_follow_mode(c); free(c); } } - geom = ini_get_string("global", "geometry", geom); - line_height = ini_get_int("global", "line_height", line_height); + geom = option_get_string("global", "geometry", "-geom/-geometry", geom); + line_height = option_get_int("global", "line_height", "-lh/-line_height", line_height); { - char *c = ini_get_string("global", "modifier", ""); + char *c = option_get_string("global", "modifier", NULL, ""); if (strlen(c) > 0) { deprecated_dunstrc_shortcuts = True; KeySym mod = string_to_mask(c); @@ -1561,12 +1420,12 @@ void parse_dunstrc(char *cmdline_config_path) free(c); } } - close_ks.str = ini_get_string("global", "key", close_ks.str); - close_all_ks.str = ini_get_string("global", "key", close_all_ks.str); - history_ks.str = ini_get_string("global", "key", history_ks.str); - bounce_freq = ini_get_double("global", "bounce_freq", bounce_freq); + close_ks.str = option_get_string("global", "key", NULL, close_ks.str); + close_all_ks.str = option_get_string("global", "all_key", NULL, close_all_ks.str); + history_ks.str = option_get_string("global", "history_key", NULL, history_ks.str); + bounce_freq = option_get_double("global", "bounce_freq", "-bounce_freq", bounce_freq); { - char *c = ini_get_string("global", "alignment", ""); + char *c = option_get_string("global", "alignment", "-align/-alignment", ""); if (strlen(c) > 0) { if (strcmp(c, "left") == 0) align = left; @@ -1579,12 +1438,12 @@ void parse_dunstrc(char *cmdline_config_path) free(c); } } - show_age_threshold = ini_get_int("global", "show_age_threshold", show_age_threshold); - sticky_history = ini_get_bool("global", "sticky_history", sticky_history); - separator_height = ini_get_int("global", "separator_height", separator_height); - transparency = ini_get_int("global", "transparency", transparency); + show_age_threshold = option_get_int("global", "show_age_threshold", "-show_age_threshold", show_age_threshold); + sticky_history = option_get_bool("global", "sticky_history", "-sticky_history", sticky_history); + separator_height = option_get_int("global", "separator_height", "-sep_height/-separator_height", separator_height); + transparency = option_get_int("global", "transparency", "-transparency", transparency); { - char *c = ini_get_string("global", "separator_color", ""); + char *c = option_get_string("global", "separator_color", "-sep_color/-separator_color", ""); if (strlen(c) > 0) { if (strcmp(c, "auto") == 0) sep_color = AUTO; @@ -1596,20 +1455,21 @@ void parse_dunstrc(char *cmdline_config_path) } } - lowbgcolor = ini_get_string("urgency_low", "background", lowbgcolor); - lowfgcolor = ini_get_string("urgency_low", "foreground", lowfgcolor); - timeouts[LOW] = ini_get_int("urgency_low", "timeout", timeouts[LOW]); - normbgcolor = ini_get_string("urgency_normal", "background", normbgcolor); - normfgcolor = ini_get_string("urgency_normal", "foreground", normfgcolor); - timeouts[NORM] = ini_get_int("urgency_normal", "timeout", timeouts[NORM]); - critbgcolor = ini_get_string("urgency_critical", "background", critbgcolor); - critfgcolor = ini_get_string("urgency_critical", "foreground", critfgcolor); - timeouts[CRIT] = ini_get_int("urgency_critical", "timeout", timeouts[CRIT]); + lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor); + lowfgcolor = option_get_string("urgency_low", "foreground", "-lf", lowfgcolor); + timeouts[LOW] = option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW]); + normbgcolor = option_get_string("urgency_normal", "background", "-nb", normbgcolor); + normfgcolor = option_get_string("urgency_normal", "foreground", "-nf", normfgcolor); + timeouts[NORM] = option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM]); + critbgcolor = option_get_string("urgency_critical", "background", "-cb", critbgcolor); + critfgcolor = option_get_string("urgency_critical", "foreground", "-cf", critfgcolor); + timeouts[CRIT] = option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT]); - close_ks.str = ini_get_string("shortcuts", "close", close_ks.str); - close_all_ks.str = ini_get_string("shortcuts", "close_all", close_all_ks.str); - history_ks.str = ini_get_string("shortcuts", "history", history_ks.str); + close_ks.str = option_get_string("shortcuts", "close", "-key", close_ks.str); + close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str); + history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str); + print_notifications = cmdline_get_bool("print", False); char *cur_section = NULL; for (;;) { @@ -1663,21 +1523,6 @@ void parse_dunstrc(char *cmdline_config_path) } -char *parse_cmdline_for_config_file(int argc, char *argv[]) -{ - for (int i = 0; i < argc; i++) { - if (strstr(argv[i], "-config") != 0) { - if (i + 1 == argc) { - printf - ("Invalid commandline: -config needs argument\n"); - } - return argv[++i]; - } - } - return NULL; -} -#endif /* STATIC_CONFIG */ - int main(int argc, char *argv[]) { now = time(&now); @@ -1687,12 +1532,24 @@ int main(int argc, char *argv[]) l_push(rules, &default_rules[i]); } scr.scr = monitor; + + cmdline_load(argc, argv); + + if (cmdline_get_bool("-h/-help", False) || cmdline_get_bool("--help", False)) { + usage(EXIT_SUCCESS); + } + + if (cmdline_get_bool("-v/-version", False) || cmdline_get_bool("--version", False)) { + print_version(); + } + #ifndef STATIC_CONFIG char *cmdline_config_path; - cmdline_config_path = parse_cmdline_for_config_file(argc, argv); - parse_dunstrc(cmdline_config_path); + cmdline_config_path = cmdline_get_string("-conf/-config", NULL); +#else + cmdline_config_path = NULL; #endif - parse_cmdline(argc, argv); + load_options(cmdline_config_path); dc = initdc(); init_shortcut(&close_ks); From 65d07c4f96f63701e13e234981323e9dc63365c1 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 10:37:18 +0200 Subject: [PATCH 07/51] autocreate usage --- dunst.c | 17 ++++++++++------- options.c | 37 +++++++++++++++++++++++++++++++++++++ options.h | 1 + 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/dunst.c b/dunst.c index 50c62f8..c89874f 100644 --- a/dunst.c +++ b/dunst.c @@ -1469,7 +1469,7 @@ void load_options(char *cmdline_config_path) close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str); history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str); - print_notifications = cmdline_get_bool("print", False); + print_notifications = cmdline_get_bool("-print", False); char *cur_section = NULL; for (;;) { @@ -1535,9 +1535,6 @@ int main(int argc, char *argv[]) cmdline_load(argc, argv); - if (cmdline_get_bool("-h/-help", False) || cmdline_get_bool("--help", False)) { - usage(EXIT_SUCCESS); - } if (cmdline_get_bool("-v/-version", False) || cmdline_get_bool("--version", False)) { print_version(); @@ -1550,6 +1547,11 @@ int main(int argc, char *argv[]) cmdline_config_path = NULL; #endif load_options(cmdline_config_path); + + if (cmdline_get_bool("-h/-help", False) || cmdline_get_bool("--help", False)) { + usage(EXIT_SUCCESS); + } + dc = initdc(); init_shortcut(&close_ks); @@ -1602,9 +1604,10 @@ int main(int argc, char *argv[]) void usage(int exit_status) { - fputs - ("usage: dunst [-h/--help] [-v] [-geometry geom] [-lh height] [-fn font] [-format fmt]\n[-nb color] [-nf color] [-lb color] [-lf color] [-cb color] [ -cf color]\n[-to secs] [-lto secs] [-cto secs] [-nto secs] [-key key] [-history_key key] [-all_key key] [-mon n] [-follow none/mouse/keyboard] [-config dunstrc]\n", - stderr); + fputs("usage:\n", stderr); + char *us = cmdline_create_usage(); + fputs(us, stderr); + fputs("\n", stderr); exit(exit_status); } diff --git a/options.c b/options.c index f94a47b..1325a1f 100644 --- a/options.c +++ b/options.c @@ -1,4 +1,6 @@ /* copyright 2012 Sascha Kruse and contributors (see LICENSE for licensing information) */ +#define _GNU_SOURCE + #include #include #include @@ -35,6 +37,9 @@ static char *clean_value(char *value); static int cmdline_argc; static char **cmdline_argv; +static char *usage_str = NULL; +static void cmdline_usage_append(char *key, char *type); + static int cmdline_find_option(char *key); section_t *new_section(char *name) @@ -304,6 +309,7 @@ int cmdline_find_option(char *key) char *cmdline_get_string(char *key, char *def) { + cmdline_usage_append(key, "string"); int idx = cmdline_find_option(key); if (idx < 0) { return def; @@ -320,6 +326,7 @@ char *cmdline_get_string(char *key, char *def) int cmdline_get_int(char *key, int def) { + cmdline_usage_append(key, "double"); char *str = cmdline_get_string(key, NULL); if (str == NULL) return def; @@ -329,6 +336,7 @@ int cmdline_get_int(char *key, int def) double cmdline_get_double(char *key, double def) { + cmdline_usage_append(key, "double"); char *str = cmdline_get_string(key, NULL); if (str == NULL) return def; @@ -338,6 +346,7 @@ double cmdline_get_double(char *key, double def) int cmdline_get_bool(char *key, int def) { + cmdline_usage_append(key, ""); int idx = cmdline_find_option(key); if (idx > 0) return true; @@ -413,4 +422,32 @@ int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def return ini_get_bool(ini_section, ini_key, def); } +void cmdline_usage_append(char *key, char *type) +{ + static int add_linebreak = 2; + + + if (!usage_str) { + asprintf(&usage_str, "[%s %s]", key, type); + return; + } + + char *tmp; + add_linebreak--; + if (add_linebreak == 0) { + asprintf(&tmp, "%s[%s %s]\n", usage_str, key, type); + add_linebreak = 3; + } else { + asprintf(&tmp, "%s[%s %s] ", usage_str, key, type); + } + + free(usage_str); + usage_str = tmp; + +} + +char *cmdline_create_usage(void) +{ + return strdup(usage_str); +} /* vim: set ts=8 sw=8 tw=0: */ diff --git a/options.h b/options.h index 6337744..76a04ba 100644 --- a/options.h +++ b/options.h @@ -17,6 +17,7 @@ char *cmdline_get_string(char *key, char *def); int cmdline_get_int(char *key, int def); double cmdline_get_double(char *key, double def); int cmdline_get_bool(char *key, int def); +char *cmdline_create_usage(void); char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def); int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def); From f682519ea95f8c2f24f16f60c884a2a484c09417 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 13:39:54 +0200 Subject: [PATCH 08/51] make STATIC_CONFIG behave as expected again --- dunst.c | 8 ++++---- options.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dunst.c b/dunst.c index c89874f..5f36d0d 100644 --- a/dunst.c +++ b/dunst.c @@ -1369,6 +1369,7 @@ static rule_t *dunst_rules_find_or_create(const char *section) void load_options(char *cmdline_config_path) { +#ifndef STATIC_CONFIG xdgHandle xdg; FILE *config_file = NULL; @@ -1392,6 +1393,7 @@ void load_options(char *cmdline_config_path) } load_ini_file(config_file); +#endif font = option_get_string("global", "font", "-fn", font); format = option_get_string("global", "format", "-format", format); @@ -1517,9 +1519,11 @@ void load_options(char *cmdline_config_path) cur_section, "format", current_rule->format); } +#ifndef STATIC_CONFIG fclose(config_file); free_ini(); xdgWipeHandle(&xdg); +#endif } @@ -1540,12 +1544,8 @@ int main(int argc, char *argv[]) print_version(); } -#ifndef STATIC_CONFIG char *cmdline_config_path; cmdline_config_path = cmdline_get_string("-conf/-config", NULL); -#else - cmdline_config_path = NULL; -#endif load_options(cmdline_config_path); if (cmdline_get_bool("-h/-help", False) || cmdline_get_bool("--help", False)) { diff --git a/options.c b/options.c index 1325a1f..541184b 100644 --- a/options.c +++ b/options.c @@ -25,7 +25,7 @@ typedef struct _section_t { -static int section_count; +static int section_count = 0; static section_t *sections; static section_t *new_section(char *name); From 78d7daed129074572a10b51865694fda63b04638 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 14:44:50 +0200 Subject: [PATCH 09/51] negative width within geometry See github issue #72 --- dunst.c | 14 +++++++++++++- dunst.h | 1 + dunstrc | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index 5f36d0d..ff578a5 100644 --- a/dunst.c +++ b/dunst.c @@ -559,7 +559,11 @@ void draw_win(void) width = 0; } else if (geometry.mask & WidthValue) { /* fixed width */ - width = geometry.w; + if (geometry.negative_width) { + width = scr.dim.w - geometry.w; + } else { + width = geometry.w; + } } else { /* across the screen */ width = scr.dim.w; @@ -1559,10 +1563,18 @@ int main(int argc, char *argv[]) init_shortcut(&history_ks); + if (geom[0] == '-') { + geometry.negative_width = True; + geom++; + } else { + geometry.negative_width = False; + } + geometry.mask = XParseGeometry(geom, &geometry.x, &geometry.y, &geometry.w, &geometry.h); + screensaver_info = XScreenSaverAllocInfo(); initdbus(); diff --git a/dunst.h b/dunst.h index 270e598..8caeb54 100644 --- a/dunst.h +++ b/dunst.h @@ -23,6 +23,7 @@ typedef struct _dimension_t { unsigned int h; unsigned int w; int mask; + int negative_width; } dimension_t; typedef struct _screen_info { diff --git a/dunstrc b/dunstrc index 9955fe2..3ef3e82 100644 --- a/dunstrc +++ b/dunstrc @@ -43,6 +43,8 @@ # the window expands to the longest message displayed. # A positive x is measured from the left, a negative from the # right side of the screen. Y is measured from the top and down respectevly. + # The width can be negative. In this case the actual width is the + # screen width minus the width defined in within the geometry option. geometry = "0x3-30+20" # The transparency of the window. range: [0; 100] From bdfa4301d7fde603838409bc2bf414291a8d00c4 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 15:35:04 +0200 Subject: [PATCH 10/51] add descriptions to usage --- dunst.c | 74 +++++++++++++++++----------------- options.c | 117 +++++++++++++++++++++++++++--------------------------- options.h | 16 ++++---- 3 files changed, 103 insertions(+), 104 deletions(-) diff --git a/dunst.c b/dunst.c index ff578a5..624b7cb 100644 --- a/dunst.c +++ b/dunst.c @@ -1399,24 +1399,24 @@ void load_options(char *cmdline_config_path) load_ini_file(config_file); #endif - font = option_get_string("global", "font", "-fn", font); - format = option_get_string("global", "format", "-format", format); - sort = option_get_bool("global", "sort", "-sort", sort); - indicate_hidden = option_get_bool("global", "indicate_hidden", "-indicate_hidden", indicate_hidden); - word_wrap = option_get_bool("global", "word_wrap", "-word_wrap", word_wrap); - idle_threshold = option_get_int("global", "idle_threshold", "-idle_threshold", idle_threshold); - monitor = option_get_int("global", "monitor", "-mon", monitor); + font = option_get_string("global", "font", "-fn", font, "The font dunst should use."); + format = option_get_string("global", "format", "-format", format, "The format template for the notifictions"); + sort = option_get_bool("global", "sort", "-sort", sort, "Sort notifications by urgency and date?"); + indicate_hidden = option_get_bool("global", "indicate_hidden", "-indicate_hidden", indicate_hidden, "Show how many notificaitons are hidden?"); + word_wrap = option_get_bool("global", "word_wrap", "-word_wrap", word_wrap, "Truncating long lines or do word wrap"); + idle_threshold = option_get_int("global", "idle_threshold", "-idle_threshold", idle_threshold, "Don't timeout notifications if user is longer idle than threshold"); + monitor = option_get_int("global", "monitor", "-mon", monitor, "On which monitor should the notifications be displayed"); { - char *c = option_get_string("global", "follow", "-follow", ""); + char *c = option_get_string("global", "follow", "-follow", "", "Follow mouse, keyboard or none?"); if (strlen(c) > 0) { parse_follow_mode(c); free(c); } } - geom = option_get_string("global", "geometry", "-geom/-geometry", geom); - line_height = option_get_int("global", "line_height", "-lh/-line_height", line_height); + geom = option_get_string("global", "geometry", "-geom/-geometry", geom, "Geometry for the window"); + line_height = option_get_int("global", "line_height", "-lh/-line_height", line_height, "Add additional padding above and beneath text"); { - char *c = option_get_string("global", "modifier", NULL, ""); + char *c = option_get_string("global", "modifier", NULL, "", ""); if (strlen(c) > 0) { deprecated_dunstrc_shortcuts = True; KeySym mod = string_to_mask(c); @@ -1426,12 +1426,12 @@ void load_options(char *cmdline_config_path) free(c); } } - close_ks.str = option_get_string("global", "key", NULL, close_ks.str); - close_all_ks.str = option_get_string("global", "all_key", NULL, close_all_ks.str); - history_ks.str = option_get_string("global", "history_key", NULL, history_ks.str); - bounce_freq = option_get_double("global", "bounce_freq", "-bounce_freq", bounce_freq); + close_ks.str = option_get_string("global", "key", NULL, close_ks.str, ""); + close_all_ks.str = option_get_string("global", "all_key", NULL, close_all_ks.str, ""); + history_ks.str = option_get_string("global", "history_key", NULL, history_ks.str, ""); + bounce_freq = option_get_double("global", "bounce_freq", "-bounce_freq", bounce_freq, "Make long text bounce from side to side"); { - char *c = option_get_string("global", "alignment", "-align/-alignment", ""); + char *c = option_get_string("global", "alignment", "-align/-alignment", "", "Align notifications left/center/right"); if (strlen(c) > 0) { if (strcmp(c, "left") == 0) align = left; @@ -1444,12 +1444,12 @@ void load_options(char *cmdline_config_path) free(c); } } - show_age_threshold = option_get_int("global", "show_age_threshold", "-show_age_threshold", show_age_threshold); - sticky_history = option_get_bool("global", "sticky_history", "-sticky_history", sticky_history); - separator_height = option_get_int("global", "separator_height", "-sep_height/-separator_height", separator_height); - transparency = option_get_int("global", "transparency", "-transparency", transparency); + show_age_threshold = option_get_int("global", "show_age_threshold", "-show_age_threshold", show_age_threshold, "When should the age of the notification be displayed?"); + sticky_history = option_get_bool("global", "sticky_history", "-sticky_history", sticky_history, "Don't timeout notifications popped up from history"); + separator_height = option_get_int("global", "separator_height", "-sep_height/-separator_height", separator_height, "height of the separator line"); + transparency = option_get_int("global", "transparency", "-transparency", transparency, "Transparency. range 0-100"); { - char *c = option_get_string("global", "separator_color", "-sep_color/-separator_color", ""); + char *c = option_get_string("global", "separator_color", "-sep_color/-separator_color", "", "Color of the separator line (or 'auto')"); if (strlen(c) > 0) { if (strcmp(c, "auto") == 0) sep_color = AUTO; @@ -1461,21 +1461,21 @@ void load_options(char *cmdline_config_path) } } - lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor); - lowfgcolor = option_get_string("urgency_low", "foreground", "-lf", lowfgcolor); - timeouts[LOW] = option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW]); - normbgcolor = option_get_string("urgency_normal", "background", "-nb", normbgcolor); - normfgcolor = option_get_string("urgency_normal", "foreground", "-nf", normfgcolor); - timeouts[NORM] = option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM]); - critbgcolor = option_get_string("urgency_critical", "background", "-cb", critbgcolor); - critfgcolor = option_get_string("urgency_critical", "foreground", "-cf", critfgcolor); - timeouts[CRIT] = option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT]); + lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor, "Background color for notifcations with low urgency"); + lowfgcolor = option_get_string("urgency_low", "foreground", "-lf", lowfgcolor, "Foreground color for notifications with low urgency"); + timeouts[LOW] = option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW], "Timeout for notifications with low urgency"); + normbgcolor = option_get_string("urgency_normal", "background", "-nb", normbgcolor, "Background color for notifications with normal urgency"); + normfgcolor = option_get_string("urgency_normal", "foreground", "-nf", normfgcolor, "Foreground color for notifications with normal urgency"); + timeouts[NORM] = option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM], "Timeout for notifications with normal urgency"); + critbgcolor = option_get_string("urgency_critical", "background", "-cb", critbgcolor, "Background color for notifications with critical urgency"); + critfgcolor = option_get_string("urgency_critical", "foreground", "-cf", critfgcolor, "Foreground color for notifications with ciritical urgency"); + timeouts[CRIT] = option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT], "Timeout for notifications with critical urgency"); - close_ks.str = option_get_string("shortcuts", "close", "-key", close_ks.str); - close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str); - history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str); + close_ks.str = option_get_string("shortcuts", "close", "-key", close_ks.str, "Shortcut for closing one notification"); + close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str, "Shortcut for closing all notifications"); + history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str, "Shortcut to pop the last notification from history"); - print_notifications = cmdline_get_bool("-print", False); + print_notifications = cmdline_get_bool("-print", False, "Print notifications to cmdline (DEBUG)"); char *cur_section = NULL; for (;;) { @@ -1544,15 +1544,15 @@ int main(int argc, char *argv[]) cmdline_load(argc, argv); - if (cmdline_get_bool("-v/-version", False) || cmdline_get_bool("--version", False)) { + if (cmdline_get_bool("-v/-version", False, "Print version") || cmdline_get_bool("--version", False, "Print version")) { print_version(); } char *cmdline_config_path; - cmdline_config_path = cmdline_get_string("-conf/-config", NULL); + cmdline_config_path = cmdline_get_string("-conf/-config", NULL, "Path to configuration file"); load_options(cmdline_config_path); - if (cmdline_get_bool("-h/-help", False) || cmdline_get_bool("--help", False)) { + if (cmdline_get_bool("-h/-help", False, "Print help") || cmdline_get_bool("--help", False, "Print help")) { usage(EXIT_SUCCESS); } diff --git a/options.c b/options.c index 541184b..225b47d 100644 --- a/options.c +++ b/options.c @@ -38,7 +38,7 @@ static int cmdline_argc; static char **cmdline_argv; static char *usage_str = NULL; -static void cmdline_usage_append(char *key, char *type); +static void cmdline_usage_append(char *key, char *type, char *description); static int cmdline_find_option(char *key); @@ -307,46 +307,56 @@ int cmdline_find_option(char *key) return -1; } -char *cmdline_get_string(char *key, char *def) +static char *cmdline_get_value(char *key) { - cmdline_usage_append(key, "string"); int idx = cmdline_find_option(key); if (idx < 0) { - return def; + return NULL; } if (idx + 1 >= cmdline_argc || cmdline_argv[idx+1][0] == '-') { /* the argument is missing */ fprintf(stderr, "Warning: %s, missing argument. Ignoring\n", key); - return def; + return NULL; } - return cmdline_argv[idx+1]; } -int cmdline_get_int(char *key, int def) +char *cmdline_get_string(char *key, char *def, char *description) { - cmdline_usage_append(key, "double"); - char *str = cmdline_get_string(key, NULL); + cmdline_usage_append(key, "string", description); + char *str = cmdline_get_value(key); + + if (str) + return str; + else + return def; +} + +int cmdline_get_int(char *key, int def, char *description) +{ + cmdline_usage_append(key, "double", description); + char *str = cmdline_get_value(key); + if (str == NULL) return def; else return atoi(str); } -double cmdline_get_double(char *key, double def) +double cmdline_get_double(char *key, double def, char *description) { - cmdline_usage_append(key, "double"); - char *str = cmdline_get_string(key, NULL); + cmdline_usage_append(key, "double", description); + char *str = cmdline_get_value(key); if (str == NULL) return def; else return atof(str); } -int cmdline_get_bool(char *key, int def) +int cmdline_get_bool(char *key, int def, char *description) { - cmdline_usage_append(key, ""); + cmdline_usage_append(key, "", description); int idx = cmdline_find_option(key); if (idx > 0) return true; @@ -354,12 +364,12 @@ int cmdline_get_bool(char *key, int def) return def; } -char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def) +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def, char *description) { char *val = NULL; if (cmdline_key) { - val = cmdline_get_string(cmdline_key, NULL); + val = cmdline_get_string(cmdline_key, NULL, description); } if (val) { @@ -370,48 +380,38 @@ char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, cha } -int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def) +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description) { - /* we have to get this twice in order to check wether the actual value - * is the same as the first default value - */ - int val, val2; - if (cmdline_key) { - val = cmdline_get_int(cmdline_key, 1); - val2 = cmdline_get_int(cmdline_key, 0); - } + /* *str is only used to check wether the cmdline option is actually set. */ + char *str = cmdline_get_value(cmdline_key); - if (cmdline_key && val == val2) { - /* the cmdline option has been set */ - return val; - } else { + /* we call cmdline_get_int even when the option isn't set in order to + * add the usage info */ + int val = cmdline_get_int(cmdline_key, def, description); + + if (!str) return ini_get_int(ini_section, ini_key, def); - } -} - -double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def) -{ - /* see option_get_int */ - double val, val2; - if (cmdline_key) { - val = cmdline_get_double(cmdline_key, 1); - val2 = cmdline_get_double(cmdline_key, 0); - } - - if (cmdline_key && val == val2) { + else return val; - } else { - return ini_get_double(ini_section, ini_key, def); - } - } -int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def) +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def, char *description) +{ + char *str = cmdline_get_value(cmdline_key); + double val = cmdline_get_double(cmdline_key, def, description); + + if (!str) + return ini_get_int(ini_section, ini_key, def); + else + return val; +} + +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description) { int val; if (cmdline_key) - val = cmdline_get_bool(cmdline_key, false); + val = cmdline_get_bool(cmdline_key, false, description); if (cmdline_key && val) { /* this can only be true if the value has been set, @@ -422,24 +422,23 @@ int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def return ini_get_bool(ini_section, ini_key, def); } -void cmdline_usage_append(char *key, char *type) +void cmdline_usage_append(char *key, char *type, char *description) { - static int add_linebreak = 2; - + char *key_type; + if (type && strlen(type) > 0) + asprintf(&key_type, "%s (%s)", key, type); + else + asprintf(&key_type, "%s", key); if (!usage_str) { - asprintf(&usage_str, "[%s %s]", key, type); + asprintf(&usage_str, "%-40s - %s\n", key_type, description); + free(key_type); return; } char *tmp; - add_linebreak--; - if (add_linebreak == 0) { - asprintf(&tmp, "%s[%s %s]\n", usage_str, key, type); - add_linebreak = 3; - } else { - asprintf(&tmp, "%s[%s %s] ", usage_str, key, type); - } + asprintf(&tmp, "%s%-40s - %s\n", usage_str, key_type, description); + free(key_type); free(usage_str); usage_str = tmp; diff --git a/options.h b/options.h index 76a04ba..e752e9e 100644 --- a/options.h +++ b/options.h @@ -13,16 +13,16 @@ void free_ini(void); void cmdline_load(int argc, char *argv[]); /* for all cmdline_get_* key can be either "-key" or "-key/-longkey" */ -char *cmdline_get_string(char *key, char *def); -int cmdline_get_int(char *key, int def); -double cmdline_get_double(char *key, double def); -int cmdline_get_bool(char *key, int def); +char *cmdline_get_string(char *key, char *def, char *description); +int cmdline_get_int(char *key, int def, char *description); +double cmdline_get_double(char *key, double def, char *description); +int cmdline_get_bool(char *key, int def, char *description); char *cmdline_create_usage(void); -char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def); -int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def); -double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def); -int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def); +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def, char *description); +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description); +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def, char *description); +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description); /* returns the next known section. * if section == NULL returns first section. From 3c8d8b00c663b91c934ef04378aa1c47cd2c7c59 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 15:48:16 +0200 Subject: [PATCH 11/51] make use of stdbool.h --- draw.c | 7 +++--- draw.h | 4 ++-- dunst.c | 73 +++++++++++++++++++++++++++++---------------------------- dunst.h | 6 +++-- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/draw.c b/draw.c index 66ea483..159ac7b 100644 --- a/draw.c +++ b/draw.c @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ DEALINGS IN THE SOFTWARE. #define MIN(a, b) ((a) < (b) ? (a) : (b)) void -drawrect(DC * dc, int x, int y, unsigned int w, unsigned int h, Bool fill, +drawrect(DC * dc, int x, int y, unsigned int w, unsigned int h, bool fill, unsigned long color) { XSetForeground(dc->dpy, dc->gc, color); @@ -71,7 +72,7 @@ void drawtext(DC * dc, const char *text, ColorSet * col) if (mn < n) for (n = MAX(mn - 3, 0); n < mn; buf[n++] = '.') ; - drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); + drawrect(dc, 0, 0, dc->w, dc->h, true, col->BG); drawtextn(dc, buf, mn, col); } @@ -237,7 +238,7 @@ void initfont(DC * dc, const char *fontstr) void setopacity(DC *dc, Window win, unsigned long opacity) { - Atom _NET_WM_WINDOW_OPACITY = XInternAtom(dc->dpy, "_NET_WM_WINDOW_OPACITY", False); + Atom _NET_WM_WINDOW_OPACITY = XInternAtom(dc->dpy, "_NET_WM_WINDOW_OPACITY", false); XChangeProperty(dc->dpy, win, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&opacity, 1L); } diff --git a/draw.h b/draw.h index 645f86c..117986a 100644 --- a/draw.h +++ b/draw.h @@ -37,7 +37,7 @@ DEALINGS IN THE SOFTWARE. typedef struct { int x, y, w, h; - Bool invert; + bool invert; Display *dpy; GC gc; Pixmap canvas; @@ -59,7 +59,7 @@ typedef struct { unsigned long BG; } ColorSet; -void drawrect(DC * dc, int x, int y, unsigned int w, unsigned int h, Bool fill, +void drawrect(DC * dc, int x, int y, unsigned int w, unsigned int h, bool fill, unsigned long color); void drawtext(DC * dc, const char *text, ColorSet * col); void drawtextn(DC * dc, const char *text, size_t n, ColorSet * col); diff --git a/dunst.c b/dunst.c index 624b7cb..644a0e8 100644 --- a/dunst.c +++ b/dunst.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -59,20 +60,20 @@ static Atom utf8; static DC *dc; static Window win; static time_t now; -static int visible = False; +static bool visible = false; static screen_info scr; static dimension_t geometry; static XScreenSaverInfo *screensaver_info; static int font_h; -static int print_notifications = False; +static bool print_notifications = false; static dimension_t window_dim; -int dunst_grab_errored = False; +bool dunst_grab_errored = false; int next_notification_id = 1; -int deprecated_mod = False; -int deprecated_dunstrc_shortcuts = False; +bool deprecated_mod = false; +bool deprecated_dunstrc_shortcuts = false; /* notification lists */ list *notification_queue = NULL; /* all new notifications get into here */ @@ -88,7 +89,7 @@ void handle_mouse_click(XEvent ev); void handleXEvents(void); void history_pop(void); rule_t *initrule(void); -int is_idle(void); +bool is_idle(void); void run(void); void setup(void); void update_screen_info(); @@ -121,7 +122,7 @@ static void print_notification(notification *n) static int GrabXErrorHandler(Display * display, XErrorEvent * e) { - dunst_grab_errored = True; + dunst_grab_errored = true; char err_buf[BUFSIZ]; XGetErrorText(display, e->error_code, err_buf, BUFSIZ); fputs(err_buf, stderr); @@ -136,7 +137,7 @@ static int GrabXErrorHandler(Display * display, XErrorEvent * e) static void setup_error_handler(void) { - dunst_grab_errored = False; + dunst_grab_errored = false; XFlush(dc->dpy); XSetErrorHandler(GrabXErrorHandler); @@ -145,7 +146,7 @@ static void setup_error_handler(void) static int tear_down_error_handler(void) { XFlush(dc->dpy); - XSync(dc->dpy, False); + XSync(dc->dpy, false); XSetErrorHandler(NULL); return dunst_grab_errored; } @@ -161,11 +162,11 @@ int grab_key(keyboard_shortcut * ks) if (ks->is_valid) XGrabKey(dc->dpy, ks->code, ks->mask, root, - True, GrabModeAsync, GrabModeAsync); + true, GrabModeAsync, GrabModeAsync); if (tear_down_error_handler()) { fprintf(stderr, "Unable to grab key \"%s\"\n", ks->str); - ks->is_valid = False; + ks->is_valid = false; return 1; } return 0; @@ -371,7 +372,7 @@ int do_word_wrap(char *source, int max_width) char *eol = source; - while (True) { + while (true) { if (*eol == '\0') return 1; if (*eol == '\n') { @@ -656,7 +657,7 @@ void draw_win(void) char *line = draw_txt_get_line(&n->draw_txt_buf, i + 1); dc->x = 0; - drawrect(dc, 0, 0, width, line_height, True, + drawrect(dc, 0, 0, width, line_height, true, n->colors->BG); dc->x = calculate_x_offset(width, textw(dc, line)); @@ -674,7 +675,7 @@ void draw_win(void) else color = n->colors->FG; - drawrect(dc, 0, 0, width, separator_height, True, color); + drawrect(dc, 0, 0, width, separator_height, true, color); dc->y += separator_height; } } @@ -682,7 +683,7 @@ void draw_win(void) /* draw x_more */ if (x_more.txt) { dc->x = 0; - drawrect(dc, 0, 0, width, line_height, True, last_color->BG); + drawrect(dc, 0, 0, width, line_height, true, last_color->BG); dc->x = calculate_x_offset(width, textw(dc, x_more.txt)); drawtext(dc, x_more.txt, last_color); } @@ -870,7 +871,7 @@ void history_pop(void) for (iter = notification_history->head; iter->next; iter = iter->next) ; data = (notification *) iter->data; - data->redisplayed = True; + data->redisplayed = true; data->start = 0; if (sticky_history) { data->timeout = 0; @@ -968,7 +969,7 @@ int init_notification(notification * n, int id) n->timestamp = now; - n->redisplayed = False; + n->redisplayed = false; if (id == 0) { n->id = ++next_notification_id; @@ -1063,7 +1064,7 @@ void init_shortcut(keyboard_shortcut * ks) return; if (!strcmp(ks->str, "none") || (!strcmp(ks->str, ""))) { - ks->is_valid = False; + ks->is_valid = false; return; } @@ -1103,9 +1104,9 @@ void init_shortcut(keyboard_shortcut * ks) if (ks->sym == NoSymbol || ks->code == NoSymbol) { fprintf(stderr, "Warning: Unknown keyboard shortcut: %s\n", ks->str); - ks->is_valid = False; + ks->is_valid = false; } else { - ks->is_valid = True; + ks->is_valid = true; } free(str_begin); @@ -1128,19 +1129,19 @@ rule_t *initrule(void) return r; } -int is_idle(void) +bool is_idle(void) { XScreenSaverQueryInfo(dc->dpy, DefaultRootWindow(dc->dpy), screensaver_info); if (idle_threshold == 0) { - return False; + return false; } return screensaver_info->idle / 1000 > idle_threshold; } void run(void) { - while (True) { + while (true) { if (visible) { dbus_poll(50); } else { @@ -1173,7 +1174,7 @@ void hide_win() XUngrabButton(dc->dpy, AnyButton, AnyModifier, win); XUnmapWindow(dc->dpy, win); XFlush(dc->dpy); - visible = False; + visible = false; } Window get_focused_window(void) @@ -1185,10 +1186,10 @@ Window get_focused_window(void) unsigned char *prop_return = NULL; Window root = RootWindow(dc->dpy, DefaultScreen(dc->dpy)); Atom netactivewindow = - XInternAtom(dc->dpy, "_NET_ACTIVE_WINDOW", False); + XInternAtom(dc->dpy, "_NET_ACTIVE_WINDOW", false); XGetWindowProperty(dc->dpy, root, netactivewindow, 0L, - sizeof(Window), False, XA_WINDOW, + sizeof(Window), false, XA_WINDOW, &type, &format, &nitems, &bytes_after, &prop_return); if (prop_return) { focused = *(Window *) prop_return; @@ -1286,7 +1287,7 @@ void setup(void) } root = RootWindow(dc->dpy, DefaultScreen(dc->dpy)); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + utf8 = XInternAtom(dc->dpy, "UTF8_STRING", false); /* menu geometry */ font_h = dc->font.height + FONT_HEIGHT_BORDER; @@ -1294,7 +1295,7 @@ void setup(void) update_screen_info(); /* menu window */ - wa.override_redirect = True; + wa.override_redirect = true; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | @@ -1321,7 +1322,7 @@ void map_win(void) grab_key(&close_ks); grab_key(&close_all_ks); setup_error_handler(); - XGrabButton(dc->dpy, AnyButton, AnyModifier, win, False, + XGrabButton(dc->dpy, AnyButton, AnyModifier, win, false, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); if (tear_down_error_handler()) { fprintf(stderr, "Unable to grab mouse button(s)\n"); @@ -1331,7 +1332,7 @@ void map_win(void) XMapRaised(dc->dpy, win); draw_win(); XFlush(dc->dpy); - visible = True; + visible = true; } void parse_follow_mode(const char *mode) @@ -1418,7 +1419,7 @@ void load_options(char *cmdline_config_path) { char *c = option_get_string("global", "modifier", NULL, "", ""); if (strlen(c) > 0) { - deprecated_dunstrc_shortcuts = True; + deprecated_dunstrc_shortcuts = true; KeySym mod = string_to_mask(c); close_ks.mask = mod; close_all_ks.mask = mod; @@ -1475,7 +1476,7 @@ void load_options(char *cmdline_config_path) close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str, "Shortcut for closing all notifications"); history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str, "Shortcut to pop the last notification from history"); - print_notifications = cmdline_get_bool("-print", False, "Print notifications to cmdline (DEBUG)"); + print_notifications = cmdline_get_bool("-print", false, "Print notifications to cmdline (DEBUG)"); char *cur_section = NULL; for (;;) { @@ -1544,7 +1545,7 @@ int main(int argc, char *argv[]) cmdline_load(argc, argv); - if (cmdline_get_bool("-v/-version", False, "Print version") || cmdline_get_bool("--version", False, "Print version")) { + if (cmdline_get_bool("-v/-version", false, "Print version") || cmdline_get_bool("--version", false, "Print version")) { print_version(); } @@ -1552,7 +1553,7 @@ int main(int argc, char *argv[]) cmdline_config_path = cmdline_get_string("-conf/-config", NULL, "Path to configuration file"); load_options(cmdline_config_path); - if (cmdline_get_bool("-h/-help", False, "Print help") || cmdline_get_bool("--help", False, "Print help")) { + if (cmdline_get_bool("-h/-help", false, "Print help") || cmdline_get_bool("--help", false, "Print help")) { usage(EXIT_SUCCESS); } @@ -1564,10 +1565,10 @@ int main(int argc, char *argv[]) if (geom[0] == '-') { - geometry.negative_width = True; + geometry.negative_width = true; geom++; } else { - geometry.negative_width = False; + geometry.negative_width = false; } geometry.mask = XParseGeometry(geom, diff --git a/dunst.h b/dunst.h index 8caeb54..b390998 100644 --- a/dunst.h +++ b/dunst.h @@ -2,6 +2,8 @@ #pragma once +#include + #include "draw.h" #define LOW 0 @@ -49,7 +51,7 @@ typedef struct _notification { time_t timestamp; int timeout; int urgency; - int redisplayed; /* has been displayed before? */ + bool redisplayed; /* has been displayed before? */ int id; int dup_count; ColorSet *colors; @@ -84,7 +86,7 @@ typedef struct _keyboard_shortcut { KeyCode code; KeySym sym; KeySym mask; - int is_valid; + bool is_valid; } keyboard_shortcut; extern int verbosity; From 2f72f58b4a28242fbc3f15f0179df6535bbe5cf8 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 19:41:30 +0200 Subject: [PATCH 12/51] move stuff from main() to setup() --- dunst.c | 114 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/dunst.c b/dunst.c index 644a0e8..1522cbf 100644 --- a/dunst.c +++ b/dunst.c @@ -1276,25 +1276,69 @@ void update_screen_info() void setup(void) { - Window root; - XSetWindowAttributes wa; - notification_queue = l_init(); - notification_history = l_init(); - displayed_notifications = l_init(); + dc = initdc(); + + initfont(dc, font); + + + init_shortcut(&close_ks); + init_shortcut(&close_all_ks); + init_shortcut(&history_ks); + + grab_key(&close_ks); + ungrab_key(&close_ks); + grab_key(&close_all_ks); + ungrab_key(&close_all_ks); + grab_key(&history_ks); + ungrab_key(&history_ks); + + colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor); + colors[NORM] = initcolor(dc, normfgcolor, normbgcolor); + colors[CRIT] = initcolor(dc, critfgcolor, critbgcolor); + + color_strings[ColFG][LOW] = lowfgcolor; + color_strings[ColFG][NORM] = normfgcolor; + color_strings[ColFG][CRIT] = critfgcolor; + + color_strings[ColBG][LOW] = lowbgcolor; + color_strings[ColBG][NORM] = normbgcolor; + color_strings[ColBG][CRIT] = critbgcolor; + + scr.scr = monitor; + + if (geom[0] == '-') { + geometry.negative_width = true; + geom++; + } else { + geometry.negative_width = false; + } + + geometry.mask = XParseGeometry(geom, + &geometry.x, &geometry.y, + &geometry.w, &geometry.h); + + + screensaver_info = XScreenSaverAllocInfo(); + + window_dim.x = 0; + window_dim.y = 0; + window_dim.w = 0; + window_dim.h = 0; + if (scr.scr < 0) { scr.scr = DefaultScreen(dc->dpy); } + + /* window */ + Window root; + XSetWindowAttributes wa; + root = RootWindow(dc->dpy, DefaultScreen(dc->dpy)); - utf8 = XInternAtom(dc->dpy, "UTF8_STRING", false); - - /* menu geometry */ font_h = dc->font.height + FONT_HEIGHT_BORDER; - update_screen_info(); - /* menu window */ wa.override_redirect = true; wa.background_pixmap = ParentRelative; wa.event_mask = @@ -1536,11 +1580,14 @@ int main(int argc, char *argv[]) { now = time(&now); + notification_queue = l_init(); + notification_history = l_init(); + displayed_notifications = l_init(); rules = l_init(); + for (int i = 0; i < LENGTH(default_rules); i++) { l_push(rules, &default_rules[i]); } - scr.scr = monitor; cmdline_load(argc, argv); @@ -1557,53 +1604,8 @@ int main(int argc, char *argv[]) usage(EXIT_SUCCESS); } - dc = initdc(); - - init_shortcut(&close_ks); - init_shortcut(&close_all_ks); - init_shortcut(&history_ks); - - - if (geom[0] == '-') { - geometry.negative_width = true; - geom++; - } else { - geometry.negative_width = false; - } - - geometry.mask = XParseGeometry(geom, - &geometry.x, &geometry.y, - &geometry.w, &geometry.h); - - - screensaver_info = XScreenSaverAllocInfo(); initdbus(); - initfont(dc, font); - - grab_key(&close_ks); - ungrab_key(&close_ks); - grab_key(&close_all_ks); - ungrab_key(&close_all_ks); - grab_key(&history_ks); - ungrab_key(&history_ks); - - colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor); - colors[NORM] = initcolor(dc, normfgcolor, normbgcolor); - colors[CRIT] = initcolor(dc, critfgcolor, critbgcolor); - - color_strings[ColFG][LOW] = lowfgcolor; - color_strings[ColFG][NORM] = normfgcolor; - color_strings[ColFG][CRIT] = critfgcolor; - - color_strings[ColBG][LOW] = lowbgcolor; - color_strings[ColBG][NORM] = normbgcolor; - color_strings[ColBG][CRIT] = critbgcolor; - - window_dim.x = 0; - window_dim.y = 0; - window_dim.w = 0; - window_dim.h = 0; setup(); if (deprecated_mod) From 3cc299537e1c019e0e61497d3f48b3570bc73a81 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 19:45:18 +0200 Subject: [PATCH 13/51] add some comments to setup() --- dunst.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dunst.c b/dunst.c index 1522cbf..b112a1e 100644 --- a/dunst.c +++ b/dunst.c @@ -1277,11 +1277,11 @@ void update_screen_info() void setup(void) { + /* initialize dc, font, keyboard, colors */ dc = initdc(); initfont(dc, font); - init_shortcut(&close_ks); init_shortcut(&close_all_ks); init_shortcut(&history_ks); @@ -1305,8 +1305,8 @@ void setup(void) color_strings[ColBG][NORM] = normbgcolor; color_strings[ColBG][CRIT] = critbgcolor; - scr.scr = monitor; + /* parse and set geometry and monitor position */ if (geom[0] == '-') { geometry.negative_width = true; geom++; @@ -1318,19 +1318,19 @@ void setup(void) &geometry.x, &geometry.y, &geometry.w, &geometry.h); - - screensaver_info = XScreenSaverAllocInfo(); - window_dim.x = 0; window_dim.y = 0; window_dim.w = 0; window_dim.h = 0; + screensaver_info = XScreenSaverAllocInfo(); + + scr.scr = monitor; if (scr.scr < 0) { scr.scr = DefaultScreen(dc->dpy); } - /* window */ + /* initialize window */ Window root; XSetWindowAttributes wa; From 609f20c99ce74dd552399df39acc4e4b198f3f45 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 19:49:54 +0200 Subject: [PATCH 14/51] indent --no-tabs -linux --- draw.c | 10 +- draw.h | 2 +- dunst.c | 270 +++++++++++++++++++++++++++++++++------------------ dunst.h | 3 +- dunst_dbus.c | 18 ++-- options.c | 62 ++++++------ options.h | 13 ++- utils.c | 5 +- utils.h | 2 +- 9 files changed, 243 insertions(+), 142 deletions(-) diff --git a/draw.c b/draw.c index 159ac7b..663e88a 100644 --- a/draw.c +++ b/draw.c @@ -235,12 +235,12 @@ void initfont(DC * dc, const char *fontstr) return; } -void -setopacity(DC *dc, Window win, unsigned long opacity) +void setopacity(DC * dc, Window win, unsigned long opacity) { - Atom _NET_WM_WINDOW_OPACITY = XInternAtom(dc->dpy, "_NET_WM_WINDOW_OPACITY", false); - XChangeProperty(dc->dpy, win, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)&opacity, 1L); + Atom _NET_WM_WINDOW_OPACITY = + XInternAtom(dc->dpy, "_NET_WM_WINDOW_OPACITY", false); + XChangeProperty(dc->dpy, win, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&opacity, 1L); } void mapdc(DC * dc, Window win, unsigned int w, unsigned int h) diff --git a/draw.h b/draw.h index 117986a..7a5c3be 100644 --- a/draw.h +++ b/draw.h @@ -70,7 +70,7 @@ unsigned long getcolor(DC * dc, const char *colstr); ColorSet *initcolor(DC * dc, const char *foreground, const char *background); DC *initdc(void); void initfont(DC * dc, const char *fontstr); -void setopacity(DC *dc, Window win, unsigned long opacity); +void setopacity(DC * dc, Window win, unsigned long opacity); void mapdc(DC * dc, Window win, unsigned int w, unsigned int h); void resizedc(DC * dc, unsigned int w, unsigned int h); int textnw(DC * dc, const char *text, size_t len); diff --git a/dunst.c b/dunst.c index b112a1e..4a904cd 100644 --- a/dunst.c +++ b/dunst.c @@ -45,7 +45,6 @@ #define INFO 2 #define DEBUG 3 - /* global variables */ #include "config.h" @@ -107,7 +106,7 @@ void warn(const char *text, int urg); void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); -static void print_notification(notification *n) +static void print_notification(notification * n) { printf("{\n"); printf("\tappname: %s\n", n->appname); @@ -154,7 +153,7 @@ static int tear_down_error_handler(void) int grab_key(keyboard_shortcut * ks) { if (!ks->is_valid) - return 1; + return 1; Window root; root = RootWindow(dc->dpy, DefaultScreen(dc->dpy)); @@ -379,9 +378,9 @@ int do_word_wrap(char *source, int max_width) *eol = '\0'; return 1 + do_word_wrap(eol + 1, max_width); } - if (*eol == '\\' && *(eol+1) == 'n') { + if (*eol == '\\' && *(eol + 1) == 'n') { *eol = ' '; - *(eol+1) = '\0'; + *(eol + 1) = '\0'; return 1 + do_word_wrap(eol + 2, max_width); } @@ -404,7 +403,7 @@ int do_word_wrap(char *source, int max_width) return 1 + do_word_wrap(space + 1, max_width); } } - eol++; + eol++; } } @@ -412,7 +411,7 @@ void update_draw_txt_buf(notification * n, int max_width) { rstrip(n->msg); char *msg = n->msg; - while(isspace(*msg)) + while (isspace(*msg)) msg++; if (n->draw_txt_buf.txt) @@ -447,9 +446,10 @@ void update_draw_txt_buf(notification * n, int max_width) char *new_buf; if (hours > 0) { asprintf(&new_buf, "%s (%dh %dm %ds old)", buf, hours, - minutes, seconds); + minutes, seconds); } else if (minutes > 0) { - asprintf(&new_buf, "%s (%dm %ds old)", buf, minutes, seconds); + asprintf(&new_buf, "%s (%dm %ds old)", buf, minutes, + seconds); } else { asprintf(&new_buf, "%s (%ds old)", buf, seconds); } @@ -484,7 +484,8 @@ int calculate_x_offset(int line_width, int text_width) /* If the text is wider than the frame, bouncing is enabled and word_wrap disabled */ if (line_width < text_width && bounce_freq > 0.0001 && !word_wrap) { gettimeofday(&t, NULL); - pos = ((t.tv_sec % 100) * 1e6 + t.tv_usec) / (1e6 / bounce_freq); + pos = + ((t.tv_sec % 100) * 1e6 + t.tv_usec) / (1e6 / bounce_freq); return (1 + sinf(2 * 3.14159 * pos)) * leftover / 2; } switch (align) { @@ -579,8 +580,6 @@ void draw_win(void) line_cnt += n->draw_txt_buf.line_count; } - - /* calculate height */ if (geometry.h == 0) { height = line_cnt * line_height; @@ -590,7 +589,6 @@ void draw_win(void) height += (l_length(displayed_notifications) - 1) * separator_height; - /* add "(x more)" */ draw_txt x_more; x_more.txt = NULL; @@ -612,7 +610,8 @@ void draw_win(void) } else { /* append "(x more)" message to notification text */ notification *n = - (notification *) displayed_notifications->head->data; + (notification *) displayed_notifications->head-> + data; print_to = draw_txt_get_line(&n->draw_txt_buf, n->draw_txt_buf.line_count); @@ -628,7 +627,7 @@ void draw_win(void) notification *n = (notification *) iter->data; for (int i = 0; i < n->draw_txt_buf.line_count; i++) { char *line = - draw_txt_get_line(&n->draw_txt_buf, i+1); + draw_txt_get_line(&n->draw_txt_buf, i + 1); assert(line != NULL); width = MAX(width, textw(dc, line)); } @@ -668,14 +667,16 @@ void draw_win(void) /* draw separator */ if (separator_height > 0) { - dc -> x = 0; + dc->x = 0; double color; if (sep_color == AUTO) - color = calculate_foreground_color(n->colors->BG); + color = + calculate_foreground_color(n->colors->BG); else color = n->colors->FG; - drawrect(dc, 0, 0, width, separator_height, true, color); + drawrect(dc, 0, 0, width, separator_height, true, + color); dc->y += separator_height; } } @@ -703,8 +704,7 @@ void draw_win(void) /* move and map window */ if (x != window_dim.x || y != window_dim.y - || width != window_dim.w - || height != window_dim.h) { + || width != window_dim.w || height != window_dim.h) { XResizeWindow(dc->dpy, win, width, height); XMoveWindow(dc->dpy, win, x, y); @@ -914,7 +914,7 @@ int init_notification(notification * n, int id) n->msg = string_replace("%b", n->body, n->msg); if (n->progress) { char pg[10]; - sprintf(pg, "[%3d%%]", n->progress-1); + sprintf(pg, "[%3d%%]", n->progress - 1); n->msg = string_replace("%p", pg, n->msg); } else { n->msg = string_replace("%p", "", n->msg); @@ -922,14 +922,14 @@ int init_notification(notification * n, int id) n->msg = fix_markup(n->msg); - n->dup_count = 0; n->draw_txt_buf.txt = NULL; /* check if n is a duplicate */ for (l_node * iter = notification_queue->head; iter; iter = iter->next) { notification *orig = (notification *) iter->data; - if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { + if (strcmp(orig->appname, n->appname) == 0 + && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; free_notification(n); return orig->id; @@ -939,7 +939,8 @@ int init_notification(notification * n, int id) for (l_node * iter = displayed_notifications->head; iter; iter = iter->next) { notification *orig = (notification *) iter->data; - if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { + if (strcmp(orig->appname, n->appname) == 0 + && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; orig->start = now; free_notification(n); @@ -978,7 +979,7 @@ int init_notification(notification * n, int id) n->id = id; } - if(strlen(n->msg) == 0) { + if (strlen(n->msg) == 0) { close_notification(n, 2); printf("skipping notification: %s %s\n", n->body, n->summary); } else { @@ -988,7 +989,6 @@ int init_notification(notification * n, int id) if (print_notifications) print_notification(n); - return n->id; } @@ -1100,7 +1100,6 @@ void init_shortcut(keyboard_shortcut * ks) } } - if (ks->sym == NoSymbol || ks->code == NoSymbol) { fprintf(stderr, "Warning: Unknown keyboard shortcut: %s\n", ks->str); @@ -1305,7 +1304,6 @@ void setup(void) color_strings[ColBG][NORM] = normbgcolor; color_strings[ColBG][CRIT] = critbgcolor; - /* parse and set geometry and monitor position */ if (geom[0] == '-') { geometry.negative_width = true; @@ -1352,7 +1350,8 @@ void setup(void) DefaultScreen(dc->dpy)), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); transparency = transparency > 100 ? 100 : transparency; - setopacity(dc, win, (unsigned long)((100 - transparency) * (0xffffffff/100))); + setopacity(dc, win, + (unsigned long)((100 - transparency) * (0xffffffff / 100))); grab_key(&history_ks); } @@ -1444,22 +1443,45 @@ void load_options(char *cmdline_config_path) load_ini_file(config_file); #endif - font = option_get_string("global", "font", "-fn", font, "The font dunst should use."); - format = option_get_string("global", "format", "-format", format, "The format template for the notifictions"); - sort = option_get_bool("global", "sort", "-sort", sort, "Sort notifications by urgency and date?"); - indicate_hidden = option_get_bool("global", "indicate_hidden", "-indicate_hidden", indicate_hidden, "Show how many notificaitons are hidden?"); - word_wrap = option_get_bool("global", "word_wrap", "-word_wrap", word_wrap, "Truncating long lines or do word wrap"); - idle_threshold = option_get_int("global", "idle_threshold", "-idle_threshold", idle_threshold, "Don't timeout notifications if user is longer idle than threshold"); - monitor = option_get_int("global", "monitor", "-mon", monitor, "On which monitor should the notifications be displayed"); + font = + option_get_string("global", "font", "-fn", font, + "The font dunst should use."); + format = + option_get_string("global", "format", "-format", format, + "The format template for the notifictions"); + sort = + option_get_bool("global", "sort", "-sort", sort, + "Sort notifications by urgency and date?"); + indicate_hidden = + option_get_bool("global", "indicate_hidden", "-indicate_hidden", + indicate_hidden, + "Show how many notificaitons are hidden?"); + word_wrap = + option_get_bool("global", "word_wrap", "-word_wrap", word_wrap, + "Truncating long lines or do word wrap"); + idle_threshold = + option_get_int("global", "idle_threshold", "-idle_threshold", + idle_threshold, + "Don't timeout notifications if user is longer idle than threshold"); + monitor = + option_get_int("global", "monitor", "-mon", monitor, + "On which monitor should the notifications be displayed"); { - char *c = option_get_string("global", "follow", "-follow", "", "Follow mouse, keyboard or none?"); + char *c = + option_get_string("global", "follow", "-follow", "", + "Follow mouse, keyboard or none?"); if (strlen(c) > 0) { parse_follow_mode(c); free(c); } } - geom = option_get_string("global", "geometry", "-geom/-geometry", geom, "Geometry for the window"); - line_height = option_get_int("global", "line_height", "-lh/-line_height", line_height, "Add additional padding above and beneath text"); + geom = + option_get_string("global", "geometry", "-geom/-geometry", geom, + "Geometry for the window"); + line_height = + option_get_int("global", "line_height", "-lh/-line_height", + line_height, + "Add additional padding above and beneath text"); { char *c = option_get_string("global", "modifier", NULL, "", ""); if (strlen(c) > 0) { @@ -1471,12 +1493,22 @@ void load_options(char *cmdline_config_path) free(c); } } - close_ks.str = option_get_string("global", "key", NULL, close_ks.str, ""); - close_all_ks.str = option_get_string("global", "all_key", NULL, close_all_ks.str, ""); - history_ks.str = option_get_string("global", "history_key", NULL, history_ks.str, ""); - bounce_freq = option_get_double("global", "bounce_freq", "-bounce_freq", bounce_freq, "Make long text bounce from side to side"); + close_ks.str = + option_get_string("global", "key", NULL, close_ks.str, ""); + close_all_ks.str = + option_get_string("global", "all_key", NULL, close_all_ks.str, ""); + history_ks.str = + option_get_string("global", "history_key", NULL, history_ks.str, + ""); + bounce_freq = + option_get_double("global", "bounce_freq", "-bounce_freq", + bounce_freq, + "Make long text bounce from side to side"); { - char *c = option_get_string("global", "alignment", "-align/-alignment", "", "Align notifications left/center/right"); + char *c = + option_get_string("global", "alignment", + "-align/-alignment", "", + "Align notifications left/center/right"); if (strlen(c) > 0) { if (strcmp(c, "left") == 0) align = left; @@ -1485,42 +1517,91 @@ void load_options(char *cmdline_config_path) else if (strcmp(c, "right") == 0) align = right; else - fprintf(stderr, "Warning: unknown allignment\n"); + fprintf(stderr, + "Warning: unknown allignment\n"); free(c); } } - show_age_threshold = option_get_int("global", "show_age_threshold", "-show_age_threshold", show_age_threshold, "When should the age of the notification be displayed?"); - sticky_history = option_get_bool("global", "sticky_history", "-sticky_history", sticky_history, "Don't timeout notifications popped up from history"); - separator_height = option_get_int("global", "separator_height", "-sep_height/-separator_height", separator_height, "height of the separator line"); - transparency = option_get_int("global", "transparency", "-transparency", transparency, "Transparency. range 0-100"); + show_age_threshold = + option_get_int("global", "show_age_threshold", + "-show_age_threshold", show_age_threshold, + "When should the age of the notification be displayed?"); + sticky_history = + option_get_bool("global", "sticky_history", "-sticky_history", + sticky_history, + "Don't timeout notifications popped up from history"); + separator_height = + option_get_int("global", "separator_height", + "-sep_height/-separator_height", separator_height, + "height of the separator line"); + transparency = + option_get_int("global", "transparency", "-transparency", + transparency, "Transparency. range 0-100"); { - char *c = option_get_string("global", "separator_color", "-sep_color/-separator_color", "", "Color of the separator line (or 'auto')"); + char *c = + option_get_string("global", "separator_color", + "-sep_color/-separator_color", "", + "Color of the separator line (or 'auto')"); if (strlen(c) > 0) { if (strcmp(c, "auto") == 0) sep_color = AUTO; else if (strcmp(c, "foreground") == 0) sep_color = FOREGROUND; else - fprintf(stderr, "Warning: Unknown separator color\n"); + fprintf(stderr, + "Warning: Unknown separator color\n"); free(c); } } - lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor, "Background color for notifcations with low urgency"); - lowfgcolor = option_get_string("urgency_low", "foreground", "-lf", lowfgcolor, "Foreground color for notifications with low urgency"); - timeouts[LOW] = option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW], "Timeout for notifications with low urgency"); - normbgcolor = option_get_string("urgency_normal", "background", "-nb", normbgcolor, "Background color for notifications with normal urgency"); - normfgcolor = option_get_string("urgency_normal", "foreground", "-nf", normfgcolor, "Foreground color for notifications with normal urgency"); - timeouts[NORM] = option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM], "Timeout for notifications with normal urgency"); - critbgcolor = option_get_string("urgency_critical", "background", "-cb", critbgcolor, "Background color for notifications with critical urgency"); - critfgcolor = option_get_string("urgency_critical", "foreground", "-cf", critfgcolor, "Foreground color for notifications with ciritical urgency"); - timeouts[CRIT] = option_get_int("urgency_critical", "timeout", "-cto", timeouts[CRIT], "Timeout for notifications with critical urgency"); + lowbgcolor = + option_get_string("urgency_low", "background", "-lb", lowbgcolor, + "Background color for notifcations with low urgency"); + lowfgcolor = + option_get_string("urgency_low", "foreground", "-lf", lowfgcolor, + "Foreground color for notifications with low urgency"); + timeouts[LOW] = + option_get_int("urgency_low", "timeout", "-lto", timeouts[LOW], + "Timeout for notifications with low urgency"); + normbgcolor = + option_get_string("urgency_normal", "background", "-nb", + normbgcolor, + "Background color for notifications with normal urgency"); + normfgcolor = + option_get_string("urgency_normal", "foreground", "-nf", + normfgcolor, + "Foreground color for notifications with normal urgency"); + timeouts[NORM] = + option_get_int("urgency_normal", "timeout", "-nto", timeouts[NORM], + "Timeout for notifications with normal urgency"); + critbgcolor = + option_get_string("urgency_critical", "background", "-cb", + critbgcolor, + "Background color for notifications with critical urgency"); + critfgcolor = + option_get_string("urgency_critical", "foreground", "-cf", + critfgcolor, + "Foreground color for notifications with ciritical urgency"); + timeouts[CRIT] = + option_get_int("urgency_critical", "timeout", "-cto", + timeouts[CRIT], + "Timeout for notifications with critical urgency"); - close_ks.str = option_get_string("shortcuts", "close", "-key", close_ks.str, "Shortcut for closing one notification"); - close_all_ks.str = option_get_string("shortcuts", "close_all", "-all_key", close_all_ks.str, "Shortcut for closing all notifications"); - history_ks.str = option_get_string("shortcuts", "history", "-history_key", history_ks.str, "Shortcut to pop the last notification from history"); + close_ks.str = + option_get_string("shortcuts", "close", "-key", close_ks.str, + "Shortcut for closing one notification"); + close_all_ks.str = + option_get_string("shortcuts", "close_all", "-all_key", + close_all_ks.str, + "Shortcut for closing all notifications"); + history_ks.str = + option_get_string("shortcuts", "history", "-history_key", + history_ks.str, + "Shortcut to pop the last notification from history"); - print_notifications = cmdline_get_bool("-print", false, "Print notifications to cmdline (DEBUG)"); + print_notifications = + cmdline_get_bool("-print", false, + "Print notifications to cmdline (DEBUG)"); char *cur_section = NULL; for (;;) { @@ -1528,23 +1609,25 @@ void load_options(char *cmdline_config_path) if (!cur_section) break; if (strcmp(cur_section, "global") == 0 - || strcmp(cur_section, "shortcuts") == 0 - || strcmp(cur_section, "urgency_low") == 0 - || strcmp(cur_section, "urgency_normal") == 0 - || strcmp(cur_section, "urgency_critical") == 0) + || strcmp(cur_section, "shortcuts") == 0 + || strcmp(cur_section, "urgency_low") == 0 + || strcmp(cur_section, "urgency_normal") == 0 + || strcmp(cur_section, "urgency_critical") == 0) continue; rule_t *current_rule = dunst_rules_find_or_create(cur_section); - current_rule->appname = ini_get_string( - cur_section, "appname", current_rule->appname); - current_rule->summary = ini_get_string( - cur_section, "summary", current_rule->summary); - current_rule->body = ini_get_string( - cur_section, "body", current_rule->body); - current_rule->icon = ini_get_string( - cur_section, "icon", current_rule->icon); - current_rule->timeout = ini_get_int( - cur_section, "timeout", current_rule->timeout); + current_rule->appname = + ini_get_string(cur_section, "appname", + current_rule->appname); + current_rule->summary = + ini_get_string(cur_section, "summary", + current_rule->summary); + current_rule->body = + ini_get_string(cur_section, "body", current_rule->body); + current_rule->icon = + ini_get_string(cur_section, "icon", current_rule->icon); + current_rule->timeout = + ini_get_int(cur_section, "timeout", current_rule->timeout); { char *urg = ini_get_string(cur_section, "urgency", ""); if (strlen(urg) > 0) { @@ -1556,16 +1639,17 @@ void load_options(char *cmdline_config_path) current_rule->urgency = CRIT; else fprintf(stderr, - "unknown urgency: %s, ignoring\n", urg); + "unknown urgency: %s, ignoring\n", + urg); free(urg); } } - current_rule->fg = ini_get_string( - cur_section, "foreground", current_rule->fg); - current_rule->bg = ini_get_string( - cur_section, "background", current_rule->bg); - current_rule->format = ini_get_string( - cur_section, "format", current_rule->format); + current_rule->fg = + ini_get_string(cur_section, "foreground", current_rule->fg); + current_rule->bg = + ini_get_string(cur_section, "background", current_rule->bg); + current_rule->format = + ini_get_string(cur_section, "format", current_rule->format); } #ifndef STATIC_CONFIG @@ -1575,7 +1659,6 @@ void load_options(char *cmdline_config_path) #endif } - int main(int argc, char *argv[]) { now = time(&now); @@ -1591,20 +1674,22 @@ int main(int argc, char *argv[]) cmdline_load(argc, argv); - - if (cmdline_get_bool("-v/-version", false, "Print version") || cmdline_get_bool("--version", false, "Print version")) { + if (cmdline_get_bool("-v/-version", false, "Print version") + || cmdline_get_bool("--version", false, "Print version")) { print_version(); } char *cmdline_config_path; - cmdline_config_path = cmdline_get_string("-conf/-config", NULL, "Path to configuration file"); + cmdline_config_path = + cmdline_get_string("-conf/-config", NULL, + "Path to configuration file"); load_options(cmdline_config_path); - if (cmdline_get_bool("-h/-help", false, "Print help") || cmdline_get_bool("--help", false, "Print help")) { + if (cmdline_get_bool("-h/-help", false, "Print help") + || cmdline_get_bool("--help", false, "Print help")) { usage(EXIT_SUCCESS); } - initdbus(); setup(); @@ -1628,7 +1713,8 @@ void usage(int exit_status) void print_version(void) { - printf("Dunst - a dmenu-ish notification-daemon, version: %s\n", VERSION); + printf("Dunst - a dmenu-ish notification-daemon, version: %s\n", + VERSION); exit(EXIT_SUCCESS); } diff --git a/dunst.h b/dunst.h index b390998..e56e8d4 100644 --- a/dunst.h +++ b/dunst.h @@ -14,7 +14,6 @@ #define ColFG 1 #define ColBG 0 - enum alignment { left, center, right }; enum separator_color { FOREGROUND, AUTO }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; @@ -51,7 +50,7 @@ typedef struct _notification { time_t timestamp; int timeout; int urgency; - bool redisplayed; /* has been displayed before? */ + bool redisplayed; /* has been displayed before? */ int id; int dup_count; ColorSet *colors; diff --git a/dunst_dbus.c b/dunst_dbus.c index 8590af5..e7a40af 100644 --- a/dunst_dbus.c +++ b/dunst_dbus.c @@ -336,11 +336,17 @@ void notify(DBusMessage * dmsg) continue; } dbus_message_iter_get_basic(&hint, &hint_name); - _extract_hint(DBUS_TYPE_BYTE, "urgency", hint_name, &hint, &urgency); - _extract_hint(DBUS_TYPE_STRING, "fgcolor", hint_name, &hint, &fgcolor); - _extract_hint(DBUS_TYPE_STRING, "bgcolor", hint_name, &hint, &bgcolor); - _extract_hint(DBUS_TYPE_INT32, "value", hint_name, &hint, &progress); - if (!progress) _extract_hint(DBUS_TYPE_UINT32, "value", hint_name, &hint, &progress); + _extract_hint(DBUS_TYPE_BYTE, "urgency", hint_name, + &hint, &urgency); + _extract_hint(DBUS_TYPE_STRING, "fgcolor", hint_name, + &hint, &fgcolor); + _extract_hint(DBUS_TYPE_STRING, "bgcolor", hint_name, + &hint, &bgcolor); + _extract_hint(DBUS_TYPE_INT32, "value", hint_name, + &hint, &progress); + if (!progress) + _extract_hint(DBUS_TYPE_UINT32, "value", + hint_name, &hint, &progress); dbus_message_iter_next(&hint); } dbus_message_iter_next(&hints); @@ -358,7 +364,7 @@ void notify(DBusMessage * dmsg) n->body = body != NULL ? strdup(body) : ""; n->icon = icon != NULL ? strdup(icon) : ""; n->timeout = expires; - n->progress = (progress < 0 || progress > 100) ? 0 : progress+1; + n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1; n->urgency = urgency; n->dbus_client = strdup(dbus_message_get_sender(dmsg)); for (i = 0; i < ColLast; i++) { diff --git a/options.c b/options.c index 225b47d..29c0e58 100644 --- a/options.c +++ b/options.c @@ -11,20 +11,16 @@ #include "utils.h" typedef struct _entry_t { - char *key; - char *value; + char *key; + char *value; } entry_t; typedef struct _section_t { - char *name; - int entry_count; - entry_t *entries; + char *name; + int entry_count; + entry_t *entries; } section_t; - - - - static int section_count = 0; static section_t *sections; @@ -45,16 +41,16 @@ static int cmdline_find_option(char *key); section_t *new_section(char *name) { section_count++; - sections = realloc(sections, sizeof(section_t) *section_count); + sections = realloc(sections, sizeof(section_t) * section_count); sections[section_count - 1].name = strdup(name); sections[section_count - 1].entries = NULL; sections[section_count - 1].entry_count = 0; - return §ions[section_count -1]; + return §ions[section_count - 1]; } void free_ini(void) { - for(int i = 0; i < section_count; i++) { + for (int i = 0; i < section_count; i++) { for (int j = 0; j < sections[i].entry_count; j++) { free(sections[i].entries[j].key); free(sections[i].entries[j].value); @@ -145,7 +141,7 @@ char *next_section(char *section) if (i + 1 >= section_count) return NULL; else - return sections[i+1].name; + return sections[i + 1].name; } } return NULL; @@ -192,7 +188,7 @@ char *clean_value(char *value) } -int load_ini_file(FILE *fp) +int load_ini_file(FILE * fp) { char line[BUFSIZ]; @@ -209,7 +205,9 @@ int load_ini_file(FILE *fp) if (*start == '[') { char *end = strstr(start + 1, "]"); if (!end) { - printf("Warning: invalid config file at line %d\n", line_num); + printf + ("Warning: invalid config file at line %d\n", + line_num); printf("Missing ']'\n"); continue; } @@ -218,27 +216,30 @@ int load_ini_file(FILE *fp) if (current_section) free(current_section); - current_section = (strdup(start+1)); + current_section = (strdup(start + 1)); new_section(current_section); continue; } char *equal = strstr(start + 1, "="); if (!equal) { - printf("Warning: invalid config file at line %d\n", line_num); + printf("Warning: invalid config file at line %d\n", + line_num); printf("Missing '='\n"); continue; } *equal = '\0'; char *key = rstrip(start); - char *value = lskip(equal+1); + char *value = lskip(equal + 1); char *quote = strstr(value, "\""); if (quote) { char *closing_quote = strstr(quote + 1, "\""); if (!closing_quote) { - printf("Warning: invalid config file at line %d\n", line_num); + printf + ("Warning: invalid config file at line %d\n", + line_num); printf("Missing '\"'\n"); continue; } @@ -254,7 +255,8 @@ int load_ini_file(FILE *fp) value = rstrip(value); if (!current_section) { - printf("Warning: invalid config file at line: %d\n", line_num); + printf("Warning: invalid config file at line: %d\n", + line_num); printf("Key value pair without a section\n"); continue; } @@ -314,12 +316,13 @@ static char *cmdline_get_value(char *key) return NULL; } - if (idx + 1 >= cmdline_argc || cmdline_argv[idx+1][0] == '-') { + if (idx + 1 >= cmdline_argc || cmdline_argv[idx + 1][0] == '-') { /* the argument is missing */ - fprintf(stderr, "Warning: %s, missing argument. Ignoring\n", key); + fprintf(stderr, "Warning: %s, missing argument. Ignoring\n", + key); return NULL; } - return cmdline_argv[idx+1]; + return cmdline_argv[idx + 1]; } char *cmdline_get_string(char *key, char *def, char *description) @@ -364,7 +367,8 @@ int cmdline_get_bool(char *key, int def, char *description) return def; } -char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def, char *description) +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, + char *def, char *description) { char *val = NULL; @@ -380,7 +384,8 @@ char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, cha } -int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description) +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, + char *description) { /* *str is only used to check wether the cmdline option is actually set. */ char *str = cmdline_get_value(cmdline_key); @@ -395,7 +400,8 @@ int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, return val; } -double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def, char *description) +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, + double def, char *description) { char *str = cmdline_get_value(cmdline_key); double val = cmdline_get_double(cmdline_key, def, description); @@ -406,7 +412,8 @@ double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, do return val; } -int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description) +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, + int def, char *description) { int val; @@ -449,4 +456,5 @@ char *cmdline_create_usage(void) { return strdup(usage_str); } + /* vim: set ts=8 sw=8 tw=0: */ diff --git a/options.h b/options.h index e752e9e..dd34a79 100644 --- a/options.h +++ b/options.h @@ -3,7 +3,6 @@ #include - int load_ini_file(FILE *); char *ini_get_string(char *section, char *key, const char *def); int ini_get_int(char *section, char *key, int def); @@ -19,10 +18,14 @@ double cmdline_get_double(char *key, double def, char *description); int cmdline_get_bool(char *key, int def, char *description); char *cmdline_create_usage(void); -char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, char *def, char *description); -int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description); -double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, double def, char *description); -int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description); +char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, + char *def, char *description); +int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, + char *description); +double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, + double def, char *description); +int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, + int def, char *description); /* returns the next known section. * if section == NULL returns first section. diff --git a/utils.c b/utils.c index e587429..895af89 100644 --- a/utils.c +++ b/utils.c @@ -6,7 +6,6 @@ #include "utils.h" #include "dunst.h" - char *rstrip(char *str) { char *end; @@ -20,7 +19,7 @@ char *rstrip(char *str) char *lskip(char *s) { - for(; *s && isspace(*s); s++); + for (; *s && isspace(*s); s++) ; return s; } @@ -54,7 +53,7 @@ char *string_replace(const char *needle, const char *replacement, int digit_count(int i) { int len = 0; - if ( i == 0) { + if (i == 0) { return 1; } diff --git a/utils.h b/utils.h index 8995b01..3d3774f 100644 --- a/utils.h +++ b/utils.h @@ -9,7 +9,7 @@ char *string_replace(const char *needle, const char *replacement, char *haystack); /* exit with an error message */ -void die(char * msg, int exit_value); +void die(char *msg, int exit_value); int digit_count(int i); From 02a3bce7abc1aaca0fbb51108e4b706f26793247 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 20 Oct 2012 19:51:11 +0200 Subject: [PATCH 15/51] initialize val in option_get_bool --- options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/options.c b/options.c index 29c0e58..42e1203 100644 --- a/options.c +++ b/options.c @@ -415,7 +415,7 @@ double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, int option_get_bool(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description) { - int val; + int val = false; if (cmdline_key) val = cmdline_get_bool(cmdline_key, false, description); From eb09078de6e73fedbae85e4f29394516bc81b8c6 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 21 Nov 2012 17:43:45 +0100 Subject: [PATCH 16/51] define VERSION if not defined --- dunst.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dunst.c b/dunst.c index 4a904cd..fd8e456 100644 --- a/dunst.c +++ b/dunst.c @@ -41,6 +41,10 @@ #define DEFFONT "Monospace-11" +#ifndef VERSION +#define VERSION 0 +#endif + #define MSG 1 #define INFO 2 #define DEBUG 3 From b074699a0a10e8e13e9f094067fa66ce6e5cf6ee Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Thu, 22 Nov 2012 13:43:59 +0100 Subject: [PATCH 17/51] remove unused function definitions --- dunst.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dunst.c b/dunst.c index fd8e456..4338645 100644 --- a/dunst.c +++ b/dunst.c @@ -86,7 +86,6 @@ list *notification_history = NULL; /* history of displayed notifications */ /* misc funtions */ void apply_rules(notification * n); void check_timeouts(void); -void draw_notifications(void); char *fix_markup(char *str); void handle_mouse_click(XEvent ev); void handleXEvents(void); @@ -97,7 +96,6 @@ void run(void); void setup(void); void update_screen_info(); void usage(int exit_status); -void hide_window(); l_node *most_important(list * l); void draw_win(void); void hide_win(void); From a509b80c479da3e1e93ba0c20da6e0a64e9c8ec9 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 5 Dec 2012 18:14:09 +0100 Subject: [PATCH 18/51] only react to Expose events when we are running --- dunst.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dunst.c b/dunst.c index 4338645..7debb34 100644 --- a/dunst.c +++ b/dunst.c @@ -804,9 +804,10 @@ void handleXEvents(void) XNextEvent(dc->dpy, &ev); switch (ev.type) { case Expose: - if (ev.xexpose.count == 0) + if (ev.xexpose.count == 0 && visible) { draw_win(); - mapdc(dc, win, scr.dim.w, font_h); + mapdc(dc, win, scr.dim.w, font_h); + } break; case SelectionNotify: if (ev.xselection.property == utf8) From 808b37508a1af59bcfae19c92dd13fcac5dd666d Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 5 Dec 2012 19:03:28 +0100 Subject: [PATCH 19/51] pause end resume --- dunst.c | 20 ++++++++++++++++++++ dunst_dbus.c | 4 +++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index 7debb34..8412a4c 100644 --- a/dunst.c +++ b/dunst.c @@ -70,6 +70,7 @@ static XScreenSaverInfo *screensaver_info; static int font_h; static bool print_notifications = false; static dimension_t window_dim; +static bool pause_display = false; bool dunst_grab_errored = false; @@ -323,6 +324,13 @@ void update_lists() check_timeouts(); + if (pause_display) { + while (!l_is_empty(displayed_notifications)) { + l_move(displayed_notifications, notification_queue, displayed_notifications->head); + } + return; + } + if (geometry.h == 0) { limit = 0; } else if (geometry.h == 1) { @@ -333,6 +341,7 @@ void update_lists() limit = geometry.h; } + /* move notifications from queue to displayed */ while (!l_is_empty(notification_queue)) { @@ -906,6 +915,17 @@ int init_notification(notification * n, int id) if (n == NULL) return -1; + + if (strcmp("DUNST_COMMAND_PAUSE", n->summary) == 0) { + pause_display = true; + return 0; + } + + if (strcmp("DUNST_COMMAND_RESUME", n->summary) == 0) { + pause_display = false; + return 0; + } + n->format = format; apply_rules(n); diff --git a/dunst_dbus.c b/dunst_dbus.c index e7a40af..f36745d 100644 --- a/dunst_dbus.c +++ b/dunst_dbus.c @@ -372,8 +372,10 @@ void notify(DBusMessage * dmsg) } n->color_strings[ColFG] = fgcolor == NULL ? NULL : strdup(fgcolor); n->color_strings[ColBG] = bgcolor == NULL ? NULL : strdup(bgcolor); + id = init_notification(n, replaces_id); - map_win(); + if (id > 0) + map_win(); reply = dbus_message_new_method_return(dmsg); From 5c4469d56a68bb50ebdd86b63ab40470c361120b Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 5 Dec 2012 20:11:49 +0100 Subject: [PATCH 20/51] fix compiler warnings --- options.c | 19 ++++++++++++------- options.h | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/options.c b/options.c index 42e1203..ab90b57 100644 --- a/options.c +++ b/options.c @@ -103,10 +103,13 @@ char *get_value(char *section, char *key) char *ini_get_string(char *section, char *key, const char *def) { char *value = get_value(section, key); - if (value == NULL) - return def; - else + if (value) return strdup(value); + + if (def == NULL) + return NULL; + else + return strdup(def); } int ini_get_int(char *section, char *key, int def) @@ -325,15 +328,17 @@ static char *cmdline_get_value(char *key) return cmdline_argv[idx + 1]; } -char *cmdline_get_string(char *key, char *def, char *description) +char *cmdline_get_string(char *key, const char *def, char *description) { cmdline_usage_append(key, "string", description); char *str = cmdline_get_value(key); if (str) - return str; + return strdup(str); + if (def == NULL) + return NULL; else - return def; + return strdup(def); } int cmdline_get_int(char *key, int def, char *description) @@ -368,7 +373,7 @@ int cmdline_get_bool(char *key, int def, char *description) } char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, - char *def, char *description) + const char *def, char *description) { char *val = NULL; diff --git a/options.h b/options.h index dd34a79..13cf490 100644 --- a/options.h +++ b/options.h @@ -12,14 +12,14 @@ void free_ini(void); void cmdline_load(int argc, char *argv[]); /* for all cmdline_get_* key can be either "-key" or "-key/-longkey" */ -char *cmdline_get_string(char *key, char *def, char *description); +char *cmdline_get_string(char *key, const char *def, char *description); int cmdline_get_int(char *key, int def, char *description); double cmdline_get_double(char *key, double def, char *description); int cmdline_get_bool(char *key, int def, char *description); char *cmdline_create_usage(void); char *option_get_string(char *ini_section, char *ini_key, char *cmdline_key, - char *def, char *description); + const char *def, char *description); int option_get_int(char *ini_section, char *ini_key, char *cmdline_key, int def, char *description); double option_get_double(char *ini_section, char *ini_key, char *cmdline_key, From 62ecd76cfe210b223dd71831942910ea5b9c7c8b Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 5 Dec 2012 20:40:11 +0100 Subject: [PATCH 21/51] add pause/resume info to manpage --- README.pod | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.pod b/README.pod index 2cf685c..36e7cbd 100644 --- a/README.pod +++ b/README.pod @@ -145,6 +145,14 @@ The progress value can be set with a hint, too. =back +=head1 MISCELLANEOUS + +Dunst can be paused by sending a notification with a summary of "DUNST_COMMAND_PAUSE" +and resumed with a summary of "DUNST_COMMAND_RESUME". +When paused dunst will not display any notifications but keep all notifications in a queue. +This can for example be wrapped around a screen locker (i3lock, slock) to prevent flickering +of notifications through the lock and to read all missed notifications after returning to the computer. + =head1 CONFIGURATION An example configuration file is included (usually /usr/share/dunst/dunstrc). From ae2114512170805acfcb3ea3f0e9c9f9245bbcc9 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Fri, 7 Dec 2012 05:16:48 +0100 Subject: [PATCH 22/51] non recursive string_replace Previous to this commit a replacement that also contains the needle would cause an endless loop --- utils.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/utils.c b/utils.c index 895af89..ef1b133 100644 --- a/utils.c +++ b/utils.c @@ -43,11 +43,7 @@ char *string_replace(const char *needle, const char *replacement, sprintf(tmp + strlen(tmp), "%s%s", replacement, start + strlen(needle)); free(haystack); - if (strstr(tmp, needle)) { - return string_replace(needle, replacement, tmp); - } else { - return tmp; - } + return tmp; } int digit_count(int i) From d53ad1b3765babcb58061310d6017c0f956c4918 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 8 Dec 2012 15:24:06 +0100 Subject: [PATCH 23/51] remove unused #include --- dunst.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dunst.c b/dunst.c index 8412a4c..af91632 100644 --- a/dunst.c +++ b/dunst.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include From a378aa9b196f5f73fcfcc278c72fa40b2ee0d6aa Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 8 Dec 2012 15:42:44 +0100 Subject: [PATCH 24/51] pause/unpause via SIGUSR1/SIGUSR2 --- README.pod | 9 ++++++++- dunst.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.pod b/README.pod index 36e7cbd..10a9662 100644 --- a/README.pod +++ b/README.pod @@ -148,7 +148,14 @@ The progress value can be set with a hint, too. =head1 MISCELLANEOUS Dunst can be paused by sending a notification with a summary of "DUNST_COMMAND_PAUSE" -and resumed with a summary of "DUNST_COMMAND_RESUME". +and resumed with a summary of "DUNST_COMMAND_RESUME". Alternatively you can send SIGUSR1 and SIGUSR2 to pause and unpause respectivly. For Example: + +=item killall -SIGUSR1 dunst # pause + +=item killall -SIGUSR2 dunst # resume + +=back + When paused dunst will not display any notifications but keep all notifications in a queue. This can for example be wrapped around a screen locker (i3lock, slock) to prevent flickering of notifications through the lock and to read all missed notifications after returning to the computer. diff --git a/dunst.c b/dunst.c index af91632..abd63e4 100644 --- a/dunst.c +++ b/dunst.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -108,6 +109,18 @@ void warn(const char *text, int urg); void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); +void pause_signal_handler(int sig) +{ + if (sig == SIGUSR1) { + pause_display = true; + } + if (sig == SIGUSR2) { + pause_display = false; + } + + signal (sig, pause_signal_handler); +} + static void print_notification(notification * n) { printf("{\n"); @@ -1714,6 +1727,8 @@ int main(int argc, char *argv[]) initdbus(); setup(); + signal (SIGUSR1, pause_signal_handler); + signal (SIGUSR2, pause_signal_handler); if (deprecated_mod) warn("-mod is deprecated. Use \"-key mod+key\" instead\n", From 69c55f25e54c241d931b2794d354f1ac8a55ac59 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Tue, 11 Dec 2012 00:07:56 +0100 Subject: [PATCH 25/51] include missing stdbool.h in draw.h --- draw.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/draw.h b/draw.h index 7a5c3be..6746cbb 100644 --- a/draw.h +++ b/draw.h @@ -33,6 +33,8 @@ DEALINGS IN THE SOFTWARE. #ifndef DRAW_H #define DRAW_H +#include + #include typedef struct { From e16b1764f8f5093fe9c687070b86dcbb0ad0920b Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Tue, 11 Dec 2012 00:08:34 +0100 Subject: [PATCH 26/51] refactor draw_win --- dunst.c | 231 ++++++++++++++++++++++++++++---------------------------- dunst.h | 20 +++-- 2 files changed, 128 insertions(+), 123 deletions(-) diff --git a/dunst.c b/dunst.c index abd63e4..27d2bd2 100644 --- a/dunst.c +++ b/dunst.c @@ -72,6 +72,8 @@ static bool print_notifications = false; static dimension_t window_dim; static bool pause_display = false; +static r_line_cache line_cache; + bool dunst_grab_errored = false; int next_notification_id = 1; @@ -103,6 +105,10 @@ void hide_win(void); void move_all_to_history(void); void print_version(void); +void r_line_cache_init(r_line_cache *c); +void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col); +void r_line_cache_reset(r_line_cache *c); + /* show warning notification */ void warn(const char *text, int urg); @@ -383,6 +389,40 @@ void update_lists() } } +void r_line_cache_init(r_line_cache *c) +{ + c->count = 0; + c->size = 0; + c->lines = NULL; +} + +void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col) +{ + if (!c || !s) + return; + + /* resize cache if it's too small */ + if (c->count >= c->size) { + c->size++; + c->lines = realloc(c->lines, c->size * sizeof(r_line)); + } + + c->count++; + c->lines[c->count-1].colors = col; + c->lines[c->count-1].str = strdup(s); +} + +void r_line_cache_reset(r_line_cache *c) +{ + for (int i = 0; i < c->count; i++) { + if (c->lines[i].str) + free(c->lines[i].str); + c->lines[i].str = NULL; + c->lines[i].colors = NULL; + } + c->count = 0; +} + /* TODO get draw_txt_buf as argument */ int do_word_wrap(char *source, int max_width) { @@ -430,16 +470,13 @@ int do_word_wrap(char *source, int max_width) } } -void update_draw_txt_buf(notification * n, int max_width) +void add_notification_to_line_cache(notification *n, int max_width) { rstrip(n->msg); char *msg = n->msg; while (isspace(*msg)) msg++; - if (n->draw_txt_buf.txt) - free(n->draw_txt_buf.txt); - char *buf; /* print dup_count */ @@ -481,22 +518,18 @@ void update_draw_txt_buf(notification * n, int max_width) buf = new_buf; } - n->draw_txt_buf.line_count = do_word_wrap(buf, max_width); - n->draw_txt_buf.txt = buf; -} -char *draw_txt_get_line(draw_txt * dt, int line) -{ - if (line > dt->line_count) { - return NULL; + int linecnt = do_word_wrap(buf, max_width); + n->line_count = linecnt; + char *cur = buf; + for (int i = 0; i < linecnt; i++) { + r_line_cache_append(&line_cache, cur, n->colors); + + while (*cur != '\0') + cur++; + cur++; } - - char *begin = dt->txt; - for (int i = 1; i < line; i++) { - begin += strlen(begin) + 1; - } - - return begin; + free(buf); } int calculate_x_offset(int line_width, int text_width) @@ -570,148 +603,114 @@ unsigned long calculate_foreground_color(unsigned long source_color) return color.pixel; } -void draw_win(void) +int calculate_width(void) { - int width, x, y, height; - - line_height = MAX(line_height, font_h); - - update_screen_info(); - - /* calculate width */ if (geometry.mask & WidthValue && geometry.w == 0) { /* dynamic width */ - width = 0; + return 0; } else if (geometry.mask & WidthValue) { /* fixed width */ if (geometry.negative_width) { - width = scr.dim.w - geometry.w; + return scr.dim.w - geometry.w; } else { - width = geometry.w; + return geometry.w; } } else { /* across the screen */ - width = scr.dim.w; + return scr.dim.w; } +} - /* update draw_txt_bufs and line_cnt */ - int line_cnt = 0; + +void draw_win(void) +{ + + r_line_cache_reset(&line_cache); + update_screen_info(); + int width = calculate_width(); + + + line_height = MAX(line_height, font_h); + + + /* create cache with all lines */ for (l_node * iter = displayed_notifications->head; iter; iter = iter->next) { notification *n = (notification *) iter->data; - update_draw_txt_buf(n, width); - line_cnt += n->draw_txt_buf.line_count; + add_notification_to_line_cache(n, width); } - /* calculate height */ - if (geometry.h == 0) { - height = line_cnt * line_height; - } else { - height = MAX(geometry.h, (line_cnt * line_height)); - } - - height += (l_length(displayed_notifications) - 1) * separator_height; - - /* add "(x more)" */ - draw_txt x_more; - x_more.txt = NULL; - - char *print_to; - int more = l_length(notification_queue); - if (indicate_hidden && more > 0) { - - int x_more_len = strlen(" ( more) ") + digit_count(more); + assert(line_cache.count > 0); + /* add (x more) */ + int queue_cnt = l_length(notification_queue); + if (indicate_hidden && queue_cnt > 0) { if (geometry.h != 1) { - /* add additional line */ - x_more.txt = calloc(x_more_len, sizeof(char)); - height += line_height; - line_cnt++; - - print_to = x_more.txt; - + char *tmp; + asprintf(&tmp, "(%d more)", queue_cnt); + ColorSet *last_colors = + line_cache.lines[line_cache.count-1].colors; + r_line_cache_append(&line_cache, strdup(tmp), last_colors); + free(tmp); } else { - /* append "(x more)" message to notification text */ - notification *n = - (notification *) displayed_notifications->head-> - data; - print_to = - draw_txt_get_line(&n->draw_txt_buf, - n->draw_txt_buf.line_count); - for (; *print_to != '\0'; print_to++) ; + char *old = line_cache.lines[0].str; + char *new; + asprintf(&new, "%s (%d more)", old, queue_cnt); + free(old); + line_cache.lines[0].str = new; } - snprintf(print_to, x_more_len, "(%d more)", more); } + /* if we have a dynamic width, calculate the actual width */ if (width == 0) { - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *n = (notification *) iter->data; - for (int i = 0; i < n->draw_txt_buf.line_count; i++) { - char *line = - draw_txt_get_line(&n->draw_txt_buf, i + 1); - assert(line != NULL); - width = MAX(width, textw(dc, line)); - } + for (int i = 0; i < line_cache.count; i++) { + char *line = line_cache.lines[i].str; + width = MAX(width, textw(dc, line)); } } - assert(line_height > 0); - assert(font_h > 0); - assert(width > 0); - assert(height > 0); - assert(line_cnt > 0); + /* resize dc to correct width */ + + int height = (line_cache.count * line_height) + + ((line_cache.count - 1) * separator_height); + resizedc(dc, width, height); - /* draw buffers */ dc->y = 0; - ColorSet *last_color; - assert(displayed_notifications->head != NULL); - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *n = (notification *) iter->data; - last_color = n->colors; + for (int i = 0; i < line_cache.count; i++) { + dc->x = 0; - for (int i = 0; i < n->draw_txt_buf.line_count; i++) { + r_line line = line_cache.lines[i]; - char *line = draw_txt_get_line(&n->draw_txt_buf, i + 1); - dc->x = 0; - drawrect(dc, 0, 0, width, line_height, true, - n->colors->BG); - dc->x = calculate_x_offset(width, textw(dc, line)); - dc->y += (line_height - font_h) / 2; - drawtextn(dc, line, strlen(line), n->colors); - dc->y += line_height - ((line_height - font_h) / 2); - } + /* draw background */ + drawrect(dc, 0, 0, width, line_height, true, line.colors->BG); + + /* draw text */ + dc->x = calculate_x_offset(width, textw(dc, line.str)); + dc->y += (line_height - font_h) / 2; + drawtextn(dc, line.str, strlen(line.str), line.colors); + dc->y += line_height - ((line_height - font_h) / 2); /* draw separator */ - if (separator_height > 0) { + if (separator_height > 0 && i < line_cache.count - 1) { dc->x = 0; double color; if (sep_color == AUTO) - color = - calculate_foreground_color(n->colors->BG); + color = calculate_foreground_color(line.colors->BG); else - color = n->colors->FG; - - drawrect(dc, 0, 0, width, separator_height, true, - color); + color = line.colors->FG; + drawrect(dc, 0, 0, width, separator_height, true, color); dc->y += separator_height; } + } - /* draw x_more */ - if (x_more.txt) { - dc->x = 0; - drawrect(dc, 0, 0, width, line_height, true, last_color->BG); - dc->x = calculate_x_offset(width, textw(dc, x_more.txt)); - drawtext(dc, x_more.txt, last_color); - } + int x,y; /* calculate window position */ if (geometry.mask & XNegative) { x = (scr.dim.x + (scr.dim.w - width)) + geometry.x; @@ -739,8 +738,6 @@ void draw_win(void) } mapdc(dc, win, width, height); - - free(x_more.txt); } char @@ -808,7 +805,7 @@ void handle_mouse_click(XEvent ev) assert(iter); for (; iter; iter = iter->next) { n = (notification *) iter->data; - int height = font_h * n->draw_txt_buf.line_count; + int height = font_h * n->line_count; if (ev.xbutton.y > y && ev.xbutton.y < y + height) break; else @@ -958,7 +955,6 @@ int init_notification(notification * n, int id) n->msg = fix_markup(n->msg); n->dup_count = 0; - n->draw_txt_buf.txt = NULL; /* check if n is a duplicate */ for (l_node * iter = notification_queue->head; iter; iter = iter->next) { @@ -1702,6 +1698,7 @@ int main(int argc, char *argv[]) notification_history = l_init(); displayed_notifications = l_init(); rules = l_init(); + r_line_cache_init(&line_cache); for (int i = 0; i < LENGTH(default_rules); i++) { l_push(rules, &default_rules[i]); diff --git a/dunst.h b/dunst.h index e56e8d4..471987c 100644 --- a/dunst.h +++ b/dunst.h @@ -32,18 +32,12 @@ typedef struct _screen_info { dimension_t dim; } screen_info; -typedef struct _draw_txt { - char *txt; - int line_count; -} draw_txt; - typedef struct _notification { char *appname; char *summary; char *body; char *icon; char *msg; - draw_txt draw_txt_buf; const char *format; char *dbus_client; time_t start; @@ -56,6 +50,7 @@ typedef struct _notification { ColorSet *colors; char *color_strings[2]; int progress; /* percentage + 1, 0 to hide */ + int line_count; } notification; typedef struct _notification_buffer { @@ -88,6 +83,19 @@ typedef struct _keyboard_shortcut { bool is_valid; } keyboard_shortcut; +typedef struct _r_line { + ColorSet *colors; + char *str; +} r_line; + +typedef struct r_line_cache { + int count; + int size; + r_line *lines; +} r_line_cache; + + + extern int verbosity; /* return id of notification */ From e380849c24dda4de2d4d717a938a397eb67d2ece Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Tue, 11 Dec 2012 00:21:54 +0100 Subject: [PATCH 27/51] move stuff from draw_win to separate functions --- dunst.c | 81 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/dunst.c b/dunst.c index 27d2bd2..2226ac3 100644 --- a/dunst.c +++ b/dunst.c @@ -621,18 +621,42 @@ int calculate_width(void) } } - -void draw_win(void) +void move_and_map(int width, int height) { - r_line_cache_reset(&line_cache); - update_screen_info(); - int width = calculate_width(); + int x,y; + /* calculate window position */ + if (geometry.mask & XNegative) { + x = (scr.dim.x + (scr.dim.w - width)) + geometry.x; + } else { + x = scr.dim.x + geometry.x; + } + if (geometry.mask & YNegative) { + y = scr.dim.y + (scr.dim.h + geometry.y) - height; + } else { + y = scr.dim.y + geometry.y; + } - line_height = MAX(line_height, font_h); + /* move and map window */ + if (x != window_dim.x || y != window_dim.y + || width != window_dim.w || height != window_dim.h) { + XResizeWindow(dc->dpy, win, width, height); + XMoveWindow(dc->dpy, win, x, y); + window_dim.x = x; + window_dim.y = y; + window_dim.h = height; + window_dim.w = width; + } + + mapdc(dc, win, width, height); + +} + +void fill_line_cache(int width) +{ /* create cache with all lines */ for (l_node * iter = displayed_notifications->head; iter; iter = iter->next) { @@ -660,6 +684,21 @@ void draw_win(void) line_cache.lines[0].str = new; } } +} + + +void draw_win(void) +{ + + r_line_cache_reset(&line_cache); + update_screen_info(); + int width = calculate_width(); + + + line_height = MAX(line_height, font_h); + + + fill_line_cache(width); /* if we have a dynamic width, calculate the actual width */ @@ -709,35 +748,7 @@ void draw_win(void) } - - int x,y; - /* calculate window position */ - if (geometry.mask & XNegative) { - x = (scr.dim.x + (scr.dim.w - width)) + geometry.x; - } else { - x = scr.dim.x + geometry.x; - } - - if (geometry.mask & YNegative) { - y = scr.dim.y + (scr.dim.h + geometry.y) - height; - } else { - y = scr.dim.y + geometry.y; - } - - /* move and map window */ - if (x != window_dim.x || y != window_dim.y - || width != window_dim.w || height != window_dim.h) { - - XResizeWindow(dc->dpy, win, width, height); - XMoveWindow(dc->dpy, win, x, y); - - window_dim.x = x; - window_dim.y = y; - window_dim.h = height; - window_dim.w = width; - } - - mapdc(dc, win, width, height); + move_and_map(width, height); } char From 034505c35627d1372019dc9581c0a4e3629cab3a Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Tue, 11 Dec 2012 00:31:32 +0100 Subject: [PATCH 28/51] draw_win don't draw separator after every line --- dunst.c | 11 ++++++----- dunst.h | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/dunst.c b/dunst.c index 2226ac3..0743147 100644 --- a/dunst.c +++ b/dunst.c @@ -106,7 +106,7 @@ void move_all_to_history(void); void print_version(void); void r_line_cache_init(r_line_cache *c); -void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col); +void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues); void r_line_cache_reset(r_line_cache *c); /* show warning notification */ @@ -396,7 +396,7 @@ void r_line_cache_init(r_line_cache *c) c->lines = NULL; } -void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col) +void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues) { if (!c || !s) return; @@ -410,6 +410,7 @@ void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col) c->count++; c->lines[c->count-1].colors = col; c->lines[c->count-1].str = strdup(s); + c->lines[c->count-1].continues = continues; } void r_line_cache_reset(r_line_cache *c) @@ -523,7 +524,7 @@ void add_notification_to_line_cache(notification *n, int max_width) n->line_count = linecnt; char *cur = buf; for (int i = 0; i < linecnt; i++) { - r_line_cache_append(&line_cache, cur, n->colors); + r_line_cache_append(&line_cache, cur, n->colors, i+1 != linecnt); while (*cur != '\0') cur++; @@ -674,7 +675,7 @@ void fill_line_cache(int width) asprintf(&tmp, "(%d more)", queue_cnt); ColorSet *last_colors = line_cache.lines[line_cache.count-1].colors; - r_line_cache_append(&line_cache, strdup(tmp), last_colors); + r_line_cache_append(&line_cache, strdup(tmp), last_colors, false); free(tmp); } else { char *old = line_cache.lines[0].str; @@ -735,7 +736,7 @@ void draw_win(void) dc->y += line_height - ((line_height - font_h) / 2); /* draw separator */ - if (separator_height > 0 && i < line_cache.count - 1) { + if (separator_height > 0 && i < line_cache.count - 1 && !line.continues) { dc->x = 0; double color; if (sep_color == AUTO) diff --git a/dunst.h b/dunst.h index 471987c..60b0da2 100644 --- a/dunst.h +++ b/dunst.h @@ -86,6 +86,7 @@ typedef struct _keyboard_shortcut { typedef struct _r_line { ColorSet *colors; char *str; + bool continues; } r_line; typedef struct r_line_cache { From 843fbab9585c8bed07491fa41039cc2f64fa86fe Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Tue, 11 Dec 2012 04:49:27 +0100 Subject: [PATCH 29/51] use array for rules --- dunst.c | 94 +++++++++++++++++++++------------------------------------ dunst.h | 4 +++ 2 files changed, 39 insertions(+), 59 deletions(-) diff --git a/dunst.c b/dunst.c index 0743147..a886961 100644 --- a/dunst.c +++ b/dunst.c @@ -55,7 +55,7 @@ int height_limit; -list *rules = NULL; +rule_array rules; /* index of colors fit to urgency level */ static ColorSet *colors[3]; static const char *color_strings[2][3]; @@ -93,7 +93,7 @@ char *fix_markup(char *str); void handle_mouse_click(XEvent ev); void handleXEvents(void); void history_pop(void); -rule_t *initrule(void); +void initrule(rule_t *r); bool is_idle(void); void run(void); void setup(void); @@ -270,13 +270,9 @@ l_node *most_important(list * l) void apply_rules(notification * n) { - if (l_is_empty(rules) || n == NULL) { - return; - } - - for (l_node * iter = rules->head; iter; iter = iter->next) { - rule_t *r = (rule_t *) iter->data; + for (int i = 0; i < rules.count; i++) { + rule_t *r = &(rules.rules[i]); if ((!r->appname || !fnmatch(r->appname, n->appname, 0)) && (!r->summary || !fnmatch(r->summary, n->summary, 0)) && (!r->body || !fnmatch(r->body, n->body, 0)) @@ -1154,9 +1150,8 @@ void init_shortcut(keyboard_shortcut * ks) free(str_begin); } -rule_t *initrule(void) +void initrule(rule_t *r) { - rule_t *r = malloc(sizeof(rule_t)); r->name = NULL; r->appname = NULL; r->summary = NULL; @@ -1167,8 +1162,6 @@ rule_t *initrule(void) r->fg = NULL; r->bg = NULL; r->format = NULL; - - return r; } bool is_idle(void) @@ -1436,27 +1429,6 @@ void parse_follow_mode(const char *mode) } -static rule_t *dunst_rules_find_or_create(const char *section) -{ - l_node *iter; - rule_t *rule; - - /* find rule */ - for (iter = rules->head; iter; iter = iter->next) { - rule_t *r = (rule_t *) iter->data; - if (strcmp(r->name, section) == 0) { - return r; - } - } - - rule = initrule(); - rule->name = strdup(section); - - l_push(rules, rule); - - return rule; -} - void load_options(char *cmdline_config_path) { @@ -1658,28 +1630,35 @@ void load_options(char *cmdline_config_path) || strcmp(cur_section, "urgency_critical") == 0) continue; - rule_t *current_rule = dunst_rules_find_or_create(cur_section); - current_rule->appname = - ini_get_string(cur_section, "appname", - current_rule->appname); - current_rule->summary = - ini_get_string(cur_section, "summary", - current_rule->summary); - current_rule->body = - ini_get_string(cur_section, "body", current_rule->body); - current_rule->icon = - ini_get_string(cur_section, "icon", current_rule->icon); - current_rule->timeout = - ini_get_int(cur_section, "timeout", current_rule->timeout); + /* check for existing rule with same name */ + rule_t *r = NULL; + for (int i = 0; i < rules.count; i++) + if (rules.rules[i].name && + strcmp(rules.rules[i].name, cur_section) == 0) + r = &(rules.rules[i]); + + if (r == NULL) { + rules.count++; + rules.rules = realloc(rules.rules, + rules.count * sizeof(rule_t)); + r = &(rules.rules[rules.count-1]); + initrule(r); + } + + r->appname = ini_get_string(cur_section, "appname", r->appname); + r->summary = ini_get_string(cur_section, "summary", r->summary); + r->body = ini_get_string(cur_section, "body", r->body); + r->icon = ini_get_string(cur_section, "icon", r->icon); + r->timeout = ini_get_int(cur_section, "timeout", r->timeout); { char *urg = ini_get_string(cur_section, "urgency", ""); if (strlen(urg) > 0) { if (strcmp(urg, "low") == 0) - current_rule->urgency = LOW; + r->urgency = LOW; else if (strcmp(urg, "normal") == 0) - current_rule->urgency = NORM; + r->urgency = NORM; else if (strcmp(urg, "critical") == 0) - current_rule->urgency = CRIT; + r->urgency = CRIT; else fprintf(stderr, "unknown urgency: %s, ignoring\n", @@ -1687,12 +1666,9 @@ void load_options(char *cmdline_config_path) free(urg); } } - current_rule->fg = - ini_get_string(cur_section, "foreground", current_rule->fg); - current_rule->bg = - ini_get_string(cur_section, "background", current_rule->bg); - current_rule->format = - ini_get_string(cur_section, "format", current_rule->format); + r->fg = ini_get_string(cur_section, "foreground", r->fg); + r->bg = ini_get_string(cur_section, "background", r->bg); + r->format = ini_get_string(cur_section, "format", r->format); } #ifndef STATIC_CONFIG @@ -1709,12 +1685,12 @@ int main(int argc, char *argv[]) notification_queue = l_init(); notification_history = l_init(); displayed_notifications = l_init(); - rules = l_init(); r_line_cache_init(&line_cache); - for (int i = 0; i < LENGTH(default_rules); i++) { - l_push(rules, &default_rules[i]); - } + + rules.count = LENGTH(default_rules); + rules.rules = calloc(rules.count, sizeof(rule_t)); + memcpy(rules.rules, default_rules, sizeof(rule_t) * rules.count); cmdline_load(argc, argv); diff --git a/dunst.h b/dunst.h index 60b0da2..6f9b854 100644 --- a/dunst.h +++ b/dunst.h @@ -95,6 +95,10 @@ typedef struct r_line_cache { r_line *lines; } r_line_cache; +typedef struct _rule_array { + int count; + rule_t *rules; +} rule_array; extern int verbosity; From 07ec142990ec2f006d5dcef018fbfa75c369c466 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 08:57:03 +0100 Subject: [PATCH 30/51] removed outdated TODOs --- dunst.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dunst.c b/dunst.c index a886961..63b9c0d 100644 --- a/dunst.c +++ b/dunst.c @@ -373,11 +373,6 @@ void update_lists() return; n->start = now; - /* TODO get notifications pushed back into - * notification_queue if there's a more important - * message waiting there - */ - l_move(notification_queue, displayed_notifications, to_move); l_sort(displayed_notifications, cmp_notification); @@ -420,7 +415,6 @@ void r_line_cache_reset(r_line_cache *c) c->count = 0; } -/* TODO get draw_txt_buf as argument */ int do_word_wrap(char *source, int max_width) { From b2a20c05241137b5d069dca4faecf2c7b75dd773 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 09:05:56 +0100 Subject: [PATCH 31/51] list.{c,h} -> container.{c,h} --- Makefile | 6 +++--- list.c => container.c | 2 +- list.h => container.h | 0 dunst.c | 2 +- dunst_dbus.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename list.c => container.c (99%) rename list.h => container.h (100%) diff --git a/Makefile b/Makefile index 6b54f7e..fc49eac 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = draw.c dunst.c list.c dunst_dbus.c utils.c options.c +SRC = draw.c dunst.c container.c dunst_dbus.c utils.c options.c OBJ = ${SRC:.c=.o} all: doc options dunst service @@ -24,9 +24,9 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -dunst: draw.o dunst.o list.o dunst_dbus.o utils.o options.o +dunst: draw.o dunst.o container.o dunst_dbus.o utils.o options.o @echo CC -o $@ - @${CC} ${CFLAGS} -o $@ dunst.o draw.o list.o dunst_dbus.o options.o utils.o ${LDFLAGS} + @${CC} ${CFLAGS} -o $@ dunst.o draw.o container.o dunst_dbus.o options.o utils.o ${LDFLAGS} clean: @echo cleaning diff --git a/list.c b/container.c similarity index 99% rename from list.c rename to container.c index 395aef0..b54574c 100644 --- a/list.c +++ b/container.c @@ -1,7 +1,7 @@ #include "stdlib.h" #include "stdio.h" -#include "list.h" +#include "container.h" int l_push(list * l, void *data) { diff --git a/list.h b/container.h similarity index 100% rename from list.h rename to container.h diff --git a/dunst.c b/dunst.c index 63b9c0d..44ab7a7 100644 --- a/dunst.c +++ b/dunst.c @@ -27,7 +27,7 @@ #include "dunst.h" #include "draw.h" #include "dunst_dbus.h" -#include "list.h" +#include "container.h" #include "utils.h" #include "options.h" diff --git a/dunst_dbus.c b/dunst_dbus.c index f36745d..164b7c6 100644 --- a/dunst_dbus.c +++ b/dunst_dbus.c @@ -3,7 +3,7 @@ #include #include "dunst.h" -#include "list.h" +#include "container.h" #include "dunst_dbus.h" From b641a9c8818fe60915e95cc2ce08bb4738053239 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 09:58:52 +0100 Subject: [PATCH 32/51] use n_stack for history --- container.c | 25 +++++++++++++++++++++++++ container.h | 27 ++++++++++++++++++++++++++- dunst.c | 29 +++++++++++------------------ 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/container.c b/container.c index b54574c..9775cbd 100644 --- a/container.c +++ b/container.c @@ -263,4 +263,29 @@ void l_sort(list * l, int (*f) (void *, void *)) free(old_list); } +void n_stack_push(n_stack **s, notification *n) +{ + if (!n) + return; + + n_stack *new = malloc(sizeof(n_stack)); + new->n = n; + new->next = *s; + *s = new; +} + +notification *n_stack_pop(n_stack **s) +{ + if (!s || !*s) + return NULL; + + n_stack *head = *s; + *s = (*s)->next; + + notification *n = head->n; + free(head); + + return n; +} + /* vim: set ts=8 sw=8 tw=0: */ diff --git a/container.h b/container.h index 800ee9c..d4ca72e 100644 --- a/container.h +++ b/container.h @@ -1,6 +1,8 @@ #ifndef _LIST_H #define _LIST_H +#include "dunst.h" + typedef struct _l_node { struct _l_node *next; void *data; @@ -10,6 +12,11 @@ typedef struct _list { l_node *head; } list; +typedef struct _n_stack { + notification *n; + struct _n_stack *next; +} n_stack; + /* append to end of list */ int l_push(list * l, void *data); @@ -54,6 +61,24 @@ int l_move(list * from, list * to, l_node * node); void l_sort(list * l, int (*f) (void *, void *)); list *l_init(void); -#endif + +/************ + * stack + */ + +/** + * push notification onto stack + * creates a new stack if *s == NULL + */ +void n_stack_push(n_stack **s, notification *n); + +/** + * remove and return notification from stack + * sets *s to NULL if stack is empty + */ +notification *n_stack_pop(n_stack **s); + + +#endif /* vim: set ts=8 sw=8 tw=0: */ diff --git a/dunst.c b/dunst.c index 44ab7a7..8a1b2a6 100644 --- a/dunst.c +++ b/dunst.c @@ -84,7 +84,7 @@ bool deprecated_dunstrc_shortcuts = false; /* notification lists */ list *notification_queue = NULL; /* all new notifications get into here */ list *displayed_notifications = NULL; /* currently displayed notifications */ -list *notification_history = NULL; /* history of displayed notifications */ +n_stack *n_history = NULL; /* history of displayed notifications */ /* misc funtions */ void apply_rules(notification * n); @@ -884,22 +884,15 @@ void move_all_to_history() void history_pop(void) { - l_node *iter; - notification *data; - /* nothing to do */ - if (l_is_empty(notification_history)) { + if (!n_history) return; - } - for (iter = notification_history->head; iter->next; iter = iter->next) ; - data = (notification *) iter->data; - data->redisplayed = true; - data->start = 0; - if (sticky_history) { - data->timeout = 0; - } - l_move(notification_history, notification_queue, iter); + notification *n = n_stack_pop(&n_history); + n->redisplayed = true; + n->start = 0; + n->timeout = sticky_history ? 0 : n->timeout; + l_push(notification_queue, n); if (!visible) { map_win(); @@ -1040,8 +1033,8 @@ int close_notification_by_id(int id, int reason) for (iter = displayed_notifications->head; iter; iter = iter->next) { notification *n = (notification *) iter->data; if (n->id == id) { - l_move(displayed_notifications, notification_history, - iter); + l_remove(displayed_notifications, iter); + n_stack_push(&n_history, n); target = n; break; } @@ -1050,7 +1043,8 @@ int close_notification_by_id(int id, int reason) for (iter = notification_queue->head; iter; iter = iter->next) { notification *n = (notification *) iter->data; if (n->id == id) { - l_move(notification_queue, notification_history, iter); + l_remove(notification_queue, iter); + n_stack_push(&n_history, n); target = n; break; } @@ -1677,7 +1671,6 @@ int main(int argc, char *argv[]) now = time(&now); notification_queue = l_init(); - notification_history = l_init(); displayed_notifications = l_init(); r_line_cache_init(&line_cache); From 557a8e29fac3b61c0f2edfbdd7eb6e98a26c42ab Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 10:07:40 +0100 Subject: [PATCH 33/51] removed deprecated keyboard settings --- dunst.c | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/dunst.c b/dunst.c index 8a1b2a6..1f72bc0 100644 --- a/dunst.c +++ b/dunst.c @@ -78,9 +78,6 @@ bool dunst_grab_errored = false; int next_notification_id = 1; -bool deprecated_mod = false; -bool deprecated_dunstrc_shortcuts = false; - /* notification lists */ list *notification_queue = NULL; /* all new notifications get into here */ list *displayed_notifications = NULL; /* currently displayed notifications */ @@ -109,9 +106,6 @@ void r_line_cache_init(r_line_cache *c); void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues); void r_line_cache_reset(r_line_cache *c); -/* show warning notification */ -void warn(const char *text, int urg); - void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); @@ -200,29 +194,6 @@ void ungrab_key(keyboard_shortcut * ks) XUngrabKey(dc->dpy, ks->code, ks->mask, root); } -void warn(const char *text, int urg) -{ - notification *n = malloc(sizeof(notification)); - - if (n == NULL) - die("Unable to allocate memory", EXIT_FAILURE); - - n->appname = strdup("dunst"); - n->summary = strdup(text); - if (n->summary == NULL) - die("Unable to allocate memory", EXIT_FAILURE); - n->body = strdup(""); - n->icon = strdup(""); - n->timeout = 0; - n->urgency = urg; - n->progress = 0; - n->dbus_client = NULL; - n->color_strings[ColFG] = NULL; - n->color_strings[ColBG] = NULL; - init_notification(n, 0); - map_win(); -} - int cmp_notification(void *a, void *b) { if (a == NULL && b == NULL) @@ -1485,24 +1456,6 @@ void load_options(char *cmdline_config_path) option_get_int("global", "line_height", "-lh/-line_height", line_height, "Add additional padding above and beneath text"); - { - char *c = option_get_string("global", "modifier", NULL, "", ""); - if (strlen(c) > 0) { - deprecated_dunstrc_shortcuts = true; - KeySym mod = string_to_mask(c); - close_ks.mask = mod; - close_all_ks.mask = mod; - close_all_ks.mask = mod; - free(c); - } - } - close_ks.str = - option_get_string("global", "key", NULL, close_ks.str, ""); - close_all_ks.str = - option_get_string("global", "all_key", NULL, close_all_ks.str, ""); - history_ks.str = - option_get_string("global", "history_key", NULL, history_ks.str, - ""); bounce_freq = option_get_double("global", "bounce_freq", "-bounce_freq", bounce_freq, @@ -1702,11 +1655,6 @@ int main(int argc, char *argv[]) signal (SIGUSR1, pause_signal_handler); signal (SIGUSR2, pause_signal_handler); - if (deprecated_mod) - warn("-mod is deprecated. Use \"-key mod+key\" instead\n", - CRIT); - if (deprecated_dunstrc_shortcuts) - warn("You are using deprecated settings. Please update your dunstrc. SEE [shortcuts]", CRIT); run(); return 0; } From 1dd6e2587eabb61c37055023c7de4def1eb70581 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 12:06:04 +0100 Subject: [PATCH 34/51] use queue for notification queue --- container.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++- container.h | 33 +++++++++++++++++++ dunst.c | 94 +++++++++++++---------------------------------------- 3 files changed, 139 insertions(+), 72 deletions(-) diff --git a/container.c b/container.c index 9775cbd..8f1883b 100644 --- a/container.c +++ b/container.c @@ -265,7 +265,7 @@ void l_sort(list * l, int (*f) (void *, void *)) void n_stack_push(n_stack **s, notification *n) { - if (!n) + if (!n || !s) return; n_stack *new = malloc(sizeof(n_stack)); @@ -288,4 +288,86 @@ notification *n_stack_pop(n_stack **s) return n; } +int n_stack_len(n_stack **s) +{ + if (!s || !*s) + return 0; + + n_stack *cur = *s; + int count = 0; + + while (cur) { + cur = cur->next; + count++; + } + + return count; +} + +int cmp_notification(notification *a, notification *b) +{ + if (a == NULL && b == NULL) + return 0; + else if (a == NULL) + return -1; + else if (b == NULL) + return 1; + + if (a->urgency != b->urgency) { + return a->urgency - b->urgency; + } else { + return b->timestamp - a->timestamp; + } +} + +void n_queue_enqueue(n_queue **q, notification *n) +{ + if (!n || !q) + return; + + + n_queue *new = malloc(sizeof(n_queue)); + new->n = n; + new->next = NULL; + + if (!(*q)) { + /* queue was empty */ + *q = new; + return; + } + + + /* new head */ + if (cmp_notification(new->n, (*q)->n) > 0) { + new->next = *q; + *q = new; + return; + } + + /* in between */ + n_queue *cur = *q; + while (cur->next) { + if (cmp_notification(new->n, cur->next->n) > 0) { + new->next = cur->next; + cur->next = new; + return; + } + + cur = cur->next; + } + + /* last */ + cur->next = new; +} + +notification *n_queue_dequeue(n_queue **q) +{ + return n_stack_pop(q); +} + +int n_queue_len(n_queue **q) +{ + return n_stack_len(q); +} + /* vim: set ts=8 sw=8 tw=0: */ diff --git a/container.h b/container.h index d4ca72e..e8386b2 100644 --- a/container.h +++ b/container.h @@ -17,6 +17,10 @@ typedef struct _n_stack { struct _n_stack *next; } n_stack; +typedef n_stack n_queue; + +int cmp_notification(notification *a, notification *b); + /* append to end of list */ int l_push(list * l, void *data); @@ -79,6 +83,35 @@ void n_stack_push(n_stack **s, notification *n); */ notification *n_stack_pop(n_stack **s); +/** + * return length of stack + */ + +int n_stack_len(n_stack **s); + +/*************** + * queue + */ + +/** + * enqueue notification into queue + * creates a new queue if *q == NULL + */ + +void n_queue_enqueue(n_queue **q, notification *n); + +/** + * dequeues the next element from the queue. + * returns NULL if queue is empty + */ + +notification *n_queue_dequeue(n_queue **q); + +/** + * return length of queue + */ + +int n_queue_len(n_queue **q); #endif /* vim: set ts=8 sw=8 tw=0: */ diff --git a/dunst.c b/dunst.c index 1f72bc0..2601273 100644 --- a/dunst.c +++ b/dunst.c @@ -79,7 +79,7 @@ bool dunst_grab_errored = false; int next_notification_id = 1; /* notification lists */ -list *notification_queue = NULL; /* all new notifications get into here */ +n_queue *queue = NULL; /* all new notifications get into here */ list *displayed_notifications = NULL; /* currently displayed notifications */ n_stack *n_history = NULL; /* history of displayed notifications */ @@ -194,51 +194,6 @@ void ungrab_key(keyboard_shortcut * ks) XUngrabKey(dc->dpy, ks->code, ks->mask, root); } -int cmp_notification(void *a, void *b) -{ - if (a == NULL && b == NULL) - return 0; - else if (a == NULL) - return -1; - else if (b == NULL) - return 1; - - notification *na = (notification *) a; - notification *nb = (notification *) b; - if (na->urgency != nb->urgency) { - return na->urgency - nb->urgency; - } else { - return nb->timestamp - na->timestamp; - } -} - -l_node *most_important(list * l) -{ - - if (l == NULL || l_is_empty(l)) { - return NULL; - } - - if (sort) { - notification *max; - l_node *node_max; - notification *data; - - max = l->head->data; - node_max = l->head; - for (l_node * iter = l->head; iter; iter = iter->next) { - data = (notification *) iter->data; - if (cmp_notification(max, data) < 0) { - max = data; - node_max = iter; - } - } - return node_max; - } else { - return l->head; - } -} - void apply_rules(notification * n) { @@ -303,15 +258,14 @@ void check_timeouts(void) void update_lists() { - l_node *to_move; - notification *n; int limit; check_timeouts(); if (pause_display) { while (!l_is_empty(displayed_notifications)) { - l_move(displayed_notifications, notification_queue, displayed_notifications->head); + notification *n = (notification *) l_remove(displayed_notifications, displayed_notifications->head); + n_queue_enqueue(&queue, n); } return; } @@ -328,23 +282,20 @@ void update_lists() /* move notifications from queue to displayed */ - while (!l_is_empty(notification_queue)) { + while (queue) { if (limit > 0 && l_length(displayed_notifications) >= limit) { /* the list is full */ break; } - to_move = most_important(notification_queue); - if (!to_move) { - return; - } - n = (notification *) to_move->data; + notification *n = n_queue_dequeue(&queue); + if (!n) return; n->start = now; - l_move(notification_queue, displayed_notifications, to_move); + l_push(displayed_notifications, n); l_sort(displayed_notifications, cmp_notification); @@ -629,7 +580,7 @@ void fill_line_cache(int width) assert(line_cache.count > 0); /* add (x more) */ - int queue_cnt = l_length(notification_queue); + int queue_cnt = n_queue_len(&queue); if (indicate_hidden && queue_cnt > 0) { if (geometry.h != 1) { char *tmp; @@ -846,10 +797,11 @@ void move_all_to_history() n = (notification *) node->data; close_notification(n, 2); } - while (!l_is_empty(notification_queue)) { - node = notification_queue->head; - n = (notification *) node->data; - close_notification(n, 2); + + n = n_queue_dequeue(&queue); + while (n) { + n_stack_push(&n_history, n); + n = n_queue_dequeue(&queue); } } @@ -863,7 +815,7 @@ void history_pop(void) n->redisplayed = true; n->start = 0; n->timeout = sticky_history ? 0 : n->timeout; - l_push(notification_queue, n); + n_queue_enqueue(&queue, n); if (!visible) { map_win(); @@ -923,8 +875,8 @@ int init_notification(notification * n, int id) n->dup_count = 0; /* check if n is a duplicate */ - for (l_node * iter = notification_queue->head; iter; iter = iter->next) { - notification *orig = (notification *) iter->data; + for (n_queue *iter = queue; iter; iter = iter->next) { + notification *orig = iter->n; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; @@ -980,7 +932,7 @@ int init_notification(notification * n, int id) close_notification(n, 2); printf("skipping notification: %s %s\n", n->body, n->summary); } else { - l_push(notification_queue, n); + n_queue_enqueue(&queue, n); } if (print_notifications) @@ -998,10 +950,9 @@ int init_notification(notification * n, int id) */ int close_notification_by_id(int id, int reason) { - l_node *iter; notification *target = NULL; - for (iter = displayed_notifications->head; iter; iter = iter->next) { + for (l_node *iter = displayed_notifications->head; iter; iter = iter->next) { notification *n = (notification *) iter->data; if (n->id == id) { l_remove(displayed_notifications, iter); @@ -1011,10 +962,12 @@ int close_notification_by_id(int id, int reason) } } - for (iter = notification_queue->head; iter; iter = iter->next) { - notification *n = (notification *) iter->data; + for (n_queue *iter = queue; iter && iter->next; iter = iter->next) { + notification *n = iter->next->n; if (n->id == id) { - l_remove(notification_queue, iter); + n_queue *tmp = iter->next; + iter->next = iter->next->next; + free(tmp); n_stack_push(&n_history, n); target = n; break; @@ -1623,7 +1576,6 @@ int main(int argc, char *argv[]) { now = time(&now); - notification_queue = l_init(); displayed_notifications = l_init(); r_line_cache_init(&line_cache); From 91fa27fbf40766335c77a851fc5195e2d9c6d6c9 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 12:06:51 +0100 Subject: [PATCH 35/51] n_history -> history --- dunst.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dunst.c b/dunst.c index 2601273..a6bce55 100644 --- a/dunst.c +++ b/dunst.c @@ -81,7 +81,7 @@ int next_notification_id = 1; /* notification lists */ n_queue *queue = NULL; /* all new notifications get into here */ list *displayed_notifications = NULL; /* currently displayed notifications */ -n_stack *n_history = NULL; /* history of displayed notifications */ +n_stack *history = NULL; /* history of displayed notifications */ /* misc funtions */ void apply_rules(notification * n); @@ -800,7 +800,7 @@ void move_all_to_history() n = n_queue_dequeue(&queue); while (n) { - n_stack_push(&n_history, n); + n_stack_push(&history, n); n = n_queue_dequeue(&queue); } } @@ -808,10 +808,10 @@ void move_all_to_history() void history_pop(void) { - if (!n_history) + if (!history) return; - notification *n = n_stack_pop(&n_history); + notification *n = n_stack_pop(&history); n->redisplayed = true; n->start = 0; n->timeout = sticky_history ? 0 : n->timeout; @@ -956,7 +956,7 @@ int close_notification_by_id(int id, int reason) notification *n = (notification *) iter->data; if (n->id == id) { l_remove(displayed_notifications, iter); - n_stack_push(&n_history, n); + n_stack_push(&history, n); target = n; break; } @@ -968,7 +968,7 @@ int close_notification_by_id(int id, int reason) n_queue *tmp = iter->next; iter->next = iter->next->next; free(tmp); - n_stack_push(&n_history, n); + n_stack_push(&history, n); target = n; break; } From 1b04f51d674463252c41d0edffc997ca06b34d92 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 12:48:21 +0100 Subject: [PATCH 36/51] use n_queue for displayed notifications --- container.c | 288 +++++----------------------------------------------- container.h | 67 +++--------- dunst.c | 103 +++++++------------ 3 files changed, 76 insertions(+), 382 deletions(-) diff --git a/container.c b/container.c index 8f1883b..8e89fa3 100644 --- a/container.c +++ b/container.c @@ -3,266 +3,6 @@ #include "container.h" -int l_push(list * l, void *data) -{ - l_node *n; - int ret; - - /* invalid input */ - if (!l || !data) { - return -1; - } - - n = l_init_node(data); - if (!n) { - /* something went wrong */ - return -2; - } - - ret = l_node_push(l, n); - - return ret; -} - -int l_node_push(list * l, l_node * n) -{ - l_node *end; - - /* invalid input */ - if (!l || !n) { - return -1; - } - - n->next = NULL; - - /* empty list */ - if (!l->head) { - l->head = n; - - return 0; - } - - for (end = l->head; end->next; end = end->next) ; - - if (end != n) { - end->next = n; - } - - return 0; -} - -void *l_pop(list * l) -{ - l_node *penultimate; - void *data; - - /* invalid input */ - if (!l) { - return NULL; - } - - /* empty list */ - if (!l->head) { - return NULL; - } - - /* len(l) == 1 */ - if (!l->head->next) { - data = l->head->data; - free(l->head); - l->head = NULL; - - return data; - } - - for (penultimate = l->head; - penultimate->next->next; penultimate = penultimate->next) ; - data = penultimate->next->data; - free(penultimate->next); - penultimate->next = NULL; - - return data; -} - -int l_insert(l_node * node, void *data) -{ - int ret; - l_node *to_be_inserted; - - /* invalid input */ - if (!node || !data) { - return -1; - } - - to_be_inserted = l_init_node(data); - if (!to_be_inserted) { - return -2; - } - - ret = l_node_insert(node, to_be_inserted); - - return ret; -} - -int l_node_insert(l_node * node, l_node * to_be_inserted) -{ - l_node *tmp; - - /* invalid input */ - if (!node || !to_be_inserted) { - return -1; - } - - tmp = node->next; - node->next = to_be_inserted; - to_be_inserted->next = tmp; - - return 0; -} - -void *l_remove(list * l, l_node * node) -{ - void *data; - if (l != NULL) { - l_node_remove(l, node); - } - - if (node == NULL) { - return NULL; - } - - data = node->data; - free(node); - - return data; -} - -l_node *l_node_remove(list * l, l_node * node) -{ - l_node *prev; - l_node *next; - - /* invalid input */ - if (!l || !node) { - return NULL; - } - - /* empty list */ - if (!l->head) { - return NULL; - } - - /* node is head */ - if (l->head == node) { - l->head = node->next; - node->next = NULL; - return node; - } - - /* find the predecessor of node */ - for (prev = l->head; - prev->next && prev->next != node; prev = prev->next) ; - - /* node not in list */ - if (prev->next != node) { - return node; - } - - next = node->next; - prev->next = next; - - return node; -} - -l_node *l_init_node(void *data) -{ - l_node *node; - - node = malloc(sizeof(l_node)); - if (!node) { - return NULL; - } - - node->data = data; - node->next = NULL; - - return node; -} - -int l_length(list * l) -{ - l_node *iter; - int count; - - if (!l || !l->head) { - return 0; - } - - count = 0; - iter = l->head; - while (iter) { - count++; - iter = iter->next; - } - - return count; -} - -int l_is_empty(list * l) -{ - return l->head == NULL; -} - -int l_move(list * from, list * to, l_node * node) -{ - - if (!from || !to || !node) { - return -1; - } - node = l_node_remove(from, node); - return l_node_push(to, node); -} - -list *l_init(void) -{ - list *l = malloc(sizeof(list)); - l->head = NULL; - - return l; -} - -void l_sort(list * l, int (*f) (void *, void *)) -{ - list *old_list; - - if (!l || l_length(l) < 2) { - /* nothing to do */ - return; - } - - old_list = l_init(); - - old_list->head = l->head; - l->head = NULL; - - while (!l_is_empty(old_list)) { - l_node *iter; - l_node *max; - - /* find max in old_list */ - max = old_list->head; - for (iter = old_list->head; iter; iter = iter->next) { - if (f(max->data, iter->data) < 0) { - max = iter; - } - } - - l_move(old_list, l, max); - } - - free(old_list); -} - void n_stack_push(n_stack **s, notification *n) { if (!n || !s) @@ -288,6 +28,29 @@ notification *n_stack_pop(n_stack **s) return n; } +void n_stack_remove(n_stack **s, notification *n) +{ + if (!s || !*s || !n) + return; + + /* head is n */ + if ((*s)->n == n) { + n_stack *tmp = *s; + *s = (*s)->next; + free(tmp); + return; + } + + for (n_stack *iter = *s; iter->next; iter = iter->next) { + if (iter->next->n == n) { + n_stack *tmp = iter->next; + iter->next = iter->next->next; + free(tmp); + return; + } + } +} + int n_stack_len(n_stack **s) { if (!s || !*s) @@ -360,6 +123,11 @@ void n_queue_enqueue(n_queue **q, notification *n) cur->next = new; } +void n_queue_remove(n_queue **q, notification *n) +{ + n_stack_remove(q, n); +} + notification *n_queue_dequeue(n_queue **q) { return n_stack_pop(q); diff --git a/container.h b/container.h index e8386b2..9a16150 100644 --- a/container.h +++ b/container.h @@ -3,15 +3,6 @@ #include "dunst.h" -typedef struct _l_node { - struct _l_node *next; - void *data; -} l_node; - -typedef struct _list { - l_node *head; -} list; - typedef struct _n_stack { notification *n; struct _n_stack *next; @@ -21,52 +12,6 @@ typedef n_stack n_queue; int cmp_notification(notification *a, notification *b); -/* append to end of list */ -int l_push(list * l, void *data); - -/* same as append but with a l_node */ -int l_node_push(list * l, l_node * n); - -/* remove and return last element of list */ -void *l_pop(list * l); - -/* insert after node. */ -int l_insert(l_node * node, void *data); - -/* - * same as insert, but using a node_t - */ -int l_node_insert(l_node * node, l_node * to_be_inserted); - -/* - * remove l_node from list and return a pointer to its data - */ -void *l_remove(list * l, l_node * node); - -/* - * same as l_remove but returns the node instead of the data - */ -l_node *l_node_remove(list * l, l_node * node); - -/* - * initialize a node - */ -l_node *l_init_node(void *data); - -/* return the length of the list */ -int l_length(list * l); - -/* is list empty */ -int l_is_empty(list * l); - -/* move node from 'from' to 'to' */ -int l_move(list * from, list * to, l_node * node); - -void l_sort(list * l, int (*f) (void *, void *)); - -list *l_init(void); - - /************ * stack */ @@ -83,6 +28,12 @@ void n_stack_push(n_stack **s, notification *n); */ notification *n_stack_pop(n_stack **s); +/** + * remove notification from stack + */ + +void n_stack_remove(n_stack **q, notification *n); + /** * return length of stack */ @@ -107,6 +58,12 @@ void n_queue_enqueue(n_queue **q, notification *n); notification *n_queue_dequeue(n_queue **q); +/** + * remove notification from queue + */ + +void n_queue_remove(n_queue **q, notification *n); + /** * return length of queue */ diff --git a/dunst.c b/dunst.c index a6bce55..2835e14 100644 --- a/dunst.c +++ b/dunst.c @@ -80,7 +80,7 @@ int next_notification_id = 1; /* notification lists */ n_queue *queue = NULL; /* all new notifications get into here */ -list *displayed_notifications = NULL; /* currently displayed notifications */ +n_queue *displayed = NULL; /* currently displayed notifications */ n_stack *history = NULL; /* history of displayed notifications */ /* misc funtions */ @@ -96,7 +96,6 @@ void run(void); void setup(void); void update_screen_info(); void usage(int exit_status); -l_node *most_important(list * l); void draw_win(void); void hide_win(void); void move_all_to_history(void); @@ -216,42 +215,30 @@ void apply_rules(notification * n) void check_timeouts(void) { - l_node *iter; - notification *current; - l_node *next; - /* nothing to do */ - if (l_is_empty(displayed_notifications)) { + if (!displayed) return; - } - iter = displayed_notifications->head; - while (iter != NULL) { - current = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *n = iter->n; /* don't timeout when user is idle */ if (is_idle()) { - current->start = now; - iter = iter->next; + n->start = now; continue; } /* skip hidden and sticky messages */ - if (current->start == 0 || current->timeout == 0) { - iter = iter->next; + if (n->start == 0 || n->timeout == 0) { continue; } /* remove old message */ - if (difftime(now, current->start) > current->timeout) { - /* l_move changes iter->next, so we need to store it beforehand */ - next = iter->next; - close_notification(current, 1); - iter = next; - continue; - - } else { - iter = iter->next; + if (difftime(now, n->start) > n->timeout) { + /* close_notification may conflict with iter, so restart */ + close_notification(n, 1); + check_timeouts(); + return; } } } @@ -263,8 +250,8 @@ void update_lists() check_timeouts(); if (pause_display) { - while (!l_is_empty(displayed_notifications)) { - notification *n = (notification *) l_remove(displayed_notifications, displayed_notifications->head); + while (displayed) { + notification *n = n_queue_dequeue(&displayed); n_queue_enqueue(&queue, n); } return; @@ -284,7 +271,7 @@ void update_lists() /* move notifications from queue to displayed */ while (queue) { - if (limit > 0 && l_length(displayed_notifications) >= limit) { + if (limit > 0 && n_queue_len(&displayed) >= limit) { /* the list is full */ break; } @@ -295,10 +282,7 @@ void update_lists() return; n->start = now; - l_push(displayed_notifications, n); - - l_sort(displayed_notifications, cmp_notification); - + n_queue_enqueue(&displayed, n); } } @@ -571,10 +555,8 @@ void move_and_map(int width, int height) void fill_line_cache(int width) { /* create cache with all lines */ - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *n = (notification *) iter->data; - add_notification_to_line_cache(n, width); + for (n_queue *iter = displayed; iter; iter = iter->next) { + add_notification_to_line_cache(iter->n, width); } assert(line_cache.count > 0); @@ -724,18 +706,16 @@ void handle_mouse_click(XEvent ev) if (ev.xbutton.button == Button1) { int y = 0; - notification *n; - l_node *iter = displayed_notifications->head; - assert(iter); - for (; iter; iter = iter->next) { - n = (notification *) iter->data; - int height = font_h * n->line_count; + notification *n = NULL; + for (n_queue *iter = displayed; iter; iter = iter->next) { + int height = font_h * iter->n->line_count; if (ev.xbutton.y > y && ev.xbutton.y < y + height) break; else y += height; } - close_notification(n, 2); + if (n) + close_notification(n, 2); } } @@ -767,10 +747,8 @@ void handleXEvents(void) if (close_ks.str && XLookupKeysym(&ev.xkey, 0) == close_ks.sym && close_ks.mask == ev.xkey.state) { - if (!l_is_empty(displayed_notifications)) { - notification *n = (notification *) - displayed_notifications->head->data; - close_notification(n, 2); + if (displayed) { + close_notification(displayed->n, 2); } } if (history_ks.str @@ -789,16 +767,11 @@ void handleXEvents(void) void move_all_to_history() { - l_node *node; - notification *n; - - while (!l_is_empty(displayed_notifications)) { - node = displayed_notifications->head; - n = (notification *) node->data; - close_notification(n, 2); + while (displayed) { + close_notification(displayed->n, 2); } - n = n_queue_dequeue(&queue); + notification *n = n_queue_dequeue(&queue); while (n) { n_stack_push(&history, n); n = n_queue_dequeue(&queue); @@ -885,9 +858,8 @@ int init_notification(notification * n, int id) } } - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *orig = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *orig = iter->n; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; @@ -952,22 +924,20 @@ int close_notification_by_id(int id, int reason) { notification *target = NULL; - for (l_node *iter = displayed_notifications->head; iter; iter = iter->next) { - notification *n = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *n = iter->n; if (n->id == id) { - l_remove(displayed_notifications, iter); + n_queue_remove(&displayed, n); n_stack_push(&history, n); target = n; break; } } - for (n_queue *iter = queue; iter && iter->next; iter = iter->next) { + for (n_queue *iter = queue; iter; iter = iter->next) { notification *n = iter->next->n; if (n->id == id) { - n_queue *tmp = iter->next; - iter->next = iter->next->next; - free(tmp); + n_queue_remove(&queue, n); n_stack_push(&history, n); target = n; break; @@ -1098,7 +1068,7 @@ void run(void) /* move messages from notification_queue to displayed_notifications */ update_lists(); - if (l_length(displayed_notifications) > 0) { + if (displayed) { if (!visible) { map_win(); } else { @@ -1306,7 +1276,7 @@ void setup(void) void map_win(void) { /* window is already mapped or there's nothing to show */ - if (visible || l_is_empty(displayed_notifications)) { + if (visible || !displayed) { return; } @@ -1576,7 +1546,6 @@ int main(int argc, char *argv[]) { now = time(&now); - displayed_notifications = l_init(); r_line_cache_init(&line_cache); From 70839e1321de0c77c9a571ef334dd32998d5e0da Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 13:34:07 +0100 Subject: [PATCH 37/51] fix segfault --- dunst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index 2835e14..99a4fc8 100644 --- a/dunst.c +++ b/dunst.c @@ -935,7 +935,7 @@ int close_notification_by_id(int id, int reason) } for (n_queue *iter = queue; iter; iter = iter->next) { - notification *n = iter->next->n; + notification *n = iter->n; if (n->id == id) { n_queue_remove(&queue, n); n_stack_push(&history, n); From d866bb0c35f6776e1e27ce28875f089bbedfa851 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 13:38:45 +0100 Subject: [PATCH 38/51] rstrip(n->msg) This causes the dupliate detection to ignore trailing whitespaces --- dunst.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dunst.c b/dunst.c index 99a4fc8..2d9d4ae 100644 --- a/dunst.c +++ b/dunst.c @@ -844,6 +844,8 @@ int init_notification(notification * n, int id) } n->msg = fix_markup(n->msg); + n->msg = rstrip(n->msg); + n->dup_count = 0; From 3af63f1ddc520f94c7267cc177ca77b43ee5361b Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 13:53:04 +0100 Subject: [PATCH 39/51] stuff memory leak --- dunst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index 2d9d4ae..8f9e95b 100644 --- a/dunst.c +++ b/dunst.c @@ -569,7 +569,7 @@ void fill_line_cache(int width) asprintf(&tmp, "(%d more)", queue_cnt); ColorSet *last_colors = line_cache.lines[line_cache.count-1].colors; - r_line_cache_append(&line_cache, strdup(tmp), last_colors, false); + r_line_cache_append(&line_cache, tmp, last_colors, false); free(tmp); } else { char *old = line_cache.lines[0].str; From 345a35fe9fdceeab9c3e1e48f7d9267896e84a8a Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 14:05:34 +0100 Subject: [PATCH 40/51] dbus fetch all pending messages at once --- dunst_dbus.c | 55 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/dunst_dbus.c b/dunst_dbus.c index 164b7c6..1280b58 100644 --- a/dunst_dbus.c +++ b/dunst_dbus.c @@ -131,37 +131,36 @@ void dbus_poll(int timeout) dbus_connection_read_write(dbus_conn, timeout); dbus_msg = dbus_connection_pop_message(dbus_conn); - /* we don't have a new message */ - if (dbus_msg == NULL) { - return; - } - if (dbus_message_is_method_call - (dbus_msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { - dbus_introspect(dbus_msg); - } + while (dbus_msg) { + if (dbus_message_is_method_call + (dbus_msg, "org.freedesktop.DBus.Introspectable", "Introspect")) { + dbus_introspect(dbus_msg); + } - if (dbus_message_is_method_call(dbus_msg, - "org.freedesktop.Notifications", - "Notify")) { - notify(dbus_msg); + if (dbus_message_is_method_call(dbus_msg, + "org.freedesktop.Notifications", + "Notify")) { + notify(dbus_msg); + } + if (dbus_message_is_method_call(dbus_msg, + "org.freedesktop.Notifications", + "GetCapabilities")) { + getCapabilities(dbus_msg); + } + if (dbus_message_is_method_call(dbus_msg, + "org.freedesktop.Notifications", + "GetServerInformation")) { + getServerInformation(dbus_msg); + } + if (dbus_message_is_method_call(dbus_msg, + "org.freedesktop.Notifications", + "CloseNotification")) { + closeNotification(dbus_msg); + } + dbus_message_unref(dbus_msg); + dbus_msg = dbus_connection_pop_message(dbus_conn); } - if (dbus_message_is_method_call(dbus_msg, - "org.freedesktop.Notifications", - "GetCapabilities")) { - getCapabilities(dbus_msg); - } - if (dbus_message_is_method_call(dbus_msg, - "org.freedesktop.Notifications", - "GetServerInformation")) { - getServerInformation(dbus_msg); - } - if (dbus_message_is_method_call(dbus_msg, - "org.freedesktop.Notifications", - "CloseNotification")) { - closeNotification(dbus_msg); - } - dbus_message_unref(dbus_msg); } void getCapabilities(DBusMessage * dmsg) From 73e4ab0e006b9b42bee741899857358d1d3559fc Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 14:06:04 +0100 Subject: [PATCH 41/51] fix height calculation --- dunst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index 8f9e95b..c554ed9 100644 --- a/dunst.c +++ b/dunst.c @@ -607,7 +607,7 @@ void draw_win(void) /* resize dc to correct width */ int height = (line_cache.count * line_height) - + ((line_cache.count - 1) * separator_height); + + (separator_height * (n_queue_len(&displayed) - 1)); resizedc(dc, width, height); From 6de6ef06190c4a84af39cc948b7f6cce0b7900ef Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 14:25:01 +0100 Subject: [PATCH 42/51] fix left mouse click --- dunst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dunst.c b/dunst.c index c554ed9..c3d13a0 100644 --- a/dunst.c +++ b/dunst.c @@ -708,7 +708,8 @@ void handle_mouse_click(XEvent ev) int y = 0; notification *n = NULL; for (n_queue *iter = displayed; iter; iter = iter->next) { - int height = font_h * iter->n->line_count; + n = iter->n; + int height = MAX(font_h, line_height) * n->line_count; if (ev.xbutton.y > y && ev.xbutton.y < y + height) break; else From 43b2b3bb1d777c8b4f63b790cb91ab2705a4ab17 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Thu, 13 Dec 2012 22:49:11 +0100 Subject: [PATCH 43/51] don't try to replace NULL icon --- dunst.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dunst.c b/dunst.c index c3d13a0..585b492 100644 --- a/dunst.c +++ b/dunst.c @@ -833,8 +833,10 @@ int init_notification(notification * n, int id) n->msg = string_replace("%a", n->appname, strdup(n->format)); n->msg = string_replace("%s", n->summary, n->msg); - n->msg = string_replace("%i", n->icon, n->msg); - n->msg = string_replace("%I", basename(n->icon), n->msg); + if (n->icon) { + n->msg = string_replace("%I", basename(n->icon), n->msg); + n->msg = string_replace("%i", n->icon, n->msg); + } n->msg = string_replace("%b", n->body, n->msg); if (n->progress) { char pg[10]; From 3918fd32a894165591d2f2c5dd7f8f948fafaa24 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Thu, 13 Dec 2012 22:50:13 +0100 Subject: [PATCH 44/51] print notification on startup --- config.def.h | 6 ++++++ dunst.c | 17 +++++++++++++++++ dunstrc | 4 ++++ 3 files changed, 27 insertions(+) diff --git a/config.def.h b/config.def.h index cd702de..7fddce7 100644 --- a/config.def.h +++ b/config.def.h @@ -27,6 +27,12 @@ int line_height = 0; /* if line height < font height, it will be raised to fon int separator_height = 2; /* height of the separator line between two notifications */ enum separator_color sep_color = AUTO; /* AUTO or FOREGROUND */ +/* show a notification on startup + * This is mainly for crash detection since dbus restarts dunst + * automatically after a crash, so crashes might get unnotices otherwise + * */ +int startup_notification = False; + /* monitor to display notifications on */ int monitor = 0; diff --git a/dunst.c b/dunst.c index 585b492..b23063e 100644 --- a/dunst.c +++ b/dunst.c @@ -1438,6 +1438,9 @@ void load_options(char *cmdline_config_path) } } + startup_notification = option_get_bool("global", "startup_notification", + "-startup_notification", false, "print notification on startup"); + lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor, "Background color for notifcations with low urgency"); @@ -1581,6 +1584,20 @@ int main(int argc, char *argv[]) signal (SIGUSR1, pause_signal_handler); signal (SIGUSR2, pause_signal_handler); + if (startup_notification) { + notification *n = malloc(sizeof (notification)); + n->appname = "dunst"; + n->summary = "startup"; + n->body = "dunst is up and running"; + n->urgency = LOW; + n->icon = NULL; + n->msg = NULL; + n->dbus_client = NULL; + n->color_strings[0] = NULL; + n->color_strings[1] = NULL; + init_notification(n, 0); + } + run(); return 0; } diff --git a/dunstrc b/dunstrc index 3ef3e82..6797c8a 100644 --- a/dunstrc +++ b/dunstrc @@ -89,6 +89,10 @@ # that fits nicely to the background color. separator_color = auto + # print a notification on startup + # This is mainly for error detection, since dbus (re-)starts dunst + # automatically after a crash. + startup_notification = false [shortcuts] # shortcuts are specified as [modifier+][modifier+]...key From b46d02bfd71d7d2d98804c5f6905d7495ec19c39 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 02:01:00 +0100 Subject: [PATCH 45/51] don't strip newline from summary --- dunst.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dunst.c b/dunst.c index b23063e..efc7d21 100644 --- a/dunst.c +++ b/dunst.c @@ -661,7 +661,6 @@ char str = string_replace("<", "<", str); str = string_replace(">", ">", str); - str = string_replace("\n", " ", str); /* remove tags */ str = string_replace("", "", str); str = string_replace("", "", str); From e30692da88aa1915504ac585f22183194bb0b704 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 11:53:10 +0100 Subject: [PATCH 46/51] simplify Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fc49eac..97a7862 100644 --- a/Makefile +++ b/Makefile @@ -24,9 +24,9 @@ config.h: @echo creating $@ from config.def.h @cp config.def.h $@ -dunst: draw.o dunst.o container.o dunst_dbus.o utils.o options.o +dunst: ${OBJ} @echo CC -o $@ - @${CC} ${CFLAGS} -o $@ dunst.o draw.o container.o dunst_dbus.o options.o utils.o ${LDFLAGS} + @${CC} ${CFLAGS} -o $@ ${OBJ} ${LDFLAGS} clean: @echo cleaning From b5f4feee27c1941fa0783a258a2d5f6b36b465ac Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 11:58:21 +0100 Subject: [PATCH 47/51] Makefile: add debug target --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 97a7862..a901aed 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,10 @@ dunst: ${OBJ} @echo CC -o $@ @${CC} ${CFLAGS} -o $@ ${OBJ} ${LDFLAGS} +debug: ${OBJ} + @echo CC -o $@ + @${CC} ${CFLAGS} -O0 -o dunst ${OBJ} ${LDFLAGS} + clean: @echo cleaning @rm -f ${OBJ} From 9a662f23138f999f49dd97f77de39ef99f80425e Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 15:03:56 +0100 Subject: [PATCH 48/51] extract urls --- container.c | 36 +++++++++++++++++++++++++++++++++ container.h | 10 +++++++++ dunst.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dunst.h | 1 + 4 files changed, 105 insertions(+) diff --git a/container.c b/container.c index 8e89fa3..2db3e80 100644 --- a/container.c +++ b/container.c @@ -1,5 +1,6 @@ #include "stdlib.h" #include "stdio.h" +#include #include "container.h" @@ -138,4 +139,39 @@ int n_queue_len(n_queue **q) return n_stack_len(q); } +str_array *str_array_malloc(void) +{ + str_array *a = malloc(sizeof(str_array)); + a->count = 0; + a->strs = NULL; + return a; +} + +void str_array_append(str_array *a, char *str) +{ + if (!a) + return; + a->count++; + a->strs = realloc(a->strs, a->count); + (a->strs)[a->count-1] = str; +} + +void str_array_dup_append(str_array *a, const char *str) +{ + if (!a) + return; + char *dup = strdup(str); + str_array_append(a, dup); +} + +void str_array_deep_free(str_array *a) +{ + if (!a) + return; + for (int i = 0; i < a->count; i++) { + free((a->strs)[i]); + } + free(a); +} + /* vim: set ts=8 sw=8 tw=0: */ diff --git a/container.h b/container.h index 9a16150..1e8e0b5 100644 --- a/container.h +++ b/container.h @@ -10,6 +10,16 @@ typedef struct _n_stack { typedef n_stack n_queue; +typedef struct _str_array { + int count; + char **strs; +} str_array; + +str_array *str_array_malloc(void); +void str_array_dup_append(str_array *a, const char *str); +void str_array_append(str_array *a, char *str); +void str_array_deep_free(str_array *a); + int cmp_notification(notification *a, notification *b); /************ diff --git a/dunst.c b/dunst.c index efc7d21..bdd9255 100644 --- a/dunst.c +++ b/dunst.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,7 @@ void draw_win(void); void hide_win(void); void move_all_to_history(void); void print_version(void); +str_array *extract_urls(const char *str); void r_line_cache_init(r_line_cache *c); void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues); @@ -108,6 +110,49 @@ void r_line_cache_reset(r_line_cache *c); void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); +str_array *extract_urls( const char * to_match) +{ + static bool is_initialized = false; + static regex_t cregex; + + if (!is_initialized) { + char *regex = "((http|ftp|https)(://))?(www\\.)?[[:alnum:]_-]+\\.[^[:space:]]+"; + int ret = regcomp(&cregex, regex, REG_EXTENDED|REG_ICASE); + if (ret != 0) { + printf("failed to compile regex\n"); + return NULL; + } + } + + str_array *urls = str_array_malloc(); + + const char * p = to_match; + regmatch_t m; + + while (1) { + int nomatch = regexec (&cregex, p, 1, &m, 0); + if (nomatch) { + return urls; + } + int start; + int finish; + if (m.rm_so == -1) { + break; + } + start = m.rm_so + (p - to_match); + finish = m.rm_eo + (p - to_match); + + char *match = strndup(to_match+start, finish-start); + + str_array_append(urls, match); + + p += m.rm_eo; + } + return 0; + + return urls; +} + void pause_signal_handler(int sig) { if (sig == SIGUSR1) { @@ -130,6 +175,12 @@ static void print_notification(notification * n) printf("\turgency: %d\n", n->urgency); printf("\tformatted: %s\n", n->msg); printf("\tid: %d\n", n->id); + printf("urls\n"); + printf("\t{\n"); + for (int i = 0; i < n->urls->count; i++) { + printf("\t\t%s\n", (n->urls->strs)[i]); + } + printf("\t}\n"); printf("}\n"); } @@ -911,6 +962,13 @@ int init_notification(notification * n, int id) n_queue_enqueue(&queue, n); } + char *tmp; + asprintf(&tmp, "%s %s", n->summary, n->body); + + n->urls = extract_urls(tmp); + + free(tmp); + if (print_notifications) print_notification(n); diff --git a/dunst.h b/dunst.h index 6f9b854..b68a2ef 100644 --- a/dunst.h +++ b/dunst.h @@ -51,6 +51,7 @@ typedef struct _notification { char *color_strings[2]; int progress; /* percentage + 1, 0 to hide */ int line_count; + struct { int count; char **strs; } *urls; } notification; typedef struct _notification_buffer { From 42e49a7b3404d542c2de667f1b1eed309d4afe55 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 15:56:15 +0100 Subject: [PATCH 49/51] context menu for urls --- config.def.h | 8 ++++++ dunst.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ dunstrc | 10 ++++++++ utils.c | 18 +++++++++++++ utils.h | 2 ++ 5 files changed, 109 insertions(+) diff --git a/config.def.h b/config.def.h index 7fddce7..45c0a87 100644 --- a/config.def.h +++ b/config.def.h @@ -37,6 +37,11 @@ int startup_notification = False; /* monitor to display notifications on */ int monitor = 0; +/* path to dmenu */ +char *dmenu = "/usr/bin/dmenu"; + +char *browser = "/usr/bin/firefox"; + /* follow focus to different monitor and display notifications there? * possible values: * FOLLOW_NONE @@ -60,6 +65,9 @@ keyboard_shortcut close_all_ks = {.str = "none", keyboard_shortcut history_ks = {.str = "none", .code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */ +keyboard_shortcut context_ks = {.str = "none", + .code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */ + rule_t default_rules[] = { /* name can be any unique string. It is used to identify the rule in dunstrc to override it there */ diff --git a/dunst.c b/dunst.c index bdd9255..350bcc1 100644 --- a/dunst.c +++ b/dunst.c @@ -102,6 +102,7 @@ void hide_win(void); void move_all_to_history(void); void print_version(void); str_array *extract_urls(const char *str); +void context_menu(void); void r_line_cache_init(r_line_cache *c); void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues); @@ -153,6 +154,57 @@ str_array *extract_urls( const char * to_match) return urls; } +void context_menu(void) { + char *dmenu_input = NULL; + + n_queue *iter = displayed; + + while (iter) { + for (int i = 0; i < iter->n->urls->count; i++) { + dmenu_input = string_append(dmenu_input, + (iter->n->urls->strs)[i], "\n"); + } + iter = iter->next; + } + + int child_io[2]; + int parent_io[2]; + pipe(child_io); + pipe(parent_io); + int pid = fork(); + + if (pid == 0) { + close(child_io[1]); + close(parent_io[0]); + close(0); + dup(child_io[0]); + close(1); + dup(parent_io[1]); + execlp(dmenu, dmenu, (char *) NULL); + } else { + close(child_io[0]); + close(parent_io[1]); + write(child_io[1], dmenu_input, strlen(dmenu_input)); + close(child_io[1]); + + char buf[1024]; + size_t len = read(parent_io[0], buf, 1023); + if (len == 0) + return; + buf[len - 1] = '\0'; + } + + close(child_io[1]); + + int browser_pid = fork(); + + if (browser_pid == 0) { + execlp(browser, browser, (char *) NULL); + } else { + return; + } +} + void pause_signal_handler(int sig) { if (sig == SIGUSR1) { @@ -812,6 +864,11 @@ void handleXEvents(void) && close_all_ks.mask == ev.xkey.state) { move_all_to_history(); } + if (context_ks.str + && XLookupKeysym(&ev.xkey, 0) == context_ks.sym + && context_ks.mask == ev.xkey.state) { + context_menu(); + } } } } @@ -1149,6 +1206,7 @@ void hide_win() { ungrab_key(&close_ks); ungrab_key(&close_all_ks); + ungrab_key(&context_ks); XUngrabButton(dc->dpy, AnyButton, AnyModifier, win); XUnmapWindow(dc->dpy, win); @@ -1264,6 +1322,7 @@ void setup(void) init_shortcut(&close_ks); init_shortcut(&close_all_ks); init_shortcut(&history_ks); + init_shortcut(&context_ks); grab_key(&close_ks); ungrab_key(&close_ks); @@ -1271,6 +1330,8 @@ void setup(void) ungrab_key(&close_all_ks); grab_key(&history_ks); ungrab_key(&history_ks); + grab_key(&context_ks); + ungrab_key(&context_ks); colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor); colors[NORM] = initcolor(dc, normfgcolor, normbgcolor); @@ -1344,6 +1405,7 @@ void map_win(void) grab_key(&close_ks); grab_key(&close_all_ks); + grab_key(&context_ks); setup_error_handler(); XGrabButton(dc->dpy, AnyButton, AnyModifier, win, false, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); @@ -1498,6 +1560,10 @@ void load_options(char *cmdline_config_path) startup_notification = option_get_bool("global", "startup_notification", "-startup_notification", false, "print notification on startup"); + + dmenu = option_get_string("global", "dmenu", "-dmenu", dmenu, "path to dmenu"); + browser = option_get_string("global", "browser", "-browser", browser, "path to browser"); + lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor, "Background color for notifcations with low urgency"); @@ -1543,6 +1609,11 @@ void load_options(char *cmdline_config_path) history_ks.str, "Shortcut to pop the last notification from history"); + context_ks.str = + option_get_string("shortcuts", "context", "-context_key", + context_ks.str, + "Shortcut for context menu"); + print_notifications = cmdline_get_bool("-print", false, "Print notifications to cmdline (DEBUG)"); diff --git a/dunstrc b/dunstrc index 6797c8a..311df0d 100644 --- a/dunstrc +++ b/dunstrc @@ -94,6 +94,13 @@ # automatically after a crash. startup_notification = false + # dmenu path + dmenu = "/usr/bin/dmenu" + + # browser for opening urls in context menu + browser = /usr/bin/firefox + + [shortcuts] # shortcuts are specified as [modifier+][modifier+]...key # available modifiers are 'ctrl', 'mod1' (the alt-key), 'mod2', 'mod3' @@ -110,6 +117,9 @@ # On the US keyboard layout 'grave' is normally above TAB and left of '1'. history = ctrl+grave + # context menu + context = ctrl+shift+period + [urgency_low] # IMPORTANT: colors have to be defined in quotation marks. # Otherwise the '#' and following would be interpreted as a comment. diff --git a/utils.c b/utils.c index ef1b133..90f7026 100644 --- a/utils.c +++ b/utils.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE + #include #include #include @@ -46,6 +48,22 @@ char *string_replace(const char *needle, const char *replacement, return tmp; } +char *string_append(char *a, const char *b, const char *sep) +{ + if (!a) + return strdup(b); + + char *new; + if (!sep) + asprintf(&new, "%s%s", a, b); + else + asprintf(&new, "%s%s%s", a, sep, b); + free(a); + + return new; + +} + int digit_count(int i) { int len = 0; diff --git a/utils.h b/utils.h index 3d3774f..ab1e8d6 100644 --- a/utils.h +++ b/utils.h @@ -8,6 +8,8 @@ char *lskip(char *str); char *string_replace(const char *needle, const char *replacement, char *haystack); +char *string_append(char *a, const char *b, const char *sep); + /* exit with an error message */ void die(char *msg, int exit_value); From 02bd5879353bcde8f30cc2b57d6421ddf4784b39 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 16:38:14 +0100 Subject: [PATCH 50/51] allow parameters to dmenu and browser calls --- dunst.c | 12 ++++++++++-- dunstrc | 4 ++-- utils.c | 17 +++++++++++++++++ utils.h | 2 ++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/dunst.c b/dunst.c index 350bcc1..3f5f9a0 100644 --- a/dunst.c +++ b/dunst.c @@ -72,6 +72,8 @@ static int font_h; static bool print_notifications = false; static dimension_t window_dim; static bool pause_display = false; +static char **dmenu_cmd; +static char **browser_cmd; static r_line_cache line_cache; @@ -167,6 +169,9 @@ void context_menu(void) { iter = iter->next; } + if (!dmenu_input) + return; + int child_io[2]; int parent_io[2]; pipe(child_io); @@ -180,7 +185,7 @@ void context_menu(void) { dup(child_io[0]); close(1); dup(parent_io[1]); - execlp(dmenu, dmenu, (char *) NULL); + execvp(dmenu_cmd[0], dmenu_cmd); } else { close(child_io[0]); close(parent_io[1]); @@ -199,7 +204,7 @@ void context_menu(void) { int browser_pid = fork(); if (browser_pid == 0) { - execlp(browser, browser, (char *) NULL); + execvp(browser_cmd[0], browser_cmd); } else { return; } @@ -1562,7 +1567,10 @@ void load_options(char *cmdline_config_path) dmenu = option_get_string("global", "dmenu", "-dmenu", dmenu, "path to dmenu"); + dmenu_cmd = string_to_argv(dmenu); + browser = option_get_string("global", "browser", "-browser", browser, "path to browser"); + browser_cmd = string_to_argv(browser); lowbgcolor = option_get_string("urgency_low", "background", "-lb", lowbgcolor, diff --git a/dunstrc b/dunstrc index 311df0d..e1c5c72 100644 --- a/dunstrc +++ b/dunstrc @@ -95,10 +95,10 @@ startup_notification = false # dmenu path - dmenu = "/usr/bin/dmenu" + dmenu = /usr/bin/dmenu -p dunst: # browser for opening urls in context menu - browser = /usr/bin/firefox + browser = /usr/bin/firefox -new-tab [shortcuts] diff --git a/utils.c b/utils.c index 90f7026..681f199 100644 --- a/utils.c +++ b/utils.c @@ -64,6 +64,23 @@ char *string_append(char *a, const char *b, const char *sep) } +char **string_to_argv(const char *str) +{ + char **argv = NULL; + char *p = strtok (str, " "); + int n_spaces = 0, i; + + while (p) { + argv = realloc (argv, sizeof (char*) * ++n_spaces); + argv[n_spaces-1] = p; + p = strtok (NULL, " "); + } + argv = realloc (argv, sizeof (char*) * (n_spaces+1)); + argv[n_spaces] = NULL; + + return argv; +} + int digit_count(int i) { int len = 0; diff --git a/utils.h b/utils.h index ab1e8d6..72465da 100644 --- a/utils.h +++ b/utils.h @@ -10,6 +10,8 @@ char *string_replace(const char *needle, const char *replacement, char *string_append(char *a, const char *b, const char *sep); +char **string_to_argv(const char *str); + /* exit with an error message */ void die(char *msg, int exit_value); From d519bb6531e4b9c367a9f46f2335d62491e24f20 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 19 Dec 2012 16:49:02 +0100 Subject: [PATCH 51/51] get rid of warnings in utils.{c,h} --- utils.c | 5 +++-- utils.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/utils.c b/utils.c index 681f199..a915336 100644 --- a/utils.c +++ b/utils.c @@ -64,11 +64,12 @@ char *string_append(char *a, const char *b, const char *sep) } -char **string_to_argv(const char *str) +char **string_to_argv(const char *s) { + char *str = strdup(s); char **argv = NULL; char *p = strtok (str, " "); - int n_spaces = 0, i; + int n_spaces = 0; while (p) { argv = realloc (argv, sizeof (char*) * ++n_spaces); diff --git a/utils.h b/utils.h index 72465da..c93479d 100644 --- a/utils.h +++ b/utils.h @@ -10,7 +10,7 @@ char *string_replace(const char *needle, const char *replacement, char *string_append(char *a, const char *b, const char *sep); -char **string_to_argv(const char *str); +char **string_to_argv(const char *s); /* exit with an error message */ void die(char *msg, int exit_value);