#include "uzbl.h"
#include "config.h"
-static Uzbl uzbl;
-
-
+Uzbl uzbl;
- typedef void (*Command)(WebKitWebView*, GArray *argv);
-
-
/* commandline arguments (set initial values for the state variables) */
-static const
+const
GOptionEntry entries[] =
{
{ "uri", 'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri,
}
/* --- UTILITY FUNCTIONS --- */
- gchar *
- expand_vars(char *s) {
-
+ 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 ret[256], *vend;
+ 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) {
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);
+ 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(upto == ' ') s = vend;
- else s = vend+1;
- upto = ' ';
+ 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++;
}
/* scroll a bar in a given direction */
-static void
+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);
- 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);
+ if (*end == '%')
+ value += page_size * amount * 0.01;
+ else
+ value += 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
+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));
}
update_title();
}
+ static void
+ 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
+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);
{ "sh", {spawn_sh, 0} },
{ "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler
{ "exit", {close_uzbl, 0} },
+ { "quit", {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
+void
commands_hash(void)
{
unsigned int i;
}
}
- void
- run_js (WebKitWebView * web_view, GArray *argv) {
-
+ /* 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, 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);
}
- void
- run_external_js (WebKitWebView * web_view, GArray *argv) {
+ static void
+ 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;
return;
}
-static void
+void
set_icon() {
if(file_exists(uzbl.gui.icon)) {
- gtk_window_set_icon_from_file (GTK_WINDOW (uzbl.gui.main_window), uzbl.gui.icon, NULL);
+ 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);
}
}
}
-static gchar*
+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) {
if (error) g_error_free (error);
}
-static gboolean
+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;
}
char *
itos(int val);
-static char *
+char *
str_replace (const char* search, const char* replace, const char* string);
-static GArray*
+GArray*
read_file_by_line (gchar *path);
-static
-gchar* parseenv (char* string);
+gchar*
+parseenv (char* string);
-static void
+void
clean_up(void);
-static void
+void
catch_sigterm(int s);
-static sigfunc *
+sigfunc *
setup_signal(int signe, sigfunc *shandler);
-static gboolean
+gboolean
set_var_value(gchar *name, gchar *val);
- void
- print(WebKitWebView *page, GArray *argv);
+ static void
+ print(WebKitWebView *page, GArray *argv, GString *result);
-static gboolean
+gboolean
new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, WebKitWebPolicyDecision *policy_decision, gpointer user_data);
-static gboolean
+gboolean
mime_policy_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, gchar *mime_type, WebKitWebPolicyDecision *policy_decision, gpointer user_data);
WebKitWebView*
create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data);
-static gboolean
+gboolean
download_cb (WebKitWebView *web_view, GObject *download, gpointer user_data);
- void
- toggle_status_cb (WebKitWebView* page, GArray *argv);
+ static void
+ toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result);
+
+ static void
+ toggle_status_cb (WebKitWebView* page, GArray *argv, GString *result);
-static void
+void
link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data);
-static void
+void
title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data);
-static void
+void
progress_change_cb (WebKitWebView* page, gint progress, gpointer data);
-static void
+void
load_commit_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data);
-static void
+void
load_start_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data);
-static void
+void
load_finish_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data);
-static void
+void
destroy_cb (GtkWidget* widget, gpointer data);
-static void
+void
log_history_cb ();
-static void
+void
commands_hash(void);
void
Action*
new_action(const gchar *name, const gchar *param);
-static bool
+bool
file_exists (const char * filename);
- void
- toggle_insert_mode(WebKitWebView *page, GArray *argv);
+ static void
+ toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result);
- void
- load_uri (WebKitWebView * web_view, GArray *argv);
+ static void
+ load_uri (WebKitWebView * web_view, GArray *argv, GString *result);
-static void
+void
new_window_load_uri (const gchar * uri);
- void
- chain (WebKitWebView *page, GArray *argv);
+ static void
+ chain (WebKitWebView *page, GArray *argv, GString *result);
- void
- keycmd (WebKitWebView *page, GArray *argv);
+ static void
+ keycmd (WebKitWebView *page, GArray *argv, GString *result);
- void
- keycmd_nl (WebKitWebView *page, GArray *argv);
+ static void
+ keycmd_nl (WebKitWebView *page, GArray *argv, GString *result);
- void
- keycmd_bs (WebKitWebView *page, GArray *argv);
+ static void
+ keycmd_bs (WebKitWebView *page, GArray *argv, GString *result);
- void
- close_uzbl (WebKitWebView *page, GArray *argv);
+ static void
+ close_uzbl (WebKitWebView *page, GArray *argv, GString *result);
-static gboolean
+gboolean
run_command(const gchar *command, const guint npre,
const gchar **args, const gboolean sync, char **output_stdout);
- void
- spawn(WebKitWebView *web_view, GArray *argv);
+ static void
+ spawn(WebKitWebView *web_view, GArray *argv, GString *result);
- void
- spawn_sh(WebKitWebView *web_view, GArray *argv);
+ static void
+ spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result);
- void
- spawn_sync(WebKitWebView *web_view, GArray *argv);
+ static void
+ spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result);
- void
- spawn_sh_sync(WebKitWebView *web_view, GArray *argv);
+ static void
+ spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result);
- void
- parse_command(const char *cmd, const char *param);
+ static void
+ parse_command(const char *cmd, const char *param, GString *result);
- void
- parse_cmd_line(const char *ctl_line);
+ static void
+ parse_cmd_line(const char *ctl_line, GString *result);
-static gchar*
+gchar*
build_stream_name(int type, const gchar *dir);
-static gboolean
+gboolean
control_fifo(GIOChannel *gio, GIOCondition condition);
-static gchar*
+gchar*
init_fifo(gchar *dir);
-static gboolean
+gboolean
control_stdin(GIOChannel *gio, GIOCondition condition);
-static void
+void
create_stdin();
-static gchar*
+gchar*
init_socket(gchar *dir);
-static gboolean
+gboolean
control_socket(GIOChannel *chan);
- void
+ static gboolean
+ control_client_socket(GIOChannel *chan);
+
+ static void
update_title (void);
-static gboolean
+gboolean
key_press_cb (GtkWidget* window, GdkEventKey* event);
-static void
+void
run_keycmd(const gboolean key_ret);
-static void
+void
exec_paramcmd(const Action* act, const guint i);
-static GtkWidget*
+GtkWidget*
create_browser ();
-static GtkWidget*
+GtkWidget*
create_mainbar ();
-static
-GtkWidget* create_window ();
+GtkWidget*
+create_window ();
- void
+ static
+ GtkPlug* create_plug ();
+
+ static void
run_handler (const gchar *act, const gchar *args);
-static void
+void
add_binding (const gchar *key, const gchar *act);
-static gchar*
+gchar*
get_xdg_var (XDG_Var xdg);
-static gchar*
+gchar*
find_xdg_file (int xdg_type, char* filename);
-static void
+void
settings_init ();
-static void
+void
search_text (WebKitWebView *page, GArray *argv, const gboolean forward);
- void
- search_forward_text (WebKitWebView *page, GArray *argv);
+ static void
+ search_forward_text (WebKitWebView *page, GArray *argv, GString *result);
- void
- search_reverse_text (WebKitWebView *page, GArray *argv);
+ static void
+ search_reverse_text (WebKitWebView *page, GArray *argv, GString *result);
- void
- dehilight (WebKitWebView *page, GArray *argv);
+ static void
+ dehilight (WebKitWebView *page, GArray *argv, GString *result);
- void
- run_js (WebKitWebView * web_view, GArray *argv);
+ static void
+ run_js (WebKitWebView * web_view, GArray *argv, GString *result);
- void
- run_external_js (WebKitWebView * web_view, GArray *argv);
+ static void
+ run_external_js (WebKitWebView * web_view, GArray *argv, GString *result);
+
+ static void
+ eval_js(WebKitWebView * web_view, gchar *script, GString *result);
-static void handle_cookies (SoupSession *session,
+void handle_cookies (SoupSession *session,
SoupMessage *msg,
gpointer user_data);
-static void
+void
save_cookies (SoupMessage *msg,
gpointer user_data);
- void
- set_var(WebKitWebView *page, GArray *argv);
+ static void
+ set_var(WebKitWebView *page, GArray *argv, GString *result);
- void
- act_bind(WebKitWebView *page, GArray *argv);
+ static void
+ act_bind(WebKitWebView *page, GArray *argv, GString *result);
-static void
+void
act_dump_config();
-static void
+void
render_html();
-static void
+void
set_timeout(int seconds);
-static void
+void
dump_var_hash(gpointer k, gpointer v, gpointer ud);
-static void
+void
dump_key_hash(gpointer k, gpointer v, gpointer ud);
-static void
+void
dump_config();
-
+ typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result);
+ typedef struct {
+ Command function;
+ gboolean no_split;
+ } CommandInfo;
/* Command callbacks */
-static void
+void
cmd_load_uri();
-static void
+void
cmd_set_status();
-static void
+void
set_proxy_url();
-static void
+void
set_icon();
-static void
+void
cmd_cookie_handler();
-static void
+void
move_statusbar();
-static void
+void
cmd_always_insert_mode();
-static void
+void
cmd_http_debug();
-static void
+void
cmd_max_conns();
-static void
+void
cmd_max_conns_host();
/* exported WebKitWebSettings properties */