Merge pull request #72 from yshui/clean-opt2
Option/config parsing clean up
This commit is contained in:
commit
4dce20fab4
58
src/c2.c
58
src/c2.c
|
@ -34,6 +34,8 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||||
|
|
||||||
#define C2_MAX_LEVELS 10
|
#define C2_MAX_LEVELS 10
|
||||||
|
|
||||||
typedef struct _c2_b c2_b_t;
|
typedef struct _c2_b c2_b_t;
|
||||||
|
@ -301,22 +303,19 @@ c2h_b_opcmp(c2_b_op_t op1, c2_b_op_t op2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level);
|
c2_parse_grp(const char *pattern, int offset, c2_ptr_t *presult, int level);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
c2_parse_op(const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult);
|
c2_parse_legacy(const char *pattern, int offset, c2_ptr_t *presult);
|
||||||
|
|
||||||
static bool
|
|
||||||
c2_l_postprocess(session_t *ps, c2_l_t *pleaf);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
c2_free(c2_ptr_t p);
|
c2_free(c2_ptr_t p);
|
||||||
|
@ -351,7 +350,7 @@ c2_match_once(session_t *ps, win *w, const c2_ptr_t cond);
|
||||||
* Parse a condition string.
|
* Parse a condition string.
|
||||||
*/
|
*/
|
||||||
c2_lptr_t *
|
c2_lptr_t *
|
||||||
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
c2_parse(c2_lptr_t **pcondlst, const char *pattern,
|
||||||
void *data) {
|
void *data) {
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -361,9 +360,9 @@ c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||||
int offset = -1;
|
int offset = -1;
|
||||||
|
|
||||||
if (strlen(pattern) >= 2 && ':' == pattern[1])
|
if (strlen(pattern) >= 2 && ':' == pattern[1])
|
||||||
offset = c2_parse_legacy(ps, pattern, 0, &result);
|
offset = c2_parse_legacy(pattern, 0, &result);
|
||||||
else
|
else
|
||||||
offset = c2_parse_grp(ps, pattern, 0, &result, 0);
|
offset = c2_parse_grp(pattern, 0, &result, 0);
|
||||||
|
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
c2_freep(&result);
|
c2_freep(&result);
|
||||||
|
@ -405,7 +404,7 @@ c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
||||||
* @return offset of next character in string
|
* @return offset of next character in string
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult, int level) {
|
c2_parse_grp(const char *pattern, int offset, c2_ptr_t *presult, int level) {
|
||||||
// Check for recursion levels
|
// Check for recursion levels
|
||||||
if (level > C2_MAX_LEVELS)
|
if (level > C2_MAX_LEVELS)
|
||||||
c2_error("Exceeded maximum recursion levels.");
|
c2_error("Exceeded maximum recursion levels.");
|
||||||
|
@ -505,12 +504,12 @@ c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult,
|
||||||
|
|
||||||
// It's a subgroup if it starts with '('
|
// It's a subgroup if it starts with '('
|
||||||
if ('(' == pattern[offset]) {
|
if ('(' == pattern[offset]) {
|
||||||
if ((offset = c2_parse_grp(ps, pattern, offset + 1, pele, level + 1)) < 0)
|
if ((offset = c2_parse_grp(pattern, offset + 1, pele, level + 1)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// Otherwise it's a leaf
|
// Otherwise it's a leaf
|
||||||
else {
|
else {
|
||||||
if ((offset = c2_parse_target(ps, pattern, offset, pele)) < 0)
|
if ((offset = c2_parse_target(pattern, offset, pele)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
assert(!pele->isbranch && !c2_ptr_isempty(*pele));
|
assert(!pele->isbranch && !c2_ptr_isempty(*pele));
|
||||||
|
@ -518,10 +517,7 @@ c2_parse_grp(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult,
|
||||||
if ((offset = c2_parse_op(pattern, offset, pele)) < 0)
|
if ((offset = c2_parse_op(pattern, offset, pele)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if ((offset = c2_parse_pattern(ps, pattern, offset, pele)) < 0)
|
if ((offset = c2_parse_pattern(pattern, offset, pele)) < 0)
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (!c2_l_postprocess(ps, pele->l))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
// Decrement offset -- we will increment it in loop update
|
// Decrement offset -- we will increment it in loop update
|
||||||
|
@ -579,7 +575,7 @@ fail:
|
||||||
* Parse the target part of a rule.
|
* Parse the target part of a rule.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
c2_parse_target(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
c2_parse_target(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||||
// Initialize leaf
|
// Initialize leaf
|
||||||
presult->isbranch = false;
|
presult->isbranch = false;
|
||||||
presult->l = cmalloc(c2_l_t);
|
presult->l = cmalloc(c2_l_t);
|
||||||
|
@ -838,7 +834,7 @@ fail:
|
||||||
* Parse the pattern part of a leaf.
|
* Parse the pattern part of a leaf.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
c2_parse_pattern(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
c2_parse_pattern(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||||
c2_l_t * const pleaf = presult->l;
|
c2_l_t * const pleaf = presult->l;
|
||||||
|
|
||||||
// Exists operator cannot have pattern
|
// Exists operator cannot have pattern
|
||||||
|
@ -977,7 +973,7 @@ fail:
|
||||||
* Parse a condition with legacy syntax.
|
* Parse a condition with legacy syntax.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presult) {
|
c2_parse_legacy(const char *pattern, int offset, c2_ptr_t *presult) {
|
||||||
unsigned plen = strlen(pattern + offset);
|
unsigned plen = strlen(pattern + offset);
|
||||||
|
|
||||||
if (plen < 4 || ':' != pattern[offset + 1]
|
if (plen < 4 || ':' != pattern[offset + 1]
|
||||||
|
@ -1033,9 +1029,6 @@ c2_parse_legacy(session_t *ps, const char *pattern, int offset, c2_ptr_t *presul
|
||||||
// Copy the pattern
|
// Copy the pattern
|
||||||
pleaf->ptnstr = strdup(pattern + offset);
|
pleaf->ptnstr = strdup(pattern + offset);
|
||||||
|
|
||||||
if (!c2_l_postprocess(ps, pleaf))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -1145,6 +1138,25 @@ c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool c2_tree_postprocess(session_t *ps, c2_ptr_t node) {
|
||||||
|
if (!node.isbranch) {
|
||||||
|
return c2_l_postprocess(ps, node.l);
|
||||||
|
}
|
||||||
|
if (!c2_tree_postprocess(ps, node.b->opr1))
|
||||||
|
return false;
|
||||||
|
return c2_tree_postprocess(ps, node.b->opr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list) {
|
||||||
|
c2_lptr_t *head = list;
|
||||||
|
while (head) {
|
||||||
|
if (!c2_tree_postprocess(ps, head->ptr))
|
||||||
|
return false;
|
||||||
|
head = head->next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Free a condition tree.
|
* Free a condition tree.
|
||||||
*/
|
*/
|
||||||
|
|
14
src/c2.h
14
src/c2.h
|
@ -17,13 +17,11 @@ typedef struct _c2_lptr c2_lptr_t;
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
typedef struct win win;
|
typedef struct win win;
|
||||||
|
|
||||||
c2_lptr_t *
|
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
|
||||||
c2_parse(session_t *ps, c2_lptr_t **pcondlst, const char *pattern,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
c2_lptr_t *
|
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp);
|
||||||
c2_free_lptr(c2_lptr_t *lp);
|
|
||||||
|
|
||||||
bool
|
bool c2_match(session_t *ps, win *w, const c2_lptr_t *condlst, const c2_lptr_t **cache,
|
||||||
c2_match(session_t *ps, win *w, const c2_lptr_t *condlst,
|
void **pdata);
|
||||||
const c2_lptr_t **cache, void **pdata);
|
|
||||||
|
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list);
|
||||||
|
|
323
src/common.h
323
src/common.h
|
@ -122,6 +122,7 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
// === Constants ===
|
// === Constants ===
|
||||||
|
|
||||||
|
@ -155,9 +156,6 @@
|
||||||
/// @brief Maximum OpenGL buffer age.
|
/// @brief Maximum OpenGL buffer age.
|
||||||
#define CGLX_MAX_BUFFER_AGE 5
|
#define CGLX_MAX_BUFFER_AGE 5
|
||||||
|
|
||||||
/// @brief Maximum passes for blur.
|
|
||||||
#define MAX_BLUR_PASS 5
|
|
||||||
|
|
||||||
// Window flags
|
// Window flags
|
||||||
|
|
||||||
// Window size is changed
|
// Window size is changed
|
||||||
|
@ -173,9 +171,6 @@
|
||||||
|
|
||||||
// === Types ===
|
// === Types ===
|
||||||
|
|
||||||
typedef long time_ms_t;
|
|
||||||
typedef struct _c2_lptr c2_lptr_t;
|
|
||||||
|
|
||||||
/// Structure representing needed window updates.
|
/// Structure representing needed window updates.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool shadow : 1;
|
bool shadow : 1;
|
||||||
|
@ -206,25 +201,6 @@ enum wincond_type {
|
||||||
|
|
||||||
#define CONDF_IGNORECASE 0x0001
|
#define CONDF_IGNORECASE 0x0001
|
||||||
|
|
||||||
/// VSync modes.
|
|
||||||
typedef enum {
|
|
||||||
VSYNC_NONE,
|
|
||||||
VSYNC_DRM,
|
|
||||||
VSYNC_OPENGL,
|
|
||||||
VSYNC_OPENGL_OML,
|
|
||||||
VSYNC_OPENGL_SWC,
|
|
||||||
VSYNC_OPENGL_MSWC,
|
|
||||||
NUM_VSYNC,
|
|
||||||
} vsync_t;
|
|
||||||
|
|
||||||
/// @brief Possible backends of compton.
|
|
||||||
enum backend {
|
|
||||||
BKEND_XRENDER,
|
|
||||||
BKEND_GLX,
|
|
||||||
BKEND_XR_GLX_HYBRID,
|
|
||||||
NUM_BKEND,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Possible swap methods.
|
/// @brief Possible swap methods.
|
||||||
enum {
|
enum {
|
||||||
SWAPM_BUFFER_AGE = -1,
|
SWAPM_BUFFER_AGE = -1,
|
||||||
|
@ -371,202 +347,6 @@ typedef struct _latom {
|
||||||
|
|
||||||
#define REG_DATA_INIT { NULL, 0 }
|
#define REG_DATA_INIT { NULL, 0 }
|
||||||
|
|
||||||
typedef struct win_option_mask {
|
|
||||||
bool shadow: 1;
|
|
||||||
bool fade: 1;
|
|
||||||
bool focus: 1;
|
|
||||||
bool full_shadow: 1;
|
|
||||||
bool redir_ignore: 1;
|
|
||||||
bool opacity: 1;
|
|
||||||
} win_option_mask_t;
|
|
||||||
|
|
||||||
typedef struct win_option {
|
|
||||||
bool shadow;
|
|
||||||
bool fade;
|
|
||||||
bool focus;
|
|
||||||
bool full_shadow;
|
|
||||||
bool redir_ignore;
|
|
||||||
double opacity;
|
|
||||||
} win_option_t;
|
|
||||||
|
|
||||||
/// Structure representing all options.
|
|
||||||
typedef struct options_t {
|
|
||||||
// === Debugging ===
|
|
||||||
bool monitor_repaint;
|
|
||||||
bool print_diagnostics;
|
|
||||||
// === General ===
|
|
||||||
/// The configuration file we used.
|
|
||||||
char *config_file;
|
|
||||||
/// Path to write PID to.
|
|
||||||
char *write_pid_path;
|
|
||||||
/// The backend in use.
|
|
||||||
enum backend backend;
|
|
||||||
/// Whether to sync X drawing to avoid certain delay issues with
|
|
||||||
/// GLX backend.
|
|
||||||
bool xrender_sync;
|
|
||||||
/// Whether to sync X drawing with X Sync fence.
|
|
||||||
bool xrender_sync_fence;
|
|
||||||
/// Whether to avoid using stencil buffer under GLX backend. Might be
|
|
||||||
/// unsafe.
|
|
||||||
bool glx_no_stencil;
|
|
||||||
/// Whether to avoid rebinding pixmap on window damage.
|
|
||||||
bool glx_no_rebind_pixmap;
|
|
||||||
/// GLX swap method we assume OpenGL uses.
|
|
||||||
int glx_swap_method;
|
|
||||||
/// Whether to use GL_EXT_gpu_shader4 to (hopefully) accelerates blurring.
|
|
||||||
bool glx_use_gpushader4;
|
|
||||||
/// Custom fragment shader for painting windows, as a string.
|
|
||||||
char *glx_fshader_win_str;
|
|
||||||
/// Custom GLX program used for painting window.
|
|
||||||
glx_prog_main_t glx_prog_win;
|
|
||||||
/// Whether to fork to background.
|
|
||||||
bool fork_after_register;
|
|
||||||
/// Whether to detect rounded corners.
|
|
||||||
bool detect_rounded_corners;
|
|
||||||
/// Force painting of window content with blending.
|
|
||||||
bool force_win_blend;
|
|
||||||
/// Resize damage for a specific number of pixels.
|
|
||||||
int resize_damage;
|
|
||||||
/// Whether to unredirect all windows if a full-screen opaque window
|
|
||||||
/// is detected.
|
|
||||||
bool unredir_if_possible;
|
|
||||||
/// List of conditions of windows to ignore as a full-screen window
|
|
||||||
/// when determining if a window could be unredirected.
|
|
||||||
c2_lptr_t *unredir_if_possible_blacklist;
|
|
||||||
/// Delay before unredirecting screen.
|
|
||||||
time_ms_t unredir_if_possible_delay;
|
|
||||||
/// Forced redirection setting through D-Bus.
|
|
||||||
switch_t redirected_force;
|
|
||||||
/// Whether to stop painting. Controlled through D-Bus.
|
|
||||||
switch_t stoppaint_force;
|
|
||||||
/// Whether to re-redirect screen on root size change.
|
|
||||||
bool reredir_on_root_change;
|
|
||||||
/// Whether to reinitialize GLX on root size change.
|
|
||||||
bool glx_reinit_on_root_change;
|
|
||||||
/// Whether to enable D-Bus support.
|
|
||||||
bool dbus;
|
|
||||||
/// Path to log file.
|
|
||||||
char *logpath;
|
|
||||||
/// Number of cycles to paint in benchmark mode. 0 for disabled.
|
|
||||||
int benchmark;
|
|
||||||
/// Window to constantly repaint in benchmark mode. 0 for full-screen.
|
|
||||||
Window benchmark_wid;
|
|
||||||
/// A list of conditions of windows not to paint.
|
|
||||||
c2_lptr_t *paint_blacklist;
|
|
||||||
/// Whether to show all X errors.
|
|
||||||
bool show_all_xerrors;
|
|
||||||
/// Whether to avoid acquiring X Selection.
|
|
||||||
bool no_x_selection;
|
|
||||||
/// Window type option override.
|
|
||||||
win_option_t wintype_option[NUM_WINTYPES];
|
|
||||||
|
|
||||||
// === VSync & software optimization ===
|
|
||||||
/// User-specified refresh rate.
|
|
||||||
int refresh_rate;
|
|
||||||
/// Whether to enable refresh-rate-based software optimization.
|
|
||||||
bool sw_opti;
|
|
||||||
/// VSync method to use;
|
|
||||||
vsync_t vsync;
|
|
||||||
/// Whether to do VSync aggressively.
|
|
||||||
bool vsync_aggressive;
|
|
||||||
/// Whether to use glFinish() instead of glFlush() for (possibly) better
|
|
||||||
/// VSync yet probably higher CPU usage.
|
|
||||||
bool vsync_use_glfinish;
|
|
||||||
|
|
||||||
// === Shadow ===
|
|
||||||
/// Red, green and blue tone of the shadow.
|
|
||||||
double shadow_red, shadow_green, shadow_blue;
|
|
||||||
int shadow_radius;
|
|
||||||
int shadow_offset_x, shadow_offset_y;
|
|
||||||
double shadow_opacity;
|
|
||||||
/// argument string to shadow-exclude-reg option
|
|
||||||
char *shadow_exclude_reg_str;
|
|
||||||
/// Shadow blacklist. A linked list of conditions.
|
|
||||||
c2_lptr_t *shadow_blacklist;
|
|
||||||
/// Whether bounding-shaped window should be ignored.
|
|
||||||
bool shadow_ignore_shaped;
|
|
||||||
/// Whether to respect _COMPTON_SHADOW.
|
|
||||||
bool respect_prop_shadow;
|
|
||||||
/// Whether to crop shadow to the very Xinerama screen.
|
|
||||||
bool xinerama_shadow_crop;
|
|
||||||
|
|
||||||
// === Fading ===
|
|
||||||
/// How much to fade in in a single fading step.
|
|
||||||
opacity_t fade_in_step;
|
|
||||||
/// How much to fade out in a single fading step.
|
|
||||||
opacity_t fade_out_step;
|
|
||||||
/// Fading time delta. In milliseconds.
|
|
||||||
time_ms_t fade_delta;
|
|
||||||
/// Whether to disable fading on window open/close.
|
|
||||||
bool no_fading_openclose;
|
|
||||||
/// Whether to disable fading on ARGB managed destroyed windows.
|
|
||||||
bool no_fading_destroyed_argb;
|
|
||||||
/// Fading blacklist. A linked list of conditions.
|
|
||||||
c2_lptr_t *fade_blacklist;
|
|
||||||
|
|
||||||
// === Opacity ===
|
|
||||||
/// Default opacity for inactive windows.
|
|
||||||
/// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for
|
|
||||||
/// not enabled, default.
|
|
||||||
opacity_t inactive_opacity;
|
|
||||||
/// Default opacity for inactive windows.
|
|
||||||
opacity_t active_opacity;
|
|
||||||
/// Whether inactive_opacity overrides the opacity set by window
|
|
||||||
/// attributes.
|
|
||||||
bool inactive_opacity_override;
|
|
||||||
/// Frame opacity. Relative to window opacity, also affects shadow
|
|
||||||
/// opacity.
|
|
||||||
double frame_opacity;
|
|
||||||
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
|
||||||
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
|
||||||
bool detect_client_opacity;
|
|
||||||
|
|
||||||
// === Other window processing ===
|
|
||||||
/// Whether to blur background of semi-transparent / ARGB windows.
|
|
||||||
bool blur_background;
|
|
||||||
/// Whether to blur background when the window frame is not opaque.
|
|
||||||
/// Implies blur_background.
|
|
||||||
bool blur_background_frame;
|
|
||||||
/// Whether to use fixed blur strength instead of adjusting according
|
|
||||||
/// to window opacity.
|
|
||||||
bool blur_background_fixed;
|
|
||||||
/// Background blur blacklist. A linked list of conditions.
|
|
||||||
c2_lptr_t *blur_background_blacklist;
|
|
||||||
/// Blur convolution kernel.
|
|
||||||
xcb_render_fixed_t *blur_kerns[MAX_BLUR_PASS];
|
|
||||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
|
||||||
double inactive_dim;
|
|
||||||
/// Whether to use fixed inactive dim opacity, instead of deciding
|
|
||||||
/// based on window opacity.
|
|
||||||
bool inactive_dim_fixed;
|
|
||||||
/// Conditions of windows to have inverted colors.
|
|
||||||
c2_lptr_t *invert_color_list;
|
|
||||||
/// Rules to change window opacity.
|
|
||||||
c2_lptr_t *opacity_rules;
|
|
||||||
|
|
||||||
// === Focus related ===
|
|
||||||
/// Whether to try to detect WM windows and mark them as focused.
|
|
||||||
bool mark_wmwin_focused;
|
|
||||||
/// Whether to mark override-redirect windows as focused.
|
|
||||||
bool mark_ovredir_focused;
|
|
||||||
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
|
||||||
bool use_ewmh_active_win;
|
|
||||||
/// A list of windows always to be considered focused.
|
|
||||||
c2_lptr_t *focus_blacklist;
|
|
||||||
/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
|
|
||||||
bool detect_transient;
|
|
||||||
/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
|
|
||||||
bool detect_client_leader;
|
|
||||||
|
|
||||||
// === Calculated ===
|
|
||||||
/// Whether compton needs to track focus changes.
|
|
||||||
bool track_focus;
|
|
||||||
/// Whether compton needs to track window name and class.
|
|
||||||
bool track_wdata;
|
|
||||||
/// Whether compton needs to track window leaders.
|
|
||||||
bool track_leader;
|
|
||||||
} options_t;
|
|
||||||
|
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
/// Structure containing GLX-dependent data for a compton session.
|
/// Structure containing GLX-dependent data for a compton session.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -687,6 +467,9 @@ typedef struct session {
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
/// Pointer to GLX data.
|
/// Pointer to GLX data.
|
||||||
glx_session_t *psglx;
|
glx_session_t *psglx;
|
||||||
|
/// Custom GLX program used for painting window.
|
||||||
|
// XXX should be in glx_session_t
|
||||||
|
glx_prog_main_t glx_prog_win;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// === Operation related ===
|
// === Operation related ===
|
||||||
|
@ -710,7 +493,7 @@ typedef struct session {
|
||||||
/// Pre-generated alpha pictures.
|
/// Pre-generated alpha pictures.
|
||||||
xcb_render_picture_t *alpha_picts;
|
xcb_render_picture_t *alpha_picts;
|
||||||
/// Time of last fading. In milliseconds.
|
/// Time of last fading. In milliseconds.
|
||||||
time_ms_t fade_time;
|
unsigned long fade_time;
|
||||||
/// Head pointer of the error ignore linked list.
|
/// Head pointer of the error ignore linked list.
|
||||||
ignore_t *ignore_head;
|
ignore_t *ignore_head;
|
||||||
/// Pointer to the <code>next</code> member of tail element of the error
|
/// Pointer to the <code>next</code> member of tail element of the error
|
||||||
|
@ -894,8 +677,6 @@ typedef enum {
|
||||||
} win_evmode_t;
|
} win_evmode_t;
|
||||||
|
|
||||||
extern const char * const WINTYPES[NUM_WINTYPES];
|
extern const char * const WINTYPES[NUM_WINTYPES];
|
||||||
extern const char * const VSYNC_STRS[NUM_VSYNC + 1];
|
|
||||||
extern const char * const BACKEND_STRS[NUM_BKEND + 1];
|
|
||||||
extern session_t *ps_g;
|
extern session_t *ps_g;
|
||||||
|
|
||||||
// == Debugging code ==
|
// == Debugging code ==
|
||||||
|
@ -924,7 +705,7 @@ timeval_isempty(struct timeval *ptv) {
|
||||||
* @return > 0 if ptv > ms, 0 if ptv == 0, -1 if ptv < ms
|
* @return > 0 if ptv > ms, 0 if ptv == 0, -1 if ptv < ms
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
timeval_ms_cmp(struct timeval *ptv, time_ms_t ms) {
|
timeval_ms_cmp(struct timeval *ptv, unsigned long ms) {
|
||||||
assert(ptv);
|
assert(ptv);
|
||||||
|
|
||||||
// We use those if statement instead of a - expression because of possible
|
// We use those if statement instead of a - expression because of possible
|
||||||
|
@ -1067,97 +848,6 @@ print_timestamp(session_t *ps) {
|
||||||
fprintf(stderr, "[ %5ld.%06ld ] ", diff.tv_sec, diff.tv_usec);
|
fprintf(stderr, "[ %5ld.%06ld ] ", diff.tv_sec, diff.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a VSync option argument.
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
parse_vsync(session_t *ps, const char *str) {
|
|
||||||
for (vsync_t i = 0; VSYNC_STRS[i]; ++i)
|
|
||||||
if (!strcasecmp(str, VSYNC_STRS[i])) {
|
|
||||||
ps->o.vsync = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_error("Invalid vsync argument: %s", str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a backend option argument.
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
parse_backend(session_t *ps, const char *str) {
|
|
||||||
for (enum backend i = 0; BACKEND_STRS[i]; ++i)
|
|
||||||
if (!strcasecmp(str, BACKEND_STRS[i])) {
|
|
||||||
ps->o.backend = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Keep compatibility with an old revision containing a spelling mistake...
|
|
||||||
if (!strcasecmp(str, "xr_glx_hybird")) {
|
|
||||||
ps->o.backend = BKEND_XR_GLX_HYBRID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// cju wants to use dashes
|
|
||||||
if (!strcasecmp(str, "xr-glx-hybrid")) {
|
|
||||||
ps->o.backend = BKEND_XR_GLX_HYBRID;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
log_error("Invalid backend argument: %s", str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a glx_swap_method option argument.
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
parse_glx_swap_method(session_t *ps, const char *str) {
|
|
||||||
// Parse alias
|
|
||||||
if (!strcmp("undefined", str)) {
|
|
||||||
ps->o.glx_swap_method = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp("copy", str)) {
|
|
||||||
ps->o.glx_swap_method = 1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp("exchange", str)) {
|
|
||||||
ps->o.glx_swap_method = 2;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp("buffer-age", str)) {
|
|
||||||
ps->o.glx_swap_method = -1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse number
|
|
||||||
{
|
|
||||||
char *pc = NULL;
|
|
||||||
int age = strtol(str, &pc, 0);
|
|
||||||
if (!pc || str == pc) {
|
|
||||||
log_error("glx-swap-method is an invalid number: %s", str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; *pc; ++pc)
|
|
||||||
if (!isspace(*pc)) {
|
|
||||||
log_error("Trailing characters in glx-swap-method option: %s", str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (age > CGLX_MAX_BUFFER_AGE + 1 || age < -1) {
|
|
||||||
log_error("Number for glx-swap-method is too large / too small: %s", str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps->o.glx_swap_method = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper of XFree() for convenience.
|
* Wrapper of XFree() for convenience.
|
||||||
*
|
*
|
||||||
|
@ -1187,6 +877,7 @@ get_atom(session_t *ps, const char *atom_name) {
|
||||||
|
|
||||||
xcb_atom_t atom = XCB_NONE;
|
xcb_atom_t atom = XCB_NONE;
|
||||||
if (reply) {
|
if (reply) {
|
||||||
|
log_debug("Atom %s is %d", atom_name, reply->atom);
|
||||||
atom = reply->atom;
|
atom = reply->atom;
|
||||||
free(reply);
|
free(reply);
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -190,7 +190,7 @@ free_win_res(session_t *ps, win *w) {
|
||||||
/**
|
/**
|
||||||
* Get current system clock in milliseconds.
|
* Get current system clock in milliseconds.
|
||||||
*/
|
*/
|
||||||
static inline time_ms_t
|
static inline unsigned long
|
||||||
get_time_ms(void) {
|
get_time_ms(void) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
|
@ -350,7 +350,11 @@ void add_damage(session_t *ps, const region_t *damage) {
|
||||||
*/
|
*/
|
||||||
static double
|
static double
|
||||||
fade_timeout(session_t *ps) {
|
fade_timeout(session_t *ps) {
|
||||||
int diff = ps->o.fade_delta - get_time_ms() + ps->fade_time;
|
auto now = get_time_ms();
|
||||||
|
if (ps->o.fade_delta + ps->fade_time < now)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int diff = ps->o.fade_delta + ps->fade_time - now;
|
||||||
|
|
||||||
diff = normalize_i_range(diff, 0, ps->o.fade_delta * 2);
|
diff = normalize_i_range(diff, 0, ps->o.fade_delta * 2);
|
||||||
|
|
||||||
|
@ -547,13 +551,13 @@ paint_preprocess(session_t *ps, win *list) {
|
||||||
win *t = NULL, *next = NULL;
|
win *t = NULL, *next = NULL;
|
||||||
|
|
||||||
// Fading step calculation
|
// Fading step calculation
|
||||||
time_ms_t steps = 0L;
|
unsigned long steps = 0L;
|
||||||
if (ps->fade_time)
|
auto now = get_time_ms();
|
||||||
steps = (get_time_ms() - ps->fade_time +
|
auto tolerance = FADE_DELTA_TOLERANCE*ps->o.fade_delta;
|
||||||
FADE_DELTA_TOLERANCE*ps->o.fade_delta) /
|
if (ps->fade_time && now+tolerance >= ps->fade_time) {
|
||||||
ps->o.fade_delta;
|
steps = (now - ps->fade_time + tolerance) / ps->o.fade_delta;
|
||||||
|
} else {
|
||||||
// Reset fade_time if unset, or there appears to be a time disorder
|
// Reset fade_time if unset, or there appears to be a time disorder
|
||||||
if (!ps->fade_time || steps < 0L) {
|
|
||||||
ps->fade_time = get_time_ms();
|
ps->fade_time = get_time_ms();
|
||||||
steps = 0L;
|
steps = 0L;
|
||||||
}
|
}
|
||||||
|
@ -2567,13 +2571,13 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
.tgt_picture = None,
|
.tgt_picture = None,
|
||||||
.tgt_buffer = PAINT_INIT,
|
.tgt_buffer = PAINT_INIT,
|
||||||
.reg_win = None,
|
.reg_win = None,
|
||||||
|
#ifdef CONFIG_OPENGL
|
||||||
|
.glx_prog_win = GLX_PROG_MAIN_INIT,
|
||||||
|
#endif
|
||||||
.o = {
|
.o = {
|
||||||
.config_file = NULL,
|
.config_file = NULL,
|
||||||
.backend = BKEND_XRENDER,
|
.backend = BKEND_XRENDER,
|
||||||
.glx_no_stencil = false,
|
.glx_no_stencil = false,
|
||||||
#ifdef CONFIG_OPENGL
|
|
||||||
.glx_prog_win = GLX_PROG_MAIN_INIT,
|
|
||||||
#endif
|
|
||||||
.mark_wmwin_focused = false,
|
.mark_wmwin_focused = false,
|
||||||
.mark_ovredir_focused = false,
|
.mark_ovredir_focused = false,
|
||||||
.fork_after_register = false,
|
.fork_after_register = false,
|
||||||
|
@ -2830,8 +2834,28 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
xcb_discard_reply(ps->c,
|
xcb_discard_reply(ps->c,
|
||||||
xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence);
|
xcb_xfixes_query_version(ps->c, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION).sequence);
|
||||||
|
|
||||||
// Second pass
|
// Parse configuration file
|
||||||
get_cfg(ps, argc, argv);
|
win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}};
|
||||||
|
bool shadow_enabled = false, fading_enable = false, hasneg = false;
|
||||||
|
char *config_file = parse_config(&ps->o, ps->o.config_file, &shadow_enabled,
|
||||||
|
&fading_enable, &hasneg, winopt_mask);
|
||||||
|
free(ps->o.config_file);
|
||||||
|
ps->o.config_file = config_file;
|
||||||
|
|
||||||
|
// Parse all of the rest command line options
|
||||||
|
get_cfg(&ps->o, argc, argv, shadow_enabled, fading_enable, hasneg, winopt_mask);
|
||||||
|
|
||||||
|
// Get needed atoms for c2 condition lists
|
||||||
|
if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.paint_blacklist) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.shadow_blacklist) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.fade_blacklist) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.blur_background_blacklist) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.invert_color_list) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.opacity_rules) &&
|
||||||
|
c2_list_postprocess(ps, ps->o.focus_blacklist))) {
|
||||||
|
log_error("Post-processing of conditionals failed, some of your rules might not work");
|
||||||
|
}
|
||||||
|
|
||||||
rebuild_shadow_exclude_reg(ps);
|
rebuild_shadow_exclude_reg(ps);
|
||||||
|
|
||||||
|
|
59
src/config.c
59
src/config.c
|
@ -59,8 +59,10 @@ parse_matrix_readnum(const char *src, double *dest) {
|
||||||
* Parse a matrix.
|
* Parse a matrix.
|
||||||
*/
|
*/
|
||||||
xcb_render_fixed_t *
|
xcb_render_fixed_t *
|
||||||
parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
parse_matrix(const char *src, const char **endptr, bool *hasneg) {
|
||||||
int wid = 0, hei = 0;
|
int wid = 0, hei = 0;
|
||||||
|
*hasneg = false;
|
||||||
|
|
||||||
const char *pc = NULL;
|
const char *pc = NULL;
|
||||||
|
|
||||||
// Get matrix width and height
|
// Get matrix width and height
|
||||||
|
@ -95,7 +97,6 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
// Read elements
|
// Read elements
|
||||||
{
|
{
|
||||||
int skip = hei / 2 * wid + wid / 2;
|
int skip = hei / 2 * wid + wid / 2;
|
||||||
bool hasneg = false;
|
|
||||||
for (int i = 0; i < wid * hei; ++i) {
|
for (int i = 0; i < wid * hei; ++i) {
|
||||||
// Ignore the center element
|
// Ignore the center element
|
||||||
if (i == skip) {
|
if (i == skip) {
|
||||||
|
@ -106,12 +107,9 @@ parse_matrix(session_t *ps, const char *src, const char **endptr) {
|
||||||
if (src == (pc = parse_matrix_readnum(src, &val)))
|
if (src == (pc = parse_matrix_readnum(src, &val)))
|
||||||
goto err2;
|
goto err2;
|
||||||
src = pc;
|
src = pc;
|
||||||
if (val < 0) hasneg = true;
|
if (val < 0) *hasneg = true;
|
||||||
matrix[2 + i] = DOUBLE_TO_XFIXED(val);
|
matrix[2 + i] = DOUBLE_TO_XFIXED(val);
|
||||||
}
|
}
|
||||||
if (BKEND_XRENDER == ps->o.backend && hasneg)
|
|
||||||
log_warn("A convolution kernel with negative values may not work properly under X "
|
|
||||||
"Render backend.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect trailing characters
|
// Detect trailing characters
|
||||||
|
@ -151,17 +149,23 @@ err1:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a convolution kernel.
|
* Parse a convolution kernel.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* hasneg: whether the convolution kernel has negative values
|
||||||
*/
|
*/
|
||||||
xcb_render_fixed_t *
|
xcb_render_fixed_t *
|
||||||
parse_conv_kern(session_t *ps, const char *src, const char **endptr) {
|
parse_conv_kern(const char *src, const char **endptr, bool *hasneg) {
|
||||||
return parse_matrix(ps, src, endptr);
|
return parse_matrix(src, endptr, hasneg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a list of convolution kernels.
|
* Parse a list of convolution kernels.
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* hasneg: whether any of the convolution kernel has negative values
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, int max) {
|
parse_conv_kern_lst(const char *src, xcb_render_fixed_t **dest, int max, bool *hasneg) {
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *kern_str;
|
const char *kern_str;
|
||||||
|
@ -175,10 +179,13 @@ parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, i
|
||||||
{ "9x9gaussian", "9,9,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000," },
|
{ "9x9gaussian", "9,9,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000," },
|
||||||
{ "11x11gaussian", "11,11,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000," },
|
{ "11x11gaussian", "11,11,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000012,0.001723,0.059106,0.493069,0.493069,0.059106,0.001723,0.000012,0.000000,0.000000,0.000006,0.000849,0.029143,0.243117,0.493069,0.243117,0.029143,0.000849,0.000006,0.000000,0.000000,0.000001,0.000102,0.003493,0.029143,0.059106,0.029143,0.003493,0.000102,0.000001,0.000000,0.000000,0.000000,0.000003,0.000102,0.000849,0.001723,0.000849,0.000102,0.000003,0.000000,0.000000,0.000000,0.000000,0.000000,0.000001,0.000006,0.000012,0.000006,0.000001,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000,0.000000," },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
*hasneg = false;
|
||||||
|
|
||||||
for (unsigned int i = 0;
|
for (unsigned int i = 0;
|
||||||
i < sizeof(CONV_KERN_PREDEF) / sizeof(CONV_KERN_PREDEF[0]); ++i)
|
i < sizeof(CONV_KERN_PREDEF) / sizeof(CONV_KERN_PREDEF[0]); ++i)
|
||||||
if (!strcmp(CONV_KERN_PREDEF[i].name, src))
|
if (!strcmp(CONV_KERN_PREDEF[i].name, src))
|
||||||
return parse_conv_kern_lst(ps, CONV_KERN_PREDEF[i].kern_str, dest, max);
|
return parse_conv_kern_lst(CONV_KERN_PREDEF[i].kern_str, dest, max, hasneg);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const char *pc = src;
|
const char *pc = src;
|
||||||
|
@ -192,8 +199,10 @@ parse_conv_kern_lst(session_t *ps, const char *src, xcb_render_fixed_t **dest, i
|
||||||
// Continue parsing until the end of source string
|
// Continue parsing until the end of source string
|
||||||
i = 0;
|
i = 0;
|
||||||
while (pc && *pc && i < max - 1) {
|
while (pc && *pc && i < max - 1) {
|
||||||
if (!(dest[i++] = parse_conv_kern(ps, pc, &pc)))
|
bool tmp_hasneg;
|
||||||
|
if (!(dest[i++] = parse_conv_kern(pc, &pc, &tmp_hasneg)))
|
||||||
return false;
|
return false;
|
||||||
|
*hasneg |= tmp_hasneg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > 1) {
|
if (i > 1) {
|
||||||
|
@ -300,7 +309,7 @@ parse_geometry_end:
|
||||||
/**
|
/**
|
||||||
* Parse a list of opacity rules.
|
* Parse a list of opacity rules.
|
||||||
*/
|
*/
|
||||||
bool parse_rule_opacity(session_t *ps, const char *src) {
|
bool parse_rule_opacity(c2_lptr_t **res, const char *src) {
|
||||||
// Find opacity value
|
// Find opacity value
|
||||||
char *endptr = NULL;
|
char *endptr = NULL;
|
||||||
long val = strtol(src, &endptr, 0);
|
long val = strtol(src, &endptr, 0);
|
||||||
|
@ -324,27 +333,30 @@ bool parse_rule_opacity(session_t *ps, const char *src) {
|
||||||
|
|
||||||
// Parse pattern
|
// Parse pattern
|
||||||
// I hope 1-100 is acceptable for (void *)
|
// I hope 1-100 is acceptable for (void *)
|
||||||
return c2_parse(ps, &ps->o.opacity_rules, endptr, (void *) val);
|
return c2_parse(res, endptr, (void *) val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a pattern to a condition linked list.
|
* Add a pattern to a condition linked list.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
condlst_add(session_t *ps, c2_lptr_t **pcondlst, const char *pattern) {
|
condlst_add(c2_lptr_t **pcondlst, const char *pattern) {
|
||||||
if (!pattern)
|
if (!pattern)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!c2_parse(ps, pcondlst, pattern, NULL))
|
if (!c2_parse(pcondlst, pattern, NULL))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
char *parse_config(options_t *opt, const char *config_file,
|
||||||
|
bool *shadow_enable, bool *fading_enable, bool *hasneg,
|
||||||
win_option_mask_t *winopt_mask) {
|
win_option_mask_t *winopt_mask) {
|
||||||
|
char *ret = NULL;
|
||||||
#ifdef CONFIG_LIBCONFIG
|
#ifdef CONFIG_LIBCONFIG
|
||||||
parse_config_libconfig(ps, shadow_enable, fading_enable, winopt_mask);
|
ret = parse_config_libconfig(opt, config_file, shadow_enable, fading_enable,
|
||||||
|
hasneg, winopt_mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Apply default wintype options that does not depends on global options.
|
// Apply default wintype options that does not depends on global options.
|
||||||
|
@ -354,7 +366,7 @@ void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
||||||
// Except desktop windows are always drawn without shadow.
|
// Except desktop windows are always drawn without shadow.
|
||||||
if (!winopt_mask[WINTYPE_DESKTOP].shadow) {
|
if (!winopt_mask[WINTYPE_DESKTOP].shadow) {
|
||||||
winopt_mask[WINTYPE_DESKTOP].shadow = true;
|
winopt_mask[WINTYPE_DESKTOP].shadow = true;
|
||||||
ps->o.wintype_option[WINTYPE_DESKTOP].shadow = false;
|
opt->wintype_option[WINTYPE_DESKTOP].shadow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focused/unfocused state only apply to a few window types, all other windows
|
// Focused/unfocused state only apply to a few window types, all other windows
|
||||||
|
@ -364,27 +376,28 @@ void parse_config(session_t *ps, bool *shadow_enable, bool *fading_enable,
|
||||||
for (unsigned long i = 0; i < ARR_SIZE(nofocus_type); i++) {
|
for (unsigned long i = 0; i < ARR_SIZE(nofocus_type); i++) {
|
||||||
if (!winopt_mask[nofocus_type[i]].focus) {
|
if (!winopt_mask[nofocus_type[i]].focus) {
|
||||||
winopt_mask[nofocus_type[i]].focus = true;
|
winopt_mask[nofocus_type[i]].focus = true;
|
||||||
ps->o.wintype_option[nofocus_type[i]].focus = false;
|
opt->wintype_option[nofocus_type[i]].focus = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned long i = 0; i < NUM_WINTYPES; i++) {
|
for (unsigned long i = 0; i < NUM_WINTYPES; i++) {
|
||||||
if (!winopt_mask[i].focus) {
|
if (!winopt_mask[i].focus) {
|
||||||
winopt_mask[i].focus = true;
|
winopt_mask[i].focus = true;
|
||||||
ps->o.wintype_option[i].focus = true;
|
opt->wintype_option[i].focus = true;
|
||||||
}
|
}
|
||||||
if (!winopt_mask[i].full_shadow) {
|
if (!winopt_mask[i].full_shadow) {
|
||||||
winopt_mask[i].full_shadow = true;
|
winopt_mask[i].full_shadow = true;
|
||||||
ps->o.wintype_option[i].full_shadow = false;
|
opt->wintype_option[i].full_shadow = false;
|
||||||
}
|
}
|
||||||
if (!winopt_mask[i].redir_ignore) {
|
if (!winopt_mask[i].redir_ignore) {
|
||||||
winopt_mask[i].redir_ignore = true;
|
winopt_mask[i].redir_ignore = true;
|
||||||
ps->o.wintype_option[i].redir_ignore = false;
|
opt->wintype_option[i].redir_ignore = false;
|
||||||
}
|
}
|
||||||
if (!winopt_mask[i].opacity) {
|
if (!winopt_mask[i].opacity) {
|
||||||
winopt_mask[i].opacity = true;
|
winopt_mask[i].opacity = true;
|
||||||
// Opacity is not set to a concrete number here because the opacity logic
|
// Opacity is not set to a concrete number here because the opacity logic
|
||||||
// is complicated, and needs an "unset" state
|
// is complicated, and needs an "unset" state
|
||||||
ps->o.wintype_option[i].opacity = NAN;
|
opt->wintype_option[i].opacity = NAN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
357
src/config.h
357
src/config.h
|
@ -1,7 +1,11 @@
|
||||||
#pragma once
|
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
// Copyright (c) 2011-2013, Christopher Jeffrey
|
// Copyright (c) 2011-2013, Christopher Jeffrey
|
||||||
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
|
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
|
||||||
|
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// Common functions and definitions for configuration parsing
|
||||||
|
/// Used for command line arguments and config files
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
@ -11,25 +15,348 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
bool parse_long(const char *, long *);
|
/// VSync modes.
|
||||||
const char *parse_matrix_readnum(const char *, double *);
|
typedef enum {
|
||||||
xcb_render_fixed_t *parse_matrix(session_t *, const char *, const char **);
|
VSYNC_NONE,
|
||||||
xcb_render_fixed_t *parse_conv_kern(session_t *, const char *, const char **);
|
VSYNC_DRM,
|
||||||
bool parse_conv_kern_lst(session_t *, const char *, xcb_render_fixed_t **, int);
|
VSYNC_OPENGL,
|
||||||
bool parse_geometry(session_t *, const char *, region_t *);
|
VSYNC_OPENGL_OML,
|
||||||
bool parse_rule_opacity(session_t *, const char *);
|
VSYNC_OPENGL_SWC,
|
||||||
|
VSYNC_OPENGL_MSWC,
|
||||||
|
NUM_VSYNC,
|
||||||
|
} vsync_t;
|
||||||
|
|
||||||
|
/// @brief Possible backends of compton.
|
||||||
|
enum backend {
|
||||||
|
BKEND_XRENDER,
|
||||||
|
BKEND_GLX,
|
||||||
|
BKEND_XR_GLX_HYBRID,
|
||||||
|
NUM_BKEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct win_option_mask {
|
||||||
|
bool shadow : 1;
|
||||||
|
bool fade : 1;
|
||||||
|
bool focus : 1;
|
||||||
|
bool full_shadow : 1;
|
||||||
|
bool redir_ignore : 1;
|
||||||
|
bool opacity : 1;
|
||||||
|
} win_option_mask_t;
|
||||||
|
|
||||||
|
typedef struct win_option {
|
||||||
|
bool shadow;
|
||||||
|
bool fade;
|
||||||
|
bool focus;
|
||||||
|
bool full_shadow;
|
||||||
|
bool redir_ignore;
|
||||||
|
double opacity;
|
||||||
|
} win_option_t;
|
||||||
|
|
||||||
|
typedef struct _c2_lptr c2_lptr_t;
|
||||||
|
|
||||||
|
// This macro is here because this is the maximum number
|
||||||
|
// of blur passes options_t can hold, not a limitation of
|
||||||
|
// rendering.
|
||||||
|
/// @brief Maximum passes for blur.
|
||||||
|
#define MAX_BLUR_PASS 5
|
||||||
|
|
||||||
|
/// Structure representing all options.
|
||||||
|
typedef struct options_t {
|
||||||
|
// === Debugging ===
|
||||||
|
bool monitor_repaint;
|
||||||
|
bool print_diagnostics;
|
||||||
|
// === General ===
|
||||||
|
/// The configuration file we used.
|
||||||
|
char *config_file;
|
||||||
|
/// Path to write PID to.
|
||||||
|
char *write_pid_path;
|
||||||
|
/// The backend in use.
|
||||||
|
enum backend backend;
|
||||||
|
/// Whether to sync X drawing to avoid certain delay issues with
|
||||||
|
/// GLX backend.
|
||||||
|
bool xrender_sync;
|
||||||
|
/// Whether to sync X drawing with X Sync fence.
|
||||||
|
bool xrender_sync_fence;
|
||||||
|
/// Whether to avoid using stencil buffer under GLX backend. Might be
|
||||||
|
/// unsafe.
|
||||||
|
bool glx_no_stencil;
|
||||||
|
/// Whether to avoid rebinding pixmap on window damage.
|
||||||
|
bool glx_no_rebind_pixmap;
|
||||||
|
/// GLX swap method we assume OpenGL uses.
|
||||||
|
int glx_swap_method;
|
||||||
|
/// Whether to use GL_EXT_gpu_shader4 to (hopefully) accelerates blurring.
|
||||||
|
bool glx_use_gpushader4;
|
||||||
|
/// Custom fragment shader for painting windows, as a string.
|
||||||
|
char *glx_fshader_win_str;
|
||||||
|
/// Whether to fork to background.
|
||||||
|
bool fork_after_register;
|
||||||
|
/// Whether to detect rounded corners.
|
||||||
|
bool detect_rounded_corners;
|
||||||
|
/// Force painting of window content with blending.
|
||||||
|
bool force_win_blend;
|
||||||
|
/// Resize damage for a specific number of pixels.
|
||||||
|
int resize_damage;
|
||||||
|
/// Whether to unredirect all windows if a full-screen opaque window
|
||||||
|
/// is detected.
|
||||||
|
bool unredir_if_possible;
|
||||||
|
/// List of conditions of windows to ignore as a full-screen window
|
||||||
|
/// when determining if a window could be unredirected.
|
||||||
|
c2_lptr_t *unredir_if_possible_blacklist;
|
||||||
|
/// Delay before unredirecting screen, in milliseconds.
|
||||||
|
unsigned long unredir_if_possible_delay;
|
||||||
|
/// Forced redirection setting through D-Bus.
|
||||||
|
switch_t redirected_force;
|
||||||
|
/// Whether to stop painting. Controlled through D-Bus.
|
||||||
|
switch_t stoppaint_force;
|
||||||
|
/// Whether to re-redirect screen on root size change.
|
||||||
|
bool reredir_on_root_change;
|
||||||
|
/// Whether to reinitialize GLX on root size change.
|
||||||
|
bool glx_reinit_on_root_change;
|
||||||
|
/// Whether to enable D-Bus support.
|
||||||
|
bool dbus;
|
||||||
|
/// Path to log file.
|
||||||
|
char *logpath;
|
||||||
|
/// Number of cycles to paint in benchmark mode. 0 for disabled.
|
||||||
|
int benchmark;
|
||||||
|
/// Window to constantly repaint in benchmark mode. 0 for full-screen.
|
||||||
|
Window benchmark_wid;
|
||||||
|
/// A list of conditions of windows not to paint.
|
||||||
|
c2_lptr_t *paint_blacklist;
|
||||||
|
/// Whether to show all X errors.
|
||||||
|
bool show_all_xerrors;
|
||||||
|
/// Whether to avoid acquiring X Selection.
|
||||||
|
bool no_x_selection;
|
||||||
|
/// Window type option override.
|
||||||
|
win_option_t wintype_option[NUM_WINTYPES];
|
||||||
|
|
||||||
|
// === VSync & software optimization ===
|
||||||
|
/// User-specified refresh rate.
|
||||||
|
int refresh_rate;
|
||||||
|
/// Whether to enable refresh-rate-based software optimization.
|
||||||
|
bool sw_opti;
|
||||||
|
/// VSync method to use;
|
||||||
|
vsync_t vsync;
|
||||||
|
/// Whether to do VSync aggressively.
|
||||||
|
bool vsync_aggressive;
|
||||||
|
/// Whether to use glFinish() instead of glFlush() for (possibly) better
|
||||||
|
/// VSync yet probably higher CPU usage.
|
||||||
|
bool vsync_use_glfinish;
|
||||||
|
|
||||||
|
// === Shadow ===
|
||||||
|
/// Red, green and blue tone of the shadow.
|
||||||
|
double shadow_red, shadow_green, shadow_blue;
|
||||||
|
int shadow_radius;
|
||||||
|
int shadow_offset_x, shadow_offset_y;
|
||||||
|
double shadow_opacity;
|
||||||
|
/// argument string to shadow-exclude-reg option
|
||||||
|
char *shadow_exclude_reg_str;
|
||||||
|
/// Shadow blacklist. A linked list of conditions.
|
||||||
|
c2_lptr_t *shadow_blacklist;
|
||||||
|
/// Whether bounding-shaped window should be ignored.
|
||||||
|
bool shadow_ignore_shaped;
|
||||||
|
/// Whether to respect _COMPTON_SHADOW.
|
||||||
|
bool respect_prop_shadow;
|
||||||
|
/// Whether to crop shadow to the very Xinerama screen.
|
||||||
|
bool xinerama_shadow_crop;
|
||||||
|
|
||||||
|
// === Fading ===
|
||||||
|
/// How much to fade in in a single fading step.
|
||||||
|
opacity_t fade_in_step;
|
||||||
|
/// How much to fade out in a single fading step.
|
||||||
|
opacity_t fade_out_step;
|
||||||
|
/// Fading time delta. In milliseconds.
|
||||||
|
unsigned long fade_delta;
|
||||||
|
/// Whether to disable fading on window open/close.
|
||||||
|
bool no_fading_openclose;
|
||||||
|
/// Whether to disable fading on ARGB managed destroyed windows.
|
||||||
|
bool no_fading_destroyed_argb;
|
||||||
|
/// Fading blacklist. A linked list of conditions.
|
||||||
|
c2_lptr_t *fade_blacklist;
|
||||||
|
|
||||||
|
// === Opacity ===
|
||||||
|
/// Default opacity for inactive windows.
|
||||||
|
/// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for
|
||||||
|
/// not enabled, default.
|
||||||
|
opacity_t inactive_opacity;
|
||||||
|
/// Default opacity for inactive windows.
|
||||||
|
opacity_t active_opacity;
|
||||||
|
/// Whether inactive_opacity overrides the opacity set by window
|
||||||
|
/// attributes.
|
||||||
|
bool inactive_opacity_override;
|
||||||
|
/// Frame opacity. Relative to window opacity, also affects shadow
|
||||||
|
/// opacity.
|
||||||
|
double frame_opacity;
|
||||||
|
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
||||||
|
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
||||||
|
bool detect_client_opacity;
|
||||||
|
|
||||||
|
// === Other window processing ===
|
||||||
|
/// Whether to blur background of semi-transparent / ARGB windows.
|
||||||
|
bool blur_background;
|
||||||
|
/// Whether to blur background when the window frame is not opaque.
|
||||||
|
/// Implies blur_background.
|
||||||
|
bool blur_background_frame;
|
||||||
|
/// Whether to use fixed blur strength instead of adjusting according
|
||||||
|
/// to window opacity.
|
||||||
|
bool blur_background_fixed;
|
||||||
|
/// Background blur blacklist. A linked list of conditions.
|
||||||
|
c2_lptr_t *blur_background_blacklist;
|
||||||
|
/// Blur convolution kernel.
|
||||||
|
xcb_render_fixed_t *blur_kerns[MAX_BLUR_PASS];
|
||||||
|
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||||
|
double inactive_dim;
|
||||||
|
/// Whether to use fixed inactive dim opacity, instead of deciding
|
||||||
|
/// based on window opacity.
|
||||||
|
bool inactive_dim_fixed;
|
||||||
|
/// Conditions of windows to have inverted colors.
|
||||||
|
c2_lptr_t *invert_color_list;
|
||||||
|
/// Rules to change window opacity.
|
||||||
|
c2_lptr_t *opacity_rules;
|
||||||
|
|
||||||
|
// === Focus related ===
|
||||||
|
/// Whether to try to detect WM windows and mark them as focused.
|
||||||
|
bool mark_wmwin_focused;
|
||||||
|
/// Whether to mark override-redirect windows as focused.
|
||||||
|
bool mark_ovredir_focused;
|
||||||
|
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
||||||
|
bool use_ewmh_active_win;
|
||||||
|
/// A list of windows always to be considered focused.
|
||||||
|
c2_lptr_t *focus_blacklist;
|
||||||
|
/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
|
||||||
|
bool detect_transient;
|
||||||
|
/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
|
||||||
|
bool detect_client_leader;
|
||||||
|
|
||||||
|
// === Calculated ===
|
||||||
|
/// Whether compton needs to track focus changes.
|
||||||
|
bool track_focus;
|
||||||
|
/// Whether compton needs to track window name and class.
|
||||||
|
bool track_wdata;
|
||||||
|
/// Whether compton needs to track window leaders.
|
||||||
|
bool track_leader;
|
||||||
|
} options_t;
|
||||||
|
|
||||||
|
extern const char *const VSYNC_STRS[NUM_VSYNC + 1];
|
||||||
|
extern const char *const BACKEND_STRS[NUM_BKEND + 1];
|
||||||
|
|
||||||
|
attr_warn_unused_result bool parse_long(const char *, long *);
|
||||||
|
attr_warn_unused_result const char *parse_matrix_readnum(const char *, double *);
|
||||||
|
attr_warn_unused_result xcb_render_fixed_t *
|
||||||
|
parse_matrix(const char *, const char **, bool *hasneg);
|
||||||
|
attr_warn_unused_result xcb_render_fixed_t *
|
||||||
|
parse_conv_kern(const char *, const char **, bool *hasneg);
|
||||||
|
attr_warn_unused_result bool
|
||||||
|
parse_conv_kern_lst(const char *, xcb_render_fixed_t **, int, bool *hasneg);
|
||||||
|
attr_warn_unused_result bool parse_geometry(session_t *, const char *, region_t *);
|
||||||
|
attr_warn_unused_result bool parse_rule_opacity(c2_lptr_t **, const char *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a pattern to a condition linked list.
|
* Add a pattern to a condition linked list.
|
||||||
*/
|
*/
|
||||||
bool condlst_add(session_t *, c2_lptr_t **, const char *);
|
bool condlst_add(c2_lptr_t **, const char *);
|
||||||
|
|
||||||
#ifdef CONFIG_LIBCONFIG
|
#ifdef CONFIG_LIBCONFIG
|
||||||
void
|
/// Parse a configuration file
|
||||||
parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
/// Returns the actually config_file name used, allocated on heap
|
||||||
bool *fading_enable, win_option_mask_t *winopt_mask);
|
/// Outputs:
|
||||||
|
/// shadow_enable = whether shaodw is enabled globally
|
||||||
|
/// fading_enable = whether fading is enabled globally
|
||||||
|
/// win_option_mask = whether option overrides for specific window type is set for given
|
||||||
|
/// options
|
||||||
|
/// hasneg = whether the convolution kernel has negative values
|
||||||
|
char *
|
||||||
|
parse_config_libconfig(options_t *, const char *config_file, bool *shadow_enable,
|
||||||
|
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
/// Parse a configuration file is that is enabled, also initialize the winopt_mask with
|
||||||
parse_config(session_t *ps, bool *shadow_enable,
|
/// default values
|
||||||
bool *fading_enable, win_option_mask_t *winopt_mask);
|
/// Outputs and returns:
|
||||||
|
/// same as parse_config_libconfig
|
||||||
|
char *parse_config(options_t *, const char *config_file, bool *shadow_enable,
|
||||||
|
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a backend option argument.
|
||||||
|
*/
|
||||||
|
static inline attr_const enum backend parse_backend(const char *str) {
|
||||||
|
for (enum backend i = 0; BACKEND_STRS[i]; ++i) {
|
||||||
|
if (!strcasecmp(str, BACKEND_STRS[i])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Keep compatibility with an old revision containing a spelling mistake...
|
||||||
|
if (!strcasecmp(str, "xr_glx_hybird")) {
|
||||||
|
log_warn("backend xr_glx_hybird should be xr_glx_hybrid, the misspelt"
|
||||||
|
"version will be removed soon.");
|
||||||
|
return BKEND_XR_GLX_HYBRID;
|
||||||
|
}
|
||||||
|
// cju wants to use dashes
|
||||||
|
if (!strcasecmp(str, "xr-glx-hybrid")) {
|
||||||
|
log_warn("backend xr-glx-hybrid should be xr_glx_hybrid, the alternative"
|
||||||
|
"version will be removed soon.");
|
||||||
|
return BKEND_XR_GLX_HYBRID;
|
||||||
|
}
|
||||||
|
log_error("Invalid backend argument: %s", str);
|
||||||
|
return NUM_BKEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a glx_swap_method option argument.
|
||||||
|
*
|
||||||
|
* Returns -2 on failure
|
||||||
|
*/
|
||||||
|
static inline attr_const int parse_glx_swap_method(const char *str) {
|
||||||
|
// Parse alias
|
||||||
|
if (!strcmp("undefined", str)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp("copy", str)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp("exchange", str)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp("buffer-age", str)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse number
|
||||||
|
char *pc = NULL;
|
||||||
|
int age = strtol(str, &pc, 0);
|
||||||
|
if (!pc || str == pc) {
|
||||||
|
log_error("glx-swap-method is an invalid number: %s", str);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; *pc; ++pc)
|
||||||
|
if (!isspace(*pc)) {
|
||||||
|
log_error("Trailing characters in glx-swap-method option: %s", str);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (age < -1) {
|
||||||
|
log_error("Number for glx-swap-method is too small: %s", str);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a VSync option argument.
|
||||||
|
*/
|
||||||
|
static inline vsync_t parse_vsync(const char *str) {
|
||||||
|
for (vsync_t i = 0; VSYNC_STRS[i]; ++i)
|
||||||
|
if (!strcasecmp(str, VSYNC_STRS[i])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("Invalid vsync argument: %s", str);
|
||||||
|
return NUM_VSYNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: set noet sw=8 ts=8 :
|
||||||
|
|
|
@ -12,8 +12,11 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
#include "options.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
* Wrapper of libconfig's <code>config_lookup_int</code>.
|
||||||
*
|
*
|
||||||
|
@ -36,7 +39,7 @@ lcfg_lookup_bool(const config_t *config, const char *path, bool *value) {
|
||||||
* Follows the XDG specification to search for the configuration file.
|
* Follows the XDG specification to search for the configuration file.
|
||||||
*/
|
*/
|
||||||
FILE *
|
FILE *
|
||||||
open_config_file(char *cpath, char **ppath) {
|
open_config_file(const char *cpath, char **ppath) {
|
||||||
static const char *config_paths[] = {
|
static const char *config_paths[] = {
|
||||||
"/compton.conf",
|
"/compton.conf",
|
||||||
"/compton/compton.conf"
|
"/compton/compton.conf"
|
||||||
|
@ -46,7 +49,7 @@ open_config_file(char *cpath, char **ppath) {
|
||||||
if (cpath) {
|
if (cpath) {
|
||||||
FILE *ret = fopen(cpath, "r");
|
FILE *ret = fopen(cpath, "r");
|
||||||
if (ret && ppath)
|
if (ret && ppath)
|
||||||
*ppath = cpath;
|
*ppath = strdup(cpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +85,7 @@ open_config_file(char *cpath, char **ppath) {
|
||||||
* Parse a condition list in configuration file.
|
* Parse a condition list in configuration file.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
parse_cfg_condlst(const config_t *pcfg, c2_lptr_t **pcondlst,
|
||||||
const char *name) {
|
const char *name) {
|
||||||
config_setting_t *setting = config_lookup(pcfg, name);
|
config_setting_t *setting = config_lookup(pcfg, name);
|
||||||
if (setting) {
|
if (setting) {
|
||||||
|
@ -90,11 +93,11 @@ parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
||||||
if (config_setting_is_array(setting)) {
|
if (config_setting_is_array(setting)) {
|
||||||
int i = config_setting_length(setting);
|
int i = config_setting_length(setting);
|
||||||
while (i--)
|
while (i--)
|
||||||
condlst_add(ps, pcondlst, config_setting_get_string_elem(setting, i));
|
condlst_add(pcondlst, config_setting_get_string_elem(setting, i));
|
||||||
}
|
}
|
||||||
// Treat it as a single pattern if it's a string
|
// Treat it as a single pattern if it's a string
|
||||||
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
||||||
condlst_add(ps, pcondlst, config_setting_get_string(setting));
|
condlst_add(pcondlst, config_setting_get_string(setting));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,29 +106,32 @@ parse_cfg_condlst(session_t *ps, const config_t *pcfg, c2_lptr_t **pcondlst,
|
||||||
* Parse an opacity rule list in configuration file.
|
* Parse an opacity rule list in configuration file.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
parse_cfg_condlst_opct(session_t *ps, const config_t *pcfg, const char *name) {
|
parse_cfg_condlst_opct(options_t *opt, const config_t *pcfg, const char *name) {
|
||||||
config_setting_t *setting = config_lookup(pcfg, name);
|
config_setting_t *setting = config_lookup(pcfg, name);
|
||||||
if (setting) {
|
if (setting) {
|
||||||
// Parse an array of options
|
// Parse an array of options
|
||||||
if (config_setting_is_array(setting)) {
|
if (config_setting_is_array(setting)) {
|
||||||
int i = config_setting_length(setting);
|
int i = config_setting_length(setting);
|
||||||
while (i--)
|
while (i--)
|
||||||
if (!parse_rule_opacity(ps, config_setting_get_string_elem(setting,
|
if (!parse_rule_opacity(&opt->opacity_rules,
|
||||||
i)))
|
config_setting_get_string_elem(setting, i)))
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
// Treat it as a single pattern if it's a string
|
// Treat it as a single pattern if it's a string
|
||||||
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
else if (config_setting_type(setting) == CONFIG_TYPE_STRING) {
|
||||||
parse_rule_opacity(ps, config_setting_get_string(setting));
|
if (!parse_rule_opacity(&opt->opacity_rules, config_setting_get_string(setting)))
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a configuration file from default location.
|
* Parse a configuration file from default location.
|
||||||
|
*
|
||||||
|
* Returns the actually config_file name
|
||||||
*/
|
*/
|
||||||
void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shadow_enable,
|
||||||
bool *fading_enable, win_option_mask_t *winopt_mask)
|
bool *fading_enable, bool *conv_kern_hasneg, win_option_mask_t *winopt_mask)
|
||||||
{
|
{
|
||||||
char *path = NULL;
|
char *path = NULL;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
@ -137,16 +143,14 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
// anything
|
// anything
|
||||||
const char *sval = NULL;
|
const char *sval = NULL;
|
||||||
|
|
||||||
f = open_config_file(ps->o.config_file, &path);
|
f = open_config_file(config_file, &path);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
if (ps->o.config_file) {
|
if (config_file) {
|
||||||
free(ps->o.config_file);
|
log_fatal("Failed to read configuration file \"%s\".", config_file);
|
||||||
ps->o.config_file = NULL;
|
|
||||||
|
|
||||||
log_fatal("Failed to read configuration file \"%s\".", ps->o.config_file);
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
return;
|
free(path);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
config_init(&cfg);
|
config_init(&cfg);
|
||||||
|
@ -171,44 +175,39 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
path, config_error_line(&cfg), config_error_text(&cfg));
|
path, config_error_line(&cfg), config_error_text(&cfg));
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
free(path);
|
free(path);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config_set_auto_convert(&cfg, 1);
|
config_set_auto_convert(&cfg, 1);
|
||||||
|
|
||||||
if (path != ps->o.config_file) {
|
|
||||||
assert(ps->o.config_file == NULL);
|
|
||||||
ps->o.config_file = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get options from the configuration file. We don't do range checking
|
// Get options from the configuration file. We don't do range checking
|
||||||
// right now. It will be done later
|
// right now. It will be done later
|
||||||
|
|
||||||
// -D (fade_delta)
|
// -D (fade_delta)
|
||||||
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
if (config_lookup_int(&cfg, "fade-delta", &ival))
|
||||||
ps->o.fade_delta = ival;
|
opt->fade_delta = ival;
|
||||||
// -I (fade_in_step)
|
// -I (fade_in_step)
|
||||||
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
if (config_lookup_float(&cfg, "fade-in-step", &dval))
|
||||||
ps->o.fade_in_step = normalize_d(dval) * OPAQUE;
|
opt->fade_in_step = normalize_d(dval) * OPAQUE;
|
||||||
// -O (fade_out_step)
|
// -O (fade_out_step)
|
||||||
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
if (config_lookup_float(&cfg, "fade-out-step", &dval))
|
||||||
ps->o.fade_out_step = normalize_d(dval) * OPAQUE;
|
opt->fade_out_step = normalize_d(dval) * OPAQUE;
|
||||||
// -r (shadow_radius)
|
// -r (shadow_radius)
|
||||||
config_lookup_int(&cfg, "shadow-radius", &ps->o.shadow_radius);
|
config_lookup_int(&cfg, "shadow-radius", &opt->shadow_radius);
|
||||||
// -o (shadow_opacity)
|
// -o (shadow_opacity)
|
||||||
config_lookup_float(&cfg, "shadow-opacity", &ps->o.shadow_opacity);
|
config_lookup_float(&cfg, "shadow-opacity", &opt->shadow_opacity);
|
||||||
// -l (shadow_offset_x)
|
// -l (shadow_offset_x)
|
||||||
config_lookup_int(&cfg, "shadow-offset-x", &ps->o.shadow_offset_x);
|
config_lookup_int(&cfg, "shadow-offset-x", &opt->shadow_offset_x);
|
||||||
// -t (shadow_offset_y)
|
// -t (shadow_offset_y)
|
||||||
config_lookup_int(&cfg, "shadow-offset-y", &ps->o.shadow_offset_y);
|
config_lookup_int(&cfg, "shadow-offset-y", &opt->shadow_offset_y);
|
||||||
// -i (inactive_opacity)
|
// -i (inactive_opacity)
|
||||||
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
if (config_lookup_float(&cfg, "inactive-opacity", &dval))
|
||||||
ps->o.inactive_opacity = normalize_d(dval) * OPAQUE;
|
opt->inactive_opacity = normalize_d(dval) * OPAQUE;
|
||||||
// --active_opacity
|
// --active_opacity
|
||||||
if (config_lookup_float(&cfg, "active-opacity", &dval))
|
if (config_lookup_float(&cfg, "active-opacity", &dval))
|
||||||
ps->o.active_opacity = normalize_d(dval) * OPAQUE;
|
opt->active_opacity = normalize_d(dval) * OPAQUE;
|
||||||
// -e (frame_opacity)
|
// -e (frame_opacity)
|
||||||
config_lookup_float(&cfg, "frame-opacity", &ps->o.frame_opacity);
|
config_lookup_float(&cfg, "frame-opacity", &opt->frame_opacity);
|
||||||
// -c (shadow_enable)
|
// -c (shadow_enable)
|
||||||
if (config_lookup_bool(&cfg, "shadow", &ival))
|
if (config_lookup_bool(&cfg, "shadow", &ival))
|
||||||
*shadow_enable = ival;
|
*shadow_enable = ival;
|
||||||
|
@ -216,22 +215,22 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
if (config_lookup_bool(&cfg, "no-dock-shadow", &ival)) {
|
if (config_lookup_bool(&cfg, "no-dock-shadow", &ival)) {
|
||||||
log_warn("Option `no-dock-shadow` is deprecated, and will be removed."
|
log_warn("Option `no-dock-shadow` is deprecated, and will be removed."
|
||||||
" Please use the wintype option `shadow` of `dock` instead.");
|
" Please use the wintype option `shadow` of `dock` instead.");
|
||||||
ps->o.wintype_option[WINTYPE_DOCK].shadow = false;
|
opt->wintype_option[WINTYPE_DOCK].shadow = false;
|
||||||
winopt_mask[WINTYPE_DOCK].shadow = true;
|
winopt_mask[WINTYPE_DOCK].shadow = true;
|
||||||
}
|
}
|
||||||
// -G (no_dnd_shadow)
|
// -G (no_dnd_shadow)
|
||||||
if (config_lookup_bool(&cfg, "no-dnd-shadow", &ival)) {
|
if (config_lookup_bool(&cfg, "no-dnd-shadow", &ival)) {
|
||||||
log_warn("Option `no-dnd-shadow` is deprecated, and will be removed."
|
log_warn("Option `no-dnd-shadow` is deprecated, and will be removed."
|
||||||
" Please use the wintype option `shadow` of `dnd` instead.");
|
" Please use the wintype option `shadow` of `dnd` instead.");
|
||||||
ps->o.wintype_option[WINTYPE_DND].shadow = false;
|
opt->wintype_option[WINTYPE_DND].shadow = false;
|
||||||
winopt_mask[WINTYPE_DND].shadow = true;
|
winopt_mask[WINTYPE_DND].shadow = true;
|
||||||
};
|
};
|
||||||
// -m (menu_opacity)
|
// -m (menu_opacity)
|
||||||
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
if (config_lookup_float(&cfg, "menu-opacity", &dval)) {
|
||||||
log_warn("Option `menu-opacity` is deprecated, and will be removed.Please use the "
|
log_warn("Option `menu-opacity` is deprecated, and will be removed.Please use the "
|
||||||
"wintype option `opacity` of `popup_menu` and `dropdown_menu` instead.");
|
"wintype option `opacity` of `popup_menu` and `dropdown_menu` instead.");
|
||||||
ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = dval;
|
opt->wintype_option[WINTYPE_DROPDOWN_MENU].opacity = dval;
|
||||||
ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = dval;
|
opt->wintype_option[WINTYPE_POPUP_MENU].opacity = dval;
|
||||||
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
||||||
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
||||||
}
|
}
|
||||||
|
@ -239,53 +238,59 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
if (config_lookup_bool(&cfg, "fading", &ival))
|
if (config_lookup_bool(&cfg, "fading", &ival))
|
||||||
*fading_enable = ival;
|
*fading_enable = ival;
|
||||||
// --no-fading-open-close
|
// --no-fading-open-close
|
||||||
lcfg_lookup_bool(&cfg, "no-fading-openclose", &ps->o.no_fading_openclose);
|
lcfg_lookup_bool(&cfg, "no-fading-openclose", &opt->no_fading_openclose);
|
||||||
// --no-fading-destroyed-argb
|
// --no-fading-destroyed-argb
|
||||||
lcfg_lookup_bool(&cfg, "no-fading-destroyed-argb",
|
lcfg_lookup_bool(&cfg, "no-fading-destroyed-argb",
|
||||||
&ps->o.no_fading_destroyed_argb);
|
&opt->no_fading_destroyed_argb);
|
||||||
// --shadow-red
|
// --shadow-red
|
||||||
config_lookup_float(&cfg, "shadow-red", &ps->o.shadow_red);
|
config_lookup_float(&cfg, "shadow-red", &opt->shadow_red);
|
||||||
// --shadow-green
|
// --shadow-green
|
||||||
config_lookup_float(&cfg, "shadow-green", &ps->o.shadow_green);
|
config_lookup_float(&cfg, "shadow-green", &opt->shadow_green);
|
||||||
// --shadow-blue
|
// --shadow-blue
|
||||||
config_lookup_float(&cfg, "shadow-blue", &ps->o.shadow_blue);
|
config_lookup_float(&cfg, "shadow-blue", &opt->shadow_blue);
|
||||||
// --shadow-exclude-reg
|
// --shadow-exclude-reg
|
||||||
if (config_lookup_string(&cfg, "shadow-exclude-reg", &sval))
|
if (config_lookup_string(&cfg, "shadow-exclude-reg", &sval))
|
||||||
ps->o.shadow_exclude_reg_str = strdup(sval);
|
opt->shadow_exclude_reg_str = strdup(sval);
|
||||||
// --inactive-opacity-override
|
// --inactive-opacity-override
|
||||||
lcfg_lookup_bool(&cfg, "inactive-opacity-override",
|
lcfg_lookup_bool(&cfg, "inactive-opacity-override",
|
||||||
&ps->o.inactive_opacity_override);
|
&opt->inactive_opacity_override);
|
||||||
// --inactive-dim
|
// --inactive-dim
|
||||||
config_lookup_float(&cfg, "inactive-dim", &ps->o.inactive_dim);
|
config_lookup_float(&cfg, "inactive-dim", &opt->inactive_dim);
|
||||||
// --mark-wmwin-focused
|
// --mark-wmwin-focused
|
||||||
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &ps->o.mark_wmwin_focused);
|
lcfg_lookup_bool(&cfg, "mark-wmwin-focused", &opt->mark_wmwin_focused);
|
||||||
// --mark-ovredir-focused
|
// --mark-ovredir-focused
|
||||||
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
lcfg_lookup_bool(&cfg, "mark-ovredir-focused",
|
||||||
&ps->o.mark_ovredir_focused);
|
&opt->mark_ovredir_focused);
|
||||||
// --shadow-ignore-shaped
|
// --shadow-ignore-shaped
|
||||||
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped",
|
||||||
&ps->o.shadow_ignore_shaped);
|
&opt->shadow_ignore_shaped);
|
||||||
// --detect-rounded-corners
|
// --detect-rounded-corners
|
||||||
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
lcfg_lookup_bool(&cfg, "detect-rounded-corners",
|
||||||
&ps->o.detect_rounded_corners);
|
&opt->detect_rounded_corners);
|
||||||
// --xinerama-shadow-crop
|
// --xinerama-shadow-crop
|
||||||
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop",
|
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop",
|
||||||
&ps->o.xinerama_shadow_crop);
|
&opt->xinerama_shadow_crop);
|
||||||
// --detect-client-opacity
|
// --detect-client-opacity
|
||||||
lcfg_lookup_bool(&cfg, "detect-client-opacity",
|
lcfg_lookup_bool(&cfg, "detect-client-opacity",
|
||||||
&ps->o.detect_client_opacity);
|
&opt->detect_client_opacity);
|
||||||
// --refresh-rate
|
// --refresh-rate
|
||||||
config_lookup_int(&cfg, "refresh-rate", &ps->o.refresh_rate);
|
config_lookup_int(&cfg, "refresh-rate", &opt->refresh_rate);
|
||||||
// --vsync
|
// --vsync
|
||||||
if (config_lookup_string(&cfg, "vsync", &sval) && !parse_vsync(ps, sval)) {
|
if (config_lookup_string(&cfg, "vsync", &sval)) {
|
||||||
|
opt->vsync = parse_vsync(sval);
|
||||||
|
if (opt->vsync >= NUM_VSYNC) {
|
||||||
log_fatal("Cannot parse vsync");
|
log_fatal("Cannot parse vsync");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// --backend
|
// --backend
|
||||||
if (config_lookup_string(&cfg, "backend", &sval) && !parse_backend(ps, sval)) {
|
if (config_lookup_string(&cfg, "backend", &sval)) {
|
||||||
|
opt->backend = parse_backend(sval);
|
||||||
|
if (opt->backend >= NUM_BKEND) {
|
||||||
log_fatal("Cannot parse backend");
|
log_fatal("Cannot parse backend");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// --log-level
|
// --log-level
|
||||||
if (config_lookup_string(&cfg, "log-level", &sval)) {
|
if (config_lookup_string(&cfg, "log-level", &sval)) {
|
||||||
auto level = string_to_log_level(sval);
|
auto level = string_to_log_level(sval);
|
||||||
|
@ -296,69 +301,71 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --sw-opti
|
// --sw-opti
|
||||||
lcfg_lookup_bool(&cfg, "sw-opti", &ps->o.sw_opti);
|
lcfg_lookup_bool(&cfg, "sw-opti", &opt->sw_opti);
|
||||||
// --use-ewmh-active-win
|
// --use-ewmh-active-win
|
||||||
lcfg_lookup_bool(&cfg, "use-ewmh-active-win",
|
lcfg_lookup_bool(&cfg, "use-ewmh-active-win",
|
||||||
&ps->o.use_ewmh_active_win);
|
&opt->use_ewmh_active_win);
|
||||||
// --unredir-if-possible
|
// --unredir-if-possible
|
||||||
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
||||||
&ps->o.unredir_if_possible);
|
&opt->unredir_if_possible);
|
||||||
// --unredir-if-possible-delay
|
// --unredir-if-possible-delay
|
||||||
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival))
|
if (config_lookup_int(&cfg, "unredir-if-possible-delay", &ival))
|
||||||
ps->o.unredir_if_possible_delay = ival;
|
opt->unredir_if_possible_delay = ival;
|
||||||
// --inactive-dim-fixed
|
// --inactive-dim-fixed
|
||||||
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &ps->o.inactive_dim_fixed);
|
lcfg_lookup_bool(&cfg, "inactive-dim-fixed", &opt->inactive_dim_fixed);
|
||||||
// --detect-transient
|
// --detect-transient
|
||||||
lcfg_lookup_bool(&cfg, "detect-transient", &ps->o.detect_transient);
|
lcfg_lookup_bool(&cfg, "detect-transient", &opt->detect_transient);
|
||||||
// --detect-client-leader
|
// --detect-client-leader
|
||||||
lcfg_lookup_bool(&cfg, "detect-client-leader",
|
lcfg_lookup_bool(&cfg, "detect-client-leader",
|
||||||
&ps->o.detect_client_leader);
|
&opt->detect_client_leader);
|
||||||
// --shadow-exclude
|
// --shadow-exclude
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
parse_cfg_condlst(&cfg, &opt->shadow_blacklist, "shadow-exclude");
|
||||||
// --fade-exclude
|
// --fade-exclude
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.fade_blacklist, "fade-exclude");
|
parse_cfg_condlst(&cfg, &opt->fade_blacklist, "fade-exclude");
|
||||||
// --focus-exclude
|
// --focus-exclude
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.focus_blacklist, "focus-exclude");
|
parse_cfg_condlst(&cfg, &opt->focus_blacklist, "focus-exclude");
|
||||||
// --invert-color-include
|
// --invert-color-include
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.invert_color_list, "invert-color-include");
|
parse_cfg_condlst(&cfg, &opt->invert_color_list, "invert-color-include");
|
||||||
// --blur-background-exclude
|
// --blur-background-exclude
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.blur_background_blacklist, "blur-background-exclude");
|
parse_cfg_condlst(&cfg, &opt->blur_background_blacklist, "blur-background-exclude");
|
||||||
// --opacity-rule
|
// --opacity-rule
|
||||||
parse_cfg_condlst_opct(ps, &cfg, "opacity-rule");
|
parse_cfg_condlst_opct(opt, &cfg, "opacity-rule");
|
||||||
// --unredir-if-possible-exclude
|
// --unredir-if-possible-exclude
|
||||||
parse_cfg_condlst(ps, &cfg, &ps->o.unredir_if_possible_blacklist, "unredir-if-possible-exclude");
|
parse_cfg_condlst(&cfg, &opt->unredir_if_possible_blacklist, "unredir-if-possible-exclude");
|
||||||
// --blur-background
|
// --blur-background
|
||||||
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
|
lcfg_lookup_bool(&cfg, "blur-background", &opt->blur_background);
|
||||||
// --blur-background-frame
|
// --blur-background-frame
|
||||||
lcfg_lookup_bool(&cfg, "blur-background-frame",
|
lcfg_lookup_bool(&cfg, "blur-background-frame",
|
||||||
&ps->o.blur_background_frame);
|
&opt->blur_background_frame);
|
||||||
// --blur-background-fixed
|
// --blur-background-fixed
|
||||||
lcfg_lookup_bool(&cfg, "blur-background-fixed",
|
lcfg_lookup_bool(&cfg, "blur-background-fixed",
|
||||||
&ps->o.blur_background_fixed);
|
&opt->blur_background_fixed);
|
||||||
// --blur-kern
|
// --blur-kern
|
||||||
if (config_lookup_string(&cfg, "blur-kern", &sval)
|
if (config_lookup_string(&cfg, "blur-kern", &sval) &&
|
||||||
&& !parse_conv_kern_lst(ps, sval, ps->o.blur_kerns, MAX_BLUR_PASS)) {
|
!parse_conv_kern_lst(sval, opt->blur_kerns, MAX_BLUR_PASS, conv_kern_hasneg)) {
|
||||||
log_fatal("Cannot parse \"blur-kern\"");
|
log_fatal("Cannot parse \"blur-kern\"");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
// --resize-damage
|
// --resize-damage
|
||||||
config_lookup_int(&cfg, "resize-damage", &ps->o.resize_damage);
|
config_lookup_int(&cfg, "resize-damage", &opt->resize_damage);
|
||||||
// --glx-no-stencil
|
// --glx-no-stencil
|
||||||
lcfg_lookup_bool(&cfg, "glx-no-stencil", &ps->o.glx_no_stencil);
|
lcfg_lookup_bool(&cfg, "glx-no-stencil", &opt->glx_no_stencil);
|
||||||
// --glx-no-rebind-pixmap
|
// --glx-no-rebind-pixmap
|
||||||
lcfg_lookup_bool(&cfg, "glx-no-rebind-pixmap", &ps->o.glx_no_rebind_pixmap);
|
lcfg_lookup_bool(&cfg, "glx-no-rebind-pixmap", &opt->glx_no_rebind_pixmap);
|
||||||
// --glx-swap-method
|
// --glx-swap-method
|
||||||
if (config_lookup_string(&cfg, "glx-swap-method", &sval) &&
|
if (config_lookup_string(&cfg, "glx-swap-method", &sval)) {
|
||||||
!parse_glx_swap_method(ps, sval)) {
|
opt->glx_swap_method = parse_glx_swap_method(sval);
|
||||||
|
if (opt->glx_swap_method == -2) {
|
||||||
log_fatal("Cannot parse \"glx-swap-method\"");
|
log_fatal("Cannot parse \"glx-swap-method\"");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// --glx-use-gpushader4
|
// --glx-use-gpushader4
|
||||||
lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &ps->o.glx_use_gpushader4);
|
lcfg_lookup_bool(&cfg, "glx-use-gpushader4", &opt->glx_use_gpushader4);
|
||||||
// --xrender-sync
|
// --xrender-sync
|
||||||
lcfg_lookup_bool(&cfg, "xrender-sync", &ps->o.xrender_sync);
|
lcfg_lookup_bool(&cfg, "xrender-sync", &opt->xrender_sync);
|
||||||
// --xrender-sync-fence
|
// --xrender-sync-fence
|
||||||
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &ps->o.xrender_sync_fence);
|
lcfg_lookup_bool(&cfg, "xrender-sync-fence", &opt->xrender_sync_fence);
|
||||||
|
|
||||||
if (lcfg_lookup_bool(&cfg, "clear-shadow", &bval))
|
if (lcfg_lookup_bool(&cfg, "clear-shadow", &bval))
|
||||||
log_warn("\"clear-shadow\" is removed as an option, and is always"
|
log_warn("\"clear-shadow\" is removed as an option, and is always"
|
||||||
|
@ -386,7 +393,7 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
config_setting_t *setting = config_lookup(&cfg, str);
|
config_setting_t *setting = config_lookup(&cfg, str);
|
||||||
free(str);
|
free(str);
|
||||||
|
|
||||||
win_option_t *o = &ps->o.wintype_option[i];
|
win_option_t *o = &opt->wintype_option[i];
|
||||||
win_option_mask_t *mask = &winopt_mask[i];
|
win_option_mask_t *mask = &winopt_mask[i];
|
||||||
if (setting) {
|
if (setting) {
|
||||||
if (config_setting_lookup_bool(setting, "shadow", &ival)) {
|
if (config_setting_lookup_bool(setting, "shadow", &ival)) {
|
||||||
|
@ -419,4 +426,5 @@ void parse_config_libconfig(session_t *ps, bool *shadow_enable,
|
||||||
}
|
}
|
||||||
|
|
||||||
config_destroy(&cfg);
|
config_destroy(&cfg);
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
26
src/dbus.c
26
src/dbus.c
|
@ -1183,15 +1183,27 @@ cdbus_process_opts_set(session_t *ps, DBusMessage *msg) {
|
||||||
if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_STRING, &val))
|
if (!cdbus_msg_get_arg(msg, 1, DBUS_TYPE_STRING, &val))
|
||||||
return false;
|
return false;
|
||||||
vsync_deinit(ps);
|
vsync_deinit(ps);
|
||||||
if (!parse_vsync(ps, val)) {
|
auto tmp_vsync = parse_vsync(val);
|
||||||
log_error(CDBUS_ERROR_BADARG_S, 1, "Value invalid.");
|
if (tmp_vsync >= NUM_VSYNC) {
|
||||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADARG, CDBUS_ERROR_BADARG_S, 1, "Value invalid.");
|
log_error("Failed to parse vsync: invalid value %s.", val);
|
||||||
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_BADARG, CDBUS_ERROR_BADARG_S, 1,
|
||||||
|
"Value invalid.");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (!vsync_init(ps)) {
|
|
||||||
log_error(CDBUS_ERROR_CUSTOM_S, "Failed to initialize specified VSync method.");
|
auto old_vsync = ps->o.vsync;
|
||||||
cdbus_reply_err(ps, msg, CDBUS_ERROR_CUSTOM, CDBUS_ERROR_CUSTOM_S, "Failed to initialize specified VSync method.");
|
ps->o.vsync = tmp_vsync;
|
||||||
|
if (!vsync_init(ps)) {
|
||||||
|
// Trying to revert back to original vsync values
|
||||||
|
log_error("Failed to initialize specified VSync method.");
|
||||||
|
ps->o.vsync = old_vsync;
|
||||||
|
if (!vsync_init(ps)) {
|
||||||
|
log_error("Failed to revert back to original VSync method.");
|
||||||
|
ps->o.vsync = VSYNC_NONE;
|
||||||
}
|
}
|
||||||
else
|
cdbus_reply_err(ps, msg, CDBUS_ERROR_CUSTOM, CDBUS_ERROR_CUSTOM_S,
|
||||||
|
"Failed to initialize specified VSync method.");
|
||||||
|
} else
|
||||||
goto cdbus_process_opts_set_success;
|
goto cdbus_process_opts_set_success;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,11 @@ glx_init(session_t *ps, bool need_render) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps->o.glx_swap_method > CGLX_MAX_BUFFER_AGE) {
|
||||||
|
log_error("glx-swap-method is too big");
|
||||||
|
goto glx_init_end;
|
||||||
|
}
|
||||||
|
|
||||||
// Get XVisualInfo
|
// Get XVisualInfo
|
||||||
pvis = get_visualinfo_from_visual(ps, ps->vis);
|
pvis = get_visualinfo_from_visual(ps, ps->vis);
|
||||||
if (!pvis) {
|
if (!pvis) {
|
||||||
|
@ -436,7 +441,7 @@ glx_destroy(session_t *ps) {
|
||||||
glDeleteProgram(ppass->prog);
|
glDeleteProgram(ppass->prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_free_prog_main(ps, &ps->o.glx_prog_win);
|
glx_free_prog_main(ps, &ps->glx_prog_win);
|
||||||
|
|
||||||
glx_check_err(ps);
|
glx_check_err(ps);
|
||||||
|
|
||||||
|
|
143
src/options.c
143
src/options.c
|
@ -6,9 +6,11 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "options.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#pragma GCC diagnostic error "-Wunused-parameter"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print usage text and exit.
|
* Print usage text and exit.
|
||||||
|
@ -502,21 +504,18 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all
|
||||||
/**
|
/**
|
||||||
* Process arguments and configuration files.
|
* Process arguments and configuration files.
|
||||||
*/
|
*/
|
||||||
void get_cfg(session_t *ps, int argc, char *const *argv) {
|
void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
|
bool fading_enable, bool conv_kern_hasneg,
|
||||||
|
win_option_mask_t *winopt_mask) {
|
||||||
|
|
||||||
int o = 0, longopt_idx = -1;
|
int o = 0, longopt_idx = -1;
|
||||||
|
|
||||||
bool shadow_enable = false, fading_enable = false;
|
|
||||||
char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL));
|
char *lc_numeric_old = strdup(setlocale(LC_NUMERIC, NULL));
|
||||||
|
|
||||||
win_option_mask_t winopt_mask[NUM_WINTYPES] = {{0}};
|
|
||||||
|
|
||||||
// Enforce LC_NUMERIC locale "C" here to make sure dots are recognized
|
// Enforce LC_NUMERIC locale "C" here to make sure dots are recognized
|
||||||
// instead of commas in atof().
|
// instead of commas in atof().
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
parse_config(ps, &shadow_enable, &fading_enable, winopt_mask);
|
|
||||||
|
|
||||||
// Parse commandline arguments. Range checking will be done later.
|
// Parse commandline arguments. Range checking will be done later.
|
||||||
|
|
||||||
const char *deprecation_message = "has been removed. If you encounter problems "
|
const char *deprecation_message = "has been removed. If you encounter problems "
|
||||||
|
@ -528,40 +527,42 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
switch (o) {
|
switch (o) {
|
||||||
#define P_CASEBOOL(idx, option) \
|
#define P_CASEBOOL(idx, option) \
|
||||||
case idx: \
|
case idx: \
|
||||||
ps->o.option = true; \
|
opt->option = true; \
|
||||||
break
|
break
|
||||||
#define P_CASELONG(idx, option) \
|
#define P_CASELONG(idx, option) \
|
||||||
case idx: \
|
case idx: \
|
||||||
if (!parse_long(optarg, &val)) \
|
if (!parse_long(optarg, &val)) \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
ps->o.option = val; \
|
opt->option = val; \
|
||||||
break
|
break
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
// Short options
|
// Short options
|
||||||
case 'h': usage(0); break;
|
case 'h': usage(0); break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'S':
|
case 'S':
|
||||||
case 314:
|
case 314:
|
||||||
case 318:
|
case 318:
|
||||||
case 320: break; P_CASELONG('D', fade_delta);
|
case 320: break;
|
||||||
case 'I': ps->o.fade_in_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
P_CASELONG('D', fade_delta);
|
||||||
case 'O': ps->o.fade_out_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
case 'I': opt->fade_in_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||||
|
case 'O': opt->fade_out_step = normalize_d(atof(optarg)) * OPAQUE; break;
|
||||||
case 'c': shadow_enable = true; break;
|
case 'c': shadow_enable = true; break;
|
||||||
case 'C':
|
case 'C':
|
||||||
winopt_mask[WINTYPE_DOCK].shadow = true;
|
winopt_mask[WINTYPE_DOCK].shadow = true;
|
||||||
ps->o.wintype_option[WINTYPE_DOCK].shadow = true;
|
opt->wintype_option[WINTYPE_DOCK].shadow = true;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
winopt_mask[WINTYPE_DND].shadow = true;
|
winopt_mask[WINTYPE_DND].shadow = true;
|
||||||
ps->o.wintype_option[WINTYPE_DND].shadow = true;
|
opt->wintype_option[WINTYPE_DND].shadow = true;
|
||||||
break;
|
break;
|
||||||
case 'm':;
|
case 'm':;
|
||||||
double tmp;
|
double tmp;
|
||||||
tmp = normalize_d(atof(optarg));
|
tmp = normalize_d(atof(optarg));
|
||||||
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
winopt_mask[WINTYPE_DROPDOWN_MENU].opacity = true;
|
||||||
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
winopt_mask[WINTYPE_POPUP_MENU].opacity = true;
|
||||||
ps->o.wintype_option[WINTYPE_POPUP_MENU].opacity = tmp;
|
opt->wintype_option[WINTYPE_POPUP_MENU].opacity = tmp;
|
||||||
ps->o.wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp;
|
opt->wintype_option[WINTYPE_DROPDOWN_MENU].opacity = tmp;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'F':
|
case 'F':
|
||||||
|
@ -569,14 +570,14 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
break;
|
break;
|
||||||
P_CASELONG('r', shadow_radius);
|
P_CASELONG('r', shadow_radius);
|
||||||
case 'o':
|
case 'o':
|
||||||
ps->o.shadow_opacity = atof(optarg);
|
opt->shadow_opacity = atof(optarg);
|
||||||
break;
|
break;
|
||||||
P_CASELONG('l', shadow_offset_x);
|
P_CASELONG('l', shadow_offset_x);
|
||||||
P_CASELONG('t', shadow_offset_y);
|
P_CASELONG('t', shadow_offset_y);
|
||||||
case 'i':
|
case 'i':
|
||||||
ps->o.inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
opt->inactive_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||||
break;
|
break;
|
||||||
case 'e': ps->o.frame_opacity = atof(optarg); break;
|
case 'e': opt->frame_opacity = atof(optarg); break;
|
||||||
case 'z':
|
case 'z':
|
||||||
log_warn("clear-shadow is removed, shadows are automatically "
|
log_warn("clear-shadow is removed, shadows are automatically "
|
||||||
"cleared now. If you want to prevent shadow from been "
|
"cleared now. If you want to prevent shadow from been "
|
||||||
|
@ -595,25 +596,25 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
break;
|
break;
|
||||||
case 257:
|
case 257:
|
||||||
// --shadow-red
|
// --shadow-red
|
||||||
ps->o.shadow_red = atof(optarg);
|
opt->shadow_red = atof(optarg);
|
||||||
break;
|
break;
|
||||||
case 258:
|
case 258:
|
||||||
// --shadow-green
|
// --shadow-green
|
||||||
ps->o.shadow_green = atof(optarg);
|
opt->shadow_green = atof(optarg);
|
||||||
break;
|
break;
|
||||||
case 259:
|
case 259:
|
||||||
// --shadow-blue
|
// --shadow-blue
|
||||||
ps->o.shadow_blue = atof(optarg);
|
opt->shadow_blue = atof(optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(260, inactive_opacity_override);
|
P_CASEBOOL(260, inactive_opacity_override);
|
||||||
case 261:
|
case 261:
|
||||||
// --inactive-dim
|
// --inactive-dim
|
||||||
ps->o.inactive_dim = atof(optarg);
|
opt->inactive_dim = atof(optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(262, mark_wmwin_focused);
|
P_CASEBOOL(262, mark_wmwin_focused);
|
||||||
case 263:
|
case 263:
|
||||||
// --shadow-exclude
|
// --shadow-exclude
|
||||||
condlst_add(ps, &ps->o.shadow_blacklist, optarg);
|
condlst_add(&opt->shadow_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(264, mark_ovredir_focused);
|
P_CASEBOOL(264, mark_ovredir_focused);
|
||||||
P_CASEBOOL(265, no_fading_openclose);
|
P_CASEBOOL(265, no_fading_openclose);
|
||||||
|
@ -623,7 +624,8 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASELONG(269, refresh_rate);
|
P_CASELONG(269, refresh_rate);
|
||||||
case 270:
|
case 270:
|
||||||
// --vsync
|
// --vsync
|
||||||
if (!parse_vsync(ps, optarg))
|
opt->vsync = parse_vsync(optarg);
|
||||||
|
if (opt->vsync >= NUM_VSYNC)
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case 271:
|
case 271:
|
||||||
|
@ -643,7 +645,7 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASEBOOL(278, unredir_if_possible);
|
P_CASEBOOL(278, unredir_if_possible);
|
||||||
case 279:
|
case 279:
|
||||||
// --focus-exclude
|
// --focus-exclude
|
||||||
condlst_add(ps, &ps->o.focus_blacklist, optarg);
|
condlst_add(&opt->focus_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(280, inactive_dim_fixed);
|
P_CASEBOOL(280, inactive_dim_fixed);
|
||||||
P_CASEBOOL(281, detect_transient);
|
P_CASEBOOL(281, detect_transient);
|
||||||
|
@ -654,19 +656,20 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASEBOOL(286, dbus);
|
P_CASEBOOL(286, dbus);
|
||||||
case 287:
|
case 287:
|
||||||
// --logpath
|
// --logpath
|
||||||
ps->o.logpath = strdup(optarg);
|
opt->logpath = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 288:
|
case 288:
|
||||||
// --invert-color-include
|
// --invert-color-include
|
||||||
condlst_add(ps, &ps->o.invert_color_list, optarg);
|
condlst_add(&opt->invert_color_list, optarg);
|
||||||
break;
|
break;
|
||||||
case 289:
|
case 289:
|
||||||
// --opengl
|
// --opengl
|
||||||
ps->o.backend = BKEND_GLX;
|
opt->backend = BKEND_GLX;
|
||||||
break;
|
break;
|
||||||
case 290:
|
case 290:
|
||||||
// --backend
|
// --backend
|
||||||
if (!parse_backend(ps, optarg))
|
opt->backend = parse_backend(optarg);
|
||||||
|
if (opt->backend >= NUM_BKEND)
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(291, glx_no_stencil);
|
P_CASEBOOL(291, glx_no_stencil);
|
||||||
|
@ -676,61 +679,62 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASELONG(293, benchmark);
|
P_CASELONG(293, benchmark);
|
||||||
case 294:
|
case 294:
|
||||||
// --benchmark-wid
|
// --benchmark-wid
|
||||||
ps->o.benchmark_wid = strtol(optarg, NULL, 0);
|
opt->benchmark_wid = strtol(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 295:
|
case 295:
|
||||||
log_warn("--glx-use-copysubbuffermesa %s", deprecation_message);
|
log_warn("--glx-use-copysubbuffermesa %s", deprecation_message);
|
||||||
break;
|
break;
|
||||||
case 296:
|
case 296:
|
||||||
// --blur-background-exclude
|
// --blur-background-exclude
|
||||||
condlst_add(ps, &ps->o.blur_background_blacklist, optarg);
|
condlst_add(&opt->blur_background_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
case 297:
|
case 297:
|
||||||
// --active-opacity
|
// --active-opacity
|
||||||
ps->o.active_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
opt->active_opacity = (normalize_d(atof(optarg)) * OPAQUE);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(298, glx_no_rebind_pixmap);
|
P_CASEBOOL(298, glx_no_rebind_pixmap);
|
||||||
case 299:
|
case 299:
|
||||||
// --glx-swap-method
|
// --glx-swap-method
|
||||||
if (!parse_glx_swap_method(ps, optarg))
|
opt->glx_swap_method = parse_glx_swap_method(optarg);
|
||||||
|
if (opt->glx_swap_method == -2)
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case 300:
|
case 300:
|
||||||
// --fade-exclude
|
// --fade-exclude
|
||||||
condlst_add(ps, &ps->o.fade_blacklist, optarg);
|
condlst_add(&opt->fade_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
case 301:
|
case 301:
|
||||||
// --blur-kern
|
// --blur-kern
|
||||||
if (!parse_conv_kern_lst(ps, optarg, ps->o.blur_kerns,
|
if (!parse_conv_kern_lst(optarg, opt->blur_kerns,
|
||||||
MAX_BLUR_PASS))
|
MAX_BLUR_PASS, &conv_kern_hasneg))
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
P_CASELONG(302, resize_damage);
|
P_CASELONG(302, resize_damage);
|
||||||
P_CASEBOOL(303, glx_use_gpushader4);
|
P_CASEBOOL(303, glx_use_gpushader4);
|
||||||
case 304:
|
case 304:
|
||||||
// --opacity-rule
|
// --opacity-rule
|
||||||
if (!parse_rule_opacity(ps, optarg))
|
if (!parse_rule_opacity(&opt->opacity_rules, optarg))
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case 305:
|
case 305:
|
||||||
// --shadow-exclude-reg
|
// --shadow-exclude-reg
|
||||||
ps->o.shadow_exclude_reg_str = strdup(optarg);
|
opt->shadow_exclude_reg_str = strdup(optarg);
|
||||||
log_warn("--shadow-exclude-reg is deprecated. You are likely "
|
log_warn("--shadow-exclude-reg is deprecated. You are likely "
|
||||||
"better off using --shadow-exclude anyway");
|
"better off using --shadow-exclude anyway");
|
||||||
break;
|
break;
|
||||||
case 306:
|
case 306:
|
||||||
// --paint-exclude
|
// --paint-exclude
|
||||||
condlst_add(ps, &ps->o.paint_blacklist, optarg);
|
condlst_add(&opt->paint_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(307, xinerama_shadow_crop);
|
P_CASEBOOL(307, xinerama_shadow_crop);
|
||||||
case 308:
|
case 308:
|
||||||
// --unredir-if-possible-exclude
|
// --unredir-if-possible-exclude
|
||||||
condlst_add(ps, &ps->o.unredir_if_possible_blacklist, optarg);
|
condlst_add(&opt->unredir_if_possible_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
P_CASELONG(309, unredir_if_possible_delay);
|
P_CASELONG(309, unredir_if_possible_delay);
|
||||||
case 310:
|
case 310:
|
||||||
// --write-pid-path
|
// --write-pid-path
|
||||||
ps->o.write_pid_path = strdup(optarg);
|
opt->write_pid_path = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(311, vsync_use_glfinish);
|
P_CASEBOOL(311, vsync_use_glfinish);
|
||||||
P_CASEBOOL(312, xrender_sync);
|
P_CASEBOOL(312, xrender_sync);
|
||||||
|
@ -738,7 +742,7 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASEBOOL(315, no_fading_destroyed_argb);
|
P_CASEBOOL(315, no_fading_destroyed_argb);
|
||||||
P_CASEBOOL(316, force_win_blend);
|
P_CASEBOOL(316, force_win_blend);
|
||||||
case 317:
|
case 317:
|
||||||
ps->o.glx_fshader_win_str = strdup(optarg);
|
opt->glx_fshader_win_str = strdup(optarg);
|
||||||
log_warn("--glx-fshader-win is being deprecated, and might be "
|
log_warn("--glx-fshader-win is being deprecated, and might be "
|
||||||
"removed in the future. If you really need this "
|
"removed in the future. If you really need this "
|
||||||
"feature, please report an issue to let us know");
|
"feature, please report an issue to let us know");
|
||||||
|
@ -756,34 +760,35 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
P_CASEBOOL(731, reredir_on_root_change);
|
P_CASEBOOL(731, reredir_on_root_change);
|
||||||
P_CASEBOOL(732, glx_reinit_on_root_change);
|
P_CASEBOOL(732, glx_reinit_on_root_change);
|
||||||
P_CASEBOOL(800, monitor_repaint);
|
P_CASEBOOL(800, monitor_repaint);
|
||||||
case 801: ps->o.print_diagnostics = true; break;
|
case 801: opt->print_diagnostics = true; break;
|
||||||
default: usage(1); break;
|
default: usage(1); break;
|
||||||
#undef P_CASEBOOL
|
#undef P_CASEBOOL
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore LC_NUMERIC
|
// Restore LC_NUMERIC
|
||||||
setlocale(LC_NUMERIC, lc_numeric_old);
|
setlocale(LC_NUMERIC, lc_numeric_old);
|
||||||
free(lc_numeric_old);
|
free(lc_numeric_old);
|
||||||
|
|
||||||
if (ps->o.monitor_repaint && ps->o.backend != BKEND_XRENDER) {
|
if (opt->monitor_repaint && opt->backend != BKEND_XRENDER) {
|
||||||
log_warn("--monitor-repaint has no effect when backend is not xrender");
|
log_warn("--monitor-repaint has no effect when backend is not xrender");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range checking and option assignments
|
// Range checking and option assignments
|
||||||
ps->o.fade_delta = max_i(ps->o.fade_delta, 1);
|
opt->fade_delta = max_i(opt->fade_delta, 1);
|
||||||
ps->o.shadow_radius = max_i(ps->o.shadow_radius, 0);
|
opt->shadow_radius = max_i(opt->shadow_radius, 0);
|
||||||
ps->o.shadow_red = normalize_d(ps->o.shadow_red);
|
opt->shadow_red = normalize_d(opt->shadow_red);
|
||||||
ps->o.shadow_green = normalize_d(ps->o.shadow_green);
|
opt->shadow_green = normalize_d(opt->shadow_green);
|
||||||
ps->o.shadow_blue = normalize_d(ps->o.shadow_blue);
|
opt->shadow_blue = normalize_d(opt->shadow_blue);
|
||||||
ps->o.inactive_dim = normalize_d(ps->o.inactive_dim);
|
opt->inactive_dim = normalize_d(opt->inactive_dim);
|
||||||
ps->o.frame_opacity = normalize_d(ps->o.frame_opacity);
|
opt->frame_opacity = normalize_d(opt->frame_opacity);
|
||||||
ps->o.shadow_opacity = normalize_d(ps->o.shadow_opacity);
|
opt->shadow_opacity = normalize_d(opt->shadow_opacity);
|
||||||
ps->o.refresh_rate = normalize_i_range(ps->o.refresh_rate, 0, 300);
|
opt->refresh_rate = normalize_i_range(opt->refresh_rate, 0, 300);
|
||||||
|
|
||||||
// Apply default wintype options that are dependent on global options
|
// Apply default wintype options that are dependent on global options
|
||||||
for (int i = 0; i < NUM_WINTYPES; i++) {
|
for (int i = 0; i < NUM_WINTYPES; i++) {
|
||||||
auto wo = &ps->o.wintype_option[i];
|
auto wo = &opt->wintype_option[i];
|
||||||
auto mask = &winopt_mask[i];
|
auto mask = &winopt_mask[i];
|
||||||
if (!mask->shadow) {
|
if (!mask->shadow) {
|
||||||
wo->shadow = shadow_enable;
|
wo->shadow = shadow_enable;
|
||||||
|
@ -796,26 +801,26 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --blur-background-frame implies --blur-background
|
// --blur-background-frame implies --blur-background
|
||||||
if (ps->o.blur_background_frame)
|
if (opt->blur_background_frame)
|
||||||
ps->o.blur_background = true;
|
opt->blur_background = true;
|
||||||
|
|
||||||
if (ps->o.xrender_sync_fence)
|
if (opt->xrender_sync_fence)
|
||||||
ps->o.xrender_sync = true;
|
opt->xrender_sync = true;
|
||||||
|
|
||||||
// Other variables determined by options
|
// Other variables determined by options
|
||||||
|
|
||||||
// Determine whether we need to track focus changes
|
// Determine whether we need to track focus changes
|
||||||
if (ps->o.inactive_opacity != ps->o.active_opacity || ps->o.inactive_dim) {
|
if (opt->inactive_opacity != opt->active_opacity || opt->inactive_dim) {
|
||||||
ps->o.track_focus = true;
|
opt->track_focus = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether we track window grouping
|
// Determine whether we track window grouping
|
||||||
if (ps->o.detect_transient || ps->o.detect_client_leader) {
|
if (opt->detect_transient || opt->detect_client_leader) {
|
||||||
ps->o.track_leader = true;
|
opt->track_leader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill default blur kernel
|
// Fill default blur kernel
|
||||||
if (ps->o.blur_background && !ps->o.blur_kerns[0]) {
|
if (opt->blur_background && !opt->blur_kerns[0]) {
|
||||||
// Convolution filter parameter (box blur)
|
// Convolution filter parameter (box blur)
|
||||||
// gaussian or binomial filters are definitely superior, yet looks
|
// gaussian or binomial filters are definitely superior, yet looks
|
||||||
// like they aren't supported as of xorg-server-1.13.0
|
// like they aren't supported as of xorg-server-1.13.0
|
||||||
|
@ -835,13 +840,17 @@ void get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
DOUBLE_TO_XFIXED(1),
|
DOUBLE_TO_XFIXED(1),
|
||||||
DOUBLE_TO_XFIXED(1),
|
DOUBLE_TO_XFIXED(1),
|
||||||
};
|
};
|
||||||
ps->o.blur_kerns[0] =
|
opt->blur_kerns[0] =
|
||||||
ccalloc(ARR_SIZE(convolution_blur), xcb_render_fixed_t);
|
ccalloc(ARR_SIZE(convolution_blur), xcb_render_fixed_t);
|
||||||
memcpy(ps->o.blur_kerns[0], convolution_blur, sizeof(convolution_blur));
|
memcpy(opt->blur_kerns[0], convolution_blur, sizeof(convolution_blur));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->o.resize_damage < 0)
|
if (opt->resize_damage < 0)
|
||||||
log_warn("Negative --resize-damage will not work correctly.");
|
log_warn("Negative --resize-damage will not work correctly.");
|
||||||
|
|
||||||
|
if (opt->backend == BKEND_XRENDER && conv_kern_hasneg)
|
||||||
|
log_warn("A convolution kernel with negative values may not work "
|
||||||
|
"properly under X Render backend.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: set noet sw=8 ts=8 :
|
// vim: set noet sw=8 ts=8 :
|
||||||
|
|
|
@ -2,9 +2,15 @@
|
||||||
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
|
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/// Parse command line options
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <xcb/render.h> // for xcb_render_fixed_t
|
||||||
|
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "win.h" // for wintype_t
|
||||||
|
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
|
|
||||||
|
@ -15,5 +21,15 @@ bool get_early_config(int argc, char *const *argv, char **config_file, bool *all
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process arguments and configuration files.
|
* Process arguments and configuration files.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* shadow_enable = Carry overs from parse_config
|
||||||
|
* fading_enable
|
||||||
|
* conv_kern_hasneg
|
||||||
|
* winopt_mask
|
||||||
*/
|
*/
|
||||||
void get_cfg(session_t *ps, int argc, char *const *argv);
|
void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
|
bool fading_enable, bool conv_kern_hasneg,
|
||||||
|
win_option_mask_t *winopt_mask);
|
||||||
|
|
||||||
|
// vim: set noet sw=8 ts=8:
|
||||||
|
|
10
src/render.c
10
src/render.c
|
@ -4,6 +4,7 @@
|
||||||
#include <xcb/xcb_image.h>
|
#include <xcb/xcb_image.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
|
@ -125,7 +126,12 @@ paint_region(session_t *ps, win *w, int x, int y, int wid, int hei, double opaci
|
||||||
|
|
||||||
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict,
|
render(ps, x, y, dx, dy, wid, hei, opacity, argb, neg, pict,
|
||||||
(w ? w->paint.ptex : ps->root_tile_paint.ptex), reg_paint,
|
(w ? w->paint.ptex : ps->root_tile_paint.ptex), reg_paint,
|
||||||
(w ? &ps->o.glx_prog_win : NULL));
|
#ifdef CONFIG_OPENGL
|
||||||
|
w ? &ps->glx_prog_win : NULL
|
||||||
|
#else
|
||||||
|
NULL
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1223,7 +1229,7 @@ bool init_render(session_t *ps) {
|
||||||
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str,
|
if (!glx_load_prog_main(ps, NULL, ps->o.glx_fshader_win_str,
|
||||||
&ps->o.glx_prog_win))
|
&ps->glx_prog_win))
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
log_error("GLSL supported not compiled in, can't load "
|
log_error("GLSL supported not compiled in, can't load "
|
||||||
|
|
Loading…
Reference in New Issue