Add a setting to show download notifications via show_oops (default 0)
[xombrero.git] / settings.c
blob9efae47ffead685b45b11f7c36ade4bde5d8ed25
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 enable_js_autorun = 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;
104 int download_notifications = 0;
106 char *cmd_font_name = NULL;
107 char *oops_font_name = NULL;
108 char *statusbar_font_name = NULL;
109 char *tabbar_font_name = NULL;
111 char *get_download_dir(struct settings *);
112 char *get_default_script(struct settings *);
113 char *get_runtime_dir(struct settings *);
114 char *get_tab_style(struct settings *);
115 char *get_edit_mode(struct settings *);
116 char *get_download_mode(struct settings *);
117 char *get_work_dir(struct settings *);
118 char *get_referer(struct settings *);
120 int add_cookie_wl(struct settings *, char *);
121 int add_js_wl(struct settings *, char *);
122 int add_pl_wl(struct settings *, char *);
123 int add_mime_type(struct settings *, char *);
124 int add_alias(struct settings *, char *);
125 int add_kb(struct settings *, char *);
126 int add_ua(struct settings *, char *);
128 int set_append_next(char *);
129 int set_cmd_font(char *);
130 int set_color_visited_uris(char *);
131 int set_cookie_policy_rt(char *);
132 int set_cookies_enabled(char *);
133 int set_ctrl_click_focus(char *);
134 int set_home(char *);
135 int set_download_dir(struct settings *, char *);
136 int set_download_notifications(char *);
137 int set_default_script(struct settings *, char *);
138 int set_default_script_rt(char *);
139 int set_default_zoom_level(char *);
140 int set_enable_cookie_whitelist(char *);
141 int set_enable_js_autorun(char *);
142 int set_enable_js_whitelist(char *);
143 int set_enable_localstorage(char *);
144 int set_enable_plugins(char *);
145 int set_enable_plugin_whitelist(char *);
146 int set_enable_scripts(char *);
147 int set_enable_spell_checking(char *);
148 int set_enable_strict_transport(char *);
149 int set_encoding_rt(char *);
150 int set_runtime_dir(struct settings *, char *);
151 int set_tabbar_font(char *value);
152 int set_tab_style(struct settings *, char *);
153 int set_tab_style_rt(char *);
154 int set_edit_mode(struct settings *, char *);
155 int set_work_dir(struct settings *, char *);
156 int set_auto_load_images(char *);
157 int set_enable_autoscroll(char *);
158 int set_enable_favicon_entry(char *);
159 int set_enable_favicon_tabs(char *);
160 int set_guess_search(char *);
161 int set_download_mode(struct settings *, char *);
162 int set_download_mode_rt(char *);
163 int set_oops_font(char *);
164 int set_read_only_cookies(char *);
165 int set_referer(struct settings *, char *);
166 int set_referer_rt(char *);
167 int set_refresh_interval(char *);
168 int set_search_string(char *s);
169 int set_session_autosave(char *);
170 int set_session_timeout(char *);
171 int set_show_statusbar(char *);
172 int set_show_tabs(char *);
173 int set_show_url(char *);
174 int set_spell_check_languages(char *);
175 int set_ssl_ca_file_rt(char *);
176 int set_ssl_strict_certs(char *);
177 int set_statusbar_font(char *);
178 int set_url_regex(char *);
179 int set_userstyle_global(char *);
180 int set_external_editor(char *);
181 int set_xterm_workaround(char *);
183 void walk_mime_type(struct settings *, void (*)(struct settings *,
184 char *, void *), void *);
185 void walk_alias(struct settings *, void (*)(struct settings *,
186 char *, void *), void *);
187 void walk_cookie_wl(struct settings *, void (*)(struct settings *,
188 char *, void *), void *);
189 void walk_js_wl(struct settings *, void (*)(struct settings *,
190 char *, void *), void *);
191 void walk_pl_wl(struct settings *, void (*)(struct settings *,
192 char *, void *), void *);
193 void walk_kb(struct settings *, void (*)(struct settings *, char *,
194 void *), void *);
195 void walk_ua(struct settings *, void (*)(struct settings *, char *,
196 void *), void *);
199 set_http_proxy(char *proxy)
201 SoupURI *uri;
203 if (proxy == NULL)
204 return (1);
206 /* see if we need to clear it instead */
207 if (strlen(proxy) == 0) {
208 setup_proxy(NULL);
209 return (0);
212 uri = soup_uri_new(proxy);
213 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
214 return (1);
216 setup_proxy(proxy);
218 soup_uri_free(uri);
220 return (0);
223 struct special {
224 int (*set)(struct settings *, char *);
225 char *(*get)(struct settings *);
226 void (*walk)(struct settings *,
227 void (*cb)(struct settings *, char *, void *),
228 void *);
231 struct special s_browser_mode = {
232 set_browser_mode,
233 get_browser_mode,
234 NULL
237 struct special s_gui_mode = {
238 set_gui_mode,
239 get_gui_mode,
240 NULL
243 struct special s_cookie = {
244 set_cookie_policy,
245 get_cookie_policy,
246 NULL
249 struct special s_alias = {
250 add_alias,
251 NULL,
252 walk_alias
255 struct special s_mime = {
256 add_mime_type,
257 NULL,
258 walk_mime_type
261 struct special s_js = {
262 add_js_wl,
263 NULL,
264 walk_js_wl
267 struct special s_pl = {
268 add_pl_wl,
269 NULL,
270 walk_pl_wl
273 struct special s_kb = {
274 add_kb,
275 NULL,
276 walk_kb
279 struct special s_cookie_wl = {
280 add_cookie_wl,
281 NULL,
282 walk_cookie_wl
285 struct special s_default_script = {
286 set_default_script,
287 get_default_script,
288 NULL
291 struct special s_download_dir = {
292 set_download_dir,
293 get_download_dir,
294 NULL
297 struct special s_work_dir = {
298 set_work_dir,
299 get_work_dir,
300 NULL
303 struct special s_tab_style = {
304 set_tab_style,
305 get_tab_style,
306 NULL
309 struct special s_edit_mode = {
310 set_edit_mode,
311 get_edit_mode,
312 NULL
315 struct special s_download_mode = {
316 set_download_mode,
317 get_download_mode,
318 NULL
321 struct special s_ua = {
322 add_ua,
323 NULL,
324 walk_ua
327 struct special s_referer = {
328 set_referer,
329 get_referer,
330 NULL
333 struct settings rs[] = {
334 { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL, NULL, NULL},
335 { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL, NULL, NULL },
336 { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode, NULL, NULL },
337 { "gui_mode", XT_S_INT, 0, NULL, NULL,&s_gui_mode, NULL, NULL },
338 { "color_visited_uris", XT_S_INT, 0, &color_visited_uris , NULL, NULL, NULL, set_color_visited_uris },
339 { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie, NULL, set_cookie_policy_rt },
340 { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL, NULL, set_cookies_enabled },
341 { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL, NULL, set_ctrl_click_focus },
342 { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level, set_default_zoom_level },
343 { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script, NULL, set_default_script_rt },
344 { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir, NULL, NULL },
345 { "download_mode", XT_S_STR, 0, NULL, NULL,&s_download_mode, NULL, set_download_mode_rt },
346 { "edit_mode", XT_S_STR, 0, NULL, NULL,&s_edit_mode, NULL, NULL},
347 { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL, NULL, set_enable_cookie_whitelist },
348 { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL, NULL, set_enable_js_whitelist },
349 { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL, NULL, set_enable_plugin_whitelist },
350 { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL, NULL, set_enable_localstorage },
351 { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL, NULL, set_enable_plugins },
352 { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL, NULL, set_enable_scripts },
353 { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL, NULL, NULL },
354 { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL, NULL, set_enable_spell_checking },
355 { "encoding", XT_S_STR, 0, NULL, &encoding, NULL, NULL, NULL },
356 { "external_editor", XT_S_STR,0, NULL, &external_editor, NULL, NULL, set_external_editor },
357 { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL, NULL, NULL },
358 { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL, NULL, set_guess_search },
359 { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL, NULL, NULL },
360 { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy },
361 { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL, NULL, NULL },
362 { "enable_js_autorun", XT_S_INT, 0, &enable_js_autorun, NULL, NULL, NULL, set_enable_js_autorun },
363 { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL, NULL, NULL },
364 { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL, NULL, NULL },
365 { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL, NULL, set_read_only_cookies },
366 { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL, NULL, set_refresh_interval },
367 { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL, NULL, NULL },
368 { "search_string", XT_S_STR, 0, NULL, &search_string, NULL, NULL, set_search_string },
369 { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL, NULL, NULL },
370 { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL, NULL, NULL },
371 { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL, NULL, set_session_timeout },
372 { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL, NULL, set_session_autosave },
373 { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL, NULL, NULL },
374 { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL, NULL, set_show_tabs },
375 { "show_url", XT_S_INT, 0, &show_url, NULL, NULL, NULL, set_show_url },
376 { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL, NULL, set_show_statusbar },
377 { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL, NULL, set_spell_check_languages },
378 { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL, NULL, set_ssl_ca_file_rt },
379 { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL, NULL, set_ssl_strict_certs },
380 { "enable_strict_transport", XT_S_INT, 0, &enable_strict_transport, NULL, NULL, NULL, set_enable_strict_transport },
381 { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL, NULL, NULL },
382 { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style, NULL, set_tab_style_rt },
383 { "userstyle_global", XT_S_INT, 0, &userstyle_global, NULL, NULL, NULL, set_userstyle_global },
384 { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL, NULL, set_url_regex },
385 { "window_height", XT_S_INT, 0, &window_height, NULL, NULL, NULL, NULL },
386 { "window_width", XT_S_INT, 0, &window_width, NULL, NULL, NULL, NULL },
387 { "window_maximize", XT_S_INT, 0, &window_maximize, NULL, NULL, NULL, NULL },
388 { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir, NULL, NULL },
389 { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL, NULL, set_xterm_workaround },
390 { "auto_load_images", XT_S_INT, 0, &auto_load_images, NULL, NULL, NULL, set_auto_load_images },
391 { "enable_favicon_entry", XT_S_INT, 0, &enable_favicon_entry, NULL, NULL, NULL, set_enable_favicon_entry },
392 { "enable_favicon_tabs", XT_S_INT, 0, &enable_favicon_tabs, NULL, NULL, NULL, set_enable_favicon_tabs },
393 { "referer", XT_S_STR, 0, NULL, NULL,&s_referer, NULL, set_referer_rt },
394 { "download_notifications", XT_S_INT, 0, &download_notifications, NULL, NULL, NULL, set_download_notifications },
396 /* font settings */
397 { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL, NULL, set_cmd_font },
398 { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL, NULL, set_oops_font },
399 { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL, NULL, set_statusbar_font },
400 { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL, NULL, set_tabbar_font },
402 /* runtime settings */
403 { "append_next", XT_S_INT, 0, &append_next, NULL, NULL, NULL, set_append_next },
404 { "enable_autoscroll", XT_S_INT, 0, &enable_autoscroll, NULL, NULL, NULL, set_enable_autoscroll },
405 { "home", XT_S_STR, 0, NULL, &home, NULL, NULL, set_home },
407 /* special settings */
408 { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias, NULL, NULL },
409 { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl, NULL, NULL },
410 { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js, NULL, NULL },
411 { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
412 { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
413 { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
414 { "user_agent", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
418 set_default_zoom_level(char *value)
420 struct karg args = {0};
421 struct tab *t;
423 if (value == NULL || strlen(value) == 0)
424 return (-1);
425 default_zoom_level = g_strtod(value, NULL);
426 args.i = 100; /* adjust = 100 percent for no additional adjustment */
427 TAILQ_FOREACH(t, &tabs, entry)
428 resizetab(t, &args);
429 return (0);
433 set_cookies_enabled(char *value)
435 int tmp;
436 const char *errstr;
438 tmp = strtonum(value, 0, 1, &errstr);
439 if (errstr)
440 return (-1);
441 cookies_enabled = tmp;
442 return (0);
446 set_append_next(char *value)
448 int tmp;
449 const char *errstr;
451 tmp = strtonum(value, 0, 1, &errstr);
452 if (errstr)
453 return (-1);
454 append_next = tmp;
455 return (0);
459 set_cmd_font(char *value)
461 struct tab *t;
463 if (value == NULL || strlen(value))
464 return (-1);
465 if (cmd_font_name)
466 g_free(cmd_font_name);
467 if (cmd_font)
468 pango_font_description_free(cmd_font);
469 cmd_font_name = g_strdup(value);
470 cmd_font = pango_font_description_from_string(cmd_font_name);
471 TAILQ_FOREACH(t, &tabs, entry)
472 gtk_widget_modify_font(GTK_WIDGET(t->cmd), cmd_font);
473 return (0);
477 set_oops_font(char *value)
479 struct tab *t;
481 if (value == NULL || strlen(value) == 0)
482 return (-1);
483 if (oops_font_name)
484 g_free(oops_font_name);
485 if (oops_font)
486 pango_font_description_free(oops_font);
487 oops_font_name = g_strdup(value);
488 oops_font = pango_font_description_from_string(oops_font_name);
489 TAILQ_FOREACH(t, &tabs, entry)
490 gtk_widget_modify_font(GTK_WIDGET(t->oops), oops_font);
491 return (0);
495 set_statusbar_font(char *value)
497 struct tab *t;
499 if (value == NULL || strlen(value) == 0)
500 return (-1);
501 if (statusbar_font_name)
502 g_free(statusbar_font_name);
503 if (statusbar_font)
504 pango_font_description_free(statusbar_font);
505 statusbar_font_name = g_strdup(value);
506 statusbar_font = pango_font_description_from_string(
507 statusbar_font_name);
508 TAILQ_FOREACH(t, &tabs, entry) {
509 gtk_widget_modify_font(GTK_WIDGET(t->sbe.statusbar),
510 statusbar_font);
511 gtk_widget_modify_font(GTK_WIDGET(t->sbe.buffercmd),
512 statusbar_font);
513 gtk_widget_modify_font(GTK_WIDGET(t->sbe.zoom),
514 statusbar_font);
515 gtk_widget_modify_font(GTK_WIDGET(t->sbe.position),
516 statusbar_font);
518 return (0);
522 set_tabbar_font(char *value)
524 struct tab *t;
526 if (value == NULL || strlen(value) == 0)
527 return (-1);
528 if (tabbar_font_name)
529 g_free(tabbar_font_name);
530 if (tabbar_font)
531 pango_font_description_free(tabbar_font);
532 tabbar_font_name = g_strdup(value);
533 tabbar_font = pango_font_description_from_string(tabbar_font_name);
534 TAILQ_FOREACH(t, &tabs, entry)
535 gtk_widget_modify_font(GTK_WIDGET(t->tab_elems.label),
536 tabbar_font);
537 return (0);
541 set_color_visited_uris(char *value)
543 int tmp;
544 const char *errstr;
546 tmp = strtonum(value, 0, 1, &errstr);
547 if (errstr)
548 return (-1);
549 color_visited_uris = tmp;
550 return (0);
554 set_home(char *value)
556 if (value == NULL || strlen(value) == 0)
557 return (-1);
558 if (home)
559 g_free(home);
560 home = g_strdup(value);
561 return (0);
565 set_search_string(char *value)
567 if (value == NULL || strlen(value) == 0)
568 return (-1);
569 if (search_string)
570 g_free(search_string);
571 search_string = g_strdup(value);
572 return (0);
575 size_t
576 get_settings_size(void)
578 return (LENGTH(rs));
581 char *
582 get_setting_name(int i)
584 if (i > LENGTH(rs))
585 return (NULL);
586 return (rs[i].name);
589 char *
590 get_as_string(struct settings *s)
592 char *r = NULL;
594 if (s == NULL)
595 return (NULL);
597 if (s->s) {
598 if (s->s->get)
599 r = s->s->get(s);
600 else
601 warnx("get_as_string skip %s\n", s->name);
602 } else if (s->type == XT_S_INT)
603 r = g_strdup_printf("%d", *s->ival);
604 else if (s->type == XT_S_STR)
605 r = g_strdup(*s->sval);
606 else if (s->type == XT_S_FLOAT)
607 r = g_strdup_printf("%f", *s->fval);
608 else
609 r = g_strdup_printf("INVALID TYPE");
611 return (r);
614 void
615 settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args)
617 int i;
618 char *s;
620 for (i = 0; i < LENGTH(rs); i++) {
621 if (rs[i].s && rs[i].s->walk)
622 rs[i].s->walk(&rs[i], cb, cb_args);
623 else {
624 s = get_as_string(&rs[i]);
625 cb(&rs[i], s, cb_args);
626 g_free(s);
632 set_browser_mode(struct settings *s, char *val)
634 if (!strcmp(val, "whitelist")) {
635 browser_mode = XT_BM_WHITELIST;
636 allow_volatile_cookies = 0;
637 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
638 cookies_enabled = 1;
639 enable_cookie_whitelist = 1;
640 enable_plugin_whitelist = 1;
641 enable_plugins = 0;
642 read_only_cookies = 0;
643 save_rejected_cookies = 0;
644 session_timeout = 3600;
645 enable_scripts = 0;
646 enable_js_whitelist = 1;
647 enable_localstorage = 0;
648 referer_mode = XT_REFERER_SAME_DOMAIN;
649 } else if (!strcmp(val, "normal")) {
650 browser_mode = XT_BM_NORMAL;
651 allow_volatile_cookies = 0;
652 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
653 cookies_enabled = 1;
654 enable_cookie_whitelist = 0;
655 enable_plugin_whitelist = 0;
656 enable_plugins = 1;
657 read_only_cookies = 0;
658 save_rejected_cookies = 0;
659 session_timeout = 3600;
660 enable_scripts = 1;
661 enable_js_whitelist = 0;
662 enable_localstorage = 1;
663 referer_mode = XT_REFERER_ALWAYS;
664 } else if (!strcmp(val, "kiosk")) {
665 browser_mode = XT_BM_KIOSK;
666 allow_volatile_cookies = 0;
667 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
668 cookies_enabled = 1;
669 enable_cookie_whitelist = 0;
670 enable_plugin_whitelist = 0;
671 enable_plugins = 1;
672 read_only_cookies = 0;
673 save_rejected_cookies = 0;
674 session_timeout = 3600;
675 enable_scripts = 1;
676 enable_js_whitelist = 0;
677 enable_localstorage = 1;
678 referer_mode = XT_REFERER_ALWAYS;
679 show_tabs = 0;
680 tabless = 1;
681 } else
682 return (1);
684 return (0);
687 char *
688 get_browser_mode(struct settings *s)
690 char *r = NULL;
692 if (browser_mode == XT_BM_WHITELIST)
693 r = g_strdup("whitelist");
694 else if (browser_mode == XT_BM_NORMAL)
695 r = g_strdup("normal");
696 else if (browser_mode == XT_BM_KIOSK)
697 r = g_strdup("kiosk");
698 else
699 return (NULL);
701 return (r);
705 set_gui_mode(struct settings *s, char *val)
707 if (!strcmp(val, "classic")) {
708 fancy_bar = 1;
709 show_tabs = 1;
710 tab_style = XT_TABS_NORMAL;
711 show_url = 1;
712 show_statusbar = 0;
713 } else if (!strcmp(val, "minimal")) {
714 fancy_bar = 0;
715 show_tabs = 1;
716 tab_style = XT_TABS_COMPACT;
717 show_url = 0;
718 show_statusbar = 1;
719 } else
720 return (1);
722 return (0);
725 char *
726 get_gui_mode(struct settings *s)
728 char *r = NULL;
730 if (gui_mode == XT_GM_CLASSIC)
731 r = g_strdup("classic");
732 else if (browser_mode == XT_GM_MINIMAL)
733 r = g_strdup("minimal");
734 else
735 return (NULL);
737 return (r);
741 set_cookie_policy(struct settings *s, char *val)
743 if (!strcmp(val, "no3rdparty"))
744 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
745 else if (!strcmp(val, "accept"))
746 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
747 else if (!strcmp(val, "reject"))
748 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
749 else
750 return (1);
752 return (0);
756 set_cookie_policy_rt(char *value)
758 if (set_cookie_policy(NULL, value))
759 return (-1);
760 g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY,
761 cookie_policy, (void *)NULL);
762 return (0);
765 char *
766 get_cookie_policy(struct settings *s)
768 char *r = NULL;
770 if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY)
771 r = g_strdup("no3rdparty");
772 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
773 r = g_strdup("accept");
774 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
775 r = g_strdup("reject");
776 else
777 return (NULL);
779 return (r);
782 char *
783 get_default_script(struct settings *s)
785 if (default_script[0] == '\0')
786 return (0);
787 return (g_strdup(default_script));
791 set_default_script(struct settings *s, char *val)
793 if (val[0] == '~')
794 snprintf(default_script, sizeof default_script, "%s" PS "%s",
795 pwd->pw_dir, &val[1]);
796 else
797 strlcpy(default_script, val, sizeof default_script);
799 return (0);
803 set_default_script_rt(char *value)
805 if (value == NULL || strlen(value) == 0)
806 return (-1);
807 return (set_default_script(NULL, value));
810 char *
811 get_download_dir(struct settings *s)
813 if (download_dir[0] == '\0')
814 return (0);
815 return (g_strdup(download_dir));
819 set_download_dir(struct settings *s, char *val)
821 if (val[0] == '~')
822 snprintf(download_dir, sizeof download_dir, "%s" PS "%s",
823 pwd->pw_dir, &val[1]);
824 else
825 strlcpy(download_dir, val, sizeof download_dir);
827 return (0);
831 add_alias(struct settings *s, char *line)
833 char *l, *alias;
834 struct alias *a = NULL;
836 if (s == NULL || line == NULL) {
837 show_oops(NULL, "add_alias invalid parameters");
838 return (1);
841 l = line;
842 a = g_malloc(sizeof(*a));
844 if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) {
845 show_oops(NULL, "add_alias: incomplete alias definition");
846 goto bad;
848 if (strlen(alias) == 0 || strlen(l) == 0) {
849 show_oops(NULL, "add_alias: invalid alias definition");
850 goto bad;
853 a->a_name = g_strdup(alias);
854 a->a_uri = g_strdup(l);
856 DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri);
858 TAILQ_INSERT_TAIL(&aliases, a, entry);
860 return (0);
861 bad:
862 if (a)
863 g_free(a);
864 return (1);
867 void
868 walk_alias(struct settings *s,
869 void (*cb)(struct settings *, char *, void *), void *cb_args)
871 struct alias *a;
872 char *str;
874 if (s == NULL || cb == NULL) {
875 show_oops(NULL, "walk_alias invalid parameters");
876 return;
879 TAILQ_FOREACH(a, &aliases, entry) {
880 str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri);
881 cb(s, str, cb_args);
882 g_free(str);
887 add_mime_type(struct settings *s, char *line)
889 char *mime_type;
890 char *l;
891 struct mime_type *m = NULL;
892 int downloadfirst = 0;
894 /* XXX this could be smarter */
896 if (line == NULL || strlen(line) == 0) {
897 show_oops(NULL, "add_mime_type invalid parameters");
898 return (1);
901 l = line;
902 if (*l == '@') {
903 downloadfirst = 1;
904 l++;
906 m = g_malloc(sizeof(*m));
908 if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) {
909 show_oops(NULL, "add_mime_type: invalid mime_type");
910 goto bad;
912 if (mime_type[strlen(mime_type) - 1] == '*') {
913 mime_type[strlen(mime_type) - 1] = '\0';
914 m->mt_default = 1;
915 } else
916 m->mt_default = 0;
918 if (strlen(mime_type) == 0 || strlen(l) == 0) {
919 show_oops(NULL, "add_mime_type: invalid mime_type");
920 goto bad;
923 m->mt_type = g_strdup(mime_type);
924 m->mt_action = g_strdup(l);
925 m->mt_download = downloadfirst;
927 DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n",
928 m->mt_type, m->mt_action, m->mt_default);
930 TAILQ_INSERT_TAIL(&mtl, m, entry);
932 return (0);
933 bad:
934 if (m)
935 g_free(m);
936 return (1);
939 void
940 walk_mime_type(struct settings *s,
941 void (*cb)(struct settings *, char *, void *), void *cb_args)
943 struct mime_type *m;
944 char *str;
946 if (s == NULL || cb == NULL) {
947 show_oops(NULL, "walk_mime_type invalid parameters");
948 return;
951 TAILQ_FOREACH(m, &mtl, entry) {
952 str = g_strdup_printf("%s%s --> %s",
953 m->mt_type,
954 m->mt_default ? "*" : "",
955 m->mt_action);
956 cb(s, str, cb_args);
957 g_free(str);
961 /* inherent to GTK not all keys will be caught at all times */
962 /* XXX sort key bindings */
963 struct key_binding keys[] = {
964 { "command_mode", 0, 1, GDK_Escape },
965 { "insert_mode", 0, 0, GDK_i },
966 { "cookiejar", MOD1, 1, GDK_j },
967 { "downloadmgr", MOD1, 1, GDK_d },
968 { "history", MOD1, 1, GDK_h },
969 { "print", CTRL, 1, GDK_p },
970 { "search", 0, 0, GDK_slash },
971 { "searchb", 0, 0, GDK_question },
972 { "statustoggle", CTRL, 1, GDK_n },
973 { "command", 0, 0, GDK_colon },
974 { "qa", CTRL, 1, GDK_q },
975 { "restart", MOD1, 1, GDK_q },
976 { "js toggle", CTRL, 1, GDK_j },
977 { "plugin toggle", MOD1, 1, GDK_p },
978 { "cookie toggle", MOD1, 1, GDK_c },
979 { "togglesrc", CTRL, 1, GDK_s },
980 { "yankuri", 0, 0, GDK_y },
981 { "pasteuricur", 0, 0, GDK_p },
982 { "pasteurinew", 0, 0, GDK_P },
983 { "toplevel toggle", 0, 1, GDK_F4 },
984 { "help", 0, 1, GDK_F1 },
985 { "run_script", MOD1, 1, GDK_r },
986 { "proxy toggle", 0, 1, GDK_F2 },
987 { "editelement", CTRL, 1, GDK_i },
988 { "passthrough", CTRL, 1, GDK_z },
989 { "modurl", CTRL, 1, GDK_Return },
991 /* search */
992 { "searchnext", 0, 0, GDK_n },
993 { "searchprevious", 0, 0, GDK_N },
995 /* focus */
996 { "focusaddress", 0, 1, GDK_F6 },
997 { "focussearch", 0, 1, GDK_F7 },
999 /* hinting */
1000 { "hinting", 0, 0, GDK_f },
1001 { "hinting", 0, 0, GDK_period },
1002 { "hinting_newtab", SHFT, 0, GDK_F },
1003 { "hinting_newtab", 0, 0, GDK_comma },
1005 /* custom stylesheet */
1006 { "userstyle", 0, 0, GDK_s },
1007 { "userstyle_global", SHFT, 0, GDK_S },
1009 /* navigation */
1010 { "goback", 0, 0, GDK_BackSpace },
1011 { "goback", MOD1, 1, GDK_Left },
1012 { "goforward", SHFT, 1, GDK_BackSpace },
1013 { "goforward", MOD1, 1, GDK_Right },
1014 { "reload", 0, 1, GDK_F5 },
1015 { "reload", CTRL, 1, GDK_r },
1016 { "reload", CTRL, 1, GDK_l },
1017 { "favorites", MOD1, 1, GDK_f },
1019 /* vertical movement */
1020 { "scrolldown", 0, 0, GDK_j },
1021 { "scrolldown", 0, 0, GDK_Down },
1022 { "scrollup", 0, 0, GDK_Up },
1023 { "scrollup", 0, 0, GDK_k },
1024 { "scrollbottom", 0, 0, GDK_G },
1025 { "scrollbottom", 0, 0, GDK_End },
1026 { "scrolltop", 0, 0, GDK_Home },
1027 { "scrollpagedown", 0, 0, GDK_space },
1028 { "scrollpagedown", CTRL, 1, GDK_f },
1029 { "scrollhalfdown", CTRL, 1, GDK_d },
1030 { "scrollpagedown", 0, 0, GDK_Page_Down },
1031 { "scrollpageup", 0, 0, GDK_Page_Up },
1032 { "scrollpageup", CTRL, 1, GDK_b },
1033 { "scrollhalfup", CTRL, 1, GDK_u },
1034 /* horizontal movement */
1035 { "scrollright", 0, 0, GDK_l },
1036 { "scrollright", 0, 0, GDK_Right },
1037 { "scrollleft", 0, 0, GDK_Left },
1038 { "scrollleft", 0, 0, GDK_h },
1039 { "scrollfarright", 0, 0, GDK_dollar },
1040 { "scrollfarleft", 0, 0, GDK_0 },
1042 /* tabs */
1043 { "tabnew", CTRL, 1, GDK_t },
1044 { "999tabnew", CTRL, 1, GDK_T },
1045 { "tabclose", CTRL, 1, GDK_w },
1046 { "tabundoclose", 0, 0, GDK_U },
1047 { "tabnext 1", CTRL, 1, GDK_1 },
1048 { "tabnext 2", CTRL, 1, GDK_2 },
1049 { "tabnext 3", CTRL, 1, GDK_3 },
1050 { "tabnext 4", CTRL, 1, GDK_4 },
1051 { "tabnext 5", CTRL, 1, GDK_5 },
1052 { "tabnext 6", CTRL, 1, GDK_6 },
1053 { "tabnext 7", CTRL, 1, GDK_7 },
1054 { "tabnext 8", CTRL, 1, GDK_8 },
1055 { "tabnext 9", CTRL, 1, GDK_9 },
1056 { "tabfirst", CTRL, 1, GDK_less },
1057 { "tablast", CTRL, 1, GDK_greater },
1058 { "tabprevious", CTRL, 1, GDK_Left },
1059 { "tabnext", CTRL, 1, GDK_Right },
1060 { "focusout", CTRL, 1, GDK_minus },
1061 { "focusin", CTRL, 1, GDK_plus },
1062 { "focusin", CTRL, 1, GDK_equal },
1063 { "focusreset", CTRL, 1, GDK_0 },
1065 /* command aliases (handy when -S flag is used) */
1066 { "promptopen", 0, 1, GDK_F9 },
1067 { "promptopencurrent", 0, 1, GDK_F10 },
1068 { "prompttabnew", 0, 1, GDK_F11 },
1069 { "prompttabnewcurrent",0, 1, GDK_F12 },
1072 void
1073 walk_kb(struct settings *s,
1074 void (*cb)(struct settings *, char *, void *), void *cb_args)
1076 struct key_binding *k;
1077 char str[1024];
1079 if (s == NULL || cb == NULL) {
1080 show_oops(NULL, "walk_kb invalid parameters");
1081 return;
1084 TAILQ_FOREACH(k, &kbl, entry) {
1085 if (k->cmd == NULL)
1086 continue;
1087 str[0] = '\0';
1089 /* sanity */
1090 if (gdk_keyval_name(k->key) == NULL)
1091 continue;
1093 strlcat(str, k->cmd, sizeof str);
1094 strlcat(str, ",", sizeof str);
1096 if (k->mask & GDK_SHIFT_MASK)
1097 strlcat(str, "S-", sizeof str);
1098 if (k->mask & GDK_CONTROL_MASK)
1099 strlcat(str, "C-", sizeof str);
1100 if (k->mask & GDK_MOD1_MASK)
1101 strlcat(str, "M1-", sizeof str);
1102 if (k->mask & GDK_MOD2_MASK)
1103 strlcat(str, "M2-", sizeof str);
1104 if (k->mask & GDK_MOD3_MASK)
1105 strlcat(str, "M3-", sizeof str);
1106 if (k->mask & GDK_MOD4_MASK)
1107 strlcat(str, "M4-", sizeof str);
1108 if (k->mask & GDK_MOD5_MASK)
1109 strlcat(str, "M5-", sizeof str);
1111 strlcat(str, gdk_keyval_name(k->key), sizeof str);
1112 cb(s, str, cb_args);
1116 void
1117 init_keybindings(void)
1119 int i;
1120 struct key_binding *k;
1122 for (i = 0; i < LENGTH(keys); i++) {
1123 k = g_malloc0(sizeof *k);
1124 k->cmd = keys[i].cmd;
1125 k->mask = keys[i].mask;
1126 k->use_in_entry = keys[i].use_in_entry;
1127 k->key = keys[i].key;
1128 TAILQ_INSERT_HEAD(&kbl, k, entry);
1130 DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n",
1131 k->cmd ? k->cmd : "unnamed key");
1135 void
1136 keybinding_clearall(void)
1138 struct key_binding *k, *next;
1140 for (k = TAILQ_FIRST(&kbl); k; k = next) {
1141 next = TAILQ_NEXT(k, entry);
1142 if (k->cmd == NULL)
1143 continue;
1145 DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n",
1146 k->cmd ? k->cmd : "unnamed key");
1147 TAILQ_REMOVE(&kbl, k, entry);
1148 g_free(k);
1153 keybinding_add(char *cmd, char *key, int use_in_entry)
1155 struct key_binding *k;
1156 guint keyval, mask = 0;
1157 int i;
1159 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key);
1161 /* Keys which are to be used in entry have been prefixed with an
1162 * exclamation mark. */
1163 if (use_in_entry)
1164 key++;
1166 /* find modifier keys */
1167 if (strstr(key, "S-"))
1168 mask |= GDK_SHIFT_MASK;
1169 if (strstr(key, "C-"))
1170 mask |= GDK_CONTROL_MASK;
1171 if (strstr(key, "M1-"))
1172 mask |= GDK_MOD1_MASK;
1173 if (strstr(key, "M2-"))
1174 mask |= GDK_MOD2_MASK;
1175 if (strstr(key, "M3-"))
1176 mask |= GDK_MOD3_MASK;
1177 if (strstr(key, "M4-"))
1178 mask |= GDK_MOD4_MASK;
1179 if (strstr(key, "M5-"))
1180 mask |= GDK_MOD5_MASK;
1182 /* find keyname */
1183 for (i = strlen(key) - 1; i > 0; i--)
1184 if (key[i] == '-')
1185 key = &key[i + 1];
1187 /* validate keyname */
1188 keyval = gdk_keyval_from_name(key);
1189 if (keyval == GDK_VoidSymbol) {
1190 warnx("invalid keybinding name %s", key);
1191 return (1);
1193 /* must run this test too, gtk+ doesn't handle 10 for example */
1194 if (gdk_keyval_name(keyval) == NULL) {
1195 warnx("invalid keybinding name %s", key);
1196 return (1);
1199 /* Remove eventual dupes. */
1200 TAILQ_FOREACH(k, &kbl, entry)
1201 if (k->key == keyval && k->mask == mask) {
1202 TAILQ_REMOVE(&kbl, k, entry);
1203 g_free(k);
1204 break;
1207 /* add keyname */
1208 k = g_malloc0(sizeof *k);
1209 k->cmd = g_strdup(cmd);
1210 k->mask = mask;
1211 k->use_in_entry = use_in_entry;
1212 k->key = keyval;
1214 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n",
1215 k->cmd,
1216 k->mask,
1217 k->use_in_entry,
1218 k->key);
1219 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n",
1220 k->cmd, gdk_keyval_name(keyval));
1222 TAILQ_INSERT_HEAD(&kbl, k, entry);
1224 return (0);
1228 add_kb(struct settings *s, char *entry)
1230 char *kb, *key;
1232 DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry);
1234 /* clearall is special */
1235 if (!strcmp(entry, "clearall")) {
1236 keybinding_clearall();
1237 return (0);
1240 kb = strstr(entry, ",");
1241 if (kb == NULL)
1242 return (1);
1243 *kb = '\0';
1244 key = kb + 1;
1246 return (keybinding_add(entry, key, key[0] == '!'));
1250 add_ua(struct settings *s, char *value)
1252 struct user_agent *ua;
1254 ua = g_malloc0(sizeof *ua);
1255 ua->value = g_strdup(value);
1257 TAILQ_INSERT_HEAD(&ua_list, ua, entry);
1259 /* use the last added user agent */
1260 user_agent = TAILQ_FIRST(&ua_list);
1261 user_agent_count++;
1263 return (0);
1267 void
1268 walk_ua(struct settings *s,
1269 void (*cb)(struct settings *, char *, void *), void *cb_args)
1271 struct user_agent *ua;
1273 if (s == NULL || cb == NULL) {
1274 show_oops(NULL, "walk_ua invalid parameters");
1275 return;
1278 TAILQ_FOREACH(ua, &ua_list, entry)
1279 cb(s, ua->value, cb_args);
1283 set_auto_load_images(char *value)
1285 struct tab *t;
1286 int tmp;
1287 const char *errstr;
1289 tmp = strtonum(value, 0, 1, &errstr);
1290 if (errstr)
1291 return (-1);
1292 auto_load_images = tmp;
1293 TAILQ_FOREACH(t, &tabs, entry) {
1294 g_object_set(G_OBJECT(t->settings),
1295 "auto-load-images", auto_load_images, (char *)NULL);
1296 webkit_web_view_set_settings(t->wv, t->settings);
1298 return (0);
1302 set_ctrl_click_focus(char *value)
1304 int tmp;
1305 const char *errstr;
1307 tmp = strtonum(value, 0, 1, &errstr);
1308 if (errstr)
1309 return (-1);
1310 ctrl_click_focus = tmp;
1311 return (0);
1315 set_download_notifications(char *value)
1317 int tmp;
1318 const char *errstr;
1320 tmp = strtonum(value, 0, 1, &errstr);
1321 if (errstr)
1322 return (-1);
1323 download_notifications = tmp;
1324 return (0);
1328 set_enable_autoscroll(char *value)
1330 int tmp;
1331 const char *errstr;
1333 tmp = strtonum(value, 0, 1, &errstr);
1334 if (errstr)
1335 return (-1);
1336 enable_autoscroll = tmp;
1337 return (0);
1341 set_enable_cookie_whitelist(char *value)
1343 int tmp;
1344 const char *errstr;
1346 tmp = strtonum(value, 0, 1, &errstr);
1347 if (errstr)
1348 return (-1);
1349 enable_cookie_whitelist = tmp;
1350 return (0);
1354 set_enable_js_autorun(char *value)
1356 int tmp;
1357 const char *errstr;
1359 tmp = strtonum(value, 0, 1, &errstr);
1360 if (errstr)
1361 return (-1);
1362 enable_js_autorun = tmp;
1363 return (0);
1367 set_enable_js_whitelist(char *value)
1369 int tmp;
1370 const char *errstr;
1372 tmp = strtonum(value, 0, 1, &errstr);
1373 if (errstr)
1374 return (-1);
1375 enable_js_whitelist = tmp;
1376 return (0);
1380 set_enable_favicon_entry(char *value)
1382 int tmp;
1383 const char *errstr;
1385 tmp = strtonum(value, 0, 1, &errstr);
1386 if (errstr)
1387 return (-1);
1388 enable_favicon_entry = tmp;
1389 return (0);
1393 set_enable_favicon_tabs(char *value)
1395 int tmp;
1396 const char *errstr;
1398 tmp = strtonum(value, 0, 1, &errstr);
1399 if (errstr)
1400 return (-1);
1401 enable_favicon_tabs = tmp;
1402 return (0);
1406 set_enable_localstorage(char *value)
1408 struct tab *t;
1409 int tmp;
1410 const char *errstr;
1412 tmp = strtonum(value, 0, 1, &errstr);
1413 if (errstr)
1414 return (-1);
1415 enable_localstorage = tmp;
1416 TAILQ_FOREACH(t, &tabs, entry) {
1417 g_object_set(G_OBJECT(t->settings),
1418 "enable-html5-local-storage", enable_localstorage,
1419 (char *)NULL);
1421 return (0);
1425 set_enable_plugins(char *value)
1427 struct tab *t;
1428 int tmp;
1429 const char *errstr;
1431 tmp = strtonum(value, 0, 1, &errstr);
1432 if (errstr)
1433 return (-1);
1434 enable_plugins = tmp;
1435 TAILQ_FOREACH(t, &tabs, entry)
1436 g_object_set(G_OBJECT(t->settings), "enable-plugins",
1437 enable_plugins, (char *)NULL);
1438 return (0);
1442 set_enable_plugin_whitelist(char *value)
1444 int tmp;
1445 const char *errstr;
1447 tmp = strtonum(value, 0, 1, &errstr);
1448 if (errstr)
1449 return (-1);
1450 enable_plugin_whitelist = tmp;
1451 return (0);
1455 set_enable_scripts(char *value)
1457 struct tab *t;
1458 int tmp;
1459 const char *errstr;
1461 tmp = strtonum(value, 0, 1, &errstr);
1462 if (errstr)
1463 return (-1);
1464 enable_scripts = tmp;
1465 TAILQ_FOREACH(t, &tabs, entry)
1466 g_object_set(G_OBJECT(t->settings), "enable-scripts",
1467 enable_scripts, (char *)NULL);
1468 return (0);
1472 set_enable_spell_checking(char *value)
1474 struct tab *t;
1475 int tmp;
1476 const char *errstr;
1478 tmp = strtonum(value, 0, 1, &errstr);
1479 if (errstr)
1480 return (-1);
1481 enable_spell_checking = tmp;
1482 TAILQ_FOREACH(t, &tabs, entry)
1483 g_object_set(G_OBJECT(t->settings), "enable_spell_checking",
1484 enable_spell_checking, (char *)NULL);
1485 return (0);
1489 set_enable_strict_transport(char *value)
1491 int tmp;
1492 const char *errstr;
1494 tmp = strtonum(value, 0, 1, &errstr);
1495 if (errstr)
1496 return (-1);
1497 enable_strict_transport = tmp;
1498 return (0);
1501 #if 0
1503 * XXX: this is currently broken. Need to figure out what to do with
1504 * this. Problemm is set_encoding will refresh the tab it's run on, so
1505 * we can either put a big fat warning in the manpage and refresh every
1506 * single open tab with the new encoding or scrap it as a runtime
1507 * setting.
1510 set_encoding_rt(char *value)
1512 struct karg args = {0};
1514 if (value == NULL || strlen(value) == 0)
1515 return (-1);
1516 if (encoding)
1517 g_free(encoding);
1518 encoding = g_strdup(value);
1519 args.s = encoding;
1520 set_encoding(get_current_tab(), &args);
1521 return (0);
1523 #endif
1526 set_guess_search(char *value)
1528 int tmp;
1529 const char *errstr;
1531 tmp = strtonum(value, 0, 1, &errstr);
1532 if (errstr)
1533 return (-1);
1534 guess_search = tmp;
1535 return (0);
1539 set_read_only_cookies(char *value)
1541 int tmp;
1542 const char *errstr;
1544 tmp = strtonum(value, 0, 1, &errstr);
1545 if (errstr)
1546 return (-1);
1547 read_only_cookies = tmp;
1548 g_object_set(G_OBJECT(p_cookiejar), SOUP_COOKIE_JAR_READ_ONLY,
1549 read_only_cookies, (void *)NULL);
1550 return (0);
1553 char *
1554 get_referer(struct settings *s)
1556 if (referer_mode == XT_REFERER_ALWAYS)
1557 return (g_strdup("always"));
1558 if (referer_mode == XT_REFERER_NEVER)
1559 return (g_strdup("never"));
1560 if (referer_mode == XT_REFERER_SAME_DOMAIN)
1561 return (g_strdup("same-domain"));
1562 if (referer_mode == XT_REFERER_SAME_FQDN)
1563 return (g_strdup("same-fqdn"));
1564 if (referer_mode == XT_REFERER_CUSTOM)
1565 return (g_strdup(referer_custom));
1566 return (NULL);
1570 set_referer(struct settings *s, char *value)
1572 if (referer_custom)
1573 g_free(referer_custom);
1575 if (!strcmp(value, "always"))
1576 referer_mode = XT_REFERER_ALWAYS;
1577 else if (!strcmp(value, "never"))
1578 referer_mode = XT_REFERER_NEVER;
1579 else if (!strcmp(value, "same-domain"))
1580 referer_mode = XT_REFERER_SAME_DOMAIN;
1581 else if (!strcmp(value, "same-fqdn"))
1582 referer_mode = XT_REFERER_SAME_FQDN;
1583 else if (!valid_url_type(value)) {
1584 referer_mode = XT_REFERER_CUSTOM;
1585 referer_custom = g_strdup(value);
1586 } else {
1587 /* we've already free'd the custom referer */
1588 if (referer_mode == XT_REFERER_CUSTOM)
1589 referer_mode = XT_REFERER_NEVER;
1590 return (1);
1593 return (0);
1597 set_referer_rt(char *value)
1599 if (value == NULL || strlen(value) == 0)
1600 return (-1);
1601 return (set_referer(NULL, value));
1605 set_refresh_interval(char *value)
1607 int tmp;
1608 const char *errstr;
1610 tmp = strtonum(value, 0, INT_MAX, &errstr);
1611 if (errstr)
1612 return (-1);
1613 refresh_interval = tmp;
1614 return (0);
1618 set_session_autosave(char *value)
1620 int tmp;
1621 const char *errstr;
1623 tmp = strtonum(value, 0, 1, &errstr);
1624 if (errstr)
1625 return (-1);
1626 session_autosave = tmp;
1627 return (0);
1631 set_session_timeout(char *value)
1633 int tmp;
1634 const char *errstr;
1636 tmp = strtonum(value, 0, INT_MAX, &errstr);
1637 if (errstr)
1638 return (-1);
1639 session_timeout = tmp;
1640 return (0);
1644 set_show_statusbar(char *value)
1646 int tmp;
1647 const char *errstr;
1649 tmp = strtonum(value, 0, 1, &errstr);
1650 if (errstr)
1651 return (-1);
1652 show_statusbar = tmp;
1653 statusbar_set_visibility();
1654 return (0);
1658 set_show_tabs(char *value)
1660 struct karg args = {0};
1661 int val;
1662 const char *errstr;
1664 val = strtonum(value, 0, 1, &errstr);
1665 if (errstr)
1666 return (-1);
1667 args.i = val ? XT_TAB_SHOW : XT_TAB_HIDE;
1668 tabaction(get_current_tab(), &args);
1669 return (0);
1673 set_show_url(char *value)
1675 struct karg args = {0};
1676 int val;
1677 const char *errstr;
1679 val = strtonum(value, 0, 1, &errstr);
1680 if (errstr)
1681 return (-1);
1682 args.i = val ? XT_URL_SHOW : XT_URL_HIDE;
1683 urlaction(get_current_tab(), &args);
1684 return (0);
1688 set_spell_check_languages(char *value)
1690 struct tab *t;
1692 if (value == NULL || strlen(value) == 0)
1693 return (-1);
1694 if (spell_check_languages)
1695 g_free(spell_check_languages);
1696 spell_check_languages = g_strdup(value);
1697 TAILQ_FOREACH(t, &tabs, entry)
1698 g_object_set(G_OBJECT(t->settings), "spell_checking_languages",
1699 spell_check_languages, (char *)NULL);
1700 return (0);
1704 check_valid_file(char *name)
1706 struct stat sb;
1708 if (name == NULL || stat(name, &sb))
1709 return (-1);
1710 return (0);
1714 set_ssl_ca_file_rt(char *value)
1716 if (value == NULL || strlen(value) == 0)
1717 return (-1);
1718 if (set_ssl_ca_file(value))
1719 return (-1);
1720 return (0);
1724 set_ssl_strict_certs(char *value)
1726 int tmp;
1727 const char *errstr;
1729 tmp = strtonum(value, 0, 1, &errstr);
1730 if (errstr)
1731 return (-1);
1732 ssl_strict_certs = tmp;
1733 set_ssl_ca_file(ssl_ca_file);
1734 return (0);
1738 set_external_editor(char *editor)
1740 if (external_editor)
1741 g_free(external_editor);
1743 external_editor = g_strdup(editor);
1745 return (0);
1748 void
1749 setup_proxy(char *uri)
1751 if (proxy_uri) {
1752 g_object_set(session, "proxy_uri", NULL, (char *)NULL);
1753 soup_uri_free(proxy_uri);
1754 proxy_uri = NULL;
1756 if (http_proxy) {
1757 if (http_proxy != uri) {
1758 g_free(http_proxy);
1759 http_proxy = NULL;
1763 if (uri) {
1764 http_proxy = g_strdup(uri);
1765 DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri);
1766 proxy_uri = soup_uri_new(http_proxy);
1767 if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri)))
1768 g_object_set(session, "proxy-uri", proxy_uri,
1769 (char *)NULL);
1773 char *
1774 get_tab_style(struct settings *s)
1776 if (tab_style == XT_TABS_NORMAL)
1777 return (g_strdup("normal"));
1778 else
1779 return (g_strdup("compact"));
1783 set_tab_style(struct settings *s, char *val)
1785 if (!strcmp(val, "normal"))
1786 tab_style = XT_TABS_NORMAL;
1787 else if (!strcmp(val, "compact"))
1788 tab_style = XT_TABS_COMPACT;
1789 else
1790 return (1);
1792 return (0);
1796 set_tab_style_rt(char *value)
1798 struct karg args = {0};
1799 int old_tab_style;
1801 old_tab_style = tab_style;
1802 if (set_tab_style(NULL, value))
1803 return (-1);
1804 if (old_tab_style != tab_style) {
1805 tab_style = old_tab_style;
1806 args.i = XT_TAB_NEXTSTYLE;
1807 tabaction(get_current_tab(), &args);
1809 return (0);
1813 set_url_regex(char *value)
1815 if (regcomp(&url_re, value, REG_EXTENDED | REG_NOSUB))
1816 return (-1);
1817 if (url_regex)
1818 g_free(url_regex);
1819 url_regex = g_strdup(value);
1820 return (0);
1824 set_userstyle_global(char *value)
1826 struct karg args = {0};
1827 int tmp, old_style;
1828 const char *errstr;
1830 old_style = userstyle_global;
1831 tmp = strtonum(value, 0, 1, &errstr);
1832 if (errstr)
1833 return (-1);
1834 if (tmp != old_style) {
1835 args.i = XT_STYLE_GLOBAL;
1836 userstyle(get_current_tab(), &args);
1838 return (0);
1841 char *
1842 get_edit_mode(struct settings *s)
1844 if (edit_mode == XT_EM_HYBRID)
1845 return (g_strdup("hybrid"));
1846 else
1847 return (g_strdup("vi"));
1851 set_edit_mode(struct settings *s, char *val)
1853 if (!strcmp(val, "hybrid"))
1854 edit_mode = XT_EM_HYBRID;
1855 else if (!strcmp(val, "vi"))
1856 edit_mode = XT_EM_VI;
1857 else
1858 return (1);
1860 return (0);
1863 char *
1864 get_download_mode(struct settings *s)
1866 switch (download_mode) {
1867 case XT_DM_START:
1868 return (g_strdup("start"));
1869 break;
1870 case XT_DM_ASK:
1871 return (g_strdup("ask"));
1872 break;
1873 case XT_DM_ADD:
1874 return (g_strdup("add"));
1875 break;
1877 return (g_strdup("unknown"));
1881 set_download_mode(struct settings *s, char *val)
1883 if (!strcmp(val, "start"))
1884 download_mode = XT_DM_START;
1885 else if (!strcmp(val, "ask"))
1886 download_mode = XT_DM_ASK;
1887 else if (!strcmp(val, "add"))
1888 download_mode = XT_DM_ADD;
1889 else
1890 return (1);
1892 return (0);
1896 set_download_mode_rt(char *val)
1898 if (val == NULL || strlen(val) == 0)
1899 return (-1);
1900 return (set_download_mode(NULL, val));
1903 char *
1904 get_work_dir(struct settings *s)
1906 if (work_dir[0] == '\0')
1907 return (0);
1908 return (g_strdup(work_dir));
1912 set_work_dir(struct settings *s, char *val)
1914 if (val[0] == '~')
1915 snprintf(work_dir, sizeof work_dir, "%s" PS "%s",
1916 pwd->pw_dir, &val[1]);
1917 else
1918 strlcpy(work_dir, val, sizeof work_dir);
1920 return (0);
1924 set_xterm_workaround(char *value)
1926 int tmp;
1927 const char *errstr;
1929 tmp = strtonum(value, 0, 1, &errstr);
1930 if (errstr)
1931 return (-1);
1932 xterm_workaround = tmp;
1933 return (0);
1936 void
1937 walk_cookie_wl(struct settings *s,
1938 void (*cb)(struct settings *, char *, void *), void *cb_args)
1940 struct domain *d;
1942 if (s == NULL || cb == NULL) {
1943 show_oops(NULL, "walk_cookie_wl invalid parameters");
1944 return;
1947 RB_FOREACH_REVERSE(d, domain_list, &c_wl)
1948 cb(s, d->d, cb_args);
1951 void
1952 walk_js_wl(struct settings *s,
1953 void (*cb)(struct settings *, char *, void *), void *cb_args)
1955 struct domain *d;
1957 if (s == NULL || cb == NULL) {
1958 show_oops(NULL, "walk_js_wl invalid parameters");
1959 return;
1962 RB_FOREACH_REVERSE(d, domain_list, &js_wl)
1963 cb(s, d->d, cb_args);
1966 void
1967 walk_pl_wl(struct settings *s,
1968 void (*cb)(struct settings *, char *, void *), void *cb_args)
1970 struct domain *d;
1972 if (s == NULL || cb == NULL) {
1973 show_oops(NULL, "walk_pl_wl invalid parameters");
1974 return;
1977 RB_FOREACH_REVERSE(d, domain_list, &pl_wl)
1978 cb(s, d->d, cb_args);
1982 settings_add(char *var, char *val)
1984 int i, rv, *p;
1985 gfloat *f;
1986 char **s;
1988 /* get settings */
1989 for (i = 0, rv = 0; i < LENGTH(rs); i++) {
1990 if (strcmp(var, rs[i].name))
1991 continue;
1993 if (rs[i].s) {
1994 if (rs[i].s->set(&rs[i], val))
1995 errx(1, "invalid value for %s: %s", var, val);
1996 rv = 1;
1997 break;
1998 } else
1999 switch (rs[i].type) {
2000 case XT_S_INT:
2001 p = rs[i].ival;
2002 *p = atoi(val);
2003 rv = 1;
2004 break;
2005 case XT_S_STR:
2006 s = rs[i].sval;
2007 if (s == NULL)
2008 errx(1, "invalid sval for %s",
2009 rs[i].name);
2010 if (*s)
2011 g_free(*s);
2012 *s = g_strdup(val);
2013 rv = 1;
2014 break;
2015 case XT_S_FLOAT:
2016 f = rs[i].fval;
2017 *f = atof(val);
2018 rv = 1;
2019 break;
2020 case XT_S_INVALID:
2021 default:
2022 errx(1, "invalid type for %s", var);
2024 break;
2026 return (rv);
2029 #define WS "\n= \t"
2030 void
2031 config_parse(char *filename, int runtime)
2033 FILE *config, *f;
2034 char *line, *cp, *var, *val;
2035 size_t len, lineno = 0;
2036 int handled;
2037 char file[PATH_MAX];
2038 struct stat sb;
2040 DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename);
2042 if (filename == NULL)
2043 return;
2045 if (runtime && runtime_settings[0] != '\0') {
2046 snprintf(file, sizeof file, "%s" PS "%s",
2047 work_dir, runtime_settings);
2048 if (stat(file, &sb)) {
2049 warnx("runtime file doesn't exist, creating it");
2050 if ((f = fopen(file, "w")) == NULL)
2051 err(1, "runtime");
2052 fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n");
2053 fclose(f);
2055 } else
2056 strlcpy(file, filename, sizeof file);
2058 if ((config = fopen(file, "r")) == NULL) {
2059 warn("config_parse: cannot open %s", filename);
2060 return;
2063 for (;;) {
2064 if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
2065 if (feof(config) || ferror(config))
2066 break;
2068 cp = line;
2069 cp += (long)strspn(cp, WS);
2070 if (cp[0] == '\0') {
2071 /* empty line */
2072 free(line);
2073 continue;
2076 if ((var = strsep(&cp, WS)) == NULL || cp == NULL)
2077 startpage_add("invalid configuration file entry: %s",
2078 line);
2079 else {
2080 cp += (long)strspn(cp, WS);
2082 if ((val = strsep(&cp, "\0")) == NULL)
2083 break;
2085 DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n",
2086 var, val);
2087 handled = settings_add(var, val);
2089 if (handled == 0)
2090 startpage_add("invalid configuration file entry"
2091 ": %s=%s", var, val);
2094 free(line);
2097 fclose(config);
2100 struct settings_args {
2101 char **body;
2102 int i;
2105 void
2106 print_setting(struct settings *s, char *val, void *cb_args)
2108 char *tmp, *color;
2109 struct settings_args *sa = cb_args;
2111 if (sa == NULL)
2112 return;
2114 if (s->flags & XT_SF_RUNTIME)
2115 color = "#22cc22";
2116 else
2117 color = "#cccccc";
2119 tmp = *sa->body;
2120 *sa->body = g_strdup_printf(
2121 "%s\n<tr>"
2122 "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>"
2123 "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>",
2124 *sa->body,
2125 color,
2126 s->name,
2127 color,
2130 g_free(tmp);
2131 sa->i++;
2135 set_show(struct tab *t, struct karg *args)
2137 char *body, *page, *tmp;
2138 int i = 1;
2139 struct settings_args sa;
2141 bzero(&sa, sizeof sa);
2142 sa.body = &body;
2144 /* body */
2145 body = g_strdup_printf("<div align='center'><table><tr>"
2146 "<th align='left'>Setting</th>"
2147 "<th align='left'>Value</th></tr>\n");
2149 settings_walk(print_setting, &sa);
2150 i = sa.i;
2152 /* small message if there are none */
2153 if (i == 1) {
2154 tmp = body;
2155 body = g_strdup_printf("%s\n<tr><td style='text-align:center'"
2156 "colspan='2'>No settings</td></tr>\n", body);
2157 g_free(tmp);
2160 tmp = body;
2161 body = g_strdup_printf("%s</table></div>", body);
2162 g_free(tmp);
2164 page = get_html_page("Settings", body, "", 0);
2166 g_free(body);
2168 load_webkit_string(t, page, XT_URI_ABOUT_SET);
2170 g_free(page);
2172 return (XT_CB_PASSTHROUGH);
2176 set(struct tab *t, struct karg *args)
2178 char *p, *val;
2179 int i;
2181 if (args == NULL || args->s == NULL)
2182 return (set_show(t, args));
2184 /* strip spaces */
2185 p = g_strstrip(args->s);
2187 if (strlen(p) == 0)
2188 return (set_show(t, args));
2190 /* we got some sort of string */
2191 val = g_strstr_len(p, strlen(p), "=");
2192 if (val) {
2193 *val++ = '\0';
2194 val = g_strstrip(val);
2195 p = g_strchomp(p);
2197 for (i = 0; i < get_settings_size(); i++) {
2198 if (strcmp(rs[i].name, p))
2199 continue;
2201 if (rs[i].activate) {
2202 if (rs[i].activate(val))
2203 show_oops(t, "%s invalid value %s",
2204 p, val);
2205 else
2206 show_oops(t, ":set %s = %s", p, val);
2207 goto done;
2208 } else {
2209 show_oops(t, "not a runtime option: %s", p);
2210 goto done;
2213 show_oops(t, "unknown option: %s", p);
2214 } else {
2215 p = g_strchomp(p);
2217 for (i = 0; i < get_settings_size(); i++) {
2218 if (strcmp(rs[i].name, p))
2219 continue;
2221 /* XXX this could use some cleanup */
2222 switch (rs[i].type) {
2223 case XT_S_INT:
2224 if (rs[i].ival)
2225 show_oops(t, "%s = %d",
2226 rs[i].name, *rs[i].ival);
2227 else if (rs[i].s && rs[i].s->get)
2228 show_oops(t, "%s = %s",
2229 rs[i].name,
2230 rs[i].s->get(&rs[i]));
2231 else if (rs[i].s && rs[i].s->get == NULL)
2232 show_oops(t, "%s = ...", rs[i].name);
2233 else
2234 show_oops(t, "%s = ", rs[i].name);
2235 break;
2236 case XT_S_FLOAT:
2237 if (rs[i].fval)
2238 show_oops(t, "%s = %f",
2239 rs[i].name, *rs[i].fval);
2240 else if (rs[i].s && rs[i].s->get)
2241 show_oops(t, "%s = %s",
2242 rs[i].name,
2243 rs[i].s->get(&rs[i]));
2244 else if (rs[i].s && rs[i].s->get == NULL)
2245 show_oops(t, "%s = ...", rs[i].name);
2246 else
2247 show_oops(t, "%s = ", rs[i].name);
2248 break;
2249 case XT_S_STR:
2250 if (rs[i].sval && *rs[i].sval)
2251 show_oops(t, "%s = %s",
2252 rs[i].name, *rs[i].sval);
2253 else if (rs[i].s && rs[i].s->get)
2254 show_oops(t, "%s = %s",
2255 rs[i].name,
2256 rs[i].s->get(&rs[i]));
2257 else if (rs[i].s && rs[i].s->get == NULL)
2258 show_oops(t, "%s = ...", rs[i].name);
2259 else
2260 show_oops(t, "%s = ", rs[i].name);
2261 break;
2262 default:
2263 show_oops(t, "unknown type for %s", rs[i].name);
2264 goto done;
2267 goto done;
2269 show_oops(t, "unknown option: %s", p);
2271 done:
2272 return (XT_CB_PASSTHROUGH);