aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dieter Plaetinck <dieter@plaetinck.be>2009-05-06 20:37:20 +0200
committerGravatar Dieter Plaetinck <dieter@plaetinck.be>2009-05-06 20:37:20 +0200
commit6d623e35f67a235ab5c3dc9a7fbce7fdfd7d3f07 (patch)
tree0bdcd0369e1a4b1cf29be497f47384d1aaf831f6
parent48dd82b3679a6b19b835c570076ba0f5b7596598 (diff)
parentf7abb5efe104568c31ef211a6a230a9e842dc5a3 (diff)
Merge commit 'rob/master' into experimental
-rw-r--r--uzbl.c299
-rw-r--r--uzbl.h39
2 files changed, 256 insertions, 82 deletions
diff --git a/uzbl.c b/uzbl.c
index ad5aa0f..947ec42 100644
--- a/uzbl.c
+++ b/uzbl.c
@@ -54,22 +54,20 @@
#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 gchar selected_url[500] = "\0";
-static gint load_progress;
-static Window xwin = 0;
static char executable_path[500];
static GString* keycmd;
static gchar searchtx[500] = "\0";
static Uzbl uzbl;
-/* 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 gchar* instance_name = NULL;
-
/* settings from config: group behaviour */
static gchar* history_handler = NULL;
static gchar* fifo_dir = NULL;
@@ -95,9 +93,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", "URI" },
- { "name", 'n', 0, G_OPTION_ARG_STRING, &instance_name, "Name of the current instance", "NAME" },
- { "config", 'c', 0, G_OPTION_ARG_STRING, &config_file, "Config file", "FILE" },
+ { "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 }
};
@@ -107,13 +105,6 @@ 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;
/* --- UTILITY FUNCTIONS --- */
@@ -239,7 +230,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();
}
@@ -247,9 +238,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
@@ -275,8 +266,8 @@ 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)
@@ -419,14 +410,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(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, uzbl.comm.fifo_path, uzbl.comm.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);
}
@@ -472,22 +607,27 @@ enum { FIFO, SOCKET};
void
build_stream_name(int type) {
char *xwin_str;
+ State *s = &uzbl.state;
- xwin_str = itos((int)xwin);
+ xwin_str = itos((int)uzbl.xwin);
switch(type) {
case FIFO:
if (fifo_dir) {
- sprintf (uzbl.comm.fifo_path, "%s/uzbl_fifo_%s", fifo_dir, instance_name ? instance_name : xwin_str);
+ 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", instance_name ? instance_name : xwin_str);
+ 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, instance_name ? instance_name : xwin_str);
+ 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", instance_name ? instance_name : xwin_str);
+ sprintf (uzbl.comm.socket_path, "/tmp/uzbl_socket_%s",
+ s->instance_name ? s->instance_name : xwin_str);
}
break;
default:
@@ -633,12 +773,14 @@ 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(instance_name) {
- iname_len = strlen(instance_name)+4;
+ if(s->instance_name) {
+ iname_len = strlen(s->instance_name)+4;
iname = malloc(iname_len);
- snprintf(iname, iname_len, "<%s> ", instance_name);
+ snprintf(iname, iname_len, "<%s> ", s->instance_name);
g_string_prepend(string_long, iname);
g_string_prepend(string_short, iname);
@@ -654,9 +796,6 @@ update_title (void) {
}
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);
}
@@ -666,7 +805,9 @@ update_title (void) {
if (show_status) {
gtk_window_set_title (GTK_WINDOW(uzbl.gui.main_window), title_short);
- gtk_label_set_text(GTK_LABEL(uzbl.gui.mainbar_label), title_long);
+ 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(uzbl.gui.main_window), title_long);
}
@@ -836,19 +977,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");
@@ -860,25 +1003,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);
+ res = g_key_file_load_from_file (config, s->config_file, G_KEY_FILE_NONE, NULL);
if (res) {
- printf ("Config %s loaded\n", config_file);
+ 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");
@@ -944,29 +1087,29 @@ settings_init () {
/* networking options */
if (res) {
- proxy_url = g_key_file_get_value (config, "network", "proxy_server", NULL);
+ 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);
- 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);
+ 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){
+ if(n->useragent){
char* newagent = malloc(1024);
- strcpy(newagent, str_replace("%webkit-major%", itos(WEBKIT_MAJOR_VERSION), useragent));
+ 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));
@@ -987,24 +1130,24 @@ settings_init () {
strcpy(newagent, str_replace("%arch-uzbl%", ARCH, newagent));
strcpy(newagent, str_replace("%commit%", COMMIT, newagent));
- useragent = malloc(1024);
- strcpy(useragent, newagent);
- g_object_set(G_OBJECT(soup_session), SOUP_SESSION_USER_AGENT, useragent, NULL);
+ 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);
}
@@ -1028,7 +1171,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 ();
@@ -1047,12 +1190,12 @@ main (int argc, char* argv[]) {
uzbl.gui.main_window = create_window ();
gtk_container_add (GTK_CONTAINER (uzbl.gui.main_window), vbox);
- load_uri (uzbl.gui.web_view, uri);
+ load_uri (uzbl.gui.web_view, uzbl.state.uri);
gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view));
gtk_widget_show_all (uzbl.gui.main_window);
- xwin = GDK_WINDOW_XID (GTK_WIDGET (uzbl.gui.main_window)->window);
- printf("window_id %i\n",(int) xwin);
+ 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);
@@ -1062,8 +1205,10 @@ main (int argc, char* argv[]) {
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);
+
if (!show_status)
gtk_widget_hide(uzbl.gui.mainbar);
+ setup_scanner();
if (fifo_dir)
create_fifo ();
diff --git a/uzbl.h b/uzbl.h
index a0af6ea..2bd8d01 100644
--- a/uzbl.h
+++ b/uzbl.h
@@ -1,3 +1,21 @@
+/* statusbar symbols */
+enum { SYM_TITLE, SYM_URI, SYM_NAME,
+ SYM_LOADPRGS, SYM_LOADPRGSBAR,
+ SYM_KEYCMD, SYM_MODE};
+const struct {
+ gchar *symbol_name;
+ guint symbol_token;
+} symbols[] = {
+ {"NAME", SYM_NAME},
+ {"URI", SYM_URI},
+ {"TITLE", SYM_TITLE},
+ {"KEYCMD", SYM_KEYCMD},
+ {"MODE", SYM_MODE},
+ {"LOAD_PROGRESS", SYM_LOADPRGS},
+ {"LOAD_PROGRESSBAR", SYM_LOADPRGSBAR},
+ {NULL, 0}
+}, *symp = symbols;
+
/* status bar elements */
typedef struct {
gint load_progress;
@@ -32,12 +50,24 @@ typedef struct {
gchar config_file_path[500];
} State;
+typedef struct {
+ SoupSession *soup_session;
+ SoupLogger *soup_logger;
+ char *proxy_url;
+ char *useragent;
+ gint max_conns;
+ gint max_conns_host;
+} Network;
+
+
/* main uzbl data structure */
typedef struct {
GUI gui;
Communication comm;
State state;
- int xwin;
+ Network net;
+ Window xwin;
+ GScanner *scan;
} Uzbl;
typedef struct {
@@ -46,11 +76,10 @@ typedef struct {
} Action;
-void
-eprint(const char *errstr, ...);
-char *
-estrdup(const char *str);
+/* Functions */
+static void
+setup_scanner();
char *
itos(int val);