Prepare for release 1.2.0.
[xombrero.git] / settings.c
blob31923b8455dcc8c385c6a7526d56be232acfbe59
1 /*
2 * Copyright (c) 2010, 2011 Marco Peereboom <marco@peereboom.us>
3 * Copyright (c) 2011 Stevan Andjelkovic <stevan@student.chalmers.se>
4 * Copyright (c) 2010, 2011 Edd Barrett <vext01@gmail.com>
5 * Copyright (c) 2011 Todd T. Fries <todd@fries.net>
6 * Copyright (c) 2011 Raphael Graf <r@undefined.ch>
7 * Copyright (c) 2011 Michal Mazurek <akfaew@jasminek.net>
8 * Copyright (c) 2012 Josh Rickmar <jrick@devio.us>
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include <xombrero.h>
25 /* globals */
26 SoupURI *proxy_uri = NULL;
27 PangoFontDescription *cmd_font;
28 PangoFontDescription *oops_font;
29 PangoFontDescription *statusbar_font;
30 PangoFontDescription *tabbar_font;
32 /* non-settings */
33 int tabless = 0; /* allow only 1 tab */
34 char search_file[PATH_MAX];
35 char command_file[PATH_MAX];
36 char runtime_settings[PATH_MAX]; /* override of settings */
38 /* settings that require restart */
39 int enable_socket = 0;
40 int single_instance = 0; /* only allow one xombrero to run */
41 int fancy_bar = 1; /* fancy toolbar */
42 int browser_mode = XT_BM_NORMAL;
43 int gui_mode = XT_GM_CLASSIC;
44 char *statusbar_elems = NULL;
45 int window_height = 768;
46 int window_width = 1024;
47 int window_maximize = 0;
48 int icon_size = 2; /* 1 = smallest, 2+ = bigger */
49 char *resource_dir = NULL;
50 char download_dir[PATH_MAX];
51 int allow_volatile_cookies = 0;
52 int save_global_history = 0; /* save global history to disk */
53 struct user_agent *user_agent = NULL;
54 struct http_accept *http_accept = NULL;
55 int save_rejected_cookies = 0;
56 gint max_connections = 25;
57 gint max_host_connections = 5;
58 int history_autosave = 0;
59 int edit_mode = XT_EM_HYBRID;
60 char *include_config = NULL;
62 /* runtime settings */
63 int show_tabs = XT_DS_SHOW_TABS; /* show tabs on notebook */
64 int tab_style = XT_DS_TAB_STYLE; /* tab bar style */
65 int statusbar_style = XT_DS_STATUSBAR_STYLE; /* status bar style */
66 int show_url = XT_DS_SHOW_URL; /* show url toolbar on notebook */
67 int show_scrollbars = XT_DS_SHOW_SCROLLBARS;
68 int show_statusbar = XT_DS_SHOW_STATUSBAR; /* vimperator style status bar */
69 int ctrl_click_focus = XT_DS_CTRL_CLICK_FOCUS; /* ctrl click gets focus */
70 int cookies_enabled = XT_DS_COOKIES_ENABLED; /* enable cookies */
71 int read_only_cookies = XT_DS_READ_ONLY_COOKIES; /* enable to not write cookies */
72 int enable_scripts = XT_DS_ENABLE_SCRIPTS;
73 int enable_plugins = XT_DS_ENABLE_PLUGINS;
74 gfloat default_zoom_level = XT_DS_DEFAULT_ZOOM_LEVEL;
75 char default_script[PATH_MAX]; /* special setting - is never g_free'd */
76 int refresh_interval = XT_DS_REFRESH_INTERVAL; /* download refresh interval */
77 int enable_plugin_whitelist = XT_DS_ENABLE_PLUGIN_WHITELIST;
78 int enable_cookie_whitelist = XT_DS_ENABLE_COOKIE_WHITELIST;
79 int enable_js_whitelist = XT_DS_ENABLE_JS_WHITELIST;
80 int enable_localstorage = XT_DS_ENABLE_LOCALSTORAGE;
81 int session_timeout = XT_DS_SESSION_TIMEOUT; /* cookie session timeout */
82 int cookie_policy = XT_DS_COOKIE_POLICY;
83 char ssl_ca_file[PATH_MAX]; /* special setting - is never g_free'd */
84 gboolean ssl_strict_certs = XT_DS_SSL_STRICT_CERTS;
85 gboolean enable_strict_transport = XT_DS_ENABLE_STRICT_TRANSPORT;
86 int append_next = XT_DS_APPEND_NEXT; /* append tab after current tab */
87 char *home = NULL; /* allocated/set at startup */
88 char *search_string = NULL; /* allocated/set at startup */
89 char *http_proxy = NULL;
90 int http_proxy_starts_enabled = 1;
91 int download_mode = XT_DM_START;
92 int color_visited_uris = XT_DS_COLOR_VISITED_URIS;
93 int session_autosave = XT_DS_SESSION_AUTOSAVE;
94 int guess_search = XT_DS_GUESS_SEARCH;
95 gint enable_spell_checking = XT_DS_ENABLE_SPELL_CHECKING;
96 char *spell_check_languages = NULL; /* allocated/set at startup */
97 char *url_regex = NULL; /* allocated/set at startup */
98 char *encoding = NULL; /* allocated/set at startup */
99 int autofocus_onload = XT_DS_AUTOFOCUS_ONLOAD;
100 int enable_js_autorun = XT_DS_ENABLE_JS_AUTORUN;
101 char *userstyle = NULL; /* allocated/set at startup */
102 int userstyle_global = XT_DS_USERSTYLE_GLOBAL;
103 int auto_load_images = XT_DS_AUTO_LOAD_IMAGES;
104 int enable_autoscroll = XT_DS_ENABLE_AUTOSCROLL;
105 int enable_favicon_entry = XT_DS_ENABLE_FAVICON_ENTRY;
106 int enable_favicon_tabs = XT_DS_ENABLE_FAVICON_TABS;
107 char *external_editor = NULL;
108 int referer_mode = XT_DS_REFERER_MODE;
109 char *referer_custom = NULL;
110 int download_notifications = XT_DS_DOWNLOAD_NOTIFICATIONS;
111 int warn_cert_changes = 0;
112 int allow_insecure_content = XT_DS_ALLOW_INSECURE_CONTENT;
113 int allow_insecure_scripts = XT_DS_ALLOW_INSECURE_SCRIPTS;
115 char *cmd_font_name = NULL; /* these are all set at startup */
116 char *oops_font_name = NULL;
117 char *statusbar_font_name = NULL;
118 char *tabbar_font_name = NULL;
120 char *get_download_dir(struct settings *);
121 char *get_default_script(struct settings *);
122 char *get_runtime_dir(struct settings *);
123 char *get_tab_style(struct settings *);
124 char *get_statusbar_style(struct settings *);
125 char *get_edit_mode(struct settings *);
126 char *get_download_mode(struct settings *);
127 char *get_work_dir(struct settings *);
128 char *get_referer(struct settings *);
129 char *get_ssl_ca_file(struct settings *);
130 char *get_userstyle(struct settings *);
132 int add_cookie_wl(struct settings *, char *);
133 int add_js_wl(struct settings *, char *);
134 int add_pl_wl(struct settings *, char *);
135 int add_mime_type(struct settings *, char *);
136 int add_alias(struct settings *, char *);
137 int add_kb(struct settings *, char *);
138 int add_ua(struct settings *, char *);
139 int add_http_accept(struct settings *, char *);
140 int add_cmd_alias(struct settings *, char *);
141 int add_custom_uri(struct settings *, char *);
143 int set_append_next(char *);
144 int set_autofocus_onload(char *);
145 int set_cmd_font(char *);
146 int set_color_visited_uris(char *);
147 int set_cookie_policy_rt(char *);
148 int set_cookies_enabled(char *);
149 int set_ctrl_click_focus(char *);
150 int set_fancy_bar(char *);
151 int set_home(char *);
152 int set_download_dir(struct settings *, char *);
153 int set_download_notifications(char *);
154 int set_default_script(struct settings *, char *);
155 int set_default_script_rt(char *);
156 int set_default_zoom_level(char *);
157 int set_enable_cookie_whitelist(char *);
158 int set_enable_js_autorun(char *);
159 int set_enable_js_whitelist(char *);
160 int set_enable_localstorage(char *);
161 int set_enable_plugins(char *);
162 int set_enable_plugin_whitelist(char *);
163 int set_enable_scripts(char *);
164 int set_enable_spell_checking(char *);
165 int set_enable_strict_transport(char *);
166 int set_encoding_rt(char *);
167 int set_runtime_dir(struct settings *, char *);
168 int set_tabbar_font(char *value);
169 int set_tab_style(struct settings *, char *);
170 int set_tab_style_rt(char *);
171 int set_statusbar_style(struct settings *, char *);
172 int set_statusbar_style_rt(char *);
173 int set_edit_mode(struct settings *, char *);
174 int set_work_dir(struct settings *, char *);
175 int set_auto_load_images(char *);
176 int set_enable_autoscroll(char *);
177 int set_enable_favicon_entry(char *);
178 int set_enable_favicon_tabs(char *);
179 int set_guess_search(char *);
180 int set_download_mode(struct settings *, char *);
181 int set_download_mode_rt(char *);
182 int set_oops_font(char *);
183 int set_read_only_cookies(char *);
184 int set_referer(struct settings *, char *);
185 int set_referer_rt(char *);
186 int set_refresh_interval(char *);
187 int set_search_string(char *s);
188 int set_session_autosave(char *);
189 int set_session_timeout(char *);
190 int set_show_scrollbars(char *);
191 int set_show_statusbar(char *);
192 int set_show_tabs(char *);
193 int set_show_url(char *);
194 int set_spell_check_languages(char *);
195 int set_ssl_ca_file_rt(char *);
196 int set_ssl_strict_certs(char *);
197 int set_statusbar_font(char *);
198 int set_url_regex(char *);
199 int set_userstyle(struct settings *, char *);
200 int set_userstyle_rt(char *);
201 int set_userstyle_global(char *);
202 int set_external_editor(char *);
203 int set_warn_cert_changes(char *);
204 int set_allow_insecure_content(char *);
205 int set_allow_insecure_scripts(char *);
207 void walk_mime_type(struct settings *, void (*)(struct settings *,
208 char *, void *), void *);
209 void walk_alias(struct settings *, void (*)(struct settings *,
210 char *, void *), void *);
211 void walk_cookie_wl(struct settings *, void (*)(struct settings *,
212 char *, void *), void *);
213 void walk_js_wl(struct settings *, void (*)(struct settings *,
214 char *, void *), void *);
215 void walk_pl_wl(struct settings *, void (*)(struct settings *,
216 char *, void *), void *);
217 void walk_kb(struct settings *, void (*)(struct settings *, char *,
218 void *), void *);
219 void walk_ua(struct settings *, void (*)(struct settings *, char *,
220 void *), void *);
221 void walk_http_accept(struct settings *, void (*)(struct settings *,
222 char *, void *), void *);
223 void walk_cmd_alias(struct settings *, void (*)(struct settings *,
224 char *, void *), void *);
225 void walk_custom_uri(struct settings *, void (*)(struct settings *,
226 char *, void *), void *);
229 set_http_proxy(char *proxy)
231 SoupURI *uri;
233 /* see if we need to clear it */
234 if (proxy == NULL || strlen(proxy) == 0) {
235 setup_proxy(NULL);
236 return (0);
239 uri = soup_uri_new(proxy);
240 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
241 return (1);
243 setup_proxy(proxy);
245 soup_uri_free(uri);
247 return (0);
250 struct special {
251 int (*set)(struct settings *, char *);
252 char *(*get)(struct settings *);
253 void (*walk)(struct settings *,
254 void (*cb)(struct settings *, char *, void *),
255 void *);
258 struct special s_browser_mode = {
259 set_browser_mode,
260 get_browser_mode,
261 NULL
264 struct special s_gui_mode = {
265 set_gui_mode,
266 get_gui_mode,
267 NULL
270 struct special s_cookie = {
271 set_cookie_policy,
272 get_cookie_policy,
273 NULL
276 struct special s_alias = {
277 add_alias,
278 NULL,
279 walk_alias
282 struct special s_cmd_alias = {
283 add_cmd_alias,
284 NULL,
285 walk_cmd_alias
288 struct special s_mime = {
289 add_mime_type,
290 NULL,
291 walk_mime_type
294 struct special s_js = {
295 add_js_wl,
296 NULL,
297 walk_js_wl
300 struct special s_pl = {
301 add_pl_wl,
302 NULL,
303 walk_pl_wl
306 struct special s_kb = {
307 add_kb,
308 NULL,
309 walk_kb
312 struct special s_cookie_wl = {
313 add_cookie_wl,
314 NULL,
315 walk_cookie_wl
318 struct special s_uri = {
319 add_custom_uri,
320 NULL,
321 walk_custom_uri,
324 struct special s_default_script = {
325 set_default_script,
326 get_default_script,
327 NULL
330 struct special s_ssl_ca_file = {
331 set_ssl_ca_file,
332 get_ssl_ca_file,
333 NULL
336 struct special s_download_dir = {
337 set_download_dir,
338 get_download_dir,
339 NULL
342 struct special s_work_dir = {
343 set_work_dir,
344 get_work_dir,
345 NULL
348 struct special s_tab_style = {
349 set_tab_style,
350 get_tab_style,
351 NULL
354 struct special s_statusbar_style = {
355 set_statusbar_style,
356 get_statusbar_style,
357 NULL
360 struct special s_edit_mode = {
361 set_edit_mode,
362 get_edit_mode,
363 NULL
366 struct special s_download_mode = {
367 set_download_mode,
368 get_download_mode,
369 NULL
372 struct special s_ua = {
373 add_ua,
374 NULL,
375 walk_ua
378 struct special s_http_accept = {
379 add_http_accept,
380 NULL,
381 walk_http_accept
384 struct special s_referer = {
385 set_referer,
386 get_referer,
387 NULL
390 struct special s_userstyle = {
391 set_userstyle,
392 get_userstyle,
393 NULL
396 struct settings rs[] = {
397 { "allow_insecure_content", XT_S_INT, 0, &allow_insecure_content, NULL, NULL, NULL, set_allow_insecure_content },
398 { "allow_insecure_scripts", XT_S_INT, 0, &allow_insecure_scripts, NULL, NULL, NULL, set_allow_insecure_scripts },
399 { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL, NULL, NULL},
400 { "append_next", XT_S_INT, 0, &append_next, NULL, NULL, NULL, set_append_next },
401 { "auto_load_images", XT_S_INT, 0, &auto_load_images, NULL, NULL, NULL, set_auto_load_images },
402 { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL, NULL, set_autofocus_onload },
403 { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode, NULL, NULL },
404 { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL, NULL, set_cmd_font },
405 { "color_visited_uris", XT_S_INT, 0, &color_visited_uris , NULL, NULL, NULL, set_color_visited_uris },
406 { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie, NULL, set_cookie_policy_rt },
407 { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL, NULL, set_cookies_enabled },
408 { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL, NULL, set_ctrl_click_focus },
409 { "default_script", XT_S_STR, 1, NULL, NULL,&s_default_script, NULL, set_default_script_rt },
410 { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level, set_default_zoom_level },
411 { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir, NULL, NULL },
412 { "download_mode", XT_S_STR, 0, NULL, NULL,&s_download_mode, NULL, set_download_mode_rt },
413 { "download_notifications", XT_S_INT, 0, &download_notifications, NULL, NULL, NULL, set_download_notifications },
414 { "edit_mode", XT_S_STR, 0, NULL, NULL,&s_edit_mode, NULL, NULL},
415 { "enable_autoscroll", XT_S_INT, 0, &enable_autoscroll, NULL, NULL, NULL, set_enable_autoscroll },
416 { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL, NULL, set_enable_cookie_whitelist },
417 { "enable_favicon_entry", XT_S_INT, 0, &enable_favicon_entry, NULL, NULL, NULL, set_enable_favicon_entry },
418 { "enable_favicon_tabs", XT_S_INT, 0, &enable_favicon_tabs, NULL, NULL, NULL, set_enable_favicon_tabs },
419 { "enable_js_autorun", XT_S_INT, 0, &enable_js_autorun, NULL, NULL, NULL, set_enable_js_autorun },
420 { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL, NULL, set_enable_js_whitelist },
421 { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL, NULL, set_enable_localstorage },
422 { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL, NULL, set_enable_plugin_whitelist },
423 { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL, NULL, set_enable_plugins },
424 { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL, NULL, set_enable_scripts },
425 { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL, NULL, NULL },
426 { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL, NULL, set_enable_spell_checking },
427 { "enable_strict_transport", XT_S_INT, 0, &enable_strict_transport, NULL, NULL, NULL, set_enable_strict_transport },
428 { "encoding", XT_S_STR, 0, NULL, &encoding, NULL, NULL, NULL },
429 { "external_editor", XT_S_STR,0, NULL, &external_editor, NULL, NULL, set_external_editor },
430 { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL, NULL, set_fancy_bar },
431 { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL, NULL, set_guess_search },
432 { "gui_mode", XT_S_INT, 0, NULL, NULL,&s_gui_mode, NULL, NULL },
433 { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL, NULL, NULL },
434 { "home", XT_S_STR, 0, NULL, &home, NULL, NULL, set_home },
435 { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy },
436 { "http_proxy_starts_enabled", XT_S_INT, 0, &http_proxy_starts_enabled, NULL, NULL, NULL, NULL },
437 { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL, NULL, NULL },
438 { "include_config", XT_S_STR, 0, NULL, &include_config, NULL, NULL, NULL },
439 { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL, NULL, NULL },
440 { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL, NULL, NULL },
441 { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL, NULL, set_oops_font },
442 { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL, NULL, set_read_only_cookies },
443 { "referer", XT_S_STR, 0, NULL, NULL,&s_referer, NULL, set_referer_rt },
444 { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL, NULL, set_refresh_interval },
445 { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL, NULL, NULL },
446 { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL, NULL, NULL },
447 { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL, NULL, NULL },
448 { "search_string", XT_S_STR, 0, NULL, &search_string, NULL, NULL, set_search_string },
449 { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL, NULL, set_session_autosave },
450 { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL, NULL, set_session_timeout },
451 { "show_scrollbars", XT_S_INT, 0, &show_scrollbars, NULL, NULL, NULL, set_show_scrollbars },
452 { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL, NULL, set_show_statusbar },
453 { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL, NULL, set_show_tabs },
454 { "show_url", XT_S_INT, 0, &show_url, NULL, NULL, NULL, set_show_url },
455 { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL, NULL, NULL },
456 { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL, NULL, set_spell_check_languages },
457 { "ssl_ca_file", XT_S_STR, 0, NULL, NULL,&s_ssl_ca_file, NULL, set_ssl_ca_file_rt },
458 { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL, NULL, set_ssl_strict_certs },
459 { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL, NULL, NULL },
460 { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL, NULL, set_statusbar_font },
461 { "statusbar_style", XT_S_STR, 0, NULL, NULL,&s_statusbar_style, NULL, set_statusbar_style_rt },
462 { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style, NULL, set_tab_style_rt },
463 { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL, NULL, set_tabbar_font },
464 { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL, NULL, set_url_regex },
465 { "userstyle", XT_S_STR, 0, NULL, NULL,&s_userstyle, NULL, set_userstyle_rt },
466 { "userstyle_global", XT_S_INT, 0, &userstyle_global, NULL, NULL, NULL, set_userstyle_global },
467 { "warn_cert_changes", XT_S_INT, 0, &warn_cert_changes, NULL, NULL, NULL, set_warn_cert_changes },
468 { "window_height", XT_S_INT, 0, &window_height, NULL, NULL, NULL, NULL },
469 { "window_maximize", XT_S_INT, 0, &window_maximize, NULL, NULL, NULL, NULL },
470 { "window_width", XT_S_INT, 0, &window_width, NULL, NULL, NULL, NULL },
471 { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir, NULL, NULL },
473 /* special settings */
474 { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias, NULL, NULL },
475 { "cmd_alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cmd_alias, NULL, NULL },
476 { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl, NULL, NULL },
477 { "custom_uri", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_uri, NULL, NULL },
478 { "http_accept", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_http_accept, NULL, NULL },
479 { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js, NULL, NULL },
480 { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
481 { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
482 { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
483 { "user_agent", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
487 set_default_zoom_level(char *value)
489 struct karg args = {0};
490 struct tab *t;
492 if (value == NULL || strlen(value) == 0)
493 default_zoom_level = XT_DS_DEFAULT_ZOOM_LEVEL;
494 else
495 default_zoom_level = g_strtod(value, NULL);
496 args.i = 100; /* adjust = 100 percent for no additional adjustment */
497 TAILQ_FOREACH(t, &tabs, entry)
498 resizetab(t, &args);
499 return (0);
503 set_cookies_enabled(char *value)
505 int tmp;
506 const char *errstr;
508 if (value == NULL || strlen(value) == 0)
509 cookies_enabled = XT_DS_COOKIES_ENABLED;
510 else {
511 tmp = strtonum(value, 0, 1, &errstr);
512 if (errstr)
513 return (-1);
514 cookies_enabled = tmp;
516 return (0);
520 set_append_next(char *value)
522 int tmp;
523 const char *errstr;
525 if (value == NULL || strlen(value) == 0)
526 append_next = XT_DS_APPEND_NEXT;
527 else {
528 tmp = strtonum(value, 0, 1, &errstr);
529 if (errstr)
530 return (-1);
531 append_next = tmp;
533 return (0);
537 set_cmd_font(char *value)
539 struct tab *t;
541 if (cmd_font_name)
542 g_free(cmd_font_name);
543 if (cmd_font)
544 pango_font_description_free(cmd_font);
545 if (value == NULL || strlen(value) == 0)
546 cmd_font_name = g_strdup(XT_DS_CMD_FONT_NAME);
547 else
548 cmd_font_name = g_strdup(value);
549 cmd_font = pango_font_description_from_string(cmd_font_name);
550 TAILQ_FOREACH(t, &tabs, entry)
551 gtk_widget_modify_font(GTK_WIDGET(t->cmd), cmd_font);
552 return (0);
556 set_oops_font(char *value)
558 struct tab *t;
560 if (oops_font_name)
561 g_free(oops_font_name);
562 if (oops_font)
563 pango_font_description_free(oops_font);
564 if (value == NULL || strlen(value) == 0)
565 cmd_font_name = g_strdup(XT_DS_OOPS_FONT_NAME);
566 else
567 oops_font_name = g_strdup(value);
568 oops_font = pango_font_description_from_string(oops_font_name);
569 TAILQ_FOREACH(t, &tabs, entry)
570 gtk_widget_modify_font(GTK_WIDGET(t->oops), oops_font);
571 return (0);
575 set_statusbar_font(char *value)
577 struct tab *t;
579 if (statusbar_font_name)
580 g_free(statusbar_font_name);
581 if (statusbar_font)
582 pango_font_description_free(statusbar_font);
583 if (value == NULL || strlen(value) == 0)
584 statusbar_font_name = g_strdup(XT_DS_STATUSBAR_FONT_NAME);
585 else
586 statusbar_font_name = g_strdup(value);
587 statusbar_font = pango_font_description_from_string(
588 statusbar_font_name);
589 TAILQ_FOREACH(t, &tabs, entry) {
590 gtk_widget_modify_font(GTK_WIDGET(t->sbe.statusbar),
591 statusbar_font);
592 gtk_widget_modify_font(GTK_WIDGET(t->sbe.buffercmd),
593 statusbar_font);
594 gtk_widget_modify_font(GTK_WIDGET(t->sbe.zoom),
595 statusbar_font);
596 gtk_widget_modify_font(GTK_WIDGET(t->sbe.position),
597 statusbar_font);
598 gtk_widget_modify_font(GTK_WIDGET(t->sbe.proxy),
599 statusbar_font);
601 return (0);
605 set_tabbar_font(char *value)
607 struct tab *t;
609 if (tabbar_font_name)
610 g_free(tabbar_font_name);
611 if (tabbar_font)
612 pango_font_description_free(tabbar_font);
613 if (value == NULL || strlen(value) == 0)
614 tabbar_font_name = g_strdup(XT_DS_TABBAR_FONT_NAME);
615 else
616 tabbar_font_name = g_strdup(value);
617 tabbar_font = pango_font_description_from_string(tabbar_font_name);
618 TAILQ_FOREACH(t, &tabs, entry)
619 gtk_widget_modify_font(GTK_WIDGET(t->tab_elems.label),
620 tabbar_font);
621 return (0);
625 set_color_visited_uris(char *value)
627 int tmp;
628 const char *errstr;
630 if (value == NULL || strlen(value) == 0)
631 color_visited_uris = XT_DS_COLOR_VISITED_URIS;
632 else {
633 tmp = strtonum(value, 0, 1, &errstr);
634 if (errstr)
635 return (-1);
636 color_visited_uris = tmp;
638 return (0);
642 set_home(char *value)
644 if (home)
645 g_free(home);
646 if (value == NULL || strlen(value) == 0)
647 home = g_strdup(XT_DS_HOME);
648 else
649 home = g_strdup(value);
650 return (0);
654 set_search_string(char *value)
656 if (search_string)
657 g_free(search_string);
658 if (value == NULL || strlen(value) == 0)
659 search_string = g_strdup(XT_DS_SEARCH_STRING);
660 else
661 search_string = g_strdup(value);
662 return (0);
665 size_t
666 get_settings_size(void)
668 return (LENGTH(rs));
671 char *
672 get_setting_name(int i)
674 if (i > LENGTH(rs))
675 return (NULL);
676 return (rs[i].name);
679 char *
680 get_as_string(struct settings *s)
682 char *r = NULL;
684 if (s == NULL)
685 return (NULL);
687 if (s->s) {
688 if (s->s->get)
689 r = s->s->get(s);
690 else
691 warnx("get_as_string skip %s\n", s->name);
692 } else if (s->type == XT_S_INT)
693 r = g_strdup_printf("%d", *s->ival);
694 else if (s->type == XT_S_STR)
695 r = g_strdup(*s->sval);
696 else if (s->type == XT_S_FLOAT)
697 r = g_strdup_printf("%f", *s->fval);
698 else
699 r = g_strdup_printf("INVALID TYPE");
701 return (r);
704 void
705 settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args)
707 int i;
708 char *s;
710 for (i = 0; i < LENGTH(rs); i++) {
711 if (rs[i].s && rs[i].s->walk)
712 rs[i].s->walk(&rs[i], cb, cb_args);
713 else {
714 s = get_as_string(&rs[i]);
715 cb(&rs[i], s, cb_args);
716 g_free(s);
722 set_browser_mode(struct settings *s, char *val)
724 if (!strcmp(val, "whitelist")) {
725 browser_mode = XT_BM_WHITELIST;
726 allow_volatile_cookies = 0;
727 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
728 cookies_enabled = 1;
729 enable_cookie_whitelist = 1;
730 enable_plugin_whitelist = 1;
731 enable_plugins = 0;
732 read_only_cookies = 0;
733 save_rejected_cookies = 0;
734 session_timeout = 3600;
735 enable_scripts = 0;
736 enable_js_whitelist = 1;
737 enable_localstorage = 0;
738 referer_mode = XT_REFERER_SAME_DOMAIN;
739 allow_insecure_content = 0;
740 allow_insecure_scripts = 0;
741 } else if (!strcmp(val, "normal")) {
742 browser_mode = XT_BM_NORMAL;
743 allow_volatile_cookies = 0;
744 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
745 cookies_enabled = 1;
746 enable_cookie_whitelist = 0;
747 enable_plugin_whitelist = 0;
748 enable_plugins = 1;
749 read_only_cookies = 0;
750 save_rejected_cookies = 0;
751 session_timeout = 3600;
752 enable_scripts = 1;
753 enable_js_whitelist = 0;
754 enable_localstorage = 1;
755 referer_mode = XT_REFERER_ALWAYS;
756 allow_insecure_content = 1;
757 allow_insecure_scripts = 1;
758 } else if (!strcmp(val, "kiosk")) {
759 browser_mode = XT_BM_KIOSK;
760 allow_volatile_cookies = 0;
761 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
762 cookies_enabled = 1;
763 enable_cookie_whitelist = 0;
764 enable_plugin_whitelist = 0;
765 enable_plugins = 1;
766 read_only_cookies = 0;
767 save_rejected_cookies = 0;
768 session_timeout = 3600;
769 enable_scripts = 1;
770 enable_js_whitelist = 0;
771 enable_localstorage = 1;
772 referer_mode = XT_REFERER_ALWAYS;
773 allow_insecure_content = 1;
774 allow_insecure_scripts = 1;
775 show_tabs = 0;
776 tabless = 1;
777 } else
778 return (1);
780 return (0);
783 char *
784 get_browser_mode(struct settings *s)
786 char *r = NULL;
788 if (browser_mode == XT_BM_WHITELIST)
789 r = g_strdup("whitelist");
790 else if (browser_mode == XT_BM_NORMAL)
791 r = g_strdup("normal");
792 else if (browser_mode == XT_BM_KIOSK)
793 r = g_strdup("kiosk");
794 else
795 return (NULL);
797 return (r);
801 set_gui_mode(struct settings *s, char *val)
803 if (!strcmp(val, "classic")) {
804 fancy_bar = 1;
805 show_tabs = 1;
806 tab_style = XT_TABS_NORMAL;
807 show_url = 1;
808 show_statusbar = 0;
809 show_scrollbars = 1;
810 } else if (!strcmp(val, "minimal")) {
811 fancy_bar = 0;
812 show_tabs = 1;
813 tab_style = XT_TABS_COMPACT;
814 show_url = 0;
815 show_statusbar = 1;
816 show_scrollbars = 0;
817 } else
818 return (1);
820 return (0);
823 char *
824 get_gui_mode(struct settings *s)
826 char *r = NULL;
828 if (gui_mode == XT_GM_CLASSIC)
829 r = g_strdup("classic");
830 else if (browser_mode == XT_GM_MINIMAL)
831 r = g_strdup("minimal");
832 else
833 return (NULL);
835 return (r);
839 set_cookie_policy(struct settings *s, char *val)
841 if (!strcmp(val, "no3rdparty"))
842 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
843 else if (!strcmp(val, "accept"))
844 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
845 else if (!strcmp(val, "reject"))
846 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
847 else
848 return (1);
850 return (0);
854 set_cookie_policy_rt(char *value)
856 if (value == NULL || strlen(value) == 0)
857 cookie_policy = XT_DS_COOKIE_POLICY;
858 else if (set_cookie_policy(NULL, value))
859 return (-1);
860 g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY,
861 cookie_policy, (void *)NULL);
862 return (0);
865 char *
866 get_cookie_policy(struct settings *s)
868 char *r = NULL;
870 if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY)
871 r = g_strdup("no3rdparty");
872 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
873 r = g_strdup("accept");
874 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
875 r = g_strdup("reject");
876 else
877 return (NULL);
879 return (r);
882 char *
883 get_default_script(struct settings *s)
885 if (default_script[0] == '\0')
886 return (0);
887 return (g_strdup(default_script));
891 set_default_script(struct settings *s, char *val)
893 expand_tilde(default_script, sizeof default_script, val);
894 return (0);
898 set_default_script_rt(char *value)
900 if (value == NULL || strlen(value) == 0)
901 return set_default_script(NULL, "");
902 return (set_default_script(NULL, value));
905 char *
906 get_download_dir(struct settings *s)
908 if (download_dir[0] == '\0')
909 return (0);
910 return (g_strdup(download_dir));
914 set_download_dir(struct settings *s, char *val)
916 expand_tilde(download_dir, sizeof download_dir, val);
917 return (0);
921 add_alias(struct settings *s, char *line)
923 char *l, *alias;
924 struct alias *a = NULL;
926 if (s == NULL || line == NULL) {
927 show_oops(NULL, "add_alias invalid parameters");
928 return (1);
931 l = line;
932 a = g_malloc(sizeof(*a));
934 if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) {
935 show_oops(NULL, "add_alias: incomplete alias definition");
936 goto bad;
938 if (strlen(alias) == 0 || strlen(l) == 0) {
939 show_oops(NULL, "add_alias: invalid alias definition");
940 goto bad;
943 a->a_name = g_strdup(alias);
944 a->a_uri = g_strdup(l);
946 DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri);
948 TAILQ_INSERT_TAIL(&aliases, a, entry);
950 return (0);
951 bad:
952 if (a)
953 g_free(a);
954 return (1);
957 void
958 walk_alias(struct settings *s,
959 void (*cb)(struct settings *, char *, void *), void *cb_args)
961 struct alias *a;
962 char *str;
964 if (s == NULL || cb == NULL) {
965 show_oops(NULL, "walk_alias invalid parameters");
966 return;
969 TAILQ_FOREACH(a, &aliases, entry) {
970 str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri);
971 cb(s, str, cb_args);
972 g_free(str);
977 add_mime_type(struct settings *s, char *line)
979 char *mime_type;
980 char *l;
981 struct mime_type *m = NULL;
982 int downloadfirst = 0;
984 /* XXX this could be smarter */
986 if (line == NULL || strlen(line) == 0) {
987 show_oops(NULL, "add_mime_type invalid parameters");
988 return (1);
991 l = line;
992 if (*l == '@') {
993 downloadfirst = 1;
994 l++;
996 m = g_malloc(sizeof(*m));
998 if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) {
999 show_oops(NULL, "add_mime_type: invalid mime_type");
1000 goto bad;
1002 if (mime_type[strlen(mime_type) - 1] == '*') {
1003 mime_type[strlen(mime_type) - 1] = '\0';
1004 m->mt_default = 1;
1005 } else
1006 m->mt_default = 0;
1008 if (strlen(mime_type) == 0 || strlen(l) == 0) {
1009 show_oops(NULL, "add_mime_type: invalid mime_type");
1010 goto bad;
1013 m->mt_type = g_strdup(mime_type);
1014 m->mt_action = g_strdup(l);
1015 m->mt_download = downloadfirst;
1017 DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n",
1018 m->mt_type, m->mt_action, m->mt_default);
1020 TAILQ_INSERT_TAIL(&mtl, m, entry);
1022 return (0);
1023 bad:
1024 if (m)
1025 g_free(m);
1026 return (1);
1029 void
1030 walk_mime_type(struct settings *s,
1031 void (*cb)(struct settings *, char *, void *), void *cb_args)
1033 struct mime_type *m;
1034 char *str;
1036 if (s == NULL || cb == NULL) {
1037 show_oops(NULL, "walk_mime_type invalid parameters");
1038 return;
1041 TAILQ_FOREACH(m, &mtl, entry) {
1042 str = g_strdup_printf("%s%s --> %s",
1043 m->mt_type,
1044 m->mt_default ? "*" : "",
1045 m->mt_action);
1046 cb(s, str, cb_args);
1047 g_free(str);
1051 /* inherent to GTK not all keys will be caught at all times */
1052 /* XXX sort key bindings */
1053 struct key_binding keys[] = {
1054 { "command_mode", 0, 1, GDK_Escape },
1055 { "insert_mode", 0, 0, GDK_i },
1056 { "cookiejar", MOD1, 1, GDK_j },
1057 { "downloadmgr", MOD1, 1, GDK_d },
1058 { "history", MOD1, 1, GDK_h },
1059 { "print", CTRL, 1, GDK_p },
1060 { "search", 0, 0, GDK_slash },
1061 { "searchb", 0, 0, GDK_question },
1062 { "statustoggle", CTRL, 1, GDK_n },
1063 { "command", 0, 0, GDK_colon },
1064 { "qa", CTRL, 1, GDK_q },
1065 { "restart", MOD1, 1, GDK_q },
1066 { "js toggle", CTRL, 1, GDK_j },
1067 { "plugin toggle", MOD1, 1, GDK_p },
1068 { "cookie toggle", MOD1, 1, GDK_c },
1069 { "togglesrc", CTRL, 1, GDK_s },
1070 { "yankuri", 0, 0, GDK_y },
1071 { "pasteuricur", 0, 0, GDK_p },
1072 { "pasteurinew", 0, 0, GDK_P },
1073 { "toplevel toggle", 0, 1, GDK_F4 },
1074 { "help", 0, 1, GDK_F1 },
1075 { "run_script", MOD1, 1, GDK_r },
1076 { "proxy toggle", 0, 1, GDK_F2 },
1077 { "editelement", CTRL, 1, GDK_i },
1078 { "passthrough", CTRL, 1, GDK_z },
1079 { "modurl", CTRL, 1, GDK_Return },
1081 /* search */
1082 { "searchnext", 0, 0, GDK_n },
1083 { "searchprevious", 0, 0, GDK_N },
1085 /* focus */
1086 { "focusaddress", 0, 1, GDK_F6 },
1087 { "focussearch", 0, 1, GDK_F7 },
1089 /* hinting */
1090 { "hinting", 0, 0, GDK_f },
1091 { "hinting", 0, 0, GDK_period },
1092 { "hinting_newtab", SHFT, 0, GDK_F },
1093 { "hinting_newtab", 0, 0, GDK_comma },
1095 /* custom stylesheet */
1096 { "userstyle", 0, 0, GDK_s },
1097 { "userstyle_global", SHFT, 0, GDK_S },
1099 /* navigation */
1100 { "goback", 0, 0, GDK_BackSpace },
1101 { "goback", MOD1, 1, GDK_Left },
1102 { "goforward", SHFT, 1, GDK_BackSpace },
1103 { "goforward", MOD1, 1, GDK_Right },
1104 { "reload", 0, 1, GDK_F5 },
1105 { "reload", CTRL, 1, GDK_r },
1106 { "reload", CTRL, 1, GDK_l },
1107 { "favorites", MOD1, 1, GDK_f },
1109 /* vertical movement */
1110 { "scrolldown", 0, 0, GDK_j },
1111 { "scrolldown", 0, 0, GDK_Down },
1112 { "scrollup", 0, 0, GDK_Up },
1113 { "scrollup", 0, 0, GDK_k },
1114 { "scrollbottom", 0, 0, GDK_G },
1115 { "scrollbottom", 0, 0, GDK_End },
1116 { "scrolltop", 0, 0, GDK_Home },
1117 { "scrollpagedown", 0, 0, GDK_space },
1118 { "scrollpagedown", CTRL, 1, GDK_f },
1119 { "scrollhalfdown", CTRL, 1, GDK_d },
1120 { "scrollpagedown", 0, 0, GDK_Page_Down },
1121 { "scrollpageup", 0, 0, GDK_Page_Up },
1122 { "scrollpageup", CTRL, 1, GDK_b },
1123 { "scrollhalfup", CTRL, 1, GDK_u },
1124 /* horizontal movement */
1125 { "scrollright", 0, 0, GDK_l },
1126 { "scrollright", 0, 0, GDK_Right },
1127 { "scrollleft", 0, 0, GDK_Left },
1128 { "scrollleft", 0, 0, GDK_h },
1129 { "scrollfarright", 0, 0, GDK_dollar },
1130 { "scrollfarleft", 0, 0, GDK_0 },
1132 /* tabs */
1133 { "tabnew", CTRL, 1, GDK_t },
1134 { "999tabnew", CTRL, 1, GDK_T },
1135 { "tabclose", CTRL, 1, GDK_w },
1136 { "tabundoclose", 0, 0, GDK_U },
1137 { "tabnext 1", CTRL, 1, GDK_1 },
1138 { "tabnext 2", CTRL, 1, GDK_2 },
1139 { "tabnext 3", CTRL, 1, GDK_3 },
1140 { "tabnext 4", CTRL, 1, GDK_4 },
1141 { "tabnext 5", CTRL, 1, GDK_5 },
1142 { "tabnext 6", CTRL, 1, GDK_6 },
1143 { "tabnext 7", CTRL, 1, GDK_7 },
1144 { "tabnext 8", CTRL, 1, GDK_8 },
1145 { "tabnext 9", CTRL, 1, GDK_9 },
1146 { "tabfirst", CTRL, 1, GDK_less },
1147 { "tablast", CTRL, 1, GDK_greater },
1148 { "tabprevious", CTRL, 1, GDK_Left },
1149 { "tabnext", CTRL, 1, GDK_Right },
1150 { "focusout", CTRL, 1, GDK_minus },
1151 { "focusin", CTRL, 1, GDK_plus },
1152 { "focusin", CTRL, 1, GDK_equal },
1153 { "focusreset", CTRL, 1, GDK_0 },
1155 /* command aliases (handy when -S flag is used) */
1156 { ":open ", 0, 1, GDK_F9 },
1157 { ":open <uri>", 0, 1, GDK_F10 },
1158 { ":tabnew ", 0, 1, GDK_F11 },
1159 { ":tabnew <uri>", 0, 1, GDK_F12 },
1162 void
1163 walk_kb(struct settings *s,
1164 void (*cb)(struct settings *, char *, void *), void *cb_args)
1166 struct key_binding *k;
1167 char str[1024];
1169 if (s == NULL || cb == NULL) {
1170 show_oops(NULL, "walk_kb invalid parameters");
1171 return;
1174 TAILQ_FOREACH(k, &kbl, entry) {
1175 if (k->cmd == NULL)
1176 continue;
1177 str[0] = '\0';
1179 /* sanity */
1180 if (gdk_keyval_name(k->key) == NULL)
1181 continue;
1183 strlcat(str, k->cmd, sizeof str);
1184 strlcat(str, ",", sizeof str);
1186 if (k->mask & GDK_SHIFT_MASK)
1187 strlcat(str, "S-", sizeof str);
1188 if (k->mask & GDK_CONTROL_MASK)
1189 strlcat(str, "C-", sizeof str);
1190 if (k->mask & GDK_MOD1_MASK)
1191 strlcat(str, "M1-", sizeof str);
1192 if (k->mask & GDK_MOD2_MASK)
1193 strlcat(str, "M2-", sizeof str);
1194 if (k->mask & GDK_MOD3_MASK)
1195 strlcat(str, "M3-", sizeof str);
1196 if (k->mask & GDK_MOD4_MASK)
1197 strlcat(str, "M4-", sizeof str);
1198 if (k->mask & GDK_MOD5_MASK)
1199 strlcat(str, "M5-", sizeof str);
1201 strlcat(str, gdk_keyval_name(k->key), sizeof str);
1202 cb(s, str, cb_args);
1206 void
1207 init_keybindings(void)
1209 int i;
1210 struct key_binding *k;
1212 for (i = 0; i < LENGTH(keys); i++) {
1213 k = g_malloc0(sizeof *k);
1214 k->cmd = keys[i].cmd;
1215 k->mask = keys[i].mask;
1216 k->use_in_entry = keys[i].use_in_entry;
1217 k->key = keys[i].key;
1218 TAILQ_INSERT_HEAD(&kbl, k, entry);
1220 DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n",
1221 k->cmd ? k->cmd : "unnamed key");
1225 void
1226 keybinding_clearall(void)
1228 struct key_binding *k, *next;
1230 for (k = TAILQ_FIRST(&kbl); k; k = next) {
1231 next = TAILQ_NEXT(k, entry);
1232 if (k->cmd == NULL)
1233 continue;
1235 DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n",
1236 k->cmd ? k->cmd : "unnamed key");
1237 TAILQ_REMOVE(&kbl, k, entry);
1238 g_free(k);
1243 keybinding_add(char *cmd, char *key, int use_in_entry)
1245 struct key_binding *k;
1246 guint keyval, mask = 0;
1247 int i;
1249 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key);
1251 /* Keys which are to be used in entry have been prefixed with an
1252 * exclamation mark. */
1253 if (use_in_entry)
1254 key++;
1256 /* find modifier keys */
1257 if (strstr(key, "S-"))
1258 mask |= GDK_SHIFT_MASK;
1259 if (strstr(key, "C-"))
1260 mask |= GDK_CONTROL_MASK;
1261 if (strstr(key, "M1-"))
1262 mask |= GDK_MOD1_MASK;
1263 if (strstr(key, "M2-"))
1264 mask |= GDK_MOD2_MASK;
1265 if (strstr(key, "M3-"))
1266 mask |= GDK_MOD3_MASK;
1267 if (strstr(key, "M4-"))
1268 mask |= GDK_MOD4_MASK;
1269 if (strstr(key, "M5-"))
1270 mask |= GDK_MOD5_MASK;
1272 /* find keyname */
1273 for (i = strlen(key) - 1; i > 0; i--)
1274 if (key[i] == '-')
1275 key = &key[i + 1];
1277 /* validate keyname */
1278 keyval = gdk_keyval_from_name(key);
1279 if (keyval == GDK_VoidSymbol) {
1280 warnx("invalid keybinding name %s", key);
1281 return (1);
1283 /* must run this test too, gtk+ doesn't handle 10 for example */
1284 if (gdk_keyval_name(keyval) == NULL) {
1285 warnx("invalid keybinding name %s", key);
1286 return (1);
1289 /* Remove eventual dupes. */
1290 TAILQ_FOREACH(k, &kbl, entry)
1291 if (k->key == keyval && k->mask == mask) {
1292 TAILQ_REMOVE(&kbl, k, entry);
1293 g_free(k);
1294 break;
1297 /* add keyname */
1298 k = g_malloc0(sizeof *k);
1299 k->cmd = g_strdup(cmd);
1300 k->mask = mask;
1301 k->use_in_entry = use_in_entry;
1302 k->key = keyval;
1304 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n",
1305 k->cmd,
1306 k->mask,
1307 k->use_in_entry,
1308 k->key);
1309 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n",
1310 k->cmd, gdk_keyval_name(keyval));
1312 TAILQ_INSERT_HEAD(&kbl, k, entry);
1314 return (0);
1318 cmd_alias_add(char *alias, char *cmd)
1320 struct cmd_alias *c;
1322 /* XXX */
1323 TAILQ_FOREACH(c, &cal, entry)
1324 if (!strcmp((alias), c->alias)) {
1325 TAILQ_REMOVE(&cal, c, entry);
1326 g_free(c);
1329 c = g_malloc(sizeof (struct cmd_alias));
1330 c->alias = g_strchug(g_strdup(alias));
1331 c->cmd = g_strchug(g_strdup(cmd));
1333 DNPRINTF(XT_D_CUSTOM_URI, "cmd_alias_add: %s %s\n", c->alias, c->cmd);
1335 TAILQ_INSERT_HEAD(&cal, c, entry);
1336 return (0);
1340 custom_uri_add(char *uri, char *cmd)
1342 struct custom_uri *u;
1344 TAILQ_FOREACH(u, &cul, entry)
1345 if (!strcmp((uri), u->uri) && !strcmp(cmd, u->cmd)) {
1346 TAILQ_REMOVE(&cul, u, entry);
1347 g_free(u);
1350 u = g_malloc(sizeof (struct custom_uri));
1351 u->uri = g_strdup(uri);
1352 expand_tilde(u->cmd, sizeof u->cmd, cmd);
1354 DNPRINTF(XT_D_CUSTOM_URI, "custom_uri_add: %s %s\n", u->uri, u->cmd);
1356 /* don't check here if the script is valid, wait until running it */
1357 TAILQ_INSERT_HEAD(&cul, u, entry);
1358 return (0);
1362 add_kb(struct settings *s, char *entry)
1364 char *kb, *key;
1366 DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry);
1368 /* clearall is special */
1369 if (!strcmp(entry, "clearall")) {
1370 keybinding_clearall();
1371 return (0);
1374 kb = strstr(entry, ",");
1375 if (kb == NULL)
1376 return (1);
1377 *kb = '\0';
1378 key = kb + 1;
1380 return (keybinding_add(entry, key, key[0] == '!'));
1384 add_custom_uri(struct settings *s, char *entry)
1386 char *uri, *cmd;
1388 DNPRINTF(XT_D_CUSTOM_URI, "add_custom_uri: %s\n", entry);
1390 uri = strstr(entry, ",");
1391 if (uri == NULL)
1392 return (1);
1393 *uri = '\0';
1394 cmd = uri + 1;
1396 return (custom_uri_add(entry, cmd));
1399 void
1400 walk_custom_uri(struct settings *s,
1401 void (*cb)(struct settings *, char *, void *), void *cb_args)
1403 struct custom_uri *u;
1404 char buf[1024];
1406 if (s == NULL || cb == NULL) {
1407 show_oops(NULL, "walk_custom_uri invalid parameters");
1408 return;
1411 TAILQ_FOREACH(u, &cul, entry) {
1412 snprintf(buf, sizeof buf, "%s,%s", u->uri, u->cmd);
1413 cb(s, buf, cb_args);
1418 add_ua(struct settings *s, char *value)
1420 struct user_agent *ua;
1421 static int ua_count = 0;
1423 ua = g_malloc(sizeof *ua);
1424 ua->id = ua_count++;
1425 ua->value = g_strdup(value);
1427 RB_INSERT(user_agent_list, &ua_list, ua);
1429 return (0);
1433 void
1434 walk_ua(struct settings *s,
1435 void (*cb)(struct settings *, char *, void *), void *cb_args)
1437 struct user_agent *ua;
1439 if (s == NULL || cb == NULL) {
1440 show_oops(NULL, "walk_ua invalid parameters");
1441 return;
1444 RB_FOREACH(ua, user_agent_list, &ua_list)
1445 cb(s, ua->value, cb_args);
1449 add_http_accept(struct settings *s, char *value)
1451 struct http_accept *ha;
1452 static int ha_count = 0;
1454 ha = g_malloc(sizeof *ha);
1455 ha->id = ha_count++;
1456 ha->value = g_strdup(value);
1458 RB_INSERT(http_accept_list, &ha_list, ha);
1460 return (0);
1463 void
1464 walk_http_accept(struct settings *s,
1465 void (*cb)(struct settings *, char *, void *), void *cb_args)
1467 struct http_accept *ha;
1469 if (s == NULL || cb == NULL) {
1470 show_oops(NULL, "%s: invalid parameters", __func__);
1471 return;
1474 RB_FOREACH(ha, http_accept_list, &ha_list)
1475 cb(s, ha->value, cb_args);
1479 add_cmd_alias(struct settings *s, char *entry)
1481 char *alias, *cmd;
1483 DNPRINTF(XT_D_CMD_ALIAS, "add_cmd_alias: %s\n", entry);
1485 alias = strstr(entry, ",");
1486 if (alias == NULL)
1487 return (1);
1488 *alias = '\0';
1489 cmd = alias + 1;
1491 return (cmd_alias_add(entry, cmd));
1494 void
1495 walk_cmd_alias(struct settings *s,
1496 void (*cb)(struct settings *, char *, void *), void *cb_args)
1498 struct cmd_alias *c;
1499 char buf[1024];
1501 if (s == NULL || cb == NULL) {
1502 show_oops(NULL, "walk_cmd_alias invalid parameters");
1503 return;
1506 TAILQ_FOREACH(c, &cal, entry) {
1507 snprintf(buf, sizeof buf, "%s --> %s", c->alias, c->cmd);
1508 cb(s, buf, cb_args);
1513 set_allow_insecure_content(char *value)
1515 struct tab *t;
1516 int tmp;
1517 const char *errstr;
1519 if (value == NULL || strlen(value) == 0)
1520 allow_insecure_content = XT_DS_ALLOW_INSECURE_CONTENT;
1521 else {
1522 tmp = strtonum(value, 0, 1, &errstr);
1523 if (errstr)
1524 return (-1);
1525 allow_insecure_content = tmp;
1527 TAILQ_FOREACH(t, &tabs, entry)
1528 if (is_g_object_setting(G_OBJECT(t->settings),
1529 "enable-display-of-insecure-content")) {
1530 g_object_set(G_OBJECT(t->settings),
1531 "enable-display-of-insecure-content",
1532 allow_insecure_content, (char *)NULL);
1533 webkit_web_view_set_settings(t->wv, t->settings);
1535 return (0);
1539 set_allow_insecure_scripts(char *value)
1541 struct tab *t;
1542 int tmp;
1543 const char *errstr;
1545 if (value == NULL || strlen(value) == 0)
1546 allow_insecure_scripts = XT_DS_ALLOW_INSECURE_SCRIPTS;
1547 else {
1548 tmp = strtonum(value, 0, 1, &errstr);
1549 if (errstr)
1550 return (-1);
1551 allow_insecure_scripts = tmp;
1553 TAILQ_FOREACH(t, &tabs, entry)
1554 if (is_g_object_setting(G_OBJECT(t->settings),
1555 "enable-running-of-insecure-content")) {
1556 g_object_set(G_OBJECT(t->settings),
1557 "enable-running-of-insecure-content",
1558 allow_insecure_scripts, (char *)NULL);
1559 webkit_web_view_set_settings(t->wv, t->settings);
1561 return (0);
1565 set_auto_load_images(char *value)
1567 struct tab *t;
1568 int tmp;
1569 const char *errstr;
1571 if (value == NULL || strlen(value) == 0)
1572 auto_load_images = XT_DS_AUTO_LOAD_IMAGES;
1573 else {
1574 tmp = strtonum(value, 0, 1, &errstr);
1575 if (errstr)
1576 return (-1);
1577 auto_load_images = tmp;
1579 TAILQ_FOREACH(t, &tabs, entry) {
1580 g_object_set(G_OBJECT(t->settings),
1581 "auto-load-images", auto_load_images, (char *)NULL);
1582 webkit_web_view_set_settings(t->wv, t->settings);
1584 return (0);
1588 set_autofocus_onload(char *value)
1590 int tmp;
1591 const char *errstr;
1593 if (value == NULL || strlen(value) == 0)
1594 autofocus_onload = XT_DS_AUTOFOCUS_ONLOAD;
1595 else {
1596 tmp = strtonum(value, 0, 1, &errstr);
1597 if (errstr)
1598 return (-1);
1599 autofocus_onload = tmp;
1601 return (0);
1605 set_ctrl_click_focus(char *value)
1607 int tmp;
1608 const char *errstr;
1610 if (value == NULL || strlen(value) == 0)
1611 ctrl_click_focus = XT_DS_CTRL_CLICK_FOCUS;
1612 else {
1613 tmp = strtonum(value, 0, 1, &errstr);
1614 if (errstr)
1615 return (-1);
1616 ctrl_click_focus = tmp;
1618 return (0);
1622 set_download_notifications(char *value)
1624 int tmp;
1625 const char *errstr;
1627 if (value == NULL || strlen(value) == 0)
1628 download_notifications = XT_DS_DOWNLOAD_NOTIFICATIONS;
1629 else {
1630 tmp = strtonum(value, 0, 1, &errstr);
1631 if (errstr)
1632 return (-1);
1633 download_notifications = tmp;
1635 return (0);
1639 set_enable_autoscroll(char *value)
1641 int tmp;
1642 const char *errstr;
1644 if (value == NULL || strlen(value) == 0)
1645 enable_autoscroll = XT_DS_ENABLE_AUTOSCROLL;
1646 else {
1647 tmp = strtonum(value, 0, 1, &errstr);
1648 if (errstr)
1649 return (-1);
1650 enable_autoscroll = tmp;
1652 return (0);
1656 set_enable_cookie_whitelist(char *value)
1658 int tmp;
1659 const char *errstr;
1661 if (value == NULL || strlen(value) == 0)
1662 enable_cookie_whitelist = XT_DS_ENABLE_COOKIE_WHITELIST;
1663 else {
1664 tmp = strtonum(value, 0, 1, &errstr);
1665 if (errstr)
1666 return (-1);
1667 enable_cookie_whitelist = tmp;
1669 return (0);
1673 set_enable_js_autorun(char *value)
1675 int tmp;
1676 const char *errstr;
1678 if (value == NULL || strlen(value) == 0)
1679 enable_js_autorun = XT_DS_ENABLE_JS_AUTORUN;
1680 else {
1681 tmp = strtonum(value, 0, 1, &errstr);
1682 if (errstr)
1683 return (-1);
1684 enable_js_autorun = tmp;
1686 return (0);
1690 set_enable_js_whitelist(char *value)
1692 int tmp;
1693 const char *errstr;
1695 if (value == NULL || strlen(value) == 0)
1696 enable_js_whitelist = XT_DS_ENABLE_JS_WHITELIST;
1697 else {
1698 tmp = strtonum(value, 0, 1, &errstr);
1699 if (errstr)
1700 return (-1);
1701 enable_js_whitelist = tmp;
1703 return (0);
1707 set_enable_favicon_entry(char *value)
1709 int tmp;
1710 const char *errstr;
1712 if (value == NULL || strlen(value) == 0)
1713 enable_favicon_entry = XT_DS_ENABLE_FAVICON_ENTRY;
1714 else {
1715 tmp = strtonum(value, 0, 1, &errstr);
1716 if (errstr)
1717 return (-1);
1718 enable_favicon_entry = tmp;
1720 return (0);
1724 set_enable_favicon_tabs(char *value)
1726 int tmp;
1727 const char *errstr;
1729 if (value == NULL || strlen(value) == 0)
1730 enable_favicon_tabs = XT_DS_ENABLE_FAVICON_TABS;
1731 else {
1732 tmp = strtonum(value, 0, 1, &errstr);
1733 if (errstr)
1734 return (-1);
1735 enable_favicon_tabs = tmp;
1737 return (0);
1741 set_enable_localstorage(char *value)
1743 struct tab *t;
1744 int tmp;
1745 const char *errstr;
1747 if (value == NULL || strlen(value) == 0)
1748 enable_localstorage = XT_DS_ENABLE_LOCALSTORAGE;
1749 else {
1750 tmp = strtonum(value, 0, 1, &errstr);
1751 if (errstr)
1752 return (-1);
1753 enable_localstorage = tmp;
1755 TAILQ_FOREACH(t, &tabs, entry)
1756 g_object_set(G_OBJECT(t->settings),
1757 "enable-html5-local-storage", enable_localstorage,
1758 (char *)NULL);
1759 return (0);
1763 set_enable_plugins(char *value)
1765 struct tab *t;
1766 int tmp;
1767 const char *errstr;
1769 if (value == NULL || strlen(value) == 0)
1770 enable_plugins = XT_DS_ENABLE_PLUGINS;
1771 else {
1772 tmp = strtonum(value, 0, 1, &errstr);
1773 if (errstr)
1774 return (-1);
1775 enable_plugins = tmp;
1777 TAILQ_FOREACH(t, &tabs, entry)
1778 g_object_set(G_OBJECT(t->settings), "enable-plugins",
1779 enable_plugins, (char *)NULL);
1780 return (0);
1784 set_enable_plugin_whitelist(char *value)
1786 int tmp;
1787 const char *errstr;
1789 if (value == NULL || strlen(value) == 0)
1790 enable_plugin_whitelist = XT_DS_ENABLE_PLUGIN_WHITELIST;
1791 else {
1792 tmp = strtonum(value, 0, 1, &errstr);
1793 if (errstr)
1794 return (-1);
1795 enable_plugin_whitelist = tmp;
1797 return (0);
1801 set_enable_scripts(char *value)
1803 struct tab *t;
1804 int tmp;
1805 const char *errstr;
1807 if (value == NULL || strlen(value) == 0)
1808 enable_scripts = XT_DS_ENABLE_SCRIPTS;
1809 else {
1810 tmp = strtonum(value, 0, 1, &errstr);
1811 if (errstr)
1812 return (-1);
1813 enable_scripts = tmp;
1815 TAILQ_FOREACH(t, &tabs, entry)
1816 g_object_set(G_OBJECT(t->settings), "enable-scripts",
1817 enable_scripts, (char *)NULL);
1818 return (0);
1822 set_enable_spell_checking(char *value)
1824 struct tab *t;
1825 int tmp;
1826 const char *errstr;
1828 if (value == NULL || strlen(value) == 0)
1829 enable_spell_checking = XT_DS_ENABLE_SPELL_CHECKING;
1830 else {
1831 tmp = strtonum(value, 0, 1, &errstr);
1832 if (errstr)
1833 return (-1);
1834 enable_spell_checking = tmp;
1836 TAILQ_FOREACH(t, &tabs, entry)
1837 g_object_set(G_OBJECT(t->settings), "enable_spell_checking",
1838 enable_spell_checking, (char *)NULL);
1839 return (0);
1843 set_enable_strict_transport(char *value)
1845 int tmp;
1846 const char *errstr;
1848 if (value == NULL || strlen(value) == 0)
1849 enable_strict_transport = XT_DS_ENABLE_STRICT_TRANSPORT;
1850 else {
1851 tmp = strtonum(value, 0, 1, &errstr);
1852 if (errstr)
1853 return (-1);
1854 enable_strict_transport = tmp;
1856 return (0);
1859 #if 0
1861 * XXX: this is currently broken. Need to figure out what to do with
1862 * this. Problemm is set_encoding will refresh the tab it's run on, so
1863 * we can either put a big fat warning in the manpage and refresh every
1864 * single open tab with the new encoding or scrap it as a runtime
1865 * setting.
1868 set_encoding_rt(char *value)
1870 struct karg args = {0};
1872 if (value == NULL || strlen(value) == 0)
1873 return (-1);
1874 if (encoding)
1875 g_free(encoding);
1876 encoding = g_strdup(value);
1877 args.s = encoding;
1878 set_encoding(get_current_tab(), &args);
1879 return (0);
1881 #endif
1884 set_guess_search(char *value)
1886 int tmp;
1887 const char *errstr;
1889 if (value == NULL || strlen(value) == 0)
1890 guess_search = XT_DS_GUESS_SEARCH;
1891 else {
1892 tmp = strtonum(value, 0, 1, &errstr);
1893 if (errstr)
1894 return (-1);
1895 guess_search = tmp;
1897 return (0);
1901 set_read_only_cookies(char *value)
1903 int tmp;
1904 const char *errstr;
1906 if (value == NULL || strlen(value) == 0)
1907 read_only_cookies = XT_DS_READ_ONLY_COOKIES;
1908 else {
1909 tmp = strtonum(value, 0, 1, &errstr);
1910 if (errstr)
1911 return (-1);
1912 read_only_cookies = tmp;
1914 g_object_set(G_OBJECT(p_cookiejar), SOUP_COOKIE_JAR_READ_ONLY,
1915 read_only_cookies, (void *)NULL);
1916 return (0);
1919 char *
1920 get_referer(struct settings *s)
1922 if (referer_mode == XT_REFERER_ALWAYS)
1923 return (g_strdup("always"));
1924 if (referer_mode == XT_REFERER_NEVER)
1925 return (g_strdup("never"));
1926 if (referer_mode == XT_REFERER_SAME_DOMAIN)
1927 return (g_strdup("same-domain"));
1928 if (referer_mode == XT_REFERER_SAME_FQDN)
1929 return (g_strdup("same-fqdn"));
1930 if (referer_mode == XT_REFERER_CUSTOM)
1931 return (g_strdup(referer_custom));
1932 return (NULL);
1936 set_referer(struct settings *s, char *value)
1938 if (referer_custom) {
1939 g_free(referer_custom);
1940 referer_custom = NULL;
1943 if (!strcmp(value, "always"))
1944 referer_mode = XT_REFERER_ALWAYS;
1945 else if (!strcmp(value, "never"))
1946 referer_mode = XT_REFERER_NEVER;
1947 else if (!strcmp(value, "same-domain"))
1948 referer_mode = XT_REFERER_SAME_DOMAIN;
1949 else if (!strcmp(value, "same-fqdn"))
1950 referer_mode = XT_REFERER_SAME_FQDN;
1951 else if (!valid_url_type(value)) {
1952 referer_mode = XT_REFERER_CUSTOM;
1953 referer_custom = g_strdup(value);
1954 } else {
1955 /* we've already free'd the custom referer */
1956 if (referer_mode == XT_REFERER_CUSTOM)
1957 referer_mode = XT_REFERER_NEVER;
1958 return (1);
1961 return (0);
1965 set_referer_rt(char *value)
1967 if (value == NULL || strlen(value) == 0) {
1968 if (referer_custom)
1969 g_free(referer_custom);
1970 referer_custom = g_strdup(XT_DS_REFERER_CUSTOM);
1971 referer_mode = XT_DS_REFERER_MODE;
1972 return (0);
1974 return (set_referer(NULL, value));
1977 char *
1978 get_ssl_ca_file(struct settings *s)
1980 if (strlen(ssl_ca_file) == 0)
1981 return (NULL);
1982 return (g_strdup(ssl_ca_file));
1986 set_refresh_interval(char *value)
1988 int tmp;
1989 const char *errstr;
1991 if (value == NULL || strlen(value) == 0)
1992 refresh_interval = XT_DS_REFRESH_INTERVAL;
1993 else {
1994 tmp = strtonum(value, 0, INT_MAX, &errstr);
1995 if (errstr)
1996 return (-1);
1997 refresh_interval = tmp;
1999 return (0);
2003 set_session_autosave(char *value)
2005 int tmp;
2006 const char *errstr;
2008 if (value == NULL || strlen(value) == 0)
2009 session_autosave = XT_DS_SESSION_AUTOSAVE;
2010 else {
2011 tmp = strtonum(value, 0, 1, &errstr);
2012 if (errstr)
2013 return (-1);
2014 session_autosave = tmp;
2016 return (0);
2020 set_session_timeout(char *value)
2022 int tmp;
2023 const char *errstr;
2025 if (value == NULL || strlen(value) == 0)
2026 session_timeout = XT_DS_SESSION_TIMEOUT;
2027 else {
2028 tmp = strtonum(value, 0, INT_MAX, &errstr);
2029 if (errstr)
2030 return (-1);
2031 session_timeout = tmp;
2033 return (0);
2037 set_show_scrollbars(char *value)
2039 struct tab *t;
2040 int tmp;
2041 const char *errstr;
2043 if (value == NULL || strlen(value) == 0)
2044 tmp = XT_DS_SHOW_SCROLLBARS;
2045 else {
2046 tmp = strtonum(value, 0, 1, &errstr);
2047 if (errstr)
2048 return (-1);
2050 show_scrollbars = tmp;
2051 TAILQ_FOREACH(t, &tabs, entry)
2052 if (set_scrollbar_visibility(t, show_scrollbars))
2053 return (-1);
2054 return (0);
2058 set_show_statusbar(char *value)
2060 int tmp;
2061 const char *errstr;
2063 if (value == NULL || strlen(value) == 0)
2064 tmp = XT_DS_SHOW_STATUSBAR;
2065 else {
2066 tmp = strtonum(value, 0, 1, &errstr);
2067 if (errstr)
2068 return (-1);
2070 show_statusbar = tmp;
2071 statusbar_set_visibility();
2072 return (0);
2076 set_show_tabs(char *value)
2078 struct karg args = {0};
2079 int val;
2080 const char *errstr;
2082 if (value == NULL || strlen(value) == 0)
2083 val = XT_DS_SHOW_TABS;
2084 else {
2085 val = strtonum(value, 0, 1, &errstr);
2086 if (errstr)
2087 return (-1);
2089 args.i = val ? XT_TAB_SHOW : XT_TAB_HIDE;
2090 tabaction(get_current_tab(), &args);
2091 return (0);
2095 set_show_url(char *value)
2097 struct karg args = {0};
2098 int val;
2099 const char *errstr;
2101 if (value == NULL || strlen(value) == 0)
2102 val = XT_DS_SHOW_URL;
2103 else {
2104 val = strtonum(value, 0, 1, &errstr);
2105 if (errstr)
2106 return (-1);
2108 args.i = val ? XT_URL_SHOW : XT_URL_HIDE;
2109 urlaction(get_current_tab(), &args);
2110 return (0);
2114 set_spell_check_languages(char *value)
2116 struct tab *t;
2118 if (spell_check_languages)
2119 g_free(spell_check_languages);
2120 if (value == NULL || strlen(value) == 0)
2121 spell_check_languages = g_strdup(XT_DS_SPELL_CHECK_LANGUAGES);
2122 else
2123 spell_check_languages = g_strdup(value);
2124 TAILQ_FOREACH(t, &tabs, entry)
2125 g_object_set(G_OBJECT(t->settings), "spell_checking_languages",
2126 spell_check_languages, (char *)NULL);
2127 return (0);
2131 check_valid_file(char *name)
2133 struct stat sb;
2135 if (name == NULL || stat(name, &sb))
2136 return (-1);
2137 return (0);
2141 set_ssl_ca_file_rt(char *value)
2143 if (value == NULL || strlen(value) == 0) {
2144 strlcpy(ssl_ca_file, XT_DS_SSL_CA_FILE, sizeof ssl_ca_file);
2145 g_object_set(session, SOUP_SESSION_SSL_CA_FILE, "", NULL);
2146 return (0);
2147 } else
2148 return (set_ssl_ca_file(NULL, value));
2152 set_ssl_strict_certs(char *value)
2154 int tmp;
2155 const char *errstr;
2157 if (value == NULL || strlen(value) == 0)
2158 ssl_strict_certs = XT_DS_SSL_STRICT_CERTS;
2159 else {
2160 tmp = strtonum(value, 0, 1, &errstr);
2161 if (errstr)
2162 return (-1);
2163 ssl_strict_certs = tmp;
2165 g_object_set(session, SOUP_SESSION_SSL_STRICT, ssl_strict_certs, NULL);
2166 return (0);
2170 set_external_editor(char *editor)
2172 if (external_editor)
2173 g_free(external_editor);
2174 if (editor == NULL || strlen(editor) == 0)
2175 external_editor = NULL;
2176 else
2177 external_editor = g_strdup(editor);
2178 return (0);
2182 set_fancy_bar(char *value)
2184 struct tab *t;
2185 int tmp;
2186 const char *errstr;
2188 if (value == NULL || strlen(value) == 0)
2189 fancy_bar = 1; /* XXX */
2190 else {
2191 tmp = strtonum(value, 0, 1, &errstr);
2192 if (errstr)
2193 return (-1);
2194 fancy_bar = tmp;
2196 TAILQ_FOREACH(t, &tabs, entry)
2197 if (fancy_bar) {
2198 gtk_widget_show(t->backward);
2199 gtk_widget_show(t->forward);
2200 gtk_widget_show(t->stop);
2201 gtk_widget_show(t->js_toggle);
2202 gtk_widget_show(t->search_entry);
2203 } else {
2204 gtk_widget_hide(t->backward);
2205 gtk_widget_hide(t->forward);
2206 gtk_widget_hide(t->stop);
2207 gtk_widget_hide(t->js_toggle);
2208 gtk_widget_hide(t->search_entry);
2210 return (0);
2213 void
2214 setup_proxy(char *uri)
2216 struct tab *t;
2218 if (proxy_uri) {
2219 g_object_set(session, "proxy_uri", NULL, (char *)NULL);
2220 soup_uri_free(proxy_uri);
2221 proxy_uri = NULL;
2222 TAILQ_FOREACH(t, &tabs, entry)
2223 gtk_entry_set_text(GTK_ENTRY(t->sbe.proxy), "");
2225 if (http_proxy) {
2226 if (http_proxy != uri) {
2227 g_free(http_proxy);
2228 http_proxy = NULL;
2232 if (uri) {
2233 http_proxy = g_strdup(uri);
2234 DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri);
2235 proxy_uri = soup_uri_new(http_proxy);
2236 if (proxy_uri != NULL && SOUP_URI_VALID_FOR_HTTP(proxy_uri)) {
2237 g_object_set(session, "proxy-uri", proxy_uri,
2238 (char *)NULL);
2239 TAILQ_FOREACH(t, &tabs, entry)
2240 gtk_entry_set_text(GTK_ENTRY(t->sbe.proxy),
2241 "proxy");
2246 char *
2247 get_tab_style(struct settings *s)
2249 if (tab_style == XT_TABS_NORMAL)
2250 return (g_strdup("normal"));
2251 else
2252 return (g_strdup("compact"));
2256 set_tab_style(struct settings *s, char *val)
2258 if (!strcmp(val, "normal"))
2259 tab_style = XT_TABS_NORMAL;
2260 else if (!strcmp(val, "compact"))
2261 tab_style = XT_TABS_COMPACT;
2262 else
2263 return (1);
2265 return (0);
2269 set_tab_style_rt(char *value)
2271 struct karg args = {0};
2272 int old_tab_style;
2274 if (value == NULL || strlen(value) == 0) {
2275 if (tab_style == XT_DS_TAB_STYLE)
2276 return (0);
2277 tab_style = XT_TABS_COMPACT;
2278 args.i = XT_TAB_NEXTSTYLE;
2279 } else {
2280 old_tab_style = tab_style;
2281 if (set_tab_style(NULL, value))
2282 return (-1);
2283 if (old_tab_style != tab_style) {
2284 tab_style = old_tab_style;
2285 args.i = XT_TAB_NEXTSTYLE;
2288 tabaction(get_current_tab(), &args);
2289 return (0);
2292 char *
2293 get_statusbar_style(struct settings *s)
2295 if (statusbar_style == XT_STATUSBAR_URL)
2296 return (g_strdup("url"));
2297 else
2298 return (g_strdup("title"));
2302 set_statusbar_style(struct settings *s, char *val)
2304 if (!strcmp(val, "url"))
2305 statusbar_style = XT_STATUSBAR_URL;
2306 else if (!strcmp(val, "title"))
2307 statusbar_style = XT_STATUSBAR_TITLE;
2308 else
2309 return (1);
2311 return (0);
2315 set_statusbar_style_rt(char *value)
2317 struct tab *t;
2318 const gchar *page_uri;
2320 if (value == NULL || strlen(value) == 0) {
2321 if (statusbar_style == XT_DS_STATUSBAR_STYLE)
2322 return (0);
2323 statusbar_style = XT_DS_STATUSBAR_STYLE;
2324 } else {
2325 if (!strcmp(value, "url"))
2326 statusbar_style = XT_STATUSBAR_URL;
2327 else if (!strcmp(value, "title"))
2328 statusbar_style = XT_STATUSBAR_TITLE;
2331 /* apply changes */
2332 TAILQ_FOREACH(t, &tabs, entry) {
2333 if (statusbar_style == XT_STATUSBAR_TITLE)
2334 set_status(t, "%s", get_title(t, FALSE));
2335 else if ((page_uri = get_uri(t)) != NULL)
2336 set_status(t, "%s", page_uri);
2339 return (0);
2343 set_url_regex(char *value)
2345 if (value == NULL || strlen(value) == 0) {
2346 if (url_regex)
2347 g_free(url_regex);
2348 url_regex = g_strdup(XT_DS_URL_REGEX);
2349 } else {
2350 if (regcomp(&url_re, value, REG_EXTENDED | REG_NOSUB))
2351 return (-1);
2352 if (url_regex)
2353 g_free(url_regex);
2354 url_regex = g_strdup(value);
2356 return (0);
2360 set_userstyle(struct settings *s, char *value)
2362 char script[PATH_MAX] = {'\0'};
2363 char *path;
2365 if (userstyle)
2366 g_free(userstyle);
2367 if (value == NULL || strlen(value) == 0) {
2368 path = g_strdup_printf("%s" PS "style.css", resource_dir);
2369 userstyle = g_filename_to_uri(path, NULL, NULL);
2370 g_free(path);
2371 } else {
2372 expand_tilde(script, sizeof script, value);
2373 userstyle = g_filename_to_uri(script, NULL, NULL);
2375 if (stylesheet)
2376 g_free(stylesheet);
2377 stylesheet = g_strdup(userstyle);
2378 return (0);
2381 char *
2382 get_userstyle(struct settings *s)
2384 return (g_filename_from_uri(userstyle, NULL, NULL));
2388 set_userstyle_rt(char *value)
2390 return (set_userstyle(NULL, value));
2394 set_userstyle_global(char *value)
2396 struct karg args = {0};
2397 int tmp, old_style;
2398 const char *errstr;
2400 if (value == NULL || strlen(value) == 0) {
2401 if (userstyle_global == XT_DS_USERSTYLE_GLOBAL)
2402 return (0);
2403 userstyle_global = 1;
2404 args.i = XT_STYLE_GLOBAL;
2405 userstyle_cmd(get_current_tab(), &args);
2406 } else {
2407 old_style = userstyle_global;
2408 tmp = strtonum(value, 0, 1, &errstr);
2409 if (errstr)
2410 return (-1);
2411 if (tmp != old_style) {
2412 args.i = XT_STYLE_GLOBAL;
2413 userstyle_cmd(get_current_tab(), &args);
2416 return (0);
2420 set_warn_cert_changes(char *value)
2422 int tmp;
2423 const char *errstr;
2425 tmp = strtonum(value, 0, 1, &errstr);
2426 if (errstr)
2427 return (-1);
2428 warn_cert_changes = tmp;
2429 return (0);
2432 char *
2433 get_edit_mode(struct settings *s)
2435 if (edit_mode == XT_EM_HYBRID)
2436 return (g_strdup("hybrid"));
2437 else
2438 return (g_strdup("vi"));
2442 set_edit_mode(struct settings *s, char *val)
2444 if (!strcmp(val, "hybrid"))
2445 edit_mode = XT_EM_HYBRID;
2446 else if (!strcmp(val, "vi"))
2447 edit_mode = XT_EM_VI;
2448 else
2449 return (1);
2451 return (0);
2454 char *
2455 get_download_mode(struct settings *s)
2457 switch (download_mode) {
2458 case XT_DM_START:
2459 return (g_strdup("start"));
2460 break;
2461 case XT_DM_ASK:
2462 return (g_strdup("ask"));
2463 break;
2464 case XT_DM_ADD:
2465 return (g_strdup("add"));
2466 break;
2468 return (g_strdup("unknown"));
2472 set_download_mode(struct settings *s, char *val)
2474 if (!strcmp(val, "start"))
2475 download_mode = XT_DM_START;
2476 else if (!strcmp(val, "ask"))
2477 download_mode = XT_DM_ASK;
2478 else if (!strcmp(val, "add"))
2479 download_mode = XT_DM_ADD;
2480 else
2481 return (1);
2483 return (0);
2487 set_download_mode_rt(char *val)
2489 if (val == NULL || strlen(val) == 0)
2490 return (-1);
2491 return (set_download_mode(NULL, val));
2494 char *
2495 get_work_dir(struct settings *s)
2497 if (work_dir[0] == '\0')
2498 return (0);
2499 return (g_strdup(work_dir));
2503 set_work_dir(struct settings *s, char *val)
2505 expand_tilde(work_dir, sizeof work_dir, val);
2506 return (0);
2509 void
2510 walk_cookie_wl(struct settings *s,
2511 void (*cb)(struct settings *, char *, void *), void *cb_args)
2513 struct domain *d;
2515 if (s == NULL || cb == NULL) {
2516 show_oops(NULL, "walk_cookie_wl invalid parameters");
2517 return;
2520 RB_FOREACH_REVERSE(d, domain_list, &c_wl)
2521 cb(s, d->d, cb_args);
2524 void
2525 walk_js_wl(struct settings *s,
2526 void (*cb)(struct settings *, char *, void *), void *cb_args)
2528 struct domain *d;
2530 if (s == NULL || cb == NULL) {
2531 show_oops(NULL, "walk_js_wl invalid parameters");
2532 return;
2535 RB_FOREACH_REVERSE(d, domain_list, &js_wl)
2536 cb(s, d->d, cb_args);
2539 void
2540 walk_pl_wl(struct settings *s,
2541 void (*cb)(struct settings *, char *, void *), void *cb_args)
2543 struct domain *d;
2545 if (s == NULL || cb == NULL) {
2546 show_oops(NULL, "walk_pl_wl invalid parameters");
2547 return;
2550 RB_FOREACH_REVERSE(d, domain_list, &pl_wl)
2551 cb(s, d->d, cb_args);
2555 settings_add(char *var, char *val)
2557 int i, rv, *p;
2558 gfloat *f;
2559 char c[PATH_MAX], **s;
2561 /* get settings */
2562 for (i = 0, rv = 0; i < LENGTH(rs); i++) {
2563 if (strcmp(var, rs[i].name))
2564 continue;
2566 if (!strcmp(var, "include_config")) {
2567 expand_tilde(c, sizeof c, val);
2568 config_parse(c, 0);
2569 rv = 1;
2570 break;
2573 if (rs[i].s) {
2574 if (rs[i].s->set(&rs[i], val))
2575 startpage_add("invalid value for %s: %s", var,
2576 val);
2577 rv = 1;
2578 break;
2579 } else
2580 switch (rs[i].type) {
2581 case XT_S_INT:
2582 p = rs[i].ival;
2583 *p = atoi(val);
2584 rv = 1;
2585 break;
2586 case XT_S_STR:
2587 s = rs[i].sval;
2588 if (s == NULL)
2589 errx(1, "invalid sval for %s",
2590 rs[i].name);
2591 if (*s)
2592 g_free(*s);
2593 *s = g_strdup(val);
2594 rv = 1;
2595 break;
2596 case XT_S_FLOAT:
2597 f = rs[i].fval;
2598 *f = atof(val);
2599 rv = 1;
2600 break;
2601 case XT_S_INVALID:
2602 default:
2603 errx(1, "invalid type for %s", var);
2605 break;
2607 return (rv);
2610 #define WS "\n= \t"
2611 void
2612 config_parse(char *filename, int runtime)
2614 FILE *config, *f;
2615 char *line, *cp, *var, *val;
2616 size_t len, lineno = 0;
2617 int handled;
2618 char file[PATH_MAX];
2619 struct stat sb;
2621 DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename);
2623 if (filename == NULL)
2624 return;
2626 if (runtime && runtime_settings[0] != '\0') {
2627 snprintf(file, sizeof file, "%s" PS "%s",
2628 work_dir, runtime_settings);
2629 if (stat(file, &sb)) {
2630 warnx("runtime file doesn't exist, creating it");
2631 if ((f = fopen(file, "w")) == NULL)
2632 err(1, "runtime");
2633 fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n");
2634 fclose(f);
2636 } else
2637 strlcpy(file, filename, sizeof file);
2639 if ((config = fopen(file, "r")) == NULL) {
2640 warn("config_parse: cannot open %s", filename);
2641 return;
2644 for (;;) {
2645 if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
2646 if (feof(config) || ferror(config))
2647 break;
2649 cp = line;
2650 cp += (long)strspn(cp, WS);
2651 if (cp[0] == '\0') {
2652 /* empty line */
2653 free(line);
2654 continue;
2657 if ((var = strsep(&cp, WS)) == NULL || cp == NULL)
2658 startpage_add("invalid configuration file entry: %s",
2659 line);
2660 else {
2661 cp += (long)strspn(cp, WS);
2663 if ((val = strsep(&cp, "\0")) == NULL)
2664 break;
2666 DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n",
2667 var, val);
2668 handled = settings_add(var, val);
2670 if (handled == 0)
2671 startpage_add("invalid configuration file entry"
2672 ": %s=%s", var, val);
2675 free(line);
2678 fclose(config);
2681 struct settings_args {
2682 char **body;
2683 int i;
2686 void
2687 print_setting(struct settings *s, char *val, void *cb_args)
2689 char *enc_val, *tmp, *color;
2690 struct settings_args *sa = cb_args;
2692 if (sa == NULL)
2693 return;
2695 if (s->flags & XT_SF_RUNTIME)
2696 color = "#22cc22";
2697 else
2698 color = "#cccccc";
2700 enc_val = html_escape(val);
2701 tmp = *sa->body;
2702 *sa->body = g_strdup_printf(
2703 "%s\n<tr>"
2704 "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>"
2705 "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>",
2706 *sa->body,
2707 color,
2708 s->name,
2709 color,
2710 enc_val == NULL ? "" : enc_val
2712 g_free(tmp);
2713 if (enc_val)
2714 g_free(enc_val);
2715 sa->i++;
2719 set_show(struct tab *t, struct karg *args)
2721 char *body, *page, *tmp;
2722 int i = 1;
2723 struct settings_args sa;
2725 bzero(&sa, sizeof sa);
2726 sa.body = &body;
2728 /* body */
2729 body = g_strdup_printf("<div align='center'><table><tr>"
2730 "<th align='left'>Setting</th>"
2731 "<th align='left'>Value</th></tr>\n");
2733 settings_walk(print_setting, &sa);
2734 i = sa.i;
2736 /* small message if there are none */
2737 if (i == 1) {
2738 tmp = body;
2739 body = g_strdup_printf("%s\n<tr><td style='text-align:center'"
2740 "colspan='2'>No settings</td></tr>\n", body);
2741 g_free(tmp);
2744 tmp = body;
2745 body = g_strdup_printf("%s</table></div>", body);
2746 g_free(tmp);
2748 page = get_html_page("Settings", body, "", 0);
2750 g_free(body);
2752 load_webkit_string(t, page, XT_URI_ABOUT_SET);
2754 g_free(page);
2756 return (XT_CB_PASSTHROUGH);
2760 set(struct tab *t, struct karg *args)
2762 char *p, *val;
2763 int i;
2765 if (args == NULL || args->s == NULL)
2766 return (set_show(t, args));
2768 /* strip spaces */
2769 p = g_strstrip(args->s);
2771 if (strlen(p) == 0)
2772 return (set_show(t, args));
2774 /* we got some sort of string */
2775 val = g_strstr_len(p, strlen(p), "=");
2776 if (val) {
2777 *val++ = '\0';
2778 val = g_strstrip(val);
2779 p = g_strchomp(p);
2781 for (i = 0; i < get_settings_size(); i++) {
2782 if (strcmp(rs[i].name, p))
2783 continue;
2785 if (rs[i].activate) {
2786 if (rs[i].activate(val))
2787 show_oops(t, "%s invalid value %s",
2788 p, val);
2789 else
2790 show_oops(t, ":set %s = %s", p, val);
2791 goto done;
2792 } else {
2793 show_oops(t, "not a runtime option: %s", p);
2794 goto done;
2797 show_oops(t, "unknown option: %s", p);
2798 } else {
2799 p = g_strchomp(p);
2801 for (i = 0; i < get_settings_size(); i++) {
2802 if (strcmp(rs[i].name, p))
2803 continue;
2805 /* XXX this could use some cleanup */
2806 switch (rs[i].type) {
2807 case XT_S_INT:
2808 if (rs[i].ival)
2809 show_oops(t, "%s = %d",
2810 rs[i].name, *rs[i].ival);
2811 else if (rs[i].s && rs[i].s->get)
2812 show_oops(t, "%s = %s",
2813 rs[i].name,
2814 rs[i].s->get(&rs[i]));
2815 else if (rs[i].s && rs[i].s->get == NULL)
2816 show_oops(t, "%s = ...", rs[i].name);
2817 else
2818 show_oops(t, "%s = ", rs[i].name);
2819 break;
2820 case XT_S_FLOAT:
2821 if (rs[i].fval)
2822 show_oops(t, "%s = %f",
2823 rs[i].name, *rs[i].fval);
2824 else if (rs[i].s && rs[i].s->get)
2825 show_oops(t, "%s = %s",
2826 rs[i].name,
2827 rs[i].s->get(&rs[i]));
2828 else if (rs[i].s && rs[i].s->get == NULL)
2829 show_oops(t, "%s = ...", rs[i].name);
2830 else
2831 show_oops(t, "%s = ", rs[i].name);
2832 break;
2833 case XT_S_STR:
2834 if (rs[i].sval && *rs[i].sval)
2835 show_oops(t, "%s = %s",
2836 rs[i].name, *rs[i].sval);
2837 else if (rs[i].s && rs[i].s->get)
2838 show_oops(t, "%s = %s",
2839 rs[i].name,
2840 rs[i].s->get(&rs[i]));
2841 else if (rs[i].s && rs[i].s->get == NULL)
2842 show_oops(t, "%s = ...", rs[i].name);
2843 else
2844 show_oops(t, "%s = ", rs[i].name);
2845 break;
2846 default:
2847 show_oops(t, "unknown type for %s", rs[i].name);
2848 goto done;
2851 goto done;
2853 show_oops(t, "unknown option: %s", p);
2855 done:
2856 return (XT_CB_PASSTHROUGH);