+setparameter(Client *c, int refresh, ParamName p, const Arg *a)
+{
+ GdkRGBA bgcolor = { 0 };
+ WebKitSettings *s = webkit_web_view_get_settings(c->view);
+
+ switch (p) {
+ case AcceleratedCanvas:
+ webkit_settings_set_enable_accelerated_2d_canvas(s, a->b);
+ break;
+ case CaretBrowsing:
+ webkit_settings_set_enable_caret_browsing(s, a->b);
+ refresh = 0;
+ break;
+ case Certificate:
+ if (a->b)
+ setcert(c, geturi(c));
+ return; /* do not update */
+ case CookiePolicies:
+ webkit_cookie_manager_set_accept_policy(
+ webkit_web_context_get_cookie_manager(
+ webkit_web_view_get_context(c->view)),
+ cookiepolicy_get());
+ refresh = 0;
+ break;
+ case DiskCache:
+ webkit_web_context_set_cache_model(
+ webkit_web_view_get_context(c->view), a->b ?
+ WEBKIT_CACHE_MODEL_WEB_BROWSER :
+ WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
+ return; /* do not update */
+ case DefaultCharset:
+ webkit_settings_set_default_charset(s, a->v);
+ return; /* do not update */
+ case DNSPrefetch:
+ webkit_settings_set_enable_dns_prefetching(s, a->b);
+ return; /* do not update */
+ case FontSize:
+ webkit_settings_set_default_font_size(s, a->i);
+ return; /* do not update */
+ case FrameFlattening:
+ webkit_settings_set_enable_frame_flattening(s, a->b);
+ break;
+ case Geolocation:
+ refresh = 0;
+ break;
+ case HideBackground:
+ if (a->b)
+ webkit_web_view_set_background_color(c->view, &bgcolor);
+ return; /* do not update */
+ case Inspector:
+ webkit_settings_set_enable_developer_extras(s, a->b);
+ return; /* do not update */
+ case Java:
+ webkit_settings_set_enable_java(s, a->b);
+ return; /* do not update */
+ case JavaScript:
+ webkit_settings_set_enable_javascript(s, a->b);
+ break;
+ case KioskMode:
+ return; /* do nothing */
+ case LoadImages:
+ webkit_settings_set_auto_load_images(s, a->b);
+ break;
+ case MediaManualPlay:
+ webkit_settings_set_media_playback_requires_user_gesture(s, a->b);
+ break;
+ case Plugins:
+ webkit_settings_set_enable_plugins(s, a->b);
+ break;
+ case PreferredLanguages:
+ return; /* do nothing */
+ case RunInFullscreen:
+ return; /* do nothing */
+ case ScrollBars:
+ /* Disabled until we write some WebKitWebExtension for
+ * manipulating the DOM directly.
+ enablescrollbars = !enablescrollbars;
+ evalscript(c, "document.documentElement.style.overflow = '%s'",
+ enablescrollbars ? "auto" : "hidden");
+ */
+ return; /* do not update */
+ case ShowIndicators:
+ break;
+ case SmoothScrolling:
+ webkit_settings_set_enable_smooth_scrolling(s, a->b);
+ return; /* do not update */
+ case SiteQuirks:
+ webkit_settings_set_enable_site_specific_quirks(s, a->b);
+ break;
+ case SpellChecking:
+ webkit_web_context_set_spell_checking_enabled(
+ webkit_web_view_get_context(c->view), a->b);
+ return; /* do not update */
+ case SpellLanguages:
+ return; /* do nothing */
+ case StrictTLS:
+ webkit_web_context_set_tls_errors_policy(
+ webkit_web_view_get_context(c->view), a->b ?
+ WEBKIT_TLS_ERRORS_POLICY_FAIL :
+ WEBKIT_TLS_ERRORS_POLICY_IGNORE);
+ break;
+ case Style:
+ if (a->b)
+ setstyle(c, getstyle(geturi(c)));
+ else
+ webkit_user_content_manager_remove_all_style_sheets(
+ webkit_web_view_get_user_content_manager(c->view));
+ refresh = 0;
+ break;
+ case ZoomLevel:
+ webkit_web_view_set_zoom_level(c->view, a->f);
+ return; /* do not update */
+ default:
+ return; /* do nothing */
+ }
+
+ updatetitle(c);
+ if (refresh)
+ reload(c, a);
+}
+
+const char *
+getcert(const char *uri)
+{
+ int i;
+
+ for (i = 0; i < LENGTH(certs); ++i) {
+ if (certs[i].regex &&
+ !regexec(&(certs[i].re), uri, 0, NULL, 0))
+ return certs[i].file;
+ }
+
+ return NULL;
+}
+
+void
+setcert(Client *c, const char *uri)
+{
+ const char *file = getcert(uri);
+ char *host;
+ GTlsCertificate *cert;
+
+ if (!file)
+ return;
+
+ if (!(cert = g_tls_certificate_new_from_file(file, NULL))) {
+ fprintf(stderr, "Could not read certificate file: %s\n", file);
+ return;
+ }
+
+ if ((uri = strstr(uri, "https://"))) {
+ uri += sizeof("https://") - 1;
+ host = g_strndup(uri, strchr(uri, '/') - uri);
+ webkit_web_context_allow_tls_certificate_for_host(
+ webkit_web_view_get_context(c->view), cert, host);
+ g_free(host);
+ }
+
+ g_object_unref(cert);
+
+}
+
+const char *
+getstyle(const char *uri)
+{
+ int i;
+
+ if (stylefile)
+ return stylefile;
+
+ for (i = 0; i < LENGTH(styles); ++i) {
+ if (styles[i].regex &&
+ !regexec(&(styles[i].re), uri, 0, NULL, 0))
+ return styles[i].file;
+ }
+
+ return "";
+}
+
+void
+setstyle(Client *c, const char *file)
+{
+ gchar *style;
+
+ if (!g_file_get_contents(file, &style, NULL, NULL)) {
+ fprintf(stderr, "Could not read style file: %s\n", file);
+ return;
+ }
+
+ webkit_user_content_manager_add_style_sheet(
+ webkit_web_view_get_user_content_manager(c->view),
+ webkit_user_style_sheet_new(style,
+ WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
+ WEBKIT_USER_STYLE_LEVEL_USER,
+ NULL, NULL));
+
+ g_free(style);
+}
+
+void
+runscript(Client *c)
+{
+ gchar *script;
+ gsize l;
+
+ if (g_file_get_contents(scriptfile, &script, &l, NULL) && l)
+ evalscript(c, script);
+ g_free(script);
+}
+
+void
+evalscript(Client *c, const char *jsstr, ...)
+{
+ va_list ap;
+ gchar *script;
+
+ va_start(ap, jsstr);
+ script = g_strdup_vprintf(jsstr, ap);
+ va_end(ap);
+
+ webkit_web_view_run_javascript(c->view, script, NULL, NULL, NULL);
+ g_free(script);
+}
+
+void
+updatewinid(Client *c)
+{
+ snprintf(winid, LENGTH(winid), "%lu", c->xid);
+}
+
+void
+handleplumb(Client *c, const char *uri)
+{
+ Arg a = (Arg)PLUMB(uri);
+ spawn(c, &a);
+}
+
+void
+newwindow(Client *c, const Arg *a, int noembed)
+{
+ int i = 0;
+ char tmp[64];
+ const char *cmd[29], *uri;
+ const Arg arg = { .v = cmd };
+
+ cmd[i++] = argv0;
+ cmd[i++] = "-a";
+ cmd[i++] = curconfig[CookiePolicies].val.v;
+ cmd[i++] = curconfig[ScrollBars].val.b ? "-B" : "-b";
+ if (cookiefile && g_strcmp0(cookiefile, "")) {
+ cmd[i++] = "-c";
+ cmd[i++] = cookiefile;
+ }
+ if (stylefile && g_strcmp0(stylefile, "")) {
+ cmd[i++] = "-C";
+ cmd[i++] = stylefile;
+ }
+ cmd[i++] = curconfig[DiskCache].val.b ? "-D" : "-d";
+ if (embed && !noembed) {
+ cmd[i++] = "-e";
+ snprintf(tmp, LENGTH(tmp), "%lu", embed);
+ cmd[i++] = tmp;
+ }
+ cmd[i++] = curconfig[RunInFullscreen].val.b ? "-F" : "-f" ;
+ cmd[i++] = curconfig[Geolocation].val.b ? "-G" : "-g" ;
+ cmd[i++] = curconfig[LoadImages].val.b ? "-I" : "-i" ;
+ cmd[i++] = curconfig[KioskMode].val.b ? "-K" : "-k" ;
+ cmd[i++] = curconfig[Style].val.b ? "-M" : "-m" ;
+ cmd[i++] = curconfig[Inspector].val.b ? "-N" : "-n" ;
+ cmd[i++] = curconfig[Plugins].val.b ? "-P" : "-p" ;
+ if (scriptfile && g_strcmp0(scriptfile, "")) {
+ cmd[i++] = "-r";
+ cmd[i++] = scriptfile;
+ }
+ cmd[i++] = curconfig[JavaScript].val.b ? "-S" : "-s";
+ cmd[i++] = curconfig[StrictTLS].val.b ? "-T" : "-t";
+ if (fulluseragent && g_strcmp0(fulluseragent, "")) {
+ cmd[i++] = "-u";
+ cmd[i++] = fulluseragent;
+ }
+ if (showxid)
+ cmd[i++] = "-w";
+ cmd[i++] = curconfig[Certificate].val.b ? "-X" : "-x" ;
+ /* do not keep zoom level */
+ cmd[i++] = "--";
+ if ((uri = a->v))
+ cmd[i++] = uri;
+ cmd[i] = NULL;
+
+ spawn(c, &arg);
+}
+
+void
+spawn(Client *c, const Arg *a)
+{
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
+ setsid();
+ execvp(((char **)a->v)[0], (char **)a->v);
+ fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]);
+ perror(" failed");
+ exit(1);
+ }
+}
+
+void
+destroyclient(Client *c)
+{
+ Client *p;
+
+ webkit_web_view_stop_loading(c->view);
+ /* Not needed, has already been called
+ gtk_widget_destroy(c->win);
+ */
+
+ for (p = clients; p && p->next != c; p = p->next)
+ ;
+ if (p)
+ p->next = c->next;
+ else
+ clients = c->next;
+ free(c);
+}
+
+void
+cleanup(void)
+{
+ while (clients)