diff options
author | keis <keijser@gmail.com> | 2011-07-28 22:31:30 +0200 |
---|---|---|
committer | keis <keijser@gmail.com> | 2011-07-28 22:31:30 +0200 |
commit | db61f092140205e71f40fb14dc98a1e650c7e527 (patch) | |
tree | 6a2459ae08c6baa4875b1db226dc7eb615a3cd3c /src | |
parent | 1e20430333aee952f55f6caec4d55238a0160bf9 (diff) | |
parent | e035f6f991fdbe9862a72fba6e8d348dcc25532f (diff) |
Merge branch 'experimental' of git://github.com/Dieterbe/uzbl into mouse-events
Diffstat (limited to 'src')
-rw-r--r-- | src/callbacks.c | 520 | ||||
-rw-r--r-- | src/callbacks.h | 159 | ||||
-rw-r--r-- | src/commands.c | 452 | ||||
-rw-r--r-- | src/commands.h | 68 | ||||
-rw-r--r-- | src/cookie-jar.c | 3 | ||||
-rw-r--r-- | src/events.c | 9 | ||||
-rw-r--r-- | src/events.h | 1 | ||||
-rw-r--r-- | src/inspector.c | 4 | ||||
-rw-r--r-- | src/io.c | 1 | ||||
-rw-r--r-- | src/menu.h | 8 | ||||
-rw-r--r-- | src/status-bar.c | 117 | ||||
-rw-r--r-- | src/status-bar.h | 36 | ||||
-rw-r--r-- | src/type.h | 24 | ||||
-rw-r--r-- | src/util.c | 2 | ||||
-rw-r--r-- | src/uzbl-core.c | 961 | ||||
-rw-r--r-- | src/uzbl-core.h | 115 | ||||
-rw-r--r-- | src/variables.c | 618 | ||||
-rw-r--r-- | src/variables.h | 21 |
18 files changed, 1551 insertions, 1568 deletions
diff --git a/src/callbacks.c b/src/callbacks.c index 3f7e27d..446e868 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -6,429 +6,30 @@ #include "uzbl-core.h" #include "callbacks.h" #include "events.h" -#include "util.h" -#include "io.h" - - -void -set_proxy_url() { - SoupURI *suri; - - if (uzbl.net.proxy_url == NULL || *uzbl.net.proxy_url == ' ') { - soup_session_remove_feature_by_type(uzbl.net.soup_session, - (GType) SOUP_SESSION_PROXY_URI); - } - else { - suri = soup_uri_new(uzbl.net.proxy_url); - g_object_set(G_OBJECT(uzbl.net.soup_session), - SOUP_SESSION_PROXY_URI, - suri, NULL); - soup_uri_free(suri); - } - - return; -} - - -void -set_authentication_handler() { - /* Check if WEBKIT_TYPE_SOUP_AUTH_DIALOG feature is set */ - GSList *flist = soup_session_get_features (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); - guint feature_is_set = g_slist_length(flist); - g_slist_free(flist); - - if (uzbl.behave.authentication_handler == NULL || *uzbl.behave.authentication_handler == 0) { - if (!feature_is_set) - soup_session_add_feature_by_type - (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); - } else { - if (feature_is_set) - soup_session_remove_feature_by_type - (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); - } - return; -} - - -void -set_status_background() { - /* labels and hboxes do not draw their own background. applying this - * on the vbox/main_window is ok as the statusbar is the only affected - * widget. (if not, we could also use GtkEventBox) */ - GtkWidget* widget = uzbl.gui.main_window ? uzbl.gui.main_window : GTK_WIDGET (uzbl.gui.plug); - -#if GTK_CHECK_VERSION(2,91,0) - GdkRGBA color; - gdk_rgba_parse (&color, uzbl.behave.status_background); - gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &color); -#else - GdkColor color; - gdk_color_parse (uzbl.behave.status_background, &color); - gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color); -#endif -} - - -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); - } -} - -void -cmd_set_geometry() { - int ret=0, x=0, y=0; - unsigned int w=0, h=0; - if(uzbl.gui.geometry) { - if(uzbl.gui.geometry[0] == 'm') { /* m/maximize/maximized */ - gtk_window_maximize((GtkWindow *)(uzbl.gui.main_window)); - } else { - /* we used to use gtk_window_parse_geometry() but that didn't work how it was supposed to */ - ret = XParseGeometry(uzbl.gui.geometry, &x, &y, &w, &h); - if(ret & XValue) - gtk_window_move((GtkWindow *)uzbl.gui.main_window, x, y); - if(ret & WidthValue) - gtk_window_resize((GtkWindow *)uzbl.gui.main_window, w, h); - } - } - - /* update geometry var with the actual geometry - this is necessary as some WMs don't seem to honour - the above setting and we don't want to end up with - wrong geometry information - */ - retrieve_geometry(); -} - -void -cmd_set_status() { - if (!uzbl.behave.show_status) { - gtk_widget_hide(uzbl.gui.mainbar); - } else { - gtk_widget_show(uzbl.gui.mainbar); - } - update_title(); -} - -void -cmd_load_uri() { - load_uri_imp (uzbl.state.uri); -} - -void -cmd_max_conns() { - g_object_set(G_OBJECT(uzbl.net.soup_session), - SOUP_SESSION_MAX_CONNS, uzbl.net.max_conns, NULL); -} - -void -cmd_max_conns_host() { - g_object_set(G_OBJECT(uzbl.net.soup_session), - SOUP_SESSION_MAX_CONNS_PER_HOST, uzbl.net.max_conns_host, NULL); -} - -void -cmd_http_debug() { - 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? */ - /*g_free(uzbl.net.soup_logger);*/ - - uzbl.net.soup_logger = soup_logger_new(uzbl.behave.http_debug, -1); - soup_session_add_feature(uzbl.net.soup_session, - SOUP_SESSION_FEATURE(uzbl.net.soup_logger)); -} - -WebKitWebSettings* -view_settings() { - return webkit_web_view_get_settings(uzbl.gui.web_view); -} - -void -cmd_font_size() { - WebKitWebSettings *ws = view_settings(); - if (uzbl.behave.font_size > 0) { - g_object_set (G_OBJECT(ws), "default-font-size", uzbl.behave.font_size, NULL); - } - - if (uzbl.behave.monospace_size > 0) { - g_object_set (G_OBJECT(ws), "default-monospace-font-size", - uzbl.behave.monospace_size, NULL); - } else { - g_object_set (G_OBJECT(ws), "default-monospace-font-size", - uzbl.behave.font_size, NULL); - } -} - -void -cmd_default_font_family() { - g_object_set (G_OBJECT(view_settings()), "default-font-family", - uzbl.behave.default_font_family, NULL); -} - -void -cmd_monospace_font_family() { - g_object_set (G_OBJECT(view_settings()), "monospace-font-family", - uzbl.behave.monospace_font_family, NULL); -} - -void -cmd_sans_serif_font_family() { - g_object_set (G_OBJECT(view_settings()), "sans_serif-font-family", - uzbl.behave.sans_serif_font_family, NULL); -} - -void -cmd_serif_font_family() { - g_object_set (G_OBJECT(view_settings()), "serif-font-family", - uzbl.behave.serif_font_family, NULL); -} - -void -cmd_cursive_font_family() { - g_object_set (G_OBJECT(view_settings()), "cursive-font-family", - uzbl.behave.cursive_font_family, NULL); -} - -void -cmd_fantasy_font_family() { - g_object_set (G_OBJECT(view_settings()), "fantasy-font-family", - uzbl.behave.fantasy_font_family, NULL); -} - -void -cmd_zoom_level() { - webkit_web_view_set_zoom_level (uzbl.gui.web_view, uzbl.behave.zoom_level); -} - -void -cmd_enable_pagecache() { - g_object_set (G_OBJECT(view_settings()), "enable-page-cache", - uzbl.behave.enable_pagecache, NULL); -} - -void -cmd_disable_plugins() { - g_object_set (G_OBJECT(view_settings()), "enable-plugins", - !uzbl.behave.disable_plugins, NULL); -} - -void -cmd_disable_scripts() { - g_object_set (G_OBJECT(view_settings()), "enable-scripts", - !uzbl.behave.disable_scripts, NULL); -} - -void -cmd_minimum_font_size() { - g_object_set (G_OBJECT(view_settings()), "minimum-font-size", - uzbl.behave.minimum_font_size, NULL); -} -void -cmd_autoload_img() { - g_object_set (G_OBJECT(view_settings()), "auto-load-images", - uzbl.behave.autoload_img, NULL); -} - - -void -cmd_autoshrink_img() { - g_object_set (G_OBJECT(view_settings()), "auto-shrink-images", - uzbl.behave.autoshrink_img, NULL); -} - - -void -cmd_enable_spellcheck() { - g_object_set (G_OBJECT(view_settings()), "enable-spell-checking", - uzbl.behave.enable_spellcheck, NULL); -} - -void -cmd_enable_private() { - g_object_set (G_OBJECT(view_settings()), "enable-private-browsing", - uzbl.behave.enable_private, NULL); -} - -void -cmd_print_bg() { - g_object_set (G_OBJECT(view_settings()), "print-backgrounds", - uzbl.behave.print_bg, NULL); -} - -void -cmd_style_uri() { - g_object_set (G_OBJECT(view_settings()), "user-stylesheet-uri", - uzbl.behave.style_uri, NULL); -} - -void -cmd_resizable_txt() { - g_object_set (G_OBJECT(view_settings()), "resizable-text-areas", - uzbl.behave.resizable_txt, NULL); -} +#include "menu.h" +#include "type.h" void -cmd_default_encoding() { - g_object_set (G_OBJECT(view_settings()), "default-encoding", - uzbl.behave.default_encoding, NULL); -} - -void -cmd_enforce_96dpi() { - g_object_set (G_OBJECT(view_settings()), "enforce-96-dpi", - uzbl.behave.enforce_96dpi, NULL); -} - -void -cmd_caret_browsing() { - g_object_set (G_OBJECT(view_settings()), "enable-caret-browsing", - uzbl.behave.caret_browsing, NULL); -} - -void -set_current_encoding() { - gchar *encoding = uzbl.behave.current_encoding; - if(strlen(encoding) == 0) - encoding = NULL; - - webkit_web_view_set_custom_encoding(uzbl.gui.web_view, encoding); -} - - -void -cmd_fifo_dir() { - uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir); -} - -void -cmd_socket_dir() { - uzbl.behave.socket_dir = init_socket(uzbl.behave.socket_dir); -} - -void -cmd_inject_html() { - if(uzbl.behave.inject_html) { - webkit_web_view_load_html_string (uzbl.gui.web_view, - uzbl.behave.inject_html, NULL); - } -} - -void -cmd_useragent() { - if (*uzbl.net.useragent == ' ') { - g_free (uzbl.net.useragent); - uzbl.net.useragent = NULL; - } else { - g_object_set(G_OBJECT(uzbl.net.soup_session), SOUP_SESSION_USER_AGENT, - uzbl.net.useragent, NULL); - } -} - -void -set_accept_languages() { - if (*uzbl.net.accept_languages == ' ') { - g_free (uzbl.net.accept_languages); - uzbl.net.accept_languages = NULL; - } else { - g_object_set(G_OBJECT(uzbl.net.soup_session), - SOUP_SESSION_ACCEPT_LANGUAGE, uzbl.net.accept_languages, NULL); - } -} - -void -cmd_javascript_windows() { - g_object_set (G_OBJECT(view_settings()), "javascript-can-open-windows-automatically", - uzbl.behave.javascript_windows, NULL); -} - -void -cmd_scrollbars_visibility() { - if(uzbl.gui.scrollbars_visible) { - uzbl.gui.bar_h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); - uzbl.gui.bar_v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); - } - else { - uzbl.gui.bar_v = gtk_range_get_adjustment (GTK_RANGE (uzbl.gui.scbar_v)); - uzbl.gui.bar_h = gtk_range_get_adjustment (GTK_RANGE (uzbl.gui.scbar_h)); - } - - set_webview_scroll_adjustments(); -} - -/* requires webkit >=1.1.14 */ -void -cmd_view_source() { - webkit_web_view_set_view_source_mode(uzbl.gui.web_view, - (gboolean) uzbl.behave.view_source); -} - -void -cmd_set_zoom_type () { - if(uzbl.behave.zoom_type) - webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, TRUE); - else - webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, FALSE); -} - -void -toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) { - (void)argv; - (void)result; - - webkit_web_view_set_full_content_zoom (page, !webkit_web_view_get_full_content_zoom (page)); -} - -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); - } else { - gtk_widget_show(uzbl.gui.mainbar); - } - uzbl.behave.show_status = !uzbl.behave.show_status; - update_title(); -} - -void -link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data) { - (void) page; - (void) title; - (void) data; +link_hover_cb (WebKitWebView *page, const gchar *title, const gchar *link, gpointer data) { + (void) page; (void) title; (void) data; State *s = &uzbl.state; + if(s->last_selected_url) + g_free(s->last_selected_url); + if(s->selected_url) { - if(s->last_selected_url) - g_free(s->last_selected_url); s->last_selected_url = g_strdup(s->selected_url); - } - else { - if(s->last_selected_url) g_free(s->last_selected_url); + g_free(s->selected_url); + s->selected_url = NULL; + } else s->last_selected_url = NULL; - } - g_free(s->selected_url); - s->selected_url = NULL; + if(s->last_selected_url && g_strcmp0(link, s->last_selected_url)) + send_event(LINK_UNHOVER, NULL, TYPE_STR, s->last_selected_url, NULL); if (link) { s->selected_url = g_strdup(link); - - if(s->last_selected_url && - g_strcmp0(s->selected_url, s->last_selected_url)) - send_event(LINK_UNHOVER, NULL, TYPE_STR, s->last_selected_url, NULL); - - send_event(LINK_HOVER, NULL, TYPE_STR, s->selected_url, NULL); - } - else if(s->last_selected_url) { - send_event(LINK_UNHOVER, NULL, TYPE_STR, s->last_selected_url, NULL); + send_event(LINK_HOVER, NULL, TYPE_STR, s->selected_url, NULL); } update_title(); @@ -478,7 +79,7 @@ load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { } } -void +gboolean load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud) { (void) page; (void) frame; (void) ud; GError *err = web_err; @@ -488,15 +89,8 @@ load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer TYPE_INT, err->code, TYPE_STR, err->message, NULL); -} - -void -uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec) { - (void) param_spec; - g_free (uzbl.state.uri); - g_object_get (web_view, "uri", &uzbl.state.uri, NULL); - g_setenv("UZBL_URI", uzbl.state.uri, TRUE); + return FALSE; } void @@ -767,10 +361,11 @@ request_starting_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitWebRes } void -create_web_view_js2_cb (WebKitWebView* web_view, GParamSpec param_spec) { +create_web_view_js_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) web_view; (void) param_spec; + webkit_web_view_stop_loading(web_view); const gchar* uri = webkit_web_view_get_uri(web_view); if (strncmp(uri, "javascript:", strlen("javascript:")) == 0) { @@ -781,18 +376,6 @@ create_web_view_js2_cb (WebKitWebView* web_view, GParamSpec param_spec) { send_event(NEW_WINDOW, NULL, TYPE_STR, uri, NULL); } - -gboolean -create_web_view_js_cb (WebKitWebView* web_view, gpointer user_data) { - (void) web_view; - (void) user_data; - - g_object_connect (web_view, "signal::notify::uri", - G_CALLBACK(create_web_view_js2_cb), NULL, NULL); - return TRUE; -} - - /*@null@*/ WebKitWebView* create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data) { (void) web_view; @@ -804,8 +387,8 @@ create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer us WebKitWebView* new_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); - g_signal_connect (new_view, "web-view-ready", - G_CALLBACK(create_web_view_js_cb), NULL); + g_object_connect (new_view, "signal::notify::uri", + G_CALLBACK(create_web_view_js_cb), NULL, NULL); return new_view; } @@ -953,43 +536,32 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat return TRUE; } -gboolean -scroll_vert_cb(GtkAdjustment *adjust, void *w) -{ - (void) w; - +void +send_scroll_event(int type, GtkAdjustment *adjust) { gdouble value = gtk_adjustment_get_value(adjust); gdouble min = gtk_adjustment_get_lower(adjust); gdouble max = gtk_adjustment_get_upper(adjust); gdouble page = gtk_adjustment_get_page_size(adjust); - send_event (SCROLL_VERT, NULL, + send_event (type, NULL, TYPE_FLOAT, value, TYPE_FLOAT, min, TYPE_FLOAT, max, TYPE_FLOAT, page, NULL); +} +gboolean +scroll_vert_cb(GtkAdjustment *adjust, void *w) { + (void) w; + send_scroll_event(SCROLL_VERT, adjust); return (FALSE); } gboolean -scroll_horiz_cb(GtkAdjustment *adjust, void *w) -{ +scroll_horiz_cb(GtkAdjustment *adjust, void *w) { (void) w; - - gdouble value = gtk_adjustment_get_value(adjust); - gdouble min = gtk_adjustment_get_lower(adjust); - gdouble max = gtk_adjustment_get_upper(adjust); - gdouble page = gtk_adjustment_get_page_size(adjust); - - send_event (SCROLL_HORIZ, NULL, - TYPE_FLOAT, value, - TYPE_FLOAT, min, - TYPE_FLOAT, max, - TYPE_FLOAT, page, - NULL); - + send_scroll_event(SCROLL_HORIZ, adjust); return (FALSE); } @@ -1079,4 +651,38 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } +void +window_object_cleared_cb(WebKitWebView *webview, WebKitWebFrame *frame, + JSGlobalContextRef *context, JSObjectRef *object) { + (void) frame; (void) context; (void) object; +#if WEBKIT_CHECK_VERSION (1, 3, 13) + // Take this opportunity to set some callbacks on the DOM + WebKitDOMDocument *document = webkit_web_view_get_dom_document (webview); + webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (document), + "focus", G_CALLBACK(dom_focus_cb), TRUE, NULL); + webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (document), + "blur", G_CALLBACK(dom_focus_cb), TRUE, NULL); +#else + (void) webview; +#endif +} + +#if WEBKIT_CHECK_VERSION (1, 3, 13) +void +dom_focus_cb(WebKitDOMEventTarget *target, WebKitDOMEvent *event, gpointer user_data) { + (void) target; (void) user_data; + WebKitDOMEventTarget *etarget = webkit_dom_event_get_target (event); + gchar* name = webkit_dom_node_get_node_name (WEBKIT_DOM_NODE (etarget)); + send_event (FOCUS_ELEMENT, NULL, TYPE_STR, name, NULL); +} + +void +dom_blur_cb(WebKitDOMEventTarget *target, WebKitDOMEvent *event, gpointer user_data) { + (void) target; (void) user_data; + WebKitDOMEventTarget *etarget = webkit_dom_event_get_target (event); + gchar* name = webkit_dom_node_get_node_name (WEBKIT_DOM_NODE (etarget)); + send_event (BLUR_ELEMENT, NULL, TYPE_STR, name, NULL); +} +#endif + /* vi: set et ts=4: */ diff --git a/src/callbacks.h b/src/callbacks.h index d34b9fa..e9240b5 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -4,148 +4,6 @@ */ void -cmd_load_uri(); - -void -cmd_set_status(); - -void -set_proxy_url(); - -void -set_authentication_handler(); - -void -set_status_background(); - -void -set_icon(); - -void -move_statusbar(); - -void -cmd_http_debug(); - -void -cmd_max_conns(); - -void -cmd_max_conns_host(); - -/* exported WebKitWebSettings properties */ -void -cmd_font_size(); - -void -cmd_default_font_family(); - -void -cmd_monospace_font_family(); - -void -cmd_sans_serif_font_family(); - -void -cmd_serif_font_family(); - -void -cmd_cursive_font_family(); - -void -cmd_fantasy_font_family(); - -void -cmd_zoom_level(); - -void -cmd_set_zoom_type(); - -void -cmd_enable_pagecache(); - -void -cmd_disable_plugins(); - -void -cmd_disable_scripts(); - -void -cmd_minimum_font_size(); - -void -cmd_fifo_dir(); - -void -cmd_socket_dir(); - -void -cmd_useragent() ; - -void -set_accept_languages(); - -void -cmd_autoload_img(); - -void -cmd_autoshrink_img(); - -void -cmd_enable_spellcheck(); - -void -cmd_enable_private(); - -void -cmd_print_bg(); - -void -cmd_style_uri(); - -void -cmd_resizable_txt(); - -void -cmd_default_encoding(); - -void -set_current_encoding(); - -void -cmd_enforce_96dpi(); - -void -cmd_inject_html(); - -void -cmd_caret_browsing(); - -void -cmd_javascript_windows(); - -void -cmd_set_geometry(); - -void -cmd_view_source(); - -void -cmd_scrollbars_visibility(); - -void -cmd_load_start(); - -WebKitWebSettings* -view_settings(); - -void -toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result); - -void -toggle_status_cb (WebKitWebView* page, GArray *argv, GString *result); - -void link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpointer data); void @@ -157,13 +15,10 @@ progress_change_cb (WebKitWebView* web_view, GParamSpec param_spec); void load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec); -void +gboolean load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud); void -uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec); - -void selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud); void @@ -222,3 +77,15 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w); gboolean scroll_horiz_cb(GtkAdjustment *adjust, void *w); + +void +window_object_cleared_cb(WebKitWebView *webview, WebKitWebFrame *frame, + JSGlobalContextRef *context, JSObjectRef *object); + +#if WEBKIT_CHECK_VERSION (1, 3, 13) +void +dom_focus_cb(WebKitDOMEventTarget *target, WebKitDOMEvent *event, gpointer user_data); + +void +dom_blur_cb(WebKitDOMEventTarget *target, WebKitDOMEvent *event, gpointer user_data); +#endif diff --git a/src/commands.c b/src/commands.c new file mode 100644 index 0000000..cd1f872 --- /dev/null +++ b/src/commands.c @@ -0,0 +1,452 @@ +#include "commands.h" +#include "uzbl-core.h" +#include "events.h" +#include "util.h" +#include "menu.h" +#include "callbacks.h" +#include "variables.h" +#include "type.h" + +/* -- command to callback/function map for things we cannot attach to any signals */ +CommandInfo cmdlist[] = +{ /* key function no_split */ + { "back", view_go_back, 0 }, + { "forward", view_go_forward, 0 }, + { "scroll", scroll_cmd, 0 }, + { "reload", view_reload, 0 }, + { "reload_ign_cache", view_reload_bypass_cache, 0 }, + { "stop", view_stop_loading, 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, TRUE }, + { "js", run_js, TRUE }, + { "script", run_external_js, 0 }, + { "toggle_status", toggle_status, 0 }, + { "spawn", spawn_async, 0 }, + { "sync_spawn", spawn_sync, 0 }, + { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :( + { "sh", spawn_sh_async, 0 }, + { "sync_sh", spawn_sh_sync, 0 }, + { "exit", close_uzbl, 0 }, + { "search", search_forward_text, TRUE }, + { "search_reverse", search_reverse_text, TRUE }, + { "search_clear", search_clear, TRUE }, + { "dehilight", dehilight, 0 }, + { "set", set_var, TRUE }, + { "dump_config", act_dump_config, 0 }, + { "dump_config_as_events", act_dump_config_as_events, 0 }, + { "chain", chain, 0 }, + { "print", print, TRUE }, + { "event", event, TRUE }, + { "request", event, TRUE }, + { "menu_add", menu_add, TRUE }, + { "menu_link_add", menu_add_link, TRUE }, + { "menu_image_add", menu_add_image, TRUE }, + { "menu_editable_add", menu_add_edit, TRUE }, + { "menu_separator", menu_add_separator, TRUE }, + { "menu_link_separator", menu_add_separator_link, TRUE }, + { "menu_image_separator", menu_add_separator_image, TRUE }, + { "menu_editable_separator", menu_add_separator_edit, TRUE }, + { "menu_remove", menu_remove, TRUE }, + { "menu_link_remove", menu_remove_link, TRUE }, + { "menu_image_remove", menu_remove_image, TRUE }, + { "menu_editable_remove", menu_remove_edit, TRUE }, + { "hardcopy", hardcopy, TRUE }, + { "include", include, TRUE }, + { "show_inspector", show_inspector, 0 }, + { "add_cookie", add_cookie, 0 }, + { "delete_cookie", delete_cookie, 0 }, + { "clear_cookies", clear_cookies, 0 }, + { "download", download, 0 } +}; + +void +commands_hash() { + unsigned int i; + 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, (gpointer) cmdlist[i].key, &cmdlist[i]); +} + +void +builtins() { + unsigned int i; + unsigned int len = LENGTH(cmdlist); + GString* command_list = g_string_new(""); + + for (i = 0; i < len; i++) { + g_string_append(command_list, cmdlist[i].key); + g_string_append_c(command_list, ' '); + } + + send_event(BUILTINS, NULL, TYPE_STR, command_list->str, NULL); + g_string_free(command_list, TRUE); +} + +/* VIEW funcs (little webkit wrappers) */ +#define VIEWFUNC(name) 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) +VIEWFUNC(zoom_in) +VIEWFUNC(zoom_out) +VIEWFUNC(go_back) +VIEWFUNC(go_forward) +#undef VIEWFUNC + +void +toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) { + (void)argv; (void)result; + webkit_web_view_set_full_content_zoom (page, !webkit_web_view_get_full_content_zoom (page)); +} + +void +toggle_status (WebKitWebView* page, GArray *argv, GString *result) { + (void)page; (void)argv; (void)result; + + uzbl.behave.show_status = !uzbl.behave.show_status; + + set_show_status(); +} + +/* + * scroll vertical 20 + * scroll vertical 20% + * scroll vertical -40 + * scroll vertical begin + * scroll vertical end + * scroll horizontal 10 + * scroll horizontal -500 + * scroll horizontal begin + * scroll horizontal end + */ +void +scroll_cmd(WebKitWebView* page, GArray *argv, GString *result) { + (void) page; (void) result; + gchar *direction = g_array_index(argv, gchar*, 0); + gchar *argv1 = g_array_index(argv, gchar*, 1); + GtkAdjustment *bar = NULL; + + if (g_strcmp0(direction, "horizontal") == 0) + bar = uzbl.gui.bar_h; + else if (g_strcmp0(direction, "vertical") == 0) + bar = uzbl.gui.bar_v; + else { + if(uzbl.state.verbose) + puts("Unrecognized scroll format"); + return; + } + + if (g_strcmp0(argv1, "begin") == 0) + gtk_adjustment_set_value(bar, gtk_adjustment_get_lower(bar)); + else if (g_strcmp0(argv1, "end") == 0) + gtk_adjustment_set_value (bar, gtk_adjustment_get_upper(bar) - + gtk_adjustment_get_page_size(bar)); + else + scroll(bar, argv1); +} + +void +set_var(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + + if(!argv_idx(argv, 0)) + return; + + gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2); + if (split[0] != NULL) { + gchar *value = split[1] ? g_strchug(split[1]) : " "; + set_var_value(g_strstrip(split[0]), value); + } + g_strfreev(split); +} + + +void +event(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + GString *event_name; + gchar **split = NULL; + + if(!argv_idx(argv, 0)) + return; + + split = g_strsplit(argv_idx(argv, 0), " ", 2); + if(split[0]) + event_name = g_string_ascii_up(g_string_new(split[0])); + else + return; + + send_event(0, event_name->str, TYPE_FORMATTEDSTR, split[1] ? split[1] : "", NULL); + + g_string_free(event_name, TRUE); + g_strfreev(split); +} + +void +print(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + gchar* buf; + + if(!result) + return; + + buf = expand(argv_idx(argv, 0), 0); + g_string_assign(result, buf); + g_free(buf); +} + +void +hardcopy(WebKitWebView *page, GArray *argv, GString *result) { + (void) argv; (void) result; + webkit_web_frame_print(webkit_web_view_get_main_frame(page)); +} + +void +include(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + gchar *path = argv_idx(argv, 0); + + if(!path) + return; + + if((path = find_existing_file(path))) { + run_command_file(path); + send_event(FILE_INCLUDED, NULL, TYPE_STR, path, NULL); + g_free(path); + } +} + +void +show_inspector(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; + + webkit_web_inspector_show(uzbl.gui.inspector); +} + +void +add_cookie(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + gchar *host, *path, *name, *value; + gboolean secure = 0; + SoupDate *expires = NULL; + + if(argv->len != 6) + return; + + // Parse with same syntax as ADD_COOKIE event + host = argv_idx (argv, 0); + path = argv_idx (argv, 1); + name = argv_idx (argv, 2); + value = argv_idx (argv, 3); + secure = strcmp (argv_idx (argv, 4), "https") == 0; + if (strlen (argv_idx (argv, 5)) != 0) + expires = soup_date_new_from_time_t ( + strtoul (argv_idx (argv, 5), NULL, 10)); + + // Create new cookie + SoupCookie * cookie = soup_cookie_new (name, value, host, path, -1); + soup_cookie_set_secure (cookie, secure); + if (expires) + soup_cookie_set_expires (cookie, expires); + + // Add cookie to jar + uzbl.net.soup_cookie_jar->in_manual_add = 1; + soup_cookie_jar_add_cookie (SOUP_COOKIE_JAR (uzbl.net.soup_cookie_jar), cookie); + uzbl.net.soup_cookie_jar->in_manual_add = 0; +} + +void +delete_cookie(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + + if(argv->len < 4) + return; + + SoupCookie * cookie = soup_cookie_new ( + argv_idx (argv, 2), + argv_idx (argv, 3), + argv_idx (argv, 0), + argv_idx (argv, 1), + 0); + + uzbl.net.soup_cookie_jar->in_manual_add = 1; + soup_cookie_jar_delete_cookie (SOUP_COOKIE_JAR (uzbl.net.soup_cookie_jar), cookie); + uzbl.net.soup_cookie_jar->in_manual_add = 0; +} + +void +clear_cookies(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; + + // Replace the current cookie jar with a new empty jar + soup_session_remove_feature (uzbl.net.soup_session, + SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); + g_object_unref (G_OBJECT (uzbl.net.soup_cookie_jar)); + uzbl.net.soup_cookie_jar = uzbl_cookie_jar_new (); + soup_session_add_feature(uzbl.net.soup_session, + SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); +} + +void +download(WebKitWebView *web_view, GArray *argv, GString *result) { + (void) result; + + const gchar *uri = argv_idx(argv, 0); + const gchar *destination = NULL; + if(argv->len > 1) + destination = argv_idx(argv, 1); + + WebKitNetworkRequest *req = webkit_network_request_new(uri); + WebKitDownload *download = webkit_download_new(req); + + download_cb(web_view, download, (gpointer)destination); + + if(webkit_download_get_destination_uri(download)) + webkit_download_start(download); + else + g_object_unref(download); + + g_object_unref(req); +} + +void +load_uri(WebKitWebView *web_view, GArray *argv, GString *result) { + (void) web_view; (void) result; + gchar * uri = argv_idx(argv, 0); + set_var_value("uri", uri ? uri : ""); +} + +void +run_js (WebKitWebView * web_view, GArray *argv, GString *result) { + if (argv_idx(argv, 0)) + eval_js(web_view, argv_idx(argv, 0), result, "(command)"); +} + +void +run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) { + (void) result; + gchar *path = NULL; + + if (argv_idx(argv, 0) && + ((path = find_existing_file(argv_idx(argv, 0)))) ) { + gchar *file_contents = NULL; + + GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); + if (chan) { + gsize len; + g_io_channel_read_to_end(chan, &file_contents, &len, NULL); + g_io_channel_unref (chan); + } + + if (uzbl.state.verbose) + printf ("External JavaScript file %s loaded\n", argv_idx(argv, 0)); + + gchar *js = str_replace("%s", argv_idx (argv, 1) ? argv_idx (argv, 1) : "", file_contents); + g_free (file_contents); + + eval_js (web_view, js, result, path); + g_free (js); + g_free(path); + } +} + +void +search_clear(WebKitWebView *page, GArray *argv, GString *result) { + (void) argv; (void) result; + webkit_web_view_unmark_text_matches (page); + g_free(uzbl.state.searchtx); + uzbl.state.searchtx = NULL; +} + +void +search_forward_text (WebKitWebView *page, GArray *argv, GString *result) { + (void) result; + search_text(page, argv_idx(argv, 0), TRUE); +} + +void +search_reverse_text(WebKitWebView *page, GArray *argv, GString *result) { + (void) result; + search_text(page, argv_idx(argv, 0), FALSE); +} + +void +dehilight(WebKitWebView *page, GArray *argv, GString *result) { + (void) argv; (void) result; + webkit_web_view_set_highlight_text_matches (page, FALSE); +} + +void +chain(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + guint i = 0; + const gchar *cmd; + GString *r = g_string_new (""); + while ((cmd = argv_idx(argv, i++))) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(cmd, a); + if (c) + run_parsed_command(c, a, r); + g_array_free (a, TRUE); + } + if(result) + g_string_assign (result, r->str); + + g_string_free(r, TRUE); +} + +void +close_uzbl (WebKitWebView *page, GArray *argv, GString *result) { + (void)page; (void)argv; (void)result; + gtk_main_quit (); +} + +void +spawn_async(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; + spawn(argv, NULL, FALSE); +} + +void +spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; + spawn(argv, result, FALSE); +} + +void +spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; + if(!result) { + GString *force_result = g_string_new(""); + spawn(argv, force_result, TRUE); + g_string_free (force_result, TRUE); + } else + spawn(argv, result, TRUE); +} + +void +spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; + spawn_sh(argv, NULL); +} + +void +spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; + spawn_sh(argv, result); +} + +void +act_dump_config(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void) argv; (void)result; + dump_config(); +} + +void +act_dump_config_as_events(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void) argv; (void)result; + dump_config_as_events(); +} diff --git a/src/commands.h b/src/commands.h new file mode 100644 index 0000000..b8cf095 --- /dev/null +++ b/src/commands.h @@ -0,0 +1,68 @@ +/* + * Uzbl Commands + */ +#ifndef __COMMANDS__ +#define __COMMANDS__ + +#include <webkit/webkit.h> + +typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); + +typedef struct { + const gchar *key; + Command function; + gboolean no_split; +} CommandInfo; + +/** + * Initialises the hash table uzbl.behave.commands with the available commands. + */ +void +commands_hash(); + +/** + * Sends the BUILTINS events with the available commands. + */ +void +builtins(); + + +void view_reload(WebKitWebView *page, GArray *argv, GString *result); +void view_reload_bypass_cache(WebKitWebView *page, GArray *argv, GString *result); +void view_stop_loading(WebKitWebView *page, GArray *argv, GString *result); +void view_zoom_in(WebKitWebView *page, GArray *argv, GString *result); +void view_zoom_out(WebKitWebView *page, GArray *argv, GString *result); +void view_go_back(WebKitWebView *page, GArray *argv, GString *result); +void view_go_forward(WebKitWebView *page, GArray *argv, GString *result); +void toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result); +void scroll_cmd(WebKitWebView* page, GArray *argv, GString *result); +void print(WebKitWebView *page, GArray *argv, GString *result); +void event(WebKitWebView *page, GArray *argv, GString *result); +void load_uri(WebKitWebView * web_view, GArray *argv, GString *result); +void chain(WebKitWebView *page, GArray *argv, GString *result); +void close_uzbl(WebKitWebView *page, GArray *argv, GString *result); +void spawn_async(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result); +void search_forward_text (WebKitWebView *page, GArray *argv, GString *result); +void search_reverse_text (WebKitWebView *page, GArray *argv, GString *result); +void search_clear(WebKitWebView *page, GArray *argv, GString *result); +void dehilight (WebKitWebView *page, GArray *argv, GString *result); +void hardcopy(WebKitWebView *page, GArray *argv, GString *result); +void include(WebKitWebView *page, GArray *argv, GString *result); +void show_inspector(WebKitWebView *page, GArray *argv, GString *result); +void add_cookie(WebKitWebView *page, GArray *argv, GString *result); +void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); +void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); +void download(WebKitWebView *pag, GArray *argv, GString *result); +void set_var(WebKitWebView *page, GArray *argv, GString *result); +void run_js (WebKitWebView * web_view, GArray *argv, GString *result); +void run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); +void toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result); +void toggle_status (WebKitWebView* page, GArray *argv, GString *result); +void act_dump_config(WebKitWebView* page, GArray *argv, GString *result); +void act_dump_config_as_events(WebKitWebView* page, GArray *argv, GString *result); + +#endif diff --git a/src/cookie-jar.c b/src/cookie-jar.c index bc7d022..dd9585b 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -3,6 +3,7 @@ #include "cookie-jar.h" #include "uzbl-core.h" #include "events.h" +#include "type.h" G_DEFINE_TYPE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR) @@ -43,7 +44,7 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { gchar *expires = NULL; if(cookie->expires) - expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires)); + expires = g_strdup_printf ("%ld", (long)soup_date_to_time_t (cookie->expires)); send_event (new_cookie ? ADD_COOKIE : DELETE_COOKIE, NULL, TYPE_STR, cookie->domain, diff --git a/src/events.c b/src/events.c index 2da3e38..45140c0 100644 --- a/src/events.c +++ b/src/events.c @@ -6,8 +6,7 @@ #include "uzbl-core.h" #include "events.h" #include "util.h" - -UzblCore uzbl; +#include "type.h" /* Event id to name mapping * Event names must be in the same @@ -54,7 +53,9 @@ const char *event_table[LAST_EVENT] = { "DOWNLOAD_PROGRESS", "DOWNLOAD_COMPLETE", "ADD_COOKIE" , - "DELETE_COOKIE" + "DELETE_COOKIE" , + "FOCUS_ELEMENT" , + "BLUR_ELEMENT" }; void @@ -217,8 +218,10 @@ get_modifier_mask(guint state) { g_string_append(modifiers, "Ctrl|"); if(state & GDK_MOD1_MASK) g_string_append(modifiers,"Mod1|"); + /* Mod2 is usually Num_Luck. Ignore it as it messes up keybindings. if(state & GDK_MOD2_MASK) g_string_append(modifiers,"Mod2|"); + */ if(state & GDK_MOD3_MASK) g_string_append(modifiers,"Mod3|"); if(state & GDK_MOD4_MASK) diff --git a/src/events.h b/src/events.h index dbe0244..8e89899 100644 --- a/src/events.h +++ b/src/events.h @@ -25,6 +25,7 @@ enum event_type { PTR_MOVE, SCROLL_VERT, SCROLL_HORIZ, DOWNLOAD_STARTED, DOWNLOAD_PROGRESS, DOWNLOAD_COMPLETE, ADD_COOKIE, DELETE_COOKIE, + FOCUS_ELEMENT, BLUR_ELEMENT, /* must be last entry */ LAST_EVENT diff --git a/src/inspector.c b/src/inspector.c index 4c8c890..d0d86b9 100644 --- a/src/inspector.c +++ b/src/inspector.c @@ -6,7 +6,7 @@ #include "uzbl-core.h" #include "events.h" #include "callbacks.h" - +#include "type.h" void hide_window_cb(GtkWidget *widget, gpointer data) { @@ -88,7 +88,7 @@ inspector_inspector_destroyed_cb (WebKitWebInspector* inspector){ void set_up_inspector() { GUI *g = &uzbl.gui; - WebKitWebSettings *settings = view_settings(); + WebKitWebSettings *settings = webkit_web_view_get_settings(g->web_view); g_object_set(G_OBJECT(settings), "enable-developer-extras", TRUE, NULL); uzbl.gui.inspector = webkit_web_view_get_inspector(uzbl.gui.web_view); @@ -6,6 +6,7 @@ #include "io.h" #include "util.h" #include "uzbl-core.h" +#include "type.h" /*@null@*/ gchar* build_stream_name(int type, const gchar* dir) { @@ -3,6 +3,14 @@ #include <webkit/webkit.h> +typedef struct { + gchar* name; + gchar* cmd; + gboolean issep; + guint context; + WebKitHitTestResult* hittest; +} MenuItem; + void menu_add(WebKitWebView *page, GArray *argv, GString *result); void menu_add_link(WebKitWebView *page, GArray *argv, GString *result); void menu_add_image(WebKitWebView *page, GArray *argv, GString *result); diff --git a/src/status-bar.c b/src/status-bar.c new file mode 100644 index 0000000..6d4541b --- /dev/null +++ b/src/status-bar.c @@ -0,0 +1,117 @@ +#include "status-bar.h" + +G_DEFINE_TYPE (UzblStatusBar, uzbl_status_bar, GTK_TYPE_HBOX) + +static void uzbl_status_bar_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); + +static void +uzbl_status_bar_class_init (UzblStatusBarClass *class) { + GtkWidgetClass *widget_class; + + widget_class = (GtkWidgetClass*) class; + + /* override the size_allocate method */ + widget_class->size_allocate = uzbl_status_bar_size_allocate; +} + +static void +uzbl_status_bar_init (UzblStatusBar *status_bar) { + gtk_box_set_homogeneous (GTK_BOX(status_bar), FALSE); + gtk_box_set_spacing (GTK_BOX(status_bar), 0); + + /* create left panel */ + status_bar->left_label = gtk_label_new (""); + gtk_label_set_selectable (GTK_LABEL(status_bar->left_label), TRUE); + gtk_misc_set_alignment (GTK_MISC(status_bar->left_label), 0, 0); + gtk_misc_set_padding (GTK_MISC(status_bar->left_label), 2, 2); + gtk_label_set_ellipsize(GTK_LABEL(status_bar->left_label), PANGO_ELLIPSIZE_END); + + /* create right panel */ + status_bar->right_label = gtk_label_new (""); + gtk_label_set_selectable(GTK_LABEL(status_bar->right_label), TRUE); + gtk_misc_set_alignment (GTK_MISC(status_bar->right_label), 1, 0); + gtk_misc_set_padding (GTK_MISC(status_bar->right_label), 2, 2); + gtk_label_set_ellipsize(GTK_LABEL(status_bar->right_label), PANGO_ELLIPSIZE_START); + + /* add the labels to the status bar */ + gtk_box_pack_start (GTK_BOX (status_bar), status_bar->left_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (status_bar), status_bar->right_label, TRUE, TRUE, 0); +} + +static void +uzbl_status_bar_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) { + GtkRequisition left_requisition, right_requisition; + GtkAllocation left_allocation, right_allocation; + UzblStatusBar *status_bar = UZBL_STATUS_BAR(widget); + + int left_natural_width; + +#if GTK_CHECK_VERSION(3,0,0) + GtkRequisition left_requisition_nat; + + gtk_widget_get_preferred_size (status_bar->left_label, &left_requisition, &left_requisition_nat); + gtk_widget_get_preferred_size (status_bar->right_label, &right_requisition, NULL); + + left_natural_width = left_requisition_nat.width; +#else + gtk_widget_size_request(status_bar->left_label, &left_requisition); + gtk_widget_size_request(status_bar->right_label, &right_requisition); + + PangoLayout *left_layout = gtk_label_get_layout(GTK_LABEL(status_bar->left_label)); + pango_layout_get_pixel_size(left_layout, &left_natural_width, NULL); + + /* some kind of fudge factor seems to be needed here */ + left_natural_width += 16; +#endif + + gtk_widget_set_allocation (widget, allocation); + + /* the entire allocation, minus the space needed for the right label's ellipsis */ + int left_max_width = allocation->width - right_requisition.width; + + /* the left label gets max(as much space as it needs, the status bar's allocation) */ + left_allocation.width = (left_max_width > left_natural_width) ? left_natural_width : left_max_width; + + /* the right label gets whatever is left over. it gets at least enough space + * for an ellipsis, it seems that it will just display everything if you give + * it 0. */ + right_allocation.width = allocation->width - left_allocation.width; + + /* don't fight guys, you can both have as much vertical space as you want! */ + left_allocation.height = right_allocation.height = allocation->height; + + left_allocation.x = 0; + right_allocation.x = left_allocation.width; + + left_allocation.y = right_allocation.y = allocation->y; + + gtk_widget_size_allocate (status_bar->left_label, &left_allocation); + gtk_widget_size_allocate (status_bar->right_label, &right_allocation); +} + +void +uzbl_status_bar_update_left(GtkWidget *widget, const gchar *format) { + UzblStatusBar *status_bar = UZBL_STATUS_BAR(widget); + + if(!format || !GTK_IS_LABEL(status_bar->left_label)) + return; + + gtk_label_set_markup(GTK_LABEL(status_bar->left_label), format); +} + +void +uzbl_status_bar_update_right(GtkWidget *widget, const gchar *format) { + UzblStatusBar *status_bar = UZBL_STATUS_BAR(widget); + + if(!format || !GTK_IS_LABEL(status_bar->right_label)) + return; + + gtk_label_set_markup(GTK_LABEL(status_bar->right_label), format); +} + +GtkWidget * +uzbl_status_bar_new() { + return g_object_new (UZBL_TYPE_STATUS_BAR, NULL); +} diff --git a/src/status-bar.h b/src/status-bar.h new file mode 100644 index 0000000..e972701 --- /dev/null +++ b/src/status-bar.h @@ -0,0 +1,36 @@ +#ifndef __UZBL_STATUS_BAR_H__ +#define __UZBL_STATUS_BAR_H__ + +#include <gtk/gtk.h> + +#define UZBL_TYPE_STATUS_BAR (uzbl_status_bar_get_type ()) +#define UZBL_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UZBL_TYPE_STATUS_BAR, UzblStatusBar)) +#define UZBL_STATUS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UZBL_TYPE_STATUS_BAR, UZblStatusBarClass)) +#define UZBL_IS_STATUS_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UZBL_TYPE_STATUS_BAR)) +#define UZBL_IS_STATUS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UZBL_TYPE_STATUS_BAR)) +#define UZBL_STATUS_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UZBL_TYPE_STATUS_BAR, UzblStatusBarClass)) + +typedef struct _UzblStatusBar UzblStatusBar; +typedef struct _UzblStatusBarClass UzblStatusBarClass; + +struct _UzblStatusBar { + GtkHBox hbox; + + GtkWidget *left_label; + GtkWidget *right_label; +}; + +struct _UzblStatusBarClass { + GtkHBoxClass parent_class; +}; + +GType uzbl_status_bar_get_type (void) G_GNUC_CONST; +GtkWidget * uzbl_status_bar_new (); + +void +uzbl_status_bar_update_left(GtkWidget *widget, const gchar *format); + +void +uzbl_status_bar_update_right(GtkWidget *widget, const gchar *format); + +#endif diff --git a/src/type.h b/src/type.h new file mode 100644 index 0000000..24fc97f --- /dev/null +++ b/src/type.h @@ -0,0 +1,24 @@ +/* + * Uzbl Types + */ + +enum ptr_type { + TYPE_INT = 1, + TYPE_STR, + TYPE_FLOAT, + TYPE_NAME, + TYPE_FORMATTEDSTR // used by send_event +}; + +typedef struct { + enum ptr_type type; + union { + int *i; + float *f; + gchar **s; + } ptr; + int dump; + int writeable; + /*@null@*/ void (*func)(void); +} uzbl_cmdprop; + @@ -134,7 +134,7 @@ find_existing_file(const gchar* path_list) { char *basename = strrchr(path_list_dup, ':'); if(!basename) - return path_list_dup; + return file_exists(path_list_dup) ? path_list_dup : NULL; basename[0] = '\0'; basename++; diff --git a/src/uzbl-core.c b/src/uzbl-core.c index c095a7f..af60767 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -37,6 +37,8 @@ #include "util.h" #include "menu.h" #include "io.h" +#include "variables.h" +#include "type.h" UzblCore uzbl; @@ -51,8 +53,11 @@ GOptionEntry entries[] = { "Name of the current instance (defaults to Xorg window id or random for GtkSocket mode)", "NAME" }, { "config", 'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file, "Path to config file or '-' for stdin", "FILE" }, + /* TODO: explain the difference between these two options */ { "socket", 's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id, - "Xembed Socket ID", "SOCKET" }, + "Xembed socket ID, this window should embed itself", "SOCKET" }, + { "embed", 'e', 0, G_OPTION_ARG_NONE, &uzbl.state.embed, + "Whether this window should expect to be embedded", NULL }, { "connect-socket", 0, 0, G_OPTION_ARG_STRING_ARRAY, &uzbl.state.connect_socket_names, "Connect to server socket for event managing", "CSOCKET" }, { "print-events", 'p', 0, G_OPTION_ARG_NONE, &uzbl.state.events_stdout, @@ -64,107 +69,6 @@ GOptionEntry entries[] = { { NULL, 0, 0, 0, NULL, NULL, NULL } }; -/* abbreviations to help keep the table's width humane */ -#define PTR_V_STR(var, d, fun) { .ptr.s = &(var), .type = TYPE_STR, .dump = d, .writeable = 1, .func = fun } -#define PTR_V_INT(var, d, fun) { .ptr.i = (int*)&(var), .type = TYPE_INT, .dump = d, .writeable = 1, .func = fun } -#define PTR_V_FLOAT(var, d, fun) { .ptr.f = &(var), .type = TYPE_FLOAT, .dump = d, .writeable = 1, .func = fun } -#define PTR_C_STR(var, fun) { .ptr.s = &(var), .type = TYPE_STR, .dump = 0, .writeable = 0, .func = fun } -#define PTR_C_INT(var, fun) { .ptr.i = (int*)&(var), .type = TYPE_INT, .dump = 0, .writeable = 0, .func = fun } -#define PTR_C_FLOAT(var, fun) { .ptr.f = &(var), .type = TYPE_FLOAT, .dump = 0, .writeable = 0, .func = fun } - -const struct var_name_to_ptr_t { - const char *name; - uzbl_cmdprop cp; -} var_name_to_ptr[] = { -/* variable name pointer to variable in code dump callback function */ -/* ---------------------------------------------------------------------------------------------- */ - { "uri", PTR_V_STR(uzbl.state.uri, 1, cmd_load_uri)}, - { "verbose", PTR_V_INT(uzbl.state.verbose, 1, NULL)}, - { "print_events", PTR_V_INT(uzbl.state.events_stdout, 1, NULL)}, - { "inject_html", PTR_V_STR(uzbl.behave.inject_html, 0, cmd_inject_html)}, - { "geometry", PTR_V_STR(uzbl.gui.geometry, 1, cmd_set_geometry)}, - { "show_status", PTR_V_INT(uzbl.behave.show_status, 1, cmd_set_status)}, - { "status_top", PTR_V_INT(uzbl.behave.status_top, 1, move_statusbar)}, - { "status_format", PTR_V_STR(uzbl.behave.status_format, 1, NULL)}, - { "status_format_right", PTR_V_STR(uzbl.behave.status_format_right, 1, NULL)}, - { "status_background", PTR_V_STR(uzbl.behave.status_background, 1, set_status_background)}, - { "title_format_long", PTR_V_STR(uzbl.behave.title_format_long, 1, NULL)}, - { "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)}, - { "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)}, - { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, - { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, - { "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)}, - { "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)}, - { "fifo_dir", PTR_V_STR(uzbl.behave.fifo_dir, 1, cmd_fifo_dir)}, - { "socket_dir", PTR_V_STR(uzbl.behave.socket_dir, 1, cmd_socket_dir)}, - { "http_debug", PTR_V_INT(uzbl.behave.http_debug, 1, cmd_http_debug)}, - { "shell_cmd", PTR_V_STR(uzbl.behave.shell_cmd, 1, NULL)}, - { "proxy_url", PTR_V_STR(uzbl.net.proxy_url, 1, set_proxy_url)}, - { "max_conns", PTR_V_INT(uzbl.net.max_conns, 1, cmd_max_conns)}, - { "max_conns_host", PTR_V_INT(uzbl.net.max_conns_host, 1, cmd_max_conns_host)}, - { "useragent", PTR_V_STR(uzbl.net.useragent, 1, cmd_useragent)}, - { "accept_languages", PTR_V_STR(uzbl.net.accept_languages, 1, set_accept_languages)}, - { "javascript_windows", PTR_V_INT(uzbl.behave.javascript_windows, 1, cmd_javascript_windows)}, - /* requires webkit >=1.1.14 */ - { "view_source", PTR_V_INT(uzbl.behave.view_source, 0, cmd_view_source)}, - - /* exported WebKitWebSettings properties */ - { "zoom_level", PTR_V_FLOAT(uzbl.behave.zoom_level, 1, cmd_zoom_level)}, - { "zoom_type", PTR_V_INT(uzbl.behave.zoom_type, 1, cmd_set_zoom_type)}, - { "font_size", PTR_V_INT(uzbl.behave.font_size, 1, cmd_font_size)}, - { "default_font_family", PTR_V_STR(uzbl.behave.default_font_family, 1, cmd_default_font_family)}, - { "monospace_font_family", PTR_V_STR(uzbl.behave.monospace_font_family, 1, cmd_monospace_font_family)}, - { "cursive_font_family", PTR_V_STR(uzbl.behave.cursive_font_family, 1, cmd_cursive_font_family)}, - { "sans_serif_font_family", PTR_V_STR(uzbl.behave.sans_serif_font_family, 1, cmd_sans_serif_font_family)}, - { "serif_font_family", PTR_V_STR(uzbl.behave.serif_font_family, 1, cmd_serif_font_family)}, - { "fantasy_font_family", PTR_V_STR(uzbl.behave.fantasy_font_family, 1, cmd_fantasy_font_family)}, - { "monospace_size", PTR_V_INT(uzbl.behave.monospace_size, 1, cmd_font_size)}, - { "minimum_font_size", PTR_V_INT(uzbl.behave.minimum_font_size, 1, cmd_minimum_font_size)}, - { "enable_pagecache", PTR_V_INT(uzbl.behave.enable_pagecache, 1, cmd_enable_pagecache)}, - { "disable_plugins", PTR_V_INT(uzbl.behave.disable_plugins, 1, cmd_disable_plugins)}, - { "disable_scripts", PTR_V_INT(uzbl.behave.disable_scripts, 1, cmd_disable_scripts)}, - { "autoload_images", PTR_V_INT(uzbl.behave.autoload_img, 1, cmd_autoload_img)}, - { "autoshrink_images", PTR_V_INT(uzbl.behave.autoshrink_img, 1, cmd_autoshrink_img)}, - { "enable_spellcheck", PTR_V_INT(uzbl.behave.enable_spellcheck, 1, cmd_enable_spellcheck)}, - { "enable_private", PTR_V_INT(uzbl.behave.enable_private, 1, cmd_enable_private)}, - { "print_backgrounds", PTR_V_INT(uzbl.behave.print_bg, 1, cmd_print_bg)}, - { "stylesheet_uri", PTR_V_STR(uzbl.behave.style_uri, 1, cmd_style_uri)}, - { "resizable_text_areas", PTR_V_INT(uzbl.behave.resizable_txt, 1, cmd_resizable_txt)}, - { "default_encoding", PTR_V_STR(uzbl.behave.default_encoding, 1, cmd_default_encoding)}, - { "current_encoding", PTR_V_STR(uzbl.behave.current_encoding, 1, set_current_encoding)}, - { "enforce_96_dpi", PTR_V_INT(uzbl.behave.enforce_96dpi, 1, cmd_enforce_96dpi)}, - { "caret_browsing", PTR_V_INT(uzbl.behave.caret_browsing, 1, cmd_caret_browsing)}, - { "scrollbars_visible", PTR_V_INT(uzbl.gui.scrollbars_visible, 1, cmd_scrollbars_visibility)}, - - /* constants (not dumpable or writeable) */ - { "WEBKIT_MAJOR", PTR_C_INT(uzbl.info.webkit_major, NULL)}, - { "WEBKIT_MINOR", PTR_C_INT(uzbl.info.webkit_minor, NULL)}, - { "WEBKIT_MICRO", PTR_C_INT(uzbl.info.webkit_micro, NULL)}, - { "ARCH_UZBL", PTR_C_STR(uzbl.info.arch, NULL)}, - { "COMMIT", PTR_C_STR(uzbl.info.commit, NULL)}, - { "TITLE", PTR_C_STR(uzbl.gui.main_title, NULL)}, - { "SELECTED_URI", PTR_C_STR(uzbl.state.selected_url, NULL)}, - { "NAME", PTR_C_STR(uzbl.state.instance_name, NULL)}, - { "PID", PTR_C_STR(uzbl.info.pid_str, NULL)}, - { "_", PTR_C_STR(uzbl.state.last_result, NULL)}, - - { NULL, {.ptr.s = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}} -}; - -/* construct a hash from the var_name_to_ptr array for quick access */ -void -create_var_to_name_hash() { - const struct var_name_to_ptr_t *n2v_p = var_name_to_ptr; - uzbl.comm.proto_var = g_hash_table_new(g_str_hash, g_str_equal); - while(n2v_p->name) { - g_hash_table_insert(uzbl.comm.proto_var, - (gpointer) n2v_p->name, - (gpointer) &n2v_p->cp); - n2v_p++; - } -} - - /* --- UTILITY FUNCTIONS --- */ enum exp_type { EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE @@ -187,7 +91,6 @@ get_exp_type(const gchar *s) { */ gchar* expand(const char* s, guint recurse) { - uzbl_cmdprop* c; enum exp_type etype; char* end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; char* ret = NULL; @@ -244,17 +147,8 @@ expand(const char* s, guint recurse) { 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 && *c->ptr.s != NULL) { - g_string_append(buf, (gchar *)*c->ptr.s); - } - else if(c->type == TYPE_INT) { - g_string_append_printf(buf, "%d", *c->ptr.i); - } - else if(c->type == TYPE_FLOAT) { - g_string_append_printf(buf, "%f", *c->ptr.f); - } - } + + expand_variable(buf, ret); if(etype == EXP_SIMPLE_VAR) s = vend; @@ -448,199 +342,8 @@ scroll(GtkAdjustment* bar, gchar *amount_str) { gtk_adjustment_set_value (bar, value); } -/* - * scroll vertical 20 - * scroll vertical 20% - * scroll vertical -40 - * scroll vertical begin - * scroll vertical end - * scroll horizontal 10 - * scroll horizontal -500 - * scroll horizontal begin - * scroll horizontal end - */ -void -scroll_cmd(WebKitWebView* page, GArray *argv, GString *result) { - (void) page; (void) result; - gchar *direction = g_array_index(argv, gchar*, 0); - gchar *argv1 = g_array_index(argv, gchar*, 1); - - if (g_strcmp0(direction, "horizontal") == 0) - { - if (g_strcmp0(argv1, "begin") == 0) - gtk_adjustment_set_value(uzbl.gui.bar_h, gtk_adjustment_get_lower(uzbl.gui.bar_h)); - else if (g_strcmp0(argv1, "end") == 0) - gtk_adjustment_set_value (uzbl.gui.bar_h, gtk_adjustment_get_upper(uzbl.gui.bar_h) - - gtk_adjustment_get_page_size(uzbl.gui.bar_h)); - else - scroll(uzbl.gui.bar_h, argv1); - } - else if (g_strcmp0(direction, "vertical") == 0) - { - if (g_strcmp0(argv1, "begin") == 0) - gtk_adjustment_set_value(uzbl.gui.bar_v, gtk_adjustment_get_lower(uzbl.gui.bar_v)); - else if (g_strcmp0(argv1, "end") == 0) - 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)); - else - scroll(uzbl.gui.bar_v, argv1); - } - else - if(uzbl.state.verbose) - puts("Unrecognized scroll format"); -} - - -/* VIEW funcs (little webkit wrappers) */ -#define VIEWFUNC(name) 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) -VIEWFUNC(zoom_in) -VIEWFUNC(zoom_out) -VIEWFUNC(go_back) -VIEWFUNC(go_forward) -#undef VIEWFUNC - -/* -- command to callback/function map for things we cannot attach to any signals */ -CommandInfo cmdlist[] = -{ /* key function no_split */ - { "back", view_go_back, 0 }, - { "forward", view_go_forward, 0 }, - { "scroll", scroll_cmd, 0 }, - { "reload", view_reload, 0 }, - { "reload_ign_cache", view_reload_bypass_cache, 0 }, - { "stop", view_stop_loading, 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, TRUE }, - { "js", run_js, TRUE }, - { "script", run_external_js, 0 }, - { "toggle_status", toggle_status_cb, 0 }, - { "spawn", spawn_async, 0 }, - { "sync_spawn", spawn_sync, 0 }, - { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :( - { "sh", spawn_sh_async, 0 }, - { "sync_sh", spawn_sh_sync, 0 }, - { "exit", close_uzbl, 0 }, - { "search", search_forward_text, TRUE }, - { "search_reverse", search_reverse_text, TRUE }, - { "search_clear", search_clear, TRUE }, - { "dehilight", dehilight, 0 }, - { "set", set_var, TRUE }, - { "dump_config", act_dump_config, 0 }, - { "dump_config_as_events", act_dump_config_as_events, 0 }, - { "chain", chain, 0 }, - { "print", print, TRUE }, - { "event", event, TRUE }, - { "request", event, TRUE }, - { "menu_add", menu_add, TRUE }, - { "menu_link_add", menu_add_link, TRUE }, - { "menu_image_add", menu_add_image, TRUE }, - { "menu_editable_add", menu_add_edit, TRUE }, - { "menu_separator", menu_add_separator, TRUE }, - { "menu_link_separator", menu_add_separator_link, TRUE }, - { "menu_image_separator", menu_add_separator_image, TRUE }, - { "menu_editable_separator", menu_add_separator_edit, TRUE }, - { "menu_remove", menu_remove, TRUE }, - { "menu_link_remove", menu_remove_link, TRUE }, - { "menu_image_remove", menu_remove_image, TRUE }, - { "menu_editable_remove", menu_remove_edit, TRUE }, - { "hardcopy", hardcopy, TRUE }, - { "include", include, TRUE }, - { "show_inspector", show_inspector, 0 }, - { "add_cookie", add_cookie, 0 }, - { "delete_cookie", delete_cookie, 0 }, - { "clear_cookies", clear_cookies, 0 }, - { "download", download, 0 } -}; - -void -commands_hash(void) { - unsigned int i; - 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, (gpointer) cmdlist[i].key, &cmdlist[i]); -} - - -void -builtins() { - unsigned int i; - unsigned int len = LENGTH(cmdlist); - GString* command_list = g_string_new(""); - - for (i = 0; i < len; i++) { - g_string_append(command_list, cmdlist[i].key); - g_string_append_c(command_list, ' '); - } - - send_event(BUILTINS, NULL, TYPE_STR, command_list->str, NULL); - g_string_free(command_list, TRUE); -} - /* -- CORE FUNCTIONS -- */ -void -set_var(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - - if(!argv_idx(argv, 0)) - return; - - gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2); - if (split[0] != NULL) { - gchar *value = split[1] ? g_strchug(split[1]) : " "; - set_var_value(g_strstrip(split[0]), value); - } - g_strfreev(split); -} - - -void -event(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - GString *event_name; - gchar **split = NULL; - - if(!argv_idx(argv, 0)) - return; - - split = g_strsplit(argv_idx(argv, 0), " ", 2); - if(split[0]) - event_name = g_string_ascii_up(g_string_new(split[0])); - else - return; - - send_event(0, event_name->str, TYPE_FORMATTEDSTR, split[1] ? split[1] : "", NULL); - - g_string_free(event_name, TRUE); - g_strfreev(split); -} - -void -print(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - gchar* buf; - - if(!result) - return; - - buf = expand(argv_idx(argv, 0), 0); - g_string_assign(result, buf); - g_free(buf); -} - -void -hardcopy(WebKitWebView *page, GArray *argv, GString *result) { - (void) argv; - (void) result; - - webkit_web_frame_print(webkit_web_view_get_main_frame(page)); -} - /* just a wrapper so parse_cmd_line can be used with for_each_line_in_file */ static void parse_cmd_line_cb(const char *line, void *user_data) { @@ -649,140 +352,17 @@ parse_cmd_line_cb(const char *line, void *user_data) { } void -include(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - gchar *path = argv_idx(argv, 0); - - if(!path) - return; - - if((path = find_existing_file(path))) { - if(!for_each_line_in_file(path, parse_cmd_line_cb, NULL)) { - gchar *tmp = g_strdup_printf("File %s can not be read.", path); - send_event(COMMAND_ERROR, NULL, TYPE_STR, tmp, NULL); - g_free(tmp); - } - - send_event(FILE_INCLUDED, NULL, TYPE_STR, path, NULL); - g_free(path); - } -} - -void -show_inspector(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) argv; (void) result; - - webkit_web_inspector_show(uzbl.gui.inspector); -} - -void -add_cookie(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - gchar *host, *path, *name, *value; - gboolean secure = 0; - SoupDate *expires = NULL; - - if(argv->len != 6) - return; - - // Parse with same syntax as ADD_COOKIE event - host = argv_idx (argv, 0); - path = argv_idx (argv, 1); - name = argv_idx (argv, 2); - value = argv_idx (argv, 3); - secure = strcmp (argv_idx (argv, 4), "https") == 0; - if (strlen (argv_idx (argv, 5)) != 0) - expires = soup_date_new_from_time_t ( - strtoul (argv_idx (argv, 5), NULL, 10)); - - // Create new cookie - SoupCookie * cookie = soup_cookie_new (name, value, host, path, -1); - soup_cookie_set_secure (cookie, secure); - if (expires) - soup_cookie_set_expires (cookie, expires); - - // Add cookie to jar - uzbl.net.soup_cookie_jar->in_manual_add = 1; - soup_cookie_jar_add_cookie (SOUP_COOKIE_JAR (uzbl.net.soup_cookie_jar), cookie); - uzbl.net.soup_cookie_jar->in_manual_add = 0; -} - -void -delete_cookie(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - - if(argv->len < 4) - return; - - SoupCookie * cookie = soup_cookie_new ( - argv_idx (argv, 2), - argv_idx (argv, 3), - argv_idx (argv, 0), - argv_idx (argv, 1), - 0); - - uzbl.net.soup_cookie_jar->in_manual_add = 1; - soup_cookie_jar_delete_cookie (SOUP_COOKIE_JAR (uzbl.net.soup_cookie_jar), cookie); - uzbl.net.soup_cookie_jar->in_manual_add = 0; -} - - -void -clear_cookies(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) argv; (void) result; - - // Replace the current cookie jar with a new empty jar - soup_session_remove_feature (uzbl.net.soup_session, - SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); - g_object_unref (G_OBJECT (uzbl.net.soup_cookie_jar)); - uzbl.net.soup_cookie_jar = uzbl_cookie_jar_new (); - soup_session_add_feature(uzbl.net.soup_session, - SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); -} - -void -download(WebKitWebView *web_view, GArray *argv, GString *result) { - (void) result; - - const gchar *uri = argv_idx(argv, 0); - const gchar *destination = NULL; - if(argv->len > 1) - destination = argv_idx(argv, 1); - - WebKitNetworkRequest *req = webkit_network_request_new(uri); - WebKitDownload *download = webkit_download_new(req); - - download_cb(web_view, download, destination); - - if(webkit_download_get_destination_uri(download)) - webkit_download_start(download); - else - g_object_unref(download); - - g_object_unref(req); -} - -void -act_dump_config() { - dump_config(); -} - -void -act_dump_config_as_events() { - dump_config_as_events(); -} - -void -load_uri(WebKitWebView *web_view, GArray *argv, GString *result) { - (void) web_view; (void) result; - gchar * uri = argv_idx(argv, 0); - set_var_value("uri", uri ? uri : ""); +run_command_file(const gchar *path) { + if(!for_each_line_in_file(path, parse_cmd_line_cb, NULL)) { + gchar *tmp = g_strdup_printf("File %s can not be read.", path); + send_event(COMMAND_ERROR, NULL, TYPE_STR, tmp, NULL); + g_free(tmp); + } } /* Javascript*/ void -eval_js(WebKitWebView * web_view, gchar *script, GString *result, const char *file) { +eval_js(WebKitWebView * web_view, const gchar *script, GString *result, const char *file) { WebKitWebFrame *frame; JSGlobalContextRef context; JSObjectRef globalobject; @@ -861,51 +441,16 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result, const char *fi } void -run_js (WebKitWebView * web_view, GArray *argv, GString *result) { - if (argv_idx(argv, 0)) - eval_js(web_view, argv_idx(argv, 0), result, "(command)"); -} - -void -run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) { - (void) result; - gchar *path = NULL; - - if (argv_idx(argv, 0) && - ((path = find_existing_file(argv_idx(argv, 0)))) ) { - gchar *file_contents = NULL; - - GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); - if (chan) { - gsize len; - g_io_channel_read_to_end(chan, &file_contents, &len, NULL); - g_io_channel_unref (chan); - } - - if (uzbl.state.verbose) - printf ("External JavaScript file %s loaded\n", argv_idx(argv, 0)); - - gchar *js = str_replace("%s", argv_idx (argv, 1) ? argv_idx (argv, 1) : "", file_contents); - g_free (file_contents); - - eval_js (web_view, js, result, path); - g_free (js); - g_free(path); - } -} - -void -search_text (WebKitWebView *page, GArray *argv, const gboolean forward) { - if (argv_idx(argv, 0) && (*argv_idx(argv, 0) != '\0')) { - if (g_strcmp0 (uzbl.state.searchtx, argv_idx(argv, 0)) != 0) { +search_text (WebKitWebView *page, const gchar *key, const gboolean forward) { + if (key && (*key != '\0')) { + if (g_strcmp0 (uzbl.state.searchtx, key) != 0) { webkit_web_view_unmark_text_matches (page); - webkit_web_view_mark_text_matches (page, argv_idx(argv, 0), FALSE, 0); + webkit_web_view_mark_text_matches (page, key, FALSE, 0); g_free (uzbl.state.searchtx); - uzbl.state.searchtx = g_strdup(argv_idx(argv, 0)); + uzbl.state.searchtx = g_strdup (key); } } - if (uzbl.state.searchtx) { if (uzbl.state.verbose) printf ("Searching: %s\n", uzbl.state.searchtx); @@ -915,61 +460,6 @@ search_text (WebKitWebView *page, GArray *argv, const gboolean forward) { } void -search_clear(WebKitWebView *page, GArray *argv, GString *result) { - (void) argv; - (void) result; - - webkit_web_view_unmark_text_matches (page); - g_free(uzbl.state.searchtx); - uzbl.state.searchtx = NULL; -} - -void -search_forward_text (WebKitWebView *page, GArray *argv, GString *result) { - (void) result; - search_text(page, argv, TRUE); -} - -void -search_reverse_text(WebKitWebView *page, GArray *argv, GString *result) { - (void) result; - search_text(page, argv, FALSE); -} - -void -dehilight(WebKitWebView *page, GArray *argv, GString *result) { - (void) argv; (void) result; - webkit_web_view_set_highlight_text_matches (page, FALSE); -} - -void -chain(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - guint i = 0; - const gchar *cmd; - GString *r = g_string_new (""); - while ((cmd = argv_idx(argv, i++))) { - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - const CommandInfo *c = parse_command_parts(cmd, a); - if (c) - run_parsed_command(c, a, r); - g_array_free (a, TRUE); - } - if(result) - g_string_assign (result, r->str); - - g_string_free(r, TRUE); -} - -void -close_uzbl (WebKitWebView *page, GArray *argv, GString *result) { - (void)page; - (void)argv; - (void)result; - gtk_main_quit (); -} - -void sharg_append(GArray *a, const gchar *str) { const gchar *s = (str ? str : ""); g_array_append_val(a, s); @@ -1063,12 +553,16 @@ split_quoted(const gchar* src, const gboolean unquote) { void spawn(GArray *argv, GString *result, gboolean exec) { gchar *path = NULL; - gchar *arg_car = argv_idx(argv, 0); - const gchar **arg_cdr = &g_array_index(argv, const gchar *, 1); - if (arg_car && (path = find_existing_file(arg_car))) { + if (!argv_idx(argv, 0)) + return; + + const gchar **args = &g_array_index(argv, const gchar *, 1); + + path = find_existing_file(argv_idx(argv, 0)); + if(path) { gchar *r = NULL; - run_command(path, arg_cdr, result != NULL, result ? &r : NULL); + run_command(path, args, result != NULL, result ? &r : NULL); if(result) { g_string_assign(result, r); // run each line of output from the program as a command @@ -1084,33 +578,12 @@ spawn(GArray *argv, GString *result, gboolean exec) { } g_free(r); g_free(path); + } else { + g_printerr ("Failed to spawn child process: %s not found\n", argv_idx(argv, 0)); } } void -spawn_async(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn(argv, NULL, FALSE); -} - -void -spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; - spawn(argv, result, FALSE); -} - -void -spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; - if(!result) { - GString *force_result = g_string_new(""); - spawn(argv, force_result, TRUE); - g_string_free (force_result, TRUE); - } else - spawn(argv, result, TRUE); -} - -void spawn_sh(GArray *argv, GString *result) { if (!uzbl.behave.shell_cmd) { g_printerr ("spawn_sh: shell_cmd is not set!\n"); @@ -1141,18 +614,6 @@ spawn_sh(GArray *argv, GString *result) { } void -spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn_sh(argv, NULL); -} - -void -spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn_sh(argv, result); -} - -void run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { /* send the COMMAND_EXECUTED event, except for set and event/request commands */ if(strcmp("set", c->key) && @@ -1253,33 +714,6 @@ parse_command(const char *cmd, const char *params, GString *result) { } } - -void -move_statusbar() { - if (!uzbl.gui.scrolled_win && - !uzbl.gui.mainbar) - return; - - g_object_ref(uzbl.gui.scrolled_win); - g_object_ref(uzbl.gui.mainbar); - gtk_container_remove(GTK_CONTAINER(uzbl.gui.vbox), uzbl.gui.scrolled_win); - gtk_container_remove(GTK_CONTAINER(uzbl.gui.vbox), uzbl.gui.mainbar); - - if(uzbl.behave.status_top) { - gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.mainbar, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.scrolled_win, TRUE, TRUE, 0); - } - else { - 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); - } - g_object_unref(uzbl.gui.scrolled_win); - g_object_unref(uzbl.gui.mainbar); - if (!uzbl.state.plug_mode) - gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); - return; -} - gboolean valid_name(const gchar* name) { char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; @@ -1287,97 +721,6 @@ valid_name(const gchar* name) { } void -send_set_var_event(const char *name, const uzbl_cmdprop *c) { - /* check for the variable type */ - switch(c->type) { - case TYPE_STR: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "str", - TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", - NULL); - break; - case TYPE_INT: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "int", - TYPE_INT, *c->ptr.i, - NULL); - break; - case TYPE_FLOAT: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "float", - TYPE_FLOAT, *c->ptr.f, - NULL); - break; - default: - g_assert_not_reached(); - } -} - -gboolean -set_var_value(const gchar *name, gchar *val) { - uzbl_cmdprop *c = NULL; - char *endp = NULL; - char *buf = NULL; - - g_assert(val != NULL); - - if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { - if(!c->writeable) return FALSE; - - switch(c->type) { - case TYPE_STR: - buf = g_strdup(val); - g_free(*c->ptr.s); - *c->ptr.s = buf; - break; - case TYPE_INT: - *c->ptr.i = (int)strtoul(val, &endp, 10); - break; - case TYPE_FLOAT: - *c->ptr.f = strtod(val, &endp); - break; - default: - g_assert_not_reached(); - } - - send_set_var_event(name, c); - - /* invoke a command specific function */ - if(c->func) c->func(); - } else { - /* check wether name violates our naming scheme */ - if(!valid_name(name)) { - if (uzbl.state.verbose) - printf("Invalid variable name: %s\n", name); - return FALSE; - } - - /* custom vars */ - c = g_malloc(sizeof(uzbl_cmdprop)); - c->type = TYPE_STR; - c->dump = 0; - c->func = NULL; - c->writeable = 1; - buf = g_strdup(val); - c->ptr.s = g_malloc(sizeof(char *)); - *c->ptr.s = buf; - g_hash_table_insert(uzbl.comm.proto_var, - g_strdup(name), (gpointer) c); - - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "str", - TYPE_STR, buf, - NULL); - } - update_title(); - return TRUE; -} - -void parse_cmd_line(const char *ctl_line, GString *result) { gchar *work_string = g_strdup(ctl_line); @@ -1407,19 +750,13 @@ update_title(void) { if (b->show_status) { title_format = b->title_format_short; - /* Left side */ - if (b->status_format && GTK_IS_LABEL(uzbl.gui.mainbar_label_left)) { - gchar *parsed = expand(b->status_format, 0); - gtk_label_set_markup(GTK_LABEL(uzbl.gui.mainbar_label_left), parsed); - g_free(parsed); - } + gchar *parsed = expand(b->status_format, 0); + uzbl_status_bar_update_left(uzbl.gui.status_bar, parsed); + g_free(parsed); - /* Right side */ - if (b->status_format_right && GTK_IS_LABEL(uzbl.gui.mainbar_label_right)) { - gchar *parsed = expand(b->status_format_right, 0); - gtk_label_set_markup(GTK_LABEL(uzbl.gui.mainbar_label_right), parsed); - g_free(parsed); - } + parsed = expand(b->status_format_right, 0); + uzbl_status_bar_update_right(uzbl.gui.status_bar, parsed); + g_free(parsed); } /* Update window title */ @@ -1443,12 +780,6 @@ create_scrolled_win() { g->web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); g->scrolled_win = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy( - GTK_SCROLLED_WINDOW(g->scrolled_win), - GTK_POLICY_NEVER, - GTK_POLICY_NEVER - ); - gtk_container_add( GTK_CONTAINER(g->scrolled_win), GTK_WIDGET(g->web_view) @@ -1476,61 +807,23 @@ create_scrolled_win() { "signal::populate-popup", (GCallback)populate_popup_cb, NULL, "signal::focus-in-event", (GCallback)focus_cb, NULL, "signal::focus-out-event", (GCallback)focus_cb, NULL, + "signal::window-object-cleared", (GCallback)window_object_cleared_cb,NULL, NULL); } GtkWidget* -create_mainbar() { - GUI *g = &uzbl.gui; - - g->mainbar = gtk_hbox_new (FALSE, 0); - - /* Left panel */ - g->mainbar_label_left = gtk_label_new (""); - gtk_label_set_selectable(GTK_LABEL(g->mainbar_label_left), TRUE); - gtk_misc_set_alignment (GTK_MISC(g->mainbar_label_left), 0, 0); - gtk_misc_set_padding (GTK_MISC(g->mainbar_label_left), 2, 2); - - gtk_box_pack_start (GTK_BOX (g->mainbar), g->mainbar_label_left, FALSE, FALSE, 0); - - /* Right panel */ - g->mainbar_label_right = gtk_label_new (""); - gtk_label_set_selectable(GTK_LABEL(g->mainbar_label_right), TRUE); - gtk_misc_set_alignment (GTK_MISC(g->mainbar_label_right), 1, 0); - gtk_misc_set_padding (GTK_MISC(g->mainbar_label_right), 2, 2); - gtk_label_set_ellipsize(GTK_LABEL(g->mainbar_label_right), PANGO_ELLIPSIZE_START); - - gtk_box_pack_start (GTK_BOX (g->mainbar), g->mainbar_label_right, TRUE, TRUE, 0); - - g_object_connect((GObject*)g->mainbar, - "signal::key-press-event", (GCallback)key_press_cb, NULL, - "signal::key-release-event", (GCallback)key_release_cb, NULL, - NULL); - - return g->mainbar; -} - - -GtkWidget* create_window() { GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); - gtk_widget_set_name (window, "Uzbl browser"); - gtk_window_set_title(GTK_WINDOW(window), "Uzbl browser"); + gtk_widget_set_name (window, "Uzbl"); + gtk_window_set_title(GTK_WINDOW(window), "Uzbl"); #if GTK_CHECK_VERSION(3,0,0) - gtk_window_set_has_resize_grip (window, FALSE); + gtk_window_set_has_resize_grip (GTK_WINDOW (window), FALSE); #endif - /* if the window has been made small, it shouldn't try to resize itself due - * to a long statusbar. */ - GdkGeometry hints; - hints.min_height = -1; - hints.min_width = 1; - gtk_window_set_geometry_hints (GTK_WINDOW (window), window, &hints, GDK_HINT_MIN_SIZE); - g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy_cb), NULL); g_signal_connect (G_OBJECT (window), "configure-event", G_CALLBACK (configure_event_cb), NULL); @@ -1540,6 +833,7 @@ create_window() { GtkPlug* create_plug() { + if(uzbl.state.embed) uzbl.state.socket_id = 0; 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); @@ -1553,7 +847,7 @@ settings_init () { State* s = &uzbl.state; Network* n = &uzbl.net; int i; - + /* Load default config */ for (i = 0; default_config[i].command != NULL; i++) { parse_cmd_line(default_config[i].command, NULL); @@ -1570,11 +864,7 @@ settings_init () { /* Load config file, if any */ if (s->config_file) { - if (!for_each_line_in_file(s->config_file, parse_cmd_line_cb, NULL)) { - gchar *tmp = g_strdup_printf("File %s can not be read.", s->config_file); - send_event(COMMAND_ERROR, NULL, TYPE_STR, tmp, NULL); - g_free(tmp); - } + run_command_file(s->config_file); g_setenv("UZBL_CONFIG", s->config_file, TRUE); } else if (uzbl.state.verbose) printf ("No configuration file loaded.\n"); @@ -1641,41 +931,6 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au } void -dump_var_hash(gpointer k, gpointer v, gpointer ud) { - (void) ud; - uzbl_cmdprop *c = v; - - if(!c->dump) - return; - - if(c->type == TYPE_STR) - printf("set %s = %s\n", (char *)k, *c->ptr.s ? *c->ptr.s : " "); - else if(c->type == TYPE_INT) - printf("set %s = %d\n", (char *)k, *c->ptr.i); - else if(c->type == TYPE_FLOAT) - printf("set %s = %f\n", (char *)k, *c->ptr.f); -} - -void -dump_config() { - g_hash_table_foreach(uzbl.comm.proto_var, dump_var_hash, NULL); -} - -void -dump_var_hash_as_event(gpointer k, gpointer v, gpointer ud) { - (void) ud; - uzbl_cmdprop *c = v; - - if(c->dump) - send_set_var_event(k, c); -} - -void -dump_config_as_events() { - g_hash_table_foreach(uzbl.comm.proto_var, dump_var_hash_as_event, NULL); -} - -void retrieve_geometry() { int w, h, x, y; GString *buf = g_string_new(""); @@ -1690,28 +945,6 @@ retrieve_geometry() { uzbl.gui.geometry = g_string_free(buf, FALSE); } -void -set_webview_scroll_adjustments() { -#if GTK_CHECK_VERSION(2,91,0) - gtk_scrollable_set_hadjustment (GTK_SCROLLABLE(uzbl.gui.web_view), uzbl.gui.bar_h); - gtk_scrollable_set_vadjustment (GTK_SCROLLABLE(uzbl.gui.web_view), uzbl.gui.bar_v); -#else - gtk_widget_set_scroll_adjustments (GTK_WIDGET (uzbl.gui.web_view), - uzbl.gui.bar_h, uzbl.gui.bar_v); -#endif - - g_object_connect((GObject*)uzbl.gui.bar_v, - "signal::value-changed", (GCallback)scroll_vert_cb, NULL, - "signal::changed", (GCallback)scroll_vert_cb, NULL, - NULL); - - g_object_connect((GObject*)uzbl.gui.bar_h, - "signal::value-changed", (GCallback)scroll_horiz_cb, NULL, - "signal::changed", (GCallback)scroll_horiz_cb, NULL, - NULL); -} - - /* Set up gtk, gobject, variable defaults and other things that tests and other * external applications need to do anyhow */ void @@ -1746,7 +979,7 @@ initialize(int argc, char** argv) { } /* Embedded mode */ - if (uzbl.state.socket_id) + if (uzbl.state.socket_id || uzbl.state.embed) uzbl.state.plug_mode = TRUE; if (!g_thread_supported()) @@ -1759,68 +992,47 @@ initialize(int argc, char** argv) { fprintf(stderr, "uzbl: error hooking %d: %s\n", SIGALRM, strerror(errno)); event_buffer_timeout(10); - /* HTTP client */ uzbl.net.soup_session = webkit_get_default_session(); uzbl.net.soup_cookie_jar = uzbl_cookie_jar_new(); soup_session_add_feature(uzbl.net.soup_session, SOUP_SESSION_FEATURE(uzbl.net.soup_cookie_jar)); - commands_hash(); - create_var_to_name_hash(); + variables_hash(); /* GUI */ gtk_init(&argc, &argv); - create_mainbar(); - create_scrolled_win(); - uzbl.gui.vbox = gtk_vbox_new(FALSE, 0); - 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); -} + /* set up the status bar */ + uzbl.gui.status_bar = uzbl_status_bar_new(); + /* set up signal handlers (it's not great to have this here...) */ + g_object_connect((GObject*)uzbl.gui.status_bar, + "signal::key-press-event", (GCallback)key_press_cb, NULL, + "signal::key-release-event", (GCallback)key_release_cb, NULL, + NULL); -void -load_uri_imp(gchar *uri) { - GString* newuri; - SoupURI* soup_uri; - - /* Strip leading whitespaces */ - while (*uri) { - if (!isspace(*uri)) break; - uri++; - } + /* + g_object_connect((GObject*)UZBL_STATUS_BAR(uzbl.gui.status_bar)->label_left, + "signal::key-press-event", (GCallback)key_press_cb, NULL, + "signal::key-release-event", (GCallback)key_release_cb, NULL, + NULL); - if (g_strstr_len (uri, 11, "javascript:") != NULL) { - eval_js(uzbl.gui.web_view, uri, NULL, "javascript:"); - return; - } + g_object_connect((GObject*)(UZBL_STATUS_BAR(uzbl.gui.status_bar)->label_right), + "signal::key-press-event", (GCallback)key_press_cb, NULL, + "signal::key-release-event", (GCallback)key_release_cb, NULL, + NULL); + */ - newuri = g_string_new (uri); - soup_uri = soup_uri_new(uri); - - if (!soup_uri) { - gchar* fullpath; - if (g_path_is_absolute (newuri->str)) - fullpath = newuri->str; - else { - gchar* wd = g_get_current_dir (); - fullpath = g_build_filename (wd, newuri->str, NULL); - g_free(wd); - } - struct stat stat_result; - if (! g_stat(fullpath, &stat_result)) - g_string_printf (newuri, "file://%s", fullpath); - else - g_string_prepend (newuri, "http://"); - } else { - soup_uri_free(soup_uri); - } + /* create the main window itself */ + create_scrolled_win(); + + /* pack the window and the status bar */ + uzbl.gui.vbox = gtk_vbox_new(FALSE, 0); - /* if we do handle cookies, ask our handler for them */ - webkit_web_view_load_uri (uzbl.gui.web_view, newuri->str); - g_string_free (newuri, TRUE); + 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.status_bar, FALSE, TRUE, 0); } @@ -1834,7 +1046,6 @@ main (int argc, char* argv[]) { if (uzbl.state.plug_mode) { 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)); /* in xembed mode the window has no unique id and thus * socket/fifo names aren't unique either. * we use a custom randomizer to create a random id @@ -1844,12 +1055,13 @@ main (int argc, char* argv[]) { srand((unsigned int)tv.tv_sec*tv.tv_usec); uzbl.xwin = rand(); } - + /* Windowed mode */ 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); + /* We need to ensure there is a window, before we can get XID */ + gtk_widget_realize (GTK_WIDGET (uzbl.gui.main_window)); uzbl.xwin = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (uzbl.gui.main_window))); @@ -1857,12 +1069,18 @@ main (int argc, char* argv[]) { } /* Scrolling */ - uzbl.gui.scbar_v = (GtkScrollbar*) gtk_vscrollbar_new (NULL); - uzbl.gui.bar_v = gtk_range_get_adjustment((GtkRange*) uzbl.gui.scbar_v); - uzbl.gui.scbar_h = (GtkScrollbar*) gtk_hscrollbar_new (NULL); - uzbl.gui.bar_h = gtk_range_get_adjustment((GtkRange*) uzbl.gui.scbar_h); + uzbl.gui.bar_h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); + uzbl.gui.bar_v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); - set_webview_scroll_adjustments(); + g_object_connect(G_OBJECT (uzbl.gui.bar_v), + "signal::value-changed", (GCallback)scroll_vert_cb, NULL, + "signal::changed", (GCallback)scroll_vert_cb, NULL, + NULL); + + g_object_connect(G_OBJECT (uzbl.gui.bar_h), + "signal::value-changed", (GCallback)scroll_horiz_cb, NULL, + "signal::changed", (GCallback)scroll_horiz_cb, NULL, + NULL); gchar *xwin = g_strdup_printf("%d", (int)uzbl.xwin); g_setenv("UZBL_XID", xwin, TRUE); @@ -1886,7 +1104,7 @@ main (int argc, char* argv[]) { /* Check uzbl is in window mode before getting/setting geometry */ if (uzbl.gui.main_window) { if (uzbl.gui.geometry) - cmd_set_geometry(); + set_geometry(); else retrieve_geometry(); } @@ -1902,7 +1120,7 @@ main (int argc, char* argv[]) { /* Update status bar */ if (!uzbl.behave.show_status) - gtk_widget_hide(uzbl.gui.mainbar); + gtk_widget_hide(uzbl.gui.status_bar); else update_title(); @@ -1918,11 +1136,18 @@ main (int argc, char* argv[]) { g_free(uri_override); } + /* Finally show the window */ + if (uzbl.gui.main_window) { + gtk_widget_show_all (uzbl.gui.main_window); + } else { + gtk_widget_show_all (GTK_WIDGET (uzbl.gui.plug)); + } + /* Verbose feedback */ if (uzbl.state.verbose) { printf("Uzbl start location: %s\n", argv[0]); if (uzbl.state.socket_id) - printf("plug_id %i\n", gtk_plug_get_id(uzbl.gui.plug)); + printf("plug_id %i\n", (int)gtk_plug_get_id(uzbl.gui.plug)); else printf("window_id %i\n",(int) uzbl.xwin); printf("pid %i\n", getpid ()); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index be8fccd..c84380e 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -48,6 +48,8 @@ #endif #include "cookie-jar.h" +#include "commands.h" +#include "status-bar.h" #define LENGTH(x) (sizeof x / sizeof x[0]) @@ -62,21 +64,17 @@ typedef struct { GtkWidget* vbox; /* Mainbar */ - GtkWidget* mainbar; - GtkWidget* mainbar_label_left; - GtkWidget* mainbar_label_right; + GtkWidget* status_bar; /* Scrolling */ - GtkScrollbar* scbar_v; /* Horizontal and Vertical Scrollbar */ - GtkScrollbar* scbar_h; /* (These are still hidden) */ GtkAdjustment* bar_v; /* Information about document length */ GtkAdjustment* bar_h; /* and scrolling position */ - int scrollbars_visible; /* Web page */ WebKitWebView* web_view; gchar* main_title; gchar* icon; + gchar* window_role; /* WebInspector */ GtkWidget* inspector_window; @@ -92,7 +90,6 @@ enum { FIFO, SOCKET}; typedef struct { gchar *fifo_path; gchar *socket_path; - GHashTable *proto_var; /* stores (key)"variable name" -> (value)"pointer to var */ GPtrArray *connect_chan; GPtrArray *client_chan; @@ -109,6 +106,7 @@ typedef struct { gchar* executable_path; gchar* searchtx; gboolean verbose; + gboolean embed; GdkEventButton* last_button; gchar* last_result; gboolean plug_mode; @@ -181,6 +179,7 @@ typedef struct { guint autoload_img; guint autoshrink_img; guint enable_spellcheck; + gchar* spellcheck_languages; guint enable_private; guint print_bg; gchar* style_uri; @@ -195,9 +194,8 @@ typedef struct { /* command list: (key)name -> (value)Command */ GHashTable* commands; - - /* event lookup: (key)event_id -> (value)event_name */ - GHashTable *event_lookup; + /* variables: (key)name -> (value)uzbl_cmdprop */ + GHashTable *proto_var; } Behaviour; @@ -229,22 +227,6 @@ extern UzblCore uzbl; /* Main Uzbl object */ typedef void sigfunc(int); -/* Uzbl variables */ -enum ptr_type {TYPE_INT = 1, TYPE_STR, TYPE_FLOAT, - TYPE_NAME, TYPE_FORMATTEDSTR // used by send_event -}; -typedef struct { - enum ptr_type type; - union { - int *i; - float *f; - gchar **s; - } ptr; - int dump; - int writeable; - /*@null@*/ void (*func)(void); -} uzbl_cmdprop; - /* Functions */ void clean_up(void); void update_title(void); @@ -253,24 +235,24 @@ void update_title(void); void catch_sigterm(int s); sigfunc* setup_signal(int signe, sigfunc *shandler); -gboolean set_var_value(const gchar *name, gchar *val); -void load_uri_imp(gchar *uri); -void print(WebKitWebView *page, GArray *argv, GString *result); -void commands_hash(void); -void load_uri(WebKitWebView * web_view, GArray *argv, GString *result); -void chain(WebKitWebView *page, GArray *argv, GString *result); -void close_uzbl(WebKitWebView *page, GArray *argv, GString *result); +/* Subprocess spawning */ +void spawn(GArray *argv, GString *result, gboolean exec); +void spawn_sh(GArray *argv, GString *result); + +/* Configuration variables */ +gboolean valid_name(const gchar* name); /* Running commands */ +gchar* expand(const char* s, guint recurse); gboolean run_command(const gchar *command, const gchar **args, const gboolean sync, char **output_stdout); -void spawn_async(WebKitWebView *web_view, GArray *argv, GString *result); -void spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result); -void spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result); -void spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result); -void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result); +void run_command_file(const gchar *path); void parse_command(const char *cmd, const char *param, GString *result); void parse_cmd_line(const char *ctl_line, GString *result); +const CommandInfo * + parse_command_parts(const gchar *line, GArray *a); +void parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); +void run_parsed_command(const CommandInfo *c, GArray *a, GString *result); /* Keyboard events functions */ gboolean key_press_cb(GtkWidget* window, GdkEventKey* event); @@ -282,20 +264,13 @@ void create_scrolled_win(); GtkWidget* create_mainbar(); GtkWidget* create_window(); GtkPlug* create_plug(); -void run_handler(const gchar *act, const gchar *args); void settings_init(); /* Search functions */ -void search_text (WebKitWebView *page, GArray *argv, const gboolean forward); -void search_forward_text (WebKitWebView *page, GArray *argv, GString *result); -void search_reverse_text (WebKitWebView *page, GArray *argv, GString *result); -void search_clear(WebKitWebView *page, GArray *argv, GString *result); -void dehilight (WebKitWebView *page, GArray *argv, GString *result); +void search_text (WebKitWebView *page, const gchar *key, const gboolean forward); /* Javascript functions */ -void run_js (WebKitWebView * web_view, GArray *argv, GString *result); -void run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); -void eval_js(WebKitWebView * web_view, gchar *script, GString *result, const gchar *script_file); +void eval_js(WebKitWebView *web_view, const gchar *script, GString *result, const gchar *script_file); /* Network functions */ void handle_authentication (SoupSession *session, @@ -303,55 +278,15 @@ void handle_authentication (SoupSession *session, SoupAuth *auth, gboolean retrying, gpointer user_data); -gboolean valid_name(const gchar* name); -void set_var(WebKitWebView *page, GArray *argv, GString *result); -void act_dump_config(); -void act_dump_config_as_events(); -void dump_var_hash(gpointer k, gpointer v, gpointer ud); -void dump_key_hash(gpointer k, gpointer v, gpointer ud); -void dump_config(); -void dump_config_as_events(); -void retrieve_geometry(); -void set_webview_scroll_adjustments(); -void event(WebKitWebView *page, GArray *argv, GString *result); void init_connect_socket(); gboolean remove_socket_from_array(GIOChannel *chan); +/* Window */ +void retrieve_geometry(); +void scroll(GtkAdjustment* bar, gchar *amount_str); gint get_click_context(); -void hardcopy(WebKitWebView *page, GArray *argv, GString *result); -void include(WebKitWebView *page, GArray *argv, GString *result); -void show_inspector(WebKitWebView *page, GArray *argv, GString *result); -void add_cookie(WebKitWebView *page, GArray *argv, GString *result); -void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); -void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); -void download(WebKitWebView *pag, GArray *argv, GString *result); -void builtins(); -typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); - -typedef struct { - const gchar *key; - Command function; - gboolean no_split; -} CommandInfo; - -const CommandInfo * -parse_command_parts(const gchar *line, GArray *a); - -void -parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); - -void -run_parsed_command(const CommandInfo *c, GArray *a, GString *result); - -typedef struct { - gchar* name; - gchar* cmd; - gboolean issep; - guint context; - WebKitHitTestResult* hittest; -} MenuItem; #endif /* vi: set et ts=4: */ diff --git a/src/variables.c b/src/variables.c new file mode 100644 index 0000000..b72c4b0 --- /dev/null +++ b/src/variables.c @@ -0,0 +1,618 @@ +#include "variables.h" +#include "uzbl-core.h" +#include "callbacks.h" +#include "events.h" +#include "io.h" +#include "util.h" +#include "type.h" + +void +send_set_var_event(const char *name, const uzbl_cmdprop *c) { + /* check for the variable type */ + switch(c->type) { + case TYPE_STR: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "str", + TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", + NULL); + break; + case TYPE_INT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "int", + TYPE_INT, *c->ptr.i, + NULL); + break; + case TYPE_FLOAT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "float", + TYPE_FLOAT, *c->ptr.f, + NULL); + break; + default: + g_assert_not_reached(); + } +} + +void +expand_variable(GString *buf, const gchar *name) { + uzbl_cmdprop* c; + if((c = g_hash_table_lookup(uzbl.behave.proto_var, name))) { + if(c->type == TYPE_STR && *c->ptr.s != NULL) { + g_string_append(buf, (gchar *)*c->ptr.s); + } + else if(c->type == TYPE_INT) { + g_string_append_printf(buf, "%d", *c->ptr.i); + } + else if(c->type == TYPE_FLOAT) { + g_string_append_printf(buf, "%f", *c->ptr.f); + } + } +} + +gboolean +set_var_value(const gchar *name, gchar *val) { + uzbl_cmdprop *c = NULL; + char *endp = NULL; + char *buf = NULL; + + g_assert(val != NULL); + + if( (c = g_hash_table_lookup(uzbl.behave.proto_var, name)) ) { + if(!c->writeable) return FALSE; + + switch(c->type) { + case TYPE_STR: + buf = g_strdup(val); + g_free(*c->ptr.s); + *c->ptr.s = buf; + break; + case TYPE_INT: + *c->ptr.i = (int)strtoul(val, &endp, 10); + break; + case TYPE_FLOAT: + *c->ptr.f = strtod(val, &endp); + break; + default: + g_assert_not_reached(); + } + + send_set_var_event(name, c); + + /* invoke a command specific function */ + if(c->func) c->func(); + } else { + /* check wether name violates our naming scheme */ + if(!valid_name(name)) { + if (uzbl.state.verbose) + printf("Invalid variable name: %s\n", name); + return FALSE; + } + + /* custom vars */ + c = g_malloc(sizeof(uzbl_cmdprop)); + c->type = TYPE_STR; + c->dump = 0; + c->func = NULL; + c->writeable = 1; + buf = g_strdup(val); + c->ptr.s = g_malloc(sizeof(char *)); + *c->ptr.s = buf; + g_hash_table_insert(uzbl.behave.proto_var, + g_strdup(name), (gpointer) c); + + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "str", + TYPE_STR, buf, + NULL); + } + update_title(); + return TRUE; +} + +void +dump_var_hash(gpointer k, gpointer v, gpointer ud) { + (void) ud; + uzbl_cmdprop *c = v; + + if(!c->dump) + return; + + if(c->type == TYPE_STR) + printf("set %s = %s\n", (char *)k, *c->ptr.s ? *c->ptr.s : " "); + else if(c->type == TYPE_INT) + printf("set %s = %d\n", (char *)k, *c->ptr.i); + else if(c->type == TYPE_FLOAT) + printf("set %s = %f\n", (char *)k, *c->ptr.f); +} + +void +dump_config() { + g_hash_table_foreach(uzbl.behave.proto_var, dump_var_hash, NULL); +} + +void +dump_var_hash_as_event(gpointer k, gpointer v, gpointer ud) { + (void) ud; + uzbl_cmdprop *c = v; + + if(c->dump) + send_set_var_event(k, c); +} + +void +dump_config_as_events() { + g_hash_table_foreach(uzbl.behave.proto_var, dump_var_hash_as_event, NULL); +} + +/* is the given string made up entirely of decimal digits? */ +gboolean +string_is_integer(const char *s) { + return (strspn(s, "0123456789") == strlen(s)); +} + + +GObject* +view_settings() { + return G_OBJECT(webkit_web_view_get_settings(uzbl.gui.web_view)); +} + +void +uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec) { + (void) param_spec; + + g_free (uzbl.state.uri); + g_object_get (web_view, "uri", &uzbl.state.uri, NULL); + g_setenv("UZBL_URI", uzbl.state.uri, TRUE); + + if(GTK_IS_WIDGET(uzbl.gui.main_window)) { + gdk_property_change( + gtk_widget_get_window (GTK_WIDGET (uzbl.gui.main_window)), + gdk_atom_intern_static_string("UZBL_URI"), + gdk_atom_intern_static_string("STRING"), + 8, + GDK_PROP_MODE_REPLACE, + (unsigned char *)uzbl.state.uri, + strlen(uzbl.state.uri)); + } +} + +void +cmd_load_uri() { + const gchar *uri = uzbl.state.uri; + + gchar *newuri; + SoupURI *soup_uri; + + /* Strip leading whitespaces */ + while (*uri && isspace(*uri)) + uri++; + + /* evaluate javascript: URIs */ + if (!strncmp (uri, "javascript:", 11)) { + eval_js(uzbl.gui.web_view, uri, NULL, "javascript:"); + return; + } + + /* attempt to parse the URI */ + soup_uri = soup_uri_new(uri); + + if (!soup_uri) { + /* it's not a valid URI, maybe it's a path on the filesystem. */ + const gchar *fullpath; + if (g_path_is_absolute (uri)) + fullpath = uri; + else { + gchar *wd = g_get_current_dir (); + fullpath = g_build_filename (wd, uri, NULL); + g_free(wd); + } + + struct stat stat_result; + if (! g_stat(fullpath, &stat_result)) + newuri = g_strconcat("file://", fullpath, NULL); + else + newuri = g_strconcat("http://", uri, NULL); + } else { + if(soup_uri->host == NULL && string_is_integer(soup_uri->path)) + /* the user probably typed in a host:port without a scheme */ + newuri = g_strconcat("http://", uri, NULL); + else + newuri = g_strdup(uri); + + soup_uri_free(soup_uri); + } + + if(GTK_IS_WIDGET(uzbl.gui.main_window)) { + gdk_property_change( + gtk_widget_get_window (GTK_WIDGET (uzbl.gui.main_window)), + gdk_atom_intern_static_string("UZBL_URI"), + gdk_atom_intern_static_string("STRING"), + 8, + GDK_PROP_MODE_REPLACE, + (unsigned char *)newuri, + strlen(newuri)); + } + + webkit_web_view_load_uri (uzbl.gui.web_view, newuri); + g_free (newuri); +} + +void +cmd_max_conns() { + g_object_set(G_OBJECT(uzbl.net.soup_session), + SOUP_SESSION_MAX_CONNS, uzbl.net.max_conns, NULL); +} + +void +cmd_max_conns_host() { + g_object_set(G_OBJECT(uzbl.net.soup_session), + SOUP_SESSION_MAX_CONNS_PER_HOST, uzbl.net.max_conns_host, NULL); +} + +void +cmd_http_debug() { + if(uzbl.net.soup_logger) { + soup_session_remove_feature + (uzbl.net.soup_session, SOUP_SESSION_FEATURE(uzbl.net.soup_logger)); + g_object_unref (uzbl.net.soup_logger); + } + + uzbl.net.soup_logger = soup_logger_new(uzbl.behave.http_debug, -1); + soup_session_add_feature(uzbl.net.soup_session, + SOUP_SESSION_FEATURE(uzbl.net.soup_logger)); +} + +void +cmd_font_size() { + GObject *ws = view_settings(); + if (uzbl.behave.font_size > 0) { + g_object_set (ws, "default-font-size", uzbl.behave.font_size, NULL); + } + + if (uzbl.behave.monospace_size > 0) { + g_object_set (ws, "default-monospace-font-size", + uzbl.behave.monospace_size, NULL); + } else { + g_object_set (ws, "default-monospace-font-size", + uzbl.behave.font_size, NULL); + } +} + +void +cmd_zoom_level() { + webkit_web_view_set_zoom_level (uzbl.gui.web_view, uzbl.behave.zoom_level); +} + +#define EXPOSE_WEBKIT_VIEW_SETTINGS(SYM, STORAGE, PROPERTY) void cmd_##SYM() { \ + g_object_set(view_settings(), (PROPERTY), (STORAGE), NULL); \ +} + +EXPOSE_WEBKIT_VIEW_SETTINGS(default_font_family, uzbl.behave.default_font_family, "default-font-family") +EXPOSE_WEBKIT_VIEW_SETTINGS(monospace_font_family, uzbl.behave.monospace_font_family, "monospace-font-family") +EXPOSE_WEBKIT_VIEW_SETTINGS(sans_serif_font_family, uzbl.behave.sans_serif_font_family, "sans_serif-font-family") +EXPOSE_WEBKIT_VIEW_SETTINGS(serif_font_family, uzbl.behave.serif_font_family, "serif-font-family") +EXPOSE_WEBKIT_VIEW_SETTINGS(cursive_font_family, uzbl.behave.cursive_font_family, "cursive-font-family") +EXPOSE_WEBKIT_VIEW_SETTINGS(fantasy_font_family, uzbl.behave.fantasy_font_family, "fantasy-font-family") + +EXPOSE_WEBKIT_VIEW_SETTINGS(minimum_font_size, uzbl.behave.minimum_font_size, "minimum_font_size") + +EXPOSE_WEBKIT_VIEW_SETTINGS(disable_plugins, !uzbl.behave.disable_plugins, "enable-plugins") +EXPOSE_WEBKIT_VIEW_SETTINGS(disable_scripts, !uzbl.behave.disable_scripts, "enable-scripts") + +EXPOSE_WEBKIT_VIEW_SETTINGS(javascript_windows, uzbl.behave.javascript_windows, "javascript-can-open-windows-automatically") + +EXPOSE_WEBKIT_VIEW_SETTINGS(autoload_img, uzbl.behave.autoload_img, "auto-load-images") +EXPOSE_WEBKIT_VIEW_SETTINGS(autoshrink_img, uzbl.behave.autoshrink_img, "auto-shrink-images") + +EXPOSE_WEBKIT_VIEW_SETTINGS(enable_pagecache, uzbl.behave.enable_pagecache, "enable-page-cache") +EXPOSE_WEBKIT_VIEW_SETTINGS(enable_private, uzbl.behave.enable_private, "enable-private-browsing") + +EXPOSE_WEBKIT_VIEW_SETTINGS(enable_spellcheck, uzbl.behave.enable_spellcheck, "enable-spell-checking") +EXPOSE_WEBKIT_VIEW_SETTINGS(spellcheck_languages, uzbl.behave.spellcheck_languages, "spell-checking-languages") +EXPOSE_WEBKIT_VIEW_SETTINGS(resizable_txt, uzbl.behave.resizable_txt, "resizable-text-areas") + +EXPOSE_WEBKIT_VIEW_SETTINGS(style_uri, uzbl.behave.style_uri, "user-stylesheet-uri") +EXPOSE_WEBKIT_VIEW_SETTINGS(print_bg, uzbl.behave.print_bg, "print-backgrounds") +EXPOSE_WEBKIT_VIEW_SETTINGS(enforce_96dpi, uzbl.behave.enforce_96dpi, "enforce-96-dpi") + +EXPOSE_WEBKIT_VIEW_SETTINGS(caret_browsing, uzbl.behave.caret_browsing, "enable-caret-browsing") + +EXPOSE_WEBKIT_VIEW_SETTINGS(default_encoding, uzbl.behave.default_encoding, "default-encoding") + +void +set_proxy_url() { + const gchar *url = uzbl.net.proxy_url; + SoupSession *session = uzbl.net.soup_session; + SoupURI *soup_uri = NULL; + + if (url != NULL || *url != 0 || *url != ' ') + soup_uri = soup_uri_new(url); + + g_object_set(G_OBJECT(session), SOUP_SESSION_PROXY_URI, soup_uri, NULL); + + if(soup_uri) + soup_uri_free(soup_uri); +} + + +void +set_authentication_handler() { + /* Check if WEBKIT_TYPE_SOUP_AUTH_DIALOG feature is set */ + GSList *flist = soup_session_get_features (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); + guint feature_is_set = g_slist_length(flist); + g_slist_free(flist); + + if (uzbl.behave.authentication_handler == NULL || *uzbl.behave.authentication_handler == 0) { + if (!feature_is_set) + soup_session_add_feature_by_type + (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); + } else { + if (feature_is_set) + soup_session_remove_feature_by_type + (uzbl.net.soup_session, (GType) WEBKIT_TYPE_SOUP_AUTH_DIALOG); + } + return; +} + +void +set_status_background() { + /* labels and hboxes do not draw their own background. applying this + * on the vbox/main_window is ok as the statusbar is the only affected + * widget. (if not, we could also use GtkEventBox) */ + GtkWidget* widget = uzbl.gui.main_window ? uzbl.gui.main_window : GTK_WIDGET (uzbl.gui.plug); + +#if GTK_CHECK_VERSION(2,91,0) + GdkRGBA color; + gdk_rgba_parse (&color, uzbl.behave.status_background); + gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &color); +#else + GdkColor color; + gdk_color_parse (uzbl.behave.status_background, &color); + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color); +#endif +} + +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); + } +} + +void +set_window_role() { + if (uzbl.gui.main_window) + gtk_window_set_role(GTK_WINDOW (uzbl.gui.main_window), uzbl.gui.window_role); +} + +void +set_geometry() { + int ret=0, x=0, y=0; + unsigned int w=0, h=0; + if(uzbl.gui.geometry) { + if(uzbl.gui.geometry[0] == 'm') { /* m/maximize/maximized */ + gtk_window_maximize((GtkWindow *)(uzbl.gui.main_window)); + } else { + /* we used to use gtk_window_parse_geometry() but that didn't work how it was supposed to */ + ret = XParseGeometry(uzbl.gui.geometry, &x, &y, &w, &h); + if(ret & XValue) + gtk_window_move((GtkWindow *)uzbl.gui.main_window, x, y); + if(ret & WidthValue) + gtk_window_resize((GtkWindow *)uzbl.gui.main_window, w, h); + } + } + + /* update geometry var with the actual geometry + this is necessary as some WMs don't seem to honour + the above setting and we don't want to end up with + wrong geometry information + */ + retrieve_geometry(); +} + +void +set_show_status() { + if (!uzbl.behave.show_status) + gtk_widget_hide(uzbl.gui.status_bar); + else + gtk_widget_show(uzbl.gui.status_bar); + + update_title(); +} + +void +set_status_top() { + if (!uzbl.gui.scrolled_win && !uzbl.gui.status_bar) + return; + + g_object_ref(uzbl.gui.scrolled_win); + g_object_ref(uzbl.gui.status_bar); + gtk_container_remove(GTK_CONTAINER(uzbl.gui.vbox), uzbl.gui.scrolled_win); + gtk_container_remove(GTK_CONTAINER(uzbl.gui.vbox), uzbl.gui.status_bar); + + if(uzbl.behave.status_top) { + gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.status_bar, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (uzbl.gui.vbox), uzbl.gui.scrolled_win, TRUE, TRUE, 0); + } else { + 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.status_bar, FALSE, TRUE, 0); + } + + g_object_unref(uzbl.gui.scrolled_win); + g_object_unref(uzbl.gui.status_bar); + + if (!uzbl.state.plug_mode) + gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); +} + +void +set_current_encoding() { + gchar *encoding = uzbl.behave.current_encoding; + if(strlen(encoding) == 0) + encoding = NULL; + + webkit_web_view_set_custom_encoding(uzbl.gui.web_view, encoding); +} + +void +cmd_fifo_dir() { + uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir); +} + +void +cmd_socket_dir() { + uzbl.behave.socket_dir = init_socket(uzbl.behave.socket_dir); +} + +void +cmd_inject_html() { + if(uzbl.behave.inject_html) { + webkit_web_view_load_html_string (uzbl.gui.web_view, + uzbl.behave.inject_html, NULL); + } +} + +void +cmd_useragent() { + if (*uzbl.net.useragent == ' ') { + g_free (uzbl.net.useragent); + uzbl.net.useragent = NULL; + } else { + g_object_set(G_OBJECT(uzbl.net.soup_session), SOUP_SESSION_USER_AGENT, + uzbl.net.useragent, NULL); + } +} + +void +set_accept_languages() { + if (*uzbl.net.accept_languages == ' ') { + g_free (uzbl.net.accept_languages); + uzbl.net.accept_languages = NULL; + } else { + g_object_set(G_OBJECT(uzbl.net.soup_session), + SOUP_SESSION_ACCEPT_LANGUAGE, uzbl.net.accept_languages, NULL); + } +} + +/* requires webkit >=1.1.14 */ +void +cmd_view_source() { + webkit_web_view_set_view_source_mode(uzbl.gui.web_view, + (gboolean) uzbl.behave.view_source); +} + +void +cmd_set_zoom_type () { + if(uzbl.behave.zoom_type) + webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, TRUE); + else + webkit_web_view_set_full_content_zoom (uzbl.gui.web_view, FALSE); +} + +/* abbreviations to help keep the table's width humane */ +#define PTR_V_STR(var, d, fun) { .ptr.s = &(var), .type = TYPE_STR, .dump = d, .writeable = 1, .func = fun } +#define PTR_V_INT(var, d, fun) { .ptr.i = (int*)&(var), .type = TYPE_INT, .dump = d, .writeable = 1, .func = fun } +#define PTR_V_FLOAT(var, d, fun) { .ptr.f = &(var), .type = TYPE_FLOAT, .dump = d, .writeable = 1, .func = fun } +#define PTR_C_STR(var, fun) { .ptr.s = &(var), .type = TYPE_STR, .dump = 0, .writeable = 0, .func = fun } +#define PTR_C_INT(var, fun) { .ptr.i = (int*)&(var), .type = TYPE_INT, .dump = 0, .writeable = 0, .func = fun } +#define PTR_C_FLOAT(var, fun) { .ptr.f = &(var), .type = TYPE_FLOAT, .dump = 0, .writeable = 0, .func = fun } + +const struct var_name_to_ptr_t { + const char *name; + uzbl_cmdprop cp; +} var_name_to_ptr[] = { +/* variable name pointer to variable in code dump callback function */ +/* ---------------------------------------------------------------------------------------------- */ + { "uri", PTR_V_STR(uzbl.state.uri, 1, cmd_load_uri)}, + { "verbose", PTR_V_INT(uzbl.state.verbose, 1, NULL)}, + { "print_events", PTR_V_INT(uzbl.state.events_stdout, 1, NULL)}, + { "inject_html", PTR_V_STR(uzbl.behave.inject_html, 0, cmd_inject_html)}, + { "geometry", PTR_V_STR(uzbl.gui.geometry, 1, set_geometry)}, + { "show_status", PTR_V_INT(uzbl.behave.show_status, 1, set_show_status)}, + { "status_top", PTR_V_INT(uzbl.behave.status_top, 1, set_status_top)}, + { "status_format", PTR_V_STR(uzbl.behave.status_format, 1, NULL)}, + { "status_format_right", PTR_V_STR(uzbl.behave.status_format_right, 1, NULL)}, + { "status_background", PTR_V_STR(uzbl.behave.status_background, 1, set_status_background)}, + { "title_format_long", PTR_V_STR(uzbl.behave.title_format_long, 1, NULL)}, + { "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)}, + { "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)}, + { "window_role", PTR_V_STR(uzbl.gui.window_role, 1, set_window_role)}, + { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, + { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, + { "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)}, + { "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)}, + { "fifo_dir", PTR_V_STR(uzbl.behave.fifo_dir, 1, cmd_fifo_dir)}, + { "socket_dir", PTR_V_STR(uzbl.behave.socket_dir, 1, cmd_socket_dir)}, + { "http_debug", PTR_V_INT(uzbl.behave.http_debug, 1, cmd_http_debug)}, + { "shell_cmd", PTR_V_STR(uzbl.behave.shell_cmd, 1, NULL)}, + { "proxy_url", PTR_V_STR(uzbl.net.proxy_url, 1, set_proxy_url)}, + { "max_conns", PTR_V_INT(uzbl.net.max_conns, 1, cmd_max_conns)}, + { "max_conns_host", PTR_V_INT(uzbl.net.max_conns_host, 1, cmd_max_conns_host)}, + { "useragent", PTR_V_STR(uzbl.net.useragent, 1, cmd_useragent)}, + { "accept_languages", PTR_V_STR(uzbl.net.accept_languages, 1, set_accept_languages)}, + { "javascript_windows", PTR_V_INT(uzbl.behave.javascript_windows, 1, cmd_javascript_windows)}, + /* requires webkit >=1.1.14 */ + { "view_source", PTR_V_INT(uzbl.behave.view_source, 0, cmd_view_source)}, + + /* exported WebKitWebSettings properties */ + { "zoom_level", PTR_V_FLOAT(uzbl.behave.zoom_level, 1, cmd_zoom_level)}, + { "zoom_type", PTR_V_INT(uzbl.behave.zoom_type, 1, cmd_set_zoom_type)}, + { "font_size", PTR_V_INT(uzbl.behave.font_size, 1, cmd_font_size)}, + { "default_font_family", PTR_V_STR(uzbl.behave.default_font_family, 1, cmd_default_font_family)}, + { "monospace_font_family", PTR_V_STR(uzbl.behave.monospace_font_family, 1, cmd_monospace_font_family)}, + { "cursive_font_family", PTR_V_STR(uzbl.behave.cursive_font_family, 1, cmd_cursive_font_family)}, + { "sans_serif_font_family", PTR_V_STR(uzbl.behave.sans_serif_font_family, 1, cmd_sans_serif_font_family)}, + { "serif_font_family", PTR_V_STR(uzbl.behave.serif_font_family, 1, cmd_serif_font_family)}, + { "fantasy_font_family", PTR_V_STR(uzbl.behave.fantasy_font_family, 1, cmd_fantasy_font_family)}, + { "monospace_size", PTR_V_INT(uzbl.behave.monospace_size, 1, cmd_font_size)}, + { "minimum_font_size", PTR_V_INT(uzbl.behave.minimum_font_size, 1, cmd_minimum_font_size)}, + { "enable_pagecache", PTR_V_INT(uzbl.behave.enable_pagecache, 1, cmd_enable_pagecache)}, + { "disable_plugins", PTR_V_INT(uzbl.behave.disable_plugins, 1, cmd_disable_plugins)}, + { "disable_scripts", PTR_V_INT(uzbl.behave.disable_scripts, 1, cmd_disable_scripts)}, + { "autoload_images", PTR_V_INT(uzbl.behave.autoload_img, 1, cmd_autoload_img)}, + { "autoshrink_images", PTR_V_INT(uzbl.behave.autoshrink_img, 1, cmd_autoshrink_img)}, + { "enable_spellcheck", PTR_V_INT(uzbl.behave.enable_spellcheck, 1, cmd_enable_spellcheck)}, + { "spellcheck_languages", PTR_V_STR(uzbl.behave.spellcheck_languages, 1, cmd_spellcheck_languages)}, + { "enable_private", PTR_V_INT(uzbl.behave.enable_private, 1, cmd_enable_private)}, + { "print_backgrounds", PTR_V_INT(uzbl.behave.print_bg, 1, cmd_print_bg)}, + { "stylesheet_uri", PTR_V_STR(uzbl.behave.style_uri, 1, cmd_style_uri)}, + { "resizable_text_areas", PTR_V_INT(uzbl.behave.resizable_txt, 1, cmd_resizable_txt)}, + { "default_encoding", PTR_V_STR(uzbl.behave.default_encoding, 1, cmd_default_encoding)}, + { "current_encoding", PTR_V_STR(uzbl.behave.current_encoding, 1, set_current_encoding)}, + { "enforce_96_dpi", PTR_V_INT(uzbl.behave.enforce_96dpi, 1, cmd_enforce_96dpi)}, + { "caret_browsing", PTR_V_INT(uzbl.behave.caret_browsing, 1, cmd_caret_browsing)}, + + /* constants (not dumpable or writeable) */ + { "WEBKIT_MAJOR", PTR_C_INT(uzbl.info.webkit_major, NULL)}, + { "WEBKIT_MINOR", PTR_C_INT(uzbl.info.webkit_minor, NULL)}, + { "WEBKIT_MICRO", PTR_C_INT(uzbl.info.webkit_micro, NULL)}, + { "ARCH_UZBL", PTR_C_STR(uzbl.info.arch, NULL)}, + { "COMMIT", PTR_C_STR(uzbl.info.commit, NULL)}, + { "TITLE", PTR_C_STR(uzbl.gui.main_title, NULL)}, + { "SELECTED_URI", PTR_C_STR(uzbl.state.selected_url, NULL)}, + { "NAME", PTR_C_STR(uzbl.state.instance_name, NULL)}, + { "PID", PTR_C_STR(uzbl.info.pid_str, NULL)}, + { "_", PTR_C_STR(uzbl.state.last_result, NULL)}, + + { NULL, {.ptr.s = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}} +}; + +/* construct a hash from the var_name_to_ptr array for quick access */ +void +variables_hash() { + const struct var_name_to_ptr_t *n2v_p = var_name_to_ptr; + uzbl.behave.proto_var = g_hash_table_new(g_str_hash, g_str_equal); + while(n2v_p->name) { + g_hash_table_insert(uzbl.behave.proto_var, + (gpointer) n2v_p->name, + (gpointer) &n2v_p->cp); + n2v_p++; + } +} diff --git a/src/variables.h b/src/variables.h new file mode 100644 index 0000000..6aa0ab0 --- /dev/null +++ b/src/variables.h @@ -0,0 +1,21 @@ +/* + * Uzbl Variables + */ + +#ifndef __VARIABLES__ +#define __VARIABLES__ + +#include <glib.h> +#include <webkit/webkit.h> + +gboolean set_var_value(const gchar *name, gchar *val); +void expand_variable(GString *buf, const gchar *name); +void variables_hash(); +void dump_config(); +void dump_config_as_events(); + +void uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec); +void set_show_status(); +void set_geometry(); + +#endif |