#include <errno.h>
#include <fcntl.h>
#include <signal.h>
+#include <poll.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
#include "uzbl.h"
#include "config.h"
Uzbl uzbl;
/* commandline arguments (set initial values for the state variables) */
-const
+const
GOptionEntry entries[] =
{
- { "uri", 'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri,
- "Uri to load at startup (equivalent to 'set uri = URI')", "URI" },
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &uzbl.state.verbose,
+ { "uri", 'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri,
+ "Uri to load at startup (equivalent to 'uzbl <uri>' or 'set uri = URI' after uzbl has launched)", "URI" },
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &uzbl.state.verbose,
"Whether to print all messages or just errors.", NULL },
- { "name", 'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name,
+ { "name", 'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name,
"Name of the current instance (defaults to Xorg window id)", "NAME" },
- { "config", 'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file,
- "Config file (this is pretty much equivalent to uzbl < FILE )", "FILE" },
- { "socket", 's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id,
+ { "config", 'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file,
+ "Path to config file or '-' for stdin", "FILE" },
+ { "socket", 's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id,
"Socket ID", "SOCKET" },
+ { "geometry", 'g', 0, G_OPTION_ARG_STRING, &uzbl.gui.geometry,
+ "Set window geometry (format: WIDTHxHEIGHT+-X+-Y)", "GEOMETRY" },
+ { "version", 'V', 0, G_OPTION_ARG_NONE, &uzbl.behave.print_version,
+ "Print the version and exit", NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
void **ptr;
int type;
int dump;
+ int writeable;
void (*func)(void);
} uzbl_cmdprop;
enum {TYPE_INT, TYPE_STR, TYPE_FLOAT};
-/* an abbreviation to help keep the table's width humane */
-#define PTR(var, t, d, fun) { .ptr = (void*)&(var), .type = TYPE_##t, .dump = d, .func = fun }
+/* abbreviations to help keep the table's width humane */
+#define PTR_V(var, t, d, fun) { .ptr = (void*)&(var), .type = TYPE_##t, .dump = d, .writeable = 1, .func = fun }
+#define PTR_C(var, t, fun) { .ptr = (void*)&(var), .type = TYPE_##t, .dump = 0, .writeable = 0, .func = fun }
const struct {
char *name;
uzbl_cmdprop cp;
} var_name_to_ptr[] = {
-/* variable name pointer to variable in code type dump callback function */
-/* --------------------------------------------------------------------------------------- */
- { "uri", PTR(uzbl.state.uri, STR, 1, cmd_load_uri)},
- { "verbose", PTR(uzbl.state.verbose, INT, 1, NULL)},
- { "mode", PTR(uzbl.behave.mode, INT, 0, NULL)},
- { "inject_html", PTR(uzbl.behave.inject_html, STR, 0, cmd_inject_html)},
- { "base_url", PTR(uzbl.behave.base_url, STR, 1, NULL)},
- { "html_endmarker", PTR(uzbl.behave.html_endmarker, STR, 1, NULL)},
- { "html_mode_timeout", PTR(uzbl.behave.html_timeout, INT, 1, NULL)},
- { "status_message", PTR(uzbl.gui.sbar.msg, STR, 1, update_title)},
- { "show_status", PTR(uzbl.behave.show_status, INT, 1, cmd_set_status)},
- { "status_top", PTR(uzbl.behave.status_top, INT, 1, move_statusbar)},
- { "status_format", PTR(uzbl.behave.status_format, STR, 1, update_title)},
- { "status_pbar_done", PTR(uzbl.gui.sbar.progress_s, STR, 1, update_title)},
- { "status_pbar_pending", PTR(uzbl.gui.sbar.progress_u, STR, 1, update_title)},
- { "status_pbar_width", PTR(uzbl.gui.sbar.progress_w, INT, 1, update_title)},
- { "status_background", PTR(uzbl.behave.status_background, STR, 1, update_title)},
- { "insert_indicator", PTR(uzbl.behave.insert_indicator, STR, 1, update_title)},
- { "command_indicator", PTR(uzbl.behave.cmd_indicator, STR, 1, update_title)},
- { "title_format_long", PTR(uzbl.behave.title_format_long, STR, 1, update_title)},
- { "title_format_short", PTR(uzbl.behave.title_format_short, STR, 1, update_title)},
- { "icon", PTR(uzbl.gui.icon, STR, 1, set_icon)},
- { "insert_mode", PTR(uzbl.behave.insert_mode, INT, 1, NULL)},
- { "always_insert_mode", PTR(uzbl.behave.always_insert_mode, INT, 1, cmd_always_insert_mode)},
- { "reset_command_mode", PTR(uzbl.behave.reset_command_mode, INT, 1, NULL)},
- { "modkey", PTR(uzbl.behave.modkey, STR, 1, cmd_modkey)},
- { "load_finish_handler", PTR(uzbl.behave.load_finish_handler, STR, 1, NULL)},
- { "load_start_handler", PTR(uzbl.behave.load_start_handler, STR, 1, NULL)},
- { "load_commit_handler", PTR(uzbl.behave.load_commit_handler, STR, 1, NULL)},
- { "history_handler", PTR(uzbl.behave.history_handler, STR, 1, NULL)},
- { "download_handler", PTR(uzbl.behave.download_handler, STR, 1, NULL)},
- { "cookie_handler", PTR(uzbl.behave.cookie_handler, STR, 1, cmd_cookie_handler)},
- { "fifo_dir", PTR(uzbl.behave.fifo_dir, STR, 1, cmd_fifo_dir)},
- { "socket_dir", PTR(uzbl.behave.socket_dir, STR, 1, cmd_socket_dir)},
- { "http_debug", PTR(uzbl.behave.http_debug, INT, 1, cmd_http_debug)},
- { "shell_cmd", PTR(uzbl.behave.shell_cmd, STR, 1, NULL)},
- { "proxy_url", PTR(uzbl.net.proxy_url, STR, 1, set_proxy_url)},
- { "max_conns", PTR(uzbl.net.max_conns, INT, 1, cmd_max_conns)},
- { "max_conns_host", PTR(uzbl.net.max_conns_host, INT, 1, cmd_max_conns_host)},
- { "useragent", PTR(uzbl.net.useragent, STR, 1, cmd_useragent)},
+/* variable name pointer to variable in code type dump callback function */
+/* ---------------------------------------------------------------------------------------------- */
+ { "uri", PTR_V(uzbl.state.uri, STR, 1, cmd_load_uri)},
+ { "verbose", PTR_V(uzbl.state.verbose, INT, 1, NULL)},
+ { "mode", PTR_V(uzbl.behave.mode, INT, 0, NULL)},
+ { "inject_html", PTR_V(uzbl.behave.inject_html, STR, 0, cmd_inject_html)},
+ { "base_url", PTR_V(uzbl.behave.base_url, STR, 1, NULL)},
+ { "html_endmarker", PTR_V(uzbl.behave.html_endmarker, STR, 1, NULL)},
+ { "html_mode_timeout", PTR_V(uzbl.behave.html_timeout, INT, 1, NULL)},
+ { "keycmd", PTR_V(uzbl.state.keycmd, STR, 1, set_keycmd)},
+ { "status_message", PTR_V(uzbl.gui.sbar.msg, STR, 1, update_title)},
+ { "show_status", PTR_V(uzbl.behave.show_status, INT, 1, cmd_set_status)},
+ { "status_top", PTR_V(uzbl.behave.status_top, INT, 1, move_statusbar)},
+ { "status_format", PTR_V(uzbl.behave.status_format, STR, 1, update_title)},
+ { "status_pbar_done", PTR_V(uzbl.gui.sbar.progress_s, STR, 1, update_title)},
+ { "status_pbar_pending", PTR_V(uzbl.gui.sbar.progress_u, STR, 1, update_title)},
+ { "status_pbar_width", PTR_V(uzbl.gui.sbar.progress_w, INT, 1, update_title)},
+ { "status_background", PTR_V(uzbl.behave.status_background, STR, 1, update_title)},
+ { "insert_indicator", PTR_V(uzbl.behave.insert_indicator, STR, 1, update_indicator)},
+ { "command_indicator", PTR_V(uzbl.behave.cmd_indicator, STR, 1, update_indicator)},
+ { "title_format_long", PTR_V(uzbl.behave.title_format_long, STR, 1, update_title)},
+ { "title_format_short", PTR_V(uzbl.behave.title_format_short, STR, 1, update_title)},
+ { "icon", PTR_V(uzbl.gui.icon, STR, 1, set_icon)},
+ { "insert_mode", PTR_V(uzbl.behave.insert_mode, INT, 1, set_mode_indicator)},
+ { "always_insert_mode", PTR_V(uzbl.behave.always_insert_mode, INT, 1, cmd_always_insert_mode)},
+ { "reset_command_mode", PTR_V(uzbl.behave.reset_command_mode, INT, 1, NULL)},
+ { "modkey", PTR_V(uzbl.behave.modkey, STR, 1, cmd_modkey)},
+ { "load_finish_handler", PTR_V(uzbl.behave.load_finish_handler, STR, 1, NULL)},
+ { "load_start_handler", PTR_V(uzbl.behave.load_start_handler, STR, 1, NULL)},
+ { "load_commit_handler", PTR_V(uzbl.behave.load_commit_handler, STR, 1, NULL)},
+ { "history_handler", PTR_V(uzbl.behave.history_handler, STR, 1, NULL)},
+ { "download_handler", PTR_V(uzbl.behave.download_handler, STR, 1, NULL)},
+ { "cookie_handler", PTR_V(uzbl.behave.cookie_handler, STR, 1, cmd_cookie_handler)},
+ { "new_window", PTR_V(uzbl.behave.new_window, STR, 1, cmd_new_window)},
+ { "fifo_dir", PTR_V(uzbl.behave.fifo_dir, STR, 1, cmd_fifo_dir)},
+ { "socket_dir", PTR_V(uzbl.behave.socket_dir, STR, 1, cmd_socket_dir)},
+ { "http_debug", PTR_V(uzbl.behave.http_debug, INT, 1, cmd_http_debug)},
+ { "shell_cmd", PTR_V(uzbl.behave.shell_cmd, STR, 1, NULL)},
+ { "proxy_url", PTR_V(uzbl.net.proxy_url, STR, 1, set_proxy_url)},
+ { "max_conns", PTR_V(uzbl.net.max_conns, INT, 1, cmd_max_conns)},
+ { "max_conns_host", PTR_V(uzbl.net.max_conns_host, INT, 1, cmd_max_conns_host)},
+ { "useragent", PTR_V(uzbl.net.useragent, STR, 1, cmd_useragent)},
+
/* exported WebKitWebSettings properties */
- { "zoom_level", PTR(uzbl.behave.zoom_level, FLOAT,1, cmd_zoom_level)},
- { "font_size", PTR(uzbl.behave.font_size, INT, 1, cmd_font_size)},
- { "monospace_size", PTR(uzbl.behave.monospace_size, INT, 1, cmd_font_size)},
- { "minimum_font_size", PTR(uzbl.behave.minimum_font_size, INT, 1, cmd_minimum_font_size)},
- { "disable_plugins", PTR(uzbl.behave.disable_plugins, INT, 1, cmd_disable_plugins)},
- { "disable_scripts", PTR(uzbl.behave.disable_scripts, INT, 1, cmd_disable_scripts)},
- { "autoload_images", PTR(uzbl.behave.autoload_img, INT, 1, cmd_autoload_img)},
- { "autoshrink_images", PTR(uzbl.behave.autoshrink_img, INT, 1, cmd_autoshrink_img)},
- { "enable_spellcheck", PTR(uzbl.behave.enable_spellcheck, INT, 1, cmd_enable_spellcheck)},
- { "enable_private", PTR(uzbl.behave.enable_private, INT, 1, cmd_enable_private)},
- { "print_backgrounds", PTR(uzbl.behave.print_bg, INT, 1, cmd_print_bg)},
- { "stylesheet_uri", PTR(uzbl.behave.style_uri, STR, 1, cmd_style_uri)},
- { "resizable_text_areas",PTR(uzbl.behave.resizable_txt, INT, 1, cmd_resizable_txt)},
- { "default_encoding", PTR(uzbl.behave.default_encoding, STR, 1, cmd_default_encoding)},
- { "enforce_96_dpi", PTR(uzbl.behave.enforce_96dpi, INT, 1, cmd_enforce_96dpi)},
- { "caret_browsing", PTR(uzbl.behave.caret_browsing, INT, 1, cmd_caret_browsing)},
-
- { NULL, {.ptr = NULL, .type = TYPE_INT, .dump = 0, .func = NULL}}
+ { "zoom_level", PTR_V(uzbl.behave.zoom_level, FLOAT,1, cmd_zoom_level)},
+ { "font_size", PTR_V(uzbl.behave.font_size, INT, 1, cmd_font_size)},
+ { "default_font_family", PTR_V(uzbl.behave.default_font_family, STR, 1, cmd_default_font_family)},
+ { "monospace_font_family", PTR_V(uzbl.behave.monospace_font_family, STR, 1, cmd_monospace_font_family)},
+ { "cursive_font_family", PTR_V(uzbl.behave.cursive_font_family, STR, 1, cmd_cursive_font_family)},
+ { "sans_serif_font_family", PTR_V(uzbl.behave.sans_serif_font_family, STR, 1, cmd_sans_serif_font_family)},
+ { "serif_font_family", PTR_V(uzbl.behave.serif_font_family, STR, 1, cmd_serif_font_family)},
+ { "fantasy_font_family", PTR_V(uzbl.behave.fantasy_font_family, STR, 1, cmd_fantasy_font_family)},
+ { "monospace_size", PTR_V(uzbl.behave.monospace_size, INT, 1, cmd_font_size)},
+ { "minimum_font_size", PTR_V(uzbl.behave.minimum_font_size, INT, 1, cmd_minimum_font_size)},
+ { "disable_plugins", PTR_V(uzbl.behave.disable_plugins, INT, 1, cmd_disable_plugins)},
+ { "disable_scripts", PTR_V(uzbl.behave.disable_scripts, INT, 1, cmd_disable_scripts)},
+ { "autoload_images", PTR_V(uzbl.behave.autoload_img, INT, 1, cmd_autoload_img)},
+ { "autoshrink_images", PTR_V(uzbl.behave.autoshrink_img, INT, 1, cmd_autoshrink_img)},
+ { "enable_spellcheck", PTR_V(uzbl.behave.enable_spellcheck, INT, 1, cmd_enable_spellcheck)},
+ { "enable_private", PTR_V(uzbl.behave.enable_private, INT, 1, cmd_enable_private)},
+ { "print_backgrounds", PTR_V(uzbl.behave.print_bg, INT, 1, cmd_print_bg)},
+ { "stylesheet_uri", PTR_V(uzbl.behave.style_uri, STR, 1, cmd_style_uri)},
+ { "resizable_text_areas", PTR_V(uzbl.behave.resizable_txt, INT, 1, cmd_resizable_txt)},
+ { "default_encoding", PTR_V(uzbl.behave.default_encoding, STR, 1, cmd_default_encoding)},
+ { "enforce_96_dpi", PTR_V(uzbl.behave.enforce_96dpi, INT, 1, cmd_enforce_96dpi)},
+ { "caret_browsing", PTR_V(uzbl.behave.caret_browsing, INT, 1, cmd_caret_browsing)},
+
+ /* constants (not dumpable or writeable) */
+ { "WEBKIT_MAJOR", PTR_C(uzbl.info.webkit_major, INT, NULL)},
+ { "WEBKIT_MINOR", PTR_C(uzbl.info.webkit_minor, INT, NULL)},
+ { "WEBKIT_MICRO", PTR_C(uzbl.info.webkit_micro, INT, NULL)},
+ { "ARCH_UZBL", PTR_C(uzbl.info.arch, STR, NULL)},
+ { "COMMIT", PTR_C(uzbl.info.commit, STR, NULL)},
+ { "LOAD_PROGRESS", PTR_C(uzbl.gui.sbar.load_progress, INT, NULL)},
+ { "LOAD_PROGRESSBAR", PTR_C(uzbl.gui.sbar.progress_bar, STR, NULL)},
+ { "TITLE", PTR_C(uzbl.gui.main_title, STR, NULL)},
+ { "SELECTED_URI", PTR_C(uzbl.state.selected_url, STR, NULL)},
+ { "MODE", PTR_C(uzbl.gui.sbar.mode_indicator, STR, NULL)},
+ { "NAME", PTR_C(uzbl.state.instance_name, STR, NULL)},
+
+ { NULL, {.ptr = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}}
}, *n2v_p = var_name_to_ptr;
+
const struct {
char *key;
guint mask;
}
/* --- UTILITY FUNCTIONS --- */
-enum {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS};
+enum {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE};
guint
get_exp_type(gchar *s) {
/* variables */
return EXP_BRACED_VAR;
else if(*(s+1) == '<')
return EXP_JS;
+ else if(*(s+1) == '[')
+ return EXP_ESCAPE;
else
return EXP_SIMPLE_VAR;
return EXP_ERR;
}
-/*
+/*
* recurse == 1: don't expand '@(command)@'
* recurse == 2: don't expand '@<java script>@'
*/
char *end_simple_var = "^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½";
char str_end[2];
char ret[4096];
- char *vend;
+ char *vend = NULL;
GError *err = NULL;
gchar *cmd_stdout = NULL;
gchar *mycmd = NULL;
switch(etype) {
case EXP_SIMPLE_VAR:
- if( (vend = strpbrk(s, end_simple_var)) ||
- (vend = strchr(s, '\0')) ) {
- strncpy(ret, s, vend-s);
- ret[vend-s] = '\0';
- }
+ vend = strpbrk(s, end_simple_var);
+ if(!vend) vend = strchr(s, '\0');
break;
case EXP_BRACED_VAR:
s++; upto = '}';
- if( (vend = strchr(s, upto)) ||
- (vend = strchr(s, '\0')) ) {
- strncpy(ret, s, vend-s);
- ret[vend-s] = '\0';
- }
+ vend = strchr(s, upto);
+ if(!vend) vend = strchr(s, '\0');
break;
case EXP_EXPR:
s++;
strcpy(str_end, ")@");
str_end[2] = '\0';
- if( (vend = strstr(s, str_end)) ||
- (vend = strchr(s, '\0')) ) {
- strncpy(ret, s, vend-s);
- ret[vend-s] = '\0';
- }
+ vend = strstr(s, str_end);
+ if(!vend) vend = strchr(s, '\0');
break;
- case EXP_JS:
+ case EXP_JS:
s++;
strcpy(str_end, ">@");
str_end[2] = '\0';
- if( (vend = strstr(s, str_end)) ||
- (vend = strchr(s, '\0')) ) {
- strncpy(ret, s, vend-s);
- ret[vend-s] = '\0';
- }
+ vend = strstr(s, str_end);
+ if(!vend) vend = strchr(s, '\0');
+ break;
+ case EXP_ESCAPE:
+ s++;
+ strcpy(str_end, "]@");
+ str_end[2] = '\0';
+ vend = strstr(s, str_end);
+ if(!vend) vend = strchr(s, '\0');
break;
}
- if(etype == EXP_SIMPLE_VAR ||
+ if(vend) {
+ strncpy(ret, s, vend-s);
+ ret[vend-s] = '\0';
+ }
+
+ if(etype == EXP_SIMPLE_VAR ||
etype == EXP_BRACED_VAR) {
if( (c = g_hash_table_lookup(uzbl.comm.proto_var, ret)) ) {
- if(c->type == TYPE_STR)
+ if(c->type == TYPE_STR && *c->ptr != NULL) {
g_string_append(buf, (gchar *)*c->ptr);
- else if(c->type == TYPE_INT) {
+ } else if(c->type == TYPE_INT) {
g_string_append_printf(buf, "%d", (int)*c->ptr);
}
else if(c->type == TYPE_FLOAT) {
g_string_append_printf(buf, "%f", *(float *)c->ptr);
}
}
+
if(etype == EXP_SIMPLE_VAR)
s = vend;
else
s = vend+1;
}
- else if(recurse != 1 &&
+ else if(recurse != 1 &&
etype == EXP_EXPR) {
mycmd = expand(ret, 1);
g_spawn_command_line_sync(mycmd, &cmd_stdout, NULL, NULL, &err);
g_error_free (err);
}
else if (*cmd_stdout) {
+ int len = strlen(cmd_stdout);
+
+ if(cmd_stdout[len-1] == '\n')
+ cmd_stdout[--len] = 0; /* strip trailing newline */
+
g_string_append(buf, cmd_stdout);
g_free(cmd_stdout);
}
s = vend+2;
}
- else if(recurse != 2 &&
+ else if(recurse != 2 &&
etype == EXP_JS) {
mycmd = expand(ret, 2);
eval_js(uzbl.gui.web_view, mycmd, js_ret);
}
s = vend+2;
}
+ else if(etype == EXP_ESCAPE) {
+ mycmd = expand(ret, 0);
+ char *escaped = g_markup_escape_text(mycmd, strlen(mycmd));
+
+ g_string_append(buf, escaped);
+
+ g_free(escaped);
+ g_free(mycmd);
+ s = vend+2;
+ }
break;
default:
gsize len;
GArray *lines = g_array_new(TRUE, FALSE, sizeof(gchar*));
int i = 0;
-
+
chan = g_io_channel_new_file(path, "r", NULL);
-
+
if (chan) {
while (g_io_channel_read_line(chan, &readbuf, &len, NULL, NULL) == G_IO_STATUS_NORMAL) {
const gchar* val = g_strdup (readbuf);
g_free (readbuf);
i ++;
}
-
+
g_io_channel_unref (chan);
} else {
fprintf(stderr, "File '%s' not be read.\n", path);
}
-
+
return lines;
}
-gchar*
+gchar*
parseenv (char* string) {
extern char** environ;
gchar* tmpstr = NULL;
int i = 0;
-
+
while (environ[i] != NULL) {
gchar** env = g_strsplit (environ[i], "=", 2);
unlink (uzbl.comm.socket_path);
g_free(uzbl.state.executable_path);
- g_string_free(uzbl.state.keycmd, TRUE);
+ g_free(uzbl.state.keycmd);
g_hash_table_destroy(uzbl.bindings);
g_hash_table_destroy(uzbl.behave.commands);
- g_scanner_destroy(uzbl.scan);
}
-/* used for html_mode_timeout
+/* used for html_mode_timeout
* be sure to extend this function to use
* more timers if needed in other places
*/
const gchar* uri = webkit_network_request_get_uri (request);
if (uzbl.state.verbose)
printf("New window requested -> %s \n", uri);
- new_window_load_uri(uri);
- return (FALSE);
+ webkit_web_policy_decision_use(policy_decision);
+ return TRUE;
}
gboolean
}
void
+cmd_set_geometry() {
+ if(!gtk_window_parse_geometry(GTK_WINDOW(uzbl.gui.main_window), uzbl.gui.geometry)) {
+ if(uzbl.state.verbose)
+ printf("Error in geometry string: %s\n", uzbl.gui.geometry);
+ }
+ /* update geometry var with the actual geometry
+ this is necessary as some WMs don't seem to honour
+ the above setting and we don't want to end up with
+ wrong geometry information
+ */
+ retrieve_geometry();
+}
+
+void
cmd_set_status() {
if (!uzbl.behave.show_status) {
gtk_widget_hide(uzbl.gui.mainbar);
(void)page;
(void)argv;
(void)result;
-
+
webkit_web_view_set_full_content_zoom (page, !webkit_web_view_get_full_content_zoom (page));
}
}
void
-title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data) {
+title_change_cb (WebKitWebView* web_view, GParamSpec param_spec) {
(void) web_view;
- (void) web_frame;
- (void) data;
+ (void) param_spec;
+ const gchar *title = webkit_web_view_get_title(web_view);
if (uzbl.gui.main_title)
g_free (uzbl.gui.main_title);
- uzbl.gui.main_title = g_strdup (title);
+ uzbl.gui.main_title = title ? g_strdup (title) : g_strdup ("(no title)");
update_title();
}
(void) page;
(void) data;
uzbl.gui.sbar.load_progress = progress;
+
+ g_free(uzbl.gui.sbar.progress_bar);
+ uzbl.gui.sbar.progress_bar = build_progressbar_ascii(uzbl.gui.sbar.load_progress);
+
update_title();
}
run_handler(uzbl.behave.load_finish_handler, "");
}
+void clear_keycmd() {
+ g_free(uzbl.state.keycmd);
+ uzbl.state.keycmd = g_strdup("");
+}
+
void
load_start_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data) {
(void) page;
(void) frame;
(void) data;
uzbl.gui.sbar.load_progress = 0;
- g_string_truncate(uzbl.state.keycmd, 0); // don't need old commands to remain on new page?
+ clear_keycmd(); // don't need old commands to remain on new page?
if (uzbl.behave.load_start_handler)
run_handler(uzbl.behave.load_start_handler, "");
}
GString* newuri = g_string_new (webkit_web_frame_get_uri (frame));
uzbl.state.uri = g_string_free (newuri, FALSE);
if (uzbl.behave.reset_command_mode && uzbl.behave.insert_mode) {
- uzbl.behave.insert_mode = uzbl.behave.always_insert_mode;
+ set_insert_mode(uzbl.behave.always_insert_mode);
update_title();
}
if (uzbl.behave.load_commit_handler)
void
log_history_cb () {
if (uzbl.behave.history_handler) {
- GTimeVal the_time;
- gchar *date;
-
- g_get_current_time(&the_time);
- /* no need to wrap this string with quotes since it contains no spaces.
- format is like: 2009-06-26T20:02:05.262864Z */
- date = g_time_val_to_iso8601(&the_time);
+ time_t rawtime;
+ struct tm * timeinfo;
+ char date [80];
+ time ( &rawtime );
+ timeinfo = localtime ( &rawtime );
+ strftime (date, 80, "\"%Y-%m-%d %H:%M:%S\"", timeinfo);
run_handler(uzbl.behave.history_handler, date);
- g_free(date);
}
}
{ "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler
{ "sh", {spawn_sh, 0} },
{ "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler
+ { "talk_to_socket", {talk_to_socket, 0} },
{ "exit", {close_uzbl, 0} },
- { "quit", {close_uzbl, 0} },
{ "search", {search_forward_text, TRUE} },
{ "search_reverse", {search_reverse_text, TRUE} },
{ "dehilight", {dehilight, 0} },
set_var(WebKitWebView *page, GArray *argv, GString *result) {
(void) page; (void) result;
gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2);
- gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
- set_var_value(g_strstrip(split[0]), value);
- g_free(value);
+ if (split[0] != NULL) {
+ gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
+ set_var_value(g_strstrip(split[0]), value);
+ g_free(value);
+ }
g_strfreev(split);
}
}
void
+set_keycmd() {
+ run_keycmd(FALSE);
+ update_title();
+}
+
+void
+set_mode_indicator() {
+ uzbl.gui.sbar.mode_indicator = (uzbl.behave.insert_mode ?
+ uzbl.behave.insert_indicator : uzbl.behave.cmd_indicator);
+}
+
+void
+update_indicator() {
+ set_mode_indicator();
+ update_title();
+}
+
+void
+set_insert_mode(gboolean mode) {
+ uzbl.behave.insert_mode = mode;
+ set_mode_indicator();
+}
+
+void
toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result) {
(void) page; (void) result;
if (argv_idx(argv, 0)) {
if (strcmp (argv_idx(argv, 0), "0") == 0) {
- uzbl.behave.insert_mode = FALSE;
+ set_insert_mode(FALSE);
} else {
- uzbl.behave.insert_mode = TRUE;
+ set_insert_mode(TRUE);
}
} else {
- uzbl.behave.insert_mode = ! uzbl.behave.insert_mode;
+ set_insert_mode( !uzbl.behave.insert_mode );
}
update_title();
(void) function;
(void) thisObject;
(void) exception;
-
+
JSStringRef js_result_string;
GString *result = g_string_new("");
}
-void
+void
eval_js(WebKitWebView * web_view, gchar *script, GString *result) {
WebKitWebFrame *frame;
JSGlobalContextRef context;
JSValueRef js_result;
JSStringRef js_result_string;
size_t js_result_size;
-
+
js_init();
frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(web_view));
context = webkit_web_frame_get_global_context(frame);
globalobject = JSContextGetGlobalObject(context);
-
+
/* uzbl javascript namespace */
var_name = JSStringCreateWithUTF8CString("Uzbl");
JSObjectSetProperty(context, globalobject, var_name,
- JSObjectMake(context, uzbl.js.classref, NULL),
+ JSObjectMake(context, uzbl.js.classref, NULL),
kJSClassAttributeNone, NULL);
-
- /* evaluate the script and get return value*/
+
+ /* evaluate the script and get return value*/
js_script = JSStringCreateWithUTF8CString(script);
js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, NULL);
if (js_result && !JSValueIsUndefined(context, js_result)) {
i ++;
g_free (line);
}
-
+
if (uzbl.state.verbose)
printf ("External JavaScript file %s loaded\n", argv_idx(argv, 0));
uzbl.state.searchtx = g_strdup(argv_idx(argv, 0));
}
}
-
+
if (uzbl.state.searchtx) {
if (uzbl.state.verbose)
printf ("Searching: %s\n", uzbl.state.searchtx);
void
new_window_load_uri (const gchar * uri) {
+ if (uzbl.behave.new_window) {
+ GString *s = g_string_new ("");
+ g_string_printf(s, "'%s'", uri);
+ run_handler(uzbl.behave.new_window, s->str);
+ return;
+ }
GString* to_execute = g_string_new ("");
g_string_append_printf (to_execute, "%s --uri '%s'", uzbl.state.executable_path, uri);
int i;
(void) page; (void) result;
gchar *a = NULL;
gchar **parts = NULL;
- guint i = 0;
+ guint i = 0;
while ((a = argv_idx(argv, i++))) {
parts = g_strsplit (a, " ", 2);
if (parts[0])
(void)page;
(void)argv;
(void)result;
- g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+ uzbl.state.keycmd = g_strdup(argv_idx(argv, 0));
run_keycmd(FALSE);
update_title();
}
(void)page;
(void)argv;
(void)result;
- g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+ uzbl.state.keycmd = g_strdup(argv_idx(argv, 0));
run_keycmd(TRUE);
update_title();
}
(void)page;
(void)argv;
(void)result;
- prev = g_utf8_find_prev_char(uzbl.state.keycmd->str, uzbl.state.keycmd->str + uzbl.state.keycmd->len);
+ int len = strlen(uzbl.state.keycmd);
+ prev = g_utf8_find_prev_char(uzbl.state.keycmd, uzbl.state.keycmd + len);
if (prev)
- g_string_truncate(uzbl.state.keycmd, prev - uzbl.state.keycmd->str);
+ uzbl.state.keycmd[prev - uzbl.state.keycmd] = '\0';
update_title();
}
return g_string_free(bar, FALSE);
}
-
-void
-setup_scanner() {
- const GScannerConfig scan_config = {
- (
- "\t\r\n"
- ) /* cset_skip_characters */,
- (
- G_CSET_a_2_z
- "_#"
- G_CSET_A_2_Z
- ) /* cset_identifier_first */,
- (
- G_CSET_a_2_z
- "_0123456789"
- G_CSET_A_2_Z
- G_CSET_LATINS
- G_CSET_LATINC
- ) /* cset_identifier_nth */,
- ( "" ) /* cpair_comment_single */,
-
- TRUE /* case_sensitive */,
-
- FALSE /* skip_comment_multi */,
- FALSE /* skip_comment_single */,
- FALSE /* scan_comment_multi */,
- TRUE /* scan_identifier */,
- TRUE /* scan_identifier_1char */,
- FALSE /* scan_identifier_NULL */,
- TRUE /* scan_symbols */,
- FALSE /* scan_binary */,
- FALSE /* scan_octal */,
- FALSE /* scan_float */,
- FALSE /* scan_hex */,
- FALSE /* scan_hex_dollar */,
- FALSE /* scan_string_sq */,
- FALSE /* scan_string_dq */,
- TRUE /* numbers_2_int */,
- FALSE /* int_2_float */,
- FALSE /* identifier_2_string */,
- FALSE /* char_2_token */,
- FALSE /* symbol_2_token */,
- TRUE /* scope_0_fallback */,
- FALSE,
- TRUE
- };
-
- uzbl.scan = g_scanner_new(&scan_config);
- while(symp->symbol_name) {
- g_scanner_scope_add_symbol(uzbl.scan, 0,
- symp->symbol_name,
- GINT_TO_POINTER(symp->symbol_token));
- symp++;
- }
-}
-
-gchar *
-expand_template(const char *template, gboolean escape_markup) {
- if(!template) return NULL;
-
- GTokenType token = G_TOKEN_NONE;
- GString *ret = g_string_new("");
- char *buf=NULL;
- int sym;
-
- g_scanner_input_text(uzbl.scan, template, strlen(template));
- while(!g_scanner_eof(uzbl.scan) && token != G_TOKEN_LAST) {
- token = g_scanner_get_next_token(uzbl.scan);
-
- if(token == G_TOKEN_SYMBOL) {
- sym = GPOINTER_TO_INT(g_scanner_cur_value(uzbl.scan).v_symbol);
- switch(sym) {
- case SYM_URI:
- if(escape_markup) {
- buf = uzbl.state.uri ?
- g_markup_printf_escaped("%s", uzbl.state.uri) : g_strdup("");
- g_string_append(ret, buf);
- g_free(buf);
- }
- else
- g_string_append(ret, uzbl.state.uri ?
- uzbl.state.uri : g_strdup(""));
- break;
- case SYM_LOADPRGS:
- buf = itos(uzbl.gui.sbar.load_progress);
- g_string_append(ret, buf);
- g_free(buf);
- break;
- case SYM_LOADPRGSBAR:
- buf = build_progressbar_ascii(uzbl.gui.sbar.load_progress);
- g_string_append(ret, buf);
- g_free(buf);
- break;
- case SYM_TITLE:
- if(escape_markup) {
- buf = uzbl.gui.main_title ?
- g_markup_printf_escaped("%s", uzbl.gui.main_title) : g_strdup("");
- g_string_append(ret, buf);
- g_free(buf);
- }
- else
- g_string_append(ret, uzbl.gui.main_title ?
- uzbl.gui.main_title : "");
- break;
- case SYM_SELECTED_URI:
- if(escape_markup) {
- buf = uzbl.state.selected_url ?
- g_markup_printf_escaped("%s", uzbl.state.selected_url) : g_strdup("");
- g_string_append(ret, buf);
- g_free(buf);
- }
- else
- g_string_append(ret, uzbl.state.selected_url ?
- uzbl.state.selected_url : "");
- break;
- case SYM_NAME:
- buf = itos(uzbl.xwin);
- g_string_append(ret,
- uzbl.state.instance_name ? uzbl.state.instance_name : buf);
- g_free(buf);
- break;
- case SYM_KEYCMD:
- if(escape_markup) {
- buf = uzbl.state.keycmd->str ?
- g_markup_printf_escaped("%s", uzbl.state.keycmd->str) : g_strdup("");
- g_string_append(ret, buf);
- g_free(buf);
- }
- else
- g_string_append(ret, uzbl.state.keycmd->str ?
- uzbl.state.keycmd->str : "");
- break;
- case SYM_MODE:
- g_string_append(ret,
- uzbl.behave.insert_mode ?
- uzbl.behave.insert_indicator : uzbl.behave.cmd_indicator);
- break;
- case SYM_MSG:
- g_string_append(ret,
- uzbl.gui.sbar.msg ? uzbl.gui.sbar.msg : "");
- break;
- /* useragent syms */
- case SYM_WK_MAJ:
- buf = itos(WEBKIT_MAJOR_VERSION);
- g_string_append(ret, buf);
- g_free(buf);
- break;
- case SYM_WK_MIN:
- buf = itos(WEBKIT_MINOR_VERSION);
- g_string_append(ret, buf);
- g_free(buf);
- break;
- case SYM_WK_MIC:
- buf = itos(WEBKIT_MICRO_VERSION);
- g_string_append(ret, buf);
- g_free(buf);
- break;
- case SYM_SYSNAME:
- g_string_append(ret, uzbl.state.unameinfo.sysname);
- break;
- case SYM_NODENAME:
- g_string_append(ret, uzbl.state.unameinfo.nodename);
- break;
- case SYM_KERNREL:
- g_string_append(ret, uzbl.state.unameinfo.release);
- break;
- case SYM_KERNVER:
- g_string_append(ret, uzbl.state.unameinfo.version);
- break;
- case SYM_ARCHSYS:
- g_string_append(ret, uzbl.state.unameinfo.machine);
- break;
- case SYM_ARCHUZBL:
- g_string_append(ret, ARCH);
- break;
-#ifdef _GNU_SOURCE
- case SYM_DOMAINNAME:
- g_string_append(ret, uzbl.state.unameinfo.domainname);
- break;
-#endif
- case SYM_COMMIT:
- g_string_append(ret, COMMIT);
- break;
- default:
- break;
- }
- }
- else if(token == G_TOKEN_INT) {
- g_string_append_printf(ret, "%lu", g_scanner_cur_value(uzbl.scan).v_int);
- }
- else if(token == G_TOKEN_IDENTIFIER) {
- g_string_append(ret, (gchar *)g_scanner_cur_value(uzbl.scan).v_identifier);
- }
- else if(token == G_TOKEN_CHAR) {
- g_string_append_c(ret, (gchar)g_scanner_cur_value(uzbl.scan).v_char);
- }
- else if(token == G_TOKEN_ERROR) {
- g_scanner_error(uzbl.scan, "Token error in template ('%s') at line %d, column %d.",
- template,
- g_scanner_cur_line(uzbl.scan),
- g_scanner_cur_position(uzbl.scan));
- }
- }
-
- return g_string_free(ret, FALSE);
-}
/* --End Statusbar functions-- */
void
const gboolean sync, char **output_stdout) {
//command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
GError *err = NULL;
-
+
GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
gchar *pid = itos(getpid());
gchar *xwin = itos(uzbl.xwin);
for (i = npre; i < g_strv_length((gchar**)args); i++)
sharg_append(a, args[i]);
-
+
gboolean result;
if (sync) {
if (*output_stdout) *output_stdout = strfree(*output_stdout);
-
+
result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, output_stdout, NULL, NULL, &err);
} else result = g_spawn_async(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
/* split on unquoted space, return array of strings;
remove a layer of quotes and backslashes if unquote */
if (!src) return NULL;
-
+
gboolean dq = FALSE;
gboolean sq = FALSE;
GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
void
spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
(void)web_view; (void)result;
-
+
if (argv_idx(argv, 0))
run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))),
TRUE, &uzbl.comm.sync_stdout);
g_printerr ("spawn_sh: shell_cmd is not set!\n");
return;
}
-
+
guint i;
gchar *spacer = g_strdup("");
g_array_insert_val(argv, 1, spacer);
g_printerr ("spawn_sh_sync: shell_cmd is not set!\n");
return;
}
-
+
guint i;
gchar *spacer = g_strdup("");
g_array_insert_val(argv, 1, spacer);
for (i = 1; i < g_strv_length(cmd); i++)
g_array_prepend_val(argv, cmd[i]);
-
+
if (cmd) run_command(cmd[0], g_strv_length(cmd) + 1, (const gchar **) argv->data,
TRUE, &uzbl.comm.sync_stdout);
g_free (spacer);
}
void
+talk_to_socket(WebKitWebView *web_view, GArray *argv, GString *result) {
+ (void)web_view; (void)result;
+
+ int fd, len;
+ struct sockaddr_un sa;
+ char* sockpath;
+ ssize_t ret;
+ struct pollfd pfd;
+ struct iovec* iov;
+ guint i;
+
+ if(uzbl.comm.sync_stdout) uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
+
+ /* This function could be optimised by storing a hash table of socket paths
+ and associated connected file descriptors rather than closing and
+ re-opening for every call. Also we could launch a script if socket connect
+ fails. */
+
+ /* First element argv[0] is path to socket. Following elements are tokens to
+ write to the socket. We write them as a single packet with each token
+ separated by an ASCII nul (\0). */
+ if(argv->len < 2) {
+ g_printerr("talk_to_socket called with only %d args (need at least two).\n",
+ (int)argv->len);
+ return;
+ }
+
+ /* copy socket path, null terminate result */
+ sockpath = g_array_index(argv, char*, 0);
+ g_strlcpy(sa.sun_path, sockpath, sizeof(sa.sun_path));
+ sa.sun_family = AF_UNIX;
+
+ /* create socket file descriptor and connect it to path */
+ fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
+ if(fd == -1) {
+ g_printerr("talk_to_socket: creating socket failed (%s)\n", strerror(errno));
+ return;
+ }
+ if(connect(fd, (struct sockaddr*)&sa, sizeof(sa))) {
+ g_printerr("talk_to_socket: connect failed (%s)\n", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ /* build request vector */
+ iov = g_malloc(sizeof(struct iovec) * (argv->len - 1));
+ if(!iov) {
+ g_printerr("talk_to_socket: unable to allocated memory for token vector\n");
+ close(fd);
+ return;
+ }
+ for(i = 1; i < argv->len; ++i) {
+ iov[i - 1].iov_base = g_array_index(argv, char*, i);
+ iov[i - 1].iov_len = strlen(iov[i - 1].iov_base) + 1; /* string plus \0 */
+ }
+
+ /* write request */
+ ret = writev(fd, iov, argv->len - 1);
+ g_free(iov);
+ if(ret == -1) {
+ g_printerr("talk_to_socket: write failed (%s)\n", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ /* wait for a response, with a 500ms timeout */
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ while(1) {
+ ret = poll(&pfd, 1, 500);
+ if(ret == 1) break;
+ if(ret == 0) errno = ETIMEDOUT;
+ if(errno == EINTR) continue;
+ g_printerr("talk_to_socket: poll failed while waiting for input (%s)\n",
+ strerror(errno));
+ close(fd);
+ return;
+ }
+
+ /* get length of response */
+ if(ioctl(fd, FIONREAD, &len) == -1) {
+ g_printerr("talk_to_socket: cannot find daemon response length, "
+ "ioctl failed (%s)\n", strerror(errno));
+ close(fd);
+ return;
+ }
+
+ /* if there is a response, read it */
+ if(len) {
+ uzbl.comm.sync_stdout = g_malloc(len + 1);
+ if(!uzbl.comm.sync_stdout) {
+ g_printerr("talk_to_socket: failed to allocate %d bytes\n", len);
+ close(fd);
+ return;
+ }
+ uzbl.comm.sync_stdout[len] = 0; /* ensure result is null terminated */
+
+ ret = read(fd, uzbl.comm.sync_stdout, len);
+ if(ret == -1) {
+ g_printerr("talk_to_socket: failed to read from socket (%s)\n",
+ strerror(errno));
+ close(fd);
+ return;
+ }
+ }
+
+ /* clean up */
+ close(fd);
+ return;
+}
+
+void
parse_command(const char *cmd, const char *param, GString *result) {
CommandInfo *c;
g_array_free (a, TRUE);
}
-void
+void
cmd_always_insert_mode() {
- uzbl.behave.insert_mode =
- uzbl.behave.always_insert_mode ? TRUE : FALSE;
+ set_insert_mode(uzbl.behave.always_insert_mode);
update_title();
}
if (uzbl.behave.font_size > 0) {
g_object_set (G_OBJECT(ws), "default-font-size", uzbl.behave.font_size, NULL);
}
-
+
if (uzbl.behave.monospace_size > 0) {
g_object_set (G_OBJECT(ws), "default-monospace-font-size",
uzbl.behave.monospace_size, NULL);
}
void
+cmd_default_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "default-font-family",
+ uzbl.behave.default_font_family, NULL);
+}
+
+void
+cmd_monospace_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "monospace-font-family",
+ uzbl.behave.monospace_font_family, NULL);
+}
+
+void
+cmd_sans_serif_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "sans_serif-font-family",
+ uzbl.behave.sans_serif_font_family, NULL);
+}
+
+void
+cmd_serif_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "serif-font-family",
+ uzbl.behave.serif_font_family, NULL);
+}
+
+void
+cmd_cursive_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "cursive-font-family",
+ uzbl.behave.cursive_font_family, NULL);
+}
+
+void
+cmd_fantasy_font_family() {
+ g_object_set (G_OBJECT(view_settings()), "fantasy-font-family",
+ uzbl.behave.fantasy_font_family, NULL);
+}
+
+void
cmd_zoom_level() {
webkit_web_view_set_zoom_level (uzbl.gui.web_view, uzbl.behave.zoom_level);
}
void
cmd_disable_plugins() {
- g_object_set (G_OBJECT(view_settings()), "enable-plugins",
+ g_object_set (G_OBJECT(view_settings()), "enable-plugins",
!uzbl.behave.disable_plugins, NULL);
}
uzbl.behave.print_bg, NULL);
}
-void
+void
cmd_style_uri() {
g_object_set (G_OBJECT(view_settings()), "user-stylesheet-uri",
uzbl.behave.style_uri, NULL);
}
-void
+void
cmd_resizable_txt() {
g_object_set (G_OBJECT(view_settings()), "resizable-text-areas",
uzbl.behave.resizable_txt, NULL);
}
-void
+void
cmd_default_encoding() {
g_object_set (G_OBJECT(view_settings()), "default-encoding",
uzbl.behave.default_encoding, NULL);
}
-void
+void
cmd_enforce_96dpi() {
g_object_set (G_OBJECT(view_settings()), "enforce-96-dpi",
uzbl.behave.enforce_96dpi, NULL);
}
-void
+void
cmd_caret_browsing() {
g_object_set (G_OBJECT(view_settings()), "enable-caret-browsing",
uzbl.behave.caret_browsing, NULL);
}
void
+cmd_new_window() {
+ gchar **split = g_strsplit(uzbl.behave.new_window, " ", 2);
+ /* pitfall: doesn't handle chain actions; must the sync_ action manually */
+ if ((g_strcmp0(split[0], "sh") == 0) ||
+ (g_strcmp0(split[0], "spawn") == 0)) {
+ g_free (uzbl.behave.new_window);
+ uzbl.behave.new_window =
+ g_strdup_printf("%s %s", split[0], split[1]);
+ }
+ g_strfreev (split);
+}
+
+void
cmd_fifo_dir() {
uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir);
}
buf = g_utf8_strup(uzbl.behave.modkey, -1);
uzbl.behave.modmask = 0;
- if(uzbl.behave.modkey)
+ if(uzbl.behave.modkey)
g_free(uzbl.behave.modkey);
uzbl.behave.modkey = buf;
g_free (uzbl.net.useragent);
uzbl.net.useragent = NULL;
} else {
- gchar *ua = expand_template(uzbl.net.useragent, FALSE);
- if (ua)
- g_object_set(G_OBJECT(uzbl.net.soup_session), SOUP_SESSION_USER_AGENT, ua, NULL);
- g_free(uzbl.net.useragent);
- uzbl.net.useragent = ua;
+ g_object_set(G_OBJECT(uzbl.net.soup_session), SOUP_SESSION_USER_AGENT,
+ uzbl.net.useragent, NULL);
}
}
char *buf = NULL;
if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
+ if(!c->writeable) return FALSE;
+
/* check for the variable type */
if (c->type == TYPE_STR) {
buf = expand(val, 0);
gchar*
build_stream_name(int type, const gchar* dir) {
- char *xwin_str = NULL;
State *s = &uzbl.state;
gchar *str = NULL;
- xwin_str = itos((int)uzbl.xwin);
if (type == FIFO) {
str = g_strdup_printf
- ("%s/uzbl_fifo_%s", dir,
- s->instance_name ? s->instance_name : xwin_str);
+ ("%s/uzbl_fifo_%s", dir, s->instance_name);
} else if (type == SOCKET) {
str = g_strdup_printf
- ("%s/uzbl_socket_%s", dir,
- s->instance_name ? s->instance_name : xwin_str );
+ ("%s/uzbl_socket_%s", dir, s->instance_name);
}
- g_free(xwin_str);
return str;
}
gchar*
init_fifo(gchar *dir) { /* return dir or, on error, free dir and return NULL */
+ if (uzbl.comm.fifo_path) { /* get rid of the old fifo if one exists */
+ if (unlink(uzbl.comm.fifo_path) == -1)
+ g_warning ("Fifo: Can't unlink old fifo at %s\n", uzbl.comm.fifo_path);
+ g_free(uzbl.comm.fifo_path);
+ uzbl.comm.fifo_path = NULL;
+ }
+
GIOChannel *chan = NULL;
GError *error = NULL;
gchar *path = build_stream_name(FIFO, dir);
clientsock = accept (g_io_channel_unix_get_fd(chan),
(struct sockaddr *) &remote, &t);
-
+
if ((clientchan = g_io_channel_unix_new(clientsock))) {
g_io_add_watch(clientchan, G_IO_IN|G_IO_HUP,
(GIOFunc) control_client_socket, clientchan);
if (b->show_status) {
if (b->title_format_short) {
- parsed = expand_template(b->title_format_short, FALSE);
+ parsed = expand(b->title_format_short, 0);
if (uzbl.gui.main_window)
gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
g_free(parsed);
}
if (b->status_format) {
- parsed = expand_template(b->status_format, TRUE);
+ parsed = expand(b->status_format, 0);
gtk_label_set_markup(GTK_LABEL(uzbl.gui.mainbar_label), parsed);
g_free(parsed);
}
if (b->status_background) {
GdkColor color;
gdk_color_parse (b->status_background, &color);
- //labels and hboxes do not draw their own background. applying this on the window is ok as we the statusbar is the only affected widget. (if not, we could also use GtkEventBox)
+ //labels and hboxes do not draw their own background. applying this on the vbox/main_window is ok as the statusbar is the only affected widget. (if not, we could also use GtkEventBox)
if (uzbl.gui.main_window)
gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color);
+ else if (uzbl.gui.plug)
+ gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color);
}
} else {
if (b->title_format_long) {
- parsed = expand_template(b->title_format_long, FALSE);
+ parsed = expand(b->title_format_long, 0);
if (uzbl.gui.main_window)
gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
g_free(parsed);
}
gboolean
+configure_event_cb(GtkWidget* window, GdkEventConfigure* event) {
+ (void) window;
+ (void) event;
+
+ retrieve_geometry();
+ return FALSE;
+}
+
+gboolean
key_press_cb (GtkWidget* window, GdkEventKey* event)
{
//TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
(void) window;
- if (event->type != GDK_KEY_PRESS || event->keyval == GDK_Page_Up || event->keyval == GDK_Page_Down
- || event->keyval == GDK_Up || event->keyval == GDK_Down || event->keyval == GDK_Left || event->keyval == GDK_Right || event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R)
+ if (event->type != GDK_KEY_PRESS ||
+ event->keyval == GDK_Page_Up ||
+ event->keyval == GDK_Page_Down ||
+ event->keyval == GDK_Up ||
+ event->keyval == GDK_Down ||
+ event->keyval == GDK_Left ||
+ event->keyval == GDK_Right ||
+ event->keyval == GDK_Shift_L ||
+ event->keyval == GDK_Shift_R)
return FALSE;
/* turn off insert mode (if always_insert_mode is not used) */
if (uzbl.behave.insert_mode && (event->keyval == GDK_Escape)) {
- uzbl.behave.insert_mode = uzbl.behave.always_insert_mode;
+ set_insert_mode(uzbl.behave.always_insert_mode);
update_title();
return TRUE;
}
- if (uzbl.behave.insert_mode && (((event->state & uzbl.behave.modmask) != uzbl.behave.modmask) || (!uzbl.behave.modmask)))
+ if (uzbl.behave.insert_mode &&
+ ( ((event->state & uzbl.behave.modmask) != uzbl.behave.modmask) ||
+ (!uzbl.behave.modmask)
+ )
+ )
return FALSE;
if (event->keyval == GDK_Escape) {
- g_string_truncate(uzbl.state.keycmd, 0);
+ clear_keycmd();
update_title();
dehilight(uzbl.gui.web_view, NULL, NULL);
return TRUE;
str = gtk_clipboard_wait_for_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD));
}
if (str) {
- g_string_append (uzbl.state.keycmd, str);
+ GString* keycmd = g_string_new(uzbl.state.keycmd);
+ g_string_append (keycmd, str);
+ uzbl.state.keycmd = g_string_free(keycmd, FALSE);
update_title ();
g_free (str);
}
gboolean key_ret = FALSE;
if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter))
key_ret = TRUE;
- if (!key_ret) g_string_append(uzbl.state.keycmd, event->string);
+ if (!key_ret) {
+ GString* keycmd = g_string_new(uzbl.state.keycmd);
+ g_string_append(keycmd, event->string);
+ uzbl.state.keycmd = g_string_free(keycmd, FALSE);
+ }
run_keycmd(key_ret);
update_title();
run_keycmd(const gboolean key_ret) {
/* run the keycmd immediately if it isn't incremental and doesn't take args */
Action *act;
- if ((act = g_hash_table_lookup(uzbl.bindings, uzbl.state.keycmd->str))) {
- g_string_truncate(uzbl.state.keycmd, 0);
+ if ((act = g_hash_table_lookup(uzbl.bindings, uzbl.state.keycmd))) {
+ clear_keycmd();
parse_command(act->name, act->param, NULL);
return;
}
GString* short_keys = g_string_new ("");
GString* short_keys_inc = g_string_new ("");
guint i;
- for (i=0; i<(uzbl.state.keycmd->len); i++) {
- g_string_append_c(short_keys, uzbl.state.keycmd->str[i]);
+ guint len = strlen(uzbl.state.keycmd);
+ for (i=0; i<len; i++) {
+ g_string_append_c(short_keys, uzbl.state.keycmd[i]);
g_string_assign(short_keys_inc, short_keys->str);
g_string_append_c(short_keys, '_');
g_string_append_c(short_keys_inc, '*');
if (key_ret && (act = g_hash_table_lookup(uzbl.bindings, short_keys->str))) {
/* run normal cmds only if return was pressed */
exec_paramcmd(act, i);
- g_string_truncate(uzbl.state.keycmd, 0);
+ clear_keycmd();
break;
} else if ((act = g_hash_table_lookup(uzbl.bindings, short_keys_inc->str))) {
if (key_ret) /* just quit the incremental command on return */
- g_string_truncate(uzbl.state.keycmd, 0);
+ clear_keycmd();
else exec_paramcmd(act, i); /* otherwise execute the incremental */
break;
}
-
+
g_string_truncate(short_keys, short_keys->len - 1);
}
g_string_free (short_keys, TRUE);
void
exec_paramcmd(const Action *act, const guint i) {
- GString *parampart = g_string_new (uzbl.state.keycmd->str);
+ GString *parampart = g_string_new (uzbl.state.keycmd);
GString *actionname = g_string_new ("");
GString *actionparam = g_string_new ("");
g_string_erase (parampart, 0, i+1);
}
-GtkWidget*
+void
create_browser () {
GUI *g = &uzbl.gui;
- GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- //main_window_ref = g_object_ref(scrolled_window);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); //todo: some sort of display of position/total length. like what emacs does
-
g->web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
- gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (g->web_view));
- g_signal_connect (G_OBJECT (g->web_view), "title-changed", G_CALLBACK (title_change_cb), g->web_view);
+ g_signal_connect (G_OBJECT (g->web_view), "notify::title", G_CALLBACK (title_change_cb), NULL);
g_signal_connect (G_OBJECT (g->web_view), "load-progress-changed", G_CALLBACK (progress_change_cb), g->web_view);
g_signal_connect (G_OBJECT (g->web_view), "load-committed", G_CALLBACK (load_commit_cb), g->web_view);
g_signal_connect (G_OBJECT (g->web_view), "load-started", G_CALLBACK (load_start_cb), g->web_view);
g_signal_connect (G_OBJECT (g->web_view), "download-requested", G_CALLBACK (download_cb), g->web_view);
g_signal_connect (G_OBJECT (g->web_view), "create-web-view", G_CALLBACK (create_web_view_cb), g->web_view);
g_signal_connect (G_OBJECT (g->web_view), "mime-type-policy-decision-requested", G_CALLBACK (mime_policy_cb), g->web_view);
-
- return scrolled_window;
}
GtkWidget*
gtk_widget_set_name (window, "Uzbl browser");
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy_cb), NULL);
g_signal_connect (G_OBJECT (window), "key-press-event", G_CALLBACK (key_press_cb), NULL);
+ g_signal_connect (G_OBJECT (window), "configure-event", G_CALLBACK (configure_event_cb), NULL);
return window;
}
-GtkPlug*
+GtkPlug*
create_plug () {
GtkPlug* plug = GTK_PLUG (gtk_plug_new (uzbl.state.socket_id));
g_signal_connect (G_OBJECT (plug), "destroy", G_CALLBACK (destroy_cb), NULL);
if ((g_strcmp0(actname, "spawn") == 0) ||
(g_strcmp0(actname, "sh") == 0) ||
(g_strcmp0(actname, "sync_spawn") == 0) ||
- (g_strcmp0(actname, "sync_sh") == 0)) {
+ (g_strcmp0(actname, "sync_sh") == 0) ||
+ (g_strcmp0(actname, "talk_to_socket") == 0)) {
guint i;
GString *a = g_string_new("");
gchar **spawnparts = split_quoted(origargs, FALSE);
if (g_strcmp0(parts[0], "chain") == 0) {
GString *newargs = g_string_new("");
gchar **chainparts = split_quoted(parts[1], FALSE);
-
+
/* for every argument in the chain, inject the handler args
and make sure the new parts are wrapped in quotes */
gchar **cp = chainparts;
gchar *quotless = NULL;
gchar **spliced_quotless = NULL; // sigh -_-;
gchar **inpart = NULL;
-
+
while (*cp) {
if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */
quot = **cp;
spliced_quotless = g_strsplit(quotless, " ", 2);
inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args);
g_strfreev(spliced_quotless);
-
+
g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot);
g_free(quotless);
g_strfreev(inpart);
parse_command(parts[0], &(newargs->str[1]), NULL);
g_string_free(newargs, TRUE);
g_strfreev(chainparts);
-
+
} else {
gchar **inparts = inject_handler_args(parts[0], parts[1], args);
parse_command(inparts[0], inparts[1], NULL);
temporary_file = g_strconcat (temporary_string, filename, NULL);
}
}
-
+
//g_free (temporary_string); - segfaults.
if (file_exists (temporary_file)) {
parse_cmd_line(default_config[i].command, NULL);
}
- if (!s->config_file) {
+ if (g_strcmp0(s->config_file, "-") == 0) {
+ s->config_file = NULL;
+ create_stdin();
+ }
+
+ else if (!s->config_file) {
s->config_file = find_xdg_file (0, "/uzbl/config");
}
soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
GString *s = g_string_new ("");
SoupURI * soup_uri = soup_message_get_uri(msg);
- g_string_printf(s, "GET '%s' '%s'", soup_uri->host, soup_uri->path);
+ g_string_printf(s, "GET '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path);
run_handler(uzbl.behave.cookie_handler, s->str);
if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
}
if (uzbl.comm.sync_stdout)
uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
-
+
g_string_free(s, TRUE);
}
cookie = soup_cookie_to_set_cookie_header(ck->data);
SoupURI * soup_uri = soup_message_get_uri(msg);
GString *s = g_string_new ("");
- g_string_printf(s, "PUT '%s' '%s' '%s'", soup_uri->host, soup_uri->path, cookie);
+ g_string_printf(s, "PUT '%s' '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path, cookie);
run_handler(uzbl.behave.cookie_handler, s->str);
g_free (cookie);
g_string_free(s, TRUE);
g_hash_table_foreach(uzbl.bindings, dump_key_hash, NULL);
}
-#ifndef UZBL_LIBRARY
-/** -- MAIN -- **/
-int
-main (int argc, char* argv[]) {
- gtk_init (&argc, &argv);
+void
+retrieve_geometry() {
+ int w, h, x, y;
+ GString *buf = g_string_new("");
+
+ gtk_window_get_size(GTK_WINDOW(uzbl.gui.main_window), &w, &h);
+ gtk_window_get_position(GTK_WINDOW(uzbl.gui.main_window), &x, &y);
+
+ g_string_printf(buf, "%dx%d+%d+%d", w, h, x, y);
+
+ if(uzbl.gui.geometry)
+ g_free(uzbl.gui.geometry);
+ uzbl.gui.geometry = g_string_free(buf, FALSE);
+}
+
+/* set up gtk, gobject, variable defaults and other things that tests and other
+ * external applications need to do anyhow */
+void
+initialize(int argc, char *argv[]) {
if (!g_thread_supported ())
g_thread_init (NULL);
uzbl.state.executable_path = g_strdup(argv[0]);
uzbl.state.selected_url = NULL;
uzbl.state.searchtx = NULL;
- GOptionContext* context = g_option_context_new ("- some stuff here maybe someday");
+ GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free(context);
-
- gchar *uri_override = (uzbl.state.uri ? g_strdup(uzbl.state.uri) : NULL);
- gboolean verbose_override = uzbl.state.verbose;
+
+ if (uzbl.behave.print_version) {
+ printf("Commit: %s\n", COMMIT);
+ exit(0);
+ }
/* initialize hash table */
uzbl.bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
uzbl.net.soup_session = webkit_get_default_session();
- uzbl.state.keycmd = g_string_new("");
+ uzbl.state.keycmd = g_strdup("");
if(setup_signal(SIGTERM, catch_sigterm) == SIG_ERR)
fprintf(stderr, "uzbl: error hooking SIGTERM\n");
if(setup_signal(SIGALRM, catch_alrm) == SIG_ERR)
fprintf(stderr, "uzbl: error hooking SIGALARM\n");
-
- if(uname(&uzbl.state.unameinfo) == -1)
- g_printerr("Can't retrieve unameinfo. Your useragent might appear wrong.\n");
-
- uzbl.gui.sbar.progress_s = g_strdup("=");
+ uzbl.gui.sbar.progress_s = g_strdup("="); //TODO: move these to config.h
uzbl.gui.sbar.progress_u = g_strdup("·");
uzbl.gui.sbar.progress_w = 10;
uzbl.behave.insert_indicator = g_strdup("I");
uzbl.behave.cmd_indicator = g_strdup("C");
- setup_scanner();
+ uzbl.info.webkit_major = WEBKIT_MAJOR_VERSION;
+ uzbl.info.webkit_minor = WEBKIT_MINOR_VERSION;
+ uzbl.info.webkit_micro = WEBKIT_MICRO_VERSION;
+ uzbl.info.arch = ARCH;
+ uzbl.info.commit = COMMIT;
+
commands_hash ();
make_var_to_name_hash();
+ create_browser();
+}
+
+#ifndef UZBL_LIBRARY
+/** -- MAIN -- **/
+int
+main (int argc, char* argv[]) {
+ initialize(argc, argv);
+
+ gtk_init (&argc, &argv);
+
+ uzbl.gui.scrolled_win = gtk_scrolled_window_new (NULL, NULL);
+ //main_window_ref = g_object_ref(scrolled_window);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win),
+ GTK_POLICY_NEVER, GTK_POLICY_NEVER); //todo: some sort of display of position/total length. like what emacs does
+
+ gtk_container_add (GTK_CONTAINER (uzbl.gui.scrolled_win),
+ GTK_WIDGET (uzbl.gui.web_view));
+
uzbl.gui.vbox = gtk_vbox_new (FALSE, 0);
- uzbl.gui.scrolled_win = create_browser();
create_mainbar();
/* initial packing */
uzbl.xwin = GDK_WINDOW_XID (GTK_WIDGET (uzbl.gui.main_window)->window);
}
+ if(!uzbl.state.instance_name)
+ uzbl.state.instance_name = itos((int)uzbl.xwin);
+
gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view));
if (uzbl.state.verbose) {
uzbl.gui.bar_h = gtk_range_get_adjustment((GtkRange*) uzbl.gui.scbar_h);
gtk_widget_set_scroll_adjustments ((GtkWidget*) uzbl.gui.web_view, uzbl.gui.bar_h, uzbl.gui.bar_v);
+ /* Check uzbl is in window mode before getting/setting geometry */
+ if (uzbl.gui.main_window) {
+ if(uzbl.gui.geometry)
+ cmd_set_geometry();
+ else
+ retrieve_geometry();
+ }
+
+ gchar *uri_override = (uzbl.state.uri ? g_strdup(uzbl.state.uri) : NULL);
+ if (argc > 1 && !uzbl.state.uri)
+ uri_override = g_strdup(argv[1]);
+ gboolean verbose_override = uzbl.state.verbose;
+
settings_init ();
+ set_insert_mode(FALSE);
if (!uzbl.behave.show_status)
gtk_widget_hide(uzbl.gui.mainbar);
/* WebInspector */
set_up_inspector();
- create_stdin();
-
if (verbose_override > uzbl.state.verbose)
uzbl.state.verbose = verbose_override;
-
+
if (uri_override) {
set_var_value("uri", uri_override);
g_free(uri_override);