merge in sm217s cookie code (which is work in progress)
[uzbl-mobile] / uzbl.c
diff --git a/uzbl.c b/uzbl.c
index 161769b..99ae5a2 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
@@ -40,8 +40,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/un.h>
+#include <sys/utsname.h>
 #include <webkit/webkit.h>
-#include <pthread.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <libsoup/soup.h>
 #include "uzbl.h"
 
+
+/* status bar format
+   TODO: integrate with the config file
+*/
+char *status_format =  "<span background=\"darkgreen\" foreground=\"khaki\"> MODE </span> | Cmd: <span background=\"red\" foreground=\"white\">KEYCMD</span> | <span background=\"darkblue\" foreground=\"white\">  <b>TITLE</b>  </span> | LOAD_PROGRESS% <span font_family=\"monospace\">LOAD_PROGRESSBAR</span> | <span foreground=\"darkgreen\">URI</span> | NAME | <span foreground=\"black\" background=\"khaki\"> Uzbl browser </span>";
+
 /* housekeeping / internal variables */
-static GtkWidget*     main_window;
-static GtkWidget*     mainbar;
-static GtkWidget*     mainbar_label;
-static GtkScrollbar*  scbar_v;   // Horizontal and Vertical Scrollbar 
-static GtkScrollbar*  scbar_h;   // (These are still hidden)
-static GtkAdjustment* bar_v; // Information about document length
-static GtkAdjustment* bar_h; // and scrolling position
-static WebKitWebView* web_view;
-static gchar*         main_title;
 static gchar          selected_url[500] = "\0";
-static gint           load_progress;
-static Window         xwin = 0;
-static char           fifo_path[64];
-static char           socket_path[108];
 static char           executable_path[500];
 static GString*       keycmd;
+static gchar          searchtx[500] = "\0";
 
-/* state variables (initial values coming from command line arguments but may be changed later) */
-static gchar*   uri         = NULL;
-static gchar*   config_file = NULL;
-static gchar    config_file_path[500];
-static gboolean verbose     = FALSE;
+static Uzbl uzbl;
 
 /* settings from config: group behaviour */
 static gchar*   history_handler    = NULL;
 static gchar*   fifo_dir           = NULL;
 static gchar*   socket_dir         = NULL;
 static gchar*   download_handler   = NULL;
+static gchar*   cookie_handler     = NULL;
 static gboolean always_insert_mode = FALSE;
 static gboolean show_status        = FALSE;
 static gboolean insert_mode        = FALSE;
@@ -90,7 +81,10 @@ static gboolean status_top         = FALSE;
 static gchar*   modkey             = NULL;
 static guint    modmask            = 0;
 static guint    http_debug         = 0;
-static gchar*   cookie_handler     = NULL;
+
+/* System info */
+static struct utsname unameinfo;
+
 /* settings from config: group bindings, key -> action */
 static GHashTable* bindings;
 
