#include <sys/time.h>
#include <webkit/webkit.h>
#include <libsoup/soup.h>
+#include <JavaScriptCore/JavaScript.h>
#include <stdio.h>
#include <string.h>
#include "config.h"
static Uzbl uzbl;
-typedef void (*Command)(WebKitWebView*, GArray *argv);
}
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_zoom_type (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) {
+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);
/* 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 */
-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} },
{ "zoom_in", {view_zoom_in, 0}, }, //Can crash (when max zoom reached?).
{ "zoom_out", {view_zoom_out, 0}, },
{ "toggle_zoom_type", {toggle_zoom_type, 0}, },
- { "uri", {load_uri, NOSPLIT} },
- { "js", {run_js, NOSPLIT} },
+ { "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} },
- { "set", {set_var, NOSPLIT} },
- //{ "get", {get_var, NOSPLIT} },
- { "bind", {act_bind, NOSPLIT} },
+ { "set", {set_var, TRUE} },
+ //{ "get", {get_var, TRUE} },
+ { "bind", {act_bind, TRUE} },
{ "dump_config", {act_dump_config, 0} },
- { "keycmd", {keycmd, NOSPLIT} },
- { "keycmd_nl", {keycmd_nl, NOSPLIT} },
+ { "keycmd", {keycmd, TRUE} },
+ { "keycmd_nl", {keycmd_nl, TRUE} },
{ "keycmd_bs", {keycmd_bs, 0} },
{ "chain", {chain, 0} },
- { "print", {print, NOSPLIT} }
+ { "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;
+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);
}
static void
-print(WebKitWebView *page, GArray *argv) {
- (void) page;
+print(WebKitWebView *page, GArray *argv, GString *result) {
+ (void) page; (void) result;
gchar* buf;
buf = expand_vars(argv_idx(argv, 0));
- puts(buf);
+ g_string_assign(result, buf);
g_free(buf);
}
static void
-act_bind(WebKitWebView *page, GArray *argv) {
- (void) page;
+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);
}
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_strstr_len (argv_idx(argv, 0), 11, "javascript:") != NULL) {
- run_js(web_view, argv);
+ 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)
}
}
+
+/* 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
-chain (WebKitWebView *page, GArray *argv) {
- (void)page;
+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]);
+ parse_command(parts[0], parts[1], result);
g_strfreev (parts);
}
}
static void
-keycmd (WebKitWebView *page, GArray *argv) {
+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) {
+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) {
+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);
}
static void
-close_uzbl (WebKitWebView *page, GArray *argv) {
+close_uzbl (WebKitWebView *page, GArray *argv, GString *result) {
(void)page;
(void)argv;
+ (void)result;
gtk_main_quit ();
}
}
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);
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);
}
enum {M_CMD, M_HTML};
static void
-parse_cmd_line(const char *ctl_line) {
+parse_cmd_line(const char *ctl_line, GString *result) {
Behaviour *b = &uzbl.behave;
size_t len=0;
else ctlstrip = g_strdup(ctl_line);
tokens = g_strsplit(ctlstrip, " ", 2);
- parse_command(tokens[0], tokens[1]);
+ parse_command(tokens[0], tokens[1], result);
g_free(ctlstrip);
g_strfreev(tokens);
}
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);
+ unsigned int t = sizeof(remote);
+ int clientsock;
+ GIOChannel *clientchan;
- memset (buffer, 0, sizeof (buffer));
-
- 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 (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;
}
}
if (event->keyval == GDK_BackSpace)
- keycmd_bs(NULL, NULL);
+ 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);
cp++;
}
- parse_command(parts[0], &(newargs->str[1]));
+ 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]);
+ parse_command(inparts[0], inparts[1], NULL);
g_free(inparts[0]);
g_free(inparts[1]);
}
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 (g_strcmp0(s->config_file, "-") == 0) {
+ s->config_file = NULL;
+ create_stdin();
}
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);
}
/* WebInspector */
set_up_inspector();
-
- create_stdin();
-
+
if (verbose_override > uzbl.state.verbose)
uzbl.state.verbose = verbose_override;
*
*/
-#define NOSPLIT ((void*)1)
-
enum {
/* statusbar symbols */
SYM_TITLE, SYM_URI, SYM_NAME,
GHashTable* commands;
} Behaviour;
+/* javascript */
+typedef struct {
+ gboolean initialized;
+ JSClassDefinition classdef;
+ JSClassRef classref;
+} Javascript;
/* main uzbl data structure */
typedef struct {
Network net;
Behaviour behave;
Communication comm;
+ Javascript js;
Window xwin;
GScanner *scan;
{ "XDG_DATA_DIRS", "/usr/local/share/:/usr/share/" },
};
+
/* Functions */
static void
setup_scanner();
static gboolean
set_var_value(gchar *name, gchar *val);
-static void
-print(WebKitWebView *page, GArray *argv);
-
static gboolean
new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, WebKitWebPolicyDecision *policy_decision, gpointer user_data);
download_cb (WebKitWebView *web_view, GObject *download, gpointer user_data);
static void
-toggle_zoom_type (WebKitWebView* page, GArray *argv);
-
-static void
-toggle_status_cb (WebKitWebView* page, GArray *argv);
-
-static void
link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data);
static void
file_exists (const char * filename);
static void
-toggle_insert_mode(WebKitWebView *page, GArray *argv);
-
-static void
-load_uri (WebKitWebView * web_view, GArray *argv);
-
-static void
new_window_load_uri (const gchar * uri);
-static void
-chain (WebKitWebView *page, GArray *argv);
-
-static void
-keycmd (WebKitWebView *page, GArray *argv);
-
-static void
-keycmd_nl (WebKitWebView *page, GArray *argv);
-
-static void
-keycmd_bs (WebKitWebView *page, GArray *argv);
-
-static void
-close_uzbl (WebKitWebView *page, GArray *argv);
-
static gboolean
run_command(const gchar *command, const guint npre,
const gchar **args, const gboolean sync, char **output_stdout);
static void
-spawn(WebKitWebView *web_view, GArray *argv);
+parse_command(const char *cmd, const char *param, GString *result);
static void
-spawn_sh(WebKitWebView *web_view, GArray *argv);
-
-static void
-spawn_sync(WebKitWebView *web_view, GArray *argv);
-
-static void
-spawn_sh_sync(WebKitWebView *web_view, GArray *argv);
-
-static void
-parse_command(const char *cmd, const char *param);
-
-static void
-parse_cmd_line(const char *ctl_line);
+parse_cmd_line(const char *ctl_line, GString *result);
static gchar*
build_stream_name(int type, const gchar *dir);
static gboolean
control_socket(GIOChannel *chan);
+static gboolean
+control_client_socket(GIOChannel *chan);
+
static void
update_title (void);
static void
search_text (WebKitWebView *page, GArray *argv, const gboolean forward);
+static void handle_cookies (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data);
static void
-search_forward_text (WebKitWebView *page, GArray *argv);
+save_cookies (SoupMessage *msg,
+ gpointer user_data);
static void
-search_reverse_text (WebKitWebView *page, GArray *argv);
+act_dump_config();
static void
-dehilight (WebKitWebView *page, GArray *argv);
+render_html();
static void
-run_js (WebKitWebView * web_view, GArray *argv);
+set_timeout(int seconds);
static void
-run_external_js (WebKitWebView * web_view, GArray *argv);
+dump_var_hash(gpointer k, gpointer v, gpointer ud);
-static void handle_cookies (SoupSession *session,
- SoupMessage *msg,
- gpointer user_data);
static void
-save_cookies (SoupMessage *msg,
- gpointer user_data);
+dump_key_hash(gpointer k, gpointer v, gpointer ud);
static void
-set_var(WebKitWebView *page, GArray *argv);
+dump_config();
+
+
+/* Commands */
+
+typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result);
+typedef struct {
+ Command function;
+ gboolean no_split;
+} CommandInfo;
static void
-act_bind(WebKitWebView *page, GArray *argv);
+print(WebKitWebView *page, GArray *argv, GString *result);
static void
-act_dump_config();
+toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result);
static void
-render_html();
+toggle_status_cb (WebKitWebView* page, GArray *argv, GString *result);
static void
-set_timeout(int seconds);
+toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result);
static void
-dump_var_hash(gpointer k, gpointer v, gpointer ud);
+load_uri (WebKitWebView * web_view, GArray *argv, GString *result);
static void
-dump_key_hash(gpointer k, gpointer v, gpointer ud);
+chain (WebKitWebView *page, GArray *argv, GString *result);
static void
-dump_config();
+keycmd (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+keycmd_nl (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+keycmd_bs (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+close_uzbl (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+spawn(WebKitWebView *web_view, GArray *argv, GString *result);
+
+static void
+spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result);
+
+static void
+spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result);
+
+static void
+spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result);
+
+static void
+search_forward_text (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+search_reverse_text (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+dehilight (WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+eval_js(WebKitWebView * web_view, gchar *script, GString *result);
+
+static void
+run_js (WebKitWebView * web_view, GArray *argv, GString *result);
+
+static void
+run_external_js (WebKitWebView * web_view, GArray *argv, GString *result);
+
+static void
+set_var(WebKitWebView *page, GArray *argv, GString *result);
+
+static void
+act_bind(WebKitWebView *page, GArray *argv, GString *result);
/* Command callbacks */