Allow tilde expansion in loaduri
[surf.git] / surf.c
diff --git a/surf.c b/surf.c
index 5ba6e51..ae2bc81 100644 (file)
--- a/surf.c
+++ b/surf.c
@@ -79,6 +79,7 @@ typedef enum {
        SpellLanguages,
        StrictTLS,
        Style,
+       WebGL,
        ZoomLevel,
        ParameterLast
 } ParamName;
@@ -91,7 +92,7 @@ typedef union {
 
 typedef struct {
        Arg val;
-       int force;
+       int prio;
 } Parameter;
 
 typedef struct Client {
@@ -145,6 +146,7 @@ static void sigchld(int unused);
 static void sighup(int unused);
 static char *buildfile(const char *path);
 static char *buildpath(const char *path);
+static char *untildepath(const char *path);
 static const char *getuserhomedir(const char *user);
 static const char *getcurrentuserhomedir(void);
 static Client *newclient(Client *c);
@@ -241,6 +243,7 @@ static GdkDevice *gdkkb;
 static char *stylefile;
 static const char *useragent;
 static Parameter *curconfig;
+static int modparams[ParameterLast];
 char *argv0;
 
 static ParamName loadtransient[] = {
@@ -372,19 +375,18 @@ setup(void)
        }
 
        for (i = 0; i < LENGTH(uriparams); ++i) {
-               if (!regcomp(&(uriparams[i].re), uriparams[i].uri,
+               if (regcomp(&(uriparams[i].re), uriparams[i].uri,
                    REG_EXTENDED)) {
-                       /* copy default parameters if they are not already set
-                        * or if they are forced */
-                       for (j = 0; j < ParameterLast; ++j) {
-                               if (!uriparams[i].config[j].force ||
-                                   defconfig[j].force)
-                                       uriparams[i].config[j] = defconfig[j];
-                       }
-               } else {
                        fprintf(stderr, "Could not compile regex: %s\n",
                                uriparams[i].uri);
                        uriparams[i].uri = NULL;
+                       continue;
+               }
+
+               /* copy default parameters with higher priority */
+               for (j = 0; j < ParameterLast; ++j) {
+                       if (defconfig[j].prio >= uriparams[i].config[j].prio)
+                               uriparams[i].config[j] = defconfig[j];
                }
        }
 }
@@ -469,26 +471,12 @@ getcurrentuserhomedir(void)
 char *
 buildpath(const char *path)
 {
-       char *apath, *name, *p, *fpath;
-       const char *homedir;
-
-       if (path[0] == '~') {
-               if (path[1] == '/' || path[1] == '\0') {
-                       p = (char *)&path[1];
-                       homedir = getcurrentuserhomedir();
-               } else {
-                       if ((p = strchr(path, '/')))
-                               name = g_strndup(&path[1], --p - path);
-                       else
-                               name = g_strdup(&path[1]);
+       char *apath, *fpath;
 
-                       homedir = getuserhomedir(name);
-                       g_free(name);
-               }
-               apath = g_build_filename(homedir, p, NULL);
-       } else {
+       if (path[0] == '~')
+               apath = untildepath(path);
+       else
                apath = g_strdup(path);
-       }
 
        /* creating directory */
        if (g_mkdir_with_parents(apath, 0700) < 0)
@@ -500,6 +488,28 @@ buildpath(const char *path)
        return fpath;
 }
 
+char *
+untildepath(const char *path)
+{
+       char *apath, *name, *p;
+       const char *homedir;
+
+       if (path[1] == '/' || path[1] == '\0') {
+               p = (char *)&path[1];
+               homedir = getcurrentuserhomedir();
+       } else {
+               if ((p = strchr(path, '/')))
+                       name = g_strndup(&path[1], p - (path + 1));
+               else
+                       name = g_strdup(&path[1]);
+
+               homedir = getuserhomedir(name);
+               g_free(name);
+       }
+       apath = g_build_filename(homedir, p, NULL);
+       return apath;
+}
+
 Client *
 newclient(Client *rc)
 {
@@ -521,7 +531,7 @@ void
 loaduri(Client *c, const Arg *a)
 {
        struct stat st;
-       char *url, *path;
+       char *url, *path, *apath;
        const char *uri = a->v;
 
        if (g_strcmp0(uri, "") == 0)
@@ -532,11 +542,19 @@ loaduri(Client *c, const Arg *a)
            g_str_has_prefix(uri, "file://")  ||
            g_str_has_prefix(uri, "about:")) {
                url = g_strdup(uri);
-       } else if (!stat(uri, &st) && (path = realpath(uri, NULL))) {
-               url = g_strdup_printf("file://%s", path);
-               free(path);
        } else {
-               url = g_strdup_printf("http://%s", uri);
+               if (uri[0] == '~')
+                       apath = untildepath(uri);
+               else
+                       apath = (char *)uri;
+               if (!stat(apath, &st) && (path = realpath(apath, NULL))) {
+                       url = g_strdup_printf("file://%s", path);
+                       free(path);
+               } else {
+                       url = g_strdup_printf("http://%s", uri);
+               }
+               if (apath != uri)
+                       free(apath);
        }
 
        setatom(c, AtomUri, url);
@@ -674,42 +692,31 @@ cookiepolicy_set(const WebKitCookieAcceptPolicy p)
 void
 seturiparameters(Client *c, const char *uri, ParamName *params)
 {
-       Parameter *config, *newconfig = NULL;
+       Parameter *config, *uriconfig = NULL;
        int i, p;
 
        for (i = 0; i < LENGTH(uriparams); ++i) {
                if (uriparams[i].uri &&
                    !regexec(&(uriparams[i].re), uri, 0, NULL, 0)) {
-                       newconfig = uriparams[i].config;
+                       uriconfig = uriparams[i].config;
                        break;
                }
        }
 
-       if (!newconfig)
-               newconfig = defconfig;
+       curconfig = uriconfig ? uriconfig : defconfig;
 
        for (i = 0; (p = params[i]) != ParameterLast; ++i) {
                switch(p) {
+               default: /* FALLTHROUGH */
+                       if (!(defconfig[p].prio < curconfig[p].prio ||
+                           defconfig[p].prio < modparams[p]))
+                               continue;
                case Certificate:
                case CookiePolicies:
                case Style:
-                       config = defconfig[p].force ? defconfig :
-                                newconfig[p].force ? newconfig :
-                                defconfig;
-                       break;
-               default:
-                       if (defconfig[p].force)
-                               continue;
-                       config = newconfig[p].force ? newconfig :
-                                curconfig[p].force ? defconfig :
-                                NULL;
+                       setparameter(c, 0, p, &curconfig[p].val);
                }
-
-               if (config)
-                       setparameter(c, 0, p, &config[p].val);
        }
-
-       curconfig = newconfig;
 }
 
 void
@@ -718,6 +725,8 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
        GdkRGBA bgcolor = { 0 };
        WebKitSettings *s = webkit_web_view_get_settings(c->view);
 
+       modparams[p] = curconfig[p].prio;
+
        switch (p) {
        case AcceleratedCanvas:
                webkit_settings_set_enable_accelerated_2d_canvas(s, a->i);
@@ -829,6 +838,9 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
                        setstyle(c, getstyle(geturi(c)));
                refresh = 0;
                break;
+       case WebGL:
+               webkit_settings_set_enable_webgl(s, a->i);
+               break;
        case ZoomLevel:
                webkit_web_view_set_zoom_level(c->view, a->f);
                return; /* do not update */
@@ -926,7 +938,7 @@ runscript(Client *c)
        gsize l;
 
        if (g_file_get_contents(scriptfile, &script, &l, NULL) && l)
-               evalscript(c, script);
+               evalscript(c, "%s", script);
        g_free(script);
 }
 
@@ -1088,6 +1100,7 @@ newview(Client *c, WebKitWebView *rv)
                   "enable-accelerated-2d-canvas", curconfig[AcceleratedCanvas].val.i,
                   "enable-site-specific-quirks", curconfig[SiteQuirks].val.i,
                   "enable-smooth-scrolling", curconfig[SmoothScrolling].val.i,
+                  "enable-webgl", curconfig[WebGL].val.i,
                   "media-playback-requires-user-gesture", curconfig[MediaManualPlay].val.i,
                   NULL);
 /* For more interesting settings, have a look at
@@ -1319,6 +1332,7 @@ showview(WebKitWebView *v, Client *c)
        if (showxid) {
                gdk_display_sync(gtk_widget_get_display(c->win));
                puts(winid);
+               fflush(stdout);
        }
 
        if (curconfig[HideBackground].val.i)
@@ -1914,15 +1928,15 @@ main(int argc, char *argv[])
        ARGBEGIN {
        case 'a':
                defconfig[CookiePolicies].val.v = EARGF(usage());
-               defconfig[CookiePolicies].force = 1;
+               defconfig[CookiePolicies].prio = 2;
                break;
        case 'b':
                defconfig[ScrollBars].val.i = 0;
-               defconfig[ScrollBars].force = 1;
+               defconfig[ScrollBars].prio = 2;
                break;
        case 'B':
                defconfig[ScrollBars].val.i = 1;
-               defconfig[ScrollBars].force = 1;
+               defconfig[ScrollBars].prio = 2;
                break;
        case 'c':
                cookiefile = EARGF(usage());
@@ -1932,89 +1946,89 @@ main(int argc, char *argv[])
                break;
        case 'd':
                defconfig[DiskCache].val.i = 0;
-               defconfig[DiskCache].force = 1;
+               defconfig[DiskCache].prio = 2;
                break;
        case 'D':
                defconfig[DiskCache].val.i = 1;
-               defconfig[DiskCache].force = 1;
+               defconfig[DiskCache].prio = 2;
                break;
        case 'e':
                embed = strtol(EARGF(usage()), NULL, 0);
                break;
        case 'f':
                defconfig[RunInFullscreen].val.i = 0;
-               defconfig[RunInFullscreen].force = 1;
+               defconfig[RunInFullscreen].prio = 2;
                break;
        case 'F':
                defconfig[RunInFullscreen].val.i = 1;
-               defconfig[RunInFullscreen].force = 1;
+               defconfig[RunInFullscreen].prio = 2;
                break;
        case 'g':
                defconfig[Geolocation].val.i = 0;
-               defconfig[Geolocation].force = 1;
+               defconfig[Geolocation].prio = 2;
                break;
        case 'G':
                defconfig[Geolocation].val.i = 1;
-               defconfig[Geolocation].force = 1;
+               defconfig[Geolocation].prio = 2;
                break;
        case 'i':
                defconfig[LoadImages].val.i = 0;
-               defconfig[LoadImages].force = 1;
+               defconfig[LoadImages].prio = 2;
                break;
        case 'I':
                defconfig[LoadImages].val.i = 1;
-               defconfig[LoadImages].force = 1;
+               defconfig[LoadImages].prio = 2;
                break;
        case 'k':
                defconfig[KioskMode].val.i = 0;
-               defconfig[KioskMode].force = 1;
+               defconfig[KioskMode].prio = 2;
                break;
        case 'K':
                defconfig[KioskMode].val.i = 1;
-               defconfig[KioskMode].force = 1;
+               defconfig[KioskMode].prio = 2;
                break;
        case 'm':
                defconfig[Style].val.i = 0;
-               defconfig[Style].force = 1;
+               defconfig[Style].prio = 2;
                break;
        case 'M':
                defconfig[Style].val.i = 1;
-               defconfig[Style].force = 1;
+               defconfig[Style].prio = 2;
                break;
        case 'n':
                defconfig[Inspector].val.i = 0;
-               defconfig[Inspector].force = 1;
+               defconfig[Inspector].prio = 2;
                break;
        case 'N':
                defconfig[Inspector].val.i = 1;
-               defconfig[Inspector].force = 1;
+               defconfig[Inspector].prio = 2;
                break;
        case 'p':
                defconfig[Plugins].val.i = 0;
-               defconfig[Plugins].force = 1;
+               defconfig[Plugins].prio = 2;
                break;
        case 'P':
                defconfig[Plugins].val.i = 1;
-               defconfig[Plugins].force = 1;
+               defconfig[Plugins].prio = 2;
                break;
        case 'r':
                scriptfile = EARGF(usage());
                break;
        case 's':
                defconfig[JavaScript].val.i = 0;
-               defconfig[JavaScript].force = 1;
+               defconfig[JavaScript].prio = 2;
                break;
        case 'S':
                defconfig[JavaScript].val.i = 1;
-               defconfig[JavaScript].force = 1;
+               defconfig[JavaScript].prio = 2;
                break;
        case 't':
                defconfig[StrictTLS].val.i = 0;
-               defconfig[StrictTLS].force = 1;
+               defconfig[StrictTLS].prio = 2;
                break;
        case 'T':
                defconfig[StrictTLS].val.i = 1;
-               defconfig[StrictTLS].force = 1;
+               defconfig[StrictTLS].prio = 2;
                break;
        case 'u':
                fulluseragent = EARGF(usage());
@@ -2026,15 +2040,15 @@ main(int argc, char *argv[])
                break;
        case 'x':
                defconfig[Certificate].val.i = 0;
-               defconfig[Certificate].force = 1;
+               defconfig[Certificate].prio = 2;
                break;
        case 'X':
                defconfig[Certificate].val.i = 1;
-               defconfig[Certificate].force = 1;
+               defconfig[Certificate].prio = 2;
                break;
        case 'z':
                defconfig[ZoomLevel].val.f = strtof(EARGF(usage()), NULL);
-               defconfig[ZoomLevel].force = 1;
+               defconfig[ZoomLevel].prio = 2;
                break;
        default:
                usage();