summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compton.c522
-rw-r--r--compton.h71
2 files changed, 460 insertions, 133 deletions
diff --git a/compton.c b/compton.c
index 8945c7749..519c8ca1a 100644
--- a/compton.c
+++ b/compton.c
@@ -87,10 +87,6 @@ Bool win_type_fade[NUM_WINTYPES];
* Macros
*/
-#define IS_NORMAL_WIN(w) \
-((w) && ((w)->window_type == WINTYPE_NORMAL \
- || (w)->window_type == WINTYPE_UTILITY))
-
#define HAS_FRAME_OPACITY(w) \
(frame_opacity && (w)->top_width)
@@ -98,6 +94,7 @@ Bool win_type_fade[NUM_WINTYPES];
* Options
*/
+char *display = NULL;
int shadow_radius = 12;
int shadow_offset_x = -15;
int shadow_offset_y = -15;
@@ -137,8 +134,20 @@ wincond *shadow_blacklist = NULL;
/// Fading blacklist. A linked list of conditions.
wincond *fade_blacklist = NULL;
+/// Whether to fork to background.
+Bool fork_after_register = False;
+/// Red, green and blue tone of the shadow.
+double shadow_red = 0.0, shadow_green = 0.0, shadow_blue = 0.0;
+
Bool synchronize = False;
+// Temporary options
+Bool shadow_enable = False;
+Bool fading_enable = False;
+Bool no_dock_shadow = False;
+Bool no_dnd_shadow = False;
+double menu_opacity = 1.0;
+
/**
* Fades
*/
@@ -740,6 +749,9 @@ win_match(win *w, wincond *condlst, wincond **cache) {
*/
static Bool
condlst_add(wincond **pcondlst, const char *pattern) {
+ if (!pattern)
+ return False;
+
unsigned plen = strlen(pattern);
wincond *cond;
const char *pos;
@@ -1231,6 +1243,10 @@ paint_preprocess(Display *dpy, win *list) {
if (!w->extents) {
w->extents = win_extents(dpy, w);
+ // If w->extents does not exist, the previous add_damage_win()
+ // call when opacity changes has no effect, so redo it here.
+ if (w->opacity != opacity_old)
+ add_damage_win(dpy, w);
}
// Rebuild alpha_pict only if necessary
@@ -1765,8 +1781,6 @@ determine_mode(Display *dpy, win *w) {
}
w->mode = mode;
-
- add_damage_win(dpy, w);
}
/**
@@ -1811,7 +1825,7 @@ calc_opacity(Display *dpy, win *w, Bool refetch_prop) {
}
// Respect inactive_opacity in some cases
- if (inactive_opacity && IS_NORMAL_WIN(w) && False == w->focused
+ if (inactive_opacity && is_normal_win(w) && False == w->focused
&& (OPAQUE == opacity || inactive_opacity_override)) {
opacity = inactive_opacity;
}
@@ -1823,7 +1837,7 @@ static void
calc_dim(Display *dpy, win *w) {
Bool dim;
- if (inactive_dim && IS_NORMAL_WIN(w) && !(w->focused)) {
+ if (inactive_dim && is_normal_win(w) && !(w->focused)) {
dim = True;
} else {
dim = False;
@@ -2916,6 +2930,8 @@ usage(void) {
" Daemonize process.\n"
"-S\n"
" Enable synchronous operation (for debugging).\n"
+ "--config path\n"
+ " Look for configuration file at the path.\n"
"--shadow-red value\n"
" Red color value of shadow (0.0 - 1.0, defaults to 0).\n"
"--shadow-green value\n"
@@ -3005,87 +3021,229 @@ fork_after(void) {
freopen("/dev/null", "w", stderr);
}
+#ifdef CONFIG_LIBCONFIG
+/**
+ * Get a file stream of the configuration file to read.
+ *
+ * Follows the XDG specification to search for the configuration file.
+ */
+static FILE *
+open_config_file(char *cpath, char **ppath) {
+ const static char *config_filename = "/compton.conf";
+ const static char *config_filename_legacy = "/.compton.conf";
+ const static char *config_home_suffix = "/.config";
+ const static char *config_system_dir = "/etc/xdg";
+
+ char *dir = NULL, *home = NULL;
+ char *path = cpath;
+ FILE *f = NULL;
+
+ if (path) {
+ f = fopen(path, "r");
+ if (f && ppath)
+ *ppath = path;
+ else
+ free(path);
+ return f;
+ }
+
+ // Check user configuration file in $XDG_CONFIG_HOME firstly
+ if (!((dir = getenv("XDG_CONFIG_HOME")) && strlen(dir))) {
+ if (!((home = getenv("HOME")) && strlen(home)))
+ return NULL;
+
+ path = mstrjoin3(home, config_home_suffix, config_filename);
+ }
+ else
+ path = mstrjoin(dir, config_filename);
+
+ f = fopen(path, "r");
+
+ if (f && ppath)
+ *ppath = path;
+ else
+ free(path);
+ if (f)
+ return f;
+
+ // Then check user configuration file in $HOME
+ if ((home = getenv("HOME")) && strlen(home)) {
+ path = mstrjoin(home, config_filename_legacy);
+ f = fopen(path, "r");
+ if (f && ppath)
+ *ppath = path;
+ else
+ free(path);
+ if (f)
+ return f;
+ }
+
+ // Check system configuration file in $XDG_CONFIG_DIRS at last
+ if ((dir = getenv("XDG_CONFIG_DIRS")) && strlen(dir)) {
+ char *part = strtok(dir, ":");
+ while (part) {
+ path = mstrjoin(part, config_filename);
+ f = fopen(path, "r");
+ if (f && ppath)
+ *ppath = path;
+ else
+ free(path);
+ if (f)
+ return f;
+ part = strtok(NULL, ":");
+ }
+ }
+ else {
+ path = mstrjoin(config_system_dir, config_filename);
+ f = fopen(path, "r");
+ if (f && ppath)
+ *ppath = path;
+ else
+ free(path);
+ if (f)
+ return f;
+ }
+
+ return NULL;
+}
+
+/**
+ * Parse a configuration file from default location.
+ */
static void
-get_atoms(void) {
- extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False);
- opacity_atom = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
- frame_extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False);
- client_atom = XA_WM_CLASS;
- name_atom = XA_WM_NAME;
- name_ewmh_atom = XInternAtom(dpy, "_NET_WM_NAME", False);
- class_atom = XA_WM_CLASS;
+parse_config(char *cpath) {
+ char *path = NULL, *parent = NULL;
+ FILE *f;
+ config_t cfg;
+ int ival = 0;
+ double dval = 0.0;
+
+ f = open_config_file(cpath, &path);
+ if (!f) {
+ if (cpath)
+ printf("Failed to read the specified configuration file.\n");
+ return;
+ }
- win_type_atom = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE", False);
- win_type[WINTYPE_UNKNOWN] = 0;
- win_type[WINTYPE_DESKTOP] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_DESKTOP", False);
- win_type[WINTYPE_DOCK] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_DOCK", False);
- win_type[WINTYPE_TOOLBAR] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
- win_type[WINTYPE_MENU] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_MENU", False);
- win_type[WINTYPE_UTILITY] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_UTILITY", False);
- win_type[WINTYPE_SPLASH] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_SPLASH", False);
- win_type[WINTYPE_DIALOG] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_DIALOG", False);
- win_type[WINTYPE_NORMAL] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_NORMAL", False);
- win_type[WINTYPE_DROPDOWN_MENU] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
- win_type[WINTYPE_POPUP_MENU] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
- win_type[WINTYPE_TOOLTIP] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
- win_type[WINTYPE_NOTIFY] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
- win_type[WINTYPE_COMBO] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_COMBO", False);
- win_type[WINTYPE_DND] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE_DND", False);
+ config_init(&cfg);
+ parent = dirname(path);
+ if (parent)
+ config_set_include_dir(&cfg, parent);
+
+ if (CONFIG_FALSE == config_read(&cfg, f)) {
+ printf("Error when reading configuration file \"%s\", line %d: %s\n",
+ path, config_error_line(&cfg), config_error_text(&cfg));
+ config_destroy(&cfg);
+ free(path);
+ return;
+ }
+ config_set_auto_convert(&cfg, 1);
+
+ free(path);
+
+ // Get options from the configuration file. We don't do range checking
+ // right now. It will be done later
+
+ // -D (fade_delta)
+ if (config_lookup_int(&cfg, "fade-delta", &ival))
+ fade_delta = ival;
+ // -I (fade_in_step)
+ if (config_lookup_float(&cfg, "fade-in-step", &dval))
+ fade_in_step = normalize_d(dval) * OPAQUE;
+ // -O (fade_out_step)
+ if (config_lookup_float(&cfg, "fade-out-step", &dval))
+ fade_out_step = normalize_d(dval) * OPAQUE;
+ // -r (shadow_radius)
+ config_lookup_int(&cfg, "shadow-radius", &shadow_radius);
+ // -o (shadow_opacity)
+ config_lookup_float(&cfg, "shadow-opacity", &shadow_opacity);
+ // -l (shadow_offset_x)
+ config_lookup_int(&cfg, "shadow-offset-x", &shadow_offset_x);
+ // -t (shadow_offset_y)
+ config_lookup_int(&cfg, "shadow-offset-y", &shadow_offset_y);
+ // -i (inactive_opacity)
+ if (config_lookup_float(&cfg, "inactive-opacity", &dval))
+ inactive_opacity = normalize_d(dval) * OPAQUE;
+ // -e (frame_opacity)
+ config_lookup_float(&cfg, "frame-opacity", &frame_opacity);
+ // -z (clear_shadow)
+ if (config_lookup_bool(&cfg, "clear-shadow", &ival))
+ clear_shadow = ival;
+ // -c (shadow_enable)
+ if (config_lookup_bool(&cfg, "shadow", &ival))
+ shadow_enable = ival;
+ // -C (no_dock_shadow)
+ if (config_lookup_bool(&cfg, "no-dock-shadow", &ival))
+ no_dock_shadow = ival;
+ // -G (no_dnd_shadow)
+ if (config_lookup_bool(&cfg, "no-dnd-shadow", &ival))
+ no_dnd_shadow = ival;
+ // -m (menu_opacity)
+ config_lookup_float(&cfg, "menu-opacity", &menu_opacity);
+ // -f (fading_enable)
+ if (config_lookup_bool(&cfg, "fading", &ival))
+ fading_enable = ival;
+ // --shadow-red
+ config_lookup_float(&cfg, "shadow-red", &shadow_red);
+ // --shadow-green
+ config_lookup_float(&cfg, "shadow-green", &shadow_green);
+ // --shadow-blue
+ config_lookup_float(&cfg, "shadow-blue", &shadow_blue);
+ // --inactive-opacity-override
+ if (config_lookup_bool(&cfg, "inactive-opacity-override", &ival))
+ inactive_opacity_override = ival;
+ // --inactive-dim
+ config_lookup_float(&cfg, "inactive-dim", &inactive_dim);
+ // --mark-wmwin-focused
+ if (config_lookup_bool(&cfg, "mark-wmwin-focused", &ival))
+ mark_wmwin_focused = ival;
+ // --shadow-exclude
+ {
+ config_setting_t *shadow_blacklist_setting =
+ config_lookup(&cfg, "shadow-exclude");
+ if (shadow_blacklist_setting) {
+ // Parse an array of shadow-exclude
+ if (config_setting_is_array(shadow_blacklist_setting)) {
+ int i = config_setting_length(shadow_blacklist_setting);
+ while (i--) {
+ condlst_add(&shadow_blacklist,
+ config_setting_get_string_elem(shadow_blacklist_setting, i));
+ }
+ }
+ // Treat it as a single pattern if it's a string
+ else if (CONFIG_TYPE_STRING ==
+ config_setting_type(shadow_blacklist_setting)) {
+ condlst_add(&shadow_blacklist,
+ config_setting_get_string(shadow_blacklist_setting));
+ }
+ }
+ }
+
+ config_destroy(&cfg);
}
+#endif
-int
-main(int argc, char **argv) {
- const static struct option longopt[] = {
- { "shadow-red", required_argument, NULL, 0 },
- { "shadow-green", required_argument, NULL, 0 },
- { "shadow-blue", required_argument, NULL, 0 },
- { "inactive-opacity-override", no_argument, NULL, 0 },
- { "inactive-dim", required_argument, NULL, 0 },
- { "mark-wmwin-focused", no_argument, NULL, 0 },
- { "shadow-exclude", required_argument, NULL, 0 },
+/**
+ * Process arguments and configuration files.
+ */
+static void
+get_cfg(int argc, char *const *argv) {
+ const static char *shortopts = "D:I:O:d:r:o:m:l:t:i:e:scnfFCaSzGb";
+ const static struct option longopts[] = {
+ { "config", required_argument, NULL, 256 },
+ { "shadow-red", required_argument, NULL, 257 },
+ { "shadow-green", required_argument, NULL, 258 },
+ { "shadow-blue", required_argument, NULL, 259 },
+ { "inactive-opacity-override", no_argument, NULL, 260 },
+ { "inactive-dim", required_argument, NULL, 261 },
+ { "mark-wmwin-focused", no_argument, NULL, 262 },
+ { "shadow-exclude", required_argument, NULL, 263 },
// Must terminate with a NULL entry
{ NULL, 0, NULL, 0 },
};
- XEvent ev;
- Window root_return, parent_return;
- Window *children;
- unsigned int nchildren;
- int i;
- XRenderPictureAttributes pa;
- struct pollfd ufd;
- int composite_major, composite_minor;
- char *display = 0;
- int o;
- int longopt_idx;
- Bool no_dock_shadow = False;
- Bool no_dnd_shadow = False;
- Bool fork_after_register = False;
- double shadow_red = 0.0;
- double shadow_green = 0.0;
- double shadow_blue = 0.0;
- win *t;
-
- gettimeofday(&time_start, NULL);
-
- // Set locale so window names with special characters are interpreted
- // correctly
- setlocale (LC_ALL, "");
+ int o, longopt_idx, i;
+ char *config_file = NULL;
for (i = 0; i < NUM_WINTYPES; ++i) {
win_type_fade[i] = False;
@@ -3093,45 +3251,31 @@ main(int argc, char **argv) {
win_type_opacity[i] = 1.0;
}
- while ((o = getopt_long(argc, argv,
- "D:I:O:d:r:o:m:l:t:i:e:scnfFCaSzGb",
- longopt, &longopt_idx)) != -1) {
+ // Pre-parse the commandline arguments to check for --config and invalid
+ // switches
+ while (-1 !=
+ (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
+ if (256 == o)
+ config_file = mstrcpy(optarg);
+ else if ('?' == o || ':' == o)
+ usage();
+ }
+
+#ifdef CONFIG_LIBCONFIG
+ parse_config(config_file);
+#endif
+
+ // Parse commandline arguments. Range checking will be done later.
+ optind = 1;
+ while (-1 !=
+ (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
switch (o) {
- // Long options
- case 0:
- switch (longopt_idx) {
- case 0:
- shadow_red = normalize_d(atof(optarg));
- break;
- case 1:
- shadow_green = normalize_d(atof(optarg));
- break;
- case 2:
- shadow_blue = normalize_d(atof(optarg));
- break;
- case 3:
- inactive_opacity_override = True;
- break;
- case 4:
- inactive_dim = normalize_d(atof(optarg));
- break;
- case 5:
- mark_wmwin_focused = True;
- break;
- case 6:
- condlst_add(&shadow_blacklist, optarg);
- break;
- }
- break;
// Short options
case 'd':
display = optarg;
break;
case 'D':
fade_delta = atoi(optarg);
- if (fade_delta < 1) {
- fade_delta = 10;
- }
break;
case 'I':
fade_in_step = normalize_d(atof(optarg)) * OPAQUE;
@@ -3140,22 +3284,16 @@ main(int argc, char **argv) {
fade_out_step = normalize_d(atof(optarg)) * OPAQUE;
break;
case 'c':
- for (i = 0; i < NUM_WINTYPES; ++i) {
- win_type_shadow[i] = True;
- }
- win_type_shadow[WINTYPE_DESKTOP] = False;
+ shadow_enable = True;
break;
case 'C':
no_dock_shadow = True;
break;
case 'm':
- win_type_opacity[WINTYPE_DROPDOWN_MENU] = atof(optarg);
- win_type_opacity[WINTYPE_POPUP_MENU] = atof(optarg);
+ menu_opacity = atof(optarg);
break;
case 'f':
- for (i = 0; i < NUM_WINTYPES; ++i) {
- win_type_fade[i] = True;
- }
+ fading_enable = True;
break;
case 'F':
fade_trans = True;
@@ -3167,7 +3305,7 @@ main(int argc, char **argv) {
shadow_radius = atoi(optarg);
break;
case 'o':
- shadow_opacity = normalize_d(atof(optarg));
+ shadow_opacity = atof(optarg);
break;
case 'l':
shadow_offset_x = atoi(optarg);
@@ -3177,12 +3315,9 @@ main(int argc, char **argv) {
break;
case 'i':
inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
- if (OPAQUE == inactive_opacity) {
- inactive_opacity = 0;
- }
break;
case 'e':
- frame_opacity = normalize_d(atof(optarg));
+ frame_opacity = atof(optarg);
break;
case 'z':
clear_shadow = True;
@@ -3199,20 +3334,79 @@ main(int argc, char **argv) {
case 'b':
fork_after_register = True;
break;
+ // Long options
+ case 256:
+ // --config
+ break;
+ case 257:
+ // --shadow-red
+ shadow_red = atof(optarg);
+ break;
+ case 258:
+ // --shadow-green
+ shadow_green = atof(optarg);
+ break;
+ case 259:
+ // --shadow-blue
+ shadow_blue = atof(optarg);
+ break;
+ case 260:
+ // --inactive-opacity-override
+ inactive_opacity_override = True;
+ break;
+ case 261:
+ // --inactive-dim
+ inactive_dim = atof(optarg);
+ break;
+ case 262:
+ // --mark-wmwin-focused
+ mark_wmwin_focused = True;
+ break;
+ case 263:
+ // --shadow-exclude
+ condlst_add(&shadow_blacklist, optarg);
+ break;
default:
usage();
break;
}
}
- if (no_dock_shadow) {
- win_type_shadow[WINTYPE_DOCK] = False;
+ // Range checking and option assignments
+ fade_delta = max_i(fade_delta, 1);
+ shadow_radius = max_i(shadow_radius, 1);
+ shadow_red = normalize_d(shadow_red);
+ shadow_green = normalize_d(shadow_green);
+ shadow_blue = normalize_d(shadow_blue);
+ inactive_dim = normalize_d(inactive_dim);
+ frame_opacity = normalize_d(frame_opacity);
+ shadow_opacity = normalize_d(shadow_opacity);
+ menu_opacity = normalize_d(menu_opacity);
+ if (OPAQUE == inactive_opacity) {
+ inactive_opacity = 0;
+ }
+ if (shadow_enable) {
+ for (i = 0; i < NUM_WINTYPES; ++i) {
+ win_type_shadow[i] = True;
+ }
+ win_type_shadow[WINTYPE_DESKTOP] = False;
+ if (no_dock_shadow)
+ win_type_shadow[WINTYPE_DOCK] = False;
+ if (no_dnd_shadow)
+ win_type_shadow[WINTYPE_DND] = False;
+ }
+ if (fading_enable) {
+ for (i = 0; i < NUM_WINTYPES; ++i) {
+ win_type_fade[i] = True;
+ }
}
-
- if (no_dnd_shadow) {
- win_type_shadow[WINTYPE_DND] = False;
+ if (1.0 != menu_opacity) {
+ win_type_opacity[WINTYPE_DROPDOWN_MENU] = menu_opacity;
+ win_type_opacity[WINTYPE_POPUP_MENU] = menu_opacity;
}
+ // Other variables determined by options
+
// Determine whether we need to track focus changes
if (inactive_opacity || inactive_dim) {
track_focus = True;
@@ -3221,6 +3415,70 @@ main(int argc, char **argv) {
// Determine whether we need to track window name and class
if (shadow_blacklist || fade_blacklist)
track_wdata = True;
+}
+
+static void
+get_atoms(void) {
+ extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False);
+ opacity_atom = XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False);
+ frame_extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False);
+ client_atom = XA_WM_CLASS;
+ name_atom = XA_WM_NAME;
+ name_ewmh_atom = XInternAtom(dpy, "_NET_WM_NAME", False);
+ class_atom = XA_WM_CLASS;
+
+ win_type_atom = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE", False);
+ win_type[WINTYPE_UNKNOWN] = 0;
+ win_type[WINTYPE_DESKTOP] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_DESKTOP", False);
+ win_type[WINTYPE_DOCK] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_DOCK", False);
+ win_type[WINTYPE_TOOLBAR] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_TOOLBAR", False);
+ win_type[WINTYPE_MENU] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_MENU", False);
+ win_type[WINTYPE_UTILITY] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_UTILITY", False);
+ win_type[WINTYPE_SPLASH] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_SPLASH", False);
+ win_type[WINTYPE_DIALOG] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ win_type[WINTYPE_NORMAL] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_NORMAL", False);
+ win_type[WINTYPE_DROPDOWN_MENU] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False);
+ win_type[WINTYPE_POPUP_MENU] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_POPUP_MENU", False);
+ win_type[WINTYPE_TOOLTIP] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_TOOLTIP", False);
+ win_type[WINTYPE_NOTIFY] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_NOTIFICATION", False);
+ win_type[WINTYPE_COMBO] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_COMBO", False);
+ win_type[WINTYPE_DND] = XInternAtom(dpy,
+ "_NET_WM_WINDOW_TYPE_DND", False);
+}
+
+int
+main(int argc, char **argv) {
+ XEvent ev;
+ Window root_return, parent_return;
+ Window *children;
+ unsigned int nchildren;
+ int i;
+ XRenderPictureAttributes pa;
+ struct pollfd ufd;
+ int composite_major, composite_minor;
+ win *t;
+
+ gettimeofday(&time_start, NULL);
+
+ // Set locale so window names with special characters are interpreted
+ // correctly
+ setlocale (LC_ALL, "");
+
+ get_cfg(argc, argv);
fade_time = get_time_in_milliseconds();
diff --git a/compton.h b/compton.h
index c57dd2fd2..88ecbf9fc 100644
--- a/compton.h
+++ b/compton.h
@@ -24,6 +24,8 @@
// Whether to enable JIT support of libpcre. This may cause problems on PaX
// kernels.
#define CONFIG_REGEX_PCRE_JIT 1
+// Whether to enable parsing of configuration files using libconfig
+#define CONFIG_LIBCONFIG 1
// === Includes ===
@@ -44,10 +46,16 @@
#include <locale.h>
#include <fnmatch.h>
+
#ifdef CONFIG_REGEX_PCRE
#include <pcre.h>
#endif
+#ifdef CONFIG_LIBCONFIG
+#include <libgen.h>
+#include <libconfig.h>
+#endif
+
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
@@ -278,6 +286,34 @@ mstrcpy(const char *src) {
}
/**
+ * Allocate the space and join two strings.
+ */
+static inline char *
+mstrjoin(const char *src1, const char *src2) {
+ char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2) + 1));
+
+ strcpy(str, src1);
+ strcat(str, src2);
+
+ return str;
+}
+
+/**
+ * Allocate the space and join two strings;
+ */
+static inline char *
+mstrjoin3(const char *src1, const char *src2, const char *src3) {
+ char *str = malloc(sizeof(char) * (strlen(src1) + strlen(src2)
+ + strlen(src3) + 1));
+
+ strcpy(str, src1);
+ strcat(str, src2);
+ strcat(str, src3);
+
+ return str;
+}
+
+/**
* Normalize an int value to a specific range.
*
* @param i int value to normalize
@@ -285,7 +321,7 @@ mstrcpy(const char *src) {
* @param max maximum value
* @return normalized value
*/
-static inline double
+static inline int
normalize_i_range(int i, int min, int max) {
if (i > max) return max;
if (i < min) return min;
@@ -293,6 +329,22 @@ normalize_i_range(int i, int min, int max) {
}
/**
+ * Select the larger integer of two.
+ */
+static inline int
+max_i(int a, int b) {
+ return (a > b ? a : b);
+}
+
+/**
+ * Select the smaller integer of two.
+ */
+static inline int
+min_i(int a, int b) {
+ return (a > b ? b : a);
+}
+
+/**
* Normalize a double value to a specific range.
*
* @param d double value to normalize
@@ -530,6 +582,12 @@ static Picture
solid_picture(Display *dpy, Bool argb, double a,
double r, double g, double b);
+static inline bool is_normal_win(const win *w) {
+ return (WINTYPE_NORMAL == w->window_type
+ || WINTYPE_UTILITY == w->window_type
+ || WINTYPE_UNKNOWN == w->window_type);
+}
+
static bool
win_match_once(win *w, const wincond *cond);
@@ -789,5 +847,16 @@ ev_handle(XEvent *ev);
static void
fork_after(void);
+#ifdef CONFIG_LIBCONFIG
+static FILE *
+open_config_file(char *cpath, char **path);
+
+static void
+parse_config(char *cpath);
+#endif
+
+static void
+get_cfg(int argc, char *const *argv);
+
static void
get_atoms(void);