#define LENGTH(x) (sizeof x / sizeof x[0])
#define MAX_BINDINGS 256
+#define _POSIX_SOURCE
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <sys/utsname.h>
#include <sys/time.h>
#include <webkit/webkit.h>
+#include <libsoup/soup.h>
+#include <JavaScriptCore/JavaScript.h>
+
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
-#include <string.h>
#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <libsoup/soup.h>
#include <signal.h>
#include "uzbl.h"
#include "config.h"
static Uzbl uzbl;
-typedef void (*Command)(WebKitWebView*, GArray *argv);
"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,
+ "Socket ID", "SOCKET" },
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
void (*func)(void);
} uzbl_cmdprop;
-enum {TYPE_INT, TYPE_STR};
+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 }
/* 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)},
{ "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)},
{ "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)},
- /* exported WebKitWebSettings properties*/
+ /* 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)},
}
}
-
/* --- UTILITY FUNCTIONS --- */
+enum {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS};
+static guint
+get_exp_type(gchar *s) {
+ /* variables */
+ if(*(s+1) == '(')
+ return EXP_EXPR;
+ else if(*(s+1) == '{')
+ return EXP_BRACED_VAR;
+ else if(*(s+1) == '<')
+ return EXP_JS;
+ else
+ return EXP_SIMPLE_VAR;
+
+return EXP_ERR;
+}
+
+/*
+ * recurse == 1: don't expand '@(command)@'
+ * recurse == 2: don't expand '@<java script>@'
+ */
+static gchar *
+expand(char *s, guint recurse) {
+ uzbl_cmdprop *c;
+ guint etype;
+ char upto = ' ';
+ char *end_simple_var = "^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½";
+ char str_end[2];
+ char ret[4096];
+ char *vend;
+ GError *err = NULL;
+ gchar *cmd_stdout = NULL;
+ gchar *mycmd = NULL;
+ GString *buf = g_string_new("");
+ GString *js_ret = g_string_new("");
+
+ while(*s) {
+ switch(*s) {
+ case '\\':
+ g_string_append_c(buf, *++s);
+ s++;
+ break;
+
+ case '@':
+ etype = get_exp_type(s);
+ s++;
+
+ 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';
+ }
+ 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';
+ }
+ 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';
+ }
+ break;
+ 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';
+ }
+ break;
+ }
+
+ 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)
+ g_string_append(buf, (gchar *)*c->ptr);
+ else if(c->type == TYPE_INT) {
+ char *b = itos((int)*c->ptr);
+ g_string_append(buf, b);
+ g_free(b);
+ }
+ }
+ if(etype == EXP_SIMPLE_VAR)
+ s = vend;
+ else
+ s = vend+1;
+ }
+ else if(recurse != 1 &&
+ etype == EXP_EXPR) {
+ mycmd = expand(ret, 1);
+ g_spawn_command_line_sync(mycmd, &cmd_stdout, NULL, NULL, &err);
+ g_free(mycmd);
+
+ if (err) {
+ g_printerr("error on running command: %s\n", err->message);
+ g_error_free (err);
+ }
+ else if (*cmd_stdout) {
+ g_string_append(buf, cmd_stdout);
+ g_free(cmd_stdout);
+ }
+ s = vend+2;
+ }
+ else if(recurse != 2 &&
+ etype == EXP_JS) {
+ mycmd = expand(ret, 2);
+ eval_js(uzbl.gui.web_view, mycmd, js_ret);
+ g_free(mycmd);
+
+ if(js_ret->str) {
+ g_string_append(buf, js_ret->str);
+ g_string_free(js_ret, TRUE);
+ js_ret = g_string_new("");
+ }
+ s = vend+2;
+ }
+ break;
+
+ default:
+ g_string_append_c(buf, *s);
+ s++;
+ break;
+ }
+ }
+ g_string_free(js_ret, TRUE);
+ return g_string_free(buf, FALSE);
+}
+
char *
itos(int val) {
char tmp[20];
return (FALSE);
}
+static gboolean
+mime_policy_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, gchar *mime_type, WebKitWebPolicyDecision *policy_decision, gpointer user_data) {
+ (void) frame;
+ (void) request;
+ (void) user_data;
+
+ /* If we can display it, let's display it... */
+ if (webkit_web_view_can_show_mime_type (web_view, mime_type)) {
+ webkit_web_policy_decision_use (policy_decision);
+ return TRUE;
+ }
+
+ /* ...everything we can't displayed is downloaded */
+ webkit_web_policy_decision_download (policy_decision);
+ return TRUE;
+}
+
WebKitWebView*
create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data) {
(void) web_view;
/* scroll a bar in a given direction */
static void
scroll (GtkAdjustment* bar, GArray *argv) {
- gdouble amount;
gchar *end;
+ gdouble max_value;
+
+ gdouble page_size = gtk_adjustment_get_page_size(bar);
+ gdouble value = gtk_adjustment_get_value(bar);
+ gdouble amount = g_ascii_strtod(g_array_index(argv, gchar*, 0), &end);
+
+ if (*end == '%')
+ value += page_size * amount * 0.01;
+ else
+ value += amount;
- amount = g_ascii_strtod(g_array_index(argv, gchar*, 0), &end);
- if (*end == '%') amount = gtk_adjustment_get_page_size(bar) * amount * 0.01;
- gtk_adjustment_set_value (bar, gtk_adjustment_get_value(bar)+amount);
+ max_value = gtk_adjustment_get_upper(bar) - page_size;
+
+ if (value > max_value)
+ value = max_value; /* don't scroll past the end of the page */
+
+ gtk_adjustment_set_value (bar, value);
}
static void
-scroll_begin(WebKitWebView* page, GArray *argv) {
- (void) page; (void) argv;
+scroll_begin(WebKitWebView* page, GArray *argv, GString *result) {
+ (void) page; (void) argv; (void) result;
gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_lower(uzbl.gui.bar_v));
}
static void
-scroll_end(WebKitWebView* page, GArray *argv) {
- (void) page; (void) argv;
+scroll_end(WebKitWebView* page, GArray *argv, GString *result) {
+ (void) page; (void) argv; (void) result;
gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_upper(uzbl.gui.bar_v) -
gtk_adjustment_get_page_size(uzbl.gui.bar_v));
}
static void
-scroll_vert(WebKitWebView* page, GArray *argv) {
- (void) page;
+scroll_vert(WebKitWebView* page, GArray *argv, GString *result) {
+ (void) page; (void) result;
scroll(uzbl.gui.bar_v, argv);
}
static void
-scroll_horz(WebKitWebView* page, GArray *argv) {
- (void) page;
+scroll_horz(WebKitWebView* page, GArray *argv, GString *result) {
+ (void) page; (void) result;
scroll(uzbl.gui.bar_h, argv);
}
}
static void
-toggle_status_cb (WebKitWebView* page, GArray *argv) {
+toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) {
+ (void)page;
+ (void)argv;
+ (void)result;
+
+ webkit_web_view_set_full_content_zoom (page, !webkit_web_view_get_full_content_zoom (page));
+}
+
+static void
+toggle_status_cb (WebKitWebView* page, GArray *argv, GString *result) {
(void)page;
(void)argv;
+ (void)result;
if (uzbl.behave.show_status) {
gtk_widget_hide(uzbl.gui.mainbar);
(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?
if (uzbl.behave.load_start_handler)
run_handler(uzbl.behave.load_start_handler, "");
/* VIEW funcs (little webkit wrappers) */
-#define VIEWFUNC(name) static void view_##name(WebKitWebView *page, GArray *argv){(void)argv; webkit_web_view_##name(page);}
+#define VIEWFUNC(name) static void view_##name(WebKitWebView *page, GArray *argv, GString *result){(void)argv; (void)result; webkit_web_view_##name(page);}
VIEWFUNC(reload)
VIEWFUNC(reload_bypass_cache)
VIEWFUNC(stop_loading)
#undef VIEWFUNC
/* -- command to callback/function map for things we cannot attach to any signals */
-// TODO: reload
-static struct {char *name; Command command[2];} cmdlist[] =
+static struct {char *key; CommandInfo value;} cmdlist[] =
{ /* key function no_split */
{ "back", {view_go_back, 0} },
{ "forward", {view_go_forward, 0} },
{ "stop", {view_stop_loading, 0}, },
{ "zoom_in", {view_zoom_in, 0}, }, //Can crash (when max zoom reached?).
{ "zoom_out", {view_zoom_out, 0}, },
- { "uri", {load_uri, NOSPLIT} },
- { "js", {run_js, NOSPLIT} },
+ { "toggle_zoom_type", {toggle_zoom_type, 0}, },
+ { "uri", {load_uri, TRUE} },
+ { "js", {run_js, TRUE} },
{ "script", {run_external_js, 0} },
{ "toggle_status", {toggle_status_cb, 0} },
{ "spawn", {spawn, 0} },
{ "sh", {spawn_sh, 0} },
{ "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler
{ "exit", {close_uzbl, 0} },
- { "search", {search_forward_text, NOSPLIT} },
- { "search_reverse", {search_reverse_text, NOSPLIT} },
+ { "search", {search_forward_text, TRUE} },
+ { "search_reverse", {search_reverse_text, TRUE} },
{ "dehilight", {dehilight, 0} },
{ "toggle_insert_mode", {toggle_insert_mode, 0} },
- { "runcmd", {runcmd, NOSPLIT} },
- { "set", {set_var, NOSPLIT} },
- { "dump_config", {act_dump_config, 0} }
+ { "set", {set_var, TRUE} },
+ //{ "get", {get_var, TRUE} },
+ { "bind", {act_bind, TRUE} },
+ { "dump_config", {act_dump_config, 0} },
+ { "keycmd", {keycmd, TRUE} },
+ { "keycmd_nl", {keycmd_nl, TRUE} },
+ { "keycmd_bs", {keycmd_bs, 0} },
+ { "chain", {chain, 0} },
+ { "print", {print, TRUE} }
};
static void
uzbl.behave.commands = g_hash_table_new(g_str_hash, g_str_equal);
for (i = 0; i < LENGTH(cmdlist); i++)
- g_hash_table_insert(uzbl.behave.commands, cmdlist[i].name, cmdlist[i].command);
+ g_hash_table_insert(uzbl.behave.commands, cmdlist[i].key, &cmdlist[i].value);
}
/* -- CORE FUNCTIONS -- */
}
static void
-set_var(WebKitWebView *page, GArray *argv) {
- (void) page;
- gchar *ctl_line;
+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);
+ g_strfreev(split);
+}
- ctl_line = g_strdup_printf("%s %s", "set", argv_idx(argv, 0));
- parse_cmd_line(ctl_line);
- g_free(ctl_line);
+static void
+print(WebKitWebView *page, GArray *argv, GString *result) {
+ (void) page; (void) result;
+ gchar* buf;
+
+ buf = expand(argv_idx(argv, 0), 0);
+ g_string_assign(result, buf);
+ g_free(buf);
}
static void
+act_bind(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]) : " "));
+ add_binding(g_strstrip(split[0]), value);
+ g_free(value);
+ g_strfreev(split);
+}
+
+
+static void
act_dump_config() {
dump_config();
}
static void
-toggle_insert_mode(WebKitWebView *page, GArray *argv) {
- (void)page;
+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) {
}
static void
-load_uri (WebKitWebView *web_view, GArray *argv) {
+load_uri (WebKitWebView *web_view, GArray *argv, GString *result) {
+ (void) result;
+
if (argv_idx(argv, 0)) {
GString* newuri = g_string_new (argv_idx(argv, 0));
- if (g_strrstr (argv_idx(argv, 0), "://") == NULL)
+ if (g_strstr_len (argv_idx(argv, 0), 11, "javascript:") != NULL) {
+ run_js(web_view, argv, NULL);
+ return;
+ }
+ if (g_strrstr (argv_idx(argv, 0), "://") == NULL && g_strstr_len (argv_idx(argv, 0), 5, "data:") == NULL)
g_string_prepend (newuri, "http://");
/* if we do handle cookies, ask our handler for them */
webkit_web_view_load_uri (web_view, newuri->str);
}
}
+
+/* Javascript*/
+
+static JSValueRef
+js_run_command (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
+ size_t argumentCount, const JSValueRef arguments[],
+ JSValueRef* exception) {
+ (void) function;
+ (void) thisObject;
+ (void) exception;
+
+ JSStringRef js_result_string;
+ GString *result = g_string_new("");
+
+ if (argumentCount >= 1) {
+ JSStringRef arg = JSValueToStringCopy(ctx, arguments[0], NULL);
+ size_t arg_size = JSStringGetMaximumUTF8CStringSize(arg);
+ char ctl_line[arg_size];
+ JSStringGetUTF8CString(arg, ctl_line, arg_size);
+
+ parse_cmd_line(ctl_line, result);
+
+ JSStringRelease(arg);
+ }
+ js_result_string = JSStringCreateWithUTF8CString(result->str);
+
+ g_string_free(result, TRUE);
+
+ return JSValueMakeString(ctx, js_result_string);
+}
+
+static JSStaticFunction js_static_functions[] = {
+ {"run", js_run_command, kJSPropertyAttributeNone},
+};
+
+static void
+js_init() {
+ /* This function creates the class and its definition, only once */
+ if (!uzbl.js.initialized) {
+ /* it would be pretty cool to make this dynamic */
+ uzbl.js.classdef = kJSClassDefinitionEmpty;
+ uzbl.js.classdef.staticFunctions = js_static_functions;
+
+ uzbl.js.classref = JSClassCreate(&uzbl.js.classdef);
+ }
+}
+
+
+static void
+eval_js(WebKitWebView * web_view, gchar *script, GString *result) {
+ WebKitWebFrame *frame;
+ JSGlobalContextRef context;
+ JSObjectRef globalobject;
+ JSStringRef var_name;
+
+ JSStringRef js_script;
+ 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),
+ kJSClassAttributeNone, NULL);
+
+ /* 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)) {
+ js_result_string = JSValueToStringCopy(context, js_result, NULL);
+ js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string);
+
+ if (js_result_size) {
+ char js_result_utf8[js_result_size];
+ JSStringGetUTF8CString(js_result_string, js_result_utf8, js_result_size);
+ g_string_assign(result, js_result_utf8);
+ }
+
+ JSStringRelease(js_result_string);
+ }
+
+ /* cleanup */
+ JSObjectDeleteProperty(context, globalobject, var_name, NULL);
+
+ JSStringRelease(var_name);
+ JSStringRelease(js_script);
+}
+
static void
-run_js (WebKitWebView * web_view, GArray *argv) {
+run_js (WebKitWebView * web_view, GArray *argv, GString *result) {
+
if (argv_idx(argv, 0))
- webkit_web_view_execute_script (web_view, argv_idx(argv, 0));
+ eval_js(web_view, argv_idx(argv, 0), result);
}
static void
-run_external_js (WebKitWebView * web_view, GArray *argv) {
+run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) {
+ (void) result;
if (argv_idx(argv, 0)) {
GArray* lines = read_file_by_line (argv_idx (argv, 0));
gchar* js = NULL;
g_free (js);
js = newjs;
}
- webkit_web_view_execute_script (web_view, js);
+ eval_js (web_view, js, result);
g_free (js);
g_array_free (lines, TRUE);
}
}
static void
-search_forward_text (WebKitWebView *page, GArray *argv) {
+search_forward_text (WebKitWebView *page, GArray *argv, GString *result) {
+ (void) result;
search_text(page, argv, TRUE);
}
static void
-search_reverse_text (WebKitWebView *page, GArray *argv) {
+search_reverse_text (WebKitWebView *page, GArray *argv, GString *result) {
+ (void) result;
search_text(page, argv, FALSE);
}
static void
-dehilight (WebKitWebView *page, GArray *argv) {
- (void) argv;
+dehilight (WebKitWebView *page, GArray *argv, GString *result) {
+ (void) argv; (void) result;
webkit_web_view_set_highlight_text_matches (page, FALSE);
}
}
static void
-close_uzbl (WebKitWebView *page, GArray *argv) {
+chain (WebKitWebView *page, GArray *argv, GString *result) {
+ (void) page; (void) result;
+ gchar *a = NULL;
+ gchar **parts = NULL;
+ guint i = 0;
+ while ((a = argv_idx(argv, i++))) {
+ parts = g_strsplit (a, " ", 2);
+ parse_command(parts[0], parts[1], result);
+ g_strfreev (parts);
+ }
+}
+
+static void
+keycmd (WebKitWebView *page, GArray *argv, GString *result) {
+ (void)page;
+ (void)argv;
+ (void)result;
+ g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+ run_keycmd(FALSE);
+ update_title();
+}
+
+static void
+keycmd_nl (WebKitWebView *page, GArray *argv, GString *result) {
+ (void)page;
+ (void)argv;
+ (void)result;
+ g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0));
+ run_keycmd(TRUE);
+ update_title();
+}
+
+static void
+keycmd_bs (WebKitWebView *page, GArray *argv, GString *result) {
+ gchar *prev;
+ (void)page;
+ (void)argv;
+ (void)result;
+ prev = g_utf8_find_prev_char(uzbl.state.keycmd->str, uzbl.state.keycmd->str + uzbl.state.keycmd->len);
+ if (prev)
+ g_string_truncate(uzbl.state.keycmd, prev - uzbl.state.keycmd->str);
+ update_title();
+}
+
+static void
+close_uzbl (WebKitWebView *page, GArray *argv, GString *result) {
(void)page;
(void)argv;
+ (void)result;
gtk_main_quit ();
}
// make sure that the args string you pass can properly be interpreted (eg properly escaped against whitespace, quotes etc)
static gboolean
run_command (const gchar *command, const guint npre, const gchar **args,
- const gboolean sync, char **stdout) {
+ const gboolean sync, char **output_stdout) {
//command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
GError *err = NULL;
gboolean result;
if (sync) {
- if (*stdout) *stdout = strfree(*stdout);
+ if (*output_stdout) *output_stdout = strfree(*output_stdout);
result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
- NULL, NULL, stdout, NULL, NULL, &err);
+ NULL, NULL, output_stdout, NULL, NULL, &err);
} else result = g_spawn_async(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, NULL, &err);
g_string_append_printf(s, " -- result: %s", (result ? "true" : "false"));
printf("%s\n", s->str);
g_string_free(s, TRUE);
+ if(output_stdout) {
+ printf("Stdout: %s\n", *output_stdout);
+ }
}
if (err) {
g_printerr("error on run_command: %s\n", err->message);
}
static void
-spawn(WebKitWebView *web_view, GArray *argv) {
- (void)web_view;
+spawn(WebKitWebView *web_view, GArray *argv, GString *result) {
+ (void)web_view; (void)result;
//TODO: allow more control over argument order so that users can have some arguments before the default ones from run_command, and some after
if (argv_idx(argv, 0))
run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))), FALSE, NULL);
}
static void
-spawn_sync(WebKitWebView *web_view, GArray *argv) {
- (void)web_view;
+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*))),
}
static void
-spawn_sh(WebKitWebView *web_view, GArray *argv) {
- (void)web_view;
+spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result) {
+ (void)web_view; (void)result;
if (!uzbl.behave.shell_cmd) {
g_printerr ("spawn_sh: shell_cmd is not set!\n");
return;
}
static void
-spawn_sh_sync(WebKitWebView *web_view, GArray *argv) {
- (void)web_view;
+spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
+ (void)web_view; (void)result;
if (!uzbl.behave.shell_cmd) {
g_printerr ("spawn_sh_sync: shell_cmd is not set!\n");
return;
}
static void
-parse_command(const char *cmd, const char *param) {
- Command *c;
+parse_command(const char *cmd, const char *param, GString *result) {
+ CommandInfo *c;
if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) {
-
guint i;
gchar **par = split_quoted(param, TRUE);
GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
- if (c[1] == NOSPLIT) { /* don't split */
+ if (c->no_split) { /* don't split */
sharg_append(a, param);
} else if (par) {
for (i = 0; i < g_strv_length(par); i++)
sharg_append(a, par[i]);
}
- c[0](uzbl.gui.web_view, a);
+
+ if (result == NULL) {
+ GString *result_print = g_string_new("");
+
+ c->function(uzbl.gui.web_view, a, result_print);
+ if (result_print->len)
+ printf("%*s\n", result_print->len, result_print->str);
+
+ g_string_free(result_print, TRUE);
+ } else {
+ c->function(uzbl.gui.web_view, a, result);
+ }
g_strfreev (par);
g_array_free (a, TRUE);
g_printerr ("command \"%s\" not understood. ignoring.\n", cmd);
}
-/* command parser */
-static void
-setup_regex() {
- uzbl.comm.get_regex = g_regex_new("^[Gg][a-zA-Z]*\\s+([^ \\n]+)$",
- G_REGEX_OPTIMIZE, 0, NULL);
- uzbl.comm.set_regex = g_regex_new("^[Ss][a-zA-Z]*\\s+([^ ]+)\\s*=\\s*([^\\n].*)$",
- G_REGEX_OPTIMIZE, 0, NULL);
- uzbl.comm.bind_regex = g_regex_new("^[Bb][a-zA-Z]*\\s+?(.*[^ ])\\s*?=\\s*([a-z][^\\n].+)$",
- G_REGEX_UNGREEDY|G_REGEX_OPTIMIZE, 0, NULL);
- uzbl.comm.act_regex = g_regex_new("^[Aa][a-zA-Z]*\\s+([^ \\n]+)\\s*([^\\n]*)?$",
- G_REGEX_OPTIMIZE, 0, NULL);
- uzbl.comm.keycmd_regex = g_regex_new("^[Kk][a-zA-Z]*\\s+([^\\n]+)$",
- G_REGEX_OPTIMIZE, 0, NULL);
-}
-
-static gboolean
-get_var_value(gchar *name) {
- uzbl_cmdprop *c;
-
- if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
- if(c->type == TYPE_STR)
- printf("VAR: %s VALUE: %s\n", name, (char *)*c->ptr);
- else if(c->type == TYPE_INT)
- printf("VAR: %s VALUE: %p\n", name, *c->ptr);
- }
- return TRUE;
-}
-
static void
set_proxy_url() {
SoupURI *suri;
}
static void
+set_icon() {
+ if(file_exists(uzbl.gui.icon)) {
+ if (uzbl.gui.main_window)
+ gtk_window_set_icon_from_file (GTK_WINDOW (uzbl.gui.main_window), uzbl.gui.icon, NULL);
+ } else {
+ g_printerr ("Icon \"%s\" not found. ignoring.\n", uzbl.gui.icon);
+ }
+ g_free (uzbl.gui.icon);
+}
+
+static void
cmd_load_uri() {
GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
g_array_append_val (a, uzbl.state.uri);
- load_uri(uzbl.gui.web_view, a);
+ load_uri(uzbl.gui.web_view, a, NULL);
g_array_free (a, TRUE);
}
}
static void
+cmd_zoom_level() {
+ webkit_web_view_set_zoom_level (uzbl.gui.web_view, uzbl.behave.zoom_level);
+}
+
+static void
cmd_disable_plugins() {
g_object_set (G_OBJECT(view_settings()), "enable-plugins",
!uzbl.behave.disable_plugins, NULL);
static void
cmd_disable_scripts() {
g_object_set (G_OBJECT(view_settings()), "enable-scripts",
- !uzbl.behave.disable_plugins, NULL);
+ !uzbl.behave.disable_scripts, NULL);
}
static void
static void
cmd_cookie_handler() {
gchar **split = g_strsplit(uzbl.behave.cookie_handler, " ", 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.cookie_handler);
set_var_value(gchar *name, gchar *val) {
uzbl_cmdprop *c = NULL;
char *endp = NULL;
+ char *buf = NULL;
if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
/* check for the variable type */
if (c->type == TYPE_STR) {
+ buf = expand(val, 0);
g_free(*c->ptr);
- *c->ptr = g_strdup(val);
+ *c->ptr = buf;
} else if(c->type == TYPE_INT) {
- int *ip = (int *) c->ptr;
- *ip = (int)strtoul(val, &endp, 10);
+ int *ip = (int *)c->ptr;
+ buf = expand(val, 0);
+ *ip = (int)strtoul(buf, &endp, 10);
+ g_free(buf);
+ } else if (c->type == TYPE_FLOAT) {
+ float *fp = (float *)c->ptr;
+ buf = expand(val, 0);
+ *fp = strtod(buf, &endp);
+ g_free(buf);
}
/* invoke a command specific function */
}
static void
-runcmd(WebKitWebView* page, GArray *argv) {
- (void) page;
- parse_cmd_line(argv_idx(argv, 0));
-}
-
-static void
render_html() {
Behaviour *b = &uzbl.behave;
enum {M_CMD, M_HTML};
static void
-parse_cmd_line(const char *ctl_line) {
- gchar **tokens = NULL;
+parse_cmd_line(const char *ctl_line, GString *result) {
Behaviour *b = &uzbl.behave;
size_t len=0;
g_string_append(b->html_buffer, ctl_line);
}
}
- else {
- /* SET command */
- if(ctl_line[0] == 's' || ctl_line[0] == 'S') {
- tokens = g_regex_split(uzbl.comm.set_regex, ctl_line, 0);
- if(tokens[0][0] == 0) {
- gchar* value = parseenv(g_strdup(tokens[2]));
- set_var_value(tokens[1], value);
- g_free(value);
- }
- else
- printf("Error in command: %s\n", tokens[0]);
- }
- /* GET command */
- else if(ctl_line[0] == 'g' || ctl_line[0] == 'G') {
- tokens = g_regex_split(uzbl.comm.get_regex, ctl_line, 0);
- if(tokens[0][0] == 0) {
- get_var_value(tokens[1]);
- }
- else
- printf("Error in command: %s\n", tokens[0]);
- }
- /* BIND command */
- else if(ctl_line[0] == 'b' || ctl_line[0] == 'B') {
- tokens = g_regex_split(uzbl.comm.bind_regex, ctl_line, 0);
- if(tokens[0][0] == 0) {
- gchar* value = parseenv(g_strdup(tokens[2]));
- add_binding(tokens[1], value);
- g_free(value);
- }
- else
- printf("Error in command: %s\n", tokens[0]);
- }
- /* ACT command */
- else if(ctl_line[0] == 'A' || ctl_line[0] == 'a') {
- tokens = g_regex_split(uzbl.comm.act_regex, ctl_line, 0);
- if(tokens[0][0] == 0) {
- parse_command(tokens[1], tokens[2]);
- }
- else
- printf("Error in command: %s\n", tokens[0]);
- }
- /* KEYCMD command */
- else if(ctl_line[0] == 'K' || ctl_line[0] == 'k') {
- tokens = g_regex_split(uzbl.comm.keycmd_regex, ctl_line, 0);
- if(tokens[0][0] == 0) {
- /* should incremental commands want each individual "keystroke"
- sent in a loop or the whole string in one go like now? */
- g_string_assign(uzbl.state.keycmd, tokens[1]);
- run_keycmd(FALSE);
- if (g_strstr_len(ctl_line, 7, "n") || g_strstr_len(ctl_line, 7, "N"))
- run_keycmd(TRUE);
- update_title();
- }
- }
- /* Comments */
- else if( (ctl_line[0] == '#')
- || (ctl_line[0] == ' ')
- || (ctl_line[0] == '\n'))
- ; /* ignore these lines */
- else
- printf("Command not understood (%s)\n", ctl_line);
-
- if(tokens)
- g_strfreev(tokens);
+ else if((ctl_line[0] == '#') /* Comments */
+ || (ctl_line[0] == ' ')
+ || (ctl_line[0] == '\n'))
+ ; /* ignore these lines */
+ else { /* parse a command */
+ gchar *ctlstrip;
+ gchar **tokens = NULL;
+ len = strlen(ctl_line);
+
+ if (ctl_line[len - 1] == '\n') /* strip trailing newline */
+ ctlstrip = g_strndup(ctl_line, len - 1);
+ else ctlstrip = g_strdup(ctl_line);
+
+ tokens = g_strsplit(ctlstrip, " ", 2);
+ parse_command(tokens[0], tokens[1], result);
+ g_free(ctlstrip);
+ g_strfreev(tokens);
}
-
- return;
}
static gchar*
build_stream_name(int type, const gchar* dir) {
- char *xwin_str;
+ char *xwin_str = NULL;
State *s = &uzbl.state;
- gchar *str;
+ gchar *str = NULL;
xwin_str = itos((int)uzbl.xwin);
if (type == FIFO) {
g_error_free (err);
}
- parse_cmd_line(ctl_line);
+ parse_cmd_line(ctl_line, NULL);
g_free(ctl_line);
return TRUE;
if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) )
return FALSE;
- parse_cmd_line(ctl_line);
+ parse_cmd_line(ctl_line, NULL);
g_free(ctl_line);
return TRUE;
static gboolean
control_socket(GIOChannel *chan) {
struct sockaddr_un remote;
- char buffer[512], *ctl_line;
- char temp[128];
- int sock, clientsock, n, done;
- unsigned int t;
-
- sock = g_io_channel_unix_get_fd(chan);
-
- memset (buffer, 0, sizeof (buffer));
+ unsigned int t = sizeof(remote);
+ int clientsock;
+ GIOChannel *clientchan;
- t = sizeof (remote);
- clientsock = accept (sock, (struct sockaddr *) &remote, &t);
-
- done = 0;
- do {
- memset (temp, 0, sizeof (temp));
- n = recv (clientsock, temp, 128, 0);
- if (n == 0) {
- buffer[strlen (buffer)] = '\0';
- done = 1;
- }
- if (!done)
- strcat (buffer, temp);
- } while (!done);
-
- if (strcmp (buffer, "\n") < 0) {
- buffer[strlen (buffer) - 1] = '\0';
- } else {
- buffer[strlen (buffer)] = '\0';
+ 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);
}
- close (clientsock);
- ctl_line = g_strdup(buffer);
- parse_cmd_line (ctl_line);
-/*
- TODO: we should be able to do it with this. but glib errors out with "Invalid argument"
+ return TRUE;
+}
+
+static gboolean
+control_client_socket(GIOChannel *clientchan) {
+ char *ctl_line;
+ GString *result = g_string_new("");
GError *error = NULL;
- gsize len;
GIOStatus ret;
- ret = g_io_channel_read_line(chan, &ctl_line, &len, NULL, &error);
- if (ret == G_IO_STATUS_ERROR)
- g_error ("Error reading: %s\n", error->message);
+ gsize len;
- printf("Got line %s (%u bytes) \n",ctl_line, len);
- if(ctl_line) {
- parse_line(ctl_line);
-*/
+ ret = g_io_channel_read_line(clientchan, &ctl_line, &len, NULL, &error);
+ if (ret == G_IO_STATUS_ERROR) {
+ g_warning ("Error reading: %s\n", error->message);
+ g_io_channel_shutdown(clientchan, TRUE, &error);
+ return FALSE;
+ } else if (ret == G_IO_STATUS_EOF) {
+ /* shutdown and remove channel watch from main loop */
+ g_io_channel_shutdown(clientchan, TRUE, &error);
+ return FALSE;
+ }
+
+ if (ctl_line) {
+ parse_cmd_line (ctl_line, result);
+ g_string_append_c(result, '\n');
+ ret = g_io_channel_write_chars (clientchan, result->str, result->len,
+ &len, &error);
+ if (ret == G_IO_STATUS_ERROR) {
+ g_warning ("Error writing: %s", error->message);
+ }
+ g_io_channel_flush(clientchan, &error);
+ }
+ if (error) g_error_free (error);
+ g_string_free(result, TRUE);
g_free(ctl_line);
return TRUE;
}
if (b->show_status) {
if (b->title_format_short) {
parsed = expand_template(b->title_format_short, FALSE);
- gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
+ if (uzbl.gui.main_window)
+ gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
g_free(parsed);
}
if (b->status_format) {
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);
+ if (uzbl.gui.main_window)
+ gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color);
}
} else {
if (b->title_format_long) {
parsed = expand_template(b->title_format_long, FALSE);
- gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
+ if (uzbl.gui.main_window)
+ gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), parsed);
g_free(parsed);
}
}
if (event->keyval == GDK_Escape) {
g_string_truncate(uzbl.state.keycmd, 0);
update_title();
- dehilight(uzbl.gui.web_view, NULL);
+ dehilight(uzbl.gui.web_view, NULL, NULL);
return TRUE;
}
return TRUE;
}
- if ((event->keyval == GDK_BackSpace) && (uzbl.state.keycmd->len > 0)) {
- g_string_truncate(uzbl.state.keycmd, uzbl.state.keycmd->len - 1);
- update_title();
- }
+ if (event->keyval == GDK_BackSpace)
+ keycmd_bs(NULL, NULL, NULL);
gboolean key_ret = FALSE;
if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter))
Action *act;
if ((act = g_hash_table_lookup(uzbl.bindings, uzbl.state.keycmd->str))) {
g_string_truncate(uzbl.state.keycmd, 0);
- parse_command(act->name, act->param);
+ parse_command(act->name, act->param, NULL);
return;
}
g_string_printf (actionname, act->name, parampart->str);
if (act->param)
g_string_printf (actionparam, act->param, parampart->str);
- parse_command(actionname->str, actionparam->str);
+ parse_command(actionname->str, actionparam->str, NULL);
g_string_free(actionname, TRUE);
g_string_free(actionparam, TRUE);
g_string_free(parampart, TRUE);
g_signal_connect (G_OBJECT (g->web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_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;
}
gtk_misc_set_alignment (GTK_MISC(g->mainbar_label), 0, 0);
gtk_misc_set_padding (GTK_MISC(g->mainbar_label), 2, 2);
gtk_box_pack_start (GTK_BOX (g->mainbar), g->mainbar_label, TRUE, TRUE, 0);
+ g_signal_connect (G_OBJECT (g->mainbar), "key-press-event", G_CALLBACK (key_press_cb), NULL);
return g->mainbar;
}
return window;
}
+static
+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);
+ g_signal_connect (G_OBJECT (plug), "key-press-event", G_CALLBACK (key_press_cb), NULL);
+
+ return plug;
+}
+
+
+static gchar**
+inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) {
+ /*
+ If actname is one that calls an external command, this function will inject
+ newargs in front of the user-provided args in that command line. They will
+ come become after the body of the script (in sh) or after the name of
+ the command to execute (in spawn).
+ i.e. sh <body> <userargs> becomes sh <body> <ARGS> <userargs> and
+ span <command> <userargs> becomes spawn <command> <ARGS> <userargs>.
+
+ The return value consist of two strings: the action (sh, ...) and its args.
+
+ If act is not one that calls an external command, then the given action merely
+ gets duplicated.
+ */
+ GArray *rets = g_array_new(TRUE, FALSE, sizeof(gchar*));
+ gchar *actdup = g_strdup(actname);
+ g_array_append_val(rets, actdup);
+
+ if ((g_strcmp0(actname, "spawn") == 0) ||
+ (g_strcmp0(actname, "sh") == 0) ||
+ (g_strcmp0(actname, "sync_spawn") == 0) ||
+ (g_strcmp0(actname, "sync_sh") == 0)) {
+ guint i;
+ GString *a = g_string_new("");
+ gchar **spawnparts = split_quoted(origargs, FALSE);
+ g_string_append_printf(a, "%s", spawnparts[0]); /* sh body or script name */
+ if (newargs) g_string_append_printf(a, " %s", newargs); /* handler args */
+
+ for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */
+ if (spawnparts[i]) g_string_append_printf(a, " %s", spawnparts[i]);
+
+ g_array_append_val(rets, a->str);
+ g_string_free(a, FALSE);
+ g_strfreev(spawnparts);
+ } else {
+ gchar *origdup = g_strdup(origargs);
+ g_array_append_val(rets, origdup);
+ }
+ return (gchar**)g_array_free(rets, FALSE);
+}
+
static void
run_handler (const gchar *act, const gchar *args) {
+ /* Consider this code a temporary hack to make the handlers usable.
+ In practice, all this splicing, injection, and reconstruction is
+ inefficient, annoying and hard to manage. Potential pitfalls arise
+ when the handler specific args 1) are not quoted (the handler
+ callbacks should take care of this) 2) are quoted but interfere
+ with the users' own quotation. A more ideal solution is
+ to refactor parse_command so that it doesn't just take a string
+ and execute it; rather than that, we should have a function which
+ returns the argument vector parsed from the string. This vector
+ could be modified (e.g. insert additional args into it) before
+ passing it to the next function that actually executes it. Though
+ it still isn't perfect for chain actions.. will reconsider & re-
+ factor when I have the time. -duc */
+
char **parts = g_strsplit(act, " ", 2);
if (!parts) return;
- else if ((g_strcmp0(parts[0], "spawn") == 0)
- || (g_strcmp0(parts[0], "sh") == 0)
- || (g_strcmp0(parts[0], "sync_spawn") == 0)
- || (g_strcmp0(parts[0], "sync_sh") == 0)) {
- guint i;
- GString *a = g_string_new ("");
- char **spawnparts;
- spawnparts = split_quoted(parts[1], FALSE);
- g_string_append_printf(a, "%s", spawnparts[0]);
- if (args) g_string_append_printf(a, " %s", args); /* append handler args before user args */
+ if (g_strcmp0(parts[0], "chain") == 0) {
+ GString *newargs = g_string_new("");
+ gchar **chainparts = split_quoted(parts[1], FALSE);
- for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */
- g_string_append_printf(a, " %s", spawnparts[i]);
- parse_command(parts[0], a->str);
- g_string_free (a, TRUE);
- g_strfreev (spawnparts);
- } else
- parse_command(parts[0], parts[1]);
- g_strfreev (parts);
+ /* for every argument in the chain, inject the handler args
+ and make sure the new parts are wrapped in quotes */
+ gchar **cp = chainparts;
+ gchar quot = '\'';
+ gchar *quotless = NULL;
+ gchar **spliced_quotless = NULL; // sigh -_-;
+ gchar **inpart = NULL;
+
+ while (*cp) {
+ if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */
+ quot = **cp;
+ quotless = g_strndup(&(*cp)[1], strlen(*cp) - 2);
+ } else quotless = g_strdup(*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);
+ cp++;
+ }
+
+ 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);
+ g_free(inparts[0]);
+ g_free(inparts[1]);
+ }
+ g_strfreev(parts);
}
static void
get_xdg_var (XDG_Var xdg) {
const gchar* actual_value = getenv (xdg.environmental);
const gchar* home = getenv ("HOME");
-
- gchar* return_value = str_replace ("~", home, actual_value);
+ gchar* return_value;
if (! actual_value || strcmp (actual_value, "") == 0) {
if (xdg.default_value) {
} else {
return_value = NULL;
}
+ } else {
+ return_value = str_replace("~", home, actual_value);
}
+
return return_value;
}
Network *n = &uzbl.net;
int i;
for (i = 0; default_config[i].command != NULL; i++) {
- parse_cmd_line(default_config[i].command);
+ parse_cmd_line(default_config[i].command, NULL);
}
if (!s->config_file) {
gchar* line;
while ((line = g_array_index(lines, gchar*, i))) {
- parse_cmd_line (line);
+ parse_cmd_line (line, NULL);
i ++;
g_free (line);
}
printf ("No configuration file loaded.\n");
}
- g_signal_connect(n->soup_session, "request-queued", G_CALLBACK(handle_cookies), NULL);
+ g_signal_connect_after(n->soup_session, "request-started", G_CALLBACK(handle_cookies), NULL);
}
static void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data){
(void) session;
(void) user_data;
- if (!uzbl.behave.cookie_handler) return;
+ if (!uzbl.behave.cookie_handler)
+ return;
soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
GString *s = g_string_new ("");
g_string_printf(s, "GET '%s' '%s'", soup_uri->host, soup_uri->path);
run_handler(uzbl.behave.cookie_handler, s->str);
- if(uzbl.comm.sync_stdout)
- soup_message_headers_replace (msg->request_headers, "Cookie", uzbl.comm.sync_stdout);
- //printf("stdout: %s\n", uzbl.comm.sync_stdout); // debugging
- if (uzbl.comm.sync_stdout) uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
+ if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
+ char *p = strchr(uzbl.comm.sync_stdout, '\n' );
+ if ( p != NULL ) *p = '\0';
+ soup_message_headers_replace (msg->request_headers, "Cookie", (const char *) uzbl.comm.sync_stdout);
+ }
+ if (uzbl.comm.sync_stdout)
+ uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
g_string_free(s, TRUE);
}
}
static gboolean
-inspector_dettach_window_cb (WebKitWebInspector* inspector){
+inspector_detach_window_cb (WebKitWebInspector* inspector){
(void) inspector;
return FALSE;
}
g_signal_connect (G_OBJECT (g->inspector), "show-window", G_CALLBACK (inspector_show_window_cb), NULL);
g_signal_connect (G_OBJECT (g->inspector), "close-window", G_CALLBACK (inspector_close_window_cb), NULL);
g_signal_connect (G_OBJECT (g->inspector), "attach-window", G_CALLBACK (inspector_attach_window_cb), NULL);
- g_signal_connect (G_OBJECT (g->inspector), "dettach-window", G_CALLBACK (inspector_dettach_window_cb), NULL);
- g_signal_connect (G_OBJECT (g->inspector), "destroy", G_CALLBACK (inspector_inspector_destroyed_cb), NULL);
+ g_signal_connect (G_OBJECT (g->inspector), "detach-window", G_CALLBACK (inspector_detach_window_cb), NULL);
+ g_signal_connect (G_OBJECT (g->inspector), "finished", G_CALLBACK (inspector_inspector_destroyed_cb), NULL);
g_signal_connect (G_OBJECT (g->inspector), "notify::inspected-uri", G_CALLBACK (inspector_uri_changed_cb), 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;
+
/* initialize hash table */
uzbl.bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
uzbl.behave.insert_indicator = g_strdup("I");
uzbl.behave.cmd_indicator = g_strdup("C");
- setup_regex();
setup_scanner();
commands_hash ();
make_var_to_name_hash();
gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.scrolled_win, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.mainbar, FALSE, TRUE, 0);
- uzbl.gui.main_window = create_window ();
- gtk_container_add (GTK_CONTAINER (uzbl.gui.main_window), uzbl.gui.vbox);
-
+ if (uzbl.state.socket_id) {
+ uzbl.gui.plug = create_plug ();
+ gtk_container_add (GTK_CONTAINER (uzbl.gui.plug), uzbl.gui.vbox);
+ gtk_widget_show_all (GTK_WIDGET (uzbl.gui.plug));
+ } else {
+ uzbl.gui.main_window = create_window ();
+ gtk_container_add (GTK_CONTAINER (uzbl.gui.main_window), uzbl.gui.vbox);
+ gtk_widget_show_all (uzbl.gui.main_window);
+ uzbl.xwin = GDK_WINDOW_XID (GTK_WIDGET (uzbl.gui.main_window)->window);
+ }
gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view));
- gtk_widget_show_all (uzbl.gui.main_window);
- uzbl.xwin = GDK_WINDOW_XID (GTK_WIDGET (uzbl.gui.main_window)->window);
if (uzbl.state.verbose) {
printf("Uzbl start location: %s\n", argv[0]);
- printf("window_id %i\n",(int) uzbl.xwin);
+ if (uzbl.state.socket_id)
+ printf("plug_id %i\n", gtk_plug_get_id(uzbl.gui.plug));
+ else
+ printf("window_id %i\n",(int) uzbl.xwin);
printf("pid %i\n", getpid ());
printf("name: %s\n", uzbl.state.instance_name);
}
create_stdin();
- if(uzbl.state.uri) {
- GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
- g_array_append_val(a, uzbl.state.uri);
- load_uri (uzbl.gui.web_view, a);
- g_array_free (a, TRUE);
- }
+ if (verbose_override > uzbl.state.verbose)
+ uzbl.state.verbose = verbose_override;
+
+ if (uri_override) {
+ set_var_value("uri", uri_override);
+ g_free(uri_override);
+ } else if (uzbl.state.uri)
+ cmd_load_uri(uzbl.gui.web_view, NULL);
gtk_main ();
clean_up();