@@ -100,9 +94,9 @@ static GHashTable* commands;
 /* commandline arguments (set initial values for the state variables) */
 static GOptionEntry entries[] =
 {
-    { "uri",     'u', 0, G_OPTION_ARG_STRING, &uri,         "Uri to load", NULL },
-    { "verbose", 'v', 0, G_OPTION_ARG_NONE,   &verbose,     "Be verbose",  NULL },
-    { "config",  'c', 0, G_OPTION_ARG_STRING, &config_file, "Config file", NULL },
+    { "uri",     'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri,           "Uri to load", "URI" },
+    { "name",    'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name, "Name of the current instance", "NAME" },
+    { "config",  'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file,   "Config file", "FILE" },
     { NULL,      0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -112,15 +106,21 @@ typedef void (*Command)(WebKitWebView*, const char *);
 static char *XDG_CONFIG_HOME_default[256];
 static char *XDG_CONFIG_DIRS_default = "/etc/xdg";
 
-/* libsoup stuff - proxy and friends; networking aptions actually */
-static SoupSession *soup_session;
-static SoupLogger *soup_logger;
-static char *proxy_url = NULL;
-static char *useragent = NULL;
-static gint max_conns;
-static gint max_conns_host;
-static SoupCookieJar *ck;
-static char* current_req = NULL;
+
+/* --- UTILITY FUNCTIONS --- */
+
+char *
+itos(int val) {
+    char tmp[20];
+
+    snprintf(tmp, sizeof(tmp), "%i", val);
+    return g_strdup(tmp);
+}
+
+static char *
+str_replace (const char* search, const char* replace, const char* string) {
+    return g_strjoinv (replace, g_strsplit(string, search, -1));
+}
 
 /* --- CALLBACKS --- */
 
@@ -180,13 +180,13 @@ scroll (GtkAdjustment* bar, const char *param) {
 static void scroll_vert(WebKitWebView* page, const char *param) {
     (void) page;
 
-    scroll(bar_v, param);
+    scroll(uzbl.gui.bar_v, param);
 }
 
 static void scroll_horz(WebKitWebView* page, const char *param) {
     (void) page;
 
-    scroll(bar_h, param);
+    scroll(uzbl.gui.bar_h, param);
 }
 
 static void
@@ -195,9 +195,9 @@ toggle_status_cb (WebKitWebView* page, const char *param) {
     (void)param;
 
     if (show_status) {
-        gtk_widget_hide(mainbar);
+        gtk_widget_hide(uzbl.gui.mainbar);
     } else {
-        gtk_widget_show(mainbar);
+        gtk_widget_show(uzbl.gui.mainbar);
     }
     show_status = !show_status;
     update_title();
@@ -221,9 +221,9 @@ title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar
     (void) web_view;
     (void) web_frame;
     (void) data;
-    if (main_title)
-        g_free (main_title);
-    main_title = g_strdup (title);
+    if (uzbl.gui.main_title)
+        g_free (uzbl.gui.main_title);
+    uzbl.gui.main_title = g_strdup (title);
     update_title();
 }
 
@@ -231,7 +231,7 @@ static void
 progress_change_cb (WebKitWebView* page, gint progress, gpointer data) {
     (void) page;
     (void) data;
-    load_progress = progress;
+    uzbl.gui.sbar.load_progress = progress;
     update_title();
 }
 
@@ -239,9 +239,9 @@ static void
 load_commit_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data) {
     (void) page;
     (void) data;
-    free (uri);
+    free (uzbl.state.uri);
     GString* newuri = g_string_new (webkit_web_frame_get_uri (frame));
-    uri = g_string_free (newuri, FALSE);
+    uzbl.state.uri = g_string_free (newuri, FALSE);
 }
 
 static void
@@ -267,10 +267,11 @@ log_history_cb () {
    }
 }
 
-/* VIEW funcs (little webkit wrappers) */
 
+/* VIEW funcs (little webkit wrappers) */
 #define VIEWFUNC(name) static void view_##name(WebKitWebView *page, const char *param){(void)param; webkit_web_view_##name(page);}
 VIEWFUNC(reload)
+VIEWFUNC(reload_bypass_cache)
 VIEWFUNC(stop_loading)
 VIEWFUNC(zoom_in)
 VIEWFUNC(zoom_out)
@@ -283,20 +284,22 @@ VIEWFUNC(go_forward)
 
 static struct {char *name; Command command;} cmdlist[] =
 {
-    { "back",          view_go_back       },
-    { "forward",       view_go_forward    },
-    { "scroll_vert",   scroll_vert        },
-    { "scroll_horz",   scroll_horz        },
-    { "reload",        view_reload,       }, //Buggy
-    { "refresh",       view_reload,       }, /* for convenience, will change */
-    { "stop",          view_stop_loading, },
-    { "zoom_in",       view_zoom_in,      }, //Can crash (when max zoom reached?).
-    { "zoom_out",      view_zoom_out,     },
-    { "uri",           load_uri           },
-    { "toggle_status", toggle_status_cb   },
-    { "spawn",         spawn              },
-    { "exit",          close_uzbl         },
-    { "insert_mode",   set_insert_mode    }
+    { "back",             view_go_back            },
+    { "forward",          view_go_forward         },
+    { "scroll_vert",      scroll_vert             },
+    { "scroll_horz",      scroll_horz             },
+    { "reload",           view_reload,            }, 
+    { "reload_ign_cache", view_reload_bypass_cache},
+    { "stop",             view_stop_loading,      },
+    { "zoom_in",          view_zoom_in,           }, //Can crash (when max zoom reached?).
+    { "zoom_out",         view_zoom_out,          },
+    { "uri",              load_uri                },
+    { "script",           run_js                  },
+    { "toggle_status",    toggle_status_cb        },
+    { "spawn",            spawn                   },
+    { "exit",             close_uzbl              },
+    { "search",           search_text             },
+    { "insert_mode",      set_insert_mode         }
 };
 
 static void
@@ -365,6 +368,26 @@ load_uri (WebKitWebView * web_view, const gchar *param) {
 }
 
 static void
+run_js (WebKitWebView * web_view, const gchar *param) {
+    if (param)
+        webkit_web_view_execute_script (web_view, param);
+}
+
+static void
+search_text (WebKitWebView *page, const char *param) {
+    if ((param) && (param[0] != '\0')) {
+        strcpy(searchtx, param);
+    }
+    if (searchtx[0] != '\0') {
+        printf ("Searching: %s\n", searchtx);
+        webkit_web_view_unmark_text_matches (page);
+        webkit_web_view_mark_text_matches (page, searchtx, FALSE, 0);
+        webkit_web_view_set_highlight_text_matches (page, TRUE);
+        webkit_web_view_search_text (page, searchtx, FALSE, TRUE, TRUE);
+    }
+}
+
+static void
 new_window_load_uri (const gchar * uri) {
     GString* to_execute = g_string_new ("");
     g_string_append_printf (to_execute, "%s --uri '%s'", executable_path, uri);
@@ -389,14 +412,158 @@ close_uzbl (WebKitWebView *page, const char *param) {
     gtk_main_quit ();
 }
 
+/* --Statusbar functions-- */
+static char*
+build_progressbar_ascii(int percent) {
+   int width=10;
+   int i;
+   double l;
+   GString *bar = g_string_new("");
+
+   l = (double)percent*((double)width/100.);
+   l = (int)(l+.5)>=(int)l ? l+.5 : l;
+
+   g_string_append(bar, "[");
+   for(i=0; i<(int)l; i++)
+       g_string_append(bar, "=");
+          
+   for(; i<width; i++)
+       g_string_append(bar, "ยท");
+   g_string_append(bar, "]");
+
+   return g_string_free(bar, FALSE);
+}
+
+static void
+setup_scanner() {
+     const GScannerConfig scan_config = {
+             (
+              "\t\r\n"
+             )            /* cset_skip_characters */,
+             (
+              G_CSET_a_2_z
+              "_"
+              G_CSET_A_2_Z
+             )            /* cset_identifier_first */,
+             (
+              G_CSET_a_2_z
+              "_0123456789"
+              G_CSET_A_2_Z
+              G_CSET_LATINS
+              G_CSET_LATINC
+             )            /* cset_identifier_nth */,
+             ( "#\n" )    /* cpair_comment_single */,
+
+             TRUE         /* case_sensitive */,
+
+             FALSE        /* skip_comment_multi */,
+             FALSE        /* skip_comment_single */,
+             FALSE        /* scan_comment_multi */,
+             TRUE         /* scan_identifier */,
+             TRUE         /* scan_identifier_1char */,
+             FALSE        /* scan_identifier_NULL */,
+             TRUE         /* scan_symbols */,
+             FALSE        /* scan_binary */,
+             FALSE        /* scan_octal */,
+             FALSE        /* scan_float */,
+             FALSE        /* scan_hex */,
+             FALSE        /* scan_hex_dollar */,
+             FALSE        /* scan_string_sq */,
+             FALSE        /* scan_string_dq */,
+             TRUE         /* numbers_2_int */,
+             FALSE        /* int_2_float */,
+             FALSE        /* identifier_2_string */,
+             FALSE        /* char_2_token */,
+             FALSE        /* symbol_2_token */,
+             TRUE         /* scope_0_fallback */,
+             FALSE,
+             TRUE
+     };
+
+     uzbl.scan = g_scanner_new(&scan_config);
+     while(symp->symbol_name) {
+         g_scanner_scope_add_symbol(uzbl.scan, 0,
+                         symp->symbol_name,
+                         GINT_TO_POINTER(symp->symbol_token));
+         symp++;
+     }
+}
+
+static gchar *
+parse_status_template(const char *template) {
+     GTokenType token = G_TOKEN_NONE;
+     GString *ret = g_string_new("");
+     gchar *buf=NULL;
+     int sym;
+
+     if(!template)
+         return NULL;
+
+     g_scanner_input_text(uzbl.scan, template, strlen(template));
+     while(!g_scanner_eof(uzbl.scan) && token != G_TOKEN_LAST) {
+         token = g_scanner_get_next_token(uzbl.scan);
+
+         if(token == G_TOKEN_SYMBOL) {
+             sym = (int)g_scanner_cur_value(uzbl.scan).v_symbol;
+             switch(sym) {
+                 case SYM_URI:
+                     g_string_append(ret, uzbl.state.uri);
+                     break;
+                 case SYM_LOADPRGS:
+                     g_string_append(ret, itos(uzbl.gui.sbar.load_progress));
+                     break;
+                 case SYM_LOADPRGSBAR:
+                     buf = build_progressbar_ascii(uzbl.gui.sbar.load_progress);
+                     g_string_append(ret, buf);
+                     g_free(buf);
+                     break;
+                 case SYM_TITLE:
+                     g_string_append(ret,
+                         uzbl.gui.main_title?uzbl.gui.main_title:"");
+                     break;
+                 case SYM_NAME:
+                     g_string_append(ret, 
+                         uzbl.state.instance_name?uzbl.state.instance_name:"" );
+                     break;
+                 case SYM_KEYCMD:
+                     g_string_append(ret, 
+                         keycmd->str?keycmd->str:"" );
+                     break;
+                 case SYM_MODE:
+                     g_string_append(ret, 
+                         insert_mode?"[I]":"[C]" );
+                     break;
+                 default:
+                     break;
+             }
+         }
+         else if(token == G_TOKEN_INT) {
+             g_string_append(ret, itos(g_scanner_cur_value(uzbl.scan).v_int));
+         }
+         else if(token == G_TOKEN_IDENTIFIER) {
+             g_string_append(ret, (gchar *)g_scanner_cur_value(uzbl.scan).v_identifier);
+         }
+         else if(token == G_TOKEN_CHAR) {
+             g_string_append_printf(ret, "%c", g_scanner_cur_value(uzbl.scan).v_char);
+         }
+     }
+
+     return g_string_free(ret, FALSE);
+}
+/* --End Statusbar functions-- */
+
+
 // make sure to put '' around args, so that if there is whitespace we can still keep arguments together.
 static gboolean
 run_command_async(const char *command, const char *args) {
    //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
     GString* to_execute = g_string_new ("");
     gboolean result;
-    g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'", command, config_file, (int) getpid() , (int) xwin, fifo_path, socket_path);
-    g_string_append_printf (to_execute, " '%s' '%s'", uri, "TODO title here");
+    g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'", 
+                    command, uzbl.state.config_file, (int) getpid() ,
+                    (int) uzbl.xwin, uzbl.comm.fifo_path, uzbl.comm.socket_path);
+    g_string_append_printf (to_execute, " '%s' '%s'", 
+                    uzbl.state.uri, "TODO title here");
     if(args) {
         g_string_append_printf (to_execute, " %s", args);
     }
@@ -411,8 +578,8 @@ run_command_sync(const char *command, const char *args, char **stdout) {
        //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
     GString* to_execute = g_string_new ("");
     gboolean result;
-    g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'", command, config_file, (int) getpid() , (int) xwin, fifo_path, socket_path);
-    g_string_append_printf (to_execute, " '%s' '%s'", uri, "TODO title here");
+    g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'", command, uzbl.state.config_file, (int) getpid() , (int) uzbl.xwin, uzbl.comm.fifo_path, uzbl.comm.socket_path);
+    g_string_append_printf (to_execute, " '%s' '%s'", uzbl.state.uri, "TODO title here");
     if(args) {
         g_string_append_printf (to_execute, " %s", args);
     }
@@ -433,7 +600,7 @@ parse_command(const char *cmd, const char *param) {
     Command c;
 
     if ((c = g_hash_table_lookup(commands, cmd)))
-        c(web_view, param);
+        c(uzbl.gui.web_view, param);
     else
         fprintf (stderr, "command \"%s\" not understood. ignoring.\n", cmd);
 }
@@ -454,132 +621,199 @@ parse_line(char *line) {
     g_strfreev(parts);
 }
 
+enum { FIFO, SOCKET};
+void
+build_stream_name(int type) {
+    char *xwin_str;
+    State *s = &uzbl.state;
+
+    xwin_str = itos((int)uzbl.xwin);
+    switch(type) {
+        case FIFO:
+            if (fifo_dir) {
+                sprintf (uzbl.comm.fifo_path, "%s/uzbl_fifo_%s", 
+                                fifo_dir, s->instance_name ? s->instance_name : xwin_str);
+            } else {
+                sprintf (uzbl.comm.fifo_path, "/tmp/uzbl_fifo_%s",
+                                s->instance_name ? s->instance_name : xwin_str);
+            }
+            break;
+
+        case SOCKET:
+            if (socket_dir) {
+                sprintf (uzbl.comm.socket_path, "%s/uzbl_socket_%s",
+                                socket_dir, s->instance_name ? s->instance_name : xwin_str);
+            } else {
+                sprintf (uzbl.comm.socket_path, "/tmp/uzbl_socket_%s",
+                                s->instance_name ? s->instance_name : xwin_str);
+            }
+            break;
+        default:
+            break;
+    }
+    g_free(xwin_str);
+}
+
 static void
-control_fifo(GIOChannel *fd) {
+control_fifo(GIOChannel *gio, GIOCondition condition) {
+    printf("triggered\n");
     gchar *ctl_line;
-    gsize term_pos;
+    GIOStatus ret;
+    GError *err = NULL;
 
-    if(!fd)
-       return;
+    if (condition & G_IO_HUP)
+        g_error ("Fifo: Read end of pipe died!\n");
 
-    g_io_channel_read_line(fd, &ctl_line, NULL, &term_pos, NULL);
-    ctl_line[term_pos] ='\0';
+    if(!gio)
+       g_error ("Fifo: GIOChannel broke\n");
 
-    parse_line(ctl_line);
+    ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, &err);
+    if (ret == G_IO_STATUS_ERROR)
+        g_error ("Fifo: Error reading: %s\n", err->message);
 
+    parse_line(ctl_line);
     g_free(ctl_line);
-
+    printf("...done\n");
     return;
 }
 
 static void
 create_fifo() {
     GIOChannel *chan = NULL;
+    GError *error = NULL;
 
-    if (fifo_dir) {
-        sprintf (fifo_path, "%s/uzbl_fifo_%d", fifo_dir, (int) xwin);
-    } else {
-        sprintf (fifo_path, "/tmp/uzbl_fifo_%d", (int) xwin);
+    build_stream_name(FIFO);
+    if (file_exists(uzbl.comm.fifo_path)) {
+        g_error ("Fifo: Error when creating %s: File exists\n", uzbl.comm.fifo_path);
+        return;
     }
-    printf ("Control fifo opened in %s\n", fifo_path);
-    if (mkfifo (fifo_path, 0666) == -1) {
-        printf ("Possible error creating fifo\n");
+    if (mkfifo (uzbl.comm.fifo_path, 0666) == -1) {
+        g_error ("Fifo: Error when creating %s: %s\n", uzbl.comm.fifo_path, strerror(errno));
+    } else {
+        // we don't really need to write to the file, but if we open the file as 'r' we will block here, waiting for a writer to open the file.
+        chan = g_io_channel_new_file((gchar *) uzbl.comm.fifo_path, "r+", &error);
+        if (chan) {
+            if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, NULL)) {
+                g_error ("Fifo: could not add watch on %s\n", uzbl.comm.fifo_path);
+            } else { 
+                printf ("Fifo: created successfully as %s\n", uzbl.comm.fifo_path);
+            }
+        } else {
+            g_error ("Fifo: Error while opening: %s\n", error->message);
+        }
     }
-
-    if( (chan = g_io_channel_new_file((gchar *) fifo_path, "r+", NULL)) )
-        g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, chan);
     return;
 }
 
 static void
-*control_socket() {
-    if (socket_dir) {
-        sprintf (socket_path, "%s/uzbl_socket_%d", socket_dir, (int) xwin);
+control_socket(GIOChannel *chan) {
+    struct sockaddr_un remote;
+    char buffer[512], *ctl_line;
+    char temp[128];
+    int sock, clientsock, n, done;
+    unsigned int t;
+
+    sock = g_io_channel_unix_get_fd(chan);
+
+    memset (buffer, 0, sizeof (buffer));
+
+    t          = sizeof (remote);
+    clientsock = accept (sock, (struct sockaddr *) &remote, &t);
+
+    done = 0;
+    do {
+        memset (temp, 0, sizeof (temp));
+        n = recv (clientsock, temp, 128, 0);
+        if (n == 0) {
+            buffer[strlen (buffer)] = '\0';
+            done = 1;
+        }
+        if (!done)
+            strcat (buffer, temp);
+    } while (!done);
+
+    if (strcmp (buffer, "\n") < 0) {
+        buffer[strlen (buffer) - 1] = '\0';
     } else {
-        sprintf (socket_path, "/tmp/uzbl_socket_%d", (int) xwin);
+        buffer[strlen (buffer)] = '\0';
     }
-    int sock, clientsock, len;
-    unsigned int t;
-    struct sockaddr_un local, remote;
+    close (clientsock);
+    ctl_line = g_strdup(buffer);
+    parse_line (ctl_line);
+
+/*
+   TODO: we should be able to do it with this.  but glib errors out with "Invalid argument"
+    GError *error = NULL;
+    gsize len;
+    GIOStatus ret;
+    ret = g_io_channel_read_line(chan, &ctl_line, &len, NULL, &error);
+    if (ret == G_IO_STATUS_ERROR)
+        g_error ("Error reading: %s\n", error->message);
+
+    printf("Got line %s (%u bytes) \n",ctl_line, len);
+    if(ctl_line) {
+       parse_line(ctl_line);
+*/
+
+    g_free(ctl_line);
+    return;
+} 
 
+static void
+create_socket() {
+    GIOChannel *chan = NULL;
+    int sock, len;
+    struct sockaddr_un local;
+
+    build_stream_name(SOCKET);
     sock = socket (AF_UNIX, SOCK_STREAM, 0);
 
     local.sun_family = AF_UNIX;
-    strcpy (local.sun_path, socket_path);
+    strcpy (local.sun_path, uzbl.comm.socket_path);
     unlink (local.sun_path);
 
     len = strlen (local.sun_path) + sizeof (local.sun_family);
     bind (sock, (struct sockaddr *) &local, len);
 
     if (errno == -1) {
-        printf ("A problem occurred when opening a socket in %s\n", socket_path);
+        printf ("Socket: Could not open in %s: %s\n", uzbl.comm.socket_path, strerror(errno));
     } else {
-        printf ("Control socket opened in %s\n", socket_path);
-    }
-
-    listen (sock, 5);
-    char buffer[512];
-    char temp[128];
-    int done, n;
-    for(;;) {
-        memset (buffer, 0, sizeof (buffer));
-
-        t          = sizeof (remote);
-        clientsock = accept (sock, (struct sockaddr *) &remote, &t);
-        printf ("Connected to client\n");
-
-        done = 0;
-        do {
-            memset (temp, 0, sizeof (temp));
-            n = recv (clientsock, temp, 128, 0);
-            if (n == 0) {
-                buffer[strlen (buffer)] = '\0';
-                done = 1;
-            }
-
-            if (!done)
-                strcat (buffer, temp);
-        } while (!done);
+        printf ("Socket: Opened in %s\n", uzbl.comm.socket_path);
+        listen (sock, 5);
 
-        if (strcmp (buffer, "\n") < 0) {
-            buffer[strlen (buffer) - 1] = '\0';
-        } else {
-          buffer[strlen (buffer)] = '\0';
-        }
-
-        parse_line (buffer);
-        close (clientsock);
+        if( (chan = g_io_channel_unix_new(sock)) )
+            g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_socket, chan);
     }
-
-    return NULL;
-} 
-static void
-setup_threading () {
-    pthread_t control_thread;
-    pthread_create(&control_thread, NULL, control_socket, NULL);
-    pthread_detach(control_thread);
 }
 
 static void
 update_title (void) {
     GString* string_long = g_string_new ("");
     GString* string_short = g_string_new ("");
+    char* iname = NULL;
+    gchar *statln;
+    int iname_len;
+    State *s = &uzbl.state;
+
+    if(s->instance_name) {
+            iname_len = strlen(s->instance_name)+4;
+            iname = malloc(iname_len);
+            snprintf(iname, iname_len, "<%s> ", s->instance_name);
+            
+            g_string_prepend(string_long, iname);
+            g_string_prepend(string_short, iname);
+            free(iname);
+    }
 
     g_string_append_printf(string_long, "%s ", keycmd->str);
     if (!always_insert_mode)
         g_string_append (string_long, (insert_mode ? "[I] " : "[C] "));
-    if (main_title) {
-        g_string_append (string_long, main_title);
-        g_string_append (string_short, main_title);
+    if (uzbl.gui.main_title) {
+        g_string_append (string_long, uzbl.gui.main_title);
+        g_string_append (string_short, uzbl.gui.main_title);
     }
     g_string_append (string_long, " - Uzbl browser");
     g_string_append (string_short, " - Uzbl browser");
-    if (load_progress < 100)
-        g_string_append_printf (string_long, " (%d%%)", load_progress);
-
     if (selected_url[0]!=0) {
         g_string_append_printf (string_long, " -> (%s)", selected_url);
     }
@@ -588,16 +822,18 @@ update_title (void) {
     gchar* title_short = g_string_free (string_short, FALSE);
 
     if (show_status) {
-        gtk_window_set_title (GTK_WINDOW(main_window), title_short);
-    gtk_label_set_text(GTK_LABEL(mainbar_label), title_long);
+        gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), title_short);
+        statln = parse_status_template(status_format);
+        gtk_label_set_markup(GTK_LABEL(uzbl.gui.mainbar_label), statln);
+        g_free(statln);
     } else {
-        gtk_window_set_title (GTK_WINDOW(main_window), title_long);
+        gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), title_long);
     }
 
     g_free (title_long);
     g_free (title_short);
 }
+
 static gboolean
 key_press_cb (WebKitWebView* page, GdkEventKey* event)
 {
@@ -617,23 +853,72 @@ key_press_cb (WebKitWebView* page, GdkEventKey* event)
         return TRUE;
     }
 
-    if (insert_mode && event->state != modmask)
+    if (insert_mode && ((event->state & modmask) != modmask))
         return FALSE;
 
-
     if (event->keyval == GDK_Escape) {
         g_string_truncate(keycmd, 0);
-
         update_title();
+        return TRUE;
+    }
 
+    //Insert without shift - insert from clipboard; Insert with shift - insert from primary
+    if (event->keyval == GDK_Insert) {
+        gchar * str;
+        if ((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) {
+            str = gtk_clipboard_wait_for_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY));
+        } else {
+            str = gtk_clipboard_wait_for_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)); 
+        }
+        if (str) {
+            g_string_append_printf (keycmd, "%s",  str);
+            update_title ();
+            free (str);
+        }
         return TRUE;
     }
 
-    g_string_append(keycmd, event->string);
+    if ((event->keyval == GDK_BackSpace) && (keycmd->len > 0)) {
+        g_string_truncate(keycmd, keycmd->len - 1);
+        update_title();
+        return TRUE;
+    }
 
+    if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter)) {
+        GString* short_keys = g_string_new ("");
+        unsigned int i;
+        for (i=0; i<(keycmd->len); i++) {
+            g_string_append_c(short_keys, keycmd->str[i]);
+            g_string_append_c(short_keys, '_');
+            
+            //printf("\nTesting string: @%s@\n", short_keys->str);
+            if ((action = g_hash_table_lookup(bindings, short_keys->str))) {
+                GString* parampart = g_string_new (keycmd->str);
+                g_string_erase (parampart, 0, i+1);
+                //printf("\nParameter: @%s@\n", parampart->str);
+                GString* actionname = g_string_new ("");
+                if (action->name)
+                    g_string_printf (actionname, action->name, parampart->str);
+                GString* actionparam = g_string_new ("");
+                if (action->param)
+                    g_string_printf (actionparam, action->param, parampart->str);
+                parse_command(actionname->str, actionparam->str);
+                g_string_free (actionname, TRUE);
+                g_string_free (actionparam, TRUE);
+                g_string_free (parampart, TRUE);
+                g_string_truncate(keycmd, 0);
+                update_title();
+            }          
+
+            g_string_truncate(short_keys, short_keys->len - 1);
+        }
+        g_string_free (short_keys, TRUE);
+        return (!insert_mode);
+    }
+
+    g_string_append(keycmd, event->string);
     if ((action = g_hash_table_lookup(bindings, keycmd->str))) {
         g_string_truncate(keycmd, 0);
-
         parse_command(action->name, action->param);
     }
 
