1 // Copyright 2014 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #define _DEFAULT_SOURCE
10 #include <Ecore_Evas.h>
11 #include <Ecore_File.h>
12 #include <Ecore_Getopt.h>
13 #include "ecore_x_wayland_wrapper.h"
15 #include <Elementary.h>
16 #include <glib/gprintf.h>
18 #include <Ecore_IMF_Evas.h>
24 #include <tizen_version.h>
27 #include <device/haptic.h>
30 #include "browser-string.h"
31 #include "browser-object.h"
32 #include "public/EWebKit.h"
33 #include "public/EWebKit_internal.h"
35 #include "tizen/system_info.h"
38 #include <efl_extension.h>
42 #define LOG_TAG "CHROMIUMEFL"
43 #define TOOL_BOX_HEIGHT 150
44 #define URL_BOX_HEIGHT 75
47 #define IMF_START_POINT_Y 635
51 static haptic_device_h s_haptic_handle; // haptic handle.
52 static Ecore_Timer* s_haptic_timer_id; // Timer ID.
53 static haptic_effect_h s_haptic_effect; // haptic_effect struct.
56 static const char default_start_url[] = "http://www.google.com/";
57 static char* start_url = NULL;
58 static int is_imf_shown = 0;
59 //Added for SIP status
60 static int im_context_status = 0;
62 static Evas_Object * curr_focus = NULL;
64 // We are just following Tizen platform application pattern.
65 // It will be required to pass data across lifecycle callbacks.
70 /*let's explain those Evas_Object's hierarchy:
85 Evas_Object *main_window;
87 Evas_Object* webview; //an ewk_view which's app demo is
89 Evas_Object *tool_box; //box containig url_box and button_box
91 Evas_Object *url_box; //box containing only url_entry
92 Evas_Object *url_entry;
94 Evas_Object *button_box; //box containing navigation buttons
97 Evas_Object *refreshbtn;
100 Evas_Object *tracestartbtn;
101 Evas_Object *tracestopbtn;
103 Evas_Object *findbtn;
104 Evas_Object *clearbtn;
105 Evas_Object *zoominbtn;
106 Evas_Object *zoomoutbtn;
108 Evas_Object *bg_tool_box; //background under the toolbox
110 Evas_Object *progress_bar;
112 Evas_Object *popup; // popup window
113 Eina_Stringshare *popup_url;
114 Ewk_Geolocation_Permission_Request* geolRequest;
115 Ewk_User_Media_Permission_Request* userMediaRequest;
116 Ewk_Context* context;
119 // Added to Support customized context menu
120 typedef enum _context_menu_type {
131 typedef enum _custom_context_menu_item_tag {
132 CUSTOM_CONTEXT_MENU_ITEM_BASE_TAG = EWK_CONTEXT_MENU_ITEM_BASE_APPLICATION_TAG,
133 CUSTOM_CONTEXT_MENU_ITEM_FIND_ON_PAGE,
134 CUSTOM_CONTEXT_MENU_ITEM_SHARE,
135 CUSTOM_CONTEXT_MENU_ITEM_SEARCH,
136 CUSTOM_CONTEXT_MENU_ITEM_SAVE_TO_KEEPIT,
137 CUSTOM_CONTEXT_MENU_ITEM_CALL,
138 CUSTOM_CONTEXT_MENU_ITEM_SEND_MESSAGE,
139 CUSTOM_CONTEXT_MENU_ITEM_SEND_EMAIL,
140 CUSTOM_CONTEXT_MENU_ITEM_SEND_ADD_TO_CONTACT,
141 } custom_context_menu_item_tag;
143 static void mini_find_word(const char *word, Eina_Bool forward, Evas_Smart_Cb found_cb, void *data);
144 static void find_hit_cb(void *data, Evas_Object *obj, void *event_info);
145 static void clear_hit_cb(void *data, Evas_Object *obj, void *event_info);
146 static void __text_found_cb(void *data, Evas_Object *obj, void *event_info);
147 static void mini_find_word_clear(void *data);
148 static void zoomin_hit_cb(void *data, Evas_Object *obj, void *event_info);
149 static void zoomout_hit_cb(void *data, Evas_Object *obj, void *event_info);
150 static double scale_factor = 1.0;
152 static void __load_started_cb (void *data, Evas_Object *obj, void *event_info);
153 static void __load_finished_cb (void *data, Evas_Object *obj, void *event_info);
154 static void __load_progress_finished_cb(void *data, Evas_Object *obj, void *event_info);
155 static void __load_error_cb (void *data, Evas_Object *obj, void *event_info);
156 static void __uri_changed_cb (void *data, Evas_Object *obj, void *event_info);
157 static void __title_changed_cb (void *data, Evas_Object *obj, void *event_info);
158 static void __load_progress_cb (void *data, Evas_Object *obj, void *event_info);
160 #if defined(OS_TIZEN)
161 static void _url_clicked_cb (void *data, Evas_Object *obj, void *event_info);
162 static void _webview_mouse_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
165 static void __policy_newwindow_decide_cb (void *data, Evas_Object *obj, void *event_info);
166 static void __navigation_policy_decide_cb(void *data, Evas_Object *obj, void *event_info);
167 static void __policy_response_decide_cb(void *data, Evas_Object *obj, void *event_info);
168 static void __geolocation_permission_request_cb(void *data, Evas_Object *obj, void *event_info);
169 static void __usermedia_permission_request_cb(void *data, Evas_Object *obj, void *event_info);
170 //Added for load previous page, when keyboard backspace key is pressed
171 static void webview_key_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
172 static void __im_context_open_cb (void *data, Evas_Object *obj, void *event_info);
173 static void __im_context_close_cb (void *data, Evas_Object *obj, void *event_info);
174 static Evas_Object* _create_view (Evas_Object *parent, app_data *data);
175 static Evas_Object* _create_button_bar(Evas_Object *parent, app_data *data);
176 static Evas_Object* _create_url_bar (Evas_Object *parent, int width, const char *start_url , app_data *data);
177 static Evas_Object* _create_tool_bar (Evas_Object *parent, const char *start_url , app_data *data);
179 static void __popup_close(app_data *data);
180 static void __popup_open_url_cb(void *data, Evas_Object *obj, void *event_info);
181 static void __popup_cancel_url_cb(void *data, Evas_Object *obj, void *event_info);
183 static void url_hit_cb(void *data, Evas_Object *obj, void *event_info);
184 static void _imf_panel_state_cb (void *data, Ecore_IMF_Context *ctx, int value);
185 #if defined(OS_TIZEN)
186 static void _imf_panel_changed_cb(void *data, Evas_Object *obj, Eina_Rectangle *rect);
189 static void _geol_cancel_cb (void *data, Evas_Object *obj, void *ev);
190 static void _geol_ok_cb (void *data, Evas_Object *obj, void *ev);
191 static void _back_btn_cb (void *data, Evas_Object *btn, void *ev);
192 static void _next_btn_cb (void *data, Evas_Object *btn, void *ev);
193 static void _reload_btn_cb (void *data, Evas_Object *btn, void *ev);
194 static void _stop_btn_cb (void *data, Evas_Object *btn, void *ev);
195 static void _trace_start_btn_cb (void *data, Evas_Object *btn, void *ev);
196 static void _trace_stop_btn_cb (void *data, Evas_Object *btn, void *ev);
198 static void hide_imf_panel(app_data * data);
200 static void _back_hard_key_cb(void *data, Evas_Object *btn, void *ev);
201 static void _on_keyup_cb(void *data, Evas *e, Evas_Object *btn, void *event_info);
202 static void _screenshot_captured_cb(Evas_Object* image, void* user_data);
205 // Added to Support cusomized context menu
206 static void __customize_context_menu_cb(void *data, Evas_Object *obj, void *event_info);
207 static void __customize_context_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
209 // To Support customized context menu
210 static void enable_customize_contextmenu(app_data *data, Eina_Bool enable);
211 static void show_context_menu_text_only(app_data *data, Ewk_Context_Menu *menu);
212 static void show_context_menu_text_link(app_data *data, Ewk_Context_Menu *menu);
213 static void show_context_menu_image_link(app_data *data, Ewk_Context_Menu *menu);
214 static void show_context_menu_call_number(app_data *data, Ewk_Context_Menu *menu);
215 static void show_context_menu_email_address(app_data *data, Ewk_Context_Menu *menu);
216 static void show_context_menu_image_only(app_data *data, Ewk_Context_Menu *menu);
217 context_menu_type get_menu_type(app_data *data, Ewk_Context_Menu *menu);
219 // Added to Support Javascript popup
220 static Eina_Bool __javascript_alert_cb(Evas_Object* o, const char* alert_text, void* user_data);
221 static Eina_Bool __javascript_confirm_cb(Evas_Object* o, const char* message, void* user_data);
222 static Eina_Bool __javascript_prompt_cb(Evas_Object* o, const char* message, const char* default_value, void* user_data);
224 #if defined(OS_TIZEN)
225 static Eina_Bool __vibration_timeout_cb(void *data);
226 static void __vibration_on_cb(uint64_t vibration_time, void *data);
227 static void __vibration_off_cb(void *data);
230 static void get_main_window_size(int *changed_ang, int *width, int *height);
232 #if defined(OS_TIZEN)
233 // To avoid implicit function declaration
234 int setenv(const char *name, const char *value, int overwrite);
239 FOR_TEST_APPLICATION_CACHE_RUN = EWK_CONTEXT_MENU_ITEM_BASE_APPLICATION_TAG + 1,
240 FOR_TEST_APPLICATION_CACHE_DELETE_ALL,
241 FOR_TEST_APPLICATION_BACK_FORWAD_CLEAR,
242 // New context menu items can be added here
245 static const Ecore_Getopt options =
247 .prog = "mini_browser",
248 .usage = "%prog [options] [url]",
252 ECORE_GETOPT_STORE_DEF_STR('u', "url", "go to url", default_start_url),
253 ECORE_GETOPT_SENTINEL,
257 static Eina_Strbuf* create_url_with_scheme(const char* base_url, const char* scheme)
259 Eina_Strbuf* buffer = eina_strbuf_new();
260 eina_strbuf_append(buffer, scheme);
261 eina_strbuf_append(buffer, base_url);
265 static void set_url_from_user_input(Evas_Object* webview, const char* url)
267 if (strstr(url, "://"))
269 ewk_view_url_set(webview, url);
274 Eina_Strbuf* full_url;
275 if (ecore_file_exists(url))
277 char* realpath = ecore_file_realpath(url);
278 full_url = create_url_with_scheme(realpath, "file://");
283 full_url = create_url_with_scheme(url, "http://");
286 ewk_view_url_set(webview, eina_strbuf_string_get(full_url));
288 eina_strbuf_free(full_url);
291 #if defined(OS_TIZEN_TV_PRODUCT)
292 static void _create_mouse_cursor(Evas_Object* window) {
293 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
294 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
295 struct wl_display* display = ecore_wl2_display_get(wl2_display);
296 Eina_Iterator* globals = ecore_wl2_display_globals_get(wl2_display);
297 struct wl_registry* registry = ecore_wl2_display_registry_get(wl2_display);
298 struct wl_seat* seat =
299 ecore_wl2_input_seat_get(ecore_wl2_input_default_input_get(wl2_display));
301 Ecore_Wl2_Global* global;
302 EINA_ITERATOR_FOREACH(globals, global) {
303 if (!strcmp(global->interface, "tizen_cursor"))
304 if (!CursorModule_Initialize(display, registry, seat, global->id))
305 LOGE("CursorModule_Initialize() Failed!\n");
307 eina_iterator_free(globals);
309 struct wl_surface* const surface =
310 ecore_wl2_window_surface_get(ecore_evas_wayland2_window_get(
311 ecore_evas_ecore_evas_get(evas_object_evas_get(window))));
314 if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL))
315 LOGE("Cursor_Set_Config() Failed!\n");
316 CursorModule_Finalize();
318 const char* t_cursor = "tizen_cursor";
319 unsigned int cursormgr_id = 0;
320 Ecore_Wl_Global* global_data = NULL;
322 EINA_INLIST_FOREACH(ecore_wl_globals_get(), global_data) {
323 if (0 == strncmp(global_data->interface, t_cursor, strlen(t_cursor))) {
324 cursormgr_id = global_data->id; // to get the id of cursormgr object
329 struct wl_surface* const surface =
330 ecore_wl_window_surface_get(elm_win_wl_window_get(window));
333 const int ret_cursormod = CursorModule_Initialize(
334 ecore_wl_display_get(), ecore_wl_registry_get(),
335 ecore_wl_input_seat_get(ecore_wl_input_get()), cursormgr_id);
337 Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL);
339 CursorModule_Finalize();
344 static Evas_Object* _create_main_window(void *data)
346 Evas_Object *window = elm_win_add(NULL, "ChromiumEfl", ELM_WIN_BASIC);
348 int width = 0, height = 0;
349 elm_win_title_set(window, "ChromiumEfl");
350 evas_object_size_hint_weight_set(window, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
351 evas_object_size_hint_align_set(window, EVAS_HINT_FILL, EVAS_HINT_FILL);
352 elm_win_borderless_set(window, EINA_TRUE);
353 elm_win_conformant_set(window, EINA_TRUE);
354 #if defined(USE_WAYLAND)
355 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
356 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
357 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
359 ecore_wl_screen_size_get(&width, &height);
360 #endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
362 ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
364 evas_object_resize(window, width, height);
365 elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW);
367 /* add a standard bg */
368 Evas_Object *bg = elm_bg_add(window);
369 /* not allow bg to expand. let's limit dialog size to contents */
370 evas_object_size_hint_weight_set(bg, 1.0, 1.0);
371 /* add object as a resize object for the window (controls window minimum
372 * size as well as gets resized if window is resized) */
373 elm_win_resize_object_add(window, bg);
374 elm_bg_color_set(bg, 225, 225, 225);
375 evas_object_show(bg);
380 Evas_Object* _create_view(Evas_Object *parent, app_data *data)
382 if (start_url == NULL)
384 start_url = (char*)default_start_url;
388 evas_object_geometry_get(parent, NULL, NULL, &width, &height);
390 Evas_Object *webview = ewk_view_add_with_context(evas_object_evas_get(parent), data->context);
391 evas_object_resize(webview, width, height - TOOL_BOX_HEIGHT);
393 evas_object_show(webview);
394 evas_object_focus_set(webview, EINA_TRUE);
396 data->webview = webview;
398 evas_object_smart_callback_add(webview, "load,finished" , __load_finished_cb , data);
399 evas_object_smart_callback_add(webview, "load,error" , __load_error_cb , data);
400 evas_object_smart_callback_add(webview, "url,changed" , __uri_changed_cb , data);
401 evas_object_smart_callback_add(webview, "title,changed" , __title_changed_cb , data);
402 evas_object_smart_callback_add(webview, "load,progress" , __load_progress_cb , data);
403 evas_object_smart_callback_add(webview, "load,progress,finished", __load_progress_finished_cb, data);
404 evas_object_smart_callback_add(webview, "load,started" , __load_started_cb , data);
405 evas_object_smart_callback_add(webview, "policy,newwindow,decide", __policy_newwindow_decide_cb, data);
407 evas_object_event_callback_add(webview, EVAS_CALLBACK_MOUSE_DOWN, _webview_mouse_down_cb , data);
409 evas_object_smart_callback_add(webview, "policy,response,decide", __policy_response_decide_cb, data);
410 evas_object_smart_callback_add(webview, "policy,navigation,decide", __navigation_policy_decide_cb, data);
411 evas_object_smart_callback_add(webview, "geolocation,permission,request", __geolocation_permission_request_cb, data);
412 evas_object_smart_callback_add(webview, "usermedia,permission,request", __usermedia_permission_request_cb, data);
413 // Added to Support Javascript popup
414 ewk_view_javascript_alert_callback_set(webview, __javascript_alert_cb, data);
415 ewk_view_javascript_confirm_callback_set(webview, __javascript_confirm_cb, data);
416 ewk_view_javascript_prompt_callback_set(webview, __javascript_prompt_cb, data);
418 if (IsMobileProfile() || IsWearableProfile()) {
419 printf("[%s][%d][%s] calling ewk_context_vibration_client_callbacks_set...\n", __FUNCTION__, __LINE__, "vibration");
420 ewk_context_vibration_client_callbacks_set((Ewk_Context*) webview, __vibration_on_cb, __vibration_off_cb, NULL);
423 //Added to support keyboard backspace key
424 evas_object_smart_callback_add(webview, "editorclient,ime,opened", __im_context_open_cb , data);
425 evas_object_smart_callback_add(webview, "editorclient,ime,closed", __im_context_close_cb , data);
426 evas_object_event_callback_add(webview, EVAS_CALLBACK_KEY_DOWN, webview_key_down_cb , data);
428 // To Enable customized context menu
429 enable_customize_contextmenu(data, EINA_TRUE);
431 if (IsMobileProfile() || IsWearableProfile()) {
432 evas_object_smart_callback_add(webview, "inputmethod,changed", (Evas_Smart_Cb) _imf_panel_changed_cb, data);
438 #if defined(OS_TIZEN)
439 // To bring back toolbar to original position when SID_DONE/SID_CANCEL is pressed
440 static void _SIP_close_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
443 Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
444 app_data *ad = (app_data*) data;
445 if (!strcmp(ev->key, "Select"))
447 const char* url = elm_entry_entry_get( ad->url_entry );
448 set_url_from_user_input(ad->webview, url);
450 evas_object_focus_set(ad->webview, EINA_TRUE);
452 if (!strcmp(ev->key, "Cancel"))
459 /* On Mouse Event over webview should bring back
460 * Tool bar to its original position
462 void _webview_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
465 app_data *ad = (app_data*) data;
471 //Added to load previous page, when keyboard backspace key is pressed
472 void webview_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
474 app_data *ad = (app_data*) data;
475 Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
477 if (strcmp(ev->key, "XF86Stop") == 0)
479 if (ewk_view_text_selection_clear(ad->webview))
482 if ( (!strcmp(ev->key, "BackSpace") || !strcmp(ev->key, "XF86Stop")) && (!im_context_status) )
484 ewk_view_back(ad->webview);
488 Evas_Object* _create_button_bar(Evas_Object *parent , app_data *data)
491 data->button_box = elm_box_add(parent);
492 elm_box_horizontal_set(data->button_box, EINA_TRUE);
493 elm_box_padding_set(data->button_box,2,2);
495 data->backbtn=elm_button_add(data->button_box);
496 elm_box_pack_end(data->button_box, data->backbtn);
497 evas_object_smart_callback_add(data->backbtn, "clicked", _back_btn_cb, data);
499 ic=elm_icon_add(parent);
500 elm_icon_standard_set(ic, "arrow_left");
501 elm_object_part_content_set(data->backbtn, "icon", ic);
502 evas_object_show(data->backbtn);
504 data->nextbtn=elm_button_add(data->button_box);
505 elm_box_pack_end(data->button_box, data->nextbtn);
506 evas_object_smart_callback_add(data->nextbtn, "clicked", _next_btn_cb, data);
508 ic=elm_icon_add(parent);
509 elm_icon_standard_set(ic, "arrow_right");
510 elm_object_part_content_set(data->nextbtn, "icon", ic);
511 evas_object_show(data->nextbtn);
513 data->refreshbtn=elm_button_add(data->button_box);
514 elm_box_pack_end(data->button_box, data->refreshbtn);
516 ic=elm_icon_add(parent);
517 elm_icon_standard_set(ic, "refresh");
518 elm_object_part_content_set(data->refreshbtn, "icon", ic);
519 evas_object_show(data->refreshbtn);
520 evas_object_smart_callback_add(data->refreshbtn, "clicked", _reload_btn_cb, data);
522 data->stopbtn=elm_button_add(data->button_box);
523 elm_box_pack_end(data->button_box, data->stopbtn);
525 ic=elm_icon_add(parent);
526 elm_icon_standard_set(ic, "close");
527 elm_object_part_content_set(data->stopbtn, "icon", ic);
528 evas_object_show(data->stopbtn);
529 evas_object_smart_callback_add(data->stopbtn, "clicked", _stop_btn_cb, data);
531 data->gobtn=elm_button_add(data->button_box);
532 elm_object_text_set(data->gobtn, "GO");
533 elm_box_pack_end(data->button_box,data->gobtn);
534 evas_object_show(data->gobtn);
535 evas_object_smart_callback_add(data->gobtn, "clicked", url_hit_cb, data);
538 data->tracestartbtn=elm_button_add(data->button_box);
539 elm_object_text_set(data->tracestartbtn, "T-Start");
540 elm_box_pack_end(data->button_box, data->tracestartbtn);
541 evas_object_show(data->tracestartbtn);
542 evas_object_smart_callback_add(data->tracestartbtn, "clicked",
543 _trace_start_btn_cb, data);
545 data->tracestopbtn=elm_button_add(data->button_box);
546 elm_object_text_set(data->tracestopbtn, "T-Stop");
547 elm_box_pack_end(data->button_box, data->tracestopbtn);
548 evas_object_show(data->tracestopbtn);
549 evas_object_smart_callback_add(data->tracestopbtn, "clicked",
550 _trace_stop_btn_cb, data);
553 data->findbtn=elm_button_add(data->button_box);
554 elm_object_text_set(data->findbtn, "FD");
555 elm_box_pack_end(data->button_box,data->findbtn);
556 evas_object_show(data->findbtn);
557 evas_object_smart_callback_add(data->findbtn, "clicked", find_hit_cb, data);
559 data->clearbtn=elm_button_add(data->button_box);
560 elm_object_text_set(data->clearbtn, "CL");
561 elm_box_pack_end(data->button_box,data->clearbtn);
562 evas_object_show(data->clearbtn);
563 evas_object_smart_callback_add(data->clearbtn, "clicked", clear_hit_cb, data);
565 data->zoomoutbtn=elm_button_add(data->button_box);
566 elm_object_text_set(data->zoomoutbtn, " - ");
567 elm_box_pack_end(data->button_box,data->zoomoutbtn);
568 evas_object_show(data->zoomoutbtn);
569 evas_object_smart_callback_add(data->zoomoutbtn, "clicked", zoomout_hit_cb, data);
571 data->zoominbtn=elm_button_add(data->button_box);
572 elm_object_text_set(data->zoominbtn, " + ");
573 elm_box_pack_end(data->button_box,data->zoominbtn);
574 evas_object_show(data->zoominbtn);
575 evas_object_smart_callback_add(data->zoominbtn, "clicked", zoomin_hit_cb, data);
577 return data->button_box;
580 Evas_Object* _create_url_bar(Evas_Object *parent, int width, const char *start_url, app_data *data )
582 data->url_box = elm_box_add(parent);
583 elm_box_horizontal_set(data->url_box, EINA_TRUE);
584 evas_object_size_hint_weight_set(data->url_box, EVAS_HINT_EXPAND, 0.0);
585 evas_object_size_hint_align_set(data->url_box, EVAS_HINT_FILL, EVAS_HINT_FILL);
586 evas_object_resize(data->url_box, width, URL_BOX_HEIGHT);
587 evas_object_show(data->url_box);
589 data->url_entry = elm_entry_add(data->url_box);
590 elm_entry_single_line_set(data->url_entry, EINA_TRUE);
591 elm_entry_scrollable_set(data->url_entry, EINA_TRUE);
592 evas_object_size_hint_weight_set(data->url_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
593 evas_object_size_hint_align_set(data->url_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
594 elm_entry_text_style_user_push(data->url_entry,
595 "DEFAULT='font=Sans font_size=35 color=#000000 ' hilight=' + font_weight=Bold'");
596 elm_object_text_set(data->url_entry, start_url);
597 elm_entry_input_panel_layout_set(data->url_entry, ELM_INPUT_PANEL_LAYOUT_URL);
598 elm_entry_autocapital_type_set (data->url_entry, ELM_AUTOCAPITAL_TYPE_NONE );
599 elm_entry_editable_set(data->url_entry, EINA_TRUE);
600 evas_object_color_set(data->url_entry, 255, 255, 255, 255);
601 elm_box_padding_set(data->url_box, 5,5);
602 elm_box_pack_end(data->url_box, data->url_entry);
603 evas_object_show(data->url_entry);
604 evas_object_smart_callback_add(data->url_entry, "activated", url_hit_cb, data);
605 #if defined(OS_TIZEN)
607 evas_object_event_callback_add(data->url_entry, EVAS_CALLBACK_KEY_DOWN, _SIP_close_cb, data);
608 evas_object_smart_callback_add(data->url_entry, "clicked", _url_clicked_cb, data);
611 elm_entry_prediction_allow_set(data->url_entry, EINA_FALSE);
613 eext_object_event_callback_add(data->url_entry, EEXT_CALLBACK_BACK, _back_hard_key_cb, data);
616 Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(data->url_entry);
618 ecore_imf_context_prediction_allow_set(imf_context, EINA_FALSE);
619 ecore_imf_context_input_panel_event_callback_add (
620 imf_context, ECORE_IMF_INPUT_PANEL_STATE_SHOW, _imf_panel_state_cb, data);
621 ecore_imf_context_input_panel_event_callback_add (
622 imf_context, ECORE_IMF_INPUT_PANEL_STATE_HIDE, _imf_panel_state_cb, data);
624 evas_object_show(data->url_entry);
626 return data->url_box;
629 Evas_Object* _create_tool_bar(Evas_Object *parent, const char *start_url, app_data *data)
631 //these pointers are local. data _create_url_bar and _create_button_bar
632 //puts pointers to the right field in app_data structure
633 Evas_Object *button_box, *url_box;
636 evas_object_geometry_get (parent, NULL, NULL, &width, &height);
638 /* add a standard bg */
639 data->bg_tool_box = evas_object_rectangle_add( evas_object_evas_get(parent) );
640 //Here we set the rectangles red, green, blue and opacity levels
641 evas_object_color_set(data->bg_tool_box, 225, 225, 225, 255); // opaque white background
642 evas_object_resize(data->bg_tool_box, width, TOOL_BOX_HEIGHT); // covers full canvas
644 data->tool_box = elm_box_add(parent);
645 evas_object_move(data->tool_box, 0, height - TOOL_BOX_HEIGHT);
646 evas_object_resize(data->tool_box, width, TOOL_BOX_HEIGHT);
647 evas_object_show(data->tool_box);
649 url_box = _create_url_bar(data->tool_box, width, start_url, data);
650 button_box = _create_button_bar(data->tool_box, data);
652 elm_box_pack_end(data->tool_box,url_box);
653 evas_object_propagate_events_set(data->tool_box, EINA_FALSE);
654 evas_object_size_hint_align_set(button_box, 0.0, 0.0);
655 elm_box_pack_end(data->tool_box,button_box);
656 evas_object_show(button_box);
657 evas_object_show(url_box);
659 Elm_Theme *theme = elm_theme_new();
660 elm_theme_set(theme, "tizen-HD-light");
661 elm_object_theme_set(data->tool_box, theme);
662 evas_object_show(data->tool_box);
664 return data->tool_box;
667 static void __br_rotate_cb(void *data, Evas_Object *obj, void *event)
672 app_data *ad = (app_data *)data;
673 int changed_ang = elm_win_rotation_get(ad->main_window);
674 int main_window_width = 0, main_window_height = 0;
675 get_main_window_size(&changed_ang, &main_window_width, &main_window_height);
677 // ewk_view_orientation_send expects angles: 0, 90, -90, 180.
678 if (changed_ang == 270)
680 ewk_view_orientation_send(ad->webview, changed_ang);
682 evas_object_resize(ad->webview, main_window_width, main_window_height - TOOL_BOX_HEIGHT);
683 evas_object_resize(ad->tool_box, main_window_width, TOOL_BOX_HEIGHT);
684 evas_object_move(ad->tool_box, 0, main_window_height - TOOL_BOX_HEIGHT);
687 static void _register_rotate_callback(Evas_Object *main_window, void *user_data)
689 if (elm_win_wm_rotation_supported_get(main_window)) {
690 const int rots[] = { APP_DEVICE_ORIENTATION_0, APP_DEVICE_ORIENTATION_90, APP_DEVICE_ORIENTATION_270 };
691 elm_win_wm_rotation_available_rotations_set(main_window, rots, (sizeof(rots) / sizeof(int)));
693 evas_object_smart_callback_add(main_window, "wm,rotation,changed", __br_rotate_cb, user_data);
696 #if defined(OS_TIZEN)
697 static void _on_focus_in_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
699 if (IsMobileProfile() || IsWearableProfile()) {
700 app_data *ad = (app_data *) data;
701 set_url_from_user_input(ad->webview, start_url);
702 evas_object_event_callback_del(ad->main_window, EVAS_CALLBACK_FOCUS_IN, _on_focus_in_cb);
707 static bool __br_app_create(void *data)
709 setenv("ELM_ENGINE", "gl", 1);
712 LOGE("elm_init Failed. App not started");
716 app_data *ad = (app_data *) data;
718 ad->context = ewk_context_default_get();
720 ad->main_window = _create_main_window(ad);
722 // All ewk things go here
723 ad->e = evas_object_evas_get (ad->main_window);
725 // Create view and tool bar
726 _create_view(ad->main_window, ad);
728 _create_tool_bar(ad->main_window, start_url, ad);
731 ad->progress_bar = evas_object_rectangle_add(ad->e);
732 evas_object_color_set(ad->progress_bar, 87, 44, 230, 200);
733 evas_object_resize(ad->progress_bar, 0, 4);
734 evas_object_show(ad->progress_bar);
736 evas_object_show(ad->main_window);
738 #if defined(OS_TIZEN)
739 evas_object_event_callback_add(ad->webview, EVAS_CALLBACK_KEY_UP, _on_keyup_cb , ad);
742 if (IsMobileProfile() || IsWearableProfile()) {
743 evas_object_event_callback_add(ad->main_window, EVAS_CALLBACK_FOCUS_IN, _on_focus_in_cb, ad);
745 set_url_from_user_input(ad->webview, start_url);
747 _register_rotate_callback(ad->main_window, ad);
750 static void __br_app_terminate(void* data)
754 hide_imf_panel(data);
758 static void __br_app_pause(void* data)
762 static void __br_app_resume(void* data)
766 int main(int argc, char** argv)
768 LOGD(" Minibrowser main\n");
770 if (setenv("ELM_ENGINE","gl",1)==0)
771 LOGD("'ELM_ENGINE' has been set to 'gl' value.\n");
773 //FIXME: this is temporal code.
774 ewk_set_arguments(argc, argv);
775 elm_init(argc, argv);
776 elm_config_accel_preference_set("opengl");
778 Ecore_Getopt_Value values[] =
780 ECORE_GETOPT_VALUE_STR(start_url),
781 ECORE_GETOPT_VALUE_NONE,
784 printf("MINIB.C main \n");
786 if (IsDesktopProfile()) {
787 printf("Runtime Profile : DESKTOP(%d)\n", IsDesktopProfile());
788 } else if (IsMobileProfile()) {
789 printf("Runtime Profile : MOBILE(%d)\n", IsMobileProfile());
790 } else if (IsTvProfile()) {
791 printf("Runtime Profile : TV(%d)\n", IsTvProfile());
792 } else if (IsWearableProfile()) {
793 printf("Runtime Profile : WEARABLE(%d)\n", IsWearableProfile());
794 } else if (IsIviProfile()) {
795 printf("Runtime Profile : IVI(%d)\n", IsIviProfile());
796 } else if (IsCommonProfile()) {
797 printf("Runtime Profile : COMMON(%d)\n", IsCommonProfile());
799 printf("Runtime Profile : UNKNOWN\n");
802 if (IsEmulatorArch()) {
803 printf("Runtime Architecture : Emulator(%d)\n", IsEmulatorArch());
806 if (ecore_getopt_parse(&options, values, argc, argv) < 0)
808 LOGE("ERROR: could not parse options.\n");
812 ui_app_lifecycle_callback_s ops;
814 memset(&ops, 0x00, sizeof(ops));
815 ops.create = __br_app_create;
816 ops.terminate = __br_app_terminate;
817 ops.pause = __br_app_pause;
818 ops.resume = __br_app_resume;
821 memset(&ad, 0x00, sizeof(app_data));
823 int ret = ui_app_main(argc, argv, &ops, &ad);
828 void get_main_window_size(int *changed_ang, int *width, int *height)
830 #if defined(USE_WAYLAND)
831 // Screen orientation is already considered in ecore_wl*_display_screen_size_get function.
832 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
833 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
834 ecore_wl2_display_screen_size_get(wl2_display, width, height);
836 ecore_wl_screen_size_get(width, height);
837 #endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
839 switch (*changed_ang) {
840 case APP_DEVICE_ORIENTATION_0:
841 ecore_x_window_size_get(ecore_x_window_root_first_get(), width, height);
843 case APP_DEVICE_ORIENTATION_90:
844 case APP_DEVICE_ORIENTATION_270:
845 ecore_x_window_size_get(ecore_x_window_root_first_get(), height, width);
853 void __load_started_cb(void *data, Evas_Object *obj, void *event_info)
855 LOGD("Start Loading \n");
856 app_data *ad = (app_data *) data;
857 evas_object_show(ad->progress_bar);
860 //To check SIP status
861 void __im_context_open_cb(void *data, Evas_Object *obj, void *event_info)
863 LOGD("IM_CONTEXT_EFL_ON \n");
864 im_context_status = 1;
867 void __im_context_close_cb(void *data, Evas_Object *obj, void *event_info)
869 LOGD("IM_CONTEXT_EFL_OFF \n");
871 if (IsMobileProfile() || IsWearableProfile()) {
872 app_data *ad = (app_data *)data;
873 int changed_ang = elm_win_rotation_get(ad->main_window);
874 int main_window_width = 0, main_window_height = 0;
875 get_main_window_size(&changed_ang, &main_window_width, &main_window_height);
876 evas_object_resize(ad->webview, main_window_width, main_window_height - TOOL_BOX_HEIGHT);
879 evas_object_move(ad->tool_box, 0, main_window_height - TOOL_BOX_HEIGHT);
880 evas_object_hide(ad->bg_tool_box);
881 elm_object_focus_set(ad->url_entry, EINA_FALSE);
886 im_context_status = 0;
889 #if defined(OS_TIZEN)
890 void _imf_panel_changed_cb(void *data, Evas_Object *obj, Eina_Rectangle *rect)
892 if (IsMobileProfile() || IsWearableProfile()) {
893 printf("__imf_panel_changed_cb\n");
894 LOGD("IM_CONTEXT_EFL_OFF \n");
896 app_data *ad = (app_data *)data;
897 int changed_ang = elm_win_rotation_get(ad->main_window);
898 int main_window_width = 0, main_window_height = 0;
899 get_main_window_size(&changed_ang, &main_window_width, &main_window_height);
901 if (rect->h < TOOL_BOX_HEIGHT)
902 evas_object_resize(ad->webview, main_window_width, main_window_height - TOOL_BOX_HEIGHT);
904 evas_object_resize(ad->webview, main_window_width, main_window_height - rect->h);
909 void __load_progress_finished_cb(void *data, Evas_Object *obj, void *event_info)
911 LOGD("Ending Loading \n");
912 app_data *ad = (app_data *) data;
913 evas_object_resize(ad->progress_bar, 0, 10);
914 evas_object_hide(ad->progress_bar);
917 void __load_finished_cb(void *data, Evas_Object *obj, void *event_info)
919 LOGD("Load Done \n");
922 void __load_progress_cb(void *data, Evas_Object *obj, void *event_info)
924 LOGD("Progress = %f \n", *((double *)event_info));
925 app_data *ad = (app_data *) data;
927 evas_object_geometry_get (ad->main_window, NULL, NULL, &width, NULL);
928 evas_object_resize(ad->progress_bar, (*((double *)event_info))*width, 10);
931 void __load_error_cb(void *data, Evas_Object *obj, void *event_info)
933 Ewk_Error* error = (Ewk_Error*)event_info;
934 LOGD("ERROR URL : %s\n", ewk_error_url_get(error));
935 LOGD("ERROR DESCRIPTION : %s\n", ewk_error_description_get(error));
937 /*do nothing if user action aborts loading page which is not
938 considered as a fault, else display error description in webview*/
939 const char* errorDescription=ewk_error_description_get(error);
940 if( strcmp(errorDescription,"net::ERR_ABORTED") != 0 )
942 ewk_view_not_found_error_page_load(obj, ewk_error_url_get(error));
946 void __uri_changed_cb(void *data, Evas_Object *obj, void *event_info)
948 LOGD("URI is = %s \n", (const char *)event_info);
949 app_data *ad = (app_data*) data;
950 elm_object_text_set(ad->url_entry, (const char *)event_info);
953 void __title_changed_cb(void *data, Evas_Object *obj, void *event_info)
955 LOGD("Title is = %s \n", (const char *)event_info);
958 void __popup_close(app_data* ad)
961 evas_object_focus_set(ad->webview, EINA_TRUE);
962 evas_object_hide(ad->popup);
963 evas_object_del(ad->popup);
965 eina_stringshare_del(ad->popup_url);
966 ad->popup_url = NULL;
970 void __popup_open_url_cb(void *data, Evas_Object *obj, void *event_info)
972 app_data* ad = (app_data*)data;
973 ewk_view_url_set(ad->webview, ad->popup_url);
975 evas_object_focus_set(ad->webview, EINA_TRUE);
978 void __popup_cancel_url_cb(void *data, Evas_Object *obj, void *event_info)
980 app_data* ad = (app_data*)data;
982 evas_object_focus_set(ad->webview, EINA_TRUE);
985 void __policy_newwindow_decide_cb(void *data, Evas_Object *obj, void *event_info)
987 app_data* ad = (app_data*)data;
993 Ewk_Policy_Decision* policy_decision = (Ewk_Policy_Decision*)event_info;
994 Evas_Object* popup = elm_popup_add(ad->main_window);
995 ad->popup_url = eina_stringshare_add(ewk_policy_decision_url_get(policy_decision));
996 gchar* title = g_strdup_printf("Do you want to open \"%s\" in current window", ad->popup_url);
997 elm_object_part_text_set(popup, "title,text", "New window request");
998 elm_object_text_set(popup, title);
1001 Evas_Object *open = elm_button_add(popup);
1002 elm_object_text_set(open, "Open");
1003 elm_object_part_content_set(popup, "button1", open);
1004 evas_object_smart_callback_add(open, "clicked", __popup_open_url_cb, ad);
1006 Evas_Object *cancel = elm_button_add(popup);
1007 elm_object_text_set(cancel, "Cancel");
1008 elm_object_part_content_set(popup, "button2", cancel);
1009 evas_object_smart_callback_add(cancel, "clicked", __popup_cancel_url_cb, ad);
1012 evas_object_show(popup);
1015 void _geol_ok_cb (void *data, Evas_Object *obj, void *event_info)
1017 LOGD("geolocation permission granted");
1018 app_data* ad = (app_data*)data;
1019 ewk_geolocation_permission_request_set( ad->geolRequest, EINA_TRUE);
1024 void _geol_cancel_cb (void *data, Evas_Object *obj, void *event_info)
1026 LOGD("geolocation restricted");
1027 app_data* ad = (app_data*)data;
1028 ewk_geolocation_permission_request_set( ad->geolRequest, EINA_FALSE);
1032 void __geolocation_permission_request_cb(void *data, Evas_Object *obj, void *event_info)
1034 LOGD("geolocation request recieved");
1035 app_data* ad = (app_data*)data;
1040 Ewk_Geolocation_Permission_Request* permissionRequest=
1041 (Ewk_Geolocation_Permission_Request*)event_info;
1042 Evas_Object* popup = elm_popup_add(ad->main_window);
1043 ewk_geolocation_permission_request_suspend(permissionRequest);
1044 ad->geolRequest=permissionRequest;
1046 elm_object_part_text_set(popup, "title,text", "Geolocation permission request");
1047 elm_object_text_set(popup,"Do you want to allow this page to access geolocation data?");
1049 Evas_Object *ok = elm_button_add(popup);
1050 elm_object_text_set(ok, "ok");
1051 elm_object_part_content_set(popup, "button1", ok);
1052 evas_object_smart_callback_add(ok, "clicked", _geol_ok_cb, ad);
1054 Evas_Object *cancel = elm_button_add(popup);
1055 elm_object_text_set(cancel, "Cancel");
1056 elm_object_part_content_set(popup, "button2", cancel);
1057 evas_object_smart_callback_add(cancel, "clicked", _geol_cancel_cb, ad);
1059 evas_object_show(popup);
1062 // Callback for Allow button press for media request
1063 void _usermedia_ok_cb (void *data, Evas_Object *obj, void *event_info)
1065 app_data* ad = (app_data*)data;
1066 ewk_user_media_permission_request_set(ad->userMediaRequest,EINA_TRUE);
1070 // Callback for Deny button press for media request
1071 void _usermedia_cancel_cb (void *data, Evas_Object *obj, void *event_info)
1073 app_data* ad = (app_data*)data;
1074 ewk_user_media_permission_request_set(ad->userMediaRequest,EINA_FALSE);
1078 // Callback for showing permission request for media request
1079 void __usermedia_permission_request_cb(void *data, Evas_Object *obj, void *event_info)
1081 app_data* ad = (app_data*)data;
1085 Ewk_User_Media_Permission_Request* permissionRequest=
1086 (Ewk_User_Media_Permission_Request*)event_info;
1087 Evas_Object* popup = elm_popup_add(ad->main_window);
1088 ewk_user_media_permission_request_suspend(permissionRequest);
1090 ad->userMediaRequest=permissionRequest;
1091 elm_object_part_text_set(popup, "title,text", "Media permission request");
1092 elm_popup_align_set(popup, -1.0, 1.0);
1093 elm_object_text_set(popup,"Do you want to allow this page to access Media Resources?");
1095 Evas_Object *ok = elm_button_add(popup);
1096 elm_object_text_set(ok, "ok");
1097 elm_object_part_content_set(popup, "button1", ok);
1098 evas_object_smart_callback_add(ok, "clicked", _usermedia_ok_cb, ad);
1100 Evas_Object *cancel = elm_button_add(popup);
1101 elm_object_text_set(cancel, "Cancel");
1102 elm_object_part_content_set(popup, "button2", cancel);
1103 evas_object_smart_callback_add(cancel, "clicked", _usermedia_cancel_cb, ad);
1105 evas_object_show(popup);
1108 void url_hit_cb(void *data, Evas_Object *obj, void *event_info)
1110 LOGD("Send load request\n");
1111 app_data *ad = (app_data*) data;
1112 const char* url = elm_entry_entry_get( ad->url_entry );
1113 set_url_from_user_input(ad->webview, url);
1115 evas_object_focus_set(ad->webview, EINA_TRUE);
1118 void find_hit_cb(void *data, Evas_Object *obj, void *event_info)
1120 LOGD("Find word\n");
1121 app_data *ad = (app_data*) data;
1122 mini_find_word("google", EINA_TRUE, __text_found_cb, data);
1126 void clear_hit_cb(void *data, Evas_Object *obj, void *event_info)
1128 LOGD("Clear word\n");
1129 mini_find_word_clear(data);
1130 mini_find_word("", EINA_FALSE, __text_found_cb, data);
1131 app_data *ad = (app_data*) data;
1135 void zoomin_hit_cb(void *data, Evas_Object *obj, void *event_info)
1137 app_data *ad = (app_data*)data;
1139 if(scale_factor >= 1 && scale_factor < 4) {
1140 printf("11 scale_factor = %f\n", scale_factor);
1141 scale_factor += 0.1;
1142 ewk_view_scale_set(ad->webview, scale_factor, 0, 0);
1143 printf("22 scale_factor = %f\n", scale_factor);
1148 void zoomout_hit_cb(void *data, Evas_Object *obj, void *event_info)
1150 app_data *ad = (app_data*)data;
1152 if(scale_factor > 1 && scale_factor <= 4) {
1153 printf("11 scale_factor = %f\n", scale_factor);
1154 scale_factor -= 0.1;
1155 printf("22 scale_factor = %f\n", scale_factor);
1156 ewk_view_scale_set(ad->webview, scale_factor, 0, 0);
1161 #if defined(OS_TIZEN)
1162 /* On Click to Urlbar need to move Toolbar top of SIP
1163 * so that SIP and toolbar should not overlap
1165 void _url_clicked_cb(void *data, Evas_Object *obj, void *event_info)
1167 if (IsTvProfile()) {
1168 app_data *ad = (app_data*) data;
1169 elm_entry_input_panel_enabled_set(ad->url_entry, EINA_TRUE);
1170 if( curr_focus == NULL )
1171 curr_focus = evas_focus_get(ad->e);
1172 evas_object_focus_set(curr_focus, EINA_TRUE);
1173 Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(ad->url_entry);
1176 if (!is_imf_shown && ecore_imf_context_input_panel_state_get(imf_context) != ECORE_IMF_INPUT_PANEL_STATE_SHOW)
1181 evas_object_geometry_get (ad->bg_tool_box, NULL, NULL, &width, &height);
1182 ecore_imf_context_input_panel_geometry_get (imf_context, &x, &y, &w, &h);
1183 //evas_object_resize(ad->webview, width, IMF_START_POINT_Y - TOOL_BOX_HEIGHT); //To resize webview size above toolbar
1184 evas_object_move(ad->bg_tool_box, 0, IMF_START_POINT_Y - TOOL_BOX_HEIGHT);
1185 evas_object_show(ad->bg_tool_box);
1186 evas_object_move(ad->tool_box, 0, IMF_START_POINT_Y - TOOL_BOX_HEIGHT);
1187 elm_entry_input_panel_show(ad->url_entry);
1194 void _imf_panel_state_cb (void *data, Ecore_IMF_Context *ctx, int value)
1196 LOGD("_imf_panel_state_cb show\n");
1197 app_data *ad = (app_data*) data;
1198 int x=0, y=0, w=0, h=0;
1199 if (value == ECORE_IMF_INPUT_PANEL_STATE_SHOW)
1201 LOGD("Keypad Up\n");
1202 ecore_imf_context_input_panel_geometry_get (ctx, &x, &y, &w, &h);
1203 evas_object_move(ad->bg_tool_box, 0, y - TOOL_BOX_HEIGHT);
1204 evas_object_show(ad->bg_tool_box);
1205 evas_object_move(ad->tool_box, 0, y - TOOL_BOX_HEIGHT);
1208 else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE)
1210 LOGD("Keypad down\n");
1211 evas_object_geometry_get(ad->main_window, NULL, NULL, &w, &h);
1212 evas_object_move(ad->tool_box, 0, h - TOOL_BOX_HEIGHT);
1213 evas_object_hide(ad->bg_tool_box);
1215 elm_object_focus_set(ad->url_entry, EINA_FALSE);
1221 void hide_imf_panel(app_data* data)
1223 if (IsTvProfile()) {
1224 /* On SIP close, Toolbar bring back to original position*/
1226 int width = 0, height = 0;
1227 #if defined(USE_WAYLAND)
1228 #if TIZEN_VERSION_AT_LEAST(5, 0, 0)
1229 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
1230 ecore_wl2_display_screen_size_get(wl2_display, &width, &height);
1232 ecore_wl_screen_size_get(&width, &height);
1233 #endif // TIZEN_VERSION_AT_LEAST(5, 0, 0)
1235 ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
1237 //evas_object_resize(data->webview, width, height - TOOL_BOX_HEIGHT);
1238 evas_object_move(data->bg_tool_box, 0, height - TOOL_BOX_HEIGHT);
1239 evas_object_show(data->bg_tool_box);
1240 evas_object_move(data->tool_box, 0, height - TOOL_BOX_HEIGHT);
1241 evas_object_focus_set(curr_focus, EINA_FALSE);
1242 elm_entry_input_panel_hide(data->url_entry);
1243 evas_object_focus_set(data->webview, EINA_TRUE);
1247 elm_object_focus_set(data->url_entry, EINA_FALSE);
1248 elm_entry_input_panel_hide(data->url_entry);
1253 void _back_btn_cb(void *data, Evas_Object *btn, void *ev)
1255 LOGD("Previous Page\n");
1256 app_data *ad = (app_data*) data;
1257 ewk_view_back(ad->webview);
1261 void _trace_start_btn_cb(void *data,Evas_Object *btn,void *ev)
1263 ewk_start_tracing("*, disabled-by-default-toplevel.flow", "", "");
1266 void _trace_stop_btn_cb(void *data,Evas_Object *btn,void *ev)
1271 void _next_btn_cb(void *data, Evas_Object *btn, void *ev)
1273 LOGD("Next Page\n");
1274 app_data *ad = (app_data*) data;
1275 ewk_view_forward(ad->webview);
1279 void _reload_btn_cb(void *data, Evas_Object *btn, void *ev)
1282 app_data *ad = (app_data*) data;
1283 ewk_view_reload(ad->webview);
1287 #if defined(OS_TIZEN)
1288 void _on_keyup_cb(void *data, Evas *e, Evas_Object *btn, void *event_info)
1290 // Make snapshot only on menu press button.
1291 app_data *ad = (app_data*) data;
1292 Evas_Event_Key_Up *ev = (Evas_Event_Key_Up*) event_info;
1293 if (strcmp(ev->key, "XF86Send") != 0)
1295 Eina_Rectangle rect;
1296 EINA_RECTANGLE_SET(&rect, 0, 0, 400, 400);
1297 ewk_view_screenshot_contents_get_async(ad->webview, rect, 1, ad->e, _screenshot_captured_cb, NULL);
1300 void _screenshot_captured_cb(Evas_Object* image, void* user_data)
1304 sprintf(buf, "/opt/usr/media/Downloads/screenshot%d.png", c++);
1305 evas_object_image_save(image, buf, NULL, NULL);
1309 void _stop_btn_cb(void *data, Evas_Object *btn, void *ev)
1312 app_data *ad = (app_data*) data;
1313 ewk_view_stop(ad->webview);
1317 void __policy_response_decide_cb(void *data, Evas_Object *obj, void *ev)
1319 LOGD(" callback called __policy_response_decide_cb \n");
1320 Ewk_Policy_Decision *policy_decision = (Ewk_Policy_Decision *)ev;
1321 Ewk_Policy_Decision_Type policy_type = ewk_policy_decision_type_get(policy_decision);
1322 const char *uri = ewk_policy_decision_url_get(policy_decision);
1323 const char *cookie = ewk_policy_decision_cookie_get(policy_decision);
1324 const char *mime = ewk_policy_decision_response_mime_get(policy_decision);
1325 LOGD(" URL : %s\n", uri);
1326 LOGD(" cookie : %s\n", cookie);
1327 LOGD(" mime type : %s\n", mime);
1328 LOGD(" policy type : %d\n", policy_type);
1329 ewk_policy_decision_use(policy_decision);
1332 void __navigation_policy_decide_cb(void *data, Evas_Object *obj, void *ev)
1334 Ewk_Policy_Decision* decision = (Ewk_Policy_Decision*)ev;
1335 LOGD(" callback called __navigation_policy_decide_cb \n");
1336 LOGD("URL: %s\n", ewk_policy_decision_url_get(decision));
1337 LOGD("Navigation type: %d", ewk_policy_decision_navigation_type_get(decision));
1339 // download needs to be handled and ignore wont have any visible difference.
1340 LOGD("Decision: USE\n");
1341 ewk_policy_decision_use(decision);
1345 void _back_hard_key_cb(void *data, Evas_Object *btn, void *ev)
1347 app_data *ad = (app_data*) data;
1353 if (IsTvProfile()) {
1354 /* SIP in TV has dedicated Close button but in Mobile Backkey is used as Close
1355 * For TV, On SIP Close Press only Hide IMF, Don't allow Navigation Back
1356 * Navigation back is handled seperatly for Backkey Event, where as
1357 * For Mobile, Backkey is used as SIP Close button and Navigation Back
1362 evas_object_focus_set(ad->webview, EINA_TRUE);
1368 context_menu_type get_menu_type(app_data *data, Ewk_Context_Menu *menu)
1370 //RETV_MSG_IF(!menu, UNKNOWN_MENU, "menu is NULL");
1372 unsigned short count = ewk_context_menu_item_count(menu);
1373 Eina_Bool text = EINA_FALSE;
1374 Eina_Bool link = EINA_FALSE;
1375 Eina_Bool image = EINA_FALSE;
1376 Eina_Bool email_address = EINA_FALSE;
1377 Eina_Bool call_number = EINA_FALSE;
1378 Eina_Bool selection_mode = EINA_FALSE;
1380 unsigned short i = 0;
1381 for (i = 0 ; i < count ; i++) {
1382 Ewk_Context_Menu_Item *item = ewk_context_menu_nth_item_get(menu, i);
1383 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1384 const char *link_url = ewk_context_menu_item_link_url_get(item);
1385 //BROWSER_LOGD("tag=%d", tag);
1387 if (link_url && !strncmp(mailto_scheme, link_url, strlen(mailto_scheme)))
1388 email_address = EINA_TRUE;
1389 if (link_url && !strncmp(tel_scheme, link_url, strlen(tel_scheme)))
1390 call_number = EINA_TRUE;
1391 if (tag == EWK_CONTEXT_MENU_ITEM_TAG_TEXT_SELECTION_MODE)
1392 selection_mode = EINA_TRUE;
1393 if (tag == EWK_CONTEXT_MENU_ITEM_TAG_CLIPBOARD)
1395 if (tag == EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB)
1397 if (tag == EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW)
1399 if (tag == EWK_CONTEXT_MENU_ITEM_TAG_COPY_IMAGE_TO_CLIPBOARD)
1403 if (email_address && selection_mode)
1404 return EMAIL_SCHEME;
1405 if (call_number && selection_mode)
1416 return UNKNOWN_MENU;
1420 void __customize_context_menu_cb(void *data, Evas_Object *obj, void *event_info)
1422 app_data * ad = (app_data*)data;
1423 Ewk_Context_Menu *menu = (Ewk_Context_Menu*)event_info;
1424 context_menu_type menu_type = get_menu_type(ad, menu);
1426 if (menu_type == UNKNOWN_MENU || menu_type == INPUT_FIELD)
1429 switch (menu_type) {
1431 show_context_menu_text_only(ad, menu);
1435 show_context_menu_text_link(ad, menu);
1439 show_context_menu_image_only(ad, menu);
1443 show_context_menu_image_link(ad, menu);
1447 show_context_menu_email_address(ad, menu);
1451 show_context_menu_call_number(ad, menu);
1460 void __customize_context_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
1462 Ewk_Context_Menu_Item* item = (Ewk_Context_Menu_Item*)event_info;
1464 switch (ewk_context_menu_item_tag_get(item)) {
1465 case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1472 void show_context_menu_text_only(app_data *data, Ewk_Context_Menu *menu)
1474 unsigned short count = ewk_context_menu_item_count(menu);
1475 //RET_MSG_IF(count == 0, "There is no context menu for text only");
1477 app_data * ad = (app_data*)data;
1478 const char *selected_text = ewk_view_text_selection_text_get(ad->webview);
1479 Eina_Bool text_selected = EINA_FALSE;
1480 if (selected_text && strlen(selected_text) > 0)
1481 text_selected = EINA_TRUE;
1483 Ewk_Context_Menu_Item_Tag *original_ctx_item = NULL;
1484 original_ctx_item = (Ewk_Context_Menu_Item_Tag *)malloc(sizeof(Ewk_Context_Menu_Item_Tag) * count);
1485 //RET_MSG_IF(original_ctx_item == NULL, "Failed to allocate memory for ctx menu reordering");
1487 memset(original_ctx_item, 0x00, sizeof(Ewk_Context_Menu_Item_Tag) * count);
1490 for (i = 0 ; i < count ; i++) {
1491 Ewk_Context_Menu_Item *item = ewk_context_menu_nth_item_get(menu, 0);
1492 Ewk_Context_Menu_Item_Tag tag = ewk_context_menu_item_tag_get(item);
1494 original_ctx_item[i] = tag;
1495 ewk_context_menu_item_remove(menu, item);
1499 for (i = 0 ; i < count ; i++) {
1500 if (original_ctx_item[i] == EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL) {
1501 ewk_context_menu_item_append_as_action(menu, EWK_CONTEXT_MENU_ITEM_TAG_SELECT_ALL, BR_STRING_CTXMENU_SELECT_ALL, true);
1507 if (text_selected == EINA_TRUE) {
1508 for (i = 0 ; i < count ; i++) {
1509 if (original_ctx_item[i] == EWK_CONTEXT_MENU_ITEM_TAG_COPY) {
1510 ewk_context_menu_item_append_as_action(menu, EWK_CONTEXT_MENU_ITEM_TAG_COPY, BR_STRING_CTXMENU_COPY, true);
1518 if (text_selected == EINA_TRUE)
1519 ewk_context_menu_item_append(menu, CUSTOM_CONTEXT_MENU_ITEM_SHARE, BR_STRING_SHARE, browser_img_dir"/I01_ctx_popup_icon_share.png", true);
1523 if (text_selected == EINA_TRUE) {
1524 for (i = 0 ; i < count ; i++) {
1525 if (original_ctx_item[i] == EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB) {
1526 ewk_context_menu_item_append(menu, CUSTOM_CONTEXT_MENU_ITEM_SEARCH, BR_STRING_CTXMENU_WEB_SEARCH, browser_img_dir"/I01_ctx_popup_icon_web_search.png", true);
1533 if (text_selected == EINA_TRUE) {
1534 for (i = 0 ; i < count ; i++) {
1535 if (original_ctx_item[i] == EWK_CONTEXT_MENU_ITEM_TAG_TRANSLATE) {
1536 ewk_context_menu_item_append(menu, EWK_CONTEXT_MENU_ITEM_TAG_TRANSLATE, BR_STRING_CTXMENU_TRANSLATE, browser_img_dir"/I01_ctx_popup_icon_translate.png", true);
1543 free(original_ctx_item);
1546 void show_context_menu_text_link(app_data *data, Ewk_Context_Menu *menu)
1549 ewk_context_menu_item_append_as_action(context_menu, EWK_CONTEXT_MENU_ITEM_TAG_GO_BACK, "Back", 1);
1550 ewk_context_menu_item_append_as_action(context_menu, EWK_CONTEXT_MENU_ITEM_TAG_GO_FORWARD, "Forward", 1);
1551 ewk_context_menu_item_append_as_action(context_menu, EWK_CONTEXT_MENU_ITEM_TAG_RELOAD, "Reload", 1);
1552 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_APPLICATION_BACK_FORWAD_CLEAR, "Bk_fwd_clear", 1);
1553 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_APPLICATION_CACHE_RUN, "Run App Cache Test", 1);
1554 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_APPLICATION_CACHE_DELETE_ALL, "Delete All App Cache", 1);
1555 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_GRAB_SNAPSHOT, "Take Snapshot", 1);
1556 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_WEB_DATABASE_GET_ORIGINS, "Get WebDB", 1);
1557 ewk_context_menu_item_append_as_action(context_menu, FOR_TEST_WEB_DATABASE_DELETE_ALL, "Clear WebDB", 1);
1562 void show_context_menu_image_only(app_data *data, Ewk_Context_Menu *menu)
1568 void show_context_menu_image_link(app_data *data, Ewk_Context_Menu *menu)
1573 void show_context_menu_email_address(app_data *data, Ewk_Context_Menu *menu)
1577 void show_context_menu_call_number(app_data *data, Ewk_Context_Menu *menu)
1582 void enable_customize_contextmenu(app_data *data, Eina_Bool enable)
1585 evas_object_smart_callback_add(data->webview, "contextmenu,customize", __customize_context_menu_cb, data);
1586 evas_object_smart_callback_add(data->webview, "contextmenu,selected", __customize_context_menu_item_selected_cb, data);
1588 evas_object_smart_callback_del(data->webview, "contextmenu,customize", __customize_context_menu_cb);
1589 evas_object_smart_callback_del(data->webview, "contextmenu,selected", __customize_context_menu_item_selected_cb);
1593 // Added to Support Javascript popup
1594 Eina_Bool __javascript_alert_cb(Evas_Object* o, const char* alert_text, void* user_data)
1599 Eina_Bool __javascript_confirm_cb(Evas_Object* o, const char* message, void* user_data)
1604 Eina_Bool __javascript_prompt_cb(Evas_Object* o, const char* message, const char* default_value, void* user_data)
1609 #if defined(OS_TIZEN)
1610 // To support vibration: this is a timeout callback.
1611 // The original source code author is kinipk.
1612 Eina_Bool __vibration_timeout_cb(void *data)
1614 if (IsMobileProfile() || IsWearableProfile()) {
1615 s_haptic_timer_id = NULL;
1616 if (s_haptic_handle) {
1617 device_haptic_stop(s_haptic_handle, s_haptic_effect);
1618 device_haptic_close(s_haptic_handle);
1619 s_haptic_handle = NULL;
1622 return ECORE_CALLBACK_CANCEL;
1628 // To support vibration: @see |ewk_context_vibration_client_callbacks_set|, also.
1629 // The original source code author is kinipk.
1630 void __vibration_on_cb(uint64_t vibration_time, void *data)
1632 printf("[%s][%d][%s] called\n", __FUNCTION__, __LINE__, "vibration");
1633 uint64_t duration = vibration_time;
1635 if (s_haptic_timer_id) {
1636 ecore_timer_del(s_haptic_timer_id);
1637 s_haptic_timer_id = NULL;
1640 if (s_haptic_handle) {
1641 device_haptic_stop(s_haptic_handle, s_haptic_effect);
1642 device_haptic_close(s_haptic_handle);
1643 s_haptic_handle = NULL;
1646 if (device_haptic_open(0, &s_haptic_handle) != DEVICE_ERROR_NONE) {
1647 printf("[%s][%d][%s] ERROR: __vibration_on_cb:device_haptic_open failed\n", __FUNCTION__, __LINE__, "vibration");
1651 device_haptic_vibrate(s_haptic_handle, duration, 100, &s_haptic_effect);
1652 double in = (double)((double)(duration) / (double)(1000));
1653 printf("[%s][%d][%s] __vibration_on_cb:duration=%f\n", __FUNCTION__, __LINE__, "vibration", in);
1655 s_haptic_timer_id = ecore_timer_add(in, __vibration_timeout_cb, NULL);
1658 // To support vibration: @see |ewk_context_vibration_client_callbacks_set|, also.
1659 // The original source code author is kinipk.
1660 void __vibration_off_cb(void *data)
1662 printf("[%s][%d][%s] called\n", __FUNCTION__, __LINE__, "vibration");
1663 if (s_haptic_timer_id) {
1664 ecore_timer_del(s_haptic_timer_id);
1665 s_haptic_timer_id = NULL;
1668 if (s_haptic_handle) {
1669 device_haptic_stop(s_haptic_handle, s_haptic_effect);
1670 device_haptic_close(s_haptic_handle);
1671 s_haptic_handle = NULL;
1674 #endif // #if caluse of #if defined(OS_TIZEN)...
1676 void mini_find_word(const char *word, Eina_Bool forward, Evas_Smart_Cb found_cb, void *data)
1678 app_data *ad = (app_data*) data;
1680 evas_object_smart_callback_del(ad->webview, "text,found", found_cb);
1681 evas_object_smart_callback_add(ad->webview, "text,found", found_cb, data);
1683 Ewk_Find_Options find_option = (Ewk_Find_Options)(EWK_FIND_OPTIONS_CASE_INSENSITIVE |
1684 EWK_FIND_OPTIONS_WRAP_AROUND |
1685 EWK_FIND_OPTIONS_SHOW_FIND_INDICATOR |
1686 EWK_FIND_OPTIONS_SHOW_HIGHLIGHT);
1689 find_option = (Ewk_Find_Options)(find_option | EWK_FIND_OPTIONS_BACKWARDS);
1691 ewk_view_text_find(ad->webview, word, find_option, 10000);
1694 void mini_find_word_clear(void *data)
1696 app_data *ad = (app_data*) data;
1697 ewk_view_text_find_highlight_clear(ad->webview);
1700 void __text_found_cb(void *data, Evas_Object *obj, void *event_info)
1702 printf("text found : %u\n", *((unsigned int*)(event_info)));