viking

webkit based web browser for Enlightenment
Log | Files | Refs | LICENSE

commands.c (24752B)


      1 
      2 #include <Elementary.h>
      3 #include <EWebKit2.h>
      4 
      5 #include "viking_state.h"
      6 #include "viking.h"
      7 #include "commands.h"
      8 #include "utilities.h"
      9 #include "window.h"
     10 #include "buffer.h"
     11 #include "keymap.h"
     12 
     13 // static unsigned int scrollstep          = 40;   /* cursor difference in pixel */
     14 // static unsigned int pagingkeep          = 40;   /* pixels kept when paging */
     15 
     16 // The zoom values are chosen to be like in Mozilla Firefox 3.
     17 const static float zoom_levels[] = {0.3, 0.5, 0.67, 0.8, 0.9, 1.0, 1.1, 1.2, 1.33, 1.5, 1.7, 2.0, 2.4, 3.0};
     18 
     19 Eina_Bool
     20 complete(const Arg *arg, void *data)
     21 {
     22 	Window_Data *wd = data;
     23 	const char *match;
     24 	Eina_List *l;
     25 	size_t len;
     26 	int i;
     27 	Evas_Object *label;
     28 
     29 	/* make this function re-entrant */
     30 	static Eina_List *matches = NULL;
     31 	static const char *prefix;
     32 	static int current = -1, n;
     33 	static Eina_List *widgets = NULL;
     34 
     35 	printf("complete()\n");
     36 
     37 	match = elm_entry_entry_get(wd->url);
     38 	len = strlen(match);
     39 
     40 	if ((len == 0 || match[0] != ':') && arg->i != HideCompletion)
     41 		return EINA_TRUE;
     42 
     43 	if (prefix) {
     44 		printf("\tprefix found, current = %i, num matches = %i\n", current, eina_list_count(matches));
     45 		if (arg->i != HideCompletion && widgets && current != -1 && !strcmp(&match[0],
     46 					eina_list_nth(matches, current))) {
     47 			elm_object_style_set(eina_list_nth(widgets, current), "default");
     48 			current = (n + current + (arg->i == DirectionPrev ? -1 : 1)) % n;
     49 			if ((arg->i == DirectionNext && current == 0)
     50 					|| (arg->i == DirectionPrev && current == n - 1))
     51 				current = -1;
     52 		} else {
     53 			eina_list_free(widgets);
     54 			eina_list_free(matches);
     55 			eina_stringshare_del(prefix);
     56 			elm_box_clear(wd->event_box);
     57 			widgets = NULL;
     58 			matches = NULL;
     59 			prefix = NULL;
     60 			n = 0;
     61 			current = -1;
     62 			if (arg->i == HideCompletion)
     63 				return EINA_TRUE;
     64 		}
     65 	} else if (arg->i == HideCompletion)
     66 		return EINA_TRUE;
     67 
     68 
     69 	if (!widgets) {
     70 		prefix = eina_stringshare_add(match);
     71 
     72 		if (strchr(match, ' ') == NULL) {
     73 			for (i = 0; i < LENGTH(commands); i++)
     74 				if (strncmp(commands[i].cmd, match + 1, len - 1) == 0) {
     75 					Eina_Strbuf *buf = eina_strbuf_new();
     76 					eina_strbuf_append_printf(buf, ":%s", commands[i].cmd);
     77 					matches = eina_list_append(matches, eina_strbuf_string_steal(buf));
     78 				}
     79 		}
     80 
     81 		char **tokens = eina_str_split(match, " ", 2);
     82 		if (tokens && (strncmp(tokens[0], ":open", 5) == 0 ||
     83 					strncmp(tokens[0], ":tabopen", 8) == 0)) {
     84 			/* :open history completion */
     85 			void *hash_data;
     86 			Eina_Iterator *it = eina_hash_iterator_tuple_new(hist_items_hash_get(wd->app->history));
     87 
     88 			while (eina_iterator_next(it, &hash_data)) {
     89 				Eina_Hash_Tuple *t = hash_data;
     90 				Eina_Strbuf *buf = eina_strbuf_new();
     91 				Hist_Item *hist_item = t->data;
     92 				const char *url = hist_item_url_get(hist_item);
     93 				if (strncmp(url, tokens[1], strlen(tokens[1])) == 0) {
     94 					eina_strbuf_append_printf(buf, "%s %s", tokens[0], url);
     95 					matches = eina_list_append(matches, eina_strbuf_string_steal(buf));
     96 				}
     97 			}
     98 			eina_iterator_free(it);
     99 		}
    100 		else if (tokens && strncmp(tokens[0], ":set", 5) == 0) {
    101 			printf("\t:set not implemented yet\n");
    102 		}
    103 
    104 		n = eina_list_count(matches);
    105 		printf("\tfound %i matches for %s\n", n, match);
    106 
    107 		EINA_LIST_FOREACH(matches, l, match) {
    108 
    109 			printf("\tbuilding label for match %s\n", match);
    110 
    111 			label = elm_label_add(wd->win);
    112 			evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
    113 			elm_object_text_set(label, match);
    114 			elm_box_pack_end(wd->event_box, label);
    115 			evas_object_show(label);
    116 
    117 			widgets = eina_list_append(widgets, label);
    118 		}
    119 
    120 		if (!n) {
    121 			label = elm_label_add(wd->win);
    122 			evas_object_size_hint_align_set(label, 0.0, EVAS_HINT_FILL);
    123 			elm_object_text_set(label, "No Completions");
    124 			elm_box_pack_end(wd->event_box, label);
    125 			evas_object_show(label);
    126 		}
    127 
    128 		evas_object_show(wd->event_box);
    129 		if (!n)
    130 			return EINA_TRUE;
    131 		current = arg->i == DirectionPrev ? n - 1 : 0;
    132 	}
    133 
    134 	if (current != -1) {
    135 		Eina_Strbuf *suggestion = eina_strbuf_new();
    136 		eina_strbuf_append_printf(suggestion, "%s", (char*)eina_list_nth(matches, current));
    137 		elm_entry_entry_set(wd->url, eina_strbuf_string_steal(suggestion));
    138 		elm_object_style_set(eina_list_nth(widgets, current), "highlighted");
    139 	} else
    140 		elm_entry_entry_set(wd->url, prefix);
    141 	elm_entry_cursor_end_set(wd->url);
    142 
    143 	return EINA_TRUE;
    144 }
    145 
    146 Eina_Bool
    147 descend(const Arg *arg, void *data) 
    148 {
    149 	Window_Data *wd = data;
    150 	// char *source = (char*)webkit_web_view_get_uri(webview), *p = &source[0], *new;
    151 	const char *source = ewk_view_url_get(wd->cur_buf->view);
    152 	const char *p = &source[0];
    153 	char *new;
    154 
    155 	int i, len;
    156 	wd->count = wd->count ? wd->count : 1;
    157 
    158 	if (!source)
    159 		return EINA_TRUE;
    160 	if (arg->i == Rootdir) {
    161 		for (i = 0; i < 3; i++)                  /* get to the third slash */
    162 			if (!(p = strchr(++p, '/')))
    163 				return EINA_TRUE;                    /* if we cannot find it quit */
    164 	} else {
    165 		len = strlen(source);
    166 		if (!len)                                /* if string is empty quit */
    167 			return EINA_TRUE;
    168 		p = source + len;                       /* start at the end */
    169 		if (*(p - 1) == '/')                     /* /\/$/ is not an additional level */
    170 			++(wd->count);
    171 		for (i = 0; i < wd->count; i++)
    172 			while(*(p--) != '/' || *p == '/')   /* count /\/+/ as one slash */
    173 				if (p == source)                 /* if we reach the first char pointer quit */
    174 					return EINA_TRUE;
    175 		++p;                                    /* since we do p-- in the while, we are pointing at
    176 												   the char before the slash, so +1  */
    177 	}
    178 	len =  p - source + 1;                      /* new length = end - start + 1 */
    179 	new = malloc(len + 1);
    180 	memcpy(new, source, len);
    181 	new[len] = '\0';
    182 	ewk_view_url_set(wd->cur_buf->view, new);
    183 	free(new);
    184 
    185 	return EINA_TRUE;
    186 }
    187 
    188 Eina_Bool
    189 input(const Arg *arg, void *data) 
    190 {
    191 	// int pos = 0;
    192 	const char *url;
    193 	// int index = Info;
    194 	Arg a;
    195 	Window_Data *wd = data;
    196 	wd->count = 0;
    197 
    198 	/* if inputbox hidden, show it again */
    199 	// if (!gtk_widget_get_visible(inputbox))
    200 	//    gtk_widget_set_visible(inputbox, TRUE);
    201 	if (!evas_object_visible_get(wd->url))
    202 		evas_object_show(wd->url);
    203 
    204 	// update_state(data);
    205 
    206 	/* Set the colour and font back to the default, so that we don't still
    207 	 * maintain a red colour from a warning from an end of search indicator,
    208 	 * etc.
    209 	 */
    210 	// set_widget_font_and_color(wd->url, urlboxfont[index], urlboxbgcolor[index], urlboxcolor[index]);
    211 
    212 	/* to avoid things like :open URL :open URL2  or :open :open URL */
    213 	// gtk_entry_set_text(GTK_ENTRY(inputbox), "");
    214 	elm_entry_entry_set(wd->url, "");
    215 
    216 	/*
    217 	   gtk_editable_insert_text(GTK_EDITABLE(inputbox), arg->s, -1, &pos);
    218 	   if (arg->i & InsertCurrentURL && (url = webkit_web_view_get_uri(webview)))
    219 	   gtk_editable_insert_text(GTK_EDITABLE(inputbox), url, -1, &pos);
    220 
    221 	   gtk_widget_grab_focus(inputbox);
    222 	   gtk_editable_set_position(GTK_EDITABLE(inputbox), -1);
    223 	   */
    224 
    225 	elm_entry_entry_set(wd->url, arg->s);
    226 	if (arg->i & InsertCurrentURL && (url = ewk_view_url_get(wd->cur_buf->view)))
    227 		elm_entry_entry_append(wd->url, url);
    228 
    229 	// evas_object_focus_set(ad->cur_buf->view, EINA_FALSE);
    230 	elm_object_focus_set(wd->url, EINA_TRUE);
    231 	elm_entry_cursor_end_set(wd->url);
    232 
    233 	if (arg->s[0] == '.' || arg->s[0] == ',' || arg->s[0] == ';') {
    234 		wd->mode = ModeHints;
    235 		memset(wd->followTarget, 0, 8);
    236 		strncpy(wd->followTarget, "current", 8);
    237 		a.i = Silent;
    238 
    239 		switch (arg->s[0]) {
    240 		case '.':
    241 			a.s = strdup("hints.createHints('', 'f');");
    242 			break;
    243 
    244 		case ',':
    245 			a.s = strdup("hints.createHints('', 'F');");
    246 			break;
    247 
    248 		case ';':
    249 			a.s = NULL;
    250 			if (arg->s[1]) {
    251 
    252 				switch (arg->s[1]) {
    253 				case 's':
    254 					a.s = strdup("hints.createHints('', 's');");
    255 					break;
    256 				case 'y':
    257 					a.s = strdup("hints.createHints('', 'y');");
    258 					break;
    259 				case 'o':
    260 					a.s = strdup("hints.createHints('', 'f');");
    261 					break;
    262 				case 't': case 'w':
    263 					a.s = strdup("hints.createHints('', 'F');");
    264 					break;
    265 				case 'O': case 'T': case 'W':
    266 					a.s = strdup("hints.createHints('', 'O');");
    267 					break;
    268 				case 'i':
    269 					a.s = strdup("hints.createHints('', 'i');");
    270 					break;
    271 				case 'I':
    272 					a.s = strdup("hints.createHints('', 'I');");
    273 					break;
    274 				}
    275 
    276 			}
    277 			break;
    278 		}
    279 
    280 		wd->count = 0;
    281 		if (a.s) {
    282 			script(&a, data);
    283 			free(a.s);
    284 		}
    285 	}
    286 
    287 	return EINA_TRUE;
    288 }
    289 
    290 Eina_Bool
    291 navigate(const Arg *arg, void *data) 
    292 {
    293 	Window_Data *ad = data;
    294 
    295 	if (arg->i & NavigationForwardBack) {
    296 		// ewk_view_navigate(ad->cur_buf->view, (arg->i == NavigationBack ? -1 : 1) * 
    297 		// (ad->count ? ad->count : 1));
    298 		if (arg->i == NavigationBack)
    299 			ewk_view_back(ad->cur_buf->view);
    300 		else
    301 			ewk_view_forward(ad->cur_buf->view);
    302 	}
    303 	else if (arg->i & NavigationReloadActions)
    304 		(arg->i == NavigationReload ? ewk_view_reload : ewk_view_reload_bypass_cache)(ad->cur_buf->view);
    305 	else
    306 		ewk_view_stop(ad->cur_buf->view);
    307 
    308 	return EINA_TRUE;
    309 }
    310 
    311 Eina_Bool
    312 number(const Arg *arg, void *data) 
    313 {
    314 	Window_Data *wd = data;
    315 	// const char *source = webkit_web_view_get_uri(webview);
    316 	const char *source = ewk_view_url_get(wd->cur_buf->view);
    317 	char *uri, *p, *new;
    318 	int number, diff = (wd->count ? wd->count : 1) * (arg->i == Increment ? 1 : -1);
    319 
    320 	if (!source)
    321 		return EINA_TRUE;
    322 	uri = strdup(source); /* copy string */
    323 	p =& uri[0];
    324 	while(*p != '\0') /* goto the end of the string */
    325 		++p;
    326 	--p;
    327 	while(*p >= '0' && *p <= '9') /* go back until non number char is reached */
    328 		--p;
    329 	if (*(++p) == '\0') { /* if no numbers were found abort */
    330 		free(uri);
    331 		return EINA_TRUE;
    332 	}
    333 	number = atoi(p) + diff; /* apply diff on number */
    334 	*p = '\0';
    335 	new = strdup_printf("%s%d", uri, number); /* create new uri */
    336 	ewk_view_url_set(wd->cur_buf->view, new);
    337 	free(new);
    338 	free(uri);
    339 
    340 	return EINA_TRUE;
    341 }
    342 
    343 Eina_Bool
    344 open_arg(const Arg *arg, void *data) 
    345 {
    346 	Arg a = { .i = NavigationReload };
    347 	Window_Data *wd = data;
    348 	Buffer_Data *buf_new;
    349 
    350 	if (!arg->s) {
    351 		navigate(&a, wd);
    352 	}
    353 	else if (arg->i == TargetCurrent) {
    354 		ewk_view_url_set(wd->cur_buf->view, uri_sanitize(arg->s));
    355 	}
    356 	else if (arg->i == TargetNew) {
    357 		buffer_add(SwitchToBuffer, wd, NULL, NULL);
    358 		a.i = TargetCurrent;
    359 		a.s = arg->s;
    360 		open_arg(&a, wd);
    361 	}
    362 	else if (arg->i == TargetNewWindow) {
    363 		buf_new = buffer_add(SwitchToBuffer | InNewWindow, wd, NULL, NULL);
    364 		a.i = TargetCurrent;
    365 		a.s = arg->s;
    366 		open_arg(&a, buf_new->window);
    367 	}
    368 
    369 	return EINA_TRUE;
    370 }
    371 
    372 Eina_Bool
    373 open_remembered(const Arg *arg, void *data)
    374 {
    375 	Window_Data *wd = data;
    376 
    377     Arg a = {arg->i, wd->rememberedURI};
    378 
    379     if (strcmp(wd->rememberedURI, ""))
    380         open_arg(&a, wd);
    381 
    382     return EINA_TRUE;
    383 }
    384 
    385 Eina_Bool
    386 yank(const Arg *arg, void *data) {
    387 	/*
    388     const char *url, *feedback, *content;
    389 
    390     if (arg->i & SourceSelection) {
    391         webkit_web_view_copy_clipboard(webview);
    392         if (arg->i & ClipboardPrimary)
    393             content = gtk_clipboard_wait_for_text(clipboards[0]);
    394         if (!content && arg->i & ClipboardGTK)
    395             content = gtk_clipboard_wait_for_text(clipboards[1]);
    396         if (content) {
    397             feedback = g_strconcat("Yanked ", content, NULL);
    398             g_free((gpointer *)content);
    399             give_feedback(feedback);
    400             g_free((gpointer *)feedback);
    401         }
    402     } else {
    403         if (arg->i & SourceURL) {
    404             url = webkit_web_view_get_uri(webview);
    405         } else {
    406             url = arg->s;
    407         }
    408         if (!url)
    409             return TRUE;
    410         feedback = g_strconcat("Yanked ", url, NULL);
    411         give_feedback(feedback);
    412         if (arg->i & ClipboardPrimary)
    413             gtk_clipboard_set_text(clipboards[0], url, -1);
    414         if (arg->i & ClipboardGTK)
    415             gtk_clipboard_set_text(clipboards[1], url, -1);
    416     }
    417 	*/
    418     return EINA_TRUE;
    419 }
    420 
    421 Eina_Bool
    422 paste(const Arg *arg, void *data) {
    423 	/*
    424     Arg a = { .i = arg->i & TargetNew, .s = NULL };
    425 
    426     // If we're over a link, open it in a new target.
    427     if (strlen(rememberedURI) > 0) {
    428         Arg new_target = { .i = TargetNew, .s = arg->s };
    429         open_arg(&new_target);
    430         return TRUE;
    431     }
    432 
    433     if (arg->i & ClipboardPrimary)
    434         a.s = gtk_clipboard_wait_for_text(clipboards[0]);
    435     if (!a.s && arg->i & ClipboardGTK)
    436         a.s = gtk_clipboard_wait_for_text(clipboards[1]);
    437     if (a.s) {
    438         open_arg(&a);
    439         g_free(a.s);
    440     }
    441 	*/
    442     return EINA_TRUE;
    443 }
    444 
    445 Eina_Bool
    446 buffer(const Arg *arg, void *data)
    447 {
    448 	Window_Data *wd = data;
    449 	Eina_List *cur, *next, *prev;
    450 
    451 	cur = eina_list_data_find_list(wd->buffer_list, wd->cur_buf);
    452 	next = eina_list_next(cur);
    453 	prev = eina_list_prev(cur);
    454 
    455 	// elm_naviframe_item_pop(wd->naviframe);
    456 	evas_object_del(wd->cur_buf->view);
    457 
    458 	if (next) {
    459 		printf("buffer_quit() setting main buf to next element\n");
    460 		window_main_buffer_set(eina_list_data_get(next));
    461 	}
    462 	else if (prev) {
    463 		printf("buffer_quit() setting main buf to prev element\n");
    464 		window_main_buffer_set(eina_list_data_get(prev));
    465 	}
    466 	else {
    467 		printf("buffer_quit() no ->next or ->prev, deleting window!\n");
    468 		evas_object_del(wd->win);
    469 	}
    470 
    471 	return EINA_TRUE;
    472 }
    473 
    474 Eina_Bool
    475 quit(const Arg *arg, void *data)
    476 {
    477 	Window_Data *wd = data;
    478 	App_Data *ad = wd->app;
    479 
    480 	ad->exiting = EINA_TRUE;
    481 	elm_exit();
    482 
    483 	return EINA_TRUE;
    484 }
    485 
    486 Eina_Bool
    487 revive(const Arg *arg, void *data)
    488 {
    489 	// Window_Data *ad = data;
    490 	return EINA_FALSE;
    491 }
    492 
    493 Eina_Bool 
    494 print_frame(const Arg *arg, void *data)
    495 {
    496 	/* can webkit-efl even do this? 
    497 	 *
    498     WebKitWebFrame *frame = webkit_web_view_get_main_frame(webview);
    499     webkit_web_frame_print (frame);
    500 	*/
    501     return EINA_TRUE;
    502 }
    503 
    504 Eina_Bool
    505 search(const Arg *arg, void *data)
    506 {
    507 	Window_Data *ad = data;
    508 
    509 	ad->count = ad->count ? ad->count : 1;
    510 	Eina_Bool success, direction = arg->i & DirectionPrev;
    511 	Arg a;
    512 	char flags = EWK_FIND_OPTIONS_SHOW_HIGHLIGHT | EWK_FIND_OPTIONS_CASE_INSENSITIVE;
    513 
    514 	if (arg->s) {
    515 		free(ad->search_handle);
    516 		ad->search_handle = strdup(arg->s);
    517 	}
    518 	if (!ad->search_handle)
    519 		return EINA_TRUE;
    520 	if (arg->i & DirectionAbsolute)
    521 		ad->search_direction = direction;
    522 	else
    523 		direction ^= ad->search_direction;
    524 	do {
    525 		if (!direction)
    526 			flags |= EWK_FIND_OPTIONS_BACKWARDS;
    527 		success = ewk_view_text_find(ad->cur_buf->view, ad->search_handle, flags, 1000);
    528 		if (!success) {
    529 			if (arg->i & Wrapping) {
    530 				success = ewk_view_text_find(ad->cur_buf->view, ad->search_handle,
    531 					 flags | EWK_FIND_OPTIONS_WRAP_AROUND, 1000);
    532 				if (success) {
    533 					a.i = Warning;
    534 					a.s = strdup_printf("search hit %s, continuing at %s",
    535 							direction ? "BOTTOM" : "TOP",
    536 							direction ? "TOP" : "BOTTOM");
    537 					echo(&a, data);
    538 					free(a.s);
    539 				} else
    540 					break;
    541 			} else
    542 				break;
    543 		}
    544 	} while(--(ad->count));
    545 	if (!success) {
    546 		a.i = Error;
    547 		a.s = strdup_printf("<bold>Pattern not found: %s", ad->search_handle);
    548 		echo(&a, data);
    549 		free(a.s);
    550 	}
    551 	return EINA_TRUE;
    552 }
    553 
    554 Eina_Bool
    555 set(const Arg *arg, void *data)
    556 {
    557 	Window_Data *ad = data;
    558 	Arg a = { .i = Info | NoAutoHide };
    559 
    560 	switch (arg->i) {
    561 		case ModeNormal:
    562 			if (ad->search_handle) {
    563 				ad->search_handle = NULL;
    564 				ewk_view_text_find_highlight_clear(ad->cur_buf->view);
    565 			}
    566 			// gtk_entry_set_text(GTK_ENTRY(inputbox), "");
    567 			// gtk_widget_grab_focus(GTK_WIDGET(webview));
    568 			elm_entry_entry_set(ad->url, "");
    569 			elm_object_focus_set(elm_object_top_widget_get(ad->win), EINA_FALSE);
    570 			evas_object_focus_set(ad->cur_buf->view, EINA_TRUE);
    571 			break;
    572 		case ModePassThrough:
    573 			a.s = strdup("-- PASS THROUGH --");
    574 			echo(&a, data);
    575 			free(a.s);
    576 			break;
    577 		case ModeSendKey:
    578 			a.s = strdup("-- PASS TROUGH (next) --");
    579 			echo(&a, data);
    580 			free(a.s);
    581 			break;
    582 		case ModeInsert: /* should not be called manually but automatically */
    583 			a.s = strdup("-- INSERT --");
    584 			echo(&a, data);
    585 			free(a.s);
    586 			break;
    587 		default:
    588 			return EINA_TRUE;
    589 	}
    590 	ad->mode = arg->i;
    591 	return EINA_TRUE;
    592 }
    593 
    594 /*
    595 gchar*
    596 jsapi_ref_to_string(JSContextRef context, JSValueRef ref) {
    597     JSStringRef string_ref;
    598     gchar *string;
    599     size_t length;
    600 
    601     string_ref = JSValueToStringCopy(context, ref, NULL);
    602     length = JSStringGetMaximumUTF8CStringSize(string_ref);
    603     string = g_new(gchar, length);
    604     JSStringGetUTF8CString(string_ref, string, length);
    605     JSStringRelease(string_ref);
    606     return string;
    607 }
    608 
    609 void
    610 jsapi_evaluate_script(const gchar *script, gchar **value, gchar **message) {
    611     WebKitWebFrame *frame = webkit_web_view_get_main_frame(webview);
    612     JSGlobalContextRef context = webkit_web_frame_get_global_context(frame);
    613     JSStringRef str;
    614     JSValueRef val, exception;
    615 
    616     str = JSStringCreateWithUTF8CString(script);
    617     val = JSEvaluateScript(context, str, JSContextGetGlobalObject(context), NULL, 0, &exception);
    618     JSStringRelease(str);
    619     if (!val)
    620         *message = jsapi_ref_to_string(context, exception);
    621     else
    622         *value = jsapi_ref_to_string(context, val);
    623 }
    624 */
    625 
    626 Eina_Bool
    627 quickmark(const Arg *a, void *data) 
    628 {
    629 	return EINA_FALSE;
    630 }
    631 
    632 Eina_Bool
    633 script(const Arg *arg, void *data)
    634 {
    635 	// gchar *value = NULL, *message = NULL;
    636 	const char *value = NULL;
    637 	char text[1024] = "";
    638 	Arg a;
    639 	// WebKitNetworkRequest *request;
    640 	// WebKitDownload *download;
    641 	Window_Data *ad = data;
    642 	// Evas_Object *frame = ewk_view_frame_main_get(ad->cur_buf->view);
    643 
    644 	if (!arg->s) {
    645 		set_error("Missing argument.", data);
    646 		return EINA_FALSE;
    647 	}
    648 	/*
    649 	   jsapi_evaluate_script(arg->s, &value, &message);
    650 	   if (message) {
    651 	   set_error(message);
    652 	   g_free(message);
    653 	   return FALSE;
    654 	   }
    655 	   g_free(message);
    656 	   */
    657 	// value = ewk_frame_script_execute(frame, arg->s);
    658 	if (arg->i != Silent && value) {
    659 		a.i = arg->i;
    660 		a.s = strdup(value);
    661 		echo(&a, data);
    662 		free(a.s);
    663 	}
    664 	/* switch mode according to scripts return value */
    665 	if (value) {
    666 		if (strncmp(value, "done;", 5) == 0) {
    667 			a.i = ModeNormal;
    668 			set(&a, data);
    669 		} else if (strncmp(value, "insert;", 7) == 0) {
    670 			a.i = ModeInsert;
    671 			set(&a, data);
    672 			ad->manual_focus = EINA_TRUE;
    673 		} else if (strncmp(value, "save;", 5) == 0) {
    674 			/* forced download */
    675 			a.i = ModeNormal;
    676 			set(&a, data);
    677 			printf("script() js returned save, not implemented.\n");
    678 			// request = webkit_network_request_new((value + 5));
    679 			// download = webkit_download_new(request);
    680 			// webview_download_cb(webview, download, (gpointer *)NULL);
    681 		} else if (strncmp(value, "yank;", 5) == 0) {
    682 			/* yank link URL to clipboard */
    683 			a.i = ModeNormal;
    684 			set(&a, echo);
    685 			printf("script() js returned yank, not implemented.\n");
    686 			// a.i = ClipboardPrimary | ClipboardGTK;
    687 			// a.s = (value + 5);
    688 			// yank(&a);
    689 		} else if (strncmp(value, "colon;", 6) == 0) {
    690 			/* use link URL for colon command */
    691 			// strncpy(text, (char *)gtk_entry_get_text(GTK_ENTRY(inputbox)), 1023);
    692 			strncpy(text, elm_entry_entry_get(ad->url), 1023);
    693 			a.i = ModeNormal;
    694 			set(&a, data);
    695 			switch (text[1]) {
    696 				case 'O':
    697 					// a.s = g_strconcat(":open ", (value + 6), NULL);
    698 					a.s = strdup_printf(":open %s", value + 6);
    699 					break;
    700 				case 'T': case 'W':
    701 					// a.s = g_strconcat(":tabopen ", (value + 6), NULL);
    702 					a.s = strdup_printf(":tabopen %s", value + 6);
    703 					break;
    704 			}
    705 			if (a.s) {
    706 				input(&a, data);
    707 				free(a.s);
    708 			}
    709 		} else if (strncmp(value, "error;", 6) == 0) {
    710 			a.i = Error;
    711 			set(&a, data);
    712 		}
    713 	}
    714 	// free(value);
    715 	eina_stringshare_del(value);
    716 	return EINA_TRUE;
    717 }
    718 
    719 Eina_Bool
    720 scroll(const Arg *arg, void *data)
    721 {
    722 	// GtkAdjustment *adjust = (arg->i & OrientationHoriz) ? adjust_h : adjust_v;
    723 	// int max = gtk_adjustment_get_upper(adjust) - gtk_adjustment_get_page_size(adjust);
    724 	// float val = gtk_adjustment_get_value(adjust) / max * 100;
    725 	
    726 	/*
    727 	int x, y, w, h, page_w, page_h;
    728 	float val;
    729 	Eina_Bool horizontal = EINA_FALSE;
    730 	Window_Data *ad = data;
    731 	Evas_Object *frame = ewk_view_frame_main_get(ad->cur_buf->view);
    732 
    733 	ewk_frame_visible_content_geometry_get(frame, EINA_FALSE, &x, &y, &page_w, &page_h);
    734 	ewk_frame_scroll_pos_get(frame, &x, &y);
    735 	ewk_frame_scroll_size_get(frame, &w, &h);
    736 
    737 	if (arg->i & OrientationHoriz)
    738 		horizontal = EINA_TRUE;
    739 
    740 	val = (float) (horizontal? x : y) / h * 100;
    741 
    742 	int direction = (arg->i & (1 << 2)) ? 1 : -1;
    743 
    744 	if ((direction == 1 && val < 100) || (direction == -1 && val > 0)) {
    745 		if (arg->i & ScrollMove) {
    746 			int total = direction *
    747 					((arg->i & UnitLine || (arg->i & UnitBuffer && ad->count)) ? (scrollstep * (ad->count ? ad->count : 1)) : (
    748 						// arg->i & UnitBuffer ? gtk_adjustment_get_page_size(adjust) / 2 :
    749 						arg->i & UnitBuffer ? (horizontal ? page_w : page_h) / 2 :
    750 						// (count ? count : 1) * (gtk_adjustment_get_page_size(adjust) -
    751 						(ad->count ? ad->count : 1) * ((horizontal ? page_w : page_h) -
    752 							// (gtk_adjustment_get_page_size(adjust) > pagingkeep ? pagingkeep : 0)))));
    753 							((horizontal ? page_w : page_h) > pagingkeep ? pagingkeep : 0))));
    754 
    755 			// gtk_adjustment_set_value(adjust, gtk_adjustment_get_value(adjust) +
    756 			if (horizontal)
    757 				ewk_frame_scroll_set(frame, x + total, y);
    758 			else
    759 				ewk_frame_scroll_set(frame, x, y + total);
    760 
    761 		}
    762 		else {
    763 			// gtk_adjustment_set_value(adjust,
    764 			//		((direction == 1) ?  gtk_adjustment_get_upper : gtk_adjustment_get_lower)(adjust));
    765 			if (horizontal)
    766 				ewk_frame_scroll_set(frame, ((direction == 1) ?  w : 0), y);
    767 			else
    768 				ewk_frame_scroll_set(frame, x, ((direction == 1) ?  h : 0));
    769 		}
    770 		update_state(data);
    771 	}
    772 	*/
    773 	return EINA_TRUE;
    774 }
    775 
    776 Eina_Bool
    777 zoom(const Arg *arg, void *data)
    778 {
    779 	Evas_Coord ox, oy, mx, my, cx, cy;
    780 	int diff = 0;
    781 	Eina_Bool result;
    782 	Window_Data *wd = data;
    783 	Buffer_Data *bd = wd->cur_buf;
    784 	unsigned int level = bd->zoom_level;
    785 
    786 	/* Get current mouse position on window. */
    787 	evas_pointer_canvas_xy_get(evas_object_evas_get(bd->view), &mx, &my);
    788 
    789 	/* Get webview's position on window. */
    790 	evas_object_geometry_get(bd->view, &ox, &oy, NULL, NULL);
    791 
    792 	cx = mx - ox; // current x position = mouse x position - webview x position
    793 	cy = my - oy; // current y position = mouse y position - webview y position
    794 
    795 	if (arg->i == ZoomReset) {
    796 		bd->zoom_level = DEFAULT_ZOOM_LEVEL;
    797 	}
    798 	else {
    799 		diff = (arg->i == ZoomIn) ? 1 : -1;
    800 		printf("zoom() diff = %i\n", diff);
    801 		diff *= (wd->count == 0) ? 1 : wd->count;
    802 
    803 		if (level+diff < 0  || level+diff >= sizeof(zoom_levels) / sizeof(float))
    804 			return EINA_FALSE;
    805 
    806 		bd->zoom_level = level + diff;
    807 	}
    808 
    809 	result = ewk_view_scale_set(bd->view, zoom_levels[bd->zoom_level], cx, cy);
    810 	gui_zoom_update(wd, zoom_levels[bd->zoom_level]);
    811 
    812 	return result;
    813 }
    814 
    815 Eina_Bool
    816 bookmark(const Arg *arg, void *data)
    817 {
    818 	return EINA_FALSE;
    819 }
    820 
    821 Eina_Bool
    822 view_source(const Arg * arg, void *data)
    823 {
    824 	printf("view_source() source mode not implemented yet.\n");
    825 	/*
    826 	gboolean current_mode = webkit_web_view_get_view_source_mode(webview);
    827 	webkit_web_view_set_view_source_mode(webview, !current_mode);
    828 	webkit_web_view_reload(webview);
    829 	*/
    830 	return EINA_TRUE;
    831 }
    832 
    833 Eina_Bool
    834 focus_input(const Arg *arg, void *data)
    835 {
    836 	static Arg a;
    837 	Window_Data *wd = data;
    838 
    839 	a.s = strdup("hints.focusInput();");
    840 	a.i = Silent;
    841 	script(&a, data);
    842 	free(a.s);
    843 	gui_scroll_update(wd);
    844 	wd->manual_focus = EINA_TRUE;
    845 
    846 	return EINA_TRUE;
    847 }
    848 
    849 Eina_Bool
    850 list(const Arg *arg, void *data) 
    851 {
    852 	Window_Data *ad = data;
    853 	Eina_List *l;
    854 	Buffer_Data *td;
    855 	Evas_Object *row, *label;
    856 
    857 	elm_box_clear(ad->event_box);
    858 
    859 	EINA_LIST_FOREACH(ad->buffer_list, l, td) {
    860 
    861 		row = elm_box_add(ad->win);
    862 		elm_box_horizontal_set(row, EINA_TRUE);
    863 		evas_object_size_hint_align_set(row, EVAS_HINT_FILL, EVAS_HINT_FILL);
    864 		elm_box_pack_end(ad->event_box, row);
    865 		evas_object_show(row);
    866 
    867 		label = elm_label_add(ad->win);
    868 		make_buffer_number(label, td);
    869 		elm_box_pack_end(row, label);
    870 
    871 		label = elm_box_add(ad->win);
    872 		make_favicon(label, td);
    873 		elm_box_pack_end(row, label);
    874 		evas_object_show(label);
    875 
    876 		label = elm_label_add(ad->win);
    877 		make_url(label, td);
    878 		elm_box_pack_end(row, label);
    879 
    880 		label = elm_label_add(ad->win);
    881 		make_bf_list(label, td);
    882 		elm_box_pack_end(row, label);
    883 		evas_object_show(label);
    884 
    885 		label = elm_label_add(ad->win);
    886 		evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    887 		evas_object_size_hint_align_set(label, 1.0, EVAS_HINT_FILL);
    888 		elm_box_pack_end(row, label);
    889 		elm_object_text_set(label, ewk_view_title_get(td->view));
    890 		evas_object_show(label);
    891 
    892 	}
    893 
    894 	evas_object_show(ad->event_box);
    895 	return EINA_TRUE;
    896 }
    897 
    898 Eina_Bool
    899 switch_buffer(const Arg *arg, void *data)
    900 {
    901 	Window_Data *ad = data;
    902 	Eina_List *l;
    903 	Buffer_Data *td;
    904 	// int arg_count = atoi(arg->s);
    905 
    906 
    907 	EINA_LIST_FOREACH(ad->buffer_list, l, td) {
    908 		/*
    909 		if (arg_count == td->buf_number) {
    910 			window_main_buffer_set(td);
    911 			return EINA_TRUE;
    912 		}
    913 		*/
    914 		if (ad->count == td->buf_number) {
    915 			window_main_buffer_set(td);
    916 			return EINA_TRUE;
    917 		}
    918 	}
    919 
    920 	return EINA_FALSE;
    921 }
    922 
    923 Eina_Bool
    924 inspector(const Arg *arg, void *data)
    925 {
    926 	Window_Data *ad = data;
    927 	Buffer_Data *bd = ad->cur_buf;
    928 
    929 	if (!bd->inspector_enabled) {
    930 		ewk_view_inspector_show(bd->view);
    931 		bd->inspector_enabled = EINA_TRUE;
    932 	}
    933 	else {
    934 		ewk_view_inspector_close(bd->view);
    935 		bd->inspector_enabled = EINA_FALSE;
    936 	}
    937 
    938 	return EINA_TRUE;
    939 }
    940