Cleanup previous patch.
[surf.git] / surf.c
diff --git a/surf.c b/surf.c
index 5cb4824..baebe5c 100644 (file)
--- a/surf.c
+++ b/surf.c
@@ -21,7 +21,6 @@
 #include <sys/file.h>
 
 #define LENGTH(x)               (sizeof x / sizeof x[0])
-#define CLEANMASK(mask)         (mask & ~(GDK_MOD2_MASK))
 
 enum { AtomFind, AtomGo, AtomUri, AtomLast };
 
@@ -38,6 +37,7 @@ typedef struct Client {
        char *title, *linkhover;
        const char *uri, *needle;
        gint progress;
+       gboolean sslfailed;
        struct Client *next;
        gboolean zoomed;
 } Client;
@@ -87,7 +87,7 @@ static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c)
 static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
 static void loaduri(Client *c, const Arg *arg);
 static void navigate(Client *c, const Arg *arg);
-static Client *newclient(gboolean view);
+static Client *newclient(void);
 static void newwindow(Client *c, const Arg *arg);
 static void newrequest(SoupSession *s, SoupMessage *msg, gpointer v);
 static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
@@ -103,6 +103,7 @@ static void setup(void);
 static void sigchld(int unused);
 static void source(Client *c, const Arg *arg);
 static void spawn(Client *c, const Arg *arg);
+static void eval(Client *c, const Arg *arg);
 static void stop(Client *c, const Arg *arg);
 static void titlechange(WebKitWebView *v, WebKitWebFrame* frame, const char* title, Client *c);
 static void update(Client *c);
@@ -144,16 +145,25 @@ cleanup(void) {
        g_free(stylefile);
 }
 
+void
+evalscript(WebKitWebFrame *frame, JSContextRef js, char *script, char* scriptname) {
+       JSStringRef jsscript, jsscriptname;
+       JSValueRef exception = NULL;
+
+       jsscript = JSStringCreateWithUTF8CString(script);
+       jsscriptname = JSStringCreateWithUTF8CString(scriptname);
+       JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), jsscriptname, 0, &exception);
+       JSStringRelease(jsscript);
+       JSStringRelease(jsscriptname);
+}
+
 void
 runscript(WebKitWebFrame *frame, JSContextRef js) {
-       JSStringRef jsscript;
        char *script;
-       JSValueRef exception = NULL;
        GError *error;
-       
+
        if(g_file_get_contents(scriptfile, &script, NULL, &error)) {
-               jsscript = JSStringCreateWithUTF8CString(script);
-               JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), NULL, 0, &exception);
+               evalscript(frame, webkit_web_frame_get_global_context(frame), script, scriptfile);
        }
 }
 
