Enable the insert mode. Thanks to stanio@cs.tu-berlin.de!
[surf.git] / surf.c
diff --git a/surf.c b/surf.c
index ae1a935..dcd0ad0 100644 (file)
--- a/surf.c
+++ b/surf.c
 #include <JavaScriptCore/JavaScript.h>
 #include <sys/file.h>
 
+#include "arg.h"
+
+char *argv0;
+
 #define LENGTH(x)               (sizeof x / sizeof x[0])
 #define COOKIEJAR_TYPE          (cookiejar_get_type ())
 #define COOKIEJAR(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar))
@@ -74,8 +78,9 @@ static Client *clients = NULL;
 static GdkNativeWindow embed = 0;
 static gboolean showxid = FALSE;
 static char winid[64];
-static char *progname;
-static gboolean loadimage = 1, plugin = 1, script = 1;
+static gboolean loadimage = 1, plugin = 1, script = 1, using_proxy = 0;
+static char togglestat[6];
+static gboolean insertmode = FALSE;
 
 static char *buildpath(const char *path);
 static gboolean buttonrelease(WebKitWebView *web, GdkEventButton *e, GList *gl);
@@ -98,6 +103,7 @@ static void find(Client *c, const Arg *arg);
 static const char *getatom(Client *c, int a);
 static char *geturi(Client *c);
 static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
+static void insert(Client *c, const Arg *arg);
 static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
 static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c);
 static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
@@ -123,6 +129,8 @@ 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 toggle(Client *c, const Arg *arg);
+static void gettogglestat(Client *c);
 static void update(Client *c);
 static void updatewinid(Client *c);
 static void usage(void);
