+static void clipboard(Client *c, const Arg *a);
+
+static WebKitCookieAcceptPolicy cookiepolicy_get(void);
+static char cookiepolicy_set(const WebKitCookieAcceptPolicy p);
+
+static char *copystr(char **str, const char *src);
+static GtkWidget *createview(WebKitWebView *v, WebKitNavigationAction *a,
+ Client *c);
+static gboolean decidepolicy(WebKitWebView *v, WebKitPolicyDecision *d,
+ WebKitPolicyDecisionType dt, Client *c);
+static void decidenavigation(WebKitPolicyDecision *d, Client *c);
+static void decidenewwindow(WebKitPolicyDecision *d, Client *c);
+static void decideresource(WebKitPolicyDecision *d, Client *c);
+static void closeview(WebKitWebView *v, Client *c);
+static void destroyclient(Client *c);
+static void destroywin(GtkWidget* w, Client *c);
+static void die(const char *errstr, ...);
+static void evalscript(Client *c, const char *jsstr, ...);
+static void runscript(Client *c);
+static void find(Client *c, const Arg *arg);
+static void togglefullscreen(Client *c, const Arg *a);
+static gboolean permissionrequested(WebKitWebView *v,
+ WebKitPermissionRequest *r, Client *c);
+static const char *getatom(Client *c, int a);
+static void gettogglestat(Client *c);
+static void getpagestat(Client *c);
+static char *geturi(Client *c);
+static const gchar *getstyle(const char *uri);
+static void setstyle(Client *c, const char *style);
+
+static void handleplumb(Client *c, const gchar *uri);
+
+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 inspector(Client *c, const Arg *arg);
+static WebKitWebView *inspector_new(WebKitWebInspector *i, WebKitWebView *v,
+ Client *c);
+static gboolean inspector_show(WebKitWebInspector *i, Client *c);
+static gboolean inspector_close(WebKitWebInspector *i, Client *c);
+static void inspector_finished(WebKitWebInspector *i, Client *c);
+
+static gboolean keypress(GtkAccelGroup *group, GObject *obj, guint key,
+ GdkModifierType mods, Client *c);
+static void mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h,
+ guint modifiers, Client *c);
+static void loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c);
+static void loaduri(Client *c, const Arg *arg);
+static void navigate(Client *c, const Arg *arg);
+static Client *newclient(Client *c);
+static WebKitWebView *newview(Client *c, WebKitWebView *rv);
+static void showview(WebKitWebView *v, Client *c);
+static void newwindow(Client *c, const Arg *arg, gboolean noembed);
+static GtkWidget *createwindow(Client *c);
+static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
+static void print(Client *c, const Arg *arg);
+static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
+ gpointer d);
+static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c);
+static void progresschanged(WebKitWebView *v, GParamSpec *ps, Client *c);
+static void linkopen(Client *c, const Arg *arg);
+static void linkopenembed(Client *c, const Arg *arg);
+static void reload(Client *c, const Arg *arg);
+static void scroll_h(Client *c, const Arg *arg);
+static void scroll_v(Client *c, const Arg *arg);
+static void scroll(GtkAdjustment *a, const Arg *arg);
+static void setatom(Client *c, int a, const char *v);
+static void setup(void);
+static void sigchld(int unused);
+static void spawn(Client *c, const Arg *arg);
+static void stop(Client *c, const Arg *arg);
+static void titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c);
+static void toggle(Client *c, const Arg *arg);
+static void togglecookiepolicy(Client *c, const Arg *arg);
+static void togglegeolocation(Client *c, const Arg *arg);
+static void togglescrollbars(Client *c, const Arg *arg);
+static void togglestyle(Client *c, const Arg *arg);
+static void updatetitle(Client *c);
+static void updatewinid(Client *c);
+static void usage(void);
+static void zoom(Client *c, const Arg *arg);
+
+/* configuration, allows nested code to access above variables */
+#include "config.h"
+
+void
+addaccelgroup(Client *c)
+{
+ int i;
+ GtkAccelGroup *group = gtk_accel_group_new();
+ GClosure *closure;
+
+ for (i = 0; i < LENGTH(keys); i++) {
+ closure = g_cclosure_new(G_CALLBACK(keypress), c, NULL);
+ gtk_accel_group_connect(group, keys[i].keyval, keys[i].mod, 0,
+ closure);
+ }
+ gtk_window_add_accel_group(GTK_WINDOW(c->win), group);
+}
+
+char *
+buildfile(const char *path)
+{
+ char *dname, *bname, *bpath, *fpath;
+ FILE *f;
+
+ dname = g_path_get_dirname(path);
+ bname = g_path_get_basename(path);
+
+ bpath = buildpath(dname);
+ g_free(dname);
+
+ fpath = g_build_filename(bpath, bname, NULL);
+ g_free(bpath);
+ g_free(bname);
+
+ if (!(f = fopen(fpath, "a")))
+ die("Could not open file: %s\n", fpath);
+
+ g_chmod(fpath, 0600); /* always */
+ fclose(f);
+
+ return fpath;
+}
+
+char *
+buildpath(const char *path)
+{
+ struct passwd *pw;
+ char *apath, *name, *p, *fpath;
+
+ if (path[0] == '~') {
+ if (path[1] == '/' || path[1] == '\0') {
+ p = (char *)&path[1];
+ pw = getpwuid(getuid());
+ } else {
+ if ((p = strchr(path, '/')))
+ name = g_strndup(&path[1], --p - path);
+ else
+ name = g_strdup(&path[1]);
+
+ if (!(pw = getpwnam(name))) {
+ die("Can't get user %s home directory: %s.\n",
+ name, path);
+ }
+ g_free(name);
+ }
+ apath = g_build_filename(pw->pw_dir, p, NULL);
+ } else {
+ apath = g_strdup(path);
+ }
+
+ /* creating directory */
+ if (g_mkdir_with_parents(apath, 0700) < 0)
+ die("Could not access directory: %s\n", apath);
+
+ fpath = realpath(apath, NULL);
+ g_free(apath);
+
+ return fpath;
+}