diff --git a/Makefile b/Makefile index 79d2018..d416498 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -SRC = draw.c dunst.c list.c dunst_dbus.c ini.c +SRC = draw.c dunst.c list.c dunst_dbus.c ini.c utils.c OBJ = ${SRC:.c=.o} all: doc options dunst service @@ -18,11 +18,15 @@ options: @echo CC -c $< @${CC} -c $< ${CFLAGS} -${OBJ}: config.mk +${OBJ}: config.h config.mk -dunst: draw.o dunst.o list.o dunst_dbus.o ini.o +config.h: + @echo creating $@ from config.def.h + @cp config.def.h $@ + +dunst: draw.o dunst.o list.o dunst_dbus.o ini.o utils.o @echo CC -o $@ - @${CC} ${CFLAGS} -o $@ dunst.o draw.o list.o dunst_dbus.o ini.o ${LDFLAGS} + @${CC} ${CFLAGS} -o $@ dunst.o draw.o list.o dunst_dbus.o ini.o utils.o ${LDFLAGS} clean: @echo cleaning diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..bb4a406 --- /dev/null +++ b/config.def.h @@ -0,0 +1,57 @@ +/* see example dunstrc for additional explanations about these options */ + +char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; +char *normbgcolor = "#1793D1"; +char *normfgcolor = "#DDDDDD"; +char *critbgcolor = "#ffaaaa"; +char *critfgcolor = "#000000"; +char *lowbgcolor = "#aaaaff"; +char *lowfgcolor = "#000000"; +char *format = "%s %b"; /* default format */ + +int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */ + +char *geom = "0x0"; /* geometry */ +int sort = True; /* sort messages by urgency */ +int indicate_hidden = True; /* show count of hidden messages */ +int idle_threshold = 0; /* don't timeout notifications when idle for x seconds */ +int show_age_threshold = -1; /* show age of notification, when notification is older than x seconds */ +enum alignment align = left; /* text alignment [left/center/right] */ +int sticky_history = True; +int verbosity = 0; + + +/* monitor to display notifications on */ +int monitor = 0; + +/* follow focus to different monitor and display notifications there? + * possible values: + * FOLLOW_NONE + * FOLLOW_MOUSE + * FOLLOW_KEYBOARD + * + * everything else than FOLLOW_NONE overrides 'monitor' + */ +enum follow_mode f_mode = FOLLOW_NONE; + +/* keyboard shortcuts */ +keyboard_shortcut close_ks = {.str = "ctrl+space", + .code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */ + +keyboard_shortcut close_all_ks = {.str = "ctrl+shift+space", + .code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */ + +keyboard_shortcut history_ks = {.str = "ctrl+grave", + .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 */ + + /* name, appname, summary, body, icon, timeout, urgency, fg, bg, format */ + { "empty", NULL, NULL, NULL, NULL, -1, -1, NULL, NULL, NULL, }, + /* { "rule1", "notify-send", NULL, NULL, NULL, -1, -1, NULL, NULL, "%s %b" }, */ + /* { "rule2", "Pidgin", "*says*, NULL, NULL, -1, CRITICAL, NULL, NULL, NULL }, */ + /* { "rule3", "Pidgin", "*signed on*", NULL, NULL, -1, LOW, NULL, NULL, NULL }, */ + /* { "rule4", "Pidgin", "*signed off*", NULL, NULL, -1, LOW, NULL, NULL, NULL }, */ + /* { "rule5", NULL, "*foobar*", NULL, NULL, -1, -1, NULL, "#00FF00", NULL, }, */ + }; diff --git a/config.mk b/config.mk index 19da3b4..9ebe2a1 100644 --- a/config.mk +++ b/config.mk @@ -7,7 +7,6 @@ VERSION="0.3.0" X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib -# Xft, comment if you don't want it XFTINC = -I/usr/include/freetype2 XFTLIBS = -lXft @@ -15,6 +14,10 @@ XFTLIBS = -lXft XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA +# uncomment to disable parsing of dunstrc +# or use "CFLAGS=-DSTATIC_CONFIG make" to build +#STATIC= -DSTATIC_CONFIG + # inih flags INIFLAGS = -DINI_ALLOW_MULTILINE=0 @@ -23,6 +26,6 @@ INCS = -I${X11INC} $(shell pkg-config --cflags dbus-1 libxdg-basedir) ${XFTINC} LIBS = -L${X11LIB} -lX11 -lXss ${XFTLIBS} ${XINERAMALIBS} $(shell pkg-config --libs dbus-1 libxdg-basedir) # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${INIFLAGS} -CFLAGS = -g --std=c99 -pedantic -Wall -Wno-overlength-strings -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} +CPPFLAGS += -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} ${INIFLAGS} +CFLAGS += -g --std=c99 -pedantic -Wall -Wno-overlength-strings -Os ${INCS} ${STATIC} ${CPPFLAGS} +LDFLAGS += ${LIBS} diff --git a/dunst.c b/dunst.c index 9cbf7d4..bbb49fc 100644 --- a/dunst.c +++ b/dunst.c @@ -24,6 +24,8 @@ #include "dunst_dbus.h" #include "list.h" #include "ini.h" +#include "utils.h" + #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]) @@ -52,27 +54,14 @@ typedef struct _notification_buffer { int x_offset; } notification_buffer; + + + /* global variables */ -char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -char *normbgcolor = "#1793D1"; -char *normfgcolor = "#DDDDDD"; -char *critbgcolor = "#ffaaaa"; -char *critfgcolor = "#000000"; -char *lowbgcolor = "#aaaaff"; -char *lowfgcolor = "#000000"; -char *format = "%s %b"; /* default format */ -int timeouts[] = { 10, 10, 0 }; /* low, normal, critical */ -char *geom = "0x0"; /* geometry */ +#include "config.h" + int height_limit; -int sort = True; /* sort messages by urgency */ -int indicate_hidden = True; /* show count of hidden messages */ -int idle_threshold = 0; -int show_age_threshold = -1; -enum alignment align = left; -int sticky_history = True; - -int verbosity = 0; list *rules = NULL; /* index of colors fit to urgency level */ @@ -83,24 +72,11 @@ static DC *dc; static Window win; static time_t now; static int visible = False; -static keyboard_shortcut close_ks = {.str = NULL,.code = 0,.sym = - NoSymbol,.mask = 0,.is_valid = False -}; - -static keyboard_shortcut close_all_ks = {.str = NULL,.code = 0,.sym = - NoSymbol,.mask = 0,.is_valid = False -}; - -static keyboard_shortcut history_ks = {.str = NULL,.code = 0,.sym = - NoSymbol,.mask = 0,.is_valid = False -}; - static screen_info scr; static dimension_t geometry; static XScreenSaverInfo *screensaver_info; static int font_h; -static enum follow_mode f_mode = FOLLOW_NONE; int next_notification_id = 1; @@ -116,16 +92,12 @@ list *notification_history = NULL; /* history of displayed notifications */ void apply_rules(notification * n); void check_timeouts(void); void draw_notifications(void); -void dunst_printf(int level, const char *fmt, ...); char *fix_markup(char *str); void handle_mouse_click(XEvent ev); void handleXEvents(void); void history_pop(void); rule_t *initrule(void); int is_idle(void); -char *string_replace(const char *needle, const char *replacement, - char *haystack); -char *strtrim(char *str); void run(void); void setup(void); void update_screen_info(); @@ -136,16 +108,13 @@ void draw_win(void); void hide_win(void); void move_all_to_history(void); void print_version(void); + +/* show warning notification */ void warn(const char * text, int urg); void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); -void die(char *text, int exit_value) -{ - fputs(text, stderr); - exit(exit_value); -} void warn(const char *text, int urg) { @@ -531,17 +500,6 @@ void draw_win(void) free(n_buf); } -void dunst_printf(int level, const char *fmt, ...) -{ - va_list ap; - - if (level > verbosity) { - return; - } - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} char *fix_markup(char *str) @@ -929,48 +887,6 @@ int is_idle(void) return screensaver_info->idle / 1000 > idle_threshold; } -char *string_replace(const char *needle, const char *replacement, - char *haystack) -{ - char *tmp, *start; - int size; - start = strstr(haystack, needle); - if (start == NULL) { - return haystack; - } - - size = (strlen(haystack) - strlen(needle)) + strlen(replacement) + 1; - tmp = calloc(sizeof(char), size); - memset(tmp, '\0', size); - - strncpy(tmp, haystack, start - haystack); - tmp[start - haystack] = '\0'; - - 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; - } -} - -char *strtrim(char *str) -{ - char *end; - while (isspace(*str)) - str++; - - end = str + strlen(str) - 1; - while (isspace(*end)) { - *end = '\0'; - end--; - } - - return str; - -} void run(void) { @@ -1041,7 +957,7 @@ Window get_focused_window(void) int select_screen(XineramaScreenInfo * info, int info_len) { if (f_mode == FOLLOW_NONE) { - return scr.scr; + return monitor; } else { int x, y; @@ -1063,7 +979,7 @@ int select_screen(XineramaScreenInfo * info, int info_len) if (focused == 0) { /* something went wrong. Fallback to default */ - return scr.scr; + return monitor; } Window child_return; @@ -1080,7 +996,7 @@ int select_screen(XineramaScreenInfo * info, int info_len) } /* something seems to be wrong. Fallback to default */ - return scr.scr; + return monitor; } } @@ -1088,15 +1004,15 @@ void update_screen_info() { #ifdef XINERAMA int n; - int screen = 0; + int screen = monitor; XineramaScreenInfo *info; #endif #ifdef XINERAMA if ((info = XineramaQueryScreens(dc->dpy, &n))) { screen = select_screen(info, n); if (screen >= n) { - fprintf(stderr, "Monitor %d not found\n", screen); - exit(EXIT_FAILURE); + /* invalid monitor, fallback to default */ + screen = 0; } scr.dim.x = info[screen].x_org; scr.dim.y = info[screen].y_org; @@ -1322,6 +1238,7 @@ void parse_cmdline(int argc, char *argv[]) } } +#ifndef STATIC_CONFIG static int dunst_ini_get_boolean(const char *value) { switch (value[0]) { @@ -1505,7 +1422,6 @@ void parse_dunstrc(char *cmdline_config_path) FILE *config_file = NULL; xdgInitHandle(&xdg); - rules = l_init(); if (cmdline_config_path != NULL) { config_file = fopen(cmdline_config_path, "r"); @@ -1533,6 +1449,7 @@ void parse_dunstrc(char *cmdline_config_path) print_rules(); } +#endif /* STATIC_CONFIG */ char *parse_cmdline_for_config_file(int argc, char *argv[]) { @@ -1550,12 +1467,17 @@ char *parse_cmdline_for_config_file(int argc, char *argv[]) int main(int argc, char *argv[]) { - char *cmdline_config_path; now = time(&now); + rules = l_init(); + for (int i = 0; i < LENGTH(default_rules); i++) { + l_push(rules, &default_rules[i]); + } +#ifndef STATIC_CONFIG + char *cmdline_config_path; cmdline_config_path = parse_cmdline_for_config_file(argc, argv); - parse_dunstrc(cmdline_config_path); +#endif parse_cmdline(argc, argv); dc = initdc(); diff --git a/dunst.h b/dunst.h index 86bf751..44a55c8 100644 --- a/dunst.h +++ b/dunst.h @@ -1,7 +1,6 @@ /* copyright 2012 Sascha Kruse and contributors (see LICENSE for licensing information) */ -#ifndef DUNST_H -#define DUNST_H +#pragma once #include "draw.h" @@ -13,6 +12,7 @@ #define ColFG 1 #define ColBG 0 + enum alignment { left, center, right }; typedef struct _rule_t { @@ -67,11 +67,12 @@ typedef struct _keyboard_shortcut { int is_valid; } keyboard_shortcut; +extern int verbosity; + /* return id of notification */ int init_notification(notification * n, int id); int close_notification(notification * n, int reason); int close_notification_by_id(int id, int reason); void map_win(void); -#endif /* vim: set ts=8 sw=8 tw=0: */ diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..7505a6c --- /dev/null +++ b/utils.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +#include "utils.h" +#include "dunst.h" + + +char *strtrim(char *str) +{ + char *end; + while (isspace(*str)) + str++; + + end = str + strlen(str) - 1; + while (isspace(*end)) { + *end = '\0'; + end--; + } + + return str; + +} + +char *string_replace(const char *needle, const char *replacement, + char *haystack) +{ + char *tmp, *start; + int size; + start = strstr(haystack, needle); + if (start == NULL) { + return haystack; + } + + size = (strlen(haystack) - strlen(needle)) + strlen(replacement) + 1; + tmp = calloc(sizeof(char), size); + memset(tmp, '\0', size); + + strncpy(tmp, haystack, start - haystack); + tmp[start - haystack] = '\0'; + + 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; + } +} + +void dunst_printf(int level, const char *fmt, ...) +{ + va_list ap; + + if (level > verbosity) { + return; + } + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +void die(char *text, int exit_value) +{ + fputs(text, stderr); + exit(exit_value); +} + +/* vim: set ts=8 sw=8 tw=0: */ diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..fb4b36f --- /dev/null +++ b/utils.h @@ -0,0 +1,18 @@ +#ifndef UTIL_H +#define UTIL_H +/* remove spaces before and after str */ +char *strtrim(char *str); + +/* replace needle with replacement in haystack */ +char *string_replace(const char *needle, const char *replacement, + char *haystack); + +/* exit with an error message */ +void die(char * msg, int exit_value); + +/* print depending on verbosity */ +void dunst_printf(int level, const char *fmt, ...); + +#endif + +/* vim: set ts=8 sw=8 tw=0: */