X-Git-Url: https://git.danieliu.xyz/?p=surf.git;a=blobdiff_plain;f=surf.c;h=6950dc5f69a61ebbc5917e17da2241f6c7810baf;hp=5ba6e514b925f8d972813be921b6a46e4aacf3c3;hb=0bd553a078cc8ec1d197fd7af96b07b1921049e2;hpb=a0ef4ba41d3e43618607f9cf1d14e83ee475f624 diff --git a/surf.c b/surf.c index 5ba6e51..6950dc5 100644 --- 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); @@ -204,6 +206,9 @@ static void downloadstarted(WebKitWebContext *wc, WebKitDownload *d, Client *c); static void responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c); static void download(Client *c, WebKitURIResponse *r); +static void webprocessterminated(WebKitWebView *v, + WebKitWebProcessTerminationReason r, + Client *c); static void closeview(WebKitWebView *v, Client *c); static void destroywin(GtkWidget* w, Client *c); @@ -241,6 +246,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 +378,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 +474,12 @@ getcurrentuserhomedir(void) char * buildpath(const char *path) { - char *apath, *name, *p, *fpath; - const char *homedir; + char *apath, *fpath; - 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]); - - 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 +491,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 +534,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 +545,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 +695,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 +728,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 +841,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 +941,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); } @@ -1064,6 +1079,7 @@ newview(Client *c, WebKitWebView *rv) WebKitSettings *settings; WebKitUserContentManager *contentmanager; WebKitWebContext *context; + WebKitCookieManager *cookiemanager; /* Webview */ if (rv) { @@ -1088,6 +1104,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 @@ -1109,6 +1126,8 @@ newview(Client *c, WebKitWebView *rv) "base-data-directory", cachedir, NULL)); + cookiemanager = webkit_web_context_get_cookie_manager(context); + /* rendering process model, can be a shared unique one * or one for each view */ webkit_web_context_set_process_model(context, @@ -1123,12 +1142,10 @@ newview(Client *c, WebKitWebView *rv) WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); /* Currently only works with text file to be compatible with curl */ - webkit_cookie_manager_set_persistent_storage( - webkit_web_context_get_cookie_manager(context), cookiefile, - WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); + webkit_cookie_manager_set_persistent_storage(cookiemanager, + cookiefile, WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT); /* cookie policy */ - webkit_cookie_manager_set_accept_policy( - webkit_web_context_get_cookie_manager(context), + webkit_cookie_manager_set_accept_policy(cookiemanager, cookiepolicy_get()); /* languages */ webkit_web_context_set_preferred_languages(context, @@ -1174,6 +1191,8 @@ newview(Client *c, WebKitWebView *rv) G_CALLBACK(permissionrequested), c); g_signal_connect(G_OBJECT(v), "ready-to-show", G_CALLBACK(showview), c); + g_signal_connect(G_OBJECT(v), "web-process-terminated", + G_CALLBACK(webprocessterminated), c); return v; } @@ -1319,6 +1338,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) @@ -1677,6 +1697,15 @@ download(Client *c, WebKitURIResponse *r) spawn(c, &a); } +void +webprocessterminated(WebKitWebView *v, WebKitWebProcessTerminationReason r, + Client *c) +{ + fprintf(stderr, "web process terminated: %s\n", + r == WEBKIT_WEB_PROCESS_CRASHED ? "crashed" : "no memory"); + closeview(v, c); +} + void closeview(WebKitWebView *v, Client *c) { @@ -1914,15 +1943,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 +1961,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 +2055,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();