commit edc43785525594f39492f66fbec1133055ec4fc8
parent 3f9605ab1fb52c7e45a41006c53313e29add9c38
Author: Kyle Milz <kmilz@ucalgary.ca>
Date: Tue, 25 Sep 2012 12:55:33 -0600
hack in config system from eve
using the .geneet file from eve (copyright proFusion) use the data
structres it generates to make a persistent config file.
config file includes a history of web pages visited, persistent
settings, and session data (buffers open, etc).
Diffstat:
M | Makefile | | | 2 | +- |
A | callbacks.c | | | 951 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | callbacks.h | | | 35 | +++++++++++++++++++++++++++++++++++ |
M | commands.c | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | commands.h | | | 5 | +---- |
D | config.h | | | 155 | ------------------------------------------------------------------------------- |
M | keymap.h | | | 4 | ++-- |
M | main.c | | | 1598 | ++++++++++++++++++++++++------------------------------------------------------- |
M | main.h | | | 7 | +++++++ |
M | utilities.c | | | 3 | ++- |
M | viking.h | | | 15 | +++++++++++++++ |
A | viking_state.c | | | 1259 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | viking_state.h | | | 157 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
13 files changed, 2962 insertions(+), 1291 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
TARGET = viking
# Objectfiles, needed for $(TARGET)
-OBJ = main.o utilities.o commands.o jsmn.o
+OBJ = main.o utilities.o commands.o jsmn.o viking_state.o callbacks.o
# Manpages
MAN1 = evi2.1
MAN5 = evirc.5
diff --git a/callbacks.c b/callbacks.c
@@ -0,0 +1,951 @@
+
+#include <Elementary.h>
+#include <EWebKit.h>
+
+#include "viking.h"
+#include "viking_state.h"
+#include "main.h"
+#include "utilities.h"
+#include "javascript.h"
+#include "commands.h"
+#include "callbacks.h"
+
+static Eina_Bool commandhistoryfetch (const Arg *, void *);
+static Eina_Bool process_keypress (void *, void*);
+
+void download_complete_cb(void*, const char*, int);
+int download_progress_cb(void*, const char*, long int, long int, long int, long int);
+
+#define IS_ESCAPE(ev) ((!strcmp(ev->keyname, "Escape")) || \
+ (!strcmp(ev->keyname, "[") && evas_key_modifier_is_set(ev->modifiers, "Control")))
+
+
+void
+webview_title_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ /*
+ const char *title = "";
+ Ewk_Text_With_Direction *dir_text = event_info;
+ if (event_info) title = dir_text->string;
+ char buf[20] = "";
+
+ if (title)
+ strncpy(buf, title, sizeof(buf) - 1);
+ elm_object_item_text_set(td->tab, buf);
+ */
+}
+
+void
+webview_progress_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ /* *event_info is a double between 0.0 and 1.0 */
+ update_state(td->app);
+}
+
+
+void
+protocol_register_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ printf("protocol_register()\n");
+}
+
+void
+load_error_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ char *contents;
+ Ewk_Frame_Load_Error *error = event_info;
+
+ if (error->is_cancellation)
+ return;
+
+ contents = strdup_printf("<html><body>\
+ <h1>Error %i</h1>\
+ <h2>%s</h2>\
+ <h2>%s</h2>\
+ </body></html>",
+ error->code, error->failing_url, error->description);
+
+ ewk_frame_contents_set(error->frame, contents, strlen(contents) - 1,
+ "text/html", "UTF-8", NULL);
+ free(contents);
+}
+
+void
+webview_inspector_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+
+ td->web_inspector = ewk_view_single_add(evas_object_evas_get(ad->win));
+ ewk_view_theme_set(td->web_inspector, "/usr/share/ewebkit-0/themes/default.edj");
+
+ evas_object_size_hint_weight_set(td->web_inspector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(td->web_inspector, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ ewk_view_web_inspector_view_set(td->view, td->web_inspector);
+
+ evas_object_show(td->web_inspector);
+ elm_box_pack_end(ad->web_inspector, td->web_inspector);
+
+ evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 0.66);
+ evas_object_show(ad->web_inspector);
+
+ /*
+ td->web_inspector = elm_web_add(ad->win);
+
+ evas_object_size_hint_weight_set(td->web_inspector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(td->web_inspector, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ ewk_view_web_inspector_view_set(view, elm_web_webkit_view_get(td->web_inspector));
+
+ evas_object_show(td->web_inspector);
+ elm_box_pack_end(ad->web_inspector, td->web_inspector);
+
+ evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 1.0);
+ evas_object_show(ad->web_inspector);
+ */
+}
+
+void
+webview_inspector_close_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+
+ elm_box_clear(ad->web_inspector);
+ evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 0.0);
+ ewk_view_web_inspector_view_set(td->view, NULL);
+
+ td->web_inspector = NULL;
+}
+
+void
+webview_uri_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Arg a = { .i = Silent, .s = strdup(JS_SETUP_HINTS) };
+ Buffer_Data *td = data;
+ const char *uri = event_info;
+
+ if (td->web != td->app->cur_buf->web)
+ return;
+
+ // userscript_hooks_start(elm_web_uri_get(td->web));
+
+ script(&a, td->app);
+ free(a.s);
+
+ /*
+ FILE *fp = fopen("/home/kyle/.config/evi/userscript/adblockplus/contentScript1.js", "r");
+ if (!fp)
+ printf("error opening file.\n");
+ fseek(fp, 0L, SEEK_END);
+ int len = ftell(fp);
+ char *buf = malloc(len);
+ rewind(fp);
+ fread(buf, len, 1, fp);
+ fclose(fp);
+
+ ewk_frame_script_execute(frame, buf);
+
+ free(buf);
+ */
+
+ if (td->app->mode == ModeInsert || td->app->mode == ModeHints) {
+ Arg a = { .i = ModeNormal };
+ set(&a, td->app);
+ }
+
+ td->app->manual_focus = EINA_FALSE;
+ update_url(uri, td->app);
+}
+
+void
+webview_document_finished_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Hist_Item *item;
+ Buffer_Data *bd = data;
+ App_Data *ad = bd->app;
+ Evas_Object *frame = event_info;
+ const Ewk_Text_With_Direction *txt = ewk_frame_title_get(frame);
+ const char *url = ewk_frame_uri_get(frame);
+ const char *title = (txt ? txt->string : "");
+
+ if (!bd->history_enabled)
+ return;
+
+ if ((item = hist_items_get(ad->history, url))) {
+ hist_item_visit_count_set(item, hist_item_visit_count_get(item) + 1);
+ hist_item_last_visit_set(item, ecore_time_unix_get());
+ hist_item_title_set(item, title);
+ }
+ else {
+ hist_items_add(ad->history, url, hist_item_new(title, url, 1, ecore_time_unix_get()));
+ }
+}
+
+static Eina_Bool escape_input_on_load = TRUE; /* TRUE will disable automatic focusing of input fields via Javascript*/
+
+void
+webview_load_finished_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ /* WebKitWebSettings *settings = webkit_web_view_get_settings(webview); */
+ Buffer_Data *bd = data;
+ App_Data *ad = bd->app;
+ Eina_Bool scripts = 1;
+ Elm_Web_Frame_Load_Error *frame_error = event_info;
+
+ printf("load_finished()\n");
+
+ if (frame_error)
+ return;
+
+ /* g_object_get(settings, "enable-scripts", &scripts, NULL); */
+ if (escape_input_on_load && scripts && !ad->manual_focus && !elm_object_focus_get(ad->url)) {
+ Arg a = { .i = Silent, .s = strdup("hints.clearFocus();") };
+ script(&a, ad);
+ free(a.s);
+ a.i = ModeNormal;
+ a.s = NULL;
+ set(&a, ad);
+ }
+
+ update_state(ad);
+
+ // userscript_hooks_end(elm_web_uri_get(td->web));
+
+ /*
+ FILE *fp = fopen("/home/kyle/.config/evi/userscript/adblockplus/contentScript2.js", "r");
+ if (!fp)
+ printf("error opening file.\n");
+ fseek(fp, 0L, SEEK_END);
+ int len = ftell(fp);
+ char *buf = malloc(len);
+ rewind(fp);
+ fread(buf, len, 1, fp);
+ fclose(fp);
+
+ ewk_frame_script_execute(frame, buf);
+
+ free(buf);
+ */
+
+
+ // elm_object_focus_set(td->web, EINA_TRUE);
+}
+
+#if 0
+void
+webview_open_js_window_cb(WebKitWebView* temp_view, GParamSpec param_spec) {
+ /* retrieve the URI of the temporary webview */
+ Arg a = { .i = TargetNew, .s = (char*)webkit_web_view_get_uri(temp_view) };
+ /* clean up */
+ webkit_web_view_stop_loading(temp_view);
+ gtk_widget_destroy(GTK_WIDGET(temp_view));
+ /* open the requested window */
+ open_arg(&a);
+}
+
+static WebKitWebView *
+webview_open_in_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, gpointer user_data) {
+ /* create a temporary webview to execute the script in */
+ WebKitWebView *temp_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ /* wait until the new webview receives its new URI */
+ g_object_connect(temp_view, "signal::notify::uri", G_CALLBACK(webview_open_js_window_cb), NULL, NULL);
+ return temp_view;
+}
+
+Eina_Bool
+webview_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request,
+ WebKitWebNavigationAction *action, WebKitWebPolicyDecision *decision, gpointer user_data) {
+ Arg a = { .i = TargetNew, .s = (char*)webkit_network_request_get_uri(request) };
+ open_arg(&a);
+ webkit_web_policy_decision_ignore(decision);
+ return TRUE;
+}
+#endif
+
+/*
+Eina_Bool
+webview_mimetype_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request,
+ char *mime_type, WebKitWebPolicyDecision *decision, gpointer user_data) {
+ if (webkit_web_view_can_show_mime_type(webview, mime_type) == FALSE) {
+ webkit_web_policy_decision_download(decision);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+*/
+
+void
+download_entry_free_cb(void *data)
+{
+ free(data);
+}
+
+void
+download_complete_cb(void *data, const char *file, int status)
+{
+ App_Data *ad = data;
+ Arg a;
+ a.i = Info;
+ a.s = strdup_printf("Download %s finished, status %i", file, status);
+ echo(&a, data);
+ free(a.s);
+
+ // ad->active_downloads = eina_list_remove(ad->active_downloads, file);
+ eina_hash_del(ad->downloads, file, NULL);
+
+ update_state(data);
+}
+
+int
+download_progress_cb(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow)
+{
+ App_Data *ad = data;
+
+ void *stat_old;
+ struct dl *stat = malloc(sizeof(struct dl));
+
+ stat->dltotal = dltotal;
+ stat->dlnow = dlnow;
+
+ stat_old = eina_hash_modify(ad->downloads, file, (const void *)stat);
+ free(stat_old);
+
+ update_state(data);
+
+ return 0;
+}
+
+void
+webview_download_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Eina_Bool ret;
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+
+ Ewk_Download *dl = event_info;
+ char *suggested_name = strdup(strrchr(dl->url, '/'));
+
+ char *full_path = strdup_printf("/home/kyle/%s", suggested_name);
+
+ ret = ecore_file_download(dl->url, full_path, download_complete_cb,
+ download_progress_cb, ad, NULL);
+
+ /* if file already exists, ret == NULL */
+ if (!ret) {
+ Arg a;
+ a.i = Info;
+ a.s = strdup_printf("%s already exists!", suggested_name);
+ echo(&a, ad);
+ free(a.s);
+ return;
+ }
+
+ // ad->active_downloads = eina_list_append(ad->active_downloads, strdup(full_path));
+ eina_hash_add(ad->downloads, full_path, calloc(1, sizeof(struct dl)));
+
+ // free(full_path);
+ free(suggested_name);
+
+ update_state(ad);
+}
+
+
+void
+webview_mousewheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ update_state(td->app);
+}
+
+Eina_Bool
+process_keypress(void *event_info, void *data)
+{
+ KeyList *walk;
+ Key key;
+ // int keyval;
+ // GdkModifierType irrelevant;
+ App_Data *ad = data;
+ Evas_Event_Key_Down *ev = event_info;
+
+ // Get a mask of modifiers that shouldn't be considered for this event.
+ // E.g.: It shouldn't matter whether ';' is shifted or not.
+ // gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode,
+ // event->state, event->group, &keyval, NULL, NULL, &irrelevant);
+
+ walk = ad->keylistroot;
+ while (walk != NULL) {
+ key = walk->Element;
+ // if (current->Element.mask == (CLEAN(event->state) & ~irrelevant)
+ if ((key.mask == 0 || evas_key_modifier_is_set(ev->modifiers, key.mask))
+ && (key.modkey == ad->current_modkey
+ || (!key.modkey && !ad->current_modkey)
+ || key.modkey == '*' ) // wildcard
+ && !strcmp(key.key, ev->key)
+ && key.func)
+ if (key.func(&key.arg, data)) {
+ // printf("process_keypress() function for mask = %s modkey = %c key = %s called.\n", key.mask, ad->current_modkey, key.key);
+ ad->current_modkey = ad->count = 0;
+ update_state(data);
+ return TRUE;
+ }
+ walk = walk->next;
+ }
+ return FALSE;
+}
+
+void
+webview_keypress_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Arg a = { .i = ModeNormal, .s = NULL };
+ // int keyval;
+ Evas_Event_Key_Down *ev = event_info;
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+ // GdkModifierType irrelevant;
+
+ /* Get a mask of modifiers that shouldn't be considered for this event.
+ * E.g.: It shouldn't matter whether ';' is shifted or not. */
+ // gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode,
+ // event->state, event->group, &keyval, NULL, NULL, &irrelevant);
+
+ switch (ad->mode) {
+ case ModeNormal:
+ // if ((CLEAN(event->state) & ~irrelevant) == 0) {
+ if (IS_ESCAPE(ev)) {
+ a.i = Info;
+ a.s = strdup("");
+ echo(&a, ad);
+ elm_box_clear(ad->event_box);
+ evas_object_hide(ad->event_box);
+ free(a.s);
+ } else if (ad->current_modkey == 0 &&
+ (( strcmp(ev->key, "1") >= 0 && strcmp(ev->key, "9") <= 0)
+ || (!strcmp(ev->key, "0") && ad->count))) {
+ // ad->count = (ad->count ? ad->count * 10 : 0) + (ev->key - "0");
+ ad->count = (ad->count ? ad->count * 10 : 0) + atoi(ev->key);
+ update_state(ad);
+ return;
+ } else if (strchr(ad->modkeys, ev->key[0]) && ad->current_modkey != ev->key[0]) {
+ ad->current_modkey = ev->key[0];
+ // ad->current_modkey = strdup(ev->key);
+
+ update_state(ad);
+ return;
+ }
+ // }
+ /* keybindings */
+ if (process_keypress(event_info, ad) == TRUE) return;
+
+ break;
+ case ModeInsert:
+ if (IS_ESCAPE(ev)) {
+ a.i = Silent;
+ a.s = strdup("hints.clearFocus();");
+ script(&a, ad);
+ free(a.s);
+ a.i = ModeNormal;
+ set(&a, ad);
+ // ewk_view_input_method_state_set(td->web, FALSE);
+ return;
+ }
+ case ModePassThrough:
+ if (IS_ESCAPE(ev)) {
+ echo(&a, ad);
+ set(&a, ad);
+ return;
+ }
+ break;
+ case ModeSendKey:
+ echo(&a, ad);
+ set(&a, ad);
+ break;
+ }
+}
+
+void
+xss_detected_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ printf("xss_detected()\n");
+}
+
+void
+icon_received_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ printf("icon_received_cb()\n");
+}
+
+void
+webview_hoverlink_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ const char *uri = elm_web_uri_get(td->web);
+ /* event_info is a char *link[2] where the first string contains the URL
+ * and the second the title of the link */
+ char **link = event_info;
+ // char *markup;
+
+ memset(td->app->rememberedURI, 0, 1024);
+ if (link && link[0]) {
+ // markup = g_markup_printf_escaped("<span font=\"%s\">Link: %s</span>", statusfont, link[0]);
+ // markup = strdup_printf("<font=Monospace font_size=10 color=#FF0>%s", link[0]);
+ // gtk_label_set_markup(GTK_LABEL(td->app->status_url), markup);
+ // elm_object_text_set(td->app->status_url, markup);
+ update_url(link[0], td->app);
+ strcpy(td->app->rememberedURI, link[0]);
+ // free(markup);
+ } else
+ update_url(uri, td->app);
+}
+
+void
+webview_hoverlink_out_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Buffer_Data *td = data;
+ update_url(elm_web_uri_get(td->web), td->app);
+}
+
+void
+webview_console_cb(void *data, Evas_Object *obj, const char *message, unsigned int line, const char *source)
+{
+ Arg a;
+ Buffer_Data *td = data;
+
+ /* Don't change internal mode if the browser doesn't have focus to prevent inconsistent states */
+ // if (gtk_window_has_toplevel_focus(window)) {
+ if (elm_object_focus_get(td->app->win)) {
+ if (!strcmp(message, "hintmode_off") || !strcmp(message, "insertmode_off")) {
+ a.i = ModeNormal;
+ set(&a, td->app);
+ return;
+ } else if (!strcmp(message, "insertmode_on")) {
+ a.i = ModeInsert;
+ set(&a, td->app);
+ return;
+ }
+ }
+}
+
+void
+inputbox_activate_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *text;
+ App_Data *ad = data;
+ uint16_t length = strlen(elm_entry_entry_get(ad->url));
+ Arg a;
+ Eina_Bool forward = FALSE;
+
+ // printf("In inputbox_activate\n");
+
+ a.i = HideCompletion;
+ complete(&a, data);
+ if (length == 0)
+ return;
+ text = elm_entry_entry_get(ad->url);
+ if (length > 1 && text[0] == ':') {
+ process_line((text + 1), data);
+ } else if (length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
+ // webkit_web_view_unmark_text_matches(webview);
+ elm_web_text_matches_unmark_all(ad->cur_buf->web);
+
+ // webkit_web_view_mark_text_matches(webview, &text[1], FALSE, 0);
+ // webkit_web_view_set_highlight_text_matches(webview, TRUE);
+ elm_web_text_matches_mark(ad->cur_buf->web, &text[1], EINA_FALSE, EINA_TRUE, 0);
+
+ ad->count = 0;
+ ad->search_direction = forward;
+ ad->search_handle = strdup(&text[1]);
+ } else if (text[0] == '.' || text[0] == ',' || text[0] == ';') {
+ a.i = Silent;
+ a.s = strdup("hints.fire();");
+ script(&a, data);
+ free(a.s);
+ update_state(data);
+ } else
+ return;
+ if (!ad->echo_active)
+ // gtk_entry_set_text(entry, "");
+ elm_entry_entry_set(ad->url, "");
+ // gtk_widget_grab_focus(GTK_WIDGET(webview));
+
+ /* process_line above may have deleted the tab, check if its still around */
+ if (ad->cur_buf->web)
+ elm_object_focus_set(ad->cur_buf->web, EINA_TRUE);
+}
+
+static Eina_Bool
+commandhistoryfetch(const Arg *arg, void *data)
+{
+ App_Data *ad = data;
+ char *command;
+ const int length = eina_list_count(ad->commandhistory);
+
+ if (length > 0) {
+ if (arg->i == DirectionPrev) {
+ ad->commandpointer = (length + ad->commandpointer - 1) % length;
+ } else {
+ ad->commandpointer = (length + ad->commandpointer + 1) % length;
+ }
+
+ command = eina_list_nth(ad->commandhistory, ad->commandpointer);
+ // gtk_entry_set_text(GTK_ENTRY(inputbox), g_strconcat(":", command, NULL));
+ // gtk_editable_set_position(GTK_EDITABLE(inputbox), -1);
+ command = strdup_printf(":%s", command);
+ elm_entry_entry_set(ad->url, command);
+ free(command);
+ elm_entry_cursor_line_end_set(ad->url);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+inputbox_keypress_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Arg a;
+ int numval;
+ Evas_Event_Key_Down *ev = event_info;
+ App_Data *ad = data;
+
+ if (ad->mode == ModeHints) {
+ // if (event->keyval == GDK_ISO_Left_Tab) {
+ if (!strcmp(ev->keyname, "Tab") && evas_key_modifier_is_set(ev->modifiers, "Shift")) {
+ a.i = Silent;
+ a.s = strdup("hints.focusPreviousHint();");
+ script(&a, data);
+ free(a.s);
+ update_state(data);
+ return;
+ }
+ // if (event->keyval == GDK_Tab) {
+ if (!strcmp(ev->keyname, "Tab")) {
+ a.i = Silent;
+ a.s = strdup("hints.focusNextHint();");
+ script(&a, data);
+ free(a.s);
+ update_state(data);
+ return;
+ }
+ // if (event->keyval == GDK_Return) {
+ if (!strcmp(ev->keyname, "Return")) {
+ a.i = Silent;
+ a.s = strdup_printf("hints.fire();");
+ script(&a, data);
+ free(a.s);
+ update_state(data);
+ return;
+ }
+ }
+ if (!strcmp(ev->keyname, "[") || !strcmp(ev->keyname, "Escape")) {
+ a.i = HideCompletion;
+ complete(&a, data);
+ a.i = ModeNormal;
+ ad->commandpointer = 0;
+ set(&a, data);
+ return;
+ }
+ else if (!strcmp(ev->keyname, "Tab") && evas_key_modifier_is_set(ev->modifiers, "Shift")) {
+ a.i = DirectionPrev;
+ complete(&a, data);
+ return;
+ }
+ else if (!strcmp(ev->keyname, "Tab")) {
+ a.i = DirectionNext;
+ complete(&a, data);
+ return;
+ }
+ else if (!strcmp(ev->keyname, "Up")) {
+ a.i = DirectionPrev;
+ commandhistoryfetch(&a, data);
+ return;
+ }
+ else if (!strcmp(ev->keyname, "Down")) {
+ a.i = DirectionNext;
+ commandhistoryfetch(&a, data);
+ return;
+ }
+
+ /*
+ switch (event->keyval) {
+ case GDK_bracketleft:
+ case GDK_Escape:
+ if (!IS_ESCAPE(event)) break;
+ a.i = HideCompletion;
+ complete(&a, data);
+ a.i = ModeNormal;
+ commandpointer = 0;
+ return set(&a, ad);
+ break;
+ case GDK_Tab:
+ a.i = DirectionNext;
+ return complete(&a, data);
+ break;
+ case GDK_Up:
+ a.i = DirectionPrev;
+ return commandhistoryfetch(&a);
+ break;
+ case GDK_Down:
+ a.i = DirectionNext;
+ return commandhistoryfetch(&a);
+ break;
+ case GDK_ISO_Left_Tab:
+ a.i = DirectionPrev;
+ return complete(&a, data);
+ break;
+ }
+ */
+
+ if (ad->mode == ModeHints) {
+#if 0
+ if ((CLEAN(event->state) & GDK_SHIFT_MASK) &&
+ (CLEAN(event->state) & GDK_CONTROL_MASK) &&
+ (event->keyval == GDK_BackSpace)) {
+ count /= 10;
+ a.i = Silent;
+ a.s = g_strdup_printf("hints.updateHints(%d);", count);
+ script(&a, data);
+ g_free(a.s);
+ update_state();
+ return TRUE;
+ }
+#endif
+
+ // numval = g_unichar_digit_value((gunichar) gdk_keyval_to_unicode(event->keyval));
+ numval = atoi(ev->key);
+ if ((numval >= 1 && numval <= 9) || (numval == 0 && ad->count)) {
+ /* allow a zero as non-first number */
+ ad->count = (ad->count ? ad->count * 10 : 0) + numval;
+ a.i = Silent;
+ a.s = strdup_printf("hints.updateHints(%d);", ad->count);
+ script(&a, data);
+ free(a.s);
+ update_state(data);
+ return;
+ }
+ }
+}
+
+void
+inputmethod_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *value;
+ Eina_Bool *enabled = event_info;
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+ Evas_Object *frame = ewk_view_frame_main_get(td->view);
+
+ if (ad->mode == ModeNormal && enabled) {
+ Arg a = { .i = ModeInsert };
+ set(&a, ad);
+ ad->manual_focus = TRUE;
+ } else if (ad->mode == ModeInsert && !enabled) {
+ Arg a = { .i = ModeNormal };
+ set(&a, ad);
+ } else {
+ // char *value = NULL, *message = NULL;
+ // jsapi_evaluate_script("window.getSelection().focusNode", &value, &message, ad);
+ value = ewk_frame_script_execute(frame, "window.getSelection().focusNode");
+ if (value && !strcmp(value, "[object HTMLFormElement]")) {
+ Arg a = { .i = ModeInsert, .s = NULL };
+ set(&a, ad);
+ ad->manual_focus = TRUE;
+ }
+ // free(value);
+ eina_stringshare_del(value);
+ // free(message);
+ }
+}
+
+/*
+static void
+// notify_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
+notify_event_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ int i;
+ // WebKitHitTestResult *result;
+ // WebKitHitTestResultContext context;
+ Ewk_Hit_Test *result;
+ Ewk_Hit_Test_Result_Context context;
+
+ Evas_Event_Mouse_Up *ev = event_info;
+ Buffer_Data *td = data;
+ App_Data *ad = td->app;
+
+ Evas_Object *view = elm_web_webkit_view_get(td->web);
+ Evas_Object *frame = ewk_view_frame_main_get(view);
+
+ // if (mode == ModeNormal && event->type == GDK_BUTTON_RELEASE) {
+ if (ad->mode == ModeNormal) {
+ // handle mouse click events
+ for (i = 0; i < LENGTH(mouse); i++) {
+ // if (mouse[i].mask == CLEAN(event->button.state)
+ if ( (mouse[i].mask == 0 || evas_key_modifier_is_set(ev->modifiers, mouse[i].mask))
+ // && (mouse[i].modkey == current_modkey
+ && ((ad->current_modkey && !strcmp(mouse[i].modkey, ad->current_modkey))
+ || (!mouse[i].modkey && !ad->current_modkey)
+ // || mouse[i].modkey == GDK_VoidSymbol) // wildcard
+ || !strcmp(mouse[i].modkey, "*")) // wildcard
+ // && mouse[i].button == event->button.button
+ && (mouse[i].button & ev->button)
+ && mouse[i].func) {
+ if (mouse[i].func(&mouse[i].arg, ad)) {
+ // current_modkey = count = 0;
+ ad->current_modkey = NULL;
+ ad->count = 0;
+ update_state(ad);
+ return TRUE;
+ }
+ }
+ }
+ // result = webkit_web_view_get_hit_test_result(WEBKIT_WEB_VIEW(widget), (GdkEventButton*)event);
+ result = ewk_frame_hit_test_new(frame, ev->canvas.x, ev->canvas.y);
+ context = result->context;
+
+ // g_object_get(result, "context", &context, NULL);
+ // if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE) {
+ if (context & EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE) {
+ Arg a = { .i = ModeInsert };
+ set(&a, ad);
+ ad->manual_focus = TRUE;
+ }
+ // } else if (mode == ModeInsert && event->type == GDK_BUTTON_RELEASE) {
+ } else if (ad->mode == ModeInsert) {
+ //result = webkit_web_view_get_hit_test_result(WEBKIT_WEB_VIEW(widget), (GdkEventButton*)event);
+ result = ewk_frame_hit_test_new(frame, ev->output.x, ev->output.y);
+
+ // g_object_get(result, "context", &context, NULL);
+ // if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) {
+ if (!(context & EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE)) {
+ Arg a = { .i = ModeNormal };
+ set(&a, ad);
+ }
+ } else {
+ char *value = NULL, *message = NULL;
+ jsapi_evaluate_script("window.getSelection().focusNode", &value, &message, ad);
+ if (value && !strcmp(value, "[object HTMLFormElement]")) {
+ Arg a = { .i = ModeInsert, .s = NULL };
+ set(&a, ad);
+ ad->manual_focus = TRUE;
+ }
+ free(value);
+ free(message);
+ }
+ ewk_frame_hit_test_free(result);
+ return FALSE;
+}
+*/
+
+void
+inputbox_keyrelease_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Arg a;
+ App_Data *ad = data;
+ // guint16 length = gtk_entry_get_text_length(entry);
+ uint16_t length = strlen(elm_entry_entry_get(ad->url));
+
+ if (!length) {
+ a.i = HideCompletion;
+ complete(&a, data);
+ a.i = ModeNormal;
+ set(&a, data);
+ }
+}
+
+/* used for incremental search */
+void
+inputbox_changed_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Arg a;
+ App_Data *ad = data;
+ const char *text = elm_entry_entry_get(ad->url);
+ uint16_t length = strlen(text);
+ Eina_Bool forward = FALSE;
+
+ /* Update incremental search if the user changes the search text.
+ *
+ * Note: gtk_widget_is_focus() is a poor way to check if the change comes
+ * from the user. But if the entry is focused and the text is set
+ * through gtk_entry_set_text() in some asyncrounous operation,
+ * I would consider that a bug.
+ */
+
+ // if (gtk_widget_is_focus(GTK_WIDGET(entry)) && length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
+ if (elm_object_focus_get(ad->url) && length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
+ // webkit_web_view_unmark_text_matches(webview);
+ elm_web_text_matches_unmark_all(ad->cur_buf->web);
+
+ // webkit_web_view_search_text(webview, &text[1], searchoptions & CaseSensitive, forward, searchoptions & Wrapping);
+ elm_web_text_search(ad->cur_buf->web, &text[1], EINA_TRUE, forward, EINA_FALSE);
+ return;
+ // } else if (gtk_widget_is_focus(GTK_WIDGET(entry)) && length >= 1 &&
+ } else if (elm_object_focus_get(ad->url) && length >= 1 &&
+ (text[0] == '.' || text[0] == ',' || text[0] == ';')) {
+ a.i = Silent;
+ switch (text[0]) {
+ case '.':
+ // a.s = strconcat("hints.createHints('", text + 1, "', 'f');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'f');", text + 1);
+ break;
+
+ case ',':
+ // a.s = strconcat("hints.createHints('", text + 1, "', 'F');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'F');", text + 1);
+ break;
+
+ case ';':
+ a.s = NULL;
+ switch (text[1]) {
+ case 's':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 's');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 's');", text + 2);
+ break;
+ case 'y':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'y');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'y');", text + 2);
+ break;
+ case 'o':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'f');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'f');", text + 2);
+ break;
+ case 't': case 'w':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'F');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'F');", text + 2);
+ break;
+ case 'O': case 'T': case 'W':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'O');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'O');", text + 2);
+ break;
+ case 'i':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'i');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'i');", text + 2);
+ break;
+ case 'I':
+ // a.s = strconcat("hints.createHints('", text + 2, "', 'I');", NULL);
+ a.s = strdup_printf("hints.createHints('%s', 'I');", text + 2);
+ break;
+ }
+ break;
+ }
+ ad->count = 0;
+ if (a.s) {
+ script(&a, data);
+ free(a.s);
+ }
+
+ return;
+ } else if (length == 0 && ad->followTarget[0]) {
+ ad->mode = ModeNormal;
+ a.i = Silent;
+ a.s = strdup("hints.clearHints();");
+ script(&a, data);
+ free(a.s);
+ ad->count = 0;
+ update_state(data);
+ }
+}
+
diff --git a/callbacks.h b/callbacks.h
@@ -0,0 +1,35 @@
+
+
+void inputbox_activate_cb (void *, Evas_Object *, void *);
+void inputbox_changed_cb (void *, Evas_Object *, void *);
+void inputbox_keypress_cb (void *, Evas *, Evas_Object *, void *);
+void inputbox_keyrelease_cb (void *, Evas *, Evas_Object *, void *);
+
+void webview_console_cb(void *, Evas_Object *, const char *, unsigned int, const char *);
+void webview_hoverlink_cb (void *, Evas_Object *, void*);
+void webview_hoverlink_out_cb (void *, Evas_Object *, void*);
+void webview_uri_changed_cb (void *, Evas_Object *, void*);
+void webview_load_finished_cb (void *, Evas_Object *, void*);
+void webview_document_finished_cb(void *, Evas_Object *, void*);
+void webview_progress_changed_cb(void *, Evas_Object *, void *);
+void webview_title_changed_cb (void *, Evas_Object *, void *);
+void webview_download_cb (void *, Evas_Object *, void *);
+void inputmethod_changed_cb (void *, Evas_Object *, void *);
+void icon_received_cb (void *, Evas_Object *, void *);
+void xss_detected_cb (void *, Evas_Object *, void *);
+void webview_inspector_cb (void *, Evas_Object *, void *);
+void webview_inspector_close_cb (void *, Evas_Object *, void *);
+void protocol_register_cb (void *, Evas_Object *, void *);
+void load_error_cb (void *, Evas_Object *, void *);
+void webview_keypress_cb (void *, Evas *, Evas_Object *, void *);
+void webview_mousewheel_cb (void *, Evas *, Evas_Object *, void *);
+
+void download_entry_free_cb(void *);
+
+/*
+static Eina_Bool webview_mimetype_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request, char *mime_type, WebKitWebPolicyDecision *decision, gpointer user_data);
+static void webview_open_js_window_cb(WebKitWebView* temp_view, GParamSpec param_spec);
+static Eina_Bool webview_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *action, WebKitWebPolicyDecision *decision, gpointer user_data);
+static WebKitWebView* webview_open_in_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, gpointer user_data);
+*/
+
diff --git a/commands.c b/commands.c
@@ -4,13 +4,13 @@
#include <libsoup/soup.h>
#include "viking.h"
+#include "viking_state.h"
#include "commands.h"
#include "utilities.h"
#include "main.h"
-extern unsigned int scrollstep;
-extern unsigned int pagingkeep;
-extern char defaultsearch[MAX_SETTING_SIZE];
+static unsigned int scrollstep = 40; /* cursor difference in pixel */
+static unsigned int pagingkeep = 40; /* pixels kept when paging */
void fill_suggline(char * suggline, const char * command, const char *fill_with);
@@ -466,6 +466,8 @@ number(const Arg *arg, void *data)
return TRUE;
}
+static char defaultsearch[MAX_SETTING_SIZE] = "d";
+
Eina_Bool
open_arg(const Arg *arg, void *data)
{
@@ -1382,29 +1384,34 @@ list(const Arg *arg, void *data)
elm_box_pack_end(ad->event_box, row);
evas_object_show(row);
- icon = ewk_settings_icon_database_icon_object_get(elm_web_uri_get(td->web), e);
- // evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(icon, 0.0, EVAS_HINT_FILL);
- evas_object_size_hint_max_set(icon, 16, 16);
- evas_object_size_hint_min_set(icon, 16, 16);
- elm_box_pack_end(row, icon);
- evas_object_show(icon);
-
label = elm_label_add(ad->win);
// evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
elm_box_pack_end(row, label);
evas_object_show(label);
- count_str = strdup_printf("<font=Monospace font_size=12>%i. ", td->buf_number);
- elm_object_text_set(label, count_str);
- free(count_str);
+ char status_buf[512] = "";
+ strcat(status_buf, "<font=Monospace font_size=12 backing=on backing_color=#FFF>");
+
+ char *flags_str = status_flags(td);
+ strcat(status_buf, flags_str);
+ free(flags_str);
+
+ elm_object_text_set(label, status_buf);
+
+ icon = ewk_settings_icon_database_icon_object_get(elm_web_uri_get(td->web), e);
+ // evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(icon, 0.0, EVAS_HINT_FILL);
+ evas_object_size_hint_max_set(icon, 14, 14);
+ evas_object_size_hint_min_set(icon, 14, 14);
+ elm_box_pack_end(row, icon);
+ evas_object_show(icon);
label = elm_label_add(ad->win);
evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
elm_box_pack_end(row, label);
evas_object_show(label);
- url = strdup_printf("<font=Monospace font_size=12>%s", elm_web_uri_get(td->web));
+ url = strdup_printf("<font=Monospace font_size=12 backing=on backing_color=#FFF>%s", elm_web_uri_get(td->web));
elm_object_text_set(label, url);
free(url);
@@ -1413,7 +1420,7 @@ list(const Arg *arg, void *data)
evas_object_size_hint_align_set(label, 1.0, EVAS_HINT_FILL);
elm_box_pack_end(row, label);
evas_object_show(label);
- count_str = strdup_printf("<font=Monospace font_size=12>%s", elm_web_title_get(td->web));
+ count_str = strdup_printf("<font=Monospace font_size=12 backing=on backing_color=#FFF>%s", elm_web_title_get(td->web));
elm_object_text_set(label, count_str);
free(count_str);
}
@@ -1421,6 +1428,29 @@ list(const Arg *arg, void *data)
evas_object_show(ad->event_box);
+ /*
+ elm_layout_sizing_eval(ad->event_box);
+
+ int x, y, w, h;
+ evas_object_geometry_get(ad->event_box, &x, &y, &w, &h);
+ printf("list() event_box is (x, y, w, h) = (%i, %i, %i, %i)\n", x, y, w, h);
+ evas_object_move(ad->event_box_bg, x, y);
+ evas_object_resize(ad->event_box_bg, w, 100);
+ evas_object_show(ad->event_box_bg);
+ */
+
+
+ /*
+ bg = evas_object_rectangle_add(evas_object_evas_get(ad->win));
+ // bg = elm_bg_add(ad->event_box);
+ evas_object_color_set(bg, 255, 255, 255, 255);
+ evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ // elm_box_pack_end(ad->event_box, bg);
+ evas_object_show(bg);
+ ecore_evas_object_associate(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win)), bg, ECORE_EVAS_OBJECT_ASSOCIATE_BASE);
+ */
+
return EINA_TRUE;
}
diff --git a/commands.h b/commands.h
@@ -1,7 +1,4 @@
-// #include "config.h"
-// #include "utilities.h"
-
Eina_Bool complete(const Arg *, void *);
Eina_Bool script(const Arg *, void *);
Eina_Bool open_arg(const Arg *, void *);
@@ -36,7 +33,7 @@ Eina_Bool toggle_history(const Arg *, void *);
Eina_Bool process_set_line(char *line);
-extern char startpage[MAX_SETTING_SIZE];
+// extern char startpage[MAX_SETTING_SIZE];
/* command mapping */
static Command commands[COMMANDSIZE] = {
diff --git a/config.h b/config.h
@@ -1,155 +0,0 @@
-/*
- (c) 2009 by Leon Winter
- (c) 2009-2012 by Hannes Schueller
- (c) 2009-2010 by Matto Fransen
- (c) 2010-2011 by Hans-Peter Deifel
- (c) 2010-2011 by Thomas Adam
- (c) 2011 by Albert Kim
- see LICENSE file
-*/
-
-/* Vimprobable version number */
-#define VERSION "1"
-#define INTERNAL_VERSION "Evi/"VERSION
-
-/* general settings */
-char startpage[MAX_SETTING_SIZE] = "http://www.getaddrinfo.net/";
-// static char useragent[MAX_SETTING_SIZE] = "Vimprobable2/" VERSION;
-// static char acceptlanguage[MAX_SETTING_SIZE] = "";
-static const Eina_Bool enablePlugins = TRUE; /* TRUE keeps plugins enabled */
-static const Eina_Bool enableJava = TRUE; /* FALSE disables Java applets */
-static const Eina_Bool enablePagecache = FALSE; /* TRUE turns on the page cache. */
-static Eina_Bool escape_input_on_load = TRUE; /* TRUE will disable automatic focusing of input fields via Javascript*/
-
-/* appearance */
-// static char statusbgcolor[MAX_SETTING_SIZE] = "#000"; /* background color for status bar */
-// static char statuscolor[MAX_SETTING_SIZE] = "#FFF"; /* color for status bar */
-// static char sslbgcolor[MAX_SETTING_SIZE] = "#b0ff00"; /* background color for status bar with SSL url */
-// static char sslinvalidbgcolor[MAX_SETTING_SIZE]= "#ff0000"; /* background color for status bar with unverified SSL url */
-// static char sslcolor[MAX_SETTING_SIZE] = "#0F0"; /* color for status bar with SSL url */
-
- /* normal, warning, error */
-static const char *urlboxfont[] = { "monospace normal 8", "monospace normal 8", "monospace bold 8"};
-static const char *urlboxcolor[] = { NULL, "#ff0000", "#ffffff" };
-static const char *urlboxbgcolor[] = { NULL, NULL, "#ff0000" };
-
- /* normal, error */
-// static const char *completionfont[] = { "monospace normal 8", "monospace bold 8" };
- /* topborder color */
-static const unsigned char completioncolor[][3] = { {0, 0, 0}, {255, 0, 255}, {0, 0, 0} };
-/* current row background */
-static const unsigned char completionbgcolor[][3] = { {255, 255, 255}, {255, 255, 255}, {255, 240, 0} };
-/* pango markup for prefix highliting: opening, closing */
-#define COMPLETION_TAG_OPEN "<b>"
-#define COMPLETION_TAG_CLOSE "</b>"
-
-static const char statusfont[] = "monospace bold 8"; /* font for status bar */
-static const int progressbartick = 20;
-static const char progressborderleft = '[';
-static const char progressbartickchar = '=';
-static const char progressbarcurrent = '>';
-static const char progressbarspacer = ' ';
-static const char progressborderright = ']';
-
-/* external handlers:
- * the handle (first string) contain what the handled links have to start with
- * the handlers (second string) contain the external applications which should be called for this sort of link
- * %s can be used as a placeholder for the link argument after the handler
- * e.g.: "mailto:user@example.org
- * "handle" is "mailto:"
- * "%s" will translate to "user@example.org"
- */
-static URIHandler uri_handlers[] = {
- { "mailto:", "x-terminal-emulator -e mutt %s" },
- { "ftp://", "x-terminal-emulator -e wget ftp://%s" },
-};
-
-/* cookies */
-#define ENABLE_COOKIE_SUPPORT
-#define COOKIES_STORAGE_FILENAME "%s/evi/cookies", config_base
-#define COOKIES_STORAGE_READONLY FALSE /* if TRUE new cookies will be lost if you quit */
-
-/* downloads directory */
-#define DOWNLOADS_PATH "%s", getenv("HOME")
-
-/* font size */
-#define DEFAULT_FONT_SIZE 12
-
-/* user styles */
-#define USER_STYLESHEET "%s/evi/style.css", config_base
-
-/* ssl */
-static Eina_Bool strict_ssl = TRUE; /* FALSE will accept any SSL certificate at face value */
-static char ca_bundle[MAX_SETTING_SIZE] = "/etc/ssl/certs/ca-certificates.crt";
-
-/* proxy */
-static const Eina_Bool use_proxy = TRUE; /* TRUE if you're going to use a proxy (whose address
- is specified in http_proxy environment variable), false otherwise */
-/* scrolling */
-unsigned int scrollstep = 40; /* cursor difference in pixel */
-unsigned int pagingkeep = 40; /* pixels kept when paging */
-#define DISABLE_SCROLLBAR
-
-/* searching */
-#define ENABLE_MATCH_HIGHLITING
-static const int searchoptions = CaseInsensitive | Wrapping;
-Eina_Bool complete_case_sensitive = TRUE;
-
-/* search engines */
-static Searchengine searchengines[] = {
- { "d", "https://duckduckgo.com/?q=%s&t=Vimprobable" },
- { "i", "http://ixquick.com/do/metasearch.pl?query=%s" },
- { "w", "https://secure.wikimedia.org/wikipedia/en/w/index.php?title=Special%%3ASearch&search=%s&go=Go" },
- { "wd", "https://secure.wikimedia.org/wikipedia/de/w/index.php?title=Special%%3ASearch&search=%s&go=Go" },
- { "dd", "https://duckduckgo.com/html/?q=%s&t=Vimprobable" },
-};
-
-char defaultsearch[MAX_SETTING_SIZE] = "d";
-
-#if 0
-/* settings (arguments of :set command) */
-static Setting browsersettings[] = {
-/* public name, internal variwebkit setting integer ? bool? colour? reload page? */
- { "useragent", useragent, "user-agent", FALSE, FALSE, FALSE, FALSE },
- { "scripts", NULL, "enable-scripts", FALSE, TRUE, FALSE, FALSE },
- { "plugins", NULL, "enable-plugins", FALSE, TRUE, FALSE, FALSE },
- { "pagecache", NULL, "enable-page-cache", FALSE, TRUE, FALSE, FALSE },
- { "java", NULL, "enable-java-applet", FALSE, TRUE, FALSE, FALSE },
- { "images", NULL, "auto-load-images", FALSE, TRUE, FALSE, FALSE },
- { "shrinkimages", NULL, "auto-shrink-images", FALSE, TRUE, FALSE, FALSE },
- { "cursivefont", NULL, "cursive-font-family", FALSE, FALSE, FALSE, FALSE },
- { "defaultencoding", NULL, "default-encoding", FALSE, FALSE, FALSE, FALSE },
- { "defaultfont", NULL, "default-font-family", FALSE, FALSE, FALSE, FALSE },
- { "fontsize", NULL, "default-font-size", TRUE, FALSE, FALSE, FALSE },
- { "monofontsize", NULL, "default-monospace-font-size", TRUE, FALSE, FALSE, FALSE },
- { "caret", NULL, "enable-caret-browsing", FALSE, TRUE, FALSE, FALSE },
- { "fantasyfont", NULL, "fantasy-font-family", FALSE, FALSE, FALSE, FALSE },
- { "minimumfontsize", NULL, "minimum-font-size", TRUE, FALSE, FALSE, FALSE },
- { "monofont", NULL, "monospace-font-family", FALSE, FALSE, FALSE, FALSE },
- { "backgrounds", NULL, "print-backgrounds", FALSE, TRUE, FALSE, FALSE },
- { "sansfont", NULL, "sans-serif-font-family", FALSE, FALSE, FALSE, FALSE },
- { "seriffont", NULL, "serif-font-family", FALSE, FALSE, FALSE, FALSE },
- { "stylesheet", NULL, "user-stylesheet-uri", FALSE, FALSE, FALSE, FALSE },
- { "resizetextareas", NULL, "resizable-text-areas", FALSE, TRUE, FALSE, FALSE },
- { "webinspector", NULL, "enable-developer-extras", FALSE, TRUE, FALSE, FALSE },
-
- { "homepage", startpage, "", FALSE, FALSE, FALSE, FALSE },
- { "statusbgcolor", statusbgcolor,"", FALSE, FALSE, TRUE, TRUE },
- { "statuscolor", statuscolor, "", FALSE, FALSE, TRUE, TRUE },
- { "sslbgcolor", sslbgcolor, "", FALSE, FALSE, TRUE, TRUE },
- { "sslcolor", sslcolor, "", FALSE, FALSE, TRUE, TRUE },
- { "acceptlanguage", acceptlanguage, "", FALSE, FALSE, FALSE, FALSE },
- { "defaultsearch", defaultsearch, "", FALSE, FALSE, FALSE, FALSE },
- { "qmark", NULL, "", FALSE, FALSE, FALSE, FALSE },
- { "proxy", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "windowsize", NULL, "", FALSE, FALSE, FALSE, FALSE },
- { "scrollbars", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "statusbar", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "inputbox", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "completioncase", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "escapeinput", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "strictssl", NULL, "", FALSE, TRUE, FALSE, FALSE },
- { "cabundle", ca_bundle, "", FALSE, FALSE, FALSE, FALSE },
-};
-#endif
-
diff --git a/keymap.h b/keymap.h
@@ -83,8 +83,8 @@ static Key keys[] = {
{ 0, 'g', "u", descend, {NthSubdir} },
{ 0, 'g', "U", descend, {Rootdir} },
- { 0, 'g', "h", open_arg, {TargetCurrent, startpage} },
- { 0, 'g', "H", open_arg, {TargetNew, startpage} },
+ { 0, 'g', "h", open_arg, {TargetCurrent, DEFAULT_URL} },
+ { 0, 'g', "H", open_arg, {TargetNew, DEFAULT_URL} },
{ "Control", 0, "p", proxy, {0} },
{ 0, 0, "p", paste, {TargetCurrent | ClipboardPrimary | ClipboardGTK} },
diff --git a/main.c b/main.c
@@ -16,10 +16,11 @@
#include "javascript.h"
#include "viking.h"
+#include "viking_state.h"
#include "main.h"
#include "commands.h"
#include "utilities.h"
-#include "config.h"
+#include "callbacks.h"
#include "keymap.h"
#include <stdio.h> /* asprintf() */
@@ -29,53 +30,12 @@
EAPI_MAIN int elm_main(int argc, char *argv[]);
-#define IS_ESCAPE(ev) ((!strcmp(ev->keyname, "Escape")) || \
- (!strcmp(ev->keyname, "[") && evas_key_modifier_is_set(ev->modifiers, "Control")))
-
-
-/* callbacks here */
-static void inputbox_activate_cb (void *, Evas_Object *, void *);
-static void inputbox_changed_cb (void *, Evas_Object *, void *);
-static Eina_Bool commandhistoryfetch (const Arg *, void *);
-static void inputbox_keypress_cb (void *, Evas *, Evas_Object *, void *);
-static void inputbox_keyrelease_cb (void *, Evas *, Evas_Object *, void *);
-
-static void webview_console_cb(void *, Evas_Object *, const char *, unsigned int, const char *);
-static void webview_hoverlink_cb (void *, Evas_Object *, void*);
-static void webview_hoverlink_out_cb (void *, Evas_Object *, void*);
-static void webview_uri_changed_cb (void *, Evas_Object *, void*);
-static void webview_load_finished_cb (void *, Evas_Object *, void*);
-static void webview_document_finished_cb(void *, Evas_Object *, void*);
-static void history(void *);
-static void webview_progress_changed_cb(void *, Evas_Object *, void *);
-static void webview_title_changed_cb (void *, Evas_Object *, void *);
-static void webview_download_cb (void *, Evas_Object *, void *);
-static void inputmethod_changed_cb (void *, Evas_Object *, void *);
-static void icon_received_cb (void *, Evas_Object *, void *);
-static void xss_detected_cb (void *, Evas_Object *, void *);
-static void webview_inspector_cb (void *, Evas_Object *, void *);
-static Eina_Bool process_keypress (void *, void*);
-static void webview_keypress_cb (void *, Evas *, Evas_Object *, void *);
-static void webview_mousewheel_cb (void *, Evas *, Evas_Object *, void *);
-Evas_Object *webview_create_window_cb(void*, Evas_Object*, Eina_Bool, const Elm_Web_Window_Features*);
-
-/*
-static WebKitWebView* inspector_inspect_web_view_cb(gpointer inspector, WebKitWebView* web_view);
-static Eina_Bool webview_mimetype_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request, char *mime_type, WebKitWebPolicyDecision *decision, gpointer user_data);
-static void webview_open_js_window_cb(WebKitWebView* temp_view, GParamSpec param_spec);
-static Eina_Bool webview_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *action, WebKitWebPolicyDecision *decision, gpointer user_data);
-static WebKitWebView* webview_open_in_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, gpointer user_data);
-*/
+Evas_Object *webview_create_window_cb(void*, Evas_Object*, Eina_Bool, const Elm_Web_Window_Features*);
/* functions */
static void ascii_bar(int total, int state, char *string);
-// static char *jsapi_ref_to_string(JSContextRef context, JSValueRef ref);
-// static void jsapi_evaluate_script(const gchar *script, gchar **value, gchar **message, void *data);
-static void set_widget_font_and_color(Evas_Object *widget, const char *font_str, const char *bg_color_str, const char *fg_color_str);
-void download_complete_cb(void*, const char*, int);
-int download_progress_cb(void*, const char*, long int, long int, long int, long int);
-
+char *uri_sanitize(const char *);
Eina_Bool
enable_proxy(Buffer_Data *bd)
@@ -109,6 +69,14 @@ enable_proxy(Buffer_Data *bd)
}
}
+static const char statusfont[] = "monospace bold 8"; /* font for status bar */
+static const int progressbartick = 20;
+static const char progressborderleft = '[';
+static const char progressbartickchar = '=';
+static const char progressbarcurrent = '>';
+static const char progressbarspacer = ' ';
+static const char progressborderright = ']';
+
static void
ascii_bar(int total, int state, char *string)
{
@@ -227,48 +195,72 @@ update_state(void *data)
// recalculate_status_bar(data);
}
-static void
+char*
+/* must free() the return value */
+status_flags(void *data)
+{
+ char *end;
+ Buffer_Data *bd = data;
+ char *flags = calloc(32, 1);
+
+ strcat(flags, "[");
+ strcat(flags, bd->proxy_enabled ? "P" : " ");
+ strcat(flags, bd->inspector_enabled ? "I" : " ");
+ strcat(flags, bd->history_enabled ? "H" : " ");
+ end = strdup_printf("] %i ", bd->buf_number);
+ strcat(flags, end);
+ free(end);
+
+ return flags;
+}
+
+void
update_url(const char *uri, void *data)
{
- char *markup;
+ char *tmp;
char before[] = " [";
char after[] = "]";
+ char url_buf[1024] = "";
+ App_Data *ad = data;
+ Buffer_Data *bd = ad->cur_buf;
if (uri == NULL)
return;
- App_Data *ad = data;
- Eina_Bool back = elm_web_back_possible_get(ad->cur_buf->web);
- Eina_Bool fwd = elm_web_forward_possible_get(ad->cur_buf->web);
+ Eina_Bool back = elm_web_back_possible_get(bd->web);
+ Eina_Bool fwd = elm_web_forward_possible_get(bd->web);
- Evas_Object *frame = ewk_view_frame_main_get(ad->cur_buf->view);
+ Evas_Object *frame = ewk_view_frame_main_get(bd->view);
char *url_color = "#FFF";
if (!strncmp(uri, "https://", 8)) {
Ewk_Certificate_Status cert_status = ewk_frame_certificate_status_get(frame);
if (cert_status & EWK_CERTIFICATE_STATUS_TRUSTED)
- url_color = "#0F0";
+ url_color = "#6F6";
else if (cert_status & EWK_CERTIFICATE_STATUS_UNTRUSTED)
- url_color = "#F00";
+ url_color = "#F66";
}
if (!back && !fwd)
before[0] = after[0] = '\0';
- markup = strdup_printf("<font=Monospace font_size=12 color=%s backing=on backing_color=#000>%s%s%s%s%s",
+ strcat(url_buf, "<font=Monospace font_size=12 color=#FFF>");
+ tmp = status_flags(bd);
+ strcat(url_buf, tmp);
+ free(tmp);
+ tmp = strdup_printf("<color=%s>%s<color=#FFF>%s%s%s%s",
url_color, uri, before, back ? "+" : "", fwd ? "-" : "", after);
-
+ strcat(url_buf, tmp);
+ free(tmp);
int state_width, window_width;
evas_object_geometry_get(ad->status_state, NULL, NULL, &state_width, NULL);
evas_object_geometry_get(ad->win, NULL, NULL, &window_width, NULL);
elm_label_wrap_width_set(ad->status_url, window_width - state_width);
- elm_object_text_set(ad->status_url, markup);
+ elm_object_text_set(ad->status_url, url_buf);
// elm_label_line_wrap_set(ad->status_url, ELM_WRAP_CHAR);
// elm_label_ellipsis_set(ad->status_url, EINA_TRUE);
-
- free(markup);
}
Eina_Bool
@@ -283,7 +275,7 @@ echo(const Arg *arg, void *data)
// printf("echo(%s)\n", arg->s);
// if (!gtk_widget_is_focus(GTK_WIDGET(inputbox))) {
if (!elm_object_focus_get(ad->url)) {
- set_widget_font_and_color(ad->url, urlboxfont[index], urlboxbgcolor[index], urlboxcolor[index]);
+ // set_widget_font_and_color(ad->url, urlboxfont[index], urlboxbgcolor[index], urlboxcolor[index]);
// gtk_entry_set_text(GTK_ENTRY(inputbox), !arg->s ? "" : arg->s);
elm_entry_entry_set(ad->url, !arg->s ? "" : arg->s);
}
@@ -291,520 +283,10 @@ echo(const Arg *arg, void *data)
return TRUE;
}
-void
-webview_title_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
- /*
- const char *title = "";
- Ewk_Text_With_Direction *dir_text = event_info;
- if (event_info) title = dir_text->string;
- char buf[20] = "";
-
- if (title)
- strncpy(buf, title, sizeof(buf) - 1);
- elm_object_item_text_set(td->tab, buf);
- */
-}
-
-void
-webview_progress_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- /* *event_info is a double between 0.0 and 1.0 */
- update_state(td->app);
-}
-
-
-static void
-protocol_register_cb(void *data, Evas_Object *obj, void *event_info)
-{
- printf("protocol_register()\n");
-}
-
-static void
-webview_inspector_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- App_Data *ad = td->app;
-
- td->web_inspector = ewk_view_single_add(evas_object_evas_get(ad->win));
- ewk_view_theme_set(td->web_inspector, "/usr/share/ewebkit-0/themes/default.edj");
-
- evas_object_size_hint_weight_set(td->web_inspector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(td->web_inspector, EVAS_HINT_FILL, EVAS_HINT_FILL);
-
- ewk_view_web_inspector_view_set(td->view, td->web_inspector);
-
- evas_object_show(td->web_inspector);
- elm_box_pack_end(ad->web_inspector, td->web_inspector);
-
- evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 0.66);
- evas_object_show(ad->web_inspector);
-
- /*
- td->web_inspector = elm_web_add(ad->win);
-
- evas_object_size_hint_weight_set(td->web_inspector, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(td->web_inspector, EVAS_HINT_FILL, EVAS_HINT_FILL);
-
- ewk_view_web_inspector_view_set(view, elm_web_webkit_view_get(td->web_inspector));
-
- evas_object_show(td->web_inspector);
- elm_box_pack_end(ad->web_inspector, td->web_inspector);
-
- evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 1.0);
- evas_object_show(ad->web_inspector);
- */
-}
-
-static void
-webview_inspector_close_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- App_Data *ad = td->app;
-
- elm_box_clear(ad->web_inspector);
- evas_object_size_hint_weight_set(ad->web_inspector, EVAS_HINT_EXPAND, 0.0);
- ewk_view_web_inspector_view_set(td->view, NULL);
-
- td->web_inspector = NULL;
-}
-
-void
-webview_uri_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Arg a = { .i = Silent, .s = strdup(JS_SETUP_HINTS) };
- Buffer_Data *td = data;
- const char *uri = event_info;
-
- if (td->web != td->app->cur_buf->web)
- return;
-
- // userscript_hooks_start(elm_web_uri_get(td->web));
-
- script(&a, td->app);
- free(a.s);
-
- /*
- FILE *fp = fopen("/home/kyle/.config/evi/userscript/adblockplus/contentScript1.js", "r");
- if (!fp)
- printf("error opening file.\n");
- fseek(fp, 0L, SEEK_END);
- int len = ftell(fp);
- char *buf = malloc(len);
- rewind(fp);
- fread(buf, len, 1, fp);
- fclose(fp);
-
- ewk_frame_script_execute(frame, buf);
-
- free(buf);
- */
-
- if (td->app->mode == ModeInsert || td->app->mode == ModeHints) {
- Arg a = { .i = ModeNormal };
- set(&a, td->app);
- }
-
- td->app->manual_focus = EINA_FALSE;
- update_url(uri, td->app);
-}
-
-void
-history(void *data)
-{
- FILE *f;
- char *filename;
- // const char *uri = webkit_web_view_get_uri(webview);
- // const char *title = webkit_web_view_get_title(webview);
- App_Data *ad = data;
- const char *uri = elm_web_uri_get(ad->cur_buf->web);
- const char *title = elm_web_title_get(ad->cur_buf->web);
- char *entry, buffer[512], *new;
- int n, i = 0;
- Eina_Bool finished = EINA_FALSE;
- if (uri != NULL) {
- if (title != NULL) {
- entry = malloc((strlen(uri) + strlen(title) + 2) * sizeof(char));
- memset(entry, 0, strlen(uri) + strlen(title) + 2);
- } else {
- entry = malloc((strlen(uri) + 1) * sizeof(char));
- memset(entry, 0, strlen(uri) + 1);
- }
- if (entry != NULL) {
- strncpy(entry, uri, strlen(uri));
- if (title != NULL) {
- strncat(entry, " ", 1);
- strncat(entry, title, strlen(title));
- }
- n = strlen(entry);
- filename = strdup_printf(HISTORY_STORAGE_FILENAME);
- f = fopen(filename, "r");
- if (f != NULL) {
- new = (char *)malloc(HISTORY_MAX_ENTRIES * 512 * sizeof(char) + 1);
- if (new != NULL) {
- memset(new, 0, HISTORY_MAX_ENTRIES * 512 * sizeof(char) + 1);
- /* newest entries go on top */
- strncpy(new, entry, strlen(entry));
- strncat(new, "\n", 1);
- /* retain at most HISTORY_MAX_ENTIRES - 1 old entries */
- while (finished != TRUE) {
- if ((char *)NULL == fgets(buffer, 512, f)) {
- /* check if end of file was reached / error occured */
- if (!feof(f)) {
- break;
- }
- /* end of file reached */
- finished = TRUE;
- continue;
- }
- /* compare line (-1 because of newline character) */
- if (n != strlen(buffer) - 1 || strncmp(entry, buffer, n) != 0) {
- /* if the URI is already in history; we put it on top and skip it here */
- strncat(new, buffer, 512);
- i++;
- }
- if ((i + 1) >= HISTORY_MAX_ENTRIES) {
- break;
- }
- }
- fclose(f);
- }
- f = fopen(filename, "w");
- free(filename);
- if (f != NULL) {
- fprintf(f, "%s", new);
- fclose(f);
- }
- if (new != NULL) {
- free(new);
- new = NULL;
- }
- }
- }
- if (entry != NULL) {
- free(entry);
- entry = NULL;
- }
- }
-}
-
-void
-webview_document_finished_cb(void *data, Evas_Object *obj, void *event_info)
-{
- // Evas_Object *frame = event_info;
- printf("loca_document_finished()\n");
-}
-
-void
-webview_load_finished_cb(void *data, Evas_Object *obj, void *event_info)
-{
- /* WebKitWebSettings *settings = webkit_web_view_get_settings(webview); */
- Buffer_Data *td = data;
- App_Data *ad = td->app;
- Eina_Bool scripts = 1;
- Elm_Web_Frame_Load_Error *frame_error = event_info;
-
- printf("load_finished()\n");
-
-// Evas_Object *view = elm_web_webkit_view_get(td->web);
-// Evas_Object *frame = ewk_view_frame_main_get(view);
-
- if (frame_error)
- fprintf(stderr, "Error http code %i on domain %s\n%s\n", frame_error->code, frame_error->failing_url, frame_error->description);
-
- /* g_object_get(settings, "enable-scripts", &scripts, NULL); */
- if (escape_input_on_load && scripts && !ad->manual_focus && !elm_object_focus_get(ad->url)) {
- Arg a = { .i = Silent, .s = strdup("hints.clearFocus();") };
- script(&a, ad);
- free(a.s);
- a.i = ModeNormal;
- a.s = NULL;
- set(&a, ad);
- }
- if (HISTORY_MAX_ENTRIES > 0)
- history(ad);
- update_state(ad);
-
- // userscript_hooks_end(elm_web_uri_get(td->web));
-
/*
- FILE *fp = fopen("/home/kyle/.config/evi/userscript/adblockplus/contentScript2.js", "r");
- if (!fp)
- printf("error opening file.\n");
- fseek(fp, 0L, SEEK_END);
- int len = ftell(fp);
- char *buf = malloc(len);
- rewind(fp);
- fread(buf, len, 1, fp);
- fclose(fp);
-
- ewk_frame_script_execute(frame, buf);
-
- free(buf);
- */
-
-
- // elm_object_focus_set(td->web, EINA_TRUE);
-}
-
-#if 0
-void
-webview_open_js_window_cb(WebKitWebView* temp_view, GParamSpec param_spec) {
- /* retrieve the URI of the temporary webview */
- Arg a = { .i = TargetNew, .s = (char*)webkit_web_view_get_uri(temp_view) };
- /* clean up */
- webkit_web_view_stop_loading(temp_view);
- gtk_widget_destroy(GTK_WIDGET(temp_view));
- /* open the requested window */
- open_arg(&a);
-}
-
-static WebKitWebView *
-webview_open_in_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, gpointer user_data) {
- /* create a temporary webview to execute the script in */
- WebKitWebView *temp_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
- /* wait until the new webview receives its new URI */
- g_object_connect(temp_view, "signal::notify::uri", G_CALLBACK(webview_open_js_window_cb), NULL, NULL);
- return temp_view;
-}
-
-Eina_Bool
-webview_new_window_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request,
- WebKitWebNavigationAction *action, WebKitWebPolicyDecision *decision, gpointer user_data) {
- Arg a = { .i = TargetNew, .s = (char*)webkit_network_request_get_uri(request) };
- open_arg(&a);
- webkit_web_policy_decision_ignore(decision);
- return TRUE;
-}
-#endif
-
-/*
-Eina_Bool
-webview_mimetype_cb(WebKitWebView *webview, WebKitWebFrame *frame, WebKitNetworkRequest *request,
- char *mime_type, WebKitWebPolicyDecision *decision, gpointer user_data) {
- if (webkit_web_view_can_show_mime_type(webview, mime_type) == FALSE) {
- webkit_web_policy_decision_download(decision);
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static WebKitWebView*
-inspector_inspect_web_view_cb(gpointer inspector, WebKitWebView* web_view) {
- gchar* inspector_title;
- GtkWidget* inspector_window;
- GtkWidget* inspector_view;
-
- // just enough code to show the inspector - no signal handling etc.
- inspector_title = strdup_printf("Inspect page - %s - Vimprobable2", webkit_web_view_get_uri(web_view));
- if (embed) {
- inspector_window = gtk_plug_new(embed);
- } else {
- inspector_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_wmclass(window, "vimprobable2", "Vimprobable2");
- }
- gtk_window_set_title(GTK_WINDOW(inspector_window), inspector_title);
- free(inspector_title);
- inspector_view = webkit_web_view_new();
- gtk_container_add(GTK_CONTAINER(inspector_window), inspector_view);
- gtk_widget_show_all(inspector_window);
- return WEBKIT_WEB_VIEW(inspector_view);
-}
-*/
-
-static void
-download_entry_free_cb(void *data)
-{
- free(data);
-}
-
-void
-download_complete_cb(void *data, const char *file, int status)
-{
- App_Data *ad = data;
- Arg a;
- a.i = Info;
- a.s = strdup_printf("Download %s finished, status %i", file, status);
- echo(&a, data);
- free(a.s);
-
- // ad->active_downloads = eina_list_remove(ad->active_downloads, file);
- eina_hash_del(ad->downloads, file, NULL);
-
- update_state(data);
-}
-
-int
-download_progress_cb(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow)
-{
- App_Data *ad = data;
-
- void *stat_old;
- struct dl *stat = malloc(sizeof(struct dl));
-
- stat->dltotal = dltotal;
- stat->dlnow = dlnow;
-
- stat_old = eina_hash_modify(ad->downloads, file, (const void *)stat);
- free(stat_old);
-
- update_state(data);
-
- return 0;
-}
-
-static void
-webview_download_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Eina_Bool ret;
- Buffer_Data *td = data;
- App_Data *ad = td->app;
-
- Ewk_Download *dl = event_info;
- char *suggested_name = strdup(strrchr(dl->url, '/'));
-
- char *full_path = strdup_printf("/home/kyle/%s", suggested_name);
-
- ret = ecore_file_download(dl->url, full_path, download_complete_cb,
- download_progress_cb, ad, NULL);
-
- /* if file already exists, ret == NULL */
- if (!ret) {
- Arg a;
- a.i = Info;
- a.s = strdup_printf("%s already exists!", suggested_name);
- echo(&a, ad);
- free(a.s);
- return;
- }
-
- // ad->active_downloads = eina_list_append(ad->active_downloads, strdup(full_path));
- eina_hash_add(ad->downloads, full_path, calloc(1, sizeof(struct dl)));
-
- // free(full_path);
- free(suggested_name);
-
- update_state(ad);
-}
-
-static void
-webview_mousewheel_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- update_state(td->app);
-}
-
-static Eina_Bool
-process_keypress(void *event_info, void *data)
-{
- KeyList *walk;
- Key key;
- // int keyval;
- // GdkModifierType irrelevant;
- App_Data *ad = data;
- Evas_Event_Key_Down *ev = event_info;
-
- // Get a mask of modifiers that shouldn't be considered for this event.
- // E.g.: It shouldn't matter whether ';' is shifted or not.
- // gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode,
- // event->state, event->group, &keyval, NULL, NULL, &irrelevant);
-
- walk = ad->keylistroot;
- while (walk != NULL) {
- key = walk->Element;
- // if (current->Element.mask == (CLEAN(event->state) & ~irrelevant)
- if ((key.mask == 0 || evas_key_modifier_is_set(ev->modifiers, key.mask))
- && (key.modkey == ad->current_modkey
- || (!key.modkey && !ad->current_modkey)
- || key.modkey == '*' ) // wildcard
- && !strcmp(key.key, ev->key)
- && key.func)
- if (key.func(&key.arg, data)) {
- // printf("process_keypress() function for mask = %s modkey = %c key = %s called.\n", key.mask, ad->current_modkey, key.key);
- ad->current_modkey = ad->count = 0;
- update_state(data);
- return TRUE;
- }
- walk = walk->next;
- }
- return FALSE;
-}
-
-static void
-webview_keypress_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- Arg a = { .i = ModeNormal, .s = NULL };
- // int keyval;
- Evas_Event_Key_Down *ev = event_info;
- Buffer_Data *td = data;
- App_Data *ad = td->app;
- // GdkModifierType irrelevant;
-
- /* Get a mask of modifiers that shouldn't be considered for this event.
- * E.g.: It shouldn't matter whether ';' is shifted or not. */
- // gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode,
- // event->state, event->group, &keyval, NULL, NULL, &irrelevant);
-
- switch (ad->mode) {
- case ModeNormal:
- // if ((CLEAN(event->state) & ~irrelevant) == 0) {
- if (IS_ESCAPE(ev)) {
- a.i = Info;
- a.s = strdup("");
- echo(&a, ad);
- elm_box_clear(ad->event_box);
- evas_object_hide(ad->event_box);
- free(a.s);
- } else if (ad->current_modkey == 0 &&
- (( strcmp(ev->key, "1") >= 0 && strcmp(ev->key, "9") <= 0)
- || (!strcmp(ev->key, "0") && ad->count))) {
- // ad->count = (ad->count ? ad->count * 10 : 0) + (ev->key - "0");
- ad->count = (ad->count ? ad->count * 10 : 0) + atoi(ev->key);
- update_state(ad);
- return;
- } else if (strchr(ad->modkeys, ev->key[0]) && ad->current_modkey != ev->key[0]) {
- ad->current_modkey = ev->key[0];
- // ad->current_modkey = strdup(ev->key);
-
- update_state(ad);
- return;
- }
- // }
- /* keybindings */
- if (process_keypress(event_info, ad) == TRUE) return;
-
- break;
- case ModeInsert:
- if (IS_ESCAPE(ev)) {
- a.i = Silent;
- a.s = strdup("hints.clearFocus();");
- script(&a, ad);
- free(a.s);
- a.i = ModeNormal;
- set(&a, ad);
- // ewk_view_input_method_state_set(td->web, FALSE);
- return;
- }
- case ModePassThrough:
- if (IS_ESCAPE(ev)) {
- echo(&a, ad);
- set(&a, ad);
- return;
- }
- break;
- case ModeSendKey:
- echo(&a, ad);
- set(&a, ad);
- break;
- }
-}
-
void
set_widget_font_and_color(Evas_Object *widget, const char *font_str, const char *bg_color_str, const char *fg_color_str)
{
- /*
GdkColor fg_color;
GdkColor bg_color;
PangoFontDescription *font;
@@ -820,492 +302,12 @@ set_widget_font_and_color(Evas_Object *widget, const char *font_str, const char
gtk_widget_modify_text(widget, GTK_STATE_NORMAL, fg_color_str ? &fg_color : NULL);
gtk_widget_modify_base(widget, GTK_STATE_NORMAL, bg_color_str ? &bg_color : NULL);
- */
return;
}
-
-void
-xss_detected_cb(void *data, Evas_Object *obj, void *event_info)
-{
- printf("xss_detected()\n");
-}
-
-void
-icon_received_cb(void *data, Evas_Object *obj, void *event_info)
-{
- printf("icon_received_cb()\n");
-}
-
-void
-webview_hoverlink_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- const char *uri = elm_web_uri_get(td->web);
- /* event_info is a char *link[2] where the first string contains the URL
- * and the second the title of the link */
- char **link = event_info;
- // char *markup;
-
- memset(td->app->rememberedURI, 0, 1024);
- if (link && link[0]) {
- // markup = g_markup_printf_escaped("<span font=\"%s\">Link: %s</span>", statusfont, link[0]);
- // markup = strdup_printf("<font=Monospace font_size=10 color=#FF0>%s", link[0]);
- // gtk_label_set_markup(GTK_LABEL(td->app->status_url), markup);
- // elm_object_text_set(td->app->status_url, markup);
- update_url(link[0], td->app);
- strcpy(td->app->rememberedURI, link[0]);
- // free(markup);
- } else
- update_url(uri, td->app);
-}
-
-static void
-webview_hoverlink_out_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Buffer_Data *td = data;
- update_url(elm_web_uri_get(td->web), td->app);
-}
-
-static void
-webview_console_cb(void *data, Evas_Object *obj, const char *message, unsigned int line, const char *source)
-{
- Arg a;
- Buffer_Data *td = data;
-
- /* Don't change internal mode if the browser doesn't have focus to prevent inconsistent states */
- // if (gtk_window_has_toplevel_focus(window)) {
- if (elm_object_focus_get(td->app->win)) {
- if (!strcmp(message, "hintmode_off") || !strcmp(message, "insertmode_off")) {
- a.i = ModeNormal;
- set(&a, td->app);
- return;
- } else if (!strcmp(message, "insertmode_on")) {
- a.i = ModeInsert;
- set(&a, td->app);
- return;
- }
- }
-}
-
-void
-inputbox_activate_cb(void *data, Evas_Object *obj, void *event_info)
-{
- const char *text;
- App_Data *ad = data;
- uint16_t length = strlen(elm_entry_entry_get(ad->url));
- Arg a;
- Eina_Bool forward = FALSE;
-
- // printf("In inputbox_activate\n");
-
- a.i = HideCompletion;
- complete(&a, data);
- if (length == 0)
- return;
- text = elm_entry_entry_get(ad->url);
- if (length > 1 && text[0] == ':') {
- process_line((text + 1), data);
- } else if (length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
- // webkit_web_view_unmark_text_matches(webview);
- elm_web_text_matches_unmark_all(ad->cur_buf->web);
-
- // webkit_web_view_mark_text_matches(webview, &text[1], FALSE, 0);
- // webkit_web_view_set_highlight_text_matches(webview, TRUE);
- elm_web_text_matches_mark(ad->cur_buf->web, &text[1], EINA_FALSE, EINA_TRUE, 0);
-
- ad->count = 0;
- ad->search_direction = forward;
- ad->search_handle = strdup(&text[1]);
- } else if (text[0] == '.' || text[0] == ',' || text[0] == ';') {
- a.i = Silent;
- a.s = strdup("hints.fire();");
- script(&a, data);
- free(a.s);
- update_state(data);
- } else
- return;
- if (!ad->echo_active)
- // gtk_entry_set_text(entry, "");
- elm_entry_entry_set(ad->url, "");
- // gtk_widget_grab_focus(GTK_WIDGET(webview));
-
- /* process_line above may have deleted the tab, check if its still around */
- if (ad->cur_buf->web)
- elm_object_focus_set(ad->cur_buf->web, EINA_TRUE);
-}
-
-static Eina_Bool
-commandhistoryfetch(const Arg *arg, void *data)
-{
- App_Data *ad = data;
- char *command;
- const int length = eina_list_count(ad->commandhistory);
-
- if (length > 0) {
- if (arg->i == DirectionPrev) {
- ad->commandpointer = (length + ad->commandpointer - 1) % length;
- } else {
- ad->commandpointer = (length + ad->commandpointer + 1) % length;
- }
-
- command = eina_list_nth(ad->commandhistory, ad->commandpointer);
- // gtk_entry_set_text(GTK_ENTRY(inputbox), g_strconcat(":", command, NULL));
- // gtk_editable_set_position(GTK_EDITABLE(inputbox), -1);
- command = strdup_printf(":%s", command);
- elm_entry_entry_set(ad->url, command);
- free(command);
- elm_entry_cursor_line_end_set(ad->url);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-inputbox_keypress_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- Arg a;
- int numval;
- Evas_Event_Key_Down *ev = event_info;
- App_Data *ad = data;
-
- if (ad->mode == ModeHints) {
- // if (event->keyval == GDK_ISO_Left_Tab) {
- if (!strcmp(ev->keyname, "Tab") && evas_key_modifier_is_set(ev->modifiers, "Shift")) {
- a.i = Silent;
- a.s = strdup("hints.focusPreviousHint();");
- script(&a, data);
- free(a.s);
- update_state(data);
- return;
- }
- // if (event->keyval == GDK_Tab) {
- if (!strcmp(ev->keyname, "Tab")) {
- a.i = Silent;
- a.s = strdup("hints.focusNextHint();");
- script(&a, data);
- free(a.s);
- update_state(data);
- return;
- }
- // if (event->keyval == GDK_Return) {
- if (!strcmp(ev->keyname, "Return")) {
- a.i = Silent;
- a.s = strdup_printf("hints.fire();");
- script(&a, data);
- free(a.s);
- update_state(data);
- return;
- }
- }
- if (!strcmp(ev->keyname, "[") || !strcmp(ev->keyname, "Escape")) {
- a.i = HideCompletion;
- complete(&a, data);
- a.i = ModeNormal;
- ad->commandpointer = 0;
- set(&a, data);
- return;
- }
- else if (!strcmp(ev->keyname, "Tab") && evas_key_modifier_is_set(ev->modifiers, "Shift")) {
- a.i = DirectionPrev;
- complete(&a, data);
- return;
- }
- else if (!strcmp(ev->keyname, "Tab")) {
- a.i = DirectionNext;
- complete(&a, data);
- return;
- }
- else if (!strcmp(ev->keyname, "Up")) {
- a.i = DirectionPrev;
- commandhistoryfetch(&a, data);
- return;
- }
- else if (!strcmp(ev->keyname, "Down")) {
- a.i = DirectionNext;
- commandhistoryfetch(&a, data);
- return;
- }
-
- /*
- switch (event->keyval) {
- case GDK_bracketleft:
- case GDK_Escape:
- if (!IS_ESCAPE(event)) break;
- a.i = HideCompletion;
- complete(&a, data);
- a.i = ModeNormal;
- commandpointer = 0;
- return set(&a, ad);
- break;
- case GDK_Tab:
- a.i = DirectionNext;
- return complete(&a, data);
- break;
- case GDK_Up:
- a.i = DirectionPrev;
- return commandhistoryfetch(&a);
- break;
- case GDK_Down:
- a.i = DirectionNext;
- return commandhistoryfetch(&a);
- break;
- case GDK_ISO_Left_Tab:
- a.i = DirectionPrev;
- return complete(&a, data);
- break;
- }
- */
-
- if (ad->mode == ModeHints) {
-#if 0
- if ((CLEAN(event->state) & GDK_SHIFT_MASK) &&
- (CLEAN(event->state) & GDK_CONTROL_MASK) &&
- (event->keyval == GDK_BackSpace)) {
- count /= 10;
- a.i = Silent;
- a.s = g_strdup_printf("hints.updateHints(%d);", count);
- script(&a, data);
- g_free(a.s);
- update_state();
- return TRUE;
- }
-#endif
-
- // numval = g_unichar_digit_value((gunichar) gdk_keyval_to_unicode(event->keyval));
- numval = atoi(ev->key);
- if ((numval >= 1 && numval <= 9) || (numval == 0 && ad->count)) {
- /* allow a zero as non-first number */
- ad->count = (ad->count ? ad->count * 10 : 0) + numval;
- a.i = Silent;
- a.s = strdup_printf("hints.updateHints(%d);", ad->count);
- script(&a, data);
- free(a.s);
- update_state(data);
- return;
- }
- }
-}
-
-static void
-inputmethod_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
- const char *value;
- Eina_Bool *enabled = event_info;
- Buffer_Data *td = data;
- App_Data *ad = td->app;
- Evas_Object *frame = ewk_view_frame_main_get(td->view);
-
- if (ad->mode == ModeNormal && enabled) {
- Arg a = { .i = ModeInsert };
- set(&a, ad);
- ad->manual_focus = TRUE;
- } else if (ad->mode == ModeInsert && !enabled) {
- Arg a = { .i = ModeNormal };
- set(&a, ad);
- } else {
- // char *value = NULL, *message = NULL;
- // jsapi_evaluate_script("window.getSelection().focusNode", &value, &message, ad);
- value = ewk_frame_script_execute(frame, "window.getSelection().focusNode");
- if (value && !strcmp(value, "[object HTMLFormElement]")) {
- Arg a = { .i = ModeInsert, .s = NULL };
- set(&a, ad);
- ad->manual_focus = TRUE;
- }
- // free(value);
- eina_stringshare_del(value);
- // free(message);
- }
-}
-
-/*
-static void
-// notify_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) {
-notify_event_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- int i;
- // WebKitHitTestResult *result;
- // WebKitHitTestResultContext context;
- Ewk_Hit_Test *result;
- Ewk_Hit_Test_Result_Context context;
-
- Evas_Event_Mouse_Up *ev = event_info;
- Buffer_Data *td = data;
- App_Data *ad = td->app;
-
- Evas_Object *view = elm_web_webkit_view_get(td->web);
- Evas_Object *frame = ewk_view_frame_main_get(view);
-
- // if (mode == ModeNormal && event->type == GDK_BUTTON_RELEASE) {
- if (ad->mode == ModeNormal) {
- // handle mouse click events
- for (i = 0; i < LENGTH(mouse); i++) {
- // if (mouse[i].mask == CLEAN(event->button.state)
- if ( (mouse[i].mask == 0 || evas_key_modifier_is_set(ev->modifiers, mouse[i].mask))
- // && (mouse[i].modkey == current_modkey
- && ((ad->current_modkey && !strcmp(mouse[i].modkey, ad->current_modkey))
- || (!mouse[i].modkey && !ad->current_modkey)
- // || mouse[i].modkey == GDK_VoidSymbol) // wildcard
- || !strcmp(mouse[i].modkey, "*")) // wildcard
- // && mouse[i].button == event->button.button
- && (mouse[i].button & ev->button)
- && mouse[i].func) {
- if (mouse[i].func(&mouse[i].arg, ad)) {
- // current_modkey = count = 0;
- ad->current_modkey = NULL;
- ad->count = 0;
- update_state(ad);
- return TRUE;
- }
- }
- }
- // result = webkit_web_view_get_hit_test_result(WEBKIT_WEB_VIEW(widget), (GdkEventButton*)event);
- result = ewk_frame_hit_test_new(frame, ev->canvas.x, ev->canvas.y);
- context = result->context;
-
- // g_object_get(result, "context", &context, NULL);
- // if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE) {
- if (context & EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE) {
- Arg a = { .i = ModeInsert };
- set(&a, ad);
- ad->manual_focus = TRUE;
- }
- // } else if (mode == ModeInsert && event->type == GDK_BUTTON_RELEASE) {
- } else if (ad->mode == ModeInsert) {
- //result = webkit_web_view_get_hit_test_result(WEBKIT_WEB_VIEW(widget), (GdkEventButton*)event);
- result = ewk_frame_hit_test_new(frame, ev->output.x, ev->output.y);
-
- // g_object_get(result, "context", &context, NULL);
- // if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) {
- if (!(context & EWK_HIT_TEST_RESULT_CONTEXT_EDITABLE)) {
- Arg a = { .i = ModeNormal };
- set(&a, ad);
- }
- } else {
- char *value = NULL, *message = NULL;
- jsapi_evaluate_script("window.getSelection().focusNode", &value, &message, ad);
- if (value && !strcmp(value, "[object HTMLFormElement]")) {
- Arg a = { .i = ModeInsert, .s = NULL };
- set(&a, ad);
- ad->manual_focus = TRUE;
- }
- free(value);
- free(message);
- }
- ewk_frame_hit_test_free(result);
- return FALSE;
-}
*/
-static void
-inputbox_keyrelease_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
-{
- Arg a;
- App_Data *ad = data;
- // guint16 length = gtk_entry_get_text_length(entry);
- uint16_t length = strlen(elm_entry_entry_get(ad->url));
-
- if (!length) {
- a.i = HideCompletion;
- complete(&a, data);
- a.i = ModeNormal;
- set(&a, data);
- }
-}
-/* used for incremental search */
-static void
-inputbox_changed_cb(void *data, Evas_Object *obj, void *event_info)
-{
- Arg a;
- App_Data *ad = data;
- const char *text = elm_entry_entry_get(ad->url);
- uint16_t length = strlen(text);
- Eina_Bool forward = FALSE;
-
- /* Update incremental search if the user changes the search text.
- *
- * Note: gtk_widget_is_focus() is a poor way to check if the change comes
- * from the user. But if the entry is focused and the text is set
- * through gtk_entry_set_text() in some asyncrounous operation,
- * I would consider that a bug.
- */
-
- // if (gtk_widget_is_focus(GTK_WIDGET(entry)) && length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
- if (elm_object_focus_get(ad->url) && length > 1 && ((forward = text[0] == '/') || text[0] == '?')) {
- // webkit_web_view_unmark_text_matches(webview);
- elm_web_text_matches_unmark_all(ad->cur_buf->web);
-
- // webkit_web_view_search_text(webview, &text[1], searchoptions & CaseSensitive, forward, searchoptions & Wrapping);
- elm_web_text_search(ad->cur_buf->web, &text[1], EINA_TRUE, forward, EINA_FALSE);
- return;
- // } else if (gtk_widget_is_focus(GTK_WIDGET(entry)) && length >= 1 &&
- } else if (elm_object_focus_get(ad->url) && length >= 1 &&
- (text[0] == '.' || text[0] == ',' || text[0] == ';')) {
- a.i = Silent;
- switch (text[0]) {
- case '.':
- // a.s = strconcat("hints.createHints('", text + 1, "', 'f');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'f');", text + 1);
- break;
-
- case ',':
- // a.s = strconcat("hints.createHints('", text + 1, "', 'F');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'F');", text + 1);
- break;
-
- case ';':
- a.s = NULL;
- switch (text[1]) {
- case 's':
- // a.s = strconcat("hints.createHints('", text + 2, "', 's');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 's');", text + 2);
- break;
- case 'y':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'y');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'y');", text + 2);
- break;
- case 'o':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'f');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'f');", text + 2);
- break;
- case 't': case 'w':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'F');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'F');", text + 2);
- break;
- case 'O': case 'T': case 'W':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'O');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'O');", text + 2);
- break;
- case 'i':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'i');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'i');", text + 2);
- break;
- case 'I':
- // a.s = strconcat("hints.createHints('", text + 2, "', 'I');", NULL);
- a.s = strdup_printf("hints.createHints('%s', 'I');", text + 2);
- break;
- }
- break;
- }
- ad->count = 0;
- if (a.s) {
- script(&a, data);
- free(a.s);
- }
-
- return;
- } else if (length == 0 && ad->followTarget[0]) {
- ad->mode = ModeNormal;
- a.i = Silent;
- a.s = strdup("hints.clearHints();");
- script(&a, data);
- free(a.s);
- ad->count = 0;
- update_state(data);
- }
-}
Evas_Object *
webview_create_window_cb(void *data, Evas_Object *obj, Eina_Bool js, const Elm_Web_Window_Features *wf)
@@ -1345,8 +347,6 @@ buffer_current_set(Buffer_Data *new_buf)
if (ad->cur_buf) {
ewk_view_visibility_state_set(ad->cur_buf->view, EWK_PAGE_VISIBILITY_STATE_VISIBLE, 0);
if (ad->cur_buf->inspector_enabled) {
- printf("re-enabling inspector ..\n");
- ewk_view_setting_enable_developer_extras_set(ad->cur_buf->view, EINA_TRUE);
ewk_view_web_inspector_show(ad->cur_buf->view);
}
@@ -1391,6 +391,7 @@ buffer_add(App_Data *ad)
td->buf_number = ad->buf_total;
td->inspector_enabled = EINA_FALSE;
td->proxy_enabled = EINA_FALSE;
+ td->history_enabled = EINA_TRUE;
td->view = elm_web_webkit_view_get(td->web);
ad->buffer_list = eina_list_append(ad->buffer_list, td);
@@ -1420,6 +421,7 @@ buffer_add(App_Data *ad)
evas_object_smart_callback_add(td->web, "inputmethod,changed", inputmethod_changed_cb, td);
/* these signals are not offered by elm_web */
+ evas_object_smart_callback_add(td->view, "load,error", load_error_cb, td);
evas_object_smart_callback_add(td->view, "inspector,view,create", webview_inspector_cb, td);
evas_object_smart_callback_add(td->view, "inspector,view,close", webview_inspector_close_cb, td);
evas_object_smart_callback_add(td->view, "protocolhandler,isregistered", protocol_register_cb, td);
@@ -1434,58 +436,19 @@ buffer_add(App_Data *ad)
return td;
}
-
-EAPI_MAIN int
-elm_main(int argc, char *argv[])
+static void
+setup_gui(App_Data *ad)
{
Evas_Object *win, *bg, *box, *status_bar, *url, *naviframe, *status_url;
Evas_Object *status_state, *event_box, *web_inspector;
- Evas *e;
- Evas_Modifier_Mask mask;
- App_Data *ad;
- unsigned int i;
-
- if (!elm_need_web())
- return -1;
-
- ad = calloc(1, sizeof(App_Data));
- if (!ad) return -1;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_add(NULL, "viking", ELM_WIN_BASIC);
elm_win_autodel_set(win, EINA_TRUE);
- // elm_win_shaped_set(win, EINA_TRUE);
// elm_win_screen_constrain_set(win, EINA_TRUE);
-
- ad->modkeys = calloc(LENGTH(keys) + 1, sizeof(char));
- ad->modkeys[0] = '\0';
- e = evas_object_evas_get(win);
-
- for (i = 0; i < LENGTH(keys); i++) {
- if (keys[i].modkey && !strchr(ad->modkeys, keys[i].modkey)) {
- // strcat(ad->modkeys, keys[i].modkey);
- ad->modkeys[strlen(ad->modkeys)] = keys[i].modkey;
- ad->modkeys[strlen(ad->modkeys) + 1] = '\0';
- }
-
- mask = evas_key_modifier_mask_get(e, keys[i].mask);
- if (keys[i].key && !evas_object_key_grab(win, keys[i].key, mask, 0, EINA_FALSE))
- fprintf(stderr, "Could not grab trigger for mask = %s, key = %s\n", keys[i].mask , keys[i].key);
- }
-
- fprintf(stderr, "Modkey array looks like %s\n", ad->modkeys);
-
evas_object_smart_callback_add(win, "delete,request", _win_del_request_cb, ad);
- // ewk_network_tls_ca_certificates_path_set(ca_bundle);
- ewk_settings_icon_database_path_set("./");
- ewk_settings_application_cache_path_set("./");
- ewk_settings_shadow_dom_enable_set(EINA_TRUE);
-
- ewk_cookies_file_set("cookies.txt");
- ewk_cookies_policy_set(EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
-
/* program bacground */
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -1533,12 +496,12 @@ elm_main(int argc, char *argv[])
evas_object_size_hint_align_set(web_inspector, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, web_inspector);
evas_object_hide(web_inspector);
-
+
/* invisible event box, populated on tab completions and :ls */
event_box = elm_box_add(win);
evas_object_size_hint_align_set(event_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, event_box);
- evas_object_hide(event_box);
+// evas_object_hide(event_box);
/* main entry widget */
url = elm_entry_add(win);
@@ -1563,44 +526,455 @@ elm_main(int argc, char *argv[])
ad->status_state = status_state;
ad->event_box = event_box;
ad->web_inspector = web_inspector;
- ad->soup_session = ewk_network_default_soup_session_get();
+}
+
+static void
+setup_modkeys(App_Data *ad)
+{
+ Evas *e;
+ Evas_Modifier_Mask mask;
+ unsigned int i;
+
+ ad->modkeys = calloc(LENGTH(keys) + 1, sizeof(char));
+ ad->modkeys[0] = '\0';
+ e = evas_object_evas_get(ad->win);
+
+ for (i = 0; i < LENGTH(keys); i++) {
+ if (keys[i].modkey && !strchr(ad->modkeys, keys[i].modkey)) {
+ // strcat(ad->modkeys, keys[i].modkey);
+ ad->modkeys[strlen(ad->modkeys)] = keys[i].modkey;
+ ad->modkeys[strlen(ad->modkeys) + 1] = '\0';
+ }
+
+ mask = evas_key_modifier_mask_get(e, keys[i].mask);
+ if (keys[i].key && !evas_object_key_grab(ad->win, keys[i].key, mask, 0, EINA_FALSE))
+ fprintf(stderr, "Could not grab trigger for mask = %s, key = %s\n", keys[i].mask , keys[i].key);
+ }
+ fprintf(stderr, "Modkey array looks like %s\n", ad->modkeys);
+}
+
+static char ca_bundle[MAX_SETTING_SIZE] = "/etc/ssl/certs/ca-certificates.crt";
+static Eina_Bool strict_ssl = TRUE; /* FALSE will accept any SSL certificate at face value */
+static void
+setup_network(App_Data *ad)
+{
+
+ ad->soup_session = ewk_network_default_soup_session_get();
g_object_set(G_OBJECT(ad->soup_session), "ssl-ca-file", ca_bundle, NULL);
g_object_set(G_OBJECT(ad->soup_session), "ssl-strict", strict_ssl, NULL);
+ // ewk_network_tls_ca_certificates_path_set(ca_bundle);
+}
- ad->buf_total = 0;
+static Eina_Bool
+_cb_session_save(void *data)
+{
+ /*
+ Browser_Window *win;
+ Eina_List *chrome_iter, *win_iter;
+ Evas_Object *chrome;
+ Eina_Bool changed = EINA_FALSE;
+ Session_Item *si;
+
+ if (!config_restore_state_get(config)) goto end;
+
+ EINA_LIST_FOREACH(app.windows, win_iter, win)
+ {
+ EINA_LIST_FOREACH(win->chromes, chrome_iter, chrome)
+ {
+ Evas_Object *view = evas_object_data_get(chrome, "view");
+ Evas_Object *frame = ewk_view_frame_main_get(view);
+ const Eina_Bool focused = chrome == win->current_chrome;
+ const char *url, *wk_url;
+ int sx, sy;
+
+ si = evas_object_data_get(chrome, "session");
+ if (!si)
+ {
+ WRN("chrome %p doesn't have a Session_Item, ignoring", chrome);
+ continue;
+ }
- Buffer_Data *td = buffer_add(ad);
- buffer_current_set(td);
- elm_web_uri_set(td->web, startpage);
+ url = session_item_url_get(si);
+ wk_url = ewk_view_uri_get(view);
+ if ((url && wk_url && strcmp(url, wk_url)) || (wk_url && !url))
+ {
+ session_item_url_set(si, wk_url);
+ changed = EINA_TRUE;
+ }
+
+ ewk_frame_scroll_pos_get(frame, &sx, &sy);
+ if (session_item_scroll_x_get(si) != sx ||
+ session_item_scroll_y_get(si) != sy)
+ {
+ session_item_scroll_x_set(si, sx);
+ session_item_scroll_y_set(si, sy);
+ changed = EINA_TRUE;
+ }
+
+ if (session_item_focused_get(si) != focused)
+ {
+ session_item_focused_set(si, focused);
+ changed = EINA_TRUE;
+ }
+ }
+ }
+
+ if (changed)
+ session_save(session, NULL);
+end:
+ return ECORE_CALLBACK_RENEW;
+ */
+
+ return EINA_FALSE;
+}
+
+
+
+static const Ecore_Getopt options = {
+ PACKAGE_NAME,
+ "%prog [options] [url]",
+ PACKAGE_VERSION " Revision: ", // VREV,
+ "(C) 2010 ProFUSION embedded systems",
+ "LGPL-3",
+ "WebKit-EFL demo browser for mobile systems with touchscreen.",
+ EINA_TRUE,
+ {
+ // ECORE_GETOPT_STORE_DEF_BOOL('F', "fullscreen", "start in fullscreen.", 1),
+ ECORE_GETOPT_STORE_DEF_BOOL('P', "disable-plugins",
+ "disable plugins (flash, etc).", 1),
+ // ECORE_GETOPT_STORE_DEF_BOOL('M', "disable-mouse",
+ // "disable mouse (hide it).", 1),
+ // ECORE_GETOPT_STORE_DEF_BOOL('T', "disable-touch-interface",
+ // "disable touch interface handling of mouse events", 1),
+ ECORE_GETOPT_STORE_STR('U', "user-agent",
+ "user agent string to use. Special cases=iphone,safari,chrome,firefox,android,ie,ie9,ie8,ie7."),
+ ECORE_GETOPT_STORE_DEF_STR('B', "backing-store",
+ "backing store to use. single or tiled.", "single"),
+ // ECORE_GETOPT_STORE_DEF_UINT('R', "rotate", "Screen Rotation in degrees", 0),
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_HELP('h', "help"),
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
+char *
+uri_sanitize(const char *uri) {
+ char *fixed_uri;
+ char *schema;
+ char *tmp;
+
+ if (!uri || !*uri) return NULL;
+
+ tmp = strstr(uri, "://");
+ if (!tmp || (tmp == uri) || (tmp > (uri + 15)))
+ {
+ char *new_uri = NULL;
+ if (ecore_file_exists(uri))
+ {
+ schema = "file";
+ new_uri = ecore_file_realpath(uri);
+ }
+ else
+ schema = "http";
+
+ if (asprintf(&fixed_uri, "%s://%s", schema, new_uri ? new_uri : uri) > 0)
+ {
+ free(new_uri);
+ return fixed_uri;
+ }
+ free(new_uri);
+ }
+ else
+ {
+ char search_uri[4096];
+ strcat(search_uri, "http://google.com/search?q=");
+ return strdup(strcat(search_uri, uri));
+ }
+
+ return NULL;
+}
+
+static void
+setup_config(App_Data *ad, int argc, char **argv)
+{
+ char *home, *basename;
+ char path[PATH_MAX];
+ Config *config;
+ Hist *hist;
+ Session *session;
+ size_t dirlen;
+ int args;
+ Ecore_Timer *session_save_timer = NULL;
+ char *user_agent_option = NULL;
+ const char *user_agent_str;
+ Eina_Bool disable_plugins = 0xff;
+ char *backing_store_option = NULL;
+ Backing_Store backing_store_enum;
+ Eina_Bool quit_option = EINA_FALSE;
+ char *uri;
+ Eina_Bool disable_mouse_cursor = 0xff;
+ Eina_Bool disable_touch_interface = 0xff;
+
+ Ecore_Getopt_Value values[] = {
+ ECORE_GETOPT_VALUE_BOOL(disable_plugins),
+ ECORE_GETOPT_VALUE_BOOL(disable_mouse_cursor),
+ ECORE_GETOPT_VALUE_BOOL(disable_touch_interface),
+ ECORE_GETOPT_VALUE_STR(user_agent_option),
+ ECORE_GETOPT_VALUE_STR(backing_store_option),
+ // ECORE_GETOPT_VALUE_UINT(ad->rotate),
+ ECORE_GETOPT_VALUE_BOOL(quit_option),
+ ECORE_GETOPT_VALUE_BOOL(quit_option),
+ ECORE_GETOPT_VALUE_BOOL(quit_option),
+ ECORE_GETOPT_VALUE_BOOL(quit_option),
+ ECORE_GETOPT_VALUE_NONE
+ };
+
+ args = ecore_getopt_parse(&options, values, argc, argv);
+ if (args < 0)
+ ERR("Could not parse command line options.");
+
+ if (!user_agent_option || (user_agent_option && (strcasecmp(user_agent_option, "eve") == 0)))
+ user_agent_str = "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 " PACKAGE_NAME "/" PACKAGE_VERSION;
+ else
+ {
+ /* http://www.useragentstring.com/ */
+ if (strcasecmp(user_agent_option, "iphone") == 0)
+ user_agent_str = "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3";
+ else if (strcasecmp(user_agent_option, "safari") == 0)
+ user_agent_str = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8";
+
+ else if (strcasecmp(user_agent_option, "chrome") == 0)
+ user_agent_str = "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7";
+ else if (strcasecmp(user_agent_option, "firefox") == 0)
+ user_agent_str = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.2) Gecko/20121223 Firefox/3.8";
+ else if (strcasecmp(user_agent_option, "android") == 0)
+ user_agent_str = "Mozilla/5.0 (Linux; U; Android 2.1; en-US;) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17";
+
+ else if (strcasecmp(user_agent_option, "ie") == 0) /* last */
+ user_agent_str = "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)";
+ else if (strcasecmp(user_agent_option, "ie9") == 0)
+ user_agent_str = "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)";
+ else if (strcasecmp(user_agent_option, "ie8") == 0)
+ user_agent_str = "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SLCC1; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322)";
+ else if (strcasecmp(user_agent_option, "ie7") == 0)
+ user_agent_str = "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)";
+ else
+ user_agent_str = user_agent_option;
+ }
+
+ if (backing_store_option && !strcasecmp(backing_store_option, "tiled"))
+ backing_store_enum = BACKING_STORE_TILED;
+ else
+ backing_store_enum = BACKING_STORE_SINGLE;
+
+ viking_state_init();
+
+ home = getenv("HOME");
+ if (!home || !home[0]) {
+ CRITICAL("Could not get $HOME");
+ home = "/";
+ }
- evas_object_resize(win, 480, 640);
- evas_object_show(win);
+ dirlen = snprintf(path, sizeof(path), "%s/.config/viking", home);
+
+ if (dirlen >= sizeof(path))
+ ERR("Path is too long: %s/.config/eve", home);
+
+ if (!ecore_file_mkpath(path))
+ ERR("Could not create %s", path);
+
+ if (!ewk_settings_icon_database_path_set(path))
+ ERR("Could not set icon database path to %s", path);
+
+ basename = path + dirlen;
+ basename[0] = '/';
+ basename++;
+ dirlen++;
+
+ eina_strlcpy(basename, "cookies.txt", sizeof(path) - dirlen);
+ ewk_cookies_file_set(path);
+ ewk_cookies_policy_set(EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
+
+
+ eina_strlcpy(basename, "config.eet", sizeof(path) - dirlen);
+ config = config_load(path);
+ if (!config) {
+
+ Eina_Bool enable_mouse_cursor, enable_touch_interface, enable_plugins;
+
+#define BOOL_OPT(opt) \
+ enable_##opt = ((disable_##opt == 0xff) ? EINA_TRUE : !disable_##opt)
+ BOOL_OPT(mouse_cursor);
+ BOOL_OPT(touch_interface);
+ BOOL_OPT(plugins);
+#undef BOOL_OPT
+
+ config = config_new(EINA_TRUE /* allow_popup */,
+ EINA_TRUE /* enable_auto_load_images */,
+ EINA_TRUE /* enable_auto_shrink_images */,
+ EINA_TRUE /* enable_javascript */,
+ enable_mouse_cursor,
+ enable_plugins,
+ EINA_FALSE /* enable_private_mode */,
+ enable_touch_interface,
+ DEFAULT_URL /* home_page */,
+ NULL /* proxy */,
+ EINA_FALSE /* restore_state */,
+ user_agent_str,
+ EINA_FALSE /* frame_flattening */,
+ EINA_FALSE /* text_only_zoom */,
+ 12 /* minimum_font_size */,
+ ewk_cookies_policy_get(),
+ backing_store_enum);
+ if (!config_save(config, path))
+ ERR("Could not save new configuration at %s", path);
+ }
+ else
+ config_backing_store_set(config, backing_store_enum);
+
+ hist = hist_load(path);
+ if (!hist) {
+ hist = hist_new();
+ if (!hist_save(hist, path))
+ ERR("Could not save new history file at %s", path);
+ }
+
+ session = session_load(path);
+ if (!session) {
+ session = session_new(NULL);
+ if (!session_save(session, path))
+ ERR("Could not save new session file at %s", path);
+ }
+
+ session_save_timer = ecore_timer_loop_add(15, _cb_session_save, NULL);
+ if (!session_save_timer)
+ ERR("Could not register session save timer");
+
+#define BOOL_OPT(opt) \
+ if (disable_##opt != 0xff) { \
+ Eina_Bool old = config_enable_##opt##_get(config); \
+ Eina_Bool cur = !disable_##opt; \
+ if (old != cur) { \
+ INF("Changed preferences to "#opt"=%hhu", cur); \
+ config_enable_##opt##_set(config, cur); \
+ } \
+ }
+ // BOOL_OPT(mouse_cursor);
+ // BOOL_OPT(touch_interface);
+ BOOL_OPT(plugins);
+#undef BOOL_OPT
+
+ if (user_agent_option) {
+ const char *old = config_user_agent_get(config);
+ const char *cur = user_agent_str;
+ if (strcmp(old, cur) != 0) {
+ INF("Changed preferences to user_agent=\"%s\"", cur);
+ config_user_agent_set(config, cur);
+ }
+ }
+
+ if (args < argc) {
+ uri = uri_sanitize(argv[args]);
+ printf("setup_config() cmd line uri = %s\n", uri);
+ free(uri);
+ }
+
+ ad->config = config;
+ ad->history = hist;
+ ad->session = session;
+ ad->session_save_timer = session_save_timer;
+}
+
+static Eina_Bool
+session_restore(void)
+{
+ return EINA_FALSE;
+}
+
+static URIHandler uri_handlers[] = {
+ { "mailto:", "x-terminal-emulator -e mutt %s" },
+ { "ftp://", "x-terminal-emulator -e wget ftp://%s" },
+};
+
+/* search engines */
+static Searchengine searchengines[] = {
+ { "d", "https://duckduckgo.com/?q=%s&t=Vimprobable" },
+ { "i", "http://ixquick.com/do/metasearch.pl?query=%s" },
+ { "w", "https://secure.wikimedia.org/wikipedia/en/w/index.php?title=Special%%3ASearch&search=%s&go=Go" },
+ { "wd", "https://secure.wikimedia.org/wikipedia/de/w/index.php?title=Special%%3ASearch&search=%s&go=Go" },
+ { "dd", "https://duckduckgo.com/html/?q=%s&t=Vimprobable" },
+};
+
+static char defaultsearch[MAX_SETTING_SIZE] = "d";
+
+
+EAPI_MAIN int
+elm_main(int argc, char *argv[])
+{
+ App_Data *ad;
+ Buffer_Data *bd;
+
+#if ENABLE_NLS
+ setlocale(LC_ALL, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+#endif
+
+ /* calloc zeros the memory!! */
+ ad = calloc(1, sizeof(App_Data));
+ if (!ad) return -1;
+
+ ad->log_domain = eina_log_domain_register("viking", NULL);
+ if (ad->log_domain < 0)
+ EINA_LOG_CRIT("could not create log domain 'viking'.");
+
+ if (!elm_need_web())
+ return -1;
+
+ setup_config(ad, argc, argv);
+ setup_gui(ad);
+ setup_modkeys(ad);
+ setup_network(ad);
+
+ /* session was restored successfully */
+ if (config_restore_state_get(ad->config)
+ && session_windows_count(ad->session) > 0
+ && session_restore());
+
+ bd = buffer_add(ad);
+ buffer_current_set(bd);
+ elm_web_uri_set(bd->web, config_home_page_get(ad->config));
+
+ evas_object_resize(ad->win, 480, 640);
+ evas_object_show(ad->win);
make_searchengines_list(searchengines, LENGTH(searchengines));
make_uri_handlers_list(uri_handlers, LENGTH(uri_handlers));
+ /* initialize fields that are non-zero */
ad->keylistroot = make_keyslist();
-
- memset(ad->rememberedURI, 0, 1024);
- memset(ad->followTarget, 0, 8);
- ad->error_msg = NULL;
ad->config_base = "./";
- ad->manual_focus = FALSE;
ad->zoomstep = 0.1f;
- ad->current_modkey = 0;
-
- ad->commandhistory = NULL;
- ad->commandpointer = 0;
-
ad->mode = ModeNormal;
- ad->count = 0;
ad->echo_active = EINA_TRUE;
-
ad->downloads = eina_hash_string_superfast_new(download_entry_free_cb);
+ /* main loop */
elm_run();
+
+ config_save(ad->config, NULL);
+ config_free(ad->config);
+ hist_save(ad->history, NULL);
+ hist_free(ad->history);
+ _cb_session_save(ad->session);
+ session_free(ad->session);
+ if (ad->session_save_timer) ecore_timer_del(ad->session_save_timer);
+
elm_shutdown();
free(ad->modkeys);
diff --git a/main.h b/main.h
@@ -52,6 +52,12 @@ typedef struct
SoupSession *soup_session;
Buffer_Data *cur_buf;
+ Hist *history;
+ Config *config;
+ Session *session;
+ Ecore_Timer *session_save_timer;
+ int log_domain;
+
Eina_Bool exiting : 1;
} App_Data;
@@ -80,6 +86,7 @@ Eina_Bool echo(const Arg *arg, void *);
void buffer_current_set(Buffer_Data *td);
Buffer_Data *buffer_add(App_Data *ad);
Eina_Bool enable_proxy(Buffer_Data *bd);
+char* status_flags(void *data);
#endif
diff --git a/utilities.c b/utilities.c
@@ -18,6 +18,7 @@
#include <unistd.h> /* realloc */
#include "viking.h"
+#include "viking_state.h"
#include "main.h"
#include "utilities.h"
#include "commands.h"
@@ -26,7 +27,7 @@
#include "jsmn.h"
/* these all need to go */
-extern Eina_Bool complete_case_sensitive;
+static Eina_Bool complete_case_sensitive = TRUE;
extern char *config_base;
static Eina_List *dynamic_searchengines = NULL, *dynamic_uri_handlers = NULL;
diff --git a/viking.h b/viking.h
@@ -194,4 +194,19 @@ enum ConfigFileError {
/* completion list size */
#define MAX_LIST_SIZE 40
+#define DEFAULT_URL "http://getaddrinfo.net"
+#define PACKAGE_NAME "viking"
+#define PACKAGE_VERSION "1"
+
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(ad->log_domain, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(ad->log_domain, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(ad->log_domain, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(ad->log_domain, __VA_ARGS__)
+#define DBG(...) EINA_LOG_DOM_DBG(ad->log_domain, __VA_ARGS__)
+
+typedef enum
+{
+ BACKING_STORE_SINGLE,
+ BACKING_STORE_TILED
+} Backing_Store;
diff --git a/viking_state.c b/viking_state.c
@@ -0,0 +1,1259 @@
+/* This file has been automatically generated by geneet.py */
+/* DO NOT MODIFY */
+
+#include <limits.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "viking_state.h"
+
+struct _Config {
+ unsigned char allow_popup;
+ unsigned char enable_auto_load_images;
+ unsigned char enable_auto_shrink_images;
+ unsigned char enable_javascript;
+ unsigned char enable_mouse_cursor;
+ unsigned char enable_plugins;
+ unsigned char enable_private_mode;
+ unsigned char enable_touch_interface;
+ const char * home_page;
+ const char * proxy;
+ unsigned char restore_state;
+ const char * user_agent;
+ unsigned char frame_flattening;
+ int text_zoom;
+ int minimum_font_size;
+ int cookie_policy;
+ int backing_store;
+ const char *__eet_filename;
+};
+
+struct _Hist_Item {
+ const char * title;
+ const char * url;
+ unsigned int visit_count;
+ double last_visit;
+};
+
+struct _Hist {
+ Eina_Hash * items;
+ const char *__eet_filename;
+};
+
+struct _Fav_Item {
+ const char * url;
+ const char * title;
+ unsigned int visit_count;
+};
+
+struct _Fav {
+ Eina_Hash * items;
+ const char *__eet_filename;
+};
+
+struct _Session_Item {
+ const char * url;
+ unsigned char focused;
+ int scroll_x;
+ int scroll_y;
+};
+
+struct _Session_Window {
+ Eina_List * tabs;
+ unsigned char focused;
+};
+
+struct _Session {
+ Eina_List * windows;
+ const char *__eet_filename;
+};
+
+static const char CONFIG_ENTRY[] = "config";
+static const char HIST_ITEM_ENTRY[] = "hist_item";
+static const char HIST_ENTRY[] = "hist";
+static const char FAV_ITEM_ENTRY[] = "fav_item";
+static const char FAV_ENTRY[] = "fav";
+static const char SESSION_ITEM_ENTRY[] = "session_item";
+static const char SESSION_WINDOW_ENTRY[] = "session_window";
+static const char SESSION_ENTRY[] = "session";
+
+static Eet_Data_Descriptor *_config_descriptor = NULL;
+static Eet_Data_Descriptor *_hist_item_descriptor = NULL;
+static Eet_Data_Descriptor *_hist_descriptor = NULL;
+static Eet_Data_Descriptor *_fav_item_descriptor = NULL;
+static Eet_Data_Descriptor *_fav_descriptor = NULL;
+static Eet_Data_Descriptor *_session_item_descriptor = NULL;
+static Eet_Data_Descriptor *_session_window_descriptor = NULL;
+static Eet_Data_Descriptor *_session_descriptor = NULL;
+
+static inline void
+_config_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_config_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Config);
+ _config_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "allow_popup", allow_popup, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_auto_load_images", enable_auto_load_images, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_auto_shrink_images", enable_auto_shrink_images, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_javascript", enable_javascript, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_mouse_cursor", enable_mouse_cursor, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_plugins", enable_plugins, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_private_mode", enable_private_mode, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "enable_touch_interface", enable_touch_interface, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "home_page", home_page, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "proxy", proxy, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "restore_state", restore_state, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "user_agent", user_agent, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "frame_flattening", frame_flattening, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "text_zoom", text_zoom, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "minimum_font_size", minimum_font_size, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "cookie_policy", cookie_policy, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_config_descriptor, Config, "backing_store", backing_store, EET_T_INT);
+}
+
+static inline void
+_config_shutdown(void)
+{
+ if (!_config_descriptor) return;
+ eet_data_descriptor_free(_config_descriptor);
+ _config_descriptor = NULL;
+}
+
+Config *
+config_new(unsigned char allow_popup, unsigned char enable_auto_load_images, unsigned char enable_auto_shrink_images, unsigned char enable_javascript, unsigned char enable_mouse_cursor, unsigned char enable_plugins, unsigned char enable_private_mode, unsigned char enable_touch_interface, const char * home_page, const char * proxy, unsigned char restore_state, const char * user_agent, unsigned char frame_flattening, int text_zoom, int minimum_font_size, int cookie_policy, int backing_store)
+{
+ Config *config = calloc(1, sizeof(Config));
+
+ if (!config)
+ {
+ fprintf(stderr, "ERROR: could not calloc Config\n");
+ return NULL;
+ }
+
+ config->allow_popup = allow_popup;
+ config->enable_auto_load_images = enable_auto_load_images;
+ config->enable_auto_shrink_images = enable_auto_shrink_images;
+ config->enable_javascript = enable_javascript;
+ config->enable_mouse_cursor = enable_mouse_cursor;
+ config->enable_plugins = enable_plugins;
+ config->enable_private_mode = enable_private_mode;
+ config->enable_touch_interface = enable_touch_interface;
+ config->home_page = eina_stringshare_add(home_page ? home_page : "http://www.google.com");
+ config->proxy = eina_stringshare_add(proxy);
+ config->restore_state = restore_state;
+ config->user_agent = eina_stringshare_add(user_agent ? user_agent : "eve");
+ config->frame_flattening = frame_flattening;
+ config->text_zoom = text_zoom;
+ config->minimum_font_size = minimum_font_size;
+ config->cookie_policy = cookie_policy;
+ config->backing_store = backing_store;
+
+ return config;
+}
+
+void
+config_free(Config *config)
+{
+ eina_stringshare_del(config->home_page);
+ eina_stringshare_del(config->proxy);
+ eina_stringshare_del(config->user_agent);
+ free(config);
+}
+
+inline unsigned char
+config_allow_popup_get(const Config *config)
+{
+ return config->allow_popup;
+}
+
+inline void
+config_allow_popup_set(Config *config, unsigned char allow_popup)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->allow_popup = allow_popup;
+}
+
+inline unsigned char
+config_enable_auto_load_images_get(const Config *config)
+{
+ return config->enable_auto_load_images;
+}
+
+inline void
+config_enable_auto_load_images_set(Config *config, unsigned char enable_auto_load_images)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_auto_load_images = enable_auto_load_images;
+}
+
+inline unsigned char
+config_enable_auto_shrink_images_get(const Config *config)
+{
+ return config->enable_auto_shrink_images;
+}
+
+inline void
+config_enable_auto_shrink_images_set(Config *config, unsigned char enable_auto_shrink_images)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_auto_shrink_images = enable_auto_shrink_images;
+}
+
+inline unsigned char
+config_enable_javascript_get(const Config *config)
+{
+ return config->enable_javascript;
+}
+
+inline void
+config_enable_javascript_set(Config *config, unsigned char enable_javascript)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_javascript = enable_javascript;
+}
+
+inline unsigned char
+config_enable_mouse_cursor_get(const Config *config)
+{
+ return config->enable_mouse_cursor;
+}
+
+inline void
+config_enable_mouse_cursor_set(Config *config, unsigned char enable_mouse_cursor)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_mouse_cursor = enable_mouse_cursor;
+}
+
+inline unsigned char
+config_enable_plugins_get(const Config *config)
+{
+ return config->enable_plugins;
+}
+
+inline void
+config_enable_plugins_set(Config *config, unsigned char enable_plugins)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_plugins = enable_plugins;
+}
+
+inline unsigned char
+config_enable_private_mode_get(const Config *config)
+{
+ return config->enable_private_mode;
+}
+
+inline void
+config_enable_private_mode_set(Config *config, unsigned char enable_private_mode)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_private_mode = enable_private_mode;
+}
+
+inline unsigned char
+config_enable_touch_interface_get(const Config *config)
+{
+ return config->enable_touch_interface;
+}
+
+inline void
+config_enable_touch_interface_set(Config *config, unsigned char enable_touch_interface)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->enable_touch_interface = enable_touch_interface;
+}
+
+inline const char *
+config_home_page_get(const Config *config)
+{
+ return config->home_page;
+}
+
+inline void
+config_home_page_set(Config *config, const char *home_page)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ eina_stringshare_replace(&(config->home_page), home_page);
+}
+
+inline const char *
+config_proxy_get(const Config *config)
+{
+ return config->proxy;
+}
+
+inline void
+config_proxy_set(Config *config, const char *proxy)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ eina_stringshare_replace(&(config->proxy), proxy);
+}
+
+inline unsigned char
+config_restore_state_get(const Config *config)
+{
+ return config->restore_state;
+}
+
+inline void
+config_restore_state_set(Config *config, unsigned char restore_state)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->restore_state = restore_state;
+}
+
+inline const char *
+config_user_agent_get(const Config *config)
+{
+ return config->user_agent;
+}
+
+inline void
+config_user_agent_set(Config *config, const char *user_agent)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ eina_stringshare_replace(&(config->user_agent), user_agent);
+}
+
+inline unsigned char
+config_frame_flattening_get(const Config *config)
+{
+ return config->frame_flattening;
+}
+
+inline void
+config_frame_flattening_set(Config *config, unsigned char frame_flattening)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->frame_flattening = frame_flattening;
+}
+
+inline int
+config_text_zoom_get(const Config *config)
+{
+ return config->text_zoom;
+}
+
+inline void
+config_text_zoom_set(Config *config, int text_zoom)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->text_zoom = text_zoom;
+}
+
+inline int
+config_minimum_font_size_get(const Config *config)
+{
+ return config->minimum_font_size;
+}
+
+inline void
+config_minimum_font_size_set(Config *config, int minimum_font_size)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->minimum_font_size = minimum_font_size;
+}
+
+inline int
+config_cookie_policy_get(const Config *config)
+{
+ return config->cookie_policy;
+}
+
+inline void
+config_cookie_policy_set(Config *config, int cookie_policy)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->cookie_policy = cookie_policy;
+}
+
+inline int
+config_backing_store_get(const Config *config)
+{
+ return config->backing_store;
+}
+
+inline void
+config_backing_store_set(Config *config, int backing_store)
+{
+ EINA_SAFETY_ON_NULL_RETURN(config);
+ config->backing_store = backing_store;
+}
+
+Config *
+config_load(const char *filename)
+{
+ Config *config = NULL;
+ Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
+ return NULL;
+ }
+
+ config = eet_data_read(ef, _config_descriptor, CONFIG_ENTRY);
+ if (!config) goto end;
+ config->__eet_filename = eina_stringshare_add(filename);
+
+end:
+ eet_close(ef);
+ return config;
+}
+
+Eina_Bool
+config_save(Config *config, const char *filename)
+{
+ Eet_File *ef;
+ Eina_Bool ret;
+
+ if (filename) eina_stringshare_replace(&(config->__eet_filename), filename);
+ else if (config->__eet_filename) filename = config->__eet_filename;
+ else return EINA_FALSE;
+
+ ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for write\n", filename);
+ return EINA_FALSE;
+ }
+
+ ret = !!eet_data_write(ef, _config_descriptor, CONFIG_ENTRY, config, EINA_TRUE);
+ eet_close(ef);
+
+ return ret;
+}
+
+static inline void
+_hist_item_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_hist_item_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Hist_Item);
+ _hist_item_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_hist_item_descriptor, Hist_Item, "title", title, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_hist_item_descriptor, Hist_Item, "url", url, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_hist_item_descriptor, Hist_Item, "visit_count", visit_count, EET_T_UINT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_hist_item_descriptor, Hist_Item, "last_visit", last_visit, EET_T_DOUBLE);
+}
+
+static inline void
+_hist_item_shutdown(void)
+{
+ if (!_hist_item_descriptor) return;
+ eet_data_descriptor_free(_hist_item_descriptor);
+ _hist_item_descriptor = NULL;
+}
+
+Hist_Item *
+hist_item_new(const char * title, const char * url, unsigned int visit_count, double last_visit)
+{
+ Hist_Item *hist_item = calloc(1, sizeof(Hist_Item));
+
+ if (!hist_item)
+ {
+ fprintf(stderr, "ERROR: could not calloc Hist_Item\n");
+ return NULL;
+ }
+
+ hist_item->title = eina_stringshare_add(title ? title : "Untitled");
+ hist_item->url = eina_stringshare_add(url ? url : "about:blank");
+ hist_item->visit_count = visit_count;
+ hist_item->last_visit = last_visit;
+
+ return hist_item;
+}
+
+void
+hist_item_free(Hist_Item *hist_item)
+{
+ eina_stringshare_del(hist_item->title);
+ eina_stringshare_del(hist_item->url);
+ free(hist_item);
+}
+
+inline const char *
+hist_item_title_get(const Hist_Item *hist_item)
+{
+ return hist_item->title;
+}
+
+inline void
+hist_item_title_set(Hist_Item *hist_item, const char *title)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist_item);
+ eina_stringshare_replace(&(hist_item->title), title);
+}
+
+inline const char *
+hist_item_url_get(const Hist_Item *hist_item)
+{
+ return hist_item->url;
+}
+
+inline void
+hist_item_url_set(Hist_Item *hist_item, const char *url)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist_item);
+ eina_stringshare_replace(&(hist_item->url), url);
+}
+
+inline unsigned int
+hist_item_visit_count_get(const Hist_Item *hist_item)
+{
+ return hist_item->visit_count;
+}
+
+inline void
+hist_item_visit_count_set(Hist_Item *hist_item, unsigned int visit_count)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist_item);
+ hist_item->visit_count = visit_count;
+}
+
+inline double
+hist_item_last_visit_get(const Hist_Item *hist_item)
+{
+ return hist_item->last_visit;
+}
+
+inline void
+hist_item_last_visit_set(Hist_Item *hist_item, double last_visit)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist_item);
+ hist_item->last_visit = last_visit;
+}
+
+
+static inline void
+_hist_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_hist_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Hist);
+ _hist_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_HASH(_hist_descriptor, Hist, "items", items, _hist_item_descriptor);
+}
+
+static inline void
+_hist_shutdown(void)
+{
+ if (!_hist_descriptor) return;
+ eet_data_descriptor_free(_hist_descriptor);
+ _hist_descriptor = NULL;
+}
+
+Hist *
+hist_new()
+{
+ Hist *hist = calloc(1, sizeof(Hist));
+
+ if (!hist)
+ {
+ fprintf(stderr, "ERROR: could not calloc Hist\n");
+ return NULL;
+ }
+
+ hist->items = eina_hash_stringshared_new(EINA_FREE_CB(hist_item_free));
+
+ return hist;
+}
+
+void
+hist_free(Hist *hist)
+{
+ if (hist->items) eina_hash_free(hist->items);
+ free(hist);
+}
+
+void
+hist_items_add(Hist *hist, const char * url, Hist_Item *hist_item)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist);
+ eina_hash_add(hist->items, url, hist_item);
+}
+
+void
+hist_items_del(Hist *hist, const char * url)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist);
+ eina_hash_del(hist->items, url, NULL);
+}
+
+inline Hist_Item *
+hist_items_get(const Hist *hist, const char * url)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hist, NULL);
+ return eina_hash_find(hist->items, url);
+}
+
+inline Eina_Hash *
+hist_items_hash_get(const Hist *hist)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(hist, NULL);
+ return hist->items;
+}
+
+void
+hist_items_modify(Hist *hist, const char * key, void *value)
+{
+ EINA_SAFETY_ON_NULL_RETURN(hist);
+ eina_hash_modify(hist->items, key, value);
+}
+
+Hist *
+hist_load(const char *filename)
+{
+ Hist *hist = NULL;
+ Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
+ return NULL;
+ }
+
+ hist = eet_data_read(ef, _hist_descriptor, HIST_ENTRY);
+ if (!hist) goto end;
+ hist->__eet_filename = eina_stringshare_add(filename);
+
+ if (!hist->items) hist->items = eina_hash_stringshared_new(EINA_FREE_CB(hist_item_free));
+
+end:
+ eet_close(ef);
+ return hist;
+}
+
+Eina_Bool
+hist_save(Hist *hist, const char *filename)
+{
+ Eet_File *ef;
+ Eina_Bool ret;
+
+ if (filename) eina_stringshare_replace(&(hist->__eet_filename), filename);
+ else if (hist->__eet_filename) filename = hist->__eet_filename;
+ else return EINA_FALSE;
+
+ ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for write\n", filename);
+ return EINA_FALSE;
+ }
+
+ ret = !!eet_data_write(ef, _hist_descriptor, HIST_ENTRY, hist, EINA_TRUE);
+ eet_close(ef);
+
+ return ret;
+}
+
+static inline void
+_fav_item_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_fav_item_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Fav_Item);
+ _fav_item_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_fav_item_descriptor, Fav_Item, "url", url, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_fav_item_descriptor, Fav_Item, "title", title, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_fav_item_descriptor, Fav_Item, "visit_count", visit_count, EET_T_UINT);
+}
+
+static inline void
+_fav_item_shutdown(void)
+{
+ if (!_fav_item_descriptor) return;
+ eet_data_descriptor_free(_fav_item_descriptor);
+ _fav_item_descriptor = NULL;
+}
+
+Fav_Item *
+fav_item_new(const char * url, const char * title, unsigned int visit_count)
+{
+ Fav_Item *fav_item = calloc(1, sizeof(Fav_Item));
+
+ if (!fav_item)
+ {
+ fprintf(stderr, "ERROR: could not calloc Fav_Item\n");
+ return NULL;
+ }
+
+ fav_item->url = eina_stringshare_add(url);
+ fav_item->title = eina_stringshare_add(title);
+ fav_item->visit_count = visit_count;
+
+ return fav_item;
+}
+
+void
+fav_item_free(Fav_Item *fav_item)
+{
+ eina_stringshare_del(fav_item->url);
+ eina_stringshare_del(fav_item->title);
+ free(fav_item);
+}
+
+inline const char *
+fav_item_url_get(const Fav_Item *fav_item)
+{
+ return fav_item->url;
+}
+
+inline void
+fav_item_url_set(Fav_Item *fav_item, const char *url)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav_item);
+ eina_stringshare_replace(&(fav_item->url), url);
+}
+
+inline const char *
+fav_item_title_get(const Fav_Item *fav_item)
+{
+ return fav_item->title;
+}
+
+inline void
+fav_item_title_set(Fav_Item *fav_item, const char *title)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav_item);
+ eina_stringshare_replace(&(fav_item->title), title);
+}
+
+inline unsigned int
+fav_item_visit_count_get(const Fav_Item *fav_item)
+{
+ return fav_item->visit_count;
+}
+
+inline void
+fav_item_visit_count_set(Fav_Item *fav_item, unsigned int visit_count)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav_item);
+ fav_item->visit_count = visit_count;
+}
+
+
+static inline void
+_fav_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_fav_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Fav);
+ _fav_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_HASH(_fav_descriptor, Fav, "items", items, _fav_item_descriptor);
+}
+
+static inline void
+_fav_shutdown(void)
+{
+ if (!_fav_descriptor) return;
+ eet_data_descriptor_free(_fav_descriptor);
+ _fav_descriptor = NULL;
+}
+
+Fav *
+fav_new()
+{
+ Fav *fav = calloc(1, sizeof(Fav));
+
+ if (!fav)
+ {
+ fprintf(stderr, "ERROR: could not calloc Fav\n");
+ return NULL;
+ }
+
+ fav->items = eina_hash_stringshared_new(EINA_FREE_CB(fav_item_free));
+
+ return fav;
+}
+
+void
+fav_free(Fav *fav)
+{
+ if (fav->items) eina_hash_free(fav->items);
+ free(fav);
+}
+
+void
+fav_items_add(Fav *fav, const char * url, Fav_Item *fav_item)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav);
+ eina_hash_add(fav->items, url, fav_item);
+}
+
+void
+fav_items_del(Fav *fav, const char * url)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav);
+ eina_hash_del(fav->items, url, NULL);
+}
+
+inline Fav_Item *
+fav_items_get(const Fav *fav, const char * url)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(fav, NULL);
+ return eina_hash_find(fav->items, url);
+}
+
+inline Eina_Hash *
+fav_items_hash_get(const Fav *fav)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(fav, NULL);
+ return fav->items;
+}
+
+void
+fav_items_modify(Fav *fav, const char * key, void *value)
+{
+ EINA_SAFETY_ON_NULL_RETURN(fav);
+ eina_hash_modify(fav->items, key, value);
+}
+
+Fav *
+fav_load(const char *filename)
+{
+ Fav *fav = NULL;
+ Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
+ return NULL;
+ }
+
+ fav = eet_data_read(ef, _fav_descriptor, FAV_ENTRY);
+ if (!fav) goto end;
+ fav->__eet_filename = eina_stringshare_add(filename);
+
+ if (!fav->items) fav->items = eina_hash_stringshared_new(EINA_FREE_CB(fav_item_free));
+
+end:
+ eet_close(ef);
+ return fav;
+}
+
+Eina_Bool
+fav_save(Fav *fav, const char *filename)
+{
+ Eet_File *ef;
+ Eina_Bool ret;
+
+ if (filename) eina_stringshare_replace(&(fav->__eet_filename), filename);
+ else if (fav->__eet_filename) filename = fav->__eet_filename;
+ else return EINA_FALSE;
+
+ ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for write\n", filename);
+ return EINA_FALSE;
+ }
+
+ ret = !!eet_data_write(ef, _fav_descriptor, FAV_ENTRY, fav, EINA_TRUE);
+ eet_close(ef);
+
+ return ret;
+}
+
+static inline void
+_session_item_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_session_item_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Session_Item);
+ _session_item_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_session_item_descriptor, Session_Item, "url", url, EET_T_STRING);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_session_item_descriptor, Session_Item, "focused", focused, EET_T_UCHAR);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_session_item_descriptor, Session_Item, "scroll_x", scroll_x, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_session_item_descriptor, Session_Item, "scroll_y", scroll_y, EET_T_INT);
+}
+
+static inline void
+_session_item_shutdown(void)
+{
+ if (!_session_item_descriptor) return;
+ eet_data_descriptor_free(_session_item_descriptor);
+ _session_item_descriptor = NULL;
+}
+
+Session_Item *
+session_item_new(const char * url, unsigned char focused, int scroll_x, int scroll_y)
+{
+ Session_Item *session_item = calloc(1, sizeof(Session_Item));
+
+ if (!session_item)
+ {
+ fprintf(stderr, "ERROR: could not calloc Session_Item\n");
+ return NULL;
+ }
+
+ session_item->url = eina_stringshare_add(url);
+ session_item->focused = focused;
+ session_item->scroll_x = scroll_x;
+ session_item->scroll_y = scroll_y;
+
+ return session_item;
+}
+
+void
+session_item_free(Session_Item *session_item)
+{
+ eina_stringshare_del(session_item->url);
+ free(session_item);
+}
+
+inline const char *
+session_item_url_get(const Session_Item *session_item)
+{
+ return session_item->url;
+}
+
+inline void
+session_item_url_set(Session_Item *session_item, const char *url)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_item);
+ eina_stringshare_replace(&(session_item->url), url);
+}
+
+inline unsigned char
+session_item_focused_get(const Session_Item *session_item)
+{
+ return session_item->focused;
+}
+
+inline void
+session_item_focused_set(Session_Item *session_item, unsigned char focused)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_item);
+ session_item->focused = focused;
+}
+
+inline int
+session_item_scroll_x_get(const Session_Item *session_item)
+{
+ return session_item->scroll_x;
+}
+
+inline void
+session_item_scroll_x_set(Session_Item *session_item, int scroll_x)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_item);
+ session_item->scroll_x = scroll_x;
+}
+
+inline int
+session_item_scroll_y_get(const Session_Item *session_item)
+{
+ return session_item->scroll_y;
+}
+
+inline void
+session_item_scroll_y_set(Session_Item *session_item, int scroll_y)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_item);
+ session_item->scroll_y = scroll_y;
+}
+
+
+static inline void
+_session_window_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_session_window_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Session_Window);
+ _session_window_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_LIST(_session_window_descriptor, Session_Window, "tabs", tabs, _session_item_descriptor);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_session_window_descriptor, Session_Window, "focused", focused, EET_T_UCHAR);
+}
+
+static inline void
+_session_window_shutdown(void)
+{
+ if (!_session_window_descriptor) return;
+ eet_data_descriptor_free(_session_window_descriptor);
+ _session_window_descriptor = NULL;
+}
+
+Session_Window *
+session_window_new(Eina_List * tabs, unsigned char focused)
+{
+ Session_Window *session_window = calloc(1, sizeof(Session_Window));
+
+ if (!session_window)
+ {
+ fprintf(stderr, "ERROR: could not calloc Session_Window\n");
+ return NULL;
+ }
+
+ session_window->tabs = tabs;
+ session_window->focused = focused;
+
+ return session_window;
+}
+
+void
+session_window_free(Session_Window *session_window)
+{
+ if (session_window->tabs)
+ {
+ Session_Item *tabs_elem;
+ EINA_LIST_FREE(session_window->tabs, tabs_elem)
+ session_item_free(tabs_elem);
+ }
+ free(session_window);
+}
+
+inline void
+session_window_tabs_add(Session_Window *session_window, Session_Item *session_item)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_window);
+ session_window->tabs = eina_list_append(session_window->tabs, session_item);
+}
+
+inline void
+session_window_tabs_del(Session_Window *session_window, Session_Item *session_item)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_window);
+ session_window->tabs = eina_list_remove(session_window->tabs, session_item);
+}
+
+inline Session_Item *
+session_window_tabs_get(const Session_Window *session_window, unsigned int nth)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session_window, NULL);
+ return eina_list_nth(session_window->tabs, nth);
+}
+
+inline unsigned int
+session_window_tabs_count(const Session_Window *session_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session_window, 0);
+ return eina_list_count(session_window->tabs);
+}
+
+void
+session_window_tabs_list_clear(Session_Window *session_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_window);
+ Session_Item *data;
+ EINA_LIST_FREE(session_window->tabs, data) session_item_free(data);
+}
+
+inline Eina_List *
+session_window_tabs_list_get(const Session_Window *session_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session_window, NULL);
+ return session_window->tabs;
+}
+
+inline void
+session_window_tabs_list_set(Session_Window *session_window, Eina_List *list)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_window);
+ session_window->tabs = list;
+}
+
+inline unsigned char
+session_window_focused_get(const Session_Window *session_window)
+{
+ return session_window->focused;
+}
+
+inline void
+session_window_focused_set(Session_Window *session_window, unsigned char focused)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session_window);
+ session_window->focused = focused;
+}
+
+
+static inline void
+_session_init(void)
+{
+ Eet_Data_Descriptor_Class eddc;
+
+ if (_session_descriptor) return;
+
+ EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Session);
+ _session_descriptor = eet_data_descriptor_stream_new(&eddc);
+
+ EET_DATA_DESCRIPTOR_ADD_LIST(_session_descriptor, Session, "windows", windows, _session_window_descriptor);
+}
+
+static inline void
+_session_shutdown(void)
+{
+ if (!_session_descriptor) return;
+ eet_data_descriptor_free(_session_descriptor);
+ _session_descriptor = NULL;
+}
+
+Session *
+session_new(Eina_List * windows)
+{
+ Session *session = calloc(1, sizeof(Session));
+
+ if (!session)
+ {
+ fprintf(stderr, "ERROR: could not calloc Session\n");
+ return NULL;
+ }
+
+ session->windows = windows;
+
+ return session;
+}
+
+void
+session_free(Session *session)
+{
+ if (session->windows)
+ {
+ Session_Window *windows_elem;
+ EINA_LIST_FREE(session->windows, windows_elem)
+ session_window_free(windows_elem);
+ }
+ free(session);
+}
+
+inline void
+session_windows_add(Session *session, Session_Window *session_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session);
+ session->windows = eina_list_append(session->windows, session_window);
+}
+
+inline void
+session_windows_del(Session *session, Session_Window *session_window)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session);
+ session->windows = eina_list_remove(session->windows, session_window);
+}
+
+inline Session_Window *
+session_windows_get(const Session *session, unsigned int nth)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session, NULL);
+ return eina_list_nth(session->windows, nth);
+}
+
+inline unsigned int
+session_windows_count(const Session *session)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session, 0);
+ return eina_list_count(session->windows);
+}
+
+void
+session_windows_list_clear(Session *session)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session);
+ Session_Window *data;
+ EINA_LIST_FREE(session->windows, data) session_window_free(data);
+}
+
+inline Eina_List *
+session_windows_list_get(const Session *session)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(session, NULL);
+ return session->windows;
+}
+
+inline void
+session_windows_list_set(Session *session, Eina_List *list)
+{
+ EINA_SAFETY_ON_NULL_RETURN(session);
+ session->windows = list;
+}
+
+Session *
+session_load(const char *filename)
+{
+ Session *session = NULL;
+ Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
+ return NULL;
+ }
+
+ session = eet_data_read(ef, _session_descriptor, SESSION_ENTRY);
+ if (!session) goto end;
+ session->__eet_filename = eina_stringshare_add(filename);
+
+end:
+ eet_close(ef);
+ return session;
+}
+
+Eina_Bool
+session_save(Session *session, const char *filename)
+{
+ Eet_File *ef;
+ Eina_Bool ret;
+
+ if (filename) eina_stringshare_replace(&(session->__eet_filename), filename);
+ else if (session->__eet_filename) filename = session->__eet_filename;
+ else return EINA_FALSE;
+
+ ef = eet_open(filename, EET_FILE_MODE_READ_WRITE);
+ if (!ef)
+ {
+ fprintf(stderr, "ERROR: could not open '%s' for write\n", filename);
+ return EINA_FALSE;
+ }
+
+ ret = !!eet_data_write(ef, _session_descriptor, SESSION_ENTRY, session, EINA_TRUE);
+ eet_close(ef);
+
+ return ret;
+}
+
+void
+viking_state_init(void)
+{
+ _config_init();
+ _hist_item_init();
+ _hist_init();
+ _fav_item_init();
+ _fav_init();
+ _session_item_init();
+ _session_window_init();
+ _session_init();
+}
+
+void
+viking_state_shutdown(void)
+{
+ _config_shutdown();
+ _hist_item_shutdown();
+ _hist_shutdown();
+ _fav_item_shutdown();
+ _fav_shutdown();
+ _session_item_shutdown();
+ _session_window_shutdown();
+ _session_shutdown();
+}
+
diff --git a/viking_state.h b/viking_state.h
@@ -0,0 +1,157 @@
+/* This file has been automatically generated by geneet.py */
+/* DO NOT MODIFY */
+
+#ifndef __VIKING_STATE_H__
+#define __VIKING_STATE_H__
+
+#include <Eina.h>
+#include <Eet.h>
+
+typedef struct _Config Config;
+typedef struct _Hist_Item Hist_Item;
+typedef struct _Hist Hist;
+typedef struct _Fav_Item Fav_Item;
+typedef struct _Fav Fav;
+typedef struct _Session_Item Session_Item;
+typedef struct _Session_Window Session_Window;
+typedef struct _Session Session;
+
+/* Config */
+Config *config_new(unsigned char allow_popup, unsigned char enable_auto_load_images, unsigned char enable_auto_shrink_images, unsigned char enable_javascript, unsigned char enable_mouse_cursor, unsigned char enable_plugins, unsigned char enable_private_mode, unsigned char enable_touch_interface, const char * home_page, const char * proxy, unsigned char restore_state, const char * user_agent, unsigned char frame_flattening, int text_zoom, int minimum_font_size, int cookie_policy, int backing_store);
+void config_free(Config *config);
+
+void config_allow_popup_set(Config *config, unsigned char allow_popup);
+unsigned char config_allow_popup_get(const Config *config);
+void config_enable_auto_load_images_set(Config *config, unsigned char enable_auto_load_images);
+unsigned char config_enable_auto_load_images_get(const Config *config);
+void config_enable_auto_shrink_images_set(Config *config, unsigned char enable_auto_shrink_images);
+unsigned char config_enable_auto_shrink_images_get(const Config *config);
+void config_enable_javascript_set(Config *config, unsigned char enable_javascript);
+unsigned char config_enable_javascript_get(const Config *config);
+void config_enable_mouse_cursor_set(Config *config, unsigned char enable_mouse_cursor);
+unsigned char config_enable_mouse_cursor_get(const Config *config);
+void config_enable_plugins_set(Config *config, unsigned char enable_plugins);
+unsigned char config_enable_plugins_get(const Config *config);
+void config_enable_private_mode_set(Config *config, unsigned char enable_private_mode);
+unsigned char config_enable_private_mode_get(const Config *config);
+void config_enable_touch_interface_set(Config *config, unsigned char enable_touch_interface);
+unsigned char config_enable_touch_interface_get(const Config *config);
+void config_home_page_set(Config *config, const char * home_page);
+const char * config_home_page_get(const Config *config);
+void config_proxy_set(Config *config, const char * proxy);
+const char * config_proxy_get(const Config *config);
+void config_restore_state_set(Config *config, unsigned char restore_state);
+unsigned char config_restore_state_get(const Config *config);
+void config_user_agent_set(Config *config, const char * user_agent);
+const char * config_user_agent_get(const Config *config);
+void config_frame_flattening_set(Config *config, unsigned char frame_flattening);
+unsigned char config_frame_flattening_get(const Config *config);
+void config_text_zoom_set(Config *config, int text_zoom);
+int config_text_zoom_get(const Config *config);
+void config_minimum_font_size_set(Config *config, int minimum_font_size);
+int config_minimum_font_size_get(const Config *config);
+void config_cookie_policy_set(Config *config, int cookie_policy);
+int config_cookie_policy_get(const Config *config);
+void config_backing_store_set(Config *config, int backing_store);
+int config_backing_store_get(const Config *config);
+
+Config *config_load(const char *filename);
+Eina_Bool config_save(Config *config, const char *filename);
+
+/* Hist_Item */
+Hist_Item *hist_item_new(const char * title, const char * url, unsigned int visit_count, double last_visit);
+void hist_item_free(Hist_Item *hist_item);
+
+void hist_item_title_set(Hist_Item *hist_item, const char * title);
+const char * hist_item_title_get(const Hist_Item *hist_item);
+void hist_item_url_set(Hist_Item *hist_item, const char * url);
+const char * hist_item_url_get(const Hist_Item *hist_item);
+void hist_item_visit_count_set(Hist_Item *hist_item, unsigned int visit_count);
+unsigned int hist_item_visit_count_get(const Hist_Item *hist_item);
+void hist_item_last_visit_set(Hist_Item *hist_item, double last_visit);
+double hist_item_last_visit_get(const Hist_Item *hist_item);
+
+/* Hist */
+Hist *hist_new(void);
+void hist_free(Hist *hist);
+
+void hist_items_add(Hist *hist, const char * url, Hist_Item *hist_item);
+void hist_items_del(Hist *hist, const char * url);
+Hist_Item *hist_items_get(const Hist *hist, const char * key);
+Eina_Hash *hist_items_hash_get(const Hist *hist);
+void hist_items_modify(Hist *hist, const char * key, void *value);
+
+Hist *hist_load(const char *filename);
+Eina_Bool hist_save(Hist *hist, const char *filename);
+
+/* Fav_Item */
+Fav_Item *fav_item_new(const char * url, const char * title, unsigned int visit_count);
+void fav_item_free(Fav_Item *fav_item);
+
+void fav_item_url_set(Fav_Item *fav_item, const char * url);
+const char * fav_item_url_get(const Fav_Item *fav_item);
+void fav_item_title_set(Fav_Item *fav_item, const char * title);
+const char * fav_item_title_get(const Fav_Item *fav_item);
+void fav_item_visit_count_set(Fav_Item *fav_item, unsigned int visit_count);
+unsigned int fav_item_visit_count_get(const Fav_Item *fav_item);
+
+/* Fav */
+Fav *fav_new(void);
+void fav_free(Fav *fav);
+
+void fav_items_add(Fav *fav, const char * url, Fav_Item *fav_item);
+void fav_items_del(Fav *fav, const char * url);
+Fav_Item *fav_items_get(const Fav *fav, const char * key);
+Eina_Hash *fav_items_hash_get(const Fav *fav);
+void fav_items_modify(Fav *fav, const char * key, void *value);
+
+Fav *fav_load(const char *filename);
+Eina_Bool fav_save(Fav *fav, const char *filename);
+
+/* Session_Item */
+Session_Item *session_item_new(const char * url, unsigned char focused, int scroll_x, int scroll_y);
+void session_item_free(Session_Item *session_item);
+
+void session_item_url_set(Session_Item *session_item, const char * url);
+const char * session_item_url_get(const Session_Item *session_item);
+void session_item_focused_set(Session_Item *session_item, unsigned char focused);
+unsigned char session_item_focused_get(const Session_Item *session_item);
+void session_item_scroll_x_set(Session_Item *session_item, int scroll_x);
+int session_item_scroll_x_get(const Session_Item *session_item);
+void session_item_scroll_y_set(Session_Item *session_item, int scroll_y);
+int session_item_scroll_y_get(const Session_Item *session_item);
+
+/* Session_Window */
+Session_Window *session_window_new(Eina_List * tabs, unsigned char focused);
+void session_window_free(Session_Window *session_window);
+
+void session_window_tabs_add(Session_Window *session_window, Session_Item *session_item);
+void session_window_tabs_del(Session_Window *session_window, Session_Item *session_item);
+Session_Item *session_window_tabs_get(const Session_Window *session_window, unsigned int nth);
+unsigned int session_window_tabs_count(const Session_Window *session_window);
+Eina_List *session_window_tabs_list_get(const Session_Window *session_window);
+void session_window_tabs_list_clear(Session_Window *session_window);
+void session_window_tabs_list_set(Session_Window *session_window, Eina_List *list);
+void session_window_focused_set(Session_Window *session_window, unsigned char focused);
+unsigned char session_window_focused_get(const Session_Window *session_window);
+
+/* Session */
+Session *session_new(Eina_List * windows);
+void session_free(Session *session);
+
+void session_windows_add(Session *session, Session_Window *session_window);
+void session_windows_del(Session *session, Session_Window *session_window);
+Session_Window *session_windows_get(const Session *session, unsigned int nth);
+unsigned int session_windows_count(const Session *session);
+Eina_List *session_windows_list_get(const Session *session);
+void session_windows_list_clear(Session *session);
+void session_windows_list_set(Session *session, Eina_List *list);
+
+Session *session_load(const char *filename);
+Eina_Bool session_save(Session *session, const char *filename);
+
+/* Global initializer / shutdown functions */
+void viking_state_init(void);
+void viking_state_shutdown(void);
+
+#endif /* __VIKING_STATE_H__ */