@@ -138,10 +146,19 @@ buildpath(const char *path) {
        FILE *f;
 
        /* creating directory */
-       if(path[0] == '/')
+       if(path[0] == '/') {
                apath = g_strdup(path);
-       else
-               apath = g_strconcat(g_get_home_dir(), "/", path, NULL);
+       } else if(path[0] == '~') {
+               if(path[1] == '/') {
+                       apath = g_strconcat(g_get_home_dir(), &path[1], NULL);
+               } else {
+                       apath = g_strconcat(g_get_home_dir(), "/",
+                                       &path[1], NULL);
+               }
+       } else {
+               apath = g_strconcat(g_get_current_dir(), "/", path, NULL);
+       }
+
        if((p = strrchr(apath, '/'))) {
                *p = '\0';
                g_mkdir_with_parents(apath, 0700);
@@ -153,6 +170,7 @@ buildpath(const char *path) {
                g_chmod(apath, 0600); /* always */
                fclose(f);
        }
+
        return apath;
 }
 
@@ -216,7 +234,7 @@ cookiejar_new(const char *filename, gboolean read_only) {
        return g_object_new(COOKIEJAR_TYPE,
                            SOUP_COOKIE_JAR_TEXT_FILENAME, filename,
                            SOUP_COOKIE_JAR_READ_ONLY, read_only, NULL);
-} 
+}
 
 static void
 cookiejar_set_property(GObject *self, guint prop_id, const GValue *value, GParamSpec *pspec) {
@@ -333,6 +351,7 @@ void
 drawindicator(Client *c) {
        gint width;
        const char *uri;
+       char *colorname;
        GtkWidget *w;
        GdkGC *gc;
        GdkColor fg;
@@ -342,11 +361,20 @@ drawindicator(Client *c) {
        width = c->progress * w->allocation.width / 100;
        gc = gdk_gc_new(w->window);
        if(strstr(uri, "https://") == uri) {
-               gdk_color_parse(c->sslfailed ?
-                               progress_untrust : progress_trust, &fg);
+               if(using_proxy) {
+                       colorname = c->sslfailed? progress_proxy_untrust : progress_proxy_trust;
+               } else {
+                       colorname = c->sslfailed? progress_untrust : progress_trust;
+               }
        } else {
-               gdk_color_parse(progress, &fg);
+               if(using_proxy) {
+                       colorname = progress_proxy;
+               } else {
+                       colorname = progress;
+               }
        }
+
+       gdk_color_parse(colorname, &fg);
        gdk_gc_set_rgb_fg_color(gc, &fg);
        gdk_draw_rectangle(w->window,
                        w->style->bg_gc[GTK_WIDGET_STATE(w)],
@@ -409,20 +437,50 @@ initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
        return FALSE;
 }
 
+void
+insert(Client *c, const Arg *arg) {
+       insertmode = TRUE;
+       update(clients);
+}
+
 gboolean
 keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
-       guint i;
+       guint i, state;
        gboolean processed = FALSE;
 
+       /* turn off insert mode */
+       if(insertmode && (ev->keyval == GDK_Escape)) {
+               insertmode = FALSE;
+               update(c);
+               return TRUE;
+       }
+
+       if(insertmode && (((ev->state & MODKEY) != MODKEY) || !MODKEY)) {
+               return FALSE;
+       }
+
+       if(ev->keyval == GDK_Escape) {
+               webkit_web_view_set_highlight_text_matches(c->view, FALSE);
+               return TRUE;
+       }
+
        updatewinid(c);
        for(i = 0; i < LENGTH(keys); i++) {
+               if(!insertmode && (MODKEY & keys[i].mod)) {
+                       state = ev->state | MODKEY;
+               } else {
+                       state = ev->state;
+               }
+
                if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval
-                               && (ev->state & keys[i].mod) == keys[i].mod
                                && keys[i].func) {
-                       keys[i].func(c, &(keys[i].arg));
-                       processed = TRUE;
+                       if(state == keys[i].mod) {
+                               keys[i].func(c, &(keys[i].arg));
+                               processed = TRUE;
+                       }
                }
        }
+
        return processed;
 }
 
@@ -430,8 +488,7 @@ void
 linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
        if(l) {
                c->linkhover = copystr(&c->linkhover, l);
-       }
-       else if(c->linkhover) {
+       } else if(c->linkhover) {
                free(c->linkhover);
                c->linkhover = NULL;
        }
@@ -481,8 +538,7 @@ loaduri(Client *c, const Arg *arg) {
        /* prevents endless loop */
        if(c->uri && strcmp(u, c->uri) == 0) {
                reload(c, &a);
-       }
-       else {
+       } else {
                webkit_web_view_load_uri(c->view, u);
                c->progress = 0;
                c->title = copystr(&c->title, u);
@@ -618,7 +674,7 @@ newwindow(Client *c, const Arg *arg, gboolean noembed) {
        const Arg a = { .v = (void *)cmd };
        char tmp[64];
 
-       cmd[i++] = progname;
+       cmd[i++] = argv0;
        if(embed && !noembed) {
                cmd[i++] = "-e";
                snprintf(tmp, LENGTH(tmp), "%u\n", (int)embed);
@@ -816,6 +872,7 @@ setup(void) {
                g_object_set(G_OBJECT(s), "proxy-uri", puri, NULL);
                soup_uri_free(puri);
                g_free(new_proxy);
+               using_proxy = 1;
        }
 }
 
@@ -867,20 +924,59 @@ titlechange(WebKitWebView *v, WebKitWebFrame *f, const char *t, Client *c) {
        update(c);
 }
 
+void
+toggle(Client *c, const Arg *arg) {
+       WebKitWebSettings *settings;
+       char *name = (char *)arg->v;
+       gboolean value;
+       Arg a = { .b = FALSE };
+
+       settings = webkit_web_view_get_settings(c->view);
+       g_object_get(G_OBJECT(settings), name, &value, NULL);
+       g_object_set(G_OBJECT(settings), name, !value, NULL);
+
+       reload(c,&a);
+}
+
+void
+gettogglestat(Client *c){
+       gboolean value;
+       WebKitWebSettings *settings = webkit_web_view_get_settings(c->view);
+
+       togglestat[4] = '\0';
+       g_object_get(G_OBJECT(settings), "auto-load-images", &value, NULL);
+       togglestat[0] = value?'I':'i';
+       g_object_get(G_OBJECT(settings), "enable-scripts", &value, NULL);
+       togglestat[1] = value?'S':'s';
+       g_object_get(G_OBJECT(settings), "enable-plugins", &value, NULL);
+       togglestat[2] = value?'V':'v';
+       g_object_get(G_OBJECT(settings), "enable-caret-browsing",
+                       &value, NULL);
+       togglestat[3] = value?'C':'c';
+
+       togglestat[4] = insertmode? '+' : '-';
+       togglestat[5] = '\0';
+}
+
+
 void
 update(Client *c) {
        char *t;
 
+       gettogglestat(c);
+
        if(c->linkhover) {
-               t = g_strdup(c->linkhover);
+               t = g_strdup_printf("%s| %s", togglestat, c->linkhover);
        } else if(c->progress != 100) {
                drawindicator(c);
                gtk_widget_show(c->indicator);
-               t = g_strdup_printf("[%i%%] %s", c->progress, c->title);
+               t = g_strdup_printf("[%i%%] %s| %s", c->progress, togglestat,
+                               c->title);
        } else {
                gtk_widget_hide_all(c->indicator);
-               t = g_strdup(c->title);
+               t = g_strdup_printf("%s| %s", togglestat, c->title);
        }
+
        gtk_window_set_title(GTK_WINDOW(c->win), t);
        g_free(t);
 }
@@ -894,7 +990,8 @@ updatewinid(Client *c) {
 void
 usage(void) {
        fputs("surf - simple browser\n", stderr);
-       die("usage: surf [-e xid] [-i] [-p] [-s] [-v] [-x] [uri]\n");
+       die("usage: surf [-c cookiefile] [-e xid] [-i] [-p] [-r scriptfile]"
+               " [-s] [-t stylefile] [-u useragent] [-v] [-x] [uri]\n");
 }
 
 void
@@ -917,49 +1014,55 @@ zoom(Client *c, const Arg *arg) {
 
 int
 main(int argc, char *argv[]) {
-       int i;
        Arg arg;
 
-       progname = argv[0];
+       memset(&arg, 0, sizeof(arg));
+
        /* command line args */
-       for(i = 1, arg.v = NULL; i < argc && argv[i][0] == '-' &&
-                       argv[i][1] != '\0' && argv[i][2] == '\0'; i++) {
-               if(!strcmp(argv[i], "--")) {
-                       i++;
-                       break;
-               }
-               switch(argv[i][1]) {
-               case 'e':
-                       if(++i < argc)
-                               embed = strtol(argv[i], NULL, 0);
-                       else
-                               usage();
-                       break;
-               case 'i':
-                       loadimage = 0;
-                       break;
-               case 'p':
-                       plugin = 0;
-                       break;
-               case 's':
-                       script = 0;
-                       break;
-               case 'x':
-                       showxid = TRUE;
-                       break;
-               case 'v':
-                       die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n");
-               default:
-                       usage();
-               }
-       }
-       if(i < argc)
-               arg.v = argv[i];
+       ARGBEGIN {
+       case 'c':
+               cookiefile = EARGF(usage());
+               break;
+       case 'e':
+               embed = strtol(EARGF(usage()), NULL, 0);
+               break;
+       case 'i':
+               loadimage = 0;
+               break;
+       case 'p':
+               plugin = 0;
+               break;
+       case 'r':
+               scriptfile = EARGF(usage());
+               break;
+       case 's':
+               script = 0;
+               break;
+       case 't':
+               stylefile = EARGF(usage());
+               break;
+       case 'u':
+               useragent = EARGF(usage());
+               break;
+       case 'x':
+               showxid = TRUE;
+               break;
+       case 'v':
+               die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n");
+       default:
+               usage();
+       } ARGEND;
+       if(argc > 0)
+               arg.v = argv[0];
+
        setup();
        newclient();
        if(arg.v)
                loaduri(clients, &arg);
+
        gtk_main();
        cleanup();
+
        return EXIT_SUCCESS;
 }
+