@@ -644,33 +929,38 @@ key_press_cb (WebKitWebView* page, GdkEventKey* event)
 
 static GtkWidget*
 create_browser () {
+    GUI *g = &uzbl.gui;
+
     GtkWidget* scrolled_window = gtk_scrolled_window_new (NULL, NULL);
     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); //todo: some sort of display of position/total length. like what emacs does
 
-    web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
-    gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));
+    g->web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
+    gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (g->web_view));
 
-    g_signal_connect (G_OBJECT (web_view), "title-changed", G_CALLBACK (title_change_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "load-progress-changed", G_CALLBACK (progress_change_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "load-committed", G_CALLBACK (load_commit_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "load-committed", G_CALLBACK (log_history_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "hovering-over-link", G_CALLBACK (link_hover_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "key-press-event", G_CALLBACK (key_press_cb), web_view);
-    g_signal_connect (G_OBJECT (web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb), web_view); 
-    g_signal_connect (G_OBJECT (web_view), "download-requested", G_CALLBACK (download_cb), web_view); 
-    g_signal_connect (G_OBJECT (web_view), "create-web-view", G_CALLBACK (create_web_view_cb), web_view);  
+    g_signal_connect (G_OBJECT (g->web_view), "title-changed", G_CALLBACK (title_change_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "load-progress-changed", G_CALLBACK (progress_change_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "load-committed", G_CALLBACK (load_commit_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "load-committed", G_CALLBACK (log_history_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "hovering-over-link", G_CALLBACK (link_hover_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "key-press-event", G_CALLBACK (key_press_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb), g->web_view); 
+    g_signal_connect (G_OBJECT (g->web_view), "download-requested", G_CALLBACK (download_cb), g->web_view); 
+    g_signal_connect (G_OBJECT (g->web_view), "create-web-view", G_CALLBACK (create_web_view_cb), g->web_view);  
 
     return scrolled_window;
 }
 
 static GtkWidget*
 create_mainbar () {
-    mainbar = gtk_hbox_new (FALSE, 0);
-    mainbar_label = gtk_label_new ("");  
-    gtk_misc_set_alignment (GTK_MISC(mainbar_label), 0, 0);
-    gtk_misc_set_padding (GTK_MISC(mainbar_label), 2, 2);
-    gtk_box_pack_start (GTK_BOX (mainbar), mainbar_label, TRUE, TRUE, 0);
-    return mainbar;
+    GUI *g = &uzbl.gui;
+
+    g->mainbar = gtk_hbox_new (FALSE, 0);
+    g->mainbar_label = gtk_label_new ("");  
+    gtk_label_set_ellipsize(GTK_LABEL(g->mainbar_label), PANGO_ELLIPSIZE_END);
+    gtk_misc_set_alignment (GTK_MISC(g->mainbar_label), 0, 0);
+    gtk_misc_set_padding (GTK_MISC(g->mainbar_label), 2, 2);
+    gtk_box_pack_start (GTK_BOX (g->mainbar), g->mainbar_label, TRUE, TRUE, 0);
+    return g->mainbar;
 }
 
 static
@@ -691,6 +981,8 @@ add_binding (const gchar *key, const gchar *act) {
     if (!parts)
         return;
 
+    //Debug:
+    printf ("Binding %-10s : %s\n", key, act);
     action = new_action(parts[0], parts[1]);
     g_hash_table_insert(bindings, g_strdup(key), action);
 
@@ -703,19 +995,21 @@ settings_init () {
     gboolean res  = FALSE;
     char *saveptr;
     gchar** keys = NULL;
+    State *s = &uzbl.state;
+    Network *n = &uzbl.net;
 
-    if (!config_file) {
+    if (!s->config_file) {
         const char* XDG_CONFIG_HOME = getenv ("XDG_CONFIG_HOME");
         if (! XDG_CONFIG_HOME || ! strcmp (XDG_CONFIG_HOME, "")) {
           XDG_CONFIG_HOME = (char*)XDG_CONFIG_HOME_default;
         }
         printf("XDG_CONFIG_HOME: %s\n", XDG_CONFIG_HOME);
     
-        strcpy (config_file_path, XDG_CONFIG_HOME);
-        strcat (config_file_path, "/uzbl/config");
-        if (file_exists (config_file_path)) {
-          printf ("Config file %s found.\n", config_file_path);
-          config_file = &config_file_path[0];
+        strcpy (s->config_file_path, XDG_CONFIG_HOME);
+        strcat (s->config_file_path, "/uzbl/config");
+        if (file_exists (s->config_file_path)) {
+          printf ("Config file %s found.\n", s->config_file_path);
+          s->config_file = &s->config_file_path[0];
         } else {
             // Now we check $XDG_CONFIG_DIRS
             char *XDG_CONFIG_DIRS = getenv ("XDG_CONFIG_DIRS");
@@ -727,25 +1021,25 @@ settings_init () {
             char buffer[512];
             strcpy (buffer, XDG_CONFIG_DIRS);
             const gchar* dir = (char *) strtok_r (buffer, ":", &saveptr);
-            while (dir && ! file_exists (config_file_path)) {
-                strcpy (config_file_path, dir);
-                strcat (config_file_path, "/uzbl/config_file_pathig");
-                if (file_exists (config_file_path)) {
-                    printf ("Config file %s found.\n", config_file_path);
-                    config_file = &config_file_path[0];
+            while (dir && ! file_exists (s->config_file_path)) {
+                strcpy (s->config_file_path, dir);
+                strcat (s->config_file_path, "/uzbl/config_file_pathig");
+                if (file_exists (s->config_file_path)) {
+                    printf ("Config file %s found.\n", s->config_file_path);
+                    s->config_file = &s->config_file_path[0];
                 }
                 dir = (char * ) strtok_r (NULL, ":", &saveptr);
             }
         }
     }
 
-    if (config_file) {
+    if (s->config_file) {
         config = g_key_file_new ();
-        res = g_key_file_load_from_file (config, config_file, G_KEY_FILE_NONE, NULL);
-          if(res) {
-            printf ("Config %s loaded\n", config_file);
+        res = g_key_file_load_from_file (config, s->config_file, G_KEY_FILE_NONE, NULL);
+          if (res) {
+            printf ("Config %s loaded\n", s->config_file);
           } else {
-            fprintf (stderr, "Config %s loading failed\n", config_file);
+            fprintf (stderr, "Config %s loading failed\n", s->config_file);
         }
     } else {
         printf ("No configuration.\n");
@@ -754,6 +1048,7 @@ settings_init () {
     if (res) {
         history_handler    = g_key_file_get_value   (config, "behavior", "history_handler",    NULL);
         download_handler   = g_key_file_get_value   (config, "behavior", "download_handler",   NULL);
+       cookie_handler     = g_key_file_get_string  (config, "behavior", "cookie_handler",     NULL);
         always_insert_mode = g_key_file_get_boolean (config, "behavior", "always_insert_mode", NULL);
         show_status        = g_key_file_get_boolean (config, "behavior", "show_status",        NULL);
         modkey             = g_key_file_get_value   (config, "behavior", "modkey",             NULL);
@@ -764,11 +1059,12 @@ settings_init () {
             socket_dir     = g_key_file_get_value   (config, "behavior", "socket_dir",         NULL);
         keys               = g_key_file_get_keys    (config, "bindings", NULL,                 NULL);
     }
-    
+
     printf ("History handler: %s\n",    (history_handler    ? history_handler  : "disabled"));
     printf ("Download manager: %s\n",   (download_handler   ? download_handler : "disabled"));
-    printf ("Fifo directory: %s\n",     (fifo_dir           ? fifo_dir         : "/tmp"));
-    printf ("Socket directory: %s\n",   (socket_dir         ? socket_dir       : "/tmp"));
+    printf ("Cookie handler: %s\n",     (cookie_handler     ? cookie_handler   : "disabled"));
+    printf ("Fifo directory: %s\n",     (fifo_dir           ? fifo_dir         : "disabled"));
+    printf ("Socket directory: %s\n",   (socket_dir         ? socket_dir       : "disabled"));
     printf ("Always insert mode: %s\n", (always_insert_mode ? "TRUE"           : "FALSE"));
     printf ("Show status: %s\n",        (show_status        ? "TRUE"           : "FALSE"));
     printf ("Status top: %s\n",         (status_top         ? "TRUE"           : "FALSE"));
@@ -810,59 +1106,84 @@ settings_init () {
     }
 
     /* networking options */
-    proxy_url      = g_key_file_get_value   (config, "network", "proxy_server",       NULL);
-    http_debug     = g_key_file_get_integer (config, "network", "http_debug",         NULL);
-    useragent      = g_key_file_get_value   (config, "network", "user-agent",         NULL);
-    max_conns      = g_key_file_get_integer (config, "network", "max_conns",          NULL);
-    max_conns_host = g_key_file_get_integer (config, "network", "max_conns_per_host", NULL);
+    if (res) {
+        n->proxy_url      = g_key_file_get_value   (config, "network", "proxy_server",       NULL);
+        http_debug     = g_key_file_get_integer (config, "network", "http_debug",         NULL);
+        n->useragent      = g_key_file_get_value   (config, "network", "user-agent",         NULL);
+        n->max_conns      = g_key_file_get_integer (config, "network", "max_conns",          NULL);
+        n->max_conns_host = g_key_file_get_integer (config, "network", "max_conns_per_host", NULL);
+    }
 
-    if(proxy_url){
-        g_object_set(G_OBJECT(soup_session), SOUP_SESSION_PROXY_URI, soup_uri_new(proxy_url), NULL);
+    if(n->proxy_url){
+        g_object_set(G_OBJECT(n->soup_session), SOUP_SESSION_PROXY_URI, soup_uri_new(n->proxy_url), NULL);
     }
        
     if(!(http_debug <= 3)){
         http_debug = 0;
         fprintf(stderr, "Wrong http_debug level, ignoring.\n");
     } else if (http_debug > 0) {
-        soup_logger = soup_logger_new(http_debug, -1);
-        soup_session_add_feature(soup_session, SOUP_SESSION_FEATURE(soup_logger));
+        n->soup_logger = soup_logger_new(http_debug, -1);
+        soup_session_add_feature(n->soup_session, SOUP_SESSION_FEATURE(n->soup_logger));
     }
        
-    if(useragent){
-        g_object_set(G_OBJECT(soup_session), SOUP_SESSION_USER_AGENT, useragent, NULL);
+    if(n->useragent){
+        char* newagent  = malloc(1024);
+
+        strcpy(newagent, str_replace("%webkit-major%", itos(WEBKIT_MAJOR_VERSION), n->useragent));
+        strcpy(newagent, str_replace("%webkit-minor%", itos(WEBKIT_MINOR_VERSION), newagent));
+        strcpy(newagent, str_replace("%webkit-micro%", itos(WEBKIT_MICRO_VERSION), newagent));
+
+        if (uname (&unameinfo) == -1) {
+            printf("Error getting uname info. Not replacing system-related user agent variables.\n");
+        } else {
+            strcpy(newagent, str_replace("%sysname%",     unameinfo.sysname, newagent));
+            strcpy(newagent, str_replace("%nodename%",    unameinfo.nodename, newagent));
+            strcpy(newagent, str_replace("%kernrel%",     unameinfo.release, newagent));
+            strcpy(newagent, str_replace("%kernver%",     unameinfo.version, newagent));
+            strcpy(newagent, str_replace("%arch-system%", unameinfo.machine, newagent));
+
+            #ifdef _GNU_SOURCE
+                strcpy(newagent, str_replace("%domainname%", unameinfo.domainname, newagent));
+            #endif
+        }
+
+        strcpy(newagent, str_replace("%arch-uzbl%",    ARCH,                       newagent));
+        strcpy(newagent, str_replace("%commit%",       COMMIT,                     newagent));
+
+        n->useragent = malloc(1024);
+        strcpy(n->useragent, newagent);
+        g_object_set(G_OBJECT(n->soup_session), SOUP_SESSION_USER_AGENT, n->useragent, NULL);
     }
 
-    if(max_conns >= 1){
-        g_object_set(G_OBJECT(soup_session), SOUP_SESSION_MAX_CONNS, max_conns, NULL);
+    if(n->max_conns >= 1){
+        g_object_set(G_OBJECT(n->soup_session), SOUP_SESSION_MAX_CONNS, n->max_conns, NULL);
     }
 
-    if(max_conns_host >= 1){
-        g_object_set(G_OBJECT(soup_session), SOUP_SESSION_MAX_CONNS_PER_HOST, max_conns_host, NULL);
+    if(n->max_conns_host >= 1){
+        g_object_set(G_OBJECT(n->soup_session), SOUP_SESSION_MAX_CONNS_PER_HOST, n->max_conns_host, NULL);
     }
 
-    printf("Proxy configured: %s\n", proxy_url ? proxy_url : "none");
+    printf("Proxy configured: %s\n", n->proxy_url ? n->proxy_url : "none");
     printf("HTTP logging level: %d\n", http_debug);
-    printf("User-agent: %s\n", useragent? useragent : "default");
-    printf("Maximum connections: %d\n", max_conns ? max_conns : 0);
-    printf("Maximum connections per host: %d\n", max_conns_host ? max_conns_host: 0);
+    printf("User-agent: %s\n", n->useragent? n->useragent : "default");
+    printf("Maximum connections: %d\n", n->max_conns ? n->max_conns : 0);
+    printf("Maximum connections per host: %d\n", n->max_conns_host ? n->max_conns_host: 0);
+               
 
-       /* om nom nom nom */
-       cookie_handler = g_key_file_get_string(config, "behavior", "cookie_handler", NULL);
 
        if(cookie_handler){
                /* ck = soup_cookie_jar_new(); */
                /* soup_session_add_feature(soup_session, SOUP_SESSION_FEATURE(ck)); */
                /* g_signal_connect(ck, "changed", G_CALLBACK(cookie_recieved_action), NULL); */
-               g_signal_connect(soup_session, "request-queued", G_CALLBACK(handle_cookies), NULL);
-               printf("Cookie handler: %s\n", cookie_handler);
+               g_signal_connect(n->soup_session, "request-queued", G_CALLBACK(handle_cookies), NULL);
        }
        
 }
 
-static void handle_cookies (SoupSession *session,
-                                                       SoupMessage *msg,
-                                                       gpointer     user_data){
-       soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
+static void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data){
+    (void) session;
+    (void) user_data;
+    soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
        
        /* ask handler for cookies, if there are any, use
           soup_message_headers_replace (msg->request_headers,
@@ -872,19 +1193,19 @@ static void handle_cookies (SoupSession *session,
 }
 
 static void
-save_cookies (SoupMessage *msg,
-                         gpointer     user_data){
-       GSList *ck;
-       char *req, *cookie;
-       for (ck = soup_cookies_from_response(msg); ck; ck = ck->next){
-               cookie = soup_cookie_to_set_cookie_header(ck->data);
-               req = malloc(strlen(cookie) + 10);
-               sprintf(req, "PUT \"%s\"", cookie);
-               run_command_async(cookie_handler, req);
-               free(req);
-               free(cookie);
-       }
-       g_slist_free(ck);
+save_cookies (SoupMessage *msg, gpointer user_data){
+    (void) user_data;
+    GSList *ck;
+    char *req, *cookie;
+    for (ck = soup_cookies_from_response(msg); ck; ck = ck->next){
+        cookie = soup_cookie_to_set_cookie_header(ck->data);
+        req = malloc(strlen(cookie) + 10);
+        sprintf(req, "PUT \"%s\"", cookie);
+        run_command_async(cookie_handler, req);
+        free(req);
+        free(cookie);
+    }
+    g_slist_free(ck);
 }
 
 int
@@ -907,7 +1228,7 @@ main (int argc, char* argv[]) {
     /* initialize hash table */
     bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
        
-       soup_session = webkit_get_default_session();
+       uzbl.net.soup_session = webkit_get_default_session();
     keycmd = g_string_new("");
 
     settings_init ();
@@ -923,35 +1244,42 @@ main (int argc, char* argv[]) {
     if (!status_top)
         gtk_box_pack_start (GTK_BOX (vbox), create_mainbar (), FALSE, TRUE, 0);
 
-    main_window = create_window ();
-    gtk_container_add (GTK_CONTAINER (main_window), vbox);
+    uzbl.gui.main_window = create_window ();
+    gtk_container_add (GTK_CONTAINER (uzbl.gui.main_window), vbox);
 
-    load_uri (web_view, uri);
+    load_uri (uzbl.gui.web_view, uzbl.state.uri);
 
-    gtk_widget_grab_focus (GTK_WIDGET (web_view));
-    gtk_widget_show_all (main_window);
-    xwin = GDK_WINDOW_XID (GTK_WIDGET (main_window)->window);
-    printf("window_id %i\n",(int) xwin);
+    gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view));
+    gtk_widget_show_all (uzbl.gui.main_window);
+    uzbl.xwin = GDK_WINDOW_XID (GTK_WIDGET (uzbl.gui.main_window)->window);
+    printf("window_id %i\n",(int) uzbl.xwin);
     printf("pid %i\n", getpid ());
+    printf("name: %s\n", uzbl.state.instance_name);
+
+    uzbl.gui.scbar_v = (GtkScrollbar*) gtk_vscrollbar_new (NULL);
+    uzbl.gui.bar_v = gtk_range_get_adjustment((GtkRange*) uzbl.gui.scbar_v);
+    uzbl.gui.scbar_h = (GtkScrollbar*) gtk_hscrollbar_new (NULL);
+    uzbl.gui.bar_h = gtk_range_get_adjustment((GtkRange*) uzbl.gui.scbar_h);
+    gtk_widget_set_scroll_adjustments ((GtkWidget*) uzbl.gui.web_view, uzbl.gui.bar_h, uzbl.gui.bar_v);
 
-    scbar_v = (GtkScrollbar*) gtk_vscrollbar_new (NULL);
-    bar_v = gtk_range_get_adjustment((GtkRange*) scbar_v);
-    scbar_h = (GtkScrollbar*) gtk_hscrollbar_new (NULL);
-    bar_h = gtk_range_get_adjustment((GtkRange*) scbar_h);
-    gtk_widget_set_scroll_adjustments ((GtkWidget*) web_view, bar_h, bar_v);
 
     if (!show_status)
-        gtk_widget_hide(mainbar);
+        gtk_widget_hide(uzbl.gui.mainbar);
+    setup_scanner();
 
-    setup_threading ();
-    create_fifo ();
+    if (fifo_dir)
+        create_fifo ();
+    if (socket_dir)
+        create_socket();
 
     gtk_main ();
 
     g_string_free(keycmd, TRUE);
 
-    unlink (socket_path);
-    unlink (fifo_path);
+    if (fifo_dir)
+        unlink (uzbl.comm.fifo_path);
+    if (socket_dir)
+        unlink (uzbl.comm.socket_path);
 
     g_hash_table_destroy(bindings);
     g_hash_table_destroy(commands);