[M67 Dev][EWK] Classify EWK APIs by public, internal, or product
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_webview_app / mini_browser.c
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.
4
5 #define _DEFAULT_SOURCE
6
7 #include <appfw/app.h>
8 #include <dlog.h>
9 #include <Ecore.h>
10 #include <Ecore_Evas.h>
11 #include <Ecore_File.h>
12 #include <Ecore_Getopt.h>
13 #include "ecore_x_wayland_wrapper.h"
14 #include <Evas.h>
15 #include <Elementary.h>
16 #include <glib/gprintf.h>
17 #if defined(OS_TIZEN)
18 #include <Ecore_IMF_Evas.h>
19 #endif
20
21 #include <unistd.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <tizen_version.h>
25
26 #if defined(OS_TIZEN)
27 #include <device/haptic.h>
28 #endif
29
30 #include "browser-string.h"
31 #include "browser-object.h"
32 #include "public/EWebKit.h"
33 #include "public/EWebKit_internal.h"
34
35 #include "tizen/system_info.h"
36
37 #ifdef OS_TIZEN
38 #include <efl_extension.h>
39 #endif
40
41 #undef LOG_TAG
42 #define LOG_TAG "CHROMIUMEFL"
43 #define TOOL_BOX_HEIGHT 150
44 #define URL_BOX_HEIGHT 75
45 // SIP height in TV
46 #if defined(OS_TIZEN)
47 #define IMF_START_POINT_Y 635
48 #endif
49
50 #if defined(OS_TIZEN)
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.
54 #endif
55
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;
61 #if defined(OS_TIZEN)
62 static Evas_Object * curr_focus = NULL;
63 #endif
64 // We are just following Tizen platform application pattern.
65 // It will be required to pass data across lifecycle callbacks.
66 typedef struct
67 {
68   Evas* e;
69
70   /*let's explain those Evas_Object's hierarchy:
71   +main_window
72     -webview
73     +tool_box
74       +url_box
75         -url_entry
76       +button_box
77         -backbtn
78         -nextbtn
79         -refreshbtn
80         -gobtn
81         -stopbtn
82     -bg_tool_box
83     -progress_bar
84   */
85   Evas_Object *main_window;
86
87   Evas_Object* webview;     //an ewk_view which's app demo is
88
89   Evas_Object *tool_box;    //box containig url_box and button_box
90
91   Evas_Object *url_box;     //box containing only url_entry
92   Evas_Object *url_entry;
93
94   Evas_Object *button_box;  //box containing navigation buttons
95   Evas_Object *backbtn;
96   Evas_Object *nextbtn;
97   Evas_Object *refreshbtn;
98   Evas_Object *gobtn;
99   Evas_Object *stopbtn;
100   Evas_Object *tracestartbtn;
101   Evas_Object *tracestopbtn;
102
103   Evas_Object *findbtn;
104   Evas_Object *clearbtn;
105   Evas_Object *zoominbtn;
106   Evas_Object *zoomoutbtn;
107
108   Evas_Object *bg_tool_box; //background under the toolbox
109
110   Evas_Object *progress_bar;
111
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;
117 } app_data;
118
119 // Added to Support customized context menu
120 typedef enum _context_menu_type {
121         TEXT_ONLY = 0,
122         INPUT_FIELD,
123         TEXT_LINK,
124         IMAGE_ONLY,
125         IMAGE_LINK,
126         EMAIL_SCHEME,
127         TEL_SCHEME,
128         UNKNOWN_MENU
129 } context_menu_type;
130
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;
142
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;
151
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);
159
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);
163 #endif
164
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);
178
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);
182
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);
187 #endif
188
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);
197
198 static void hide_imf_panel(app_data * data);
199 #ifdef OS_TIZEN
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);
203 #endif
204
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);
208
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);
218
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);
223
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);
228 #endif
229
230 static void get_main_window_size(int *changed_ang, int *width, int *height);
231
232 #if defined(OS_TIZEN)
233 // To avoid implicit function declaration
234 int setenv(const char *name, const char *value, int overwrite);
235 #endif
236
237 enum
238 {
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
243 };
244
245 static const Ecore_Getopt options =
246 {
247   .prog = "mini_browser",
248   .usage = "%prog [options] [url]",
249   .strict = EINA_TRUE,
250   .descs =
251   {
252     ECORE_GETOPT_STORE_DEF_STR('u', "url", "go to url", default_start_url),
253     ECORE_GETOPT_SENTINEL,
254   }
255 };
256
257 static Eina_Strbuf* create_url_with_scheme(const char* base_url, const char* scheme)
258 {
259   Eina_Strbuf* buffer = eina_strbuf_new();
260   eina_strbuf_append(buffer, scheme);
261   eina_strbuf_append(buffer, base_url);
262   return buffer;
263 }
264
265 static void set_url_from_user_input(Evas_Object* webview, const char* url)
266 {
267   if (strstr(url, "://"))
268   {
269     ewk_view_url_set(webview, url);
270     return;
271   }
272
273   // Add scheme.
274   Eina_Strbuf* full_url;
275   if (ecore_file_exists(url))
276   {
277     char* realpath = ecore_file_realpath(url);
278     full_url = create_url_with_scheme(realpath, "file://");
279     free(realpath);
280   }
281   else
282   {
283     full_url = create_url_with_scheme(url, "http://");
284   }
285
286   ewk_view_url_set(webview, eina_strbuf_string_get(full_url));
287
288   eina_strbuf_free(full_url);
289 }
290
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));
300
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");
306   }
307   eina_iterator_free(globals);
308
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))));
312   ecore_wl2_sync();
313
314   if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL))
315     LOGE("Cursor_Set_Config() Failed!\n");
316   CursorModule_Finalize();
317 #else
318   const char* t_cursor = "tizen_cursor";
319   unsigned int cursormgr_id = 0;
320   Ecore_Wl_Global* global_data = NULL;
321
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
325       break;
326     }
327   }
328
329   struct wl_surface* const surface =
330       ecore_wl_window_surface_get(elm_win_wl_window_get(window));
331   ecore_wl_sync();
332
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);
336   if (ret_cursormod) {
337     Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL);
338   }
339   CursorModule_Finalize();
340 #endif
341 }
342 #endif
343
344 static Evas_Object* _create_main_window(void *data)
345 {
346   Evas_Object *window = elm_win_add(NULL, "ChromiumEfl", ELM_WIN_BASIC);
347   if (window) {
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);
358 #else
359     ecore_wl_screen_size_get(&width, &height);
360 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
361 #else
362     ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
363 #endif
364     evas_object_resize(window, width, height);
365     elm_win_indicator_mode_set(window, ELM_WIN_INDICATOR_SHOW);
366
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);
376   }
377   return window;
378 }
379
380 Evas_Object* _create_view(Evas_Object *parent, app_data *data)
381 {
382   if (start_url == NULL)
383   {
384     start_url = (char*)default_start_url;
385   }
386
387   int width, height;
388   evas_object_geometry_get(parent, NULL, NULL, &width, &height);
389
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);
392
393   evas_object_show(webview);
394   evas_object_focus_set(webview, EINA_TRUE);
395
396   data->webview = webview;
397
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);
406   if (IsTvProfile()) {
407     evas_object_event_callback_add(webview, EVAS_CALLBACK_MOUSE_DOWN, _webview_mouse_down_cb       , data);
408   }
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);
417
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);
421   }
422
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);
427
428   // To Enable customized context menu
429   enable_customize_contextmenu(data, EINA_TRUE);
430
431   if (IsMobileProfile() || IsWearableProfile()) {
432     evas_object_smart_callback_add(webview, "inputmethod,changed", (Evas_Smart_Cb) _imf_panel_changed_cb, data);
433   }
434
435   return webview;
436 }
437
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)
441 {
442   if (IsTvProfile()) {
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"))
446     {
447       const char* url = elm_entry_entry_get( ad->url_entry );
448       set_url_from_user_input(ad->webview, url);
449       hide_imf_panel(ad);
450       evas_object_focus_set(ad->webview, EINA_TRUE);
451     }
452     if (!strcmp(ev->key, "Cancel"))
453     {
454       hide_imf_panel(ad);
455     }
456   }
457 }
458
459 /* On Mouse Event over webview should bring back
460  * Tool bar to its original position
461  */
462 void _webview_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
463 {
464   if (IsTvProfile()) {
465     app_data *ad = (app_data*) data;
466     hide_imf_panel(ad);
467   }
468 }
469 #endif
470
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)
473 {
474   app_data *ad = (app_data*) data;
475   Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
476
477   if (strcmp(ev->key, "XF86Stop") == 0)
478   {
479     if (ewk_view_text_selection_clear(ad->webview))
480       return;
481   }
482   if ( (!strcmp(ev->key, "BackSpace") || !strcmp(ev->key, "XF86Stop")) && (!im_context_status) )
483   {
484     ewk_view_back(ad->webview);
485   }
486 }
487
488 Evas_Object* _create_button_bar(Evas_Object *parent , app_data *data)
489 {
490   Evas_Object *ic;
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);
494
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);
498
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);
503
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);
507
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);
512
513   data->refreshbtn=elm_button_add(data->button_box);
514   elm_box_pack_end(data->button_box, data->refreshbtn);
515
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);
521
522   data->stopbtn=elm_button_add(data->button_box);
523   elm_box_pack_end(data->button_box, data->stopbtn);
524
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);
530
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);
536
537
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);
544
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);
551
552
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);
558
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);
564
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);
570
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);
576
577   return data->button_box;
578 }
579
580 Evas_Object* _create_url_bar(Evas_Object *parent, int width, const char *start_url, app_data *data )
581 {
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);
588
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)
606   if (IsTvProfile()) {
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);
609   }
610 #endif
611   elm_entry_prediction_allow_set(data->url_entry, EINA_FALSE);
612 #ifdef OS_TIZEN
613   eext_object_event_callback_add(data->url_entry, EEXT_CALLBACK_BACK, _back_hard_key_cb, data);
614 #endif
615   // Add imf event
616   Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(data->url_entry);
617   if (imf_context) {
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);
623   }
624   evas_object_show(data->url_entry);
625
626   return data->url_box;
627 }
628
629 Evas_Object* _create_tool_bar(Evas_Object *parent, const char *start_url, app_data *data)
630 {
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;
634
635   int width, height;
636   evas_object_geometry_get (parent, NULL, NULL, &width, &height);
637
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
643
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);
648
649   url_box = _create_url_bar(data->tool_box, width, start_url, data);
650   button_box = _create_button_bar(data->tool_box, data);
651
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);
658
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);
663
664   return data->tool_box;
665 }
666
667 static void __br_rotate_cb(void *data, Evas_Object *obj, void *event)
668 {
669   if (!data)
670     return;
671
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);
676
677   // ewk_view_orientation_send expects angles: 0, 90, -90, 180.
678   if (changed_ang == 270)
679     changed_ang = -90;
680   ewk_view_orientation_send(ad->webview, changed_ang);
681
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);
685 }
686
687 static void _register_rotate_callback(Evas_Object *main_window, void *user_data)
688 {
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)));
692   }
693   evas_object_smart_callback_add(main_window, "wm,rotation,changed", __br_rotate_cb, user_data);
694 }
695
696 #if defined(OS_TIZEN)
697 static void _on_focus_in_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
698 {
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);
703   }
704 }
705 #endif
706
707 static bool __br_app_create(void *data)
708 {
709   setenv("ELM_ENGINE", "gl", 1);
710   elm_init(0, NULL);
711   if (!ewk_init()) {
712     LOGE("elm_init Failed. App not started");
713     return false;
714   }
715
716   app_data *ad = (app_data *) data;
717
718   ad->context = ewk_context_default_get();
719
720   ad->main_window = _create_main_window(ad);
721
722   // All ewk things go here
723   ad->e = evas_object_evas_get (ad->main_window);
724
725   // Create view and tool bar
726   _create_view(ad->main_window, ad);
727
728   _create_tool_bar(ad->main_window, start_url, ad);
729
730   // Add progress bar
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);
735
736   evas_object_show(ad->main_window);
737
738 #if defined(OS_TIZEN)
739   evas_object_event_callback_add(ad->webview, EVAS_CALLBACK_KEY_UP, _on_keyup_cb , ad);
740 #endif
741
742   if (IsMobileProfile() || IsWearableProfile()) {
743     evas_object_event_callback_add(ad->main_window, EVAS_CALLBACK_FOCUS_IN, _on_focus_in_cb, ad);
744   } else {
745     set_url_from_user_input(ad->webview, start_url);
746   }
747   _register_rotate_callback(ad->main_window, ad);
748   return true;
749 }
750 static void __br_app_terminate(void* data)
751 {
752   if (IsTvProfile()) {
753     curr_focus = NULL;
754     hide_imf_panel(data);
755   }
756 }
757
758 static void __br_app_pause(void* data)
759 {
760 }
761
762 static void __br_app_resume(void* data)
763 {
764 }
765
766 int main(int argc, char** argv)
767 {
768   LOGD(" Minibrowser main\n");
769
770   if (setenv("ELM_ENGINE","gl",1)==0)
771     LOGD("'ELM_ENGINE' has been set to 'gl' value.\n");
772
773   //FIXME: this is temporal code.
774   ewk_set_arguments(argc, argv);
775   elm_init(argc, argv);
776   elm_config_accel_preference_set("opengl");
777
778   Ecore_Getopt_Value values[] =
779   {
780     ECORE_GETOPT_VALUE_STR(start_url),
781     ECORE_GETOPT_VALUE_NONE,
782   };
783
784   printf("MINIB.C main \n");
785
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());
798   } else {
799     printf("Runtime Profile : UNKNOWN\n");
800   }
801
802   if (IsEmulatorArch()) {
803     printf("Runtime Architecture : Emulator(%d)\n", IsEmulatorArch());
804   }
805
806   if (ecore_getopt_parse(&options, values, argc, argv) < 0)
807   {
808     LOGE("ERROR: could not parse options.\n");
809     return EXIT_FAILURE;
810   }
811
812   ui_app_lifecycle_callback_s ops;
813
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;
819
820   app_data ad;
821   memset(&ad, 0x00, sizeof(app_data));
822
823   int ret = ui_app_main(argc, argv, &ops, &ad);
824
825   return ret;
826 }
827
828 void get_main_window_size(int *changed_ang, int *width, int *height)
829 {
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);
835 #else
836   ecore_wl_screen_size_get(width, height);
837 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
838 #else
839   switch (*changed_ang) {
840     case APP_DEVICE_ORIENTATION_0:
841       ecore_x_window_size_get(ecore_x_window_root_first_get(), width, height);
842       break;
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);
846       break;
847     default:
848       return;
849   }
850 #endif
851 }
852
853 void __load_started_cb(void *data, Evas_Object *obj, void *event_info)
854 {
855   LOGD("Start Loading \n");
856   app_data *ad = (app_data *) data;
857   evas_object_show(ad->progress_bar);
858 }
859
860 //To check SIP status
861 void __im_context_open_cb(void *data, Evas_Object *obj, void *event_info)
862 {
863   LOGD("IM_CONTEXT_EFL_ON \n");
864   im_context_status = 1;
865 }
866
867 void __im_context_close_cb(void *data, Evas_Object *obj, void *event_info)
868 {
869   LOGD("IM_CONTEXT_EFL_OFF \n");
870
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);
877
878     if (is_imf_shown) {
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);
882       is_imf_shown = 0;
883     }
884   }
885
886   im_context_status = 0;
887 }
888
889 #if defined(OS_TIZEN)
890 void _imf_panel_changed_cb(void *data, Evas_Object *obj, Eina_Rectangle *rect)
891 {
892   if (IsMobileProfile() || IsWearableProfile()) {
893     printf("__imf_panel_changed_cb\n");
894     LOGD("IM_CONTEXT_EFL_OFF \n");
895
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);
900
901     if (rect->h < TOOL_BOX_HEIGHT)
902       evas_object_resize(ad->webview, main_window_width, main_window_height - TOOL_BOX_HEIGHT);
903     else
904       evas_object_resize(ad->webview, main_window_width, main_window_height - rect->h);
905   }
906 }
907 #endif
908
909 void __load_progress_finished_cb(void *data, Evas_Object *obj, void *event_info)
910 {
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);
915 }
916
917 void __load_finished_cb(void *data, Evas_Object *obj, void *event_info)
918 {
919   LOGD("Load Done \n");
920 }
921
922 void __load_progress_cb(void *data, Evas_Object *obj, void *event_info)
923 {
924   LOGD("Progress = %f \n", *((double *)event_info));
925   app_data *ad = (app_data *) data;
926   int width;
927   evas_object_geometry_get (ad->main_window, NULL, NULL, &width, NULL);
928   evas_object_resize(ad->progress_bar, (*((double *)event_info))*width, 10);
929 }
930
931 void __load_error_cb(void *data, Evas_Object *obj, void *event_info)
932 {
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));
936
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 )
941   {
942     ewk_view_not_found_error_page_load(obj, ewk_error_url_get(error));
943   }
944 }
945
946 void __uri_changed_cb(void *data, Evas_Object *obj, void *event_info)
947 {
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);
951 }
952
953 void __title_changed_cb(void *data, Evas_Object *obj, void *event_info)
954 {
955   LOGD("Title is = %s \n", (const char *)event_info);
956 }
957
958 void __popup_close(app_data* ad)
959 {
960   if (ad->popup) {
961     evas_object_focus_set(ad->webview, EINA_TRUE);
962     evas_object_hide(ad->popup);
963     evas_object_del(ad->popup);
964     ad->popup = NULL;
965     eina_stringshare_del(ad->popup_url);
966     ad->popup_url = NULL;
967   }
968 }
969
970 void __popup_open_url_cb(void *data, Evas_Object *obj, void *event_info)
971 {
972   app_data* ad = (app_data*)data;
973   ewk_view_url_set(ad->webview, ad->popup_url);
974   __popup_close(ad);
975   evas_object_focus_set(ad->webview, EINA_TRUE);
976 }
977
978 void __popup_cancel_url_cb(void *data, Evas_Object *obj, void *event_info)
979 {
980   app_data* ad = (app_data*)data;
981   __popup_close(ad);
982   evas_object_focus_set(ad->webview, EINA_TRUE);
983 }
984
985 void __policy_newwindow_decide_cb(void *data, Evas_Object *obj, void *event_info)
986 {
987   app_data* ad = (app_data*)data;
988
989   if (ad->popup) {
990     __popup_close(ad);
991   }
992
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);
999   g_free(title);
1000
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);
1005
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);
1010
1011   ad->popup = popup;
1012   evas_object_show(popup);
1013 }
1014
1015 void _geol_ok_cb (void *data, Evas_Object *obj, void *event_info)
1016 {
1017   LOGD("geolocation permission granted");
1018   app_data* ad = (app_data*)data;
1019   ewk_geolocation_permission_request_set( ad->geolRequest, EINA_TRUE);
1020   __popup_close(ad);
1021 }
1022
1023
1024 void _geol_cancel_cb (void *data, Evas_Object *obj, void *event_info)
1025 {
1026   LOGD("geolocation restricted");
1027   app_data* ad = (app_data*)data;
1028   ewk_geolocation_permission_request_set( ad->geolRequest, EINA_FALSE);
1029   __popup_close(ad);
1030 }
1031
1032 void __geolocation_permission_request_cb(void *data, Evas_Object *obj, void *event_info)
1033 {
1034   LOGD("geolocation request recieved");
1035   app_data* ad = (app_data*)data;
1036
1037   if (ad->popup) {
1038     __popup_close(ad);
1039   }
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;
1045
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?");
1048
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);
1053
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);
1058   ad->popup = popup;
1059   evas_object_show(popup);
1060 }
1061
1062 // Callback for Allow button press for media request
1063 void _usermedia_ok_cb (void *data, Evas_Object *obj, void *event_info)
1064 {
1065   app_data* ad = (app_data*)data;
1066   ewk_user_media_permission_request_set(ad->userMediaRequest,EINA_TRUE);
1067     __popup_close(ad);
1068 }
1069
1070 // Callback for Deny button press for media request
1071 void _usermedia_cancel_cb (void *data, Evas_Object *obj, void *event_info)
1072 {
1073   app_data* ad = (app_data*)data;
1074   ewk_user_media_permission_request_set(ad->userMediaRequest,EINA_FALSE);
1075   __popup_close(ad);
1076 }
1077
1078 // Callback for showing permission request for media request
1079 void __usermedia_permission_request_cb(void *data, Evas_Object *obj, void *event_info)
1080 {
1081   app_data* ad = (app_data*)data;
1082   if (ad->popup) {
1083     __popup_close(ad);
1084   }
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);
1089
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?");
1094
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);
1099
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);
1104   ad->popup = popup;
1105   evas_object_show(popup);
1106 }
1107
1108 void url_hit_cb(void *data, Evas_Object *obj, void *event_info)
1109 {
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);
1114   hide_imf_panel(ad);
1115   evas_object_focus_set(ad->webview, EINA_TRUE);
1116 }
1117
1118 void find_hit_cb(void *data, Evas_Object *obj, void *event_info)
1119 {
1120   LOGD("Find word\n");
1121   app_data *ad = (app_data*) data;
1122   mini_find_word("google", EINA_TRUE,  __text_found_cb, data);
1123   hide_imf_panel(ad);
1124 }
1125
1126 void clear_hit_cb(void *data, Evas_Object *obj, void *event_info)
1127 {
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;
1132   hide_imf_panel(ad);
1133 }
1134
1135 void zoomin_hit_cb(void *data, Evas_Object *obj, void *event_info)
1136 {
1137   app_data *ad = (app_data*)data;
1138   LOGD("Zoom in\n");
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);
1144   }
1145   hide_imf_panel(ad);
1146 }
1147
1148 void zoomout_hit_cb(void *data, Evas_Object *obj, void *event_info)
1149 {
1150   app_data *ad = (app_data*)data;
1151   LOGD("Zoom out\n");
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);
1157   }
1158   hide_imf_panel(ad);
1159 }
1160
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
1164  */
1165 void _url_clicked_cb(void *data, Evas_Object *obj, void *event_info)
1166 {
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);
1174     if (imf_context)
1175     {
1176       if (!is_imf_shown && ecore_imf_context_input_panel_state_get(imf_context) != ECORE_IMF_INPUT_PANEL_STATE_SHOW)
1177       {
1178         is_imf_shown = 1;
1179         int x, y, w, h;
1180         int width, height;
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);
1188       }
1189     }
1190   }
1191 }
1192 #endif
1193
1194 void _imf_panel_state_cb (void *data, Ecore_IMF_Context *ctx, int value)
1195 {
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)
1200   {
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);
1206     is_imf_shown = 1;
1207   }
1208   else if (value == ECORE_IMF_INPUT_PANEL_STATE_HIDE)
1209   {
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);
1214     if (is_imf_shown) {
1215       elm_object_focus_set(ad->url_entry, EINA_FALSE);
1216       is_imf_shown = 0;
1217     }
1218   }
1219 }
1220
1221 void hide_imf_panel(app_data* data)
1222 {
1223   if (IsTvProfile()) {
1224     /* On SIP close, Toolbar bring back to original position*/
1225     if (is_imf_shown) {
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);
1231 #else
1232       ecore_wl_screen_size_get(&width, &height);
1233 #endif  // TIZEN_VERSION_AT_LEAST(5, 0, 0)
1234 #else
1235       ecore_x_window_size_get(ecore_x_window_root_first_get(), &width, &height);
1236 #endif
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);
1244       is_imf_shown = 0;
1245     }
1246   } else {
1247     elm_object_focus_set(data->url_entry, EINA_FALSE);
1248     elm_entry_input_panel_hide(data->url_entry);
1249     is_imf_shown = 0;
1250   }
1251 }
1252
1253 void _back_btn_cb(void *data, Evas_Object *btn, void *ev)
1254 {
1255   LOGD("Previous Page\n");
1256   app_data *ad = (app_data*) data;
1257   ewk_view_back(ad->webview);
1258   hide_imf_panel(ad);
1259 }
1260
1261 void _trace_start_btn_cb(void *data,Evas_Object *btn,void *ev)
1262 {
1263   ewk_start_tracing("*, disabled-by-default-toplevel.flow", "", "");
1264 }
1265
1266 void _trace_stop_btn_cb(void *data,Evas_Object *btn,void *ev)
1267 {
1268   ewk_stop_tracing();
1269 }
1270
1271 void _next_btn_cb(void *data, Evas_Object *btn, void *ev)
1272 {
1273   LOGD("Next Page\n");
1274   app_data *ad = (app_data*) data;
1275   ewk_view_forward(ad->webview);
1276   hide_imf_panel(ad);
1277 }
1278
1279 void _reload_btn_cb(void *data, Evas_Object *btn, void *ev)
1280 {
1281   LOGD("Reoading\n");
1282   app_data *ad = (app_data*) data;
1283   ewk_view_reload(ad->webview);
1284   hide_imf_panel(ad);
1285 }
1286
1287 #if defined(OS_TIZEN)
1288 void _on_keyup_cb(void *data, Evas *e, Evas_Object *btn, void *event_info)
1289 {
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)
1294     return;
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);
1298 }
1299
1300 void _screenshot_captured_cb(Evas_Object* image, void* user_data)
1301 {
1302   static int c = 1;
1303   char buf[250];
1304   sprintf(buf, "/opt/usr/media/Downloads/screenshot%d.png", c++);
1305   evas_object_image_save(image, buf, NULL, NULL);
1306 }
1307 #endif
1308
1309 void _stop_btn_cb(void *data, Evas_Object *btn, void *ev)
1310 {
1311   LOGD("Stopping\n");
1312   app_data *ad = (app_data*) data;
1313   ewk_view_stop(ad->webview);
1314   hide_imf_panel(ad);
1315 }
1316
1317 void __policy_response_decide_cb(void *data, Evas_Object *obj, void *ev)
1318 {
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);
1330 }
1331
1332 void __navigation_policy_decide_cb(void *data, Evas_Object *obj, void *ev)
1333 {
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));
1338   // we only set USE
1339   // download needs to be handled and ignore wont have any visible difference.
1340   LOGD("Decision: USE\n");
1341   ewk_policy_decision_use(decision);
1342 }
1343
1344 #ifdef OS_TIZEN
1345 void _back_hard_key_cb(void *data, Evas_Object *btn, void *ev)
1346 {
1347   app_data *ad = (app_data*) data;
1348
1349   if (ad->popup) {
1350     __popup_close(ad);
1351     return;
1352   }
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
1358      */
1359     hide_imf_panel(ad);
1360   } else {
1361     if (is_imf_shown)
1362       evas_object_focus_set(ad->webview, EINA_TRUE);
1363   }
1364 }
1365 #endif
1366
1367
1368 context_menu_type get_menu_type(app_data *data, Ewk_Context_Menu *menu)
1369 {
1370   //RETV_MSG_IF(!menu, UNKNOWN_MENU, "menu is NULL");
1371
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;
1379
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);
1386
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)
1394       return INPUT_FIELD;
1395     if (tag == EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB)
1396       text = EINA_TRUE;
1397     if (tag == EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW)
1398       link = EINA_TRUE;
1399     if (tag == EWK_CONTEXT_MENU_ITEM_TAG_COPY_IMAGE_TO_CLIPBOARD)
1400       image = EINA_TRUE;
1401   }
1402
1403   if (email_address && selection_mode)
1404           return EMAIL_SCHEME;
1405   if (call_number && selection_mode)
1406           return TEL_SCHEME;
1407   if (text && !link)
1408           return TEXT_ONLY;
1409   if (link && !image)
1410           return TEXT_LINK;
1411   if (image && !link)
1412           return IMAGE_ONLY;
1413   if (image && link)
1414           return IMAGE_LINK;
1415
1416   return UNKNOWN_MENU;
1417 }
1418
1419
1420 void __customize_context_menu_cb(void *data, Evas_Object *obj, void *event_info)
1421 {
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);
1425
1426   if (menu_type == UNKNOWN_MENU || menu_type == INPUT_FIELD)
1427     return;
1428
1429   switch (menu_type) {
1430     case TEXT_ONLY:
1431       show_context_menu_text_only(ad, menu);
1432     break;
1433
1434     case TEXT_LINK:
1435       show_context_menu_text_link(ad, menu);
1436     break;
1437
1438     case IMAGE_ONLY:
1439       show_context_menu_image_only(ad, menu);
1440     break;
1441
1442     case IMAGE_LINK:
1443       show_context_menu_image_link(ad, menu);
1444     break;
1445
1446     case EMAIL_SCHEME:
1447       show_context_menu_email_address(ad, menu);
1448     break;
1449
1450     case TEL_SCHEME:
1451       show_context_menu_call_number(ad, menu);
1452     break;
1453
1454     default:
1455       return;
1456     break;
1457   }
1458 }
1459
1460 void __customize_context_menu_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
1461 {
1462   Ewk_Context_Menu_Item* item = (Ewk_Context_Menu_Item*)event_info;
1463
1464   switch (ewk_context_menu_item_tag_get(item)) {
1465     case EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW:
1466       break;
1467     default:
1468       break;
1469   }
1470 }
1471
1472 void show_context_menu_text_only(app_data *data, Ewk_Context_Menu *menu)
1473 {
1474   unsigned short count = ewk_context_menu_item_count(menu);
1475   //RET_MSG_IF(count == 0, "There is no context menu for text only");
1476
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;
1482
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");
1486
1487   memset(original_ctx_item, 0x00, sizeof(Ewk_Context_Menu_Item_Tag) * count);
1488
1489   unsigned short i=0;
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);
1493
1494     original_ctx_item[i] = tag;
1495     ewk_context_menu_item_remove(menu, item);
1496   }
1497
1498   /* Select all */
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);
1502             break;
1503     }
1504   }
1505
1506   /* Copy */
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);
1511                     break;
1512             }
1513     }
1514   }
1515
1516   /*
1517   // Share
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);
1520
1521
1522   // Search
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);
1527                     break;
1528             }
1529     }
1530   }
1531
1532   // Translator
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);
1537                     break;
1538             }
1539     }
1540   }
1541   */
1542
1543   free(original_ctx_item);
1544 }
1545
1546 void show_context_menu_text_link(app_data *data, Ewk_Context_Menu *menu)
1547 {
1548   /*
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);
1558   */
1559
1560 }
1561
1562 void show_context_menu_image_only(app_data *data, Ewk_Context_Menu *menu)
1563 {
1564
1565
1566 }
1567
1568 void show_context_menu_image_link(app_data *data, Ewk_Context_Menu *menu)
1569 {
1570
1571 }
1572
1573 void show_context_menu_email_address(app_data *data, Ewk_Context_Menu *menu)
1574 {
1575 }
1576
1577 void show_context_menu_call_number(app_data *data, Ewk_Context_Menu *menu)
1578 {
1579 }
1580
1581
1582 void enable_customize_contextmenu(app_data *data, Eina_Bool enable)
1583 {
1584   if (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);
1587   } else {
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);
1590   }
1591 }
1592
1593 //  Added to Support Javascript popup
1594 Eina_Bool __javascript_alert_cb(Evas_Object* o, const char* alert_text, void* user_data)
1595 {
1596   return EINA_TRUE;
1597 }
1598
1599 Eina_Bool __javascript_confirm_cb(Evas_Object* o, const char* message, void* user_data)
1600 {
1601   return EINA_TRUE;
1602 }
1603
1604 Eina_Bool __javascript_prompt_cb(Evas_Object* o, const char* message, const char* default_value, void* user_data)
1605 {
1606   return EINA_TRUE;
1607 }
1608
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)
1613 {
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;
1620     }
1621
1622     return ECORE_CALLBACK_CANCEL;
1623   } else {
1624     return EINA_TRUE;
1625   }
1626 }
1627
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)
1631 {
1632   printf("[%s][%d][%s] called\n", __FUNCTION__, __LINE__, "vibration");
1633   uint64_t duration = vibration_time;
1634
1635   if (s_haptic_timer_id) {
1636     ecore_timer_del(s_haptic_timer_id);
1637     s_haptic_timer_id = NULL;
1638   }
1639
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;
1644   }
1645
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");
1648     return;
1649   }
1650
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);
1654
1655   s_haptic_timer_id = ecore_timer_add(in, __vibration_timeout_cb, NULL);
1656 }
1657
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)
1661 {
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;
1666   }
1667
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;
1672   }
1673 }
1674 #endif // #if caluse of #if defined(OS_TIZEN)...
1675
1676 void mini_find_word(const char *word, Eina_Bool forward, Evas_Smart_Cb found_cb, void *data)
1677 {
1678   app_data *ad = (app_data*) data;
1679
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);
1682
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);
1687
1688   if (!forward)
1689     find_option = (Ewk_Find_Options)(find_option | EWK_FIND_OPTIONS_BACKWARDS);
1690
1691   ewk_view_text_find(ad->webview, word, find_option, 10000);
1692 }
1693
1694 void mini_find_word_clear(void *data)
1695 {
1696   app_data *ad = (app_data*) data;
1697   ewk_view_text_find_highlight_clear(ad->webview);
1698 }
1699
1700 void __text_found_cb(void *data, Evas_Object *obj, void *event_info)
1701 {
1702   printf("text found : %u\n", *((unsigned int*)(event_info)));
1703 }