diff options
Diffstat (limited to 'uzbl.c')
-rw-r--r-- | uzbl.c | 331 |
1 files changed, 181 insertions, 150 deletions
@@ -30,6 +30,7 @@ #define LENGTH(x) (sizeof x / sizeof x[0]) +#define MAX_BINDINGS 256 #include <gtk/gtk.h> #include <gdk/gdkx.h> @@ -80,15 +81,17 @@ static gchar* modkey = NULL; static guint modmask = 0; static gchar* home_page = NULL; -/* settings from config: group bindings_internal */ -static GHashTable *internal_bindings; +/* settings from config: group bindings, key -> action */ +static GHashTable *bindings; -/* settings from config: group bindings_external */ -static GHashTable *external_bindings; - -/* command list */ +/* command list: name -> Command */ static GHashTable *commands; +typedef struct { + char *name; + char *param; +} Action; + /* commandline arguments (set initial values for the state variables) */ static GOptionEntry entries[] = { @@ -98,17 +101,11 @@ static GOptionEntry entries[] = { NULL, 0, 0, 0, NULL, NULL, NULL } }; -/* for internal list of commands */ -typedef struct -{ - gpointer command; - void (*func_1_param)(WebKitWebView*); - void (*func_2_params)(WebKitWebView*, const gchar *); -} Command; +typedef void (*Command)(WebKitWebView*, const char *); /* XDG stuff */ -char *XDG_CONFIG_HOME_default[256]; -char *XDG_CONFIG_DIRS_default = "/etc/xdg"; +static char *XDG_CONFIG_HOME_default[256]; +static char *XDG_CONFIG_DIRS_default = "/etc/xdg"; static void update_title (GtkWindow* window); @@ -120,14 +117,24 @@ static void new_window_load_uri (const gchar * uri); static void -go_home ( WebKitWebView * web_view); +go_home (WebKitWebView *page, const char *param); static void -close_uzbl ( WebKitWebView * web_view); +close_uzbl (WebKitWebView *page, const char *param); static gboolean run_command(const char *command, const char *args); +static void +spawn(WebKitWebView *web_view, const char *param); + +static void +free_action(gpointer action); + +static Action* +new_action(const gchar *name, const gchar *param); + + /* --- CALLBACKS --- */ @@ -171,24 +178,13 @@ download_cb (WebKitWebView *web_view, GObject *download, gpointer user_data) { } static void -go_back_cb (WebKitWebView* page) { - (void) page; - webkit_web_view_go_back (web_view); -} - -static void -go_forward_cb (WebKitWebView* page) { - (void) page; - webkit_web_view_go_forward (web_view); -} - -static void -toggle_status_cb (WebKitWebView* page) { - (void) page; +toggle_status_cb (WebKitWebView* page, const char *param) { + (void)page; + (void)param; if (show_status) { - gtk_widget_hide(mainbar); + gtk_widget_hide(mainbar); } else { - gtk_widget_show(mainbar); + gtk_widget_show(mainbar); } show_status = !show_status; update_title (GTK_WINDOW (main_window)); @@ -257,40 +253,71 @@ log_history_cb () { g_string_free (args, TRUE); } } - + +/* 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(stop_loading) +VIEWFUNC(zoom_in) +VIEWFUNC(zoom_out) +VIEWFUNC(go_back) +VIEWFUNC(go_forward) +#undef VIEWFUNC + /* -- command to callback/function map for things we cannot attach to any signals */ // TODO: reload, home, quit -static Command cmdlist[] = +static struct {char *name; Command command;} cmdlist[] = { - { "back", &go_back_cb, NULL }, - { "forward", &go_forward_cb, NULL }, - { "refresh", &webkit_web_view_reload, NULL }, //Buggy - { "stop", &webkit_web_view_stop_loading, NULL }, - { "zoom_in", &webkit_web_view_zoom_in, NULL }, //Can crash (when max zoom reached?). - { "zoom_out", &webkit_web_view_zoom_out, NULL }, - { "uri", (void *) NULL, &load_uri }, - { "toggle_status", &toggle_status_cb, NULL }, - { "home" , &go_home, NULL }, - { "exit" , &close_uzbl, NULL }, - { NULL, NULL, NULL } -//{ "get uri", &webkit_web_view_get_uri}, + { "back", view_go_back }, + { "forward", view_go_forward }, + { "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 }, + { "home", go_home }, + { "exit", close_uzbl }, }; static void commands_hash(void) { - unsigned int i = 0; - commands = g_hash_table_new(g_str_hash, g_str_equal); - - while(cmdlist[i].command != NULL){ - g_hash_table_insert(commands, cmdlist[i].command, &cmdlist[i]); - i++; - } + unsigned int i; + commands = g_hash_table_new(g_str_hash, g_str_equal); + + for (i = 0; i < LENGTH(cmdlist); i++) + g_hash_table_insert(commands, cmdlist[i].name, cmdlist[i].command); } /* -- CORE FUNCTIONS -- */ +void +free_action(gpointer act) { + Action *action = (Action*)act; + g_free(action->name); + if (action->param) + g_free(action->param); + g_free(action); +} + +Action* +new_action(const gchar *name, const gchar *param) { + Action *action = g_new(Action, 1); + + action->name = g_strdup(name); + if (param) + action->param = g_strdup(param); + else + action->param = NULL; + + return action; +} + static bool file_exists (const char * filename) { FILE *file = fopen (filename, "r"); @@ -302,10 +329,10 @@ file_exists (const char * filename) { } static void -load_uri (WebKitWebView * web_view, const gchar * uri) { - if (uri != NULL) { - GString* newuri = g_string_new (uri); - if (g_strrstr (uri, "://") == NULL) +load_uri (WebKitWebView * web_view, const gchar *param) { + if (param) { + GString* newuri = g_string_new (param); + if (g_strrstr (param, "://") == NULL) g_string_prepend (newuri, "http://"); webkit_web_view_load_uri (web_view, newuri->str); g_string_free (newuri, TRUE); @@ -328,20 +355,23 @@ new_window_load_uri (const gchar * uri) { g_string_printf (to_execute, "./uzbl --uri '%s' --config '%s'", uri, config_file); } printf("Spawning %s\n",to_execute->str); - g_spawn_command_line_async (to_execute->str, NULL); + g_spawn_command_line_async (to_execute->str, NULL); } g_string_free (to_execute, TRUE); } static void -go_home (WebKitWebView * web_view) { +go_home (WebKitWebView *page, const char *param) { + (void)param; + if (home_page) - webkit_web_view_load_uri (web_view, home_page); + webkit_web_view_load_uri (page, home_page); } static void -close_uzbl (WebKitWebView * web_view) { - (void) web_view; +close_uzbl (WebKitWebView *page, const char *param) { + (void)page; + (void)param; gtk_main_quit (); } @@ -362,46 +392,52 @@ run_command(const char *command, const char *args) { } static void -parse_command(const char *cmd) { - Command *c = NULL; - char buffer[512]; - strcpy (buffer, cmd); - char * saveptr; - char * command_name = strtok_r (buffer, " ", &saveptr); - gchar * command_param = strtok_r (NULL, " ,", &saveptr); - - if((c = g_hash_table_lookup(commands, command_name)) != NULL){ - if (c->func_2_params != NULL) { - if (command_param != NULL) { - printf ("command executing: \"%s %s\"\n", command_name, command_param); - c->func_2_params (web_view, command_param); - } else { - if (c->func_1_param != NULL) { - printf ("command executing: \"%s\"\n", command_name); - c->func_1_param (web_view); - } else - fprintf (stderr, "command needs a parameter. \"%s\" is not complete\n", command_name); - } - } else if (c->func_1_param != NULL) { - printf ("command executing: \"%s\"\n", command_name); - c->func_1_param (web_view); - } - } else +spawn(WebKitWebView *web_view, const char *param) { + (void)web_view; + run_command(param, NULL); +} + +static void +parse_command(const char *cmd, const char *param) { + Command c; + + if ((c = g_hash_table_lookup(commands, cmd))) + c(web_view, param); + else fprintf (stderr, "command \"%s\" not understood. ignoring.\n", cmd); } static void +parse_line(char *line) { + gchar **parts; + + g_strstrip(line); + + parts = g_strsplit(line, " ", 2); + + if (!parts) + return; + + parse_command(parts[0], parts[1]); + + g_strfreev(parts); +} + +static void control_fifo(GIOChannel *fd) { gchar *ctl_line; - gsize ctl_line_length, term_pos; + gsize term_pos; if(!fd) return; - g_io_channel_read_line(fd, &ctl_line, &ctl_line_length, &term_pos, NULL); //TODO: support partial writes + g_io_channel_read_line(fd, &ctl_line, NULL, &term_pos, NULL); ctl_line[term_pos] ='\0'; - parse_command(ctl_line); - + + parse_line(ctl_line); + + g_free(ctl_line); + return; } @@ -482,10 +518,10 @@ static void buffer[strlen (buffer)] = '\0'; } - parse_command (buffer); + parse_line (buffer); close (clientsock); } - + return NULL; } @@ -501,8 +537,10 @@ update_title (GtkWindow* window) { GString* string_short = g_string_new (""); if (!always_insert_mode) g_string_append (string_long, (insert_mode ? "[I] " : "[C] ")); - g_string_append (string_long, main_title); - g_string_append (string_short, main_title); + if (main_title) { + g_string_append (string_long, main_title); + g_string_append (string_short, main_title); + } g_string_append (string_long, " - Uzbl browser"); g_string_append (string_short, " - Uzbl browser"); if (load_progress < 100) @@ -517,7 +555,7 @@ update_title (GtkWindow* window) { if (show_status) { gtk_window_set_title (window, title_short); - gtk_label_set_text(GTK_LABEL(mainbar_label), title_long); + gtk_label_set_text(GTK_LABEL(mainbar_label), title_long); } else { gtk_window_set_title (window, title_long); } @@ -529,38 +567,28 @@ update_title (GtkWindow* window) { static gboolean key_press_cb (WebKitWebView* page, GdkEventKey* event) { + //TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further. + (void) page; - gpointer act; - gboolean result=FALSE; //TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further. + Action *action; + if (event->type != GDK_KEY_PRESS || event->keyval == GDK_Page_Up || event->keyval == GDK_Page_Down || event->keyval == GDK_Up || event->keyval == GDK_Down || event->keyval == GDK_Left || event->keyval == GDK_Right) - return result; + return FALSE; //TURN OFF/ON INSERT MODE - if (!always_insert_mode && ((insert_mode && (event->keyval == GDK_Escape)) || (!insert_mode && (event->string[0] == 'i')))) { - insert_mode = !insert_mode; + if ((insert_mode && (event->keyval == GDK_Escape)) || (!insert_mode && (event->string[0] == 'i'))) { + insert_mode = !insert_mode || always_insert_mode; update_title (GTK_WINDOW (main_window)); return TRUE; } - //INTERNAL BINDINGS - if((act = g_hash_table_lookup(internal_bindings, event->string)) != NULL) - if (!insert_mode || (event->state == modmask)) { - parse_command (act); - result = TRUE; - } - - //EXTERNAL BINDINGS - if((act = g_hash_table_lookup(external_bindings, event->string)) != NULL) - if (!insert_mode || (event->state == modmask)) { - run_command (act, NULL); - result = TRUE; - } - - if (!result) - result = (insert_mode ? FALSE : TRUE); + if ((!insert_mode || (event->state == modmask)) && (action = g_hash_table_lookup(bindings, event->string))) { + parse_command(action->name, action->param); + return TRUE; + } - return result; + return !insert_mode; } static GtkWidget* @@ -605,23 +633,30 @@ GtkWidget* create_window () { } static void -add_binding (char *binding, char *action, bool internal) { - g_hash_table_insert(internal ? internal_bindings : external_bindings, - binding, action); +add_binding (const gchar *key, const gchar *act) { + char **parts = g_strsplit(act, " ", 2); + Action *action; + + if (!parts) + return; + + action = new_action(parts[0], parts[1]); + g_hash_table_insert(bindings, g_strdup(key), action); + + g_strfreev(parts); } static void settings_init () { GKeyFile* config; gboolean res = FALSE; - gchar** keysi = NULL; - gchar** keyse = NULL; char *saveptr; + gchar** keys = NULL; if (!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; + XDG_CONFIG_HOME = (char*)XDG_CONFIG_HOME_default; } printf("XDG_CONFIG_HOME: %s\n", XDG_CONFIG_HOME); @@ -656,9 +691,9 @@ settings_init () { if (config_file) { config = g_key_file_new (); res = g_key_file_load_from_file (config, config_file, G_KEY_FILE_NONE, NULL); - if(res) { + if(res) { printf ("Config %s loaded\n", config_file); - } else { + } else { fprintf (stderr, "Config %s loading failed\n", config_file); } } else { @@ -671,16 +706,15 @@ settings_init () { 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); - keysi = g_key_file_get_keys (config, "bindings_internal", NULL, NULL); - keyse = g_key_file_get_keys (config, "bindings_external", NULL, NULL); status_top = g_key_file_get_boolean (config, "behavior", "status_top", NULL); home_page = g_key_file_get_value (config, "behavior", "home_page", NULL); if (! fifo_dir) - fifo_dir = g_key_file_get_value (config, "behavior", "fifo_dir", NULL); + fifo_dir = g_key_file_get_value (config, "behavior", "fifodir", NULL); if (! socket_dir) 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")); @@ -714,21 +748,16 @@ settings_init () { if (g_strrstr (modkeyup,"META") != NULL) modmask |= GDK_META_MASK; //the Meta modifier. Since 2.10 */ free (modkeyup); - if (keysi) { - int i = 0; - for (i = 0; keysi[i]; i++) { - gchar *binding = g_key_file_get_string (config, "bindings_internal", keysi[i], NULL); - printf ("Action: %s, Binding: %s (internal)\n", g_strdup (keysi[i]), binding); - add_binding (binding, g_strdup (keysi[i]), true); - } - } - if (keyse) { - int i = 0; - for (i = 0; keyse[i]; i++) { - gchar *binding = g_key_file_get_string (config, "bindings_external", keyse[i], NULL); - printf ("Action: %s, Binding: %s (external)\n", g_strdup (keyse[i]), binding); - add_binding (binding, g_strdup (keyse[i]), false); + if (keys) { + int i; + for (i = 0; keys[i]; i++) { + gchar *value = g_key_file_get_string (config, "bindings", keys[i], NULL); + + add_binding(g_strstrip(keys[i]), value); + g_free(value); } + + g_strfreev(keys); } } @@ -748,13 +777,12 @@ main (int argc, char* argv[]) { g_option_context_add_main_entries (context, entries, NULL); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_parse (context, &argc, &argv, &error); - /* initialize has tables */ - internal_bindings = g_hash_table_new(g_str_hash, g_str_equal); - external_bindings = g_hash_table_new(g_str_hash, g_str_equal); + /* initialize hash table */ + bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action); settings_init (); commands_hash (); - + if (always_insert_mode) insert_mode = TRUE; @@ -777,7 +805,7 @@ main (int argc, char* argv[]) { printf("pid %i\n", getpid ()); if (!show_status) - gtk_widget_hide(mainbar); + gtk_widget_hide(mainbar); setup_threading (); create_fifo (); @@ -786,6 +814,9 @@ main (int argc, char* argv[]) { unlink (socket_path); unlink (fifo_path); + + g_hash_table_destroy(bindings); + g_hash_table_destroy(commands); return 0; } |