diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/callbacks.c | 85 | ||||
-rw-r--r-- | src/callbacks.h | 6 | ||||
-rw-r--r-- | src/events.c | 7 | ||||
-rw-r--r-- | src/events.h | 5 | ||||
-rw-r--r-- | src/io.c | 11 | ||||
-rw-r--r-- | src/util.c | 176 | ||||
-rw-r--r-- | src/util.h | 6 | ||||
-rw-r--r-- | src/uzbl-core.c | 34 | ||||
-rw-r--r-- | src/uzbl-core.h | 14 |
9 files changed, 180 insertions, 164 deletions
diff --git a/src/callbacks.c b/src/callbacks.c index a40057c..deda426 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -291,6 +291,13 @@ cmd_caret_browsing() { } void +set_current_encoding() { + webkit_web_view_set_custom_encoding(uzbl.gui.web_view, + uzbl.behave.current_encoding); +} + + +void cmd_fifo_dir() { uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir); } @@ -448,29 +455,45 @@ void load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) param_spec; - WebKitWebFrame *frame = webkit_web_view_get_main_frame(web_view); + WebKitWebFrame *frame; WebKitLoadStatus status = webkit_web_view_get_load_status(web_view); switch(status) { case WEBKIT_LOAD_PROVISIONAL: - send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri ? uzbl.state.uri : "", NULL); + send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri ? uzbl.state.uri : "", NULL); break; case WEBKIT_LOAD_COMMITTED: - g_free (uzbl.state.uri); - GString* newuri = g_string_new (webkit_web_frame_get_uri (frame)); - uzbl.state.uri = g_string_free (newuri, FALSE); - g_setenv("UZBL_URI", uzbl.state.uri, TRUE); - + frame = webkit_web_view_get_main_frame(web_view); send_event(LOAD_COMMIT, NULL, TYPE_STR, webkit_web_frame_get_uri (frame), NULL); break; case WEBKIT_LOAD_FINISHED: - send_event(LOAD_FINISH, NULL, TYPE_STR, webkit_web_frame_get_uri(frame), NULL); + send_event(LOAD_FINISH, NULL, TYPE_STR, uzbl.state.uri, NULL); break; case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT: break; /* we don't do anything with this (yet) */ case WEBKIT_LOAD_FAILED: break; /* load_error_cb will handle this case */ } +} +void +load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud) { + (void) page; (void) frame; (void) ud; + GError *err = web_err; + + send_event (LOAD_ERROR, NULL, + TYPE_STR, uri, + 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); } void @@ -485,20 +508,6 @@ selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud) { } void -load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud) { - (void) page; - (void) frame; - (void) ud; - GError *err = web_err; - - send_event (LOAD_ERROR, NULL, - TYPE_STR, uri, - TYPE_INT, err->code, - TYPE_STR, err->message, - NULL); -} - -void destroy_cb (GtkWidget* widget, gpointer data) { (void) widget; (void) data; @@ -957,16 +966,28 @@ scroll_horiz_cb(GtkAdjustment *adjust, void *w) } void -run_menu_command(GtkWidget *menu, const char *line) { +run_menu_command(GtkWidget *menu, MenuItem *mi) { (void) menu; - parse_cmd_line(line, NULL); + if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { + gchar* uri; + g_object_get(mi->hittest, "image-uri", &uri, NULL); + gchar* cmd = g_strdup_printf("%s %s", mi->cmd, uri); + + parse_cmd_line(cmd, NULL); + + g_free(cmd); + g_free(uri); + g_object_unref(mi->hittest); + } + else { + parse_cmd_line(mi->cmd, NULL); + } } void populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { - (void) v; (void) c; GUI *g = &uzbl.gui; GtkWidget *item; @@ -981,11 +1002,19 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { if((context = get_click_context(NULL)) == -1) return; - for(i=0; i < uzbl.gui.menu_items->len; i++) { hit = 0; mi = g_ptr_array_index(uzbl.gui.menu_items, i); + if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { + GdkEventButton ev; + gint x, y; + gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(v)), &x, &y, NULL); + ev.x = x; + ev.y = y; + mi->hittest = webkit_web_view_get_hit_test_result(v, &ev); + } + if((mi->context > WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT) && (context & mi->context)) { if(mi->issep) { @@ -996,7 +1025,7 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { else { item = gtk_menu_item_new_with_label(mi->name); g_signal_connect(item, "activate", - G_CALLBACK(run_menu_command), mi->cmd); + G_CALLBACK(run_menu_command), mi); gtk_menu_shell_append(GTK_MENU_SHELL(m), item); gtk_widget_show(item); } @@ -1014,7 +1043,7 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { else { item = gtk_menu_item_new_with_label(mi->name); g_signal_connect(item, "activate", - G_CALLBACK(run_menu_command), mi->cmd); + G_CALLBACK(run_menu_command), mi); gtk_menu_shell_append(GTK_MENU_SHELL(m), item); gtk_widget_show(item); } diff --git a/src/callbacks.h b/src/callbacks.h index 13cb83d..d34b9fa 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -110,6 +110,9 @@ void cmd_default_encoding(); void +set_current_encoding(); + +void cmd_enforce_96dpi(); void @@ -158,6 +161,9 @@ void 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 diff --git a/src/events.c b/src/events.c index 174ff75..58dddfc 100644 --- a/src/events.c +++ b/src/events.c @@ -92,7 +92,7 @@ send_event_sockets(GPtrArray *sockets, GString *msg) { } } -static void +void replay_buffered_events() { guint i = 0; @@ -205,6 +205,7 @@ void key_to_event(guint keyval, gint mode) { gchar ucs[7]; gint ulen; + gchar *keyname; guint32 ukval = gdk_keyval_to_unicode(keyval); /* check for printable unicode char */ @@ -219,9 +220,9 @@ key_to_event(guint keyval, gint mode) { NULL, TYPE_FORMATTEDSTR, ucs, NULL); } /* send keysym for non-printable chars */ - else { + else if((keyname = gdk_keyval_name(keyval))){ send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_NAME, gdk_keyval_name(keyval), NULL); + NULL, TYPE_NAME, keyname , NULL); } } diff --git a/src/events.h b/src/events.h index 8e75097..bd519a6 100644 --- a/src/events.h +++ b/src/events.h @@ -33,10 +33,7 @@ void event_buffer_timeout(guint sec); void -send_event_socket(GString *msg); - -void -send_event_stdout(GString *msg); +replay_buffered_events(); void vsend_event(int type, const gchar *custom_event, va_list vargs); @@ -123,9 +123,14 @@ control_stdin(GIOChannel *gio, GIOCondition condition) { if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) return FALSE; - parse_cmd_line(ctl_line, NULL); + GString *result = g_string_new(""); + + parse_cmd_line(ctl_line, result); g_free(ctl_line); + puts(result->str); + g_string_free(result, TRUE); + return TRUE; } @@ -211,8 +216,8 @@ init_connect_socket() { } /* replay buffered events */ - if(replay) - send_event_socket(NULL); + if(replay && uzbl.state.event_buffer) + replay_buffered_events(); } @@ -6,6 +6,8 @@ #include "util.h" +gchar* find_existing_file2(gchar *, const gchar *); + const XDG_Var XDG[] = { { "XDG_CONFIG_HOME", "~/.config" }, { "XDG_DATA_HOME", "~/.local/share" }, @@ -16,56 +18,41 @@ const XDG_Var XDG[] = { /*@null@*/ gchar* get_xdg_var (XDG_Var xdg) { - const gchar* actual_value = getenv (xdg.environmental); - const gchar* home = getenv ("HOME"); - gchar* return_value; - - if (! actual_value || strcmp (actual_value, "") == 0) { - if (xdg.default_value) { - return_value = str_replace ("~", home, xdg.default_value); - } else { - return_value = NULL; - } - } else { - return_value = str_replace("~", home, actual_value); - } + const gchar *actual_value = getenv(xdg.environmental); + const gchar *home = getenv("HOME"); + + if (!actual_value || !actual_value[0]) + actual_value = xdg.default_value; - return return_value; + if (!actual_value) + return NULL; + + return str_replace("~", home, actual_value); } /*@null@*/ gchar* -find_xdg_file (int xdg_type, const char* filename) { +find_xdg_file (int xdg_type, const char* basename) { /* xdg_type = 0 => config xdg_type = 1 => data - xdg_type = 2 => cache*/ + xdg_type = 2 => cache */ - gchar* xdgv = get_xdg_var (XDG[xdg_type]); - gchar* temporary_file = g_strconcat (xdgv, filename, NULL); + gchar *xdgv = get_xdg_var(XDG[xdg_type]); + gchar *path = g_strconcat (xdgv, basename, NULL); g_free (xdgv); - gchar* temporary_string; - char* saveptr; - char* buf; - - if (! file_exists (temporary_file) && xdg_type != 2) { - buf = get_xdg_var (XDG[3 + xdg_type]); - temporary_string = (char *) strtok_r (buf, ":", &saveptr); - g_free(buf); + if (file_exists(path)) + return path; - while ((temporary_string = (char * ) strtok_r (NULL, ":", &saveptr)) && ! file_exists (temporary_file)) { - g_free (temporary_file); - temporary_file = g_strconcat (temporary_string, filename, NULL); - } - } + if (xdg_type == 2) + return NULL; - //g_free (temporary_string); - segfaults. + /* the file doesn't exist in the expected directory. + * check if it exists in one of the system-wide directories. */ + char *system_dirs = get_xdg_var(XDG[3 + xdg_type]); + path = find_existing_file2(system_dirs, basename); + g_free(system_dirs); - if (file_exists (temporary_file)) { - return temporary_file; - } else { - g_free(temporary_file); - return NULL; - } + return path; } gboolean @@ -95,85 +82,66 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); - if (chan) { - while (g_io_channel_read_line(chan, &line, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { - callback(line, user_data); - g_free(line); - } - g_io_channel_unref (chan); + if (!chan) + return FALSE; - return TRUE; + while (g_io_channel_read_line(chan, &line, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { + callback(line, user_data); + g_free(line); } - return FALSE; -} + g_io_channel_unref (chan); -enum exp_type -get_exp_type(const gchar *s) { - /* variables */ - if(*(s+1) == '(') - return EXP_EXPR; - else if(*(s+1) == '{') - return EXP_BRACED_VAR; - else if(*(s+1) == '<') - return EXP_JS; - else if(*(s+1) == '[') - return EXP_ESCAPE; - else - return EXP_SIMPLE_VAR; - - /*@notreached@*/ -return EXP_ERR; + return TRUE; } - -/* search a PATH style string for an existing file+path combination */ +/* This function searches the directories in the : separated ($PATH style) + * string 'dirs' for a file named 'basename'. It returns the path of the first + * file found, or NULL if none could be found. + * NOTE: this function modifies the 'dirs' argument. */ gchar* -find_existing_file(gchar* path_list) { - int i=0; - int cnt; - gchar **split; - gchar *tmp = NULL; - gchar *executable; +find_existing_file2(gchar *dirs, const gchar *basename) { + char *saveptr = NULL; + + /* iterate through the : separated elements until we find our file. */ + char *tok = strtok_r(dirs, ":", &saveptr); + char *path = g_strconcat (tok, "/", basename, NULL); + + while (!file_exists(path)) { + g_free(path); + + tok = strtok_r(NULL, ":", &saveptr); + if (!tok) + return NULL; /* we've hit the end of the string */ + path = g_strconcat (tok, "/", basename, NULL); + } + + return path; +} + +/* search a PATH style string for an existing file+path combination. + * everything after the last ':' is assumed to be the name of the file. + * e.g. "/tmp:/home:a/file" will look for /tmp/a/file and /home/a/file. + * + * if there are no :s then the entire thing is taken to be the path. */ +gchar* +find_existing_file(const gchar* path_list) { if(!path_list) return NULL; - split = g_strsplit(path_list, ":", 0); - while(split[i]) - i++; + char *path_list_dup = g_strdup(path_list); - if(i<=1) { - tmp = g_strdup(split[0]); - g_strfreev(split); - return tmp; - } - else - cnt = i-1; - - i=0; - tmp = g_strdup(split[cnt]); - g_strstrip(tmp); - if(tmp[0] == '/') - executable = g_strdup_printf("%s", tmp+1); - else - executable = g_strdup(tmp); - g_free(tmp); - - while(i<cnt) { - tmp = g_strconcat(g_strstrip(split[i]), "/", executable, NULL); - if(g_file_test(tmp, G_FILE_TEST_EXISTS)) { - g_strfreev(split); - return tmp; - } - else - g_free(tmp); - i++; - } + char *basename = strrchr(path_list_dup, ':'); + if(!basename) + return path_list_dup; + + basename[0] = '\0'; + basename++; - g_free(executable); - g_strfreev(split); - return NULL; + char *result = find_existing_file2(path_list_dup, basename); + g_free(path_list_dup); + return result; } gchar* @@ -6,16 +6,12 @@ typedef struct { gchar* default_value; } XDG_Var; -enum exp_type {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE}; - - gchar* get_xdg_var(XDG_Var xdg); gchar* find_xdg_file(int xdg_type, const char* filename); gboolean file_exists(const char* filename); char* str_replace(const char* search, const char* replace, const char* string); gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); -enum exp_type get_exp_type(const gchar*); -gchar* find_existing_file(gchar*); +gchar* find_existing_file(const gchar*); gchar* argv_idx(const GArray*, const guint); /** * appends `src' to `dest' with backslash, single-quotes and newlines in diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 26b3dba..d73fbdf 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -131,6 +131,7 @@ const struct var_name_to_ptr_t { { "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)}, @@ -165,6 +166,20 @@ create_var_to_name_hash() { /* --- UTILITY FUNCTIONS --- */ +enum exp_type { + EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE +}; + +enum exp_type +get_exp_type(const gchar *s) { + switch(*(s+1)) { + case '(': return EXP_EXPR; + case '{': return EXP_BRACED_VAR; + case '<': return EXP_JS; + case '[': return EXP_ESCAPE; + default: return EXP_SIMPLE_VAR; + } +} /* * recurse == 1: don't expand '@(command)@' @@ -608,6 +623,9 @@ 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); @@ -720,7 +738,8 @@ act_dump_config_as_events() { void load_uri(WebKitWebView *web_view, GArray *argv, GString *result) { (void) web_view; (void) result; - set_var_value("uri", argv_idx(argv, 0)); + gchar * uri = argv_idx(argv, 0); + set_var_value("uri", uri ? uri : ""); } /* Javascript*/ @@ -744,7 +763,7 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result, const char *fi js_script = JSStringCreateWithUTF8CString(script); js_file = JSStringCreateWithUTF8CString(file); js_result = JSEvaluateScript(context, js_script, globalobject, js_file, 0, &js_exc); - if (js_result && !JSValueIsUndefined(context, js_result)) { + if (result && js_result && !JSValueIsUndefined(context, js_result)) { js_result_string = JSValueToStringCopy(context, js_result, NULL); js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string); @@ -1143,8 +1162,10 @@ parse_command_parts(const gchar *line, GArray *a) { CommandInfo *c = NULL; gchar *exp_line = expand(line, 0); - if(exp_line[0] == '\0') + if(exp_line[0] == '\0') { + g_free(exp_line); return NULL; + } /* separate the line into the command and its parameters */ gchar **tokens = g_strsplit(exp_line, " ", 2); @@ -1212,7 +1233,8 @@ move_statusbar() { } g_object_unref(uzbl.gui.scrolled_win); g_object_unref(uzbl.gui.mainbar); - gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); + if (!uzbl.state.plug_mode) + gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); return; } @@ -1258,6 +1280,8 @@ set_var_value(const gchar *name, gchar *val) { 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; @@ -1370,7 +1394,6 @@ update_title(void) { } } - void create_scrolled_win() { GUI* g = &uzbl.gui; @@ -1399,6 +1422,7 @@ create_scrolled_win() { "signal::selection-changed", (GCallback)selection_changed_cb, NULL, "signal::notify::progress", (GCallback)progress_change_cb, NULL, "signal::notify::load-status", (GCallback)load_status_change_cb, NULL, + "signal::notify::uri", (GCallback)uri_change_cb, NULL, "signal::load-error", (GCallback)load_error_cb, NULL, "signal::hovering-over-link", (GCallback)link_hover_cb, NULL, "signal::navigation-policy-decision-requested", (GCallback)navigation_decision_cb, NULL, diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 3240fc6..766fe56 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -165,7 +165,6 @@ typedef struct { gchar* cursive_font_family; gboolean forward_keys; - guint modmask; guint http_debug; gchar* shell_cmd; guint view_source; @@ -187,12 +186,11 @@ typedef struct { gchar* style_uri; guint resizable_txt; gchar* default_encoding; + gchar* current_encoding; guint enforce_96dpi; gchar *inject_html; guint caret_browsing; guint javascript_windows; - guint mode; - gchar* base_url; gboolean print_version; /* command list: (key)name -> (value)Command */ @@ -203,14 +201,6 @@ typedef struct { } Behaviour; -/* Javascript */ -typedef struct { - gboolean initialized; - JSClassDefinition classdef; - JSClassRef classref; -} Javascript; - - /* Static information */ typedef struct { int webkit_major; @@ -229,7 +219,6 @@ typedef struct { Network net; Behaviour behave; Communication comm; - Javascript js; Info info; Window xwin; @@ -362,6 +351,7 @@ typedef struct { gchar* cmd; gboolean issep; guint context; + WebKitHitTestResult* hittest; } MenuItem; #endif |