/* commandline arguments (set initial values for the state variables) */
static GOptionEntry entries[] =
{
- { "uri", 'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri, "Uri to load", "URI" },
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &uzbl.state.verbose, "Whether to print all messages or just errors.", "VERBOSE" },
+ { "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, "Whether to print all messages or just errors.", NULL },
{ "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", "FILE" },
+ { "config", 'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file, "Config file (this is pretty much equivalent to uzbl < FILE )", "FILE" },
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
static char *
str_replace (const char* search, const char* replace, const char* string) {
- return g_strjoinv (replace, g_strsplit (string, search, -1));
+ gchar **buf;
+ char *ret;
+
+ buf = g_strsplit (string, search, -1);
+ ret = g_strjoinv (replace, buf);
+ g_strfreev(buf);
+
+ return ret;
}
static sigfunc*
{ "spawn", spawn },
{ "sh", spawn_sh },
{ "exit", close_uzbl },
- { "search", search_text },
+ { "search", search_forward_text },
+ { "search_reverse", search_reverse_text },
{ "insert_mode", set_insert_mode },
{ "runcmd", runcmd }
};
static bool
file_exists (const char * filename) {
- return (access(filename, F_OK) == 0);
+ return (access(filename, F_OK) == 0);
}
-void
+static void
set_insert_mode(WebKitWebView *page, const gchar *param) {
(void)page;
(void)param;
GString* newuri = g_string_new (param);
if (g_strrstr (param, "://") == NULL)
g_string_prepend (newuri, "http://");
- /* if we do handle cookies, ask our handler for them */
+ /* if we do handle cookies, ask our handler for them */
webkit_web_view_load_uri (web_view, newuri->str);
g_string_free (newuri, TRUE);
}
}
static void
-search_text (WebKitWebView *page, const char *param) {
+search_text (WebKitWebView *page, const char *param, const gboolean forward) {
if ((param) && (param[0] != '\0')) {
strcpy(uzbl.state.searchtx, param);
}
webkit_web_view_unmark_text_matches (page);
webkit_web_view_mark_text_matches (page, uzbl.state.searchtx, FALSE, 0);
webkit_web_view_set_highlight_text_matches (page, TRUE);
- webkit_web_view_search_text (page, uzbl.state.searchtx, FALSE, TRUE, TRUE);
+ webkit_web_view_search_text (page, uzbl.state.searchtx, FALSE, forward, TRUE);
}
}
static void
+search_forward_text (WebKitWebView *page, const char *param) {
+ search_text(page, param, TRUE);
+}
+
+static void
+search_reverse_text (WebKitWebView *page, const char *param) {
+ search_text(page, param, FALSE);
+}
+
+static void
new_window_load_uri (const gchar * uri) {
GString* to_execute = g_string_new ("");
g_string_append_printf (to_execute, "%s --uri '%s'", uzbl.state.executable_path, uri);
int i;
for (i = 0; entries[i].long_name != NULL; i++) {
- if ((entries[i].arg == G_OPTION_ARG_STRING) && (strcmp(entries[i].long_name,"uri")!=0)) {
+ if ((entries[i].arg == G_OPTION_ARG_STRING) && (strcmp(entries[i].long_name,"uri")!=0) && (strcmp(entries[i].long_name,"name")!=0)) {
gchar** str = (gchar**)entries[i].arg_data;
if (*str!=NULL) {
g_string_append_printf (to_execute, " --%s '%s'", entries[i].long_name, *str);
sym = (int)g_scanner_cur_value(uzbl.scan).v_symbol;
switch(sym) {
case SYM_URI:
- g_string_append(ret,
- uzbl.state.uri?
- g_markup_printf_escaped("%s", uzbl.state.uri):"");
+ buf = uzbl.state.uri?
+ g_markup_printf_escaped("%s", uzbl.state.uri) :
+ g_strdup("");
+ g_string_append(ret, buf);
+ free(buf);
break;
case SYM_LOADPRGS:
buf = itos(uzbl.gui.sbar.load_progress);
g_free(buf);
break;
case SYM_TITLE:
- g_string_append(ret,
- uzbl.gui.main_title?
- g_markup_printf_escaped("%s", uzbl.gui.main_title):"");
+ buf = uzbl.gui.main_title?
+ g_markup_printf_escaped("%s", uzbl.gui.main_title) :
+ g_strdup("");
+ g_string_append(ret, buf);
+ free(buf);
break;
case SYM_SELECTED_URI:
- g_string_append(ret,
- uzbl.state.selected_url?
- g_markup_printf_escaped("%s", uzbl.state.selected_url):"");
+ buf = uzbl.state.selected_url?
+ g_markup_printf_escaped("%s", uzbl.state.selected_url) :
+ g_strdup("");
+ g_string_append(ret, buf);
+ free(buf);
break;
case SYM_NAME:
buf = itos(uzbl.xwin);
free(buf);
break;
case SYM_KEYCMD:
- g_string_append(ret,
- uzbl.state.keycmd->str ?
- g_markup_printf_escaped("%s", uzbl.state.keycmd->str):"");
+ buf = uzbl.state.keycmd->str?
+ g_markup_printf_escaped("%s", uzbl.state.keycmd->str) :
+ g_strdup("");
+ g_string_append(ret, buf);
+ free(buf);
break;
case SYM_MODE:
g_string_append(ret,
/* --End Statusbar functions-- */
-// make sure to put "" or '' around args, so that if there is whitespace we can still keep arguments together.
-// note: if your args contain ', you must wrap them in "" (you cannot escape inside '')
-// if your args contain ", you should wrap them in "" and escape them
+// make sure that the args string you pass can properly be interpreted (eg properly escaped against whitespace, quotes etc)
static gboolean
run_command (const char *command, const char *args, const gboolean sync, char **stdout) {
//command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
- GString* to_execute = g_string_new ("");
+ GString *to_execute = g_string_new ("");
GError *err = NULL;
- gchar* cmd = g_strstrip(g_strdup(command));
+ gchar *cmd = g_strstrip(g_strdup(command));
+ gchar *qcfg = (uzbl.state.config_file ? g_shell_quote(uzbl.state.config_file) : g_strdup("''"));
+ gchar *qfifo = (uzbl.comm.fifo_path ? g_shell_quote(uzbl.comm.fifo_path) : g_strdup("''"));
+ gchar *qsock = (uzbl.comm.socket_path ? g_shell_quote(uzbl.comm.socket_path) : g_strdup("''"));
+ gchar *quri = (uzbl.state.uri ? g_shell_quote(uzbl.state.uri) : g_strdup("''"));
+ gchar *qtitle = (uzbl.gui.main_title ? g_shell_quote(uzbl.gui.main_title) : g_strdup("''"));
+
gboolean result;
- const char* search = "\"";
- const char* replace = "\\\"";
- g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'",
- cmd, (uzbl.state.config_file ? uzbl.state.config_file : "(null)"),
- (int) getpid(), (int) uzbl.xwin, uzbl.comm.fifo_path,
- uzbl.comm.socket_path);
- g_string_append_printf (to_execute, " \"%s\" \"%s\"",
- uzbl.state.uri,
- str_replace(search, replace, uzbl.gui.main_title));
+ g_string_printf (to_execute, "%s %s '%i' '%i' %s %s",
+ cmd, qcfg, (int) getpid(), (int) uzbl.xwin, qfifo, qsock);
+ g_string_append_printf (to_execute, " %s %s", quri, qtitle);
if(args) g_string_append_printf (to_execute, " %s", args);
if (sync) {
g_printerr("error on run_command: %s\n", err->message);
g_error_free (err);
}
+
+ g_free (qcfg);
+ g_free (qfifo);
+ g_free (qsock);
+ g_free (quri);
+ g_free (qtitle);
g_free (cmd);
return result;
}
static void
spawn(WebKitWebView *web_view, const char *param) {
(void)web_view;
+/*
+ TODO: allow more control over argument order so that users can have some arguments before the default ones from run_command, and some after
+ gchar** cmd = g_strsplit(param, " ", 2);
+ gchar * args = NULL;
+ if (cmd[1]) {
+ args = g_shell_quote(cmd[1]);
+ }
+ if (cmd) {
+ run_command(cmd[0], args, FALSE, NULL);
+ }
+ if (args) {
+ g_free(args);
+ }
+*/
run_command(param, NULL, FALSE, NULL);
}
void **p = NULL;
if( (p = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
- if(var_is("status_format", name)
- || var_is("useragent", name)
+ if(var_is("uri", name)
+ || var_is("status_message", name)
+ || var_is("status_format", name)
+ || var_is("status_background", name)
|| var_is("title_format_short", name)
- || var_is("title_format_long", name)) {
+ || var_is("title_format_long", name)
+ || var_is("modkey", name)
+ || var_is("load_finish_handler", name)
+ || var_is("history_handler", name)
+ || var_is("download_handler", name)
+ || var_is("cookie_handler", name)
+ || var_is("fifo_dir", name)
+ || var_is("socket_dir", name)
+ || var_is("shell_cmd", name)
+ || var_is("proxy_url", name)
+ || var_is("useragent", name))
+ {
printf("VAR: %s VALUE: %s\n", name, (char *)*p);
} else printf("VAR: %s VALUE: %d\n", name, (int)*p);
}
set_var_value(gchar *name, gchar *val) {
void **p = NULL;
char *endp = NULL;
+ char *buf=NULL;
if( (p = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
if(var_is("status_message", name)
}
else if(var_is("fifo_dir", name)) {
if(*p) free(*p);
- *p = init_fifo(g_strdup(val));
+ buf = init_fifo(val);
+ *p = buf?buf:g_strdup("");
}
else if(var_is("socket_dir", name)) {
if(*p) free(*p);
- *p = init_socket(g_strdup(val));
+ buf = init_socket(val);
+ *p = buf?buf:g_strdup("");
}
else if(var_is("modkey", name)) {
if(*p) free(*p);
}
else if(var_is("useragent", name)) {
if(*p) free(*p);
- *p = set_useragent(g_strdup(val));
+ buf = set_useragent(val);
+ *p = buf?buf:g_strdup("");
}
else if(var_is("shell_cmd", name)) {
if(*p) free(*p);
SOUP_SESSION_MAX_CONNS_PER_HOST, uzbl.net.max_conns_host, NULL);
}
else if (var_is("http_debug", name)) {
- //soup_session_remove_feature
- // (uzbl.net.soup_session, uzbl.net.soup_logger);
soup_session_remove_feature
(uzbl.net.soup_session, SOUP_SESSION_FEATURE(uzbl.net.soup_logger));
/* do we leak if this doesn't get freed? why does it occasionally crash if freed? */
}
if (*dir == ' ') { /* space unsets the variable */
- g_free(dir);
return NULL;
}
/* if we got this far, there was an error; cleanup */
if (error) g_error_free (error);
g_free(path);
- g_free(dir);
return NULL;
}
static gboolean
control_stdin(GIOChannel *gio, GIOCondition condition) {
+ (void) condition;
gchar *ctl_line = NULL;
- gsize ctl_line_len = 0;
GIOStatus ret;
- if (condition & G_IO_HUP) {
- ret = g_io_channel_shutdown (gio, FALSE, NULL);
- return FALSE;
- }
-
- ret = g_io_channel_read_line(gio, &ctl_line, &ctl_line_len, NULL, NULL);
+ ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, NULL);
if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) )
return FALSE;
return NULL;
}
+/*
+ NOTE: we want to keep variables like b->title_format_long in their "unprocessed" state
+ it will probably improve performance if we would "cache" the processed variant, but for now it works well enough...
+*/
+// this function may be called very early when the templates are not set (yet), hence the checks
static void
update_title (void) {
Behaviour *b = &uzbl.behave;
+ gchar *parsed;
if (b->show_status) {
- gchar *statln;
- gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), expand_template(b->title_format_short));
- // TODO: we should probably not do this every time we want to update the title..?
- statln = expand_template(uzbl.behave.status_format);
- gtk_label_set_markup(GTK_LABEL(uzbl.gui.mainbar_label), statln);
+ if (b->title_format_short) {
+ parsed = expand_template(b->title_format_short);
+ gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
+ g_free(parsed);
+ }
+ if (b->status_format) {
+ parsed = expand_template(b->status_format);
+ 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)
gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color);
}
- g_free(statln);
} else {
- gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), expand_template(b->title_format_long));
+ if (b->title_format_long) {
+ parsed = expand_template(b->title_format_long);
+ gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
+ g_free(parsed);
+ }
}
}
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 ());
g->mainbar = gtk_hbox_new (FALSE, 0);
- /* keep a reference to the bar so we can re-pack it at runtime*/
- //sbar_ref = g_object_ref(g->mainbar);
-
g->mainbar_label = gtk_label_new ("");
gtk_label_set_selectable((GtkLabel *)g->mainbar_label, TRUE);
gtk_label_set_ellipsize(GTK_LABEL(g->mainbar_label), PANGO_ELLIPSIZE_END);
//Debug:
if (uzbl.state.verbose)
printf ("Binding %-10s : %s\n", key, act);
- action = new_action(parts[0], parts[1]);
- if(g_hash_table_lookup(uzbl.bindings, key))
- g_hash_table_remove(uzbl.bindings, key);
- g_hash_table_insert(uzbl.bindings, g_strdup(key), action);
+ action = new_action(parts[0], parts[1]);
+ g_hash_table_replace(uzbl.bindings, g_strdup(key), action);
g_strfreev(parts);
}
const gchar* actual_value = getenv (xdg.environmental);
const gchar* home = getenv ("HOME");
- gchar* return_value = str_replace ("~", home, g_strdup (actual_value));
+ gchar* return_value = str_replace ("~", home, actual_value);
if (! actual_value || strcmp (actual_value, "") == 0) {
if (xdg.default_value) {
- return_value = str_replace ("~", home, g_strdup (xdg.default_value));
+ return_value = str_replace ("~", home, xdg.default_value);
} else {
return_value = NULL;
}
}
-
return return_value;
}
xdg_type = 1 => data
xdg_type = 2 => cache*/
- gchar* xdg_config_home = get_xdg_var (XDG[0]);
- gchar* xdg_data_home = get_xdg_var (XDG[1]);
- gchar* xdg_cache_home = get_xdg_var (XDG[2]);
- gchar* xdg_config_dirs = get_xdg_var (XDG[3]);
- gchar* xdg_data_dirs = get_xdg_var (XDG[4]);
- gchar* temporary_file = (char *)malloc (1024);
+ gchar* temporary_file = malloc (1024);
gchar* temporary_string = NULL;
char* saveptr;
+ char* buf;
- if (xdg_type == 0)
- strcpy (temporary_file, xdg_config_home);
-
- if (xdg_type == 1)
- strcpy (temporary_file, xdg_data_home);
-
- if (xdg_type == 2)
- strcpy (temporary_file, xdg_cache_home);
-
+ buf = get_xdg_var (XDG[xdg_type]);
+ strcpy (temporary_file, buf);
strcat (temporary_file, filename);
+ free(buf);
if (! file_exists (temporary_file) && xdg_type != 2) {
- if (xdg_type == 0)
- temporary_string = (char *) strtok_r (xdg_config_dirs, ":", &saveptr);
-
- if (xdg_type == 1)
- temporary_string = (char *) strtok_r (xdg_data_dirs, ":", &saveptr);
-
+ buf = get_xdg_var (XDG[3 + xdg_type]);
+ temporary_string = (char *) strtok_r (buf, ":", &saveptr);
+ free(buf);
+
while (temporary_string && ! file_exists (temporary_file)) {
strcpy (temporary_file, temporary_string);
strcat (temporary_file, filename);
uzbl.behave.reset_command_mode = 1;
if (!s->config_file) {
- s->config_file = g_strdup (find_xdg_file (0, "/uzbl/config"));
+ s->config_file = find_xdg_file (0, "/uzbl/config");
}
if (s->config_file) {
printf ("No configuration file loaded.\n");
}
if (!uzbl.behave.status_format)
- uzbl.behave.status_format = g_strdup(STATUS_DEFAULT);
+ set_var_value("status_format", STATUS_DEFAULT);
if (!uzbl.behave.title_format_long)
- uzbl.behave.title_format_long = g_strdup(TITLE_LONG_DEFAULT);
+ set_var_value("title_format_long", TITLE_LONG_DEFAULT);
if (!uzbl.behave.title_format_short)
- uzbl.behave.title_format_short = g_strdup(TITLE_SHORT_DEFAULT);
+ set_var_value("title_format_short", TITLE_SHORT_DEFAULT);
g_signal_connect(n->soup_session, "request-queued", G_CALLBACK(handle_cookies), NULL);
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);
/* initialize hash table */
uzbl.bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
uzbl.gui.main_window = create_window ();
gtk_container_add (GTK_CONTAINER (uzbl.gui.main_window), uzbl.gui.vbox);
- load_uri (uzbl.gui.web_view, uzbl.state.uri); //TODO: is this needed?
gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view));
gtk_widget_show_all (uzbl.gui.main_window);
create_stdin();
+ if(uzbl.state.uri)
+ load_uri (uzbl.gui.web_view, uzbl.state.uri);
+
+
gtk_main ();
clean_up();