Make most of the rest of the settings dynamic.
[xxxterm.git] / settings.c
blob30749e6ed1eb79bb4b76b011e93302d4fbd54e66
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>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <xxxterm.h>
24 /* globals */
25 SoupURI *proxy_uri = NULL;
26 PangoFontDescription *cmd_font;
27 PangoFontDescription *oops_font;
28 PangoFontDescription *statusbar_font;
29 PangoFontDescription *tabbar_font;
30 extern regex_t url_re;
32 /* settings that require restart */
33 int tabless = 0; /* allow only 1 tab */
34 int enable_socket = 0;
35 int single_instance = 0; /* only allow one xxxterm to run */
36 int fancy_bar = 1; /* fancy toolbar */
37 int browser_mode = XT_BM_NORMAL;
38 int gui_mode = XT_GM_CLASSIC;
39 int enable_localstorage = 1;
40 char *statusbar_elems = NULL;
42 /* runtime settings */
43 int show_tabs = 1; /* show tabs on notebook */
44 int tab_style = XT_TABS_NORMAL; /* tab bar style */
45 int show_url = 1; /* show url toolbar on notebook */
46 int show_statusbar = 0; /* vimperator style status bar */
47 int ctrl_click_focus = 0; /* ctrl click gets focus */
48 int cookies_enabled = 1; /* enable cookies */
49 int read_only_cookies = 0; /* enable to not write cookies */
50 int enable_scripts = 1;
51 int enable_plugins = 1;
52 gfloat default_zoom_level = 1.0;
53 char default_script[PATH_MAX];
54 int window_height = 768;
55 int window_width = 1024;
56 int window_maximize = 0;
57 int icon_size = 2; /* 1 = smallest, 2+ = bigger */
58 int refresh_interval = 10; /* download refresh interval */
59 int enable_plugin_whitelist = 0;
60 int enable_cookie_whitelist = 0;
61 int enable_js_whitelist = 0;
62 int session_timeout = 3600; /* cookie session timeout */
63 int cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
64 char *ssl_ca_file = NULL;
65 char *resource_dir = NULL;
66 gboolean ssl_strict_certs = FALSE;
67 gboolean enable_strict_transport = TRUE;
68 int append_next = 1; /* append tab after current tab */
69 char *home = NULL;
70 char *search_string = NULL;
71 char *http_proxy = NULL;
72 char download_dir[PATH_MAX];
73 int download_mode = XT_DM_START;
74 char runtime_settings[PATH_MAX]; /* override of settings */
75 int allow_volatile_cookies = 0;
76 int color_visited_uris = 1;
77 int save_global_history = 0; /* save global history to disk */
78 struct user_agent *user_agent = NULL;
79 int save_rejected_cookies = 0;
80 int session_autosave = 0;
81 int guess_search = 0;
82 int dns_prefetch = FALSE;
83 gint max_connections = 25;
84 gint max_host_connections = 5;
85 gint enable_spell_checking = 0;
86 char *spell_check_languages = NULL;
87 int xterm_workaround = 0;
88 char *url_regex = NULL;
89 int history_autosave = 0;
90 char search_file[PATH_MAX];
91 char command_file[PATH_MAX];
92 char *encoding = NULL;
93 int autofocus_onload = 0;
94 int js_autorun_enabled = 1;
95 int edit_mode = XT_EM_HYBRID;
96 int userstyle_global = 0;
97 int auto_load_images = 1;
98 int enable_autoscroll = 0;
99 int enable_favicon_entry = 1;
100 int enable_favicon_tabs = 0;
101 char *external_editor = NULL;
102 int referer_mode = XT_REFERER_ALWAYS;
103 char *referer_custom = NULL;
105 char *cmd_font_name = NULL;
106 char *oops_font_name = NULL;
107 char *statusbar_font_name = NULL;
108 char *tabbar_font_name = NULL;
110 char *get_download_dir(struct settings *);
111 char *get_default_script(struct settings *);
112 char *get_runtime_dir(struct settings *);
113 char *get_tab_style(struct settings *);
114 char *get_edit_mode(struct settings *);
115 char *get_download_mode(struct settings *);
116 char *get_work_dir(struct settings *);
117 char *get_referer(struct settings *);
119 int add_cookie_wl(struct settings *, char *);
120 int add_js_wl(struct settings *, char *);
121 int add_pl_wl(struct settings *, char *);
122 int add_mime_type(struct settings *, char *);
123 int add_alias(struct settings *, char *);
124 int add_kb(struct settings *, char *);
125 int add_ua(struct settings *, char *);
127 int set_append_next(char *);
128 int set_cmd_font(char *);
129 int set_color_visited_uris(char *);
130 int set_cookie_policy_rt(char *);
131 int set_cookies_enabled(char *);
132 int set_ctrl_click_focus(char *);
133 int set_home(char *);
134 int set_download_dir(struct settings *, char *);
135 int set_default_script(struct settings *, char *);
136 int set_default_script_rt(char *);
137 int set_default_zoom_level(char *);
138 int set_enable_cookie_whitelist(char *);
139 int set_enable_js_whitelist(char *);
140 int set_enable_localstorage(char *);
141 int set_enable_plugins(char *);
142 int set_enable_plugin_whitelist(char *);
143 int set_enable_scripts(char *);
144 int set_enable_spell_checking(char *);
145 int set_enable_strict_transport(char *);
146 int set_encoding_rt(char *);
147 int set_runtime_dir(struct settings *, char *);
148 int set_tabbar_font(char *value);
149 int set_tab_style(struct settings *, char *);
150 int set_tab_style_rt(char *);
151 int set_edit_mode(struct settings *, char *);
152 int set_work_dir(struct settings *, char *);
153 int set_auto_load_images(char *);
154 int set_enable_autoscroll(char *);
155 int set_enable_favicon_entry(char *);
156 int set_enable_favicon_tabs(char *);
157 int set_guess_search(char *);
158 int set_download_mode(struct settings *, char *);
159 int set_download_mode_rt(char *);
160 int set_oops_font(char *);
161 int set_read_only_cookies(char *);
162 int set_referer(struct settings *, char *);
163 int set_referer_rt(char *);
164 int set_refresh_interval(char *);
165 int set_search_string(char *s);
166 int set_session_autosave(char *);
167 int set_session_timeout(char *);
168 int set_show_statusbar(char *);
169 int set_show_tabs(char *);
170 int set_show_url(char *);
171 int set_spell_check_languages(char *);
172 int set_ssl_ca_file_rt(char *);
173 int set_ssl_strict_certs(char *);
174 int set_statusbar_font(char *);
175 int set_url_regex(char *);
176 int set_userstyle_global(char *);
177 int set_external_editor(char *);
178 int set_xterm_workaround(char *);
180 void walk_mime_type(struct settings *, void (*)(struct settings *,
181 char *, void *), void *);
182 void walk_alias(struct settings *, void (*)(struct settings *,
183 char *, void *), void *);
184 void walk_cookie_wl(struct settings *, void (*)(struct settings *,
185 char *, void *), void *);
186 void walk_js_wl(struct settings *, void (*)(struct settings *,
187 char *, void *), void *);
188 void walk_pl_wl(struct settings *, void (*)(struct settings *,
189 char *, void *), void *);
190 void walk_kb(struct settings *, void (*)(struct settings *, char *,
191 void *), void *);
192 void walk_ua(struct settings *, void (*)(struct settings *, char *,
193 void *), void *);
196 set_http_proxy(char *proxy)
198 SoupURI *uri;
200 if (proxy == NULL)
201 return (1);
203 /* see if we need to clear it instead */
204 if (strlen(proxy) == 0) {
205 setup_proxy(NULL);
206 return (0);
209 uri = soup_uri_new(proxy);
210 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
211 return (1);
213 setup_proxy(proxy);
215 soup_uri_free(uri);
217 return (0);
220 struct special {
221 int (*set)(struct settings *, char *);
222 char *(*get)(struct settings *);
223 void (*walk)(struct settings *,
224 void (*cb)(struct settings *, char *, void *),
225 void *);
228 struct special s_browser_mode = {
229 set_browser_mode,
230 get_browser_mode,
231 NULL
234 struct special s_gui_mode = {
235 set_gui_mode,
236 get_gui_mode,
237 NULL
240 struct special s_cookie = {
241 set_cookie_policy,
242 get_cookie_policy,
243 NULL
246 struct special s_alias = {
247 add_alias,
248 NULL,
249 walk_alias
252 struct special s_mime = {
253 add_mime_type,
254 NULL,
255 walk_mime_type
258 struct special s_js = {
259 add_js_wl,
260 NULL,
261 walk_js_wl
264 struct special s_pl = {
265 add_pl_wl,
266 NULL,
267 walk_pl_wl
270 struct special s_kb = {
271 add_kb,
272 NULL,
273 walk_kb
276 struct special s_cookie_wl = {
277 add_cookie_wl,
278 NULL,
279 walk_cookie_wl
282 struct special s_default_script = {
283 set_default_script,
284 get_default_script,
285 NULL
288 struct special s_download_dir = {
289 set_download_dir,
290 get_download_dir,
291 NULL
294 struct special s_work_dir = {
295 set_work_dir,
296 get_work_dir,
297 NULL
300 struct special s_tab_style = {
301 set_tab_style,
302 get_tab_style,
303 NULL
306 struct special s_edit_mode = {
307 set_edit_mode,
308 get_edit_mode,
309 NULL
312 struct special s_download_mode = {
313 set_download_mode,
314 get_download_mode,
315 NULL
318 struct special s_ua = {
319 add_ua,
320 NULL,
321 walk_ua
324 struct special s_referer = {
325 set_referer,
326 get_referer,
327 NULL
330 struct settings rs[] = {
331 { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL, NULL, NULL},
332 { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL, NULL, NULL },
333 { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode, NULL, NULL },
334 { "gui_mode", XT_S_INT, 0, NULL, NULL,&s_gui_mode, NULL, NULL },
335 { "color_visited_uris", XT_S_INT, 0, &color_visited_uris , NULL, NULL, NULL, set_color_visited_uris },
336 { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie, NULL, set_cookie_policy_rt },
337 { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL, NULL, set_cookies_enabled },
338 { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL, NULL, set_ctrl_click_focus },
339 { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level, set_default_zoom_level },
340 { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script, NULL, set_default_script_rt },
341 { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir, NULL, NULL },
342 { "download_mode", XT_S_STR, 0, NULL, NULL,&s_download_mode, NULL, set_download_mode_rt },
343 { "edit_mode", XT_S_STR, 0, NULL, NULL,&s_edit_mode, NULL, NULL},
344 { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL, NULL, set_enable_cookie_whitelist },
345 { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL, NULL, set_enable_js_whitelist },
346 { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL, NULL, set_enable_plugin_whitelist },
347 { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL, NULL, set_enable_localstorage },
348 { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL, NULL, set_enable_plugins },
349 { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL, NULL, set_enable_scripts },
350 { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL, NULL, NULL },
351 { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL, NULL, set_enable_spell_checking },
352 { "encoding", XT_S_STR, 0, NULL, &encoding, NULL, NULL, set_encoding_rt },
353 { "external_editor", XT_S_STR,0, NULL, &external_editor, NULL, NULL, set_external_editor },
354 { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL, NULL, NULL },
355 { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL, NULL, set_guess_search },
356 { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL, NULL, NULL },
357 { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy },
358 { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL, NULL, NULL },
359 { "js_autorun_enabled", XT_S_INT, 0, &js_autorun_enabled, NULL, NULL, NULL, NULL },
360 { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL, NULL, NULL },
361 { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL, NULL, NULL },
362 { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL, NULL, set_read_only_cookies },
363 { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL, NULL, set_refresh_interval },
364 { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL, NULL, NULL },
365 { "search_string", XT_S_STR, 0, NULL, &search_string, NULL, NULL, set_search_string },
366 { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL, NULL, NULL },
367 { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL, NULL, NULL },
368 { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL, NULL, set_session_timeout },
369 { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL, NULL, set_session_autosave },
370 { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL, NULL, NULL },
371 { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL, NULL, set_show_tabs },
372 { "show_url", XT_S_INT, 0, &show_url, NULL, NULL, NULL, set_show_url },
373 { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL, NULL, set_show_statusbar },
374 { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL, NULL, set_spell_check_languages },
375 { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL, NULL, set_ssl_ca_file_rt },
376 { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL, NULL, set_ssl_strict_certs },
377 { "enable_strict_transport", XT_S_INT, 0, &enable_strict_transport, NULL, NULL, NULL, set_enable_strict_transport },
378 { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL, NULL, NULL },
379 { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style, NULL, set_tab_style_rt },
380 { "userstyle_global", XT_S_INT, 0, &userstyle_global, NULL, NULL, NULL, set_userstyle_global },
381 { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL, NULL, set_url_regex },
382 { "window_height", XT_S_INT, 0, &window_height, NULL, NULL, NULL, NULL },
383 { "window_width", XT_S_INT, 0, &window_width, NULL, NULL, NULL, NULL },
384 { "window_maximize", XT_S_INT, 0, &window_maximize, NULL, NULL, NULL, NULL },
385 { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir, NULL, NULL },
386 { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL, NULL, set_xterm_workaround },
387 { "auto_load_images", XT_S_INT, 0, &auto_load_images, NULL, NULL, NULL, set_auto_load_images },
388 { "enable_favicon_entry", XT_S_INT, 0, &enable_favicon_entry, NULL, NULL, NULL, set_enable_favicon_entry },
389 { "enable_favicon_tabs", XT_S_INT, 0, &enable_favicon_tabs, NULL, NULL, NULL, set_enable_favicon_tabs },
390 { "referer", XT_S_STR, 0, NULL, NULL,&s_referer, NULL, set_referer_rt },
392 /* font settings */
393 { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL, NULL, set_cmd_font },
394 { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL, NULL, set_oops_font },
395 { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL, NULL, set_statusbar_font },
396 { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL, NULL, set_tabbar_font },
398 /* runtime settings */
399 { "append_next", XT_S_INT, 0, &append_next, NULL, NULL, NULL, set_append_next },
400 { "enable_autoscroll", XT_S_INT, 0, &enable_autoscroll, NULL, NULL, NULL, set_enable_autoscroll },
401 { "home", XT_S_STR, 0, NULL, &home, NULL, NULL, set_home },
403 /* special settings */
404 { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias, NULL, NULL },
405 { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl, NULL, NULL },
406 { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js, NULL, NULL },
407 { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
408 { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
409 { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
410 { "user_agent", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
414 set_default_zoom_level(char *value)
416 struct karg args = {0};
417 struct tab *t;
419 if (value == NULL || strlen(value) == 0)
420 return (-1);
421 default_zoom_level = g_strtod(value, NULL);
422 args.i = 100; /* adjust = 100 percent for no additional adjustment */
423 TAILQ_FOREACH(t, &tabs, entry)
424 resizetab(t, &args);
425 return (0);
429 set_cookies_enabled(char *value)
431 int tmp;
432 const char *errstr;
434 tmp = strtonum(value, 0, 1, &errstr);
435 if (errstr)
436 return (-1);
437 cookies_enabled = tmp;
438 return (0);
442 set_append_next(char *value)
444 int tmp;
445 const char *errstr;
447 tmp = strtonum(value, 0, 1, &errstr);
448 if (errstr)
449 return (-1);
450 append_next = tmp;
451 return (0);
455 set_cmd_font(char *value)
457 struct tab *t;
459 if (value == NULL || strlen(value))
460 return (-1);
461 if (cmd_font_name)
462 g_free(cmd_font_name);
463 if (cmd_font)
464 pango_font_description_free(cmd_font);
465 cmd_font_name = g_strdup(value);
466 cmd_font = pango_font_description_from_string(cmd_font_name);
467 TAILQ_FOREACH(t, &tabs, entry)
468 gtk_widget_modify_font(GTK_WIDGET(t->cmd), cmd_font);
469 return (0);
473 set_oops_font(char *value)
475 struct tab *t;
477 if (value == NULL || strlen(value) == 0)
478 return (-1);
479 if (oops_font_name)
480 g_free(oops_font_name);
481 if (oops_font)
482 pango_font_description_free(oops_font);
483 oops_font_name = g_strdup(value);
484 oops_font = pango_font_description_from_string(oops_font_name);
485 TAILQ_FOREACH(t, &tabs, entry)
486 gtk_widget_modify_font(GTK_WIDGET(t->oops), oops_font);
487 return (0);
491 set_statusbar_font(char *value)
493 struct tab *t;
495 if (value == NULL || strlen(value) == 0)
496 return (-1);
497 if (statusbar_font_name)
498 g_free(statusbar_font_name);
499 if (statusbar_font)
500 pango_font_description_free(statusbar_font);
501 statusbar_font_name = g_strdup(value);
502 statusbar_font = pango_font_description_from_string(
503 statusbar_font_name);
504 TAILQ_FOREACH(t, &tabs, entry) {
505 gtk_widget_modify_font(GTK_WIDGET(t->sbe.statusbar),
506 statusbar_font);
507 gtk_widget_modify_font(GTK_WIDGET(t->sbe.buffercmd),
508 statusbar_font);
509 gtk_widget_modify_font(GTK_WIDGET(t->sbe.zoom),
510 statusbar_font);
511 gtk_widget_modify_font(GTK_WIDGET(t->sbe.position),
512 statusbar_font);
514 return (0);
518 set_tabbar_font(char *value)
520 struct tab *t;
522 if (value == NULL || strlen(value) == 0)
523 return (-1);
524 if (tabbar_font_name)
525 g_free(tabbar_font_name);
526 if (tabbar_font)
527 pango_font_description_free(tabbar_font);
528 tabbar_font_name = g_strdup(value);
529 tabbar_font = pango_font_description_from_string(tabbar_font_name);
530 TAILQ_FOREACH(t, &tabs, entry)
531 gtk_widget_modify_font(GTK_WIDGET(t->tab_elems.label),
532 tabbar_font);
533 return (0);
537 set_color_visited_uris(char *value)
539 int tmp;
540 const char *errstr;
542 tmp = strtonum(value, 0, 1, &errstr);
543 if (errstr)
544 return (-1);
545 color_visited_uris = tmp;
546 return (0);
550 set_home(char *value)
552 if (value == NULL || strlen(value) == 0)
553 return (-1);
554 if (home)
555 g_free(home);
556 home = g_strdup(value);
557 return (0);
561 set_search_string(char *value)
563 if (value == NULL || strlen(value) == 0)
564 return (-1);
565 if (search_string)
566 g_free(search_string);
567 search_string = g_strdup(value);
568 return (0);
571 size_t
572 get_settings_size(void)
574 return (LENGTH(rs));
577 char *
578 get_setting_name(int i)
580 if (i > LENGTH(rs))
581 return (NULL);
582 return (rs[i].name);
585 char *
586 get_as_string(struct settings *s)
588 char *r = NULL;
590 if (s == NULL)
591 return (NULL);
593 if (s->s) {
594 if (s->s->get)
595 r = s->s->get(s);
596 else
597 warnx("get_as_string skip %s\n", s->name);
598 } else if (s->type == XT_S_INT)
599 r = g_strdup_printf("%d", *s->ival);
600 else if (s->type == XT_S_STR)
601 r = g_strdup(*s->sval);
602 else if (s->type == XT_S_FLOAT)
603 r = g_strdup_printf("%f", *s->fval);
604 else
605 r = g_strdup_printf("INVALID TYPE");
607 return (r);
610 void
611 settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args)
613 int i;
614 char *s;
616 for (i = 0; i < LENGTH(rs); i++) {
617 if (rs[i].s && rs[i].s->walk)
618 rs[i].s->walk(&rs[i], cb, cb_args);
619 else {
620 s = get_as_string(&rs[i]);
621 cb(&rs[i], s, cb_args);
622 g_free(s);
628 set_browser_mode(struct settings *s, char *val)
630 if (!strcmp(val, "whitelist")) {
631 browser_mode = XT_BM_WHITELIST;
632 allow_volatile_cookies = 0;
633 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
634 cookies_enabled = 1;
635 enable_cookie_whitelist = 1;
636 enable_plugin_whitelist = 1;
637 enable_plugins = 0;
638 read_only_cookies = 0;
639 save_rejected_cookies = 0;
640 session_timeout = 3600;
641 enable_scripts = 0;
642 enable_js_whitelist = 1;
643 enable_localstorage = 0;
644 referer_mode = XT_REFERER_SAME_DOMAIN;
645 } else if (!strcmp(val, "normal")) {
646 browser_mode = XT_BM_NORMAL;
647 allow_volatile_cookies = 0;
648 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
649 cookies_enabled = 1;
650 enable_cookie_whitelist = 0;
651 enable_plugin_whitelist = 0;
652 enable_plugins = 1;
653 read_only_cookies = 0;
654 save_rejected_cookies = 0;
655 session_timeout = 3600;
656 enable_scripts = 1;
657 enable_js_whitelist = 0;
658 enable_localstorage = 1;
659 referer_mode = XT_REFERER_ALWAYS;
660 } else if (!strcmp(val, "kiosk")) {
661 browser_mode = XT_BM_KIOSK;
662 allow_volatile_cookies = 0;
663 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
664 cookies_enabled = 1;
665 enable_cookie_whitelist = 0;
666 enable_plugin_whitelist = 0;
667 enable_plugins = 1;
668 read_only_cookies = 0;
669 save_rejected_cookies = 0;
670 session_timeout = 3600;
671 enable_scripts = 1;
672 enable_js_whitelist = 0;
673 enable_localstorage = 1;
674 referer_mode = XT_REFERER_ALWAYS;
675 show_tabs = 0;
676 tabless = 1;
677 } else
678 return (1);
680 return (0);
683 char *
684 get_browser_mode(struct settings *s)
686 char *r = NULL;
688 if (browser_mode == XT_BM_WHITELIST)
689 r = g_strdup("whitelist");
690 else if (browser_mode == XT_BM_NORMAL)
691 r = g_strdup("normal");
692 else if (browser_mode == XT_BM_KIOSK)
693 r = g_strdup("kiosk");
694 else
695 return (NULL);
697 return (r);
701 set_gui_mode(struct settings *s, char *val)
703 if (!strcmp(val, "classic")) {
704 fancy_bar = 1;
705 show_tabs = 1;
706 tab_style = XT_TABS_NORMAL;
707 show_url = 1;
708 show_statusbar = 0;
709 } else if (!strcmp(val, "minimal")) {
710 fancy_bar = 0;
711 show_tabs = 1;
712 tab_style = XT_TABS_COMPACT;
713 show_url = 0;
714 show_statusbar = 1;
715 } else
716 return (1);
718 return (0);
721 char *
722 get_gui_mode(struct settings *s)
724 char *r = NULL;
726 if (gui_mode == XT_GM_CLASSIC)
727 r = g_strdup("classic");
728 else if (browser_mode == XT_GM_MINIMAL)
729 r = g_strdup("minimal");
730 else
731 return (NULL);
733 return (r);
737 set_cookie_policy(struct settings *s, char *val)
739 if (!strcmp(val, "no3rdparty"))
740 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
741 else if (!strcmp(val, "accept"))
742 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
743 else if (!strcmp(val, "reject"))
744 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
745 else
746 return (1);
748 return (0);
752 set_cookie_policy_rt(char *value)
754 if (set_cookie_policy(NULL, value))
755 return (-1);
756 g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY,
757 cookie_policy, (void *)NULL);
758 return (0);
761 char *
762 get_cookie_policy(struct settings *s)
764 char *r = NULL;
766 if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY)
767 r = g_strdup("no3rdparty");
768 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
769 r = g_strdup("accept");
770 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
771 r = g_strdup("reject");
772 else
773 return (NULL);
775 return (r);
778 char *
779 get_default_script(struct settings *s)
781 if (default_script[0] == '\0')
782 return (0);
783 return (g_strdup(default_script));
787 set_default_script(struct settings *s, char *val)
789 if (val[0] == '~')
790 snprintf(default_script, sizeof default_script, "%s" PS "%s",
791 pwd->pw_dir, &val[1]);
792 else
793 strlcpy(default_script, val, sizeof default_script);
795 return (0);
799 set_default_script_rt(char *value)
801 if (value == NULL || strlen(value) == 0)
802 return (-1);
803 return (set_default_script(NULL, value));
806 char *
807 get_download_dir(struct settings *s)
809 if (download_dir[0] == '\0')
810 return (0);
811 return (g_strdup(download_dir));
815 set_download_dir(struct settings *s, char *val)
817 if (val[0] == '~')
818 snprintf(download_dir, sizeof download_dir, "%s" PS "%s",
819 pwd->pw_dir, &val[1]);
820 else
821 strlcpy(download_dir, val, sizeof download_dir);
823 return (0);
827 add_alias(struct settings *s, char *line)
829 char *l, *alias;
830 struct alias *a = NULL;
832 if (s == NULL || line == NULL) {
833 show_oops(NULL, "add_alias invalid parameters");
834 return (1);
837 l = line;
838 a = g_malloc(sizeof(*a));
840 if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) {
841 show_oops(NULL, "add_alias: incomplete alias definition");
842 goto bad;
844 if (strlen(alias) == 0 || strlen(l) == 0) {
845 show_oops(NULL, "add_alias: invalid alias definition");
846 goto bad;
849 a->a_name = g_strdup(alias);
850 a->a_uri = g_strdup(l);
852 DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri);
854 TAILQ_INSERT_TAIL(&aliases, a, entry);
856 return (0);
857 bad:
858 if (a)
859 g_free(a);
860 return (1);
863 void
864 walk_alias(struct settings *s,
865 void (*cb)(struct settings *, char *, void *), void *cb_args)
867 struct alias *a;
868 char *str;
870 if (s == NULL || cb == NULL) {
871 show_oops(NULL, "walk_alias invalid parameters");
872 return;
875 TAILQ_FOREACH(a, &aliases, entry) {
876 str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri);
877 cb(s, str, cb_args);
878 g_free(str);
883 add_mime_type(struct settings *s, char *line)
885 char *mime_type;
886 char *l;
887 struct mime_type *m = NULL;
888 int downloadfirst = 0;
890 /* XXX this could be smarter */
892 if (line == NULL || strlen(line) == 0) {
893 show_oops(NULL, "add_mime_type invalid parameters");
894 return (1);
897 l = line;
898 if (*l == '@') {
899 downloadfirst = 1;
900 l++;
902 m = g_malloc(sizeof(*m));
904 if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) {
905 show_oops(NULL, "add_mime_type: invalid mime_type");
906 goto bad;
908 if (mime_type[strlen(mime_type) - 1] == '*') {
909 mime_type[strlen(mime_type) - 1] = '\0';
910 m->mt_default = 1;
911 } else
912 m->mt_default = 0;
914 if (strlen(mime_type) == 0 || strlen(l) == 0) {
915 show_oops(NULL, "add_mime_type: invalid mime_type");
916 goto bad;
919 m->mt_type = g_strdup(mime_type);
920 m->mt_action = g_strdup(l);
921 m->mt_download = downloadfirst;
923 DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n",
924 m->mt_type, m->mt_action, m->mt_default);
926 TAILQ_INSERT_TAIL(&mtl, m, entry);
928 return (0);
929 bad:
930 if (m)
931 g_free(m);
932 return (1);
935 void
936 walk_mime_type(struct settings *s,
937 void (*cb)(struct settings *, char *, void *), void *cb_args)
939 struct mime_type *m;
940 char *str;
942 if (s == NULL || cb == NULL) {
943 show_oops(NULL, "walk_mime_type invalid parameters");
944 return;
947 TAILQ_FOREACH(m, &mtl, entry) {
948 str = g_strdup_printf("%s%s --> %s",
949 m->mt_type,
950 m->mt_default ? "*" : "",
951 m->mt_action);
952 cb(s, str, cb_args);
953 g_free(str);
957 /* inherent to GTK not all keys will be caught at all times */
958 /* XXX sort key bindings */
959 struct key_binding keys[] = {
960 { "command_mode", 0, 1, GDK_Escape },
961 { "insert_mode", 0, 0, GDK_i },
962 { "cookiejar", MOD1, 1, GDK_j },
963 { "downloadmgr", MOD1, 1, GDK_d },
964 { "history", MOD1, 1, GDK_h },
965 { "print", CTRL, 1, GDK_p },
966 { "search", 0, 0, GDK_slash },
967 { "searchb", 0, 0, GDK_question },
968 { "statustoggle", CTRL, 1, GDK_n },
969 { "command", 0, 0, GDK_colon },
970 { "qa", CTRL, 1, GDK_q },
971 { "restart", MOD1, 1, GDK_q },
972 { "js toggle", CTRL, 1, GDK_j },
973 { "plugin toggle", MOD1, 1, GDK_p },
974 { "cookie toggle", MOD1, 1, GDK_c },
975 { "togglesrc", CTRL, 1, GDK_s },
976 { "yankuri", 0, 0, GDK_y },
977 { "pasteuricur", 0, 0, GDK_p },
978 { "pasteurinew", 0, 0, GDK_P },
979 { "toplevel toggle", 0, 1, GDK_F4 },
980 { "help", 0, 1, GDK_F1 },
981 { "run_script", MOD1, 1, GDK_r },
982 { "proxy toggle", 0, 1, GDK_F2 },
983 { "editelement", CTRL, 1, GDK_i },
984 { "passthrough", CTRL, 1, GDK_z },
985 { "modurl", CTRL, 1, GDK_Return },
987 /* search */
988 { "searchnext", 0, 0, GDK_n },
989 { "searchprevious", 0, 0, GDK_N },
991 /* focus */
992 { "focusaddress", 0, 1, GDK_F6 },
993 { "focussearch", 0, 1, GDK_F7 },
995 /* hinting */
996 { "hinting", 0, 0, GDK_f },
997 { "hinting", 0, 0, GDK_period },
998 { "hinting_newtab", SHFT, 0, GDK_F },
999 { "hinting_newtab", 0, 0, GDK_comma },
1001 /* custom stylesheet */
1002 { "userstyle", 0, 0, GDK_s },
1003 { "userstyle_global", SHFT, 0, GDK_S },
1005 /* navigation */
1006 { "goback", 0, 0, GDK_BackSpace },
1007 { "goback", MOD1, 1, GDK_Left },
1008 { "goforward", SHFT, 1, GDK_BackSpace },
1009 { "goforward", MOD1, 1, GDK_Right },
1010 { "reload", 0, 1, GDK_F5 },
1011 { "reload", CTRL, 1, GDK_r },
1012 { "reload", CTRL, 1, GDK_l },
1013 { "favorites", MOD1, 1, GDK_f },
1015 /* vertical movement */
1016 { "scrolldown", 0, 0, GDK_j },
1017 { "scrolldown", 0, 0, GDK_Down },
1018 { "scrollup", 0, 0, GDK_Up },
1019 { "scrollup", 0, 0, GDK_k },
1020 { "scrollbottom", 0, 0, GDK_G },
1021 { "scrollbottom", 0, 0, GDK_End },
1022 { "scrolltop", 0, 0, GDK_Home },
1023 { "scrollpagedown", 0, 0, GDK_space },
1024 { "scrollpagedown", CTRL, 1, GDK_f },
1025 { "scrollhalfdown", CTRL, 1, GDK_d },
1026 { "scrollpagedown", 0, 0, GDK_Page_Down },
1027 { "scrollpageup", 0, 0, GDK_Page_Up },
1028 { "scrollpageup", CTRL, 1, GDK_b },
1029 { "scrollhalfup", CTRL, 1, GDK_u },
1030 /* horizontal movement */
1031 { "scrollright", 0, 0, GDK_l },
1032 { "scrollright", 0, 0, GDK_Right },
1033 { "scrollleft", 0, 0, GDK_Left },
1034 { "scrollleft", 0, 0, GDK_h },
1035 { "scrollfarright", 0, 0, GDK_dollar },
1036 { "scrollfarleft", 0, 0, GDK_0 },
1038 /* tabs */
1039 { "tabnew", CTRL, 1, GDK_t },
1040 { "999tabnew", CTRL, 1, GDK_T },
1041 { "tabclose", CTRL, 1, GDK_w },
1042 { "tabundoclose", 0, 0, GDK_U },
1043 { "tabnext 1", CTRL, 1, GDK_1 },
1044 { "tabnext 2", CTRL, 1, GDK_2 },
1045 { "tabnext 3", CTRL, 1, GDK_3 },
1046 { "tabnext 4", CTRL, 1, GDK_4 },
1047 { "tabnext 5", CTRL, 1, GDK_5 },
1048 { "tabnext 6", CTRL, 1, GDK_6 },
1049 { "tabnext 7", CTRL, 1, GDK_7 },
1050 { "tabnext 8", CTRL, 1, GDK_8 },
1051 { "tabnext 9", CTRL, 1, GDK_9 },
1052 { "tabfirst", CTRL, 1, GDK_less },
1053 { "tablast", CTRL, 1, GDK_greater },
1054 { "tabprevious", CTRL, 1, GDK_Left },
1055 { "tabnext", CTRL, 1, GDK_Right },
1056 { "focusout", CTRL, 1, GDK_minus },
1057 { "focusin", CTRL, 1, GDK_plus },
1058 { "focusin", CTRL, 1, GDK_equal },
1059 { "focusreset", CTRL, 1, GDK_0 },
1061 /* command aliases (handy when -S flag is used) */
1062 { "promptopen", 0, 1, GDK_F9 },
1063 { "promptopencurrent", 0, 1, GDK_F10 },
1064 { "prompttabnew", 0, 1, GDK_F11 },
1065 { "prompttabnewcurrent",0, 1, GDK_F12 },
1068 void
1069 walk_kb(struct settings *s,
1070 void (*cb)(struct settings *, char *, void *), void *cb_args)
1072 struct key_binding *k;
1073 char str[1024];
1075 if (s == NULL || cb == NULL) {
1076 show_oops(NULL, "walk_kb invalid parameters");
1077 return;
1080 TAILQ_FOREACH(k, &kbl, entry) {
1081 if (k->cmd == NULL)
1082 continue;
1083 str[0] = '\0';
1085 /* sanity */
1086 if (gdk_keyval_name(k->key) == NULL)
1087 continue;
1089 strlcat(str, k->cmd, sizeof str);
1090 strlcat(str, ",", sizeof str);
1092 if (k->mask & GDK_SHIFT_MASK)
1093 strlcat(str, "S-", sizeof str);
1094 if (k->mask & GDK_CONTROL_MASK)
1095 strlcat(str, "C-", sizeof str);
1096 if (k->mask & GDK_MOD1_MASK)
1097 strlcat(str, "M1-", sizeof str);
1098 if (k->mask & GDK_MOD2_MASK)
1099 strlcat(str, "M2-", sizeof str);
1100 if (k->mask & GDK_MOD3_MASK)
1101 strlcat(str, "M3-", sizeof str);
1102 if (k->mask & GDK_MOD4_MASK)
1103 strlcat(str, "M4-", sizeof str);
1104 if (k->mask & GDK_MOD5_MASK)
1105 strlcat(str, "M5-", sizeof str);
1107 strlcat(str, gdk_keyval_name(k->key), sizeof str);
1108 cb(s, str, cb_args);
1112 void
1113 init_keybindings(void)
1115 int i;
1116 struct key_binding *k;
1118 for (i = 0; i < LENGTH(keys); i++) {
1119 k = g_malloc0(sizeof *k);
1120 k->cmd = keys[i].cmd;
1121 k->mask = keys[i].mask;
1122 k->use_in_entry = keys[i].use_in_entry;
1123 k->key = keys[i].key;
1124 TAILQ_INSERT_HEAD(&kbl, k, entry);
1126 DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n",
1127 k->cmd ? k->cmd : "unnamed key");
1131 void
1132 keybinding_clearall(void)
1134 struct key_binding *k, *next;
1136 for (k = TAILQ_FIRST(&kbl); k; k = next) {
1137 next = TAILQ_NEXT(k, entry);
1138 if (k->cmd == NULL)
1139 continue;
1141 DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n",
1142 k->cmd ? k->cmd : "unnamed key");
1143 TAILQ_REMOVE(&kbl, k, entry);
1144 g_free(k);
1149 keybinding_add(char *cmd, char *key, int use_in_entry)
1151 struct key_binding *k;
1152 guint keyval, mask = 0;
1153 int i;
1155 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key);
1157 /* Keys which are to be used in entry have been prefixed with an
1158 * exclamation mark. */
1159 if (use_in_entry)
1160 key++;
1162 /* find modifier keys */
1163 if (strstr(key, "S-"))
1164 mask |= GDK_SHIFT_MASK;
1165 if (strstr(key, "C-"))
1166 mask |= GDK_CONTROL_MASK;
1167 if (strstr(key, "M1-"))
1168 mask |= GDK_MOD1_MASK;
1169 if (strstr(key, "M2-"))
1170 mask |= GDK_MOD2_MASK;
1171 if (strstr(key, "M3-"))
1172 mask |= GDK_MOD3_MASK;
1173 if (strstr(key, "M4-"))
1174 mask |= GDK_MOD4_MASK;
1175 if (strstr(key, "M5-"))
1176 mask |= GDK_MOD5_MASK;
1178 /* find keyname */
1179 for (i = strlen(key) - 1; i > 0; i--)
1180 if (key[i] == '-')
1181 key = &key[i + 1];
1183 /* validate keyname */
1184 keyval = gdk_keyval_from_name(key);
1185 if (keyval == GDK_VoidSymbol) {
1186 warnx("invalid keybinding name %s", key);
1187 return (1);
1189 /* must run this test too, gtk+ doesn't handle 10 for example */
1190 if (gdk_keyval_name(keyval) == NULL) {
1191 warnx("invalid keybinding name %s", key);
1192 return (1);
1195 /* Remove eventual dupes. */
1196 TAILQ_FOREACH(k, &kbl, entry)
1197 if (k->key == keyval && k->mask == mask) {
1198 TAILQ_REMOVE(&kbl, k, entry);
1199 g_free(k);
1200 break;
1203 /* add keyname */
1204 k = g_malloc0(sizeof *k);
1205 k->cmd = g_strdup(cmd);
1206 k->mask = mask;
1207 k->use_in_entry = use_in_entry;
1208 k->key = keyval;
1210 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n",
1211 k->cmd,
1212 k->mask,
1213 k->use_in_entry,
1214 k->key);
1215 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n",
1216 k->cmd, gdk_keyval_name(keyval));
1218 TAILQ_INSERT_HEAD(&kbl, k, entry);
1220 return (0);
1224 add_kb(struct settings *s, char *entry)
1226 char *kb, *key;
1228 DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry);
1230 /* clearall is special */
1231 if (!strcmp(entry, "clearall")) {
1232 keybinding_clearall();
1233 return (0);
1236 kb = strstr(entry, ",");
1237 if (kb == NULL)
1238 return (1);
1239 *kb = '\0';
1240 key = kb + 1;
1242 return (keybinding_add(entry, key, key[0] == '!'));
1246 add_ua(struct settings *s, char *value)
1248 struct user_agent *ua;
1250 ua = g_malloc0(sizeof *ua);
1251 ua->value = g_strdup(value);
1253 TAILQ_INSERT_HEAD(&ua_list, ua, entry);
1255 /* use the last added user agent */
1256 user_agent = TAILQ_FIRST(&ua_list);
1257 user_agent_count++;
1259 return (0);
1263 void
1264 walk_ua(struct settings *s,
1265 void (*cb)(struct settings *, char *, void *), void *cb_args)
1267 struct user_agent *ua;
1269 if (s == NULL || cb == NULL) {
1270 show_oops(NULL, "walk_ua invalid parameters");
1271 return;
1274 TAILQ_FOREACH(ua, &ua_list, entry)
1275 cb(s, ua->value, cb_args);
1279 set_auto_load_images(char *value)
1281 struct tab *t;
1282 int tmp;
1283 const char *errstr;
1285 tmp = strtonum(value, 0, 1, &errstr);
1286 if (errstr)
1287 return (-1);
1288 auto_load_images = tmp;
1289 TAILQ_FOREACH(t, &tabs, entry) {
1290 g_object_set(G_OBJECT(t->settings),
1291 "auto-load-images", auto_load_images, (char *)NULL);
1292 webkit_web_view_set_settings(t->wv, t->settings);
1294 return (0);
1298 set_ctrl_click_focus(char *value)
1300 int tmp;
1301 const char *errstr;
1303 tmp = strtonum(value, 0, 1, &errstr);
1304 if (errstr)
1305 return (-1);
1306 ctrl_click_focus = tmp;
1307 return (0);
1311 set_enable_autoscroll(char *value)
1313 int tmp;
1314 const char *errstr;
1316 tmp = strtonum(value, 0, 1, &errstr);
1317 if (errstr)
1318 return (-1);
1319 enable_autoscroll = tmp;
1320 return (0);
1324 set_enable_cookie_whitelist(char *value)
1326 int tmp;
1327 const char *errstr;
1329 tmp = strtonum(value, 0, 1, &errstr);
1330 if (errstr)
1331 return (-1);
1332 enable_cookie_whitelist = tmp;
1333 return (0);
1337 set_enable_js_whitelist(char *value)
1339 int tmp;
1340 const char *errstr;
1342 tmp = strtonum(value, 0, 1, &errstr);
1343 if (errstr)
1344 return (-1);
1345 enable_js_whitelist = tmp;
1346 return (0);
1350 set_enable_favicon_entry(char *value)
1352 int tmp;
1353 const char *errstr;
1355 tmp = strtonum(value, 0, 1, &errstr);
1356 if (errstr)
1357 return (-1);
1358 enable_favicon_entry = tmp;
1359 return (0);
1363 set_enable_favicon_tabs(char *value)
1365 int tmp;
1366 const char *errstr;
1368 tmp = strtonum(value, 0, 1, &errstr);
1369 if (errstr)
1370 return (-1);
1371 enable_favicon_tabs = tmp;
1372 return (0);
1376 set_enable_localstorage(char *value)
1378 struct tab *t;
1379 int tmp;
1380 const char *errstr;
1382 tmp = strtonum(value, 0, 1, &errstr);
1383 if (errstr)
1384 return (-1);
1385 enable_localstorage = tmp;
1386 TAILQ_FOREACH(t, &tabs, entry) {
1387 g_object_set(G_OBJECT(t->settings),
1388 "enable-html5-local-storage", enable_localstorage,
1389 (char *)NULL);
1391 return (0);
1395 set_enable_plugins(char *value)
1397 struct tab *t;
1398 int tmp;
1399 const char *errstr;
1401 tmp = strtonum(value, 0, 1, &errstr);
1402 if (errstr)
1403 return (-1);
1404 enable_plugins = tmp;
1405 TAILQ_FOREACH(t, &tabs, entry)
1406 g_object_set(G_OBJECT(t->settings), "enable-plugins",
1407 enable_plugins, (char *)NULL);
1408 return (0);
1412 set_enable_plugin_whitelist(char *value)
1414 /* XXX: this needs testing */
1415 int tmp;
1416 const char *errstr;
1418 tmp = strtonum(value, 0, 1, &errstr);
1419 if (errstr)
1420 return (-1);
1421 enable_plugin_whitelist = tmp;
1422 return (0);
1426 set_enable_scripts(char *value)
1428 struct tab *t;
1429 int tmp;
1430 const char *errstr;
1432 tmp = strtonum(value, 0, 1, &errstr);
1433 if (errstr)
1434 return (-1);
1435 enable_scripts = tmp;
1436 TAILQ_FOREACH(t, &tabs, entry)
1437 g_object_set(G_OBJECT(t->settings), "enable-scripts",
1438 enable_scripts, (char *)NULL);
1439 return (0);
1443 set_enable_spell_checking(char *value)
1445 struct tab *t;
1446 int tmp;
1447 const char *errstr;
1449 tmp = strtonum(value, 0, 1, &errstr);
1450 if (errstr)
1451 return (-1);
1452 enable_spell_checking = tmp;
1453 TAILQ_FOREACH(t, &tabs, entry)
1454 g_object_set(G_OBJECT(t->settings), "enable_spell_checking",
1455 enable_spell_checking, (char *)NULL);
1456 return (0);
1460 set_enable_strict_transport(char *value)
1462 int tmp;
1463 const char *errstr;
1465 tmp = strtonum(value, 0, 1, &errstr);
1466 if (errstr)
1467 return (-1);
1468 enable_strict_transport = tmp;
1469 return (0);
1473 set_encoding_rt(char *value)
1475 struct karg args = {0};
1477 if (value == NULL || strlen(value) == 0)
1478 return (-1);
1479 if (encoding)
1480 g_free(encoding);
1481 encoding = g_strdup(value);
1482 args.s = encoding;
1483 set_encoding(get_current_tab(), &args);
1484 return (0);
1488 set_guess_search(char *value)
1490 int tmp;
1491 const char *errstr;
1493 tmp = strtonum(value, 0, 1, &errstr);
1494 if (errstr)
1495 return (-1);
1496 guess_search = tmp;
1497 return (0);
1501 set_read_only_cookies(char *value)
1503 int tmp;
1504 const char *errstr;
1506 tmp = strtonum(value, 0, 1, &errstr);
1507 if (errstr)
1508 return (-1);
1509 read_only_cookies = tmp;
1510 g_object_set(G_OBJECT(p_cookiejar), SOUP_COOKIE_JAR_READ_ONLY,
1511 read_only_cookies, (void *)NULL);
1512 return (0);
1515 char *
1516 get_referer(struct settings *s)
1518 if (referer_mode == XT_REFERER_ALWAYS)
1519 return (g_strdup("always"));
1520 if (referer_mode == XT_REFERER_NEVER)
1521 return (g_strdup("never"));
1522 if (referer_mode == XT_REFERER_SAME_DOMAIN)
1523 return (g_strdup("same-domain"));
1524 if (referer_mode == XT_REFERER_SAME_FQDN)
1525 return (g_strdup("same-fqdn"));
1526 if (referer_mode == XT_REFERER_CUSTOM)
1527 return (g_strdup(referer_custom));
1528 return (NULL);
1532 set_referer(struct settings *s, char *value)
1534 if (referer_custom)
1535 g_free(referer_custom);
1537 if (!strcmp(value, "always"))
1538 referer_mode = XT_REFERER_ALWAYS;
1539 else if (!strcmp(value, "never"))
1540 referer_mode = XT_REFERER_NEVER;
1541 else if (!strcmp(value, "same-domain"))
1542 referer_mode = XT_REFERER_SAME_DOMAIN;
1543 else if (!strcmp(value, "same-fqdn"))
1544 referer_mode = XT_REFERER_SAME_FQDN;
1545 else if (!valid_url_type(value)) {
1546 referer_mode = XT_REFERER_CUSTOM;
1547 referer_custom = g_strdup(value);
1548 } else {
1549 /* we've already free'd the custom referer */
1550 if (referer_mode == XT_REFERER_CUSTOM)
1551 referer_mode = XT_REFERER_NEVER;
1552 return (1);
1555 return (0);
1559 set_referer_rt(char *value)
1561 if (value == NULL || strlen(value) == 0)
1562 return (-1);
1563 return (set_referer(NULL, value));
1567 set_refresh_interval(char *value)
1569 int tmp;
1570 const char *errstr;
1572 tmp = strtonum(value, 0, INT_MAX, &errstr);
1573 if (errstr)
1574 return (-1);
1575 refresh_interval = tmp;
1576 return (0);
1580 set_session_autosave(char *value)
1582 int tmp;
1583 const char *errstr;
1585 tmp = strtonum(value, 0, 1, &errstr);
1586 if (errstr)
1587 return (-1);
1588 session_autosave = tmp;
1589 return (0);
1593 set_session_timeout(char *value)
1595 int tmp;
1596 const char *errstr;
1598 tmp = strtonum(value, 0, INT_MAX, &errstr);
1599 if (errstr)
1600 return (-1);
1601 session_timeout = tmp;
1602 return (0);
1606 set_show_statusbar(char *value)
1608 int tmp;
1609 const char *errstr;
1611 tmp = strtonum(value, 0, 1, &errstr);
1612 if (errstr)
1613 return (-1);
1614 show_statusbar = tmp;
1615 statusbar_set_visibility();
1616 return (0);
1620 set_show_tabs(char *value)
1622 struct karg args = {0};
1623 int val;
1624 const char *errstr;
1626 val = strtonum(value, 0, 1, &errstr);
1627 if (errstr)
1628 return (-1);
1629 args.i = val ? XT_TAB_SHOW : XT_TAB_HIDE;
1630 tabaction(get_current_tab(), &args);
1631 return (0);
1635 set_show_url(char *value)
1637 struct karg args = {0};
1638 int val;
1639 const char *errstr;
1641 val = strtonum(value, 0, 1, &errstr);
1642 if (errstr)
1643 return (-1);
1644 args.i = val ? XT_URL_SHOW : XT_URL_HIDE;
1645 urlaction(get_current_tab(), &args);
1646 return (0);
1650 set_spell_check_languages(char *value)
1652 struct tab *t;
1654 if (value == NULL || strlen(value) == 0)
1655 return (-1);
1656 if (spell_check_languages)
1657 g_free(spell_check_languages);
1658 spell_check_languages = g_strdup(value);
1659 TAILQ_FOREACH(t, &tabs, entry)
1660 g_object_set(G_OBJECT(t->settings), "spell_checking_languages",
1661 spell_check_languages, (char *)NULL);
1662 return (0);
1666 check_valid_file(char *name)
1668 struct stat sb;
1670 if (name == NULL || stat(name, &sb))
1671 return (-1);
1672 return (0);
1676 set_ssl_ca_file_rt(char *value)
1678 if (value == NULL || strlen(value) == 0)
1679 return (-1);
1680 if (set_ssl_ca_file(value))
1681 return (-1);
1682 return (0);
1686 set_ssl_strict_certs(char *value)
1688 int tmp;
1689 const char *errstr;
1691 tmp = strtonum(value, 0, 1, &errstr);
1692 if (errstr)
1693 return (-1);
1694 ssl_strict_certs = tmp;
1695 set_ssl_ca_file(ssl_ca_file);
1696 return (0);
1700 set_external_editor(char *editor)
1702 if (external_editor)
1703 g_free(external_editor);
1705 external_editor = g_strdup(editor);
1707 return (0);
1710 void
1711 setup_proxy(char *uri)
1713 if (proxy_uri) {
1714 g_object_set(session, "proxy_uri", NULL, (char *)NULL);
1715 soup_uri_free(proxy_uri);
1716 proxy_uri = NULL;
1718 if (http_proxy) {
1719 if (http_proxy != uri) {
1720 g_free(http_proxy);
1721 http_proxy = NULL;
1725 if (uri) {
1726 http_proxy = g_strdup(uri);
1727 DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri);
1728 proxy_uri = soup_uri_new(http_proxy);
1729 if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri)))
1730 g_object_set(session, "proxy-uri", proxy_uri,
1731 (char *)NULL);
1735 char *
1736 get_tab_style(struct settings *s)
1738 if (tab_style == XT_TABS_NORMAL)
1739 return (g_strdup("normal"));
1740 else
1741 return (g_strdup("compact"));
1745 set_tab_style(struct settings *s, char *val)
1747 if (!strcmp(val, "normal"))
1748 tab_style = XT_TABS_NORMAL;
1749 else if (!strcmp(val, "compact"))
1750 tab_style = XT_TABS_COMPACT;
1751 else
1752 return (1);
1754 return (0);
1758 set_tab_style_rt(char *value)
1760 struct karg args = {0};
1761 int old_tab_style;
1763 old_tab_style = tab_style;
1764 if (set_tab_style(NULL, value))
1765 return (-1);
1766 if (old_tab_style != tab_style) {
1767 tab_style = old_tab_style;
1768 args.i = XT_TAB_NEXTSTYLE;
1769 tabaction(get_current_tab(), &args);
1771 return (0);
1775 set_url_regex(char *value)
1777 if (regcomp(&url_re, value, REG_EXTENDED | REG_NOSUB))
1778 return (-1);
1779 if (url_regex)
1780 g_free(url_regex);
1781 url_regex = g_strdup(value);
1782 return (0);
1786 set_userstyle_global(char *value)
1788 struct karg args = {0};
1789 int tmp, old_style;
1790 const char *errstr;
1792 old_style = userstyle_global;
1793 tmp = strtonum(value, 0, 1, &errstr);
1794 if (errstr)
1795 return (-1);
1796 if (tmp != old_style) {
1797 args.i = XT_STYLE_GLOBAL;
1798 userstyle(get_current_tab(), &args);
1800 return (0);
1803 char *
1804 get_edit_mode(struct settings *s)
1806 if (edit_mode == XT_EM_HYBRID)
1807 return (g_strdup("hybrid"));
1808 else
1809 return (g_strdup("vi"));
1813 set_edit_mode(struct settings *s, char *val)
1815 if (!strcmp(val, "hybrid"))
1816 edit_mode = XT_EM_HYBRID;
1817 else if (!strcmp(val, "vi"))
1818 edit_mode = XT_EM_VI;
1819 else
1820 return (1);
1822 return (0);
1825 char *
1826 get_download_mode(struct settings *s)
1828 switch (download_mode) {
1829 case XT_DM_START:
1830 return (g_strdup("start"));
1831 break;
1832 case XT_DM_ASK:
1833 return (g_strdup("ask"));
1834 break;
1835 case XT_DM_ADD:
1836 return (g_strdup("add"));
1837 break;
1839 return (g_strdup("unknown"));
1843 set_download_mode(struct settings *s, char *val)
1845 if (!strcmp(val, "start"))
1846 download_mode = XT_DM_START;
1847 else if (!strcmp(val, "ask"))
1848 download_mode = XT_DM_ASK;
1849 else if (!strcmp(val, "add"))
1850 download_mode = XT_DM_ADD;
1851 else
1852 return (1);
1854 return (0);
1858 set_download_mode_rt(char *val)
1860 if (val == NULL || strlen(val) == 0)
1861 return (-1);
1862 return (set_download_mode(NULL, val));
1865 char *
1866 get_work_dir(struct settings *s)
1868 if (work_dir[0] == '\0')
1869 return (0);
1870 return (g_strdup(work_dir));
1874 set_work_dir(struct settings *s, char *val)
1876 if (val[0] == '~')
1877 snprintf(work_dir, sizeof work_dir, "%s" PS "%s",
1878 pwd->pw_dir, &val[1]);
1879 else
1880 strlcpy(work_dir, val, sizeof work_dir);
1882 return (0);
1886 set_xterm_workaround(char *value)
1888 int tmp;
1889 const char *errstr;
1891 tmp = strtonum(value, 0, 1, &errstr);
1892 if (errstr)
1893 return (-1);
1894 xterm_workaround = tmp;
1895 return (0);
1898 void
1899 walk_cookie_wl(struct settings *s,
1900 void (*cb)(struct settings *, char *, void *), void *cb_args)
1902 struct domain *d;
1904 if (s == NULL || cb == NULL) {
1905 show_oops(NULL, "walk_cookie_wl invalid parameters");
1906 return;
1909 RB_FOREACH_REVERSE(d, domain_list, &c_wl)
1910 cb(s, d->d, cb_args);
1913 void
1914 walk_js_wl(struct settings *s,
1915 void (*cb)(struct settings *, char *, void *), void *cb_args)
1917 struct domain *d;
1919 if (s == NULL || cb == NULL) {
1920 show_oops(NULL, "walk_js_wl invalid parameters");
1921 return;
1924 RB_FOREACH_REVERSE(d, domain_list, &js_wl)
1925 cb(s, d->d, cb_args);
1928 void
1929 walk_pl_wl(struct settings *s,
1930 void (*cb)(struct settings *, char *, void *), void *cb_args)
1932 struct domain *d;
1934 if (s == NULL || cb == NULL) {
1935 show_oops(NULL, "walk_pl_wl invalid parameters");
1936 return;
1939 RB_FOREACH_REVERSE(d, domain_list, &pl_wl)
1940 cb(s, d->d, cb_args);
1944 settings_add(char *var, char *val)
1946 int i, rv, *p;
1947 gfloat *f;
1948 char **s;
1950 /* get settings */
1951 for (i = 0, rv = 0; i < LENGTH(rs); i++) {
1952 if (strcmp(var, rs[i].name))
1953 continue;
1955 if (rs[i].s) {
1956 if (rs[i].s->set(&rs[i], val))
1957 errx(1, "invalid value for %s: %s", var, val);
1958 rv = 1;
1959 break;
1960 } else
1961 switch (rs[i].type) {
1962 case XT_S_INT:
1963 p = rs[i].ival;
1964 *p = atoi(val);
1965 rv = 1;
1966 break;
1967 case XT_S_STR:
1968 s = rs[i].sval;
1969 if (s == NULL)
1970 errx(1, "invalid sval for %s",
1971 rs[i].name);
1972 if (*s)
1973 g_free(*s);
1974 *s = g_strdup(val);
1975 rv = 1;
1976 break;
1977 case XT_S_FLOAT:
1978 f = rs[i].fval;
1979 *f = atof(val);
1980 rv = 1;
1981 break;
1982 case XT_S_INVALID:
1983 default:
1984 errx(1, "invalid type for %s", var);
1986 break;
1988 return (rv);
1991 #define WS "\n= \t"
1992 void
1993 config_parse(char *filename, int runtime)
1995 FILE *config, *f;
1996 char *line, *cp, *var, *val;
1997 size_t len, lineno = 0;
1998 int handled;
1999 char file[PATH_MAX];
2000 struct stat sb;
2002 DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename);
2004 if (filename == NULL)
2005 return;
2007 if (runtime && runtime_settings[0] != '\0') {
2008 snprintf(file, sizeof file, "%s" PS "%s",
2009 work_dir, runtime_settings);
2010 if (stat(file, &sb)) {
2011 warnx("runtime file doesn't exist, creating it");
2012 if ((f = fopen(file, "w")) == NULL)
2013 err(1, "runtime");
2014 fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n");
2015 fclose(f);
2017 } else
2018 strlcpy(file, filename, sizeof file);
2020 if ((config = fopen(file, "r")) == NULL) {
2021 warn("config_parse: cannot open %s", filename);
2022 return;
2025 for (;;) {
2026 if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
2027 if (feof(config) || ferror(config))
2028 break;
2030 cp = line;
2031 cp += (long)strspn(cp, WS);
2032 if (cp[0] == '\0') {
2033 /* empty line */
2034 free(line);
2035 continue;
2038 if ((var = strsep(&cp, WS)) == NULL || cp == NULL)
2039 startpage_add("invalid configuration file entry: %s",
2040 line);
2041 else {
2042 cp += (long)strspn(cp, WS);
2044 if ((val = strsep(&cp, "\0")) == NULL)
2045 break;
2047 DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n",
2048 var, val);
2049 handled = settings_add(var, val);
2051 if (handled == 0)
2052 startpage_add("invalid configuration file entry"
2053 ": %s=%s", var, val);
2056 free(line);
2059 fclose(config);
2062 struct settings_args {
2063 char **body;
2064 int i;
2067 void
2068 print_setting(struct settings *s, char *val, void *cb_args)
2070 char *tmp, *color;
2071 struct settings_args *sa = cb_args;
2073 if (sa == NULL)
2074 return;
2076 if (s->flags & XT_SF_RUNTIME)
2077 color = "#22cc22";
2078 else
2079 color = "#cccccc";
2081 tmp = *sa->body;
2082 *sa->body = g_strdup_printf(
2083 "%s\n<tr>"
2084 "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>"
2085 "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>",
2086 *sa->body,
2087 color,
2088 s->name,
2089 color,
2092 g_free(tmp);
2093 sa->i++;
2097 set_show(struct tab *t, struct karg *args)
2099 char *body, *page, *tmp;
2100 int i = 1;
2101 struct settings_args sa;
2103 bzero(&sa, sizeof sa);
2104 sa.body = &body;
2106 /* body */
2107 body = g_strdup_printf("<div align='center'><table><tr>"
2108 "<th align='left'>Setting</th>"
2109 "<th align='left'>Value</th></tr>\n");
2111 settings_walk(print_setting, &sa);
2112 i = sa.i;
2114 /* small message if there are none */
2115 if (i == 1) {
2116 tmp = body;
2117 body = g_strdup_printf("%s\n<tr><td style='text-align:center'"
2118 "colspan='2'>No settings</td></tr>\n", body);
2119 g_free(tmp);
2122 tmp = body;
2123 body = g_strdup_printf("%s</table></div>", body);
2124 g_free(tmp);
2126 page = get_html_page("Settings", body, "", 0);
2128 g_free(body);
2130 load_webkit_string(t, page, XT_URI_ABOUT_SET);
2132 g_free(page);
2134 return (XT_CB_PASSTHROUGH);
2138 set(struct tab *t, struct karg *args)
2140 char *p, *val;
2141 int i;
2143 if (args == NULL || args->s == NULL)
2144 return (set_show(t, args));
2146 /* strip spaces */
2147 p = g_strstrip(args->s);
2149 if (strlen(p) == 0)
2150 return (set_show(t, args));
2152 /* we got some sort of string */
2153 val = g_strstr_len(p, strlen(p), "=");
2154 if (val) {
2155 *val++ = '\0';
2156 val = g_strstrip(val);
2157 p = g_strchomp(p);
2159 for (i = 0; i < get_settings_size(); i++) {
2160 if (strcmp(rs[i].name, p))
2161 continue;
2163 if (rs[i].activate) {
2164 if (rs[i].activate(val))
2165 show_oops(t, "%s invalid value %s",
2166 p, val);
2167 else
2168 show_oops(t, ":set %s = %s", p, val);
2169 goto done;
2170 } else {
2171 show_oops(t, "not a runtime option: %s", p);
2172 goto done;
2175 show_oops(t, "unknown option: %s", p);
2176 } else {
2177 p = g_strchomp(p);
2179 for (i = 0; i < get_settings_size(); i++) {
2180 if (strcmp(rs[i].name, p))
2181 continue;
2183 /* XXX this could use some cleanup */
2184 switch (rs[i].type) {
2185 case XT_S_INT:
2186 if (rs[i].ival)
2187 show_oops(t, "%s = %d",
2188 rs[i].name, *rs[i].ival);
2189 else if (rs[i].s && rs[i].s->get)
2190 show_oops(t, "%s = %s",
2191 rs[i].name,
2192 rs[i].s->get(&rs[i]));
2193 else if (rs[i].s && rs[i].s->get == NULL)
2194 show_oops(t, "%s = ...", rs[i].name);
2195 else
2196 show_oops(t, "%s = ", rs[i].name);
2197 break;
2198 case XT_S_FLOAT:
2199 if (rs[i].fval)
2200 show_oops(t, "%s = %f",
2201 rs[i].name, *rs[i].fval);
2202 else if (rs[i].s && rs[i].s->get)
2203 show_oops(t, "%s = %s",
2204 rs[i].name,
2205 rs[i].s->get(&rs[i]));
2206 else if (rs[i].s && rs[i].s->get == NULL)
2207 show_oops(t, "%s = ...", rs[i].name);
2208 else
2209 show_oops(t, "%s = ", rs[i].name);
2210 break;
2211 case XT_S_STR:
2212 if (rs[i].sval && *rs[i].sval)
2213 show_oops(t, "%s = %s",
2214 rs[i].name, *rs[i].sval);
2215 else if (rs[i].s && rs[i].s->get)
2216 show_oops(t, "%s = %s",
2217 rs[i].name,
2218 rs[i].s->get(&rs[i]));
2219 else if (rs[i].s && rs[i].s->get == NULL)
2220 show_oops(t, "%s = ...", rs[i].name);
2221 else
2222 show_oops(t, "%s = ", rs[i].name);
2223 break;
2224 default:
2225 show_oops(t, "unknown type for %s", rs[i].name);
2226 goto done;
2229 goto done;
2231 show_oops(t, "unknown option: %s", p);
2233 done:
2234 return (XT_CB_PASSTHROUGH);