@@ -181,7 +191,7 @@ copystr(char **str, const char *src) {
 
 WebKitWebView *
 createwindow(WebKitWebView  *v, WebKitWebFrame *f, Client *c) {
-       Client *n = newclient(TRUE);
+       Client *n = newclient();
        return n->view;
 }
 
@@ -211,6 +221,7 @@ void
 destroyclient(Client *c) {
        Client *p;
 
+       webkit_web_view_stop_loading(c->view);
        gtk_widget_destroy(c->indicator);
        gtk_widget_destroy(GTK_WIDGET(c->view));
        gtk_widget_destroy(c->scroll);
@@ -250,8 +261,11 @@ drawindicator(Client *c) {
        w = c->indicator;
        width = c->progress * w->allocation.width / 100;
        gc = gdk_gc_new(w->window);
-       gdk_color_parse(strstr(uri, "https://") == uri ?
-                       progress_trust : progress, &fg);
+       if(strstr(uri, "https://") == uri)
+               gdk_color_parse(c->sslfailed ?
+                               progress_untrust : progress_trust, &fg);
+       else
+               gdk_color_parse(progress, &fg);
        gdk_gc_set_rgb_fg_color(gc, &fg);
        gdk_draw_rectangle(w->window,
                        w->style->bg_gc[GTK_WIDGET_STATE(w)],
@@ -344,7 +358,7 @@ keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
        updatewinid(c);
        for(i = 0; i < LENGTH(keys); i++) {
                if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval
-                               && CLEANMASK(ev->state) == keys[i].mod
+                               && (ev->state & keys[i].mod) == keys[i].mod
                                && keys[i].func) {
                        keys[i].func(c, &(keys[i].arg));
                        processed = TRUE;
@@ -367,9 +381,24 @@ linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
 
 void
 loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
+       WebKitWebFrame *frame;
+       WebKitWebDataSource *src;
+       WebKitNetworkRequest *request;
+       SoupMessage *msg;
+       char *uri;
+
        switch(webkit_web_view_get_load_status (c->view)) {
        case WEBKIT_LOAD_COMMITTED:
-               setatom(c, AtomUri, geturi(c));
+               uri = geturi(c);
+               if(strstr(uri, "https://") == uri) {
+                       frame = webkit_web_view_get_main_frame(c->view);
+                       src = webkit_web_frame_get_data_source(frame);
+                       request = webkit_web_data_source_get_request(src);
+                       msg = webkit_network_request_get_message(request);
+                       c->sslfailed = soup_message_get_flags(msg)
+                                      ^ SOUP_MESSAGE_CERTIFICATE_TRUSTED;
+               }
+               setatom(c, AtomUri, uri);
                break;
        case WEBKIT_LOAD_FINISHED:
                c->progress = 0;
@@ -410,7 +439,7 @@ navigate(Client *c, const Arg *arg) {
 }
 
 Client *
-newclient(gboolean newview) {
+newclient(void) {
        Client *c;
        WebKitWebSettings *settings;
        WebKitWebFrame *frame;
@@ -432,7 +461,7 @@ newclient(gboolean newview) {
                 * window class (WM_CLASS) is capped, while the resource is in
                 * lowercase.   Both these values come as a pair.
                 */
-               gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "surf");
+               gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "Surf");
 
                /* TA:  20091214:  And set the role here as well -- so that
                 * sessions can pick this up.
@@ -454,18 +483,15 @@ newclient(gboolean newview) {
 
        /* Webview */
        c->view = WEBKIT_WEB_VIEW(webkit_web_view_new());
-       /* The widget to which the widget is added will handle the signals. */
-       if (!newview){
-               g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlechange), c);
-               g_signal_connect(G_OBJECT(c->view), "hovering-over-link", G_CALLBACK(linkhover), c);
-               g_signal_connect(G_OBJECT(c->view), "create-web-view", G_CALLBACK(createwindow), c);
-               g_signal_connect(G_OBJECT(c->view), "new-window-policy-decision-requested", G_CALLBACK(decidewindow), c);
-               g_signal_connect(G_OBJECT(c->view), "mime-type-policy-decision-requested", G_CALLBACK(decidedownload), c);
-               g_signal_connect(G_OBJECT(c->view), "window-object-cleared", G_CALLBACK(windowobjectcleared), c);
-               g_signal_connect(G_OBJECT(c->view), "notify::load-status", G_CALLBACK(loadstatuschange), c);
-               g_signal_connect(G_OBJECT(c->view), "notify::progress", G_CALLBACK(progresschange), c);
-               g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(initdownload), c);
-       }
+       g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlechange), c);
+       g_signal_connect(G_OBJECT(c->view), "hovering-over-link", G_CALLBACK(linkhover), c);
+       g_signal_connect(G_OBJECT(c->view), "create-web-view", G_CALLBACK(createwindow), c);
+       g_signal_connect(G_OBJECT(c->view), "new-window-policy-decision-requested", G_CALLBACK(decidewindow), c);
+       g_signal_connect(G_OBJECT(c->view), "mime-type-policy-decision-requested", G_CALLBACK(decidedownload), c);
+       g_signal_connect(G_OBJECT(c->view), "window-object-cleared", G_CALLBACK(windowobjectcleared), c);
+       g_signal_connect(G_OBJECT(c->view), "notify::load-status", G_CALLBACK(loadstatuschange), c);
+       g_signal_connect(G_OBJECT(c->view), "notify::progress", G_CALLBACK(progresschange), c);
+       g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(initdownload), c);
 
        /* Indicator */
        c->indicator = gtk_drawing_area_new();
@@ -509,7 +535,7 @@ newclient(gboolean newview) {
 
        setatom(c, AtomFind, "");
        setatom(c, AtomUri, "about:blank");
-       if(NOBACKGROUND)
+       if(HIDE_BACKGROUND)
                webkit_web_view_set_transparent(c->view, TRUE);
 
        c->title = NULL;
@@ -701,6 +727,10 @@ setup(void) {
        soup_session_remove_feature_by_type(s, soup_cookie_jar_get_type());
        g_signal_connect_after(G_OBJECT(s), "request-started", G_CALLBACK(newrequest), NULL);
 
+       /* ssl */
+       g_object_set(G_OBJECT(s), "ssl-ca-file", cafile, NULL);
+       g_object_set(G_OBJECT(s), "ssl-strict", strictssl, NULL);
+
        /* proxy */
        if((proxy = getenv("http_proxy")) && strcmp(proxy, "")) {
                new_proxy = g_strrstr(proxy, "http://") ? g_strdup(proxy) :
@@ -742,6 +772,12 @@ spawn(Client *c, const Arg *arg) {
        }
 }
 
+void
+eval(Client *c, const Arg *arg) {
+       WebKitWebFrame *frame = webkit_web_view_get_main_frame(c->view);
+       evalscript(frame, webkit_web_frame_get_global_context(frame), ((char **)arg->v)[0], "");
+}
+
 void
 stop(Client *c, const Arg *arg) {
        webkit_web_view_stop_loading(c->view);
@@ -839,7 +875,7 @@ main(int argc, char *argv[]) {
        if(i < argc)
                arg.v = argv[i];
        setup();
-       newclient(FALSE);
+       newclient();
        if(arg.v)
                loaduri(clients, &arg);
        gtk_main();