1 // SPDX-License-Identifier: MIT
2 // Copyright (c) 2011-2013, Christopher Jeffrey
3 // Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
4 // Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
5 #pragma once
6 
7 /// Common functions and definitions for configuration parsing
8 /// Used for command line arguments and config files
9 
10 #include <ctype.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <xcb/render.h>        // for xcb_render_fixed_t, XXX
15 #include <xcb/xcb.h>
16 #include <xcb/xfixes.h>
17 
18 #ifdef CONFIG_LIBCONFIG
19 #include <libconfig.h>
20 #endif
21 
22 #include "compiler.h"
23 #include "kernel.h"
24 #include "log.h"
25 #include "region.h"
26 #include "types.h"
27 #include "win_defs.h"
28 
29 typedef struct session session_t;
30 
31 /// @brief Possible backends
32 enum backend {
33 	BKEND_XRENDER,
34 	BKEND_GLX,
35 	BKEND_XR_GLX_HYBRID,
36 	BKEND_DUMMY,
37 	NUM_BKEND,
38 };
39 
40 typedef struct win_option_mask {
41 	bool shadow : 1;
42 	bool fade : 1;
43 	bool focus : 1;
44 	bool full_shadow : 1;
45 	bool redir_ignore : 1;
46 	bool opacity : 1;
47 } win_option_mask_t;
48 
49 typedef struct win_option {
50 	bool shadow;
51 	bool fade;
52 	bool focus;
53 	bool full_shadow;
54 	bool redir_ignore;
55 	double opacity;
56 } win_option_t;
57 
58 enum blur_method {
59 	BLUR_METHOD_NONE = 0,
60 	BLUR_METHOD_KERNEL,
61 	BLUR_METHOD_BOX,
62 	BLUR_METHOD_GAUSSIAN,
63 	BLUR_METHOD_INVALID,
64 };
65 
66 typedef struct _c2_lptr c2_lptr_t;
67 
68 /// Structure representing all options.
69 typedef struct options {
70 	// === Debugging ===
71 	bool monitor_repaint;
72 	bool print_diagnostics;
73 	/// Render to a separate window instead of taking over the screen
74 	bool debug_mode;
75 	// === General ===
76 	/// Use the experimental new backends?
77 	bool experimental_backends;
78 	/// Path to write PID to.
79 	char *write_pid_path;
80 	/// The backend in use.
81 	enum backend backend;
82 	/// Whether to sync X drawing with X Sync fence to avoid certain delay
83 	/// issues with GLX backend.
84 	bool xrender_sync_fence;
85 	/// Whether to avoid using stencil buffer under GLX backend. Might be
86 	/// unsafe.
87 	bool glx_no_stencil;
88 	/// Whether to avoid rebinding pixmap on window damage.
89 	bool glx_no_rebind_pixmap;
90 	/// Custom fragment shader for painting windows, as a string.
91 	char *glx_fshader_win_str;
92 	/// Whether to detect rounded corners.
93 	bool detect_rounded_corners;
94 	/// Force painting of window content with blending.
95 	bool force_win_blend;
96 	/// Resize damage for a specific number of pixels.
97 	int resize_damage;
98 	/// Whether to unredirect all windows if a full-screen opaque window
99 	/// is detected.
100 	bool unredir_if_possible;
101 	/// List of conditions of windows to ignore as a full-screen window
102 	/// when determining if a window could be unredirected.
103 	c2_lptr_t *unredir_if_possible_blacklist;
104 	/// Delay before unredirecting screen, in milliseconds.
105 	long unredir_if_possible_delay;
106 	/// Forced redirection setting through D-Bus.
107 	switch_t redirected_force;
108 	/// Whether to stop painting. Controlled through D-Bus.
109 	switch_t stoppaint_force;
110 	/// Whether to enable D-Bus support.
111 	bool dbus;
112 	/// Path to log file.
113 	char *logpath;
114 	/// Number of cycles to paint in benchmark mode. 0 for disabled.
115 	int benchmark;
116 	/// Window to constantly repaint in benchmark mode. 0 for full-screen.
117 	xcb_window_t benchmark_wid;
118 	/// A list of conditions of windows not to paint.
119 	c2_lptr_t *paint_blacklist;
120 	/// Whether to show all X errors.
121 	bool show_all_xerrors;
122 	/// Whether to avoid acquiring X Selection.
123 	bool no_x_selection;
124 	/// Window type option override.
125 	win_option_t wintype_option[NUM_WINTYPES];
126 
127 	// === VSync & software optimization ===
128 	/// User-specified refresh rate.
129 	int refresh_rate;
130 	/// Whether to enable refresh-rate-based software optimization.
131 	bool sw_opti;
132 	/// VSync method to use;
133 	bool vsync;
134 	/// Whether to use glFinish() instead of glFlush() for (possibly) better
135 	/// VSync yet probably higher CPU usage.
136 	bool vsync_use_glfinish;
137 	/// Whether use damage information to help limit the area to paint
138 	bool use_damage;
139 
140 	// === Shadow ===
141 	/// Red, green and blue tone of the shadow.
142 	double shadow_red, shadow_green, shadow_blue;
143 	int shadow_radius;
144 	int shadow_offset_x, shadow_offset_y;
145 	double shadow_opacity;
146 	/// argument string to shadow-exclude-reg option
147 	char *shadow_exclude_reg_str;
148 	/// Shadow blacklist. A linked list of conditions.
149 	c2_lptr_t *shadow_blacklist;
150 	/// Whether bounding-shaped window should be ignored.
151 	bool shadow_ignore_shaped;
152 	/// Whether to crop shadow to the very Xinerama screen.
153 	bool xinerama_shadow_crop;
154 
155 	// === Fading ===
156 	/// How much to fade in in a single fading step.
157 	double fade_in_step;
158 	/// How much to fade out in a single fading step.
159 	double fade_out_step;
160 	/// Fading time delta. In milliseconds.
161 	int fade_delta;
162 	/// Whether to disable fading on window open/close.
163 	bool no_fading_openclose;
164 	/// Whether to disable fading on ARGB managed destroyed windows.
165 	bool no_fading_destroyed_argb;
166 	/// Fading blacklist. A linked list of conditions.
167 	c2_lptr_t *fade_blacklist;
168 
169 	// === Opacity ===
170 	/// Default opacity for inactive windows.
171 	/// 32-bit integer with the format of _NET_WM_OPACITY.
172 	double inactive_opacity;
173 	/// Default opacity for inactive windows.
174 	double active_opacity;
175 	/// Whether inactive_opacity overrides the opacity set by window
176 	/// attributes.
177 	bool inactive_opacity_override;
178 	/// Frame opacity. Relative to window opacity, also affects shadow
179 	/// opacity.
180 	double frame_opacity;
181 	/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
182 	/// managers that don't pass _NET_WM_OPACITY to frame windows.
183 	bool detect_client_opacity;
184 
185 	// === Other window processing ===
186 	/// Blur method for background of semi-transparent windows
187 	enum blur_method blur_method;
188 	// Size of the blur kernel
189 	int blur_radius;
190 	// Standard deviation for the gaussian blur
191 	double blur_deviation;
192 	/// Whether to blur background when the window frame is not opaque.
193 	/// Implies blur_background.
194 	bool blur_background_frame;
195 	/// Whether to use fixed blur strength instead of adjusting according
196 	/// to window opacity.
197 	bool blur_background_fixed;
198 	/// Background blur blacklist. A linked list of conditions.
199 	c2_lptr_t *blur_background_blacklist;
200 	/// Blur convolution kernel.
201 	struct conv **blur_kerns;
202 	/// Number of convolution kernels
203 	int blur_kernel_count;
204 	/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
205 	double inactive_dim;
206 	/// Whether to use fixed inactive dim opacity, instead of deciding
207 	/// based on window opacity.
208 	bool inactive_dim_fixed;
209 	/// Conditions of windows to have inverted colors.
210 	c2_lptr_t *invert_color_list;
211 	/// Rules to change window opacity.
212 	c2_lptr_t *opacity_rules;
213 	/// Limit window brightness
214 	double max_brightness;
215 
216 	// === Focus related ===
217 	/// Whether to try to detect WM windows and mark them as focused.
218 	bool mark_wmwin_focused;
219 	/// Whether to mark override-redirect windows as focused.
220 	bool mark_ovredir_focused;
221 	/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
222 	bool use_ewmh_active_win;
223 	/// A list of windows always to be considered focused.
224 	c2_lptr_t *focus_blacklist;
225 	/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
226 	bool detect_transient;
227 	/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
228 	bool detect_client_leader;
229 
230 	// === Calculated ===
231 	/// Whether we need to track window leaders.
232 	bool track_leader;
233 
234 	// Don't use EWMH to detect fullscreen applications
235 	bool no_ewmh_fullscreen;
236 
237 	// Make transparent windows clip other windows, instead of blending on top of
238 	// them
239 	bool transparent_clipping;
240 } options_t;
241 
242 extern const char *const BACKEND_STRS[NUM_BKEND + 1];
243 
244 bool must_use parse_long(const char *, long *);
245 bool must_use parse_int(const char *, int *);
246 struct conv **must_use parse_blur_kern_lst(const char *, bool *hasneg, int *count);
247 bool must_use parse_geometry(session_t *, const char *, region_t *);
248 bool must_use parse_rule_opacity(c2_lptr_t **, const char *);
249 enum blur_method must_use parse_blur_method(const char *src);
250 
251 /**
252  * Add a pattern to a condition linked list.
253  */
254 bool condlst_add(c2_lptr_t **, const char *);
255 
256 #ifdef CONFIG_LIBCONFIG
257 /// Parse a configuration file
258 /// Returns the actually config_file name used, allocated on heap
259 /// Outputs:
260 ///   shadow_enable = whether shaodw is enabled globally
261 ///   fading_enable = whether fading is enabled globally
262 ///   win_option_mask = whether option overrides for specific window type is set for given
263 ///                     options
264 ///   hasneg = whether the convolution kernel has negative values
265 char *
266 parse_config_libconfig(options_t *, const char *config_file, bool *shadow_enable,
267                        bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
268 #endif
269 
270 void set_default_winopts(options_t *, win_option_mask_t *, bool shadow_enable,
271                          bool fading_enable);
272 /// Parse a configuration file is that is enabled, also initialize the winopt_mask with
273 /// default values
274 /// Outputs and returns:
275 ///   same as parse_config_libconfig
276 char *parse_config(options_t *, const char *config_file, bool *shadow_enable,
277                    bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
278 
279 /**
280  * Parse a backend option argument.
281  */
parse_backend(const char * str)282 static inline attr_pure enum backend parse_backend(const char *str) {
283 	for (enum backend i = 0; BACKEND_STRS[i]; ++i) {
284 		if (!strcasecmp(str, BACKEND_STRS[i])) {
285 			return i;
286 		}
287 	}
288 	// Keep compatibility with an old revision containing a spelling mistake...
289 	if (!strcasecmp(str, "xr_glx_hybird")) {
290 		log_warn("backend xr_glx_hybird should be xr_glx_hybrid, the misspelt "
291 		         "version will be removed soon.");
292 		return BKEND_XR_GLX_HYBRID;
293 	}
294 	// cju wants to use dashes
295 	if (!strcasecmp(str, "xr-glx-hybrid")) {
296 		log_warn("backend xr-glx-hybrid should be xr_glx_hybrid, the alternative "
297 		         "version will be removed soon.");
298 		return BKEND_XR_GLX_HYBRID;
299 	}
300 	log_error("Invalid backend argument: %s", str);
301 	return NUM_BKEND;
302 }
303 
304 /**
305  * Parse a VSync option argument.
306  */
parse_vsync(const char * str)307 static inline bool parse_vsync(const char *str) {
308 	if (strcmp(str, "no") == 0 || strcmp(str, "none") == 0 ||
309 	    strcmp(str, "false") == 0 || strcmp(str, "nah") == 0) {
310 		return false;
311 	}
312 	return true;
313 }
314 
315 // vim: set noet sw=8 ts=8 :
316