[access] call a callback function with information
[framework/uifw/elementary.git] / src / lib / elm_web.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_web.h"
4
5 // TODO:
6 //  1 - easy to use zoom like elm_photocam API
7 //  2 - review scrolling to match elm_scroller. Maybe in future use
8 //  elm_interface_scroller
9
10 #if !defined(HAVE_ELEMENTARY_WEB) || !defined(USE_WEBKIT2)
11
12 #ifdef HAVE_ELEMENTARY_WEB
13 #include <EWebKit.h>
14
15 /* Similar to iPhone */
16 // TODO: switch between iPhone, iPad or Chrome/Safari based on some
17 // elm setting?
18
19 #define ELM_WEB_USER_AGENT                                          \
20   "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en)"                  \
21   " AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a" \
22   " Safari/419.3 " PACKAGE_NAME "/" PACKAGE_VERSION
23 #endif
24
25 EAPI const char ELM_WEB_SMART_NAME[] = "elm_web";
26
27 #ifdef HAVE_ELEMENTARY_WEB
28 static Ewk_View_Smart_Class _ewk_view_parent_sc =
29   EWK_VIEW_SMART_CLASS_INIT_NULL;
30
31 #endif
32
33 static const Evas_Smart_Cb_Description _elm_web_smart_callbacks[] = {
34    { "download,request", "p" },
35    { "editorclient,contents,changed", "" },
36    { "editorclient,selection,changed", "" },
37    { "frame,created", "p" },
38    { "icon,received", "" },
39    { "inputmethod,changed", "b" },
40    { "js,windowobject,clear", "" },
41    { "link,hover,in", "p" },
42    { "link,hover,out", "" },
43    { "load,document,finished", "p" },
44    { "load,error", "p" },
45    { "load,finished", "p" },
46    { "load,newwindow,show", "" },
47    { "load,progress", "d" },
48    { "load,provisional", "" },
49    { "load,started", "" },
50    { "menubar,visible,get", "b" },
51    { "menubar,visible,set", "b" },
52    { "popup,created", "p" },
53    { "popup,willdelete", "p" },
54    { "ready", "" },
55    { "scrollbars,visible,get", "b" },
56    { "scrollbars,visible,set", "b" },
57    { "statusbar,text,set", "s" },
58    { "statusbar,visible,get", "b" },
59    { "statusbar,visible,set", "b" },
60    { "title,changed", "s" },
61    { "toolbars,visible,get", "b" },
62    { "toolbars,visible,set", "b" },
63    { "tooltip,text,set", "s" },
64    { "uri,changed", "s" },
65    { "view,resized", "" },
66    { "windows,close,request", ""},
67    { "zoom,animated,end", "" },
68    { NULL, NULL }
69 };
70
71 EVAS_SMART_SUBCLASS_NEW
72   (ELM_WEB_SMART_NAME, _elm_web, Elm_Web_Smart_Class, Elm_Widget_Smart_Class,
73   elm_widget_smart_class_get, _elm_web_smart_callbacks);
74
75 #ifdef HAVE_ELEMENTARY_WEB
76 static char *
77 _webkit_theme_find(const Eina_List *list)
78 {
79    const Eina_List *l;
80    const char *th;
81
82    EINA_LIST_FOREACH(list, l, th)
83      {
84         char *path = elm_theme_list_item_path_get(th, NULL);
85
86         if (!path) continue;
87
88         if (edje_file_group_exists(path, "webkit/base")) return path;
89
90         free(path);
91      }
92
93    return NULL;
94 }
95
96 #endif
97
98 static Eina_Bool
99 _elm_web_smart_theme(Evas_Object *obj)
100 {
101 #ifdef HAVE_ELEMENTARY_WEB
102    Elm_Theme *theme;
103    const Eina_List *themes;
104    char *view_theme = NULL;
105
106    ELM_WEB_DATA_GET(obj, sd);
107
108    if (!_elm_web_parent_sc->theme(obj)) return EINA_FALSE;
109
110    theme = elm_object_theme_get(obj);
111    themes = elm_theme_overlay_list_get(theme);
112    view_theme = _webkit_theme_find(themes);
113    if (view_theme) goto set;
114
115    themes = elm_theme_list_get(theme);
116    view_theme = _webkit_theme_find(themes);
117    if (view_theme) goto set;
118
119    themes = elm_theme_extension_list_get(theme);
120    view_theme = _webkit_theme_find(themes);
121
122 set:
123    if (view_theme)
124      {
125         ewk_view_theme_set(ELM_WIDGET_DATA(sd)->resize_obj, view_theme);
126         free(view_theme);
127      }
128    else
129      ewk_view_theme_set
130        (ELM_WIDGET_DATA(sd)->resize_obj, WEBKIT_DATADIR "/themes/default.edj");
131 #endif
132
133    (void)obj;
134
135    return EINA_TRUE;
136 }
137
138 static Eina_Bool
139 _elm_web_smart_on_focus(Evas_Object *obj)
140 {
141 #ifdef HAVE_ELEMENTARY_WEB
142    Evas_Object *top;
143
144    ELM_WEB_DATA_GET(obj, sd);
145
146    top = elm_widget_top_get(obj);
147
148    if (elm_object_focus_get(obj))
149      {
150         evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_TRUE);
151         if (top) elm_win_keyboard_mode_set(top, sd->input_method);
152      }
153    else
154      {
155         evas_object_focus_set(ELM_WIDGET_DATA(sd)->resize_obj, EINA_FALSE);
156         if (top) elm_win_keyboard_mode_set(top, ELM_WIN_KEYBOARD_OFF);
157      }
158 #else
159    (void)obj;
160 #endif
161
162    return EINA_TRUE;
163 }
164
165 static Eina_Bool
166 _elm_web_smart_event(Evas_Object *obj,
167                      Evas_Object *src __UNUSED__,
168                      Evas_Callback_Type type,
169                      void *event_info)
170 {
171 #ifdef HAVE_ELEMENTARY_WEB
172    Evas_Event_Key_Down *ev = event_info;
173
174    ELM_WEB_DATA_GET(obj, sd);
175
176    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
177    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
178    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
179
180    if ((!strcmp(ev->keyname, "Tab")) && (!sd->tab_propagate))
181      {
182         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
183         return EINA_TRUE;
184      }
185    else return EINA_FALSE;
186 #else
187    (void)obj;
188    (void)type;
189    (void)event_info;
190
191    return EINA_FALSE;
192 #endif
193 }
194
195 #ifdef HAVE_ELEMENTARY_WEB
196 static Eina_Bool
197 _view_pan_animator(void *data)
198 {
199    View_Smart_Data *sd = data;
200    Evas_Coord x, y, dx, dy;
201
202    evas_pointer_canvas_xy_get(sd->base.base.evas, &x, &y);
203
204    dx = sd->mouse.x - x;
205    dy = sd->mouse.y - y;
206
207    if ((dx == 0) && (dy == 0))
208      goto end;
209
210    ewk_frame_scroll_add(sd->base.main_frame, dx, dy);
211
212    sd->mouse.x = x;
213    sd->mouse.y = y;
214
215 end:
216    return EINA_TRUE;
217 }
218
219 static void
220 _view_smart_add(Evas_Object *obj)
221 {
222    View_Smart_Data *sd;
223
224    sd = calloc(1, sizeof(View_Smart_Data));
225    evas_object_smart_data_set(obj, sd);
226
227    _ewk_view_parent_sc.sc.add(obj);
228
229    ewk_view_history_enable_set(obj, EINA_TRUE);
230    ewk_history_limit_set(ewk_view_history_get(obj), 100);
231
232    // TODO: auto toggle between smooth/nearest during bring-in animations
233    //ewk_view_zoom_weak_smooth_scale_set(obj, EINA_TRUE);
234 }
235
236 static void
237 _view_smart_del(Evas_Object *obj)
238 {
239    View_Smart_Data *sd;
240
241    sd = evas_object_smart_data_get(obj);
242
243    if (sd->mouse.pan_anim)
244      ecore_animator_del(sd->mouse.pan_anim);
245
246    _ewk_view_parent_sc.sc.del(obj);
247 }
248
249 static Eina_Bool
250 _view_longpress_timer(void *data)
251 {
252    View_Smart_Data *sd = data;
253
254    sd->mouse.move_count = 0;
255    sd->mouse.longpress_timer = NULL;
256
257    return ECORE_CALLBACK_CANCEL;
258 }
259
260 static Eina_Bool
261 _view_smart_mouse_down(Ewk_View_Smart_Data *esd,
262                        const Evas_Event_Mouse_Down *event)
263 {
264    // TODO: mimic elm_scroller and like
265    // TODO-minor: offer hook?
266    View_Smart_Data *sd = (View_Smart_Data *)esd;
267
268    if (event->button != 1)
269      return _ewk_view_parent_sc.mouse_down(esd, event);
270
271    sd->mouse.pan_anim = ecore_animator_add(_view_pan_animator, sd);
272    sd->mouse.longpress_timer = ecore_timer_add
273        (_elm_config->longpress_timeout, _view_longpress_timer, sd);
274    sd->mouse.move_count = 1;
275    sd->mouse.x = event->canvas.x;
276    sd->mouse.y = event->canvas.y;
277    sd->mouse.event = *event;
278
279    return EINA_TRUE;
280 }
281
282 static Eina_Bool
283 _view_smart_mouse_up(Ewk_View_Smart_Data *esd,
284                      const Evas_Event_Mouse_Up *event)
285 {
286    // TODO: mimic elm_scroller and like
287    // TODO-minor: offer hook?
288    View_Smart_Data *sd = (View_Smart_Data *)esd;
289
290    if (sd->mouse.pan_anim)
291      {
292         ecore_animator_del(sd->mouse.pan_anim);
293         sd->mouse.pan_anim = NULL;
294
295         if (sd->mouse.longpress_timer)
296           _ewk_view_parent_sc.mouse_down(esd, &sd->mouse.event);
297         else
298           return EINA_TRUE;
299      }
300
301    if (sd->mouse.longpress_timer)
302      {
303         ecore_timer_del(sd->mouse.longpress_timer);
304         sd->mouse.longpress_timer = NULL;
305      }
306
307    sd->mouse.move_count = 0;
308    return _ewk_view_parent_sc.mouse_up(esd, event);
309 }
310
311 static Eina_Bool
312 _view_smart_mouse_move(Ewk_View_Smart_Data *esd,
313                        const Evas_Event_Mouse_Move *event)
314 {
315    // TODO: mimic elm_scroller and like
316    // TODO-minor: offer hook?
317    View_Smart_Data *sd = (View_Smart_Data *)esd;
318
319    sd->mouse.move_count++;
320
321    if (sd->mouse.longpress_timer &&
322        (((sd->mouse.x ^ sd->mouse.event.canvas.x) |
323          (sd->mouse.y ^ sd->mouse.event.canvas.y)) & (~0x07)))
324      {
325         ecore_timer_del(sd->mouse.longpress_timer);
326         sd->mouse.longpress_timer = NULL;
327      }
328
329    if (sd->mouse.pan_anim)
330      {
331         return EINA_FALSE;
332      }
333
334    return _ewk_view_parent_sc.mouse_move(esd, event);
335 }
336
337 static Evas_Object *
338 _view_smart_window_create(Ewk_View_Smart_Data *vsd,
339                           Eina_Bool javascript,
340                           const Ewk_Window_Features *window_features)
341 {
342    Evas_Object *new;
343    Evas_Object *obj = evas_object_smart_parent_get(vsd->self);
344
345    ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
346
347    if (!sd->hook.window_create) return NULL;
348
349    new = sd->hook.window_create
350        (sd->hook.window_create_data, obj, javascript,
351        (const Elm_Web_Window_Features *)window_features);
352    if (new) return elm_web_webkit_view_get(new);
353
354    return NULL;
355 }
356
357 static void
358 _view_smart_window_close(Ewk_View_Smart_Data *sd)
359 {
360    Evas_Object *obj = evas_object_smart_parent_get(sd->self);
361
362    ELM_WEB_CHECK(obj);
363
364    evas_object_smart_callback_call(obj, "windows,close,request", NULL);
365 }
366
367 static void
368 _bt_close(void *data,
369           Evas_Object *obj,
370           void *event_info __UNUSED__)
371 {
372    Dialog_Data *d = data;
373
374    *d->response = (obj == d->bt_ok);
375    if ((d->type == DIALOG_PROMPT) && (*d->response == EINA_TRUE))
376      *d->entry_value = strdup(elm_entry_entry_get(d->entry));
377
378    evas_object_del(d->dialog);
379 }
380
381 static void
382 _file_sel_done(void *data,
383                Evas_Object *obj __UNUSED__,
384                void *event_info)
385 {
386    Dialog_Data *d = data;
387
388    if (event_info)
389      {
390         *d->selected_files = eina_list_append(NULL, strdup(event_info));
391         *d->response = EINA_TRUE;
392      }
393    else *d->response = EINA_FALSE;
394
395    evas_object_del(d->dialog);
396    free(d);
397 }
398
399 static Dialog_Data *
400 _dialog_new(Evas_Object *parent)
401 {
402    Dialog_Data *d;
403
404    ELM_WEB_DATA_GET(parent, sd);
405
406    d = calloc(1, sizeof(Dialog_Data));
407    if (!d) return NULL;
408
409    if (!parent || !sd->inwin_mode)
410      {
411         Evas_Object *bg;
412
413         d->dialog = elm_win_add(NULL, "elm-web-popup", ELM_WIN_DIALOG_BASIC);
414         evas_object_smart_callback_add
415           (d->dialog, "delete,request", _bt_close, d);
416
417         bg = elm_bg_add(d->dialog);
418         evas_object_size_hint_weight_set
419           (bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
420         elm_win_resize_object_add(d->dialog, bg);
421         evas_object_show(bg);
422
423         d->box = elm_box_add(d->dialog);
424         evas_object_size_hint_weight_set
425           (d->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
426         elm_win_resize_object_add(d->dialog, d->box);
427         evas_object_show(d->box);
428      }
429    else
430      {
431         Evas_Object *win = elm_widget_top_get(parent);
432
433         d->dialog = elm_win_inwin_add(win);
434         elm_object_style_set(d->dialog, "minimal");
435         evas_object_size_hint_weight_set
436           (d->dialog, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
437
438         d->box = elm_box_add(win);
439         evas_object_size_hint_weight_set
440           (d->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
441         elm_win_inwin_content_set(d->dialog, d->box);
442         evas_object_show(d->box);
443      }
444
445    return d;
446 }
447
448 static Evas_Object *
449 _run_dialog(Evas_Object *parent,
450             enum Dialog_Type type,
451             const char *message,
452             const char *default_entry_value,
453             const char **entry_value,
454             Eina_Bool allows_multiple_files __UNUSED__,
455             Eina_List *accept_types __UNUSED__,
456             Eina_List **selected_filenames,
457             Eina_Bool *response)
458 {
459    Evas_Object *lb;
460    Evas_Object *obj;
461    Dialog_Data *dialog_data;
462
463    EINA_SAFETY_ON_TRUE_RETURN_VAL
464      ((type != DIALOG_PROMPT) && (!!default_entry_value), EINA_FALSE);
465    EINA_SAFETY_ON_TRUE_RETURN_VAL
466      ((type != DIALOG_PROMPT) && (!!entry_value), EINA_FALSE);
467
468    obj = evas_object_smart_parent_get(parent);
469
470    ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, NULL);
471
472    dialog_data = _dialog_new(obj);
473
474    if (type != DIALOG_FILE_SELECTOR)
475      {
476         lb = elm_label_add(dialog_data->box);
477         elm_object_text_set(lb, message);
478         elm_box_pack_end(dialog_data->box, lb);
479         evas_object_show(lb);
480      }
481
482    dialog_data->type = type;
483    dialog_data->response = response;
484    dialog_data->entry_value = entry_value;
485    dialog_data->selected_files = selected_filenames;
486
487    if (type == DIALOG_ALERT)
488      {
489         dialog_data->bt_ok = elm_button_add(dialog_data->box);
490         elm_object_text_set(dialog_data->bt_ok, "Close");
491         elm_box_pack_end(dialog_data->box, dialog_data->bt_ok);
492         evas_object_size_hint_align_set
493           (dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL);
494         evas_object_smart_callback_add
495           (dialog_data->bt_ok, "clicked", _bt_close, dialog_data);
496         evas_object_show(dialog_data->bt_ok);
497      }
498    else if (type == DIALOG_FILE_SELECTOR)
499      {
500         dialog_data->file_sel = elm_fileselector_add(dialog_data->dialog);
501         evas_object_size_hint_weight_set(dialog_data->file_sel,
502                                          EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
503         evas_object_size_hint_align_set(dialog_data->file_sel, EVAS_HINT_FILL,
504                                         EVAS_HINT_FILL);
505         elm_box_pack_end(dialog_data->box, dialog_data->file_sel);
506         evas_object_show(dialog_data->file_sel);
507
508         elm_fileselector_path_set(dialog_data->file_sel, ".");
509         elm_fileselector_is_save_set(dialog_data->file_sel, EINA_FALSE);
510         elm_fileselector_folder_only_set(dialog_data->file_sel, EINA_FALSE);
511         elm_fileselector_buttons_ok_cancel_set(dialog_data->file_sel,
512                                                EINA_TRUE);
513         elm_fileselector_expandable_set(dialog_data->file_sel, EINA_FALSE);
514         evas_object_smart_callback_add(dialog_data->file_sel, "done",
515                                        _file_sel_done, dialog_data);
516         // fileselector can't set it's minimum size correctly
517         evas_object_size_hint_min_set(dialog_data->file_sel, 300, 400);
518      }
519    else
520      {
521         if (type == DIALOG_PROMPT)
522           {
523              dialog_data->entry = elm_entry_add(dialog_data->box);
524              elm_entry_single_line_set(dialog_data->entry, EINA_TRUE);
525              elm_entry_scrollable_set(dialog_data->entry, EINA_TRUE);
526              elm_entry_entry_set(dialog_data->entry, default_entry_value);
527              evas_object_size_hint_align_set
528                (dialog_data->entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
529              evas_object_size_hint_weight_set
530                (dialog_data->entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
531              elm_box_pack_end(dialog_data->box, dialog_data->entry);
532              evas_object_show(dialog_data->entry);
533           }
534
535         if (type == DIALOG_PROMPT || type == DIALOG_CONFIRM)
536           {
537              Evas_Object *bx_h = elm_box_add(dialog_data->box);
538              elm_box_horizontal_set(bx_h, 1);
539              elm_box_pack_end(dialog_data->box, bx_h);
540              evas_object_size_hint_weight_set
541                (bx_h, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
542              evas_object_size_hint_align_set
543                (bx_h, EVAS_HINT_FILL, EVAS_HINT_FILL);
544              evas_object_show(bx_h);
545
546              dialog_data->bt_cancel = elm_button_add(bx_h);
547              elm_object_text_set(dialog_data->bt_cancel, "Cancel");
548              elm_box_pack_end(bx_h, dialog_data->bt_cancel);
549              evas_object_size_hint_weight_set
550                (dialog_data->bt_cancel, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
551              evas_object_size_hint_align_set
552                (dialog_data->bt_cancel, EVAS_HINT_FILL, EVAS_HINT_FILL);
553              evas_object_smart_callback_add
554                (dialog_data->bt_cancel, "clicked", _bt_close, dialog_data);
555              evas_object_show(dialog_data->bt_cancel);
556
557              dialog_data->bt_ok = elm_button_add(bx_h);
558              elm_object_text_set(dialog_data->bt_ok, "Ok");
559              elm_box_pack_end(bx_h, dialog_data->bt_ok);
560              evas_object_size_hint_weight_set
561                (dialog_data->bt_ok, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
562              evas_object_size_hint_align_set
563                (dialog_data->bt_ok, EVAS_HINT_FILL, EVAS_HINT_FILL);
564              evas_object_smart_callback_add
565                (dialog_data->bt_ok, "clicked", _bt_close, dialog_data);
566              evas_object_show(dialog_data->bt_ok);
567           }
568         else return EINA_FALSE;
569      }
570
571    evas_object_show(dialog_data->dialog);
572
573    return dialog_data->dialog;
574 }
575
576 static void
577 _dialog_del_cb(void *data __UNUSED__,
578                Evas *e __UNUSED__,
579                Evas_Object *obj __UNUSED__,
580                void *event_info __UNUSED__)
581 {
582    ecore_main_loop_quit();
583 }
584
585 static void
586 _exec_dialog(Evas_Object *dialog)
587 {
588    evas_object_event_callback_add
589      (dialog, EVAS_CALLBACK_DEL, _dialog_del_cb, NULL);
590    ecore_main_loop_begin();
591 }
592
593 /*
594  * called by ewk_view when javascript called alert()
595  */
596 static void
597 _view_smart_run_javascript_alert(Ewk_View_Smart_Data *esd,
598                                  Evas_Object *frame __UNUSED__,
599                                  const char *message)
600 {
601    View_Smart_Data *vsd = (View_Smart_Data *)esd;
602    Evas_Object *view = vsd->base.self;
603    Evas_Object *obj = evas_object_smart_parent_get(view);
604    Evas_Object *diag = NULL;
605    Eina_Bool response = EINA_FALSE;
606
607    ELM_WEB_DATA_GET_OR_RETURN(obj, sd);
608
609    if (sd->hook.alert)
610      diag = sd->hook.alert(sd->hook.alert_data, obj, message);
611    else
612      diag = _run_dialog(view, DIALOG_ALERT, message, NULL, NULL, EINA_FALSE,
613                         NULL, NULL, &response);
614    if (diag) _exec_dialog(diag);
615 }
616
617 /*
618  * called by ewk_view when javascript called confirm()
619  */
620 static Eina_Bool
621 _view_smart_run_javascript_confirm(Ewk_View_Smart_Data *esd,
622                                    Evas_Object *frame __UNUSED__,
623                                    const char *message)
624 {
625    View_Smart_Data *vsd = (View_Smart_Data *)esd;
626    Evas_Object *view = vsd->base.self;
627    Evas_Object *obj = evas_object_smart_parent_get(view);
628    Evas_Object *diag = NULL;
629    Eina_Bool response = EINA_FALSE;
630
631    ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
632
633    if (sd->hook.confirm)
634      diag = sd->hook.confirm(sd->hook.confirm_data, obj, message, &response);
635    else
636      diag = _run_dialog(view, DIALOG_CONFIRM, message, NULL, NULL, EINA_FALSE,
637                         NULL, NULL, &response);
638    if (diag) _exec_dialog(diag);
639    return response;
640 }
641
642 /*
643  * called by ewk_view when javascript called confirm()
644  */
645 static Eina_Bool
646 _view_smart_run_javascript_prompt(Ewk_View_Smart_Data *esd,
647                                   Evas_Object *frame __UNUSED__,
648                                   const char *message,
649                                   const char *default_value,
650                                   const char **value)
651 {
652    View_Smart_Data *vsd = (View_Smart_Data *)esd;
653    Evas_Object *view = vsd->base.self;
654    Evas_Object *obj = evas_object_smart_parent_get(view);
655    Evas_Object *diag = NULL;
656    Eina_Bool response = EINA_FALSE;
657
658    ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
659
660    if (sd->hook.prompt)
661      diag = sd->hook.prompt(sd->hook.prompt_data, obj, message, default_value,
662                             value, &response);
663    else
664      diag = _run_dialog(view, DIALOG_PROMPT, message, default_value, value,
665                         EINA_FALSE, NULL, NULL, &response);
666    if (diag) _exec_dialog(diag);
667    if (!response)
668      *value = NULL;
669
670    return EINA_TRUE;
671 }
672
673 static Eina_Bool
674 _view_smart_run_open_panel(Ewk_View_Smart_Data *esd,
675                            Evas_Object *frame __UNUSED__,
676                            Eina_Bool allows_multiple_files,
677                            Eina_List *accept_types,
678                            Eina_List **selected_filenames)
679 {
680    View_Smart_Data *vsd = (View_Smart_Data *)esd;
681    Evas_Object *view = vsd->base.self;
682    Evas_Object *obj = evas_object_smart_parent_get(view);
683    Evas_Object *diag = NULL;
684    Eina_Bool response = EINA_FALSE;
685
686    ELM_WEB_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
687
688    if (sd->hook.file_selector)
689      diag = sd->hook.file_selector(sd->hook.file_selector_data, obj,
690                                    allows_multiple_files, accept_types,
691                                    selected_filenames, &response);
692    else
693      diag = _run_dialog(view, DIALOG_FILE_SELECTOR, NULL, NULL, NULL,
694                         allows_multiple_files, accept_types, selected_filenames,
695                         &response);
696    if (diag) _exec_dialog(diag);
697
698    return response;
699 }
700
701 static void
702 _view_smart_add_console_message(Ewk_View_Smart_Data *esd,
703                                 const char *message,
704                                 unsigned int line_number,
705                                 const char *source_id)
706 {
707    Evas_Object *obj = evas_object_smart_parent_get(esd->self);
708
709    ELM_WEB_DATA_GET_OR_RETURN(obj, sd);
710
711    if (sd->hook.console_message)
712      sd->hook.console_message(sd->hook.console_message_data, obj, message,
713                               line_number, source_id);
714 }
715
716 static Eina_Bool
717 _view_smart_focus_can_cycle(Ewk_View_Smart_Data *sd,
718                             Ewk_Focus_Direction direction)
719 {
720    Evas_Object *obj = evas_object_smart_parent_get(sd->self);
721
722    ELM_WEB_CHECK(obj) EINA_FALSE;
723
724    Elm_Focus_Direction dir;
725
726    switch (direction)
727      {
728       case EWK_FOCUS_DIRECTION_FORWARD:
729         dir = ELM_FOCUS_NEXT;
730         break;
731
732       case EWK_FOCUS_DIRECTION_BACKWARD:
733         dir = ELM_FOCUS_PREVIOUS;
734         break;
735
736       default:
737         return EINA_FALSE;
738      }
739
740    elm_widget_focus_cycle(elm_widget_parent_get(obj), dir);
741
742    return EINA_TRUE;
743 }
744
745 /**
746  * Creates a new view object given the parent.
747  *
748  * @param parent object to use as parent.
749  *
750  * @return newly added Evas_Object or @c NULL on errors.
751  */
752 Evas_Object *
753 _view_add(Evas_Object *parent)
754 {
755    Evas *canvas = evas_object_evas_get(parent);
756    static Evas_Smart *smart = NULL;
757    Evas_Object *view;
758
759    if (!smart)
760      {
761         static Ewk_View_Smart_Class api =
762           EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Elementary");
763
764 #ifndef TILED_BACKING_STORE
765         ewk_view_single_smart_set(&api);
766 #else
767         ewk_view_tiled_smart_set(&api);
768 #endif
769
770         _ewk_view_parent_sc = api;
771
772         // TODO: check every api method and provide overrides with hooks!
773         // TODO: hooks should provide extension points
774         // TODO: extension should have some kind of "default implementation",
775         // TODO: that can be replaced or controlled by hooks.
776         // TODO: ie: run_javascript_alert() should present an elm_win
777         // TODO: by default, but user could override it to show as inwin.
778         api.sc.add = _view_smart_add;
779         api.sc.del = _view_smart_del;
780         //api.sc.calculate = _view_smart_calculate;
781         api.mouse_down = _view_smart_mouse_down;
782         api.mouse_up = _view_smart_mouse_up;
783         api.mouse_move = _view_smart_mouse_move;
784         api.add_console_message = _view_smart_add_console_message;
785         api.window_create = _view_smart_window_create;
786         api.window_close = _view_smart_window_close;
787         api.run_javascript_alert = _view_smart_run_javascript_alert;
788         api.run_javascript_confirm = _view_smart_run_javascript_confirm;
789         api.run_javascript_prompt = _view_smart_run_javascript_prompt;
790         api.run_open_panel = _view_smart_run_open_panel;
791         api.focus_can_cycle = _view_smart_focus_can_cycle;
792
793         smart = evas_smart_class_new(&api.sc);
794         if (!smart)
795           {
796              CRITICAL("Could not create smart class");
797              return NULL;
798           }
799      }
800
801    view = evas_object_smart_add(canvas, smart);
802    if (!view)
803      {
804         ERR("Could not create smart object object for view");
805         return NULL;
806      }
807
808    return view;
809 }
810
811 static void
812 _ewk_view_inputmethod_change_cb(void *data,
813                                 Evas_Object *obj __UNUSED__,
814                                 void *event_info)
815 {
816    Elm_Web_Smart_Data *sd = data;
817    Evas_Object *top = elm_widget_top_get(ELM_WIDGET_DATA(sd)->obj);
818    if (!top) return;
819
820    if (event_info)
821      sd->input_method = ELM_WIN_KEYBOARD_ON;
822    else
823      sd->input_method = ELM_WIN_KEYBOARD_OFF;
824    elm_win_keyboard_mode_set(top, sd->input_method);
825 }
826
827 static void
828 _ewk_view_load_started_cb(void *data,
829                           Evas_Object *obj,
830                           void *event_info __UNUSED__)
831 {
832    _ewk_view_inputmethod_change_cb(data, obj, (void *)(long)EINA_FALSE);
833 }
834
835 static void
836 _ewk_view_load_finished_cb(void *data,
837                            Evas_Object *obj __UNUSED__,
838                            void *event_info)
839 {
840    Elm_Web_Smart_Data *sd = data;
841
842    if (event_info) return;
843
844    if (sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)
845      {
846         float tz = sd->zoom.current;
847         sd->zoom.current = 0.0;
848         elm_web_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz);
849      }
850 }
851
852 static void
853 _ewk_view_viewport_changed_cb(void *data,
854                               Evas_Object *obj,
855                               void *event_info __UNUSED__)
856 {
857    Elm_Web_Smart_Data *sd = data;
858
859    if (sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)
860      {
861         ewk_view_zoom_set(obj, 1.0, 0, 0);
862         sd->zoom.no_anim = EINA_TRUE;
863      }
864 }
865
866 static Eina_Bool
867 _restore_zoom_mode_timer_cb(void *data)
868 {
869    Elm_Web_Smart_Data *sd = data;
870    float tz = sd->zoom.current;
871
872    sd->zoom.timer = NULL;
873    sd->zoom.current = 0.0;
874    sd->zoom.no_anim = EINA_TRUE;
875    elm_web_zoom_set(ELM_WIDGET_DATA(sd)->obj, tz);
876
877    return EINA_FALSE;
878 }
879
880 static Eina_Bool
881 _reset_zoom_timer_cb(void *data)
882 {
883    Elm_Web_Smart_Data *sd = data;
884
885    sd->zoom.timer = ecore_timer_add(0.0, _restore_zoom_mode_timer_cb, sd);
886    ewk_view_zoom_set(ELM_WIDGET_DATA(sd)->resize_obj, 1.0, 0, 0);
887
888    return EINA_FALSE;
889 }
890
891 static void
892 _ewk_view_resized_cb(void *data,
893                      Evas_Object *obj __UNUSED__,
894                      void *event_info __UNUSED__)
895 {
896    Elm_Web_Smart_Data *sd = data;
897
898    if (!(sd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL))
899      return;
900
901    if (sd->zoom.timer)
902      ecore_timer_del(sd->zoom.timer);
903    sd->zoom.timer = ecore_timer_add(0.5, _reset_zoom_timer_cb, sd);
904 }
905
906 static void
907 _popup_del_job(void *data)
908 {
909    evas_object_del(data);
910 }
911
912 static void
913 _popup_will_delete(void *data,
914                    Evas_Object *obj,
915                    void *event_info __UNUSED__)
916 {
917    ecore_job_add(_popup_del_job, data);
918    evas_object_smart_callback_del(obj, "popup,willdelete", _popup_will_delete);
919 }
920
921 static void
922 _popup_item_selected(void *data,
923                      Evas_Object *obj,
924                      void *event_info __UNUSED__)
925 {
926    Elm_Object_Item *list_it = elm_list_selected_item_get(obj);
927    const Eina_List *itr, *list = elm_list_items_get(obj);
928    Evas_Object *view = data;
929    int i = 0;
930    void *d;
931
932    EINA_LIST_FOREACH(list, itr, d)
933      {
934         if (d == list_it)
935           break;
936
937         i++;
938      }
939
940    ewk_view_popup_selected_set(view, i);
941    ewk_view_popup_destroy(view);
942 }
943
944 static void
945 _popup_dismiss_cb(void *data,
946                   Evas_Object *obj __UNUSED__,
947                   void *event_info __UNUSED__)
948 {
949    ewk_view_popup_destroy(data);
950 }
951
952 static void
953 _ewk_view_popup_create_cb(void *data,
954                           Evas_Object *obj,
955                           void *event_info)
956 {
957    Elm_Web_Smart_Data *sd = data;
958    Evas_Object *notify, *list;
959    Ewk_Menu *m = event_info;
960    Ewk_Menu_Item *it;
961    Elm_Web_Menu m2;
962    Eina_List *itr;
963
964    m2.items = m->items;
965    m2.x = m->x;
966    m2.y = m->y;
967    m2.width = m->width;
968    m2.height = m->height;
969    m2.handled = EINA_FALSE;
970    evas_object_smart_callback_call
971      (ELM_WIDGET_DATA(sd)->obj, "popup,create", &m2);
972    if (m2.handled) return;
973
974    notify = elm_notify_add(obj);
975    elm_notify_allow_events_set(notify, EINA_FALSE);
976    elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM);
977
978    list = elm_list_add(obj);
979    elm_list_select_mode_set(data, ELM_OBJECT_SELECT_MODE_ALWAYS);
980    elm_scroller_bounce_set(list, EINA_FALSE, EINA_FALSE);
981    elm_list_mode_set(list, ELM_LIST_EXPAND);
982    evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
983    evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
984    elm_object_content_set(notify, list);
985    evas_object_show(list);
986
987    EINA_LIST_FOREACH(m->items, itr, it)
988      elm_list_item_append(list, it->text, NULL, NULL, _popup_item_selected,
989                           obj);
990    elm_list_go(list);
991
992    evas_object_show(notify);
993
994    evas_object_smart_callback_add
995      (obj, "popup,willdelete", _popup_will_delete, notify);
996    evas_object_smart_callback_add
997      (notify, "block,clicked", _popup_dismiss_cb, obj);
998 }
999
1000 static void
1001 _view_smart_callback_proxy_free_cb(void *data,
1002                                    Evas *e __UNUSED__,
1003                                    Evas_Object *obj __UNUSED__,
1004                                    void *event_info __UNUSED__)
1005 {
1006    free(data);
1007 }
1008
1009 static void
1010 _view_smart_callback_proxy_cb(void *data,
1011                               Evas_Object *obj __UNUSED__,
1012                               void *event_info)
1013 {
1014    Elm_Web_Callback_Proxy_Context *ctxt = data;
1015
1016    evas_object_smart_callback_call(ctxt->obj, ctxt->name, event_info);
1017 }
1018
1019 static void
1020 _view_smart_callback_proxy(Evas_Object *view,
1021                            Evas_Object *parent)
1022 {
1023    const Evas_Smart_Cb_Description **cls_descs, **inst_descs;
1024    unsigned int cls_count, inst_count, total;
1025    Elm_Web_Callback_Proxy_Context *ctxt;
1026
1027    evas_object_smart_callbacks_descriptions_get
1028      (view, &cls_descs, &cls_count, &inst_descs, &inst_count);
1029    total = cls_count + inst_count;
1030    if (!total) return;
1031
1032    ctxt = malloc(sizeof(Elm_Web_Callback_Proxy_Context) * total);
1033    if (!ctxt) return;
1034
1035    evas_object_event_callback_add
1036      (view, EVAS_CALLBACK_FREE, _view_smart_callback_proxy_free_cb, ctxt);
1037
1038    for (; cls_count > 0; cls_count--, cls_descs++, ctxt++)
1039      {
1040         const Evas_Smart_Cb_Description *d = *cls_descs;
1041         if (!strcmp(d->name, "popup,create"))
1042           continue;
1043         ctxt->name = d->name;
1044         ctxt->obj = parent;
1045         evas_object_smart_callback_add
1046           (view, d->name, _view_smart_callback_proxy_cb, ctxt);
1047      }
1048
1049    for (; inst_count > 0; inst_count--, inst_descs++, ctxt++)
1050      {
1051         const Evas_Smart_Cb_Description *d = *inst_descs;
1052         ctxt->name = d->name;
1053         ctxt->obj = parent;
1054         evas_object_smart_callback_add
1055           (view, d->name, _view_smart_callback_proxy_cb, ctxt);
1056      }
1057 }
1058
1059 static Eina_Bool
1060 _bring_in_anim_cb(void *data,
1061                   double pos)
1062 {
1063    Elm_Web_Smart_Data *sd = data;
1064    Evas_Object *frame =
1065      ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj);
1066    int sx, sy, rx, ry;
1067
1068    sx = sd->bring_in.start.x;
1069    sy = sd->bring_in.start.y;
1070    rx = (sd->bring_in.end.x - sx) * pos;
1071    ry = (sd->bring_in.end.y - sy) * pos;
1072
1073    ewk_frame_scroll_set(frame, rx + sx, ry + sy);
1074
1075    if (pos == 1.0)
1076      {
1077         sd->bring_in.end.x = sd->bring_in.end.y = sd->bring_in.start.x =
1078               sd->bring_in.start.y = 0;
1079         sd->bring_in.animator = NULL;
1080      }
1081
1082    return EINA_TRUE;
1083 }
1084
1085 #endif
1086
1087 #ifdef HAVE_ELEMENTARY_WEB
1088 static int _elm_need_web = 0;
1089 #endif
1090
1091 void
1092 _elm_unneed_web(void)
1093 {
1094 #ifdef HAVE_ELEMENTARY_WEB
1095    if (--_elm_need_web) return;
1096
1097    _elm_need_web = 0;
1098    ewk_shutdown();
1099 #endif
1100 }
1101
1102 EAPI Eina_Bool
1103 elm_need_web(void)
1104 {
1105 #ifdef HAVE_ELEMENTARY_WEB
1106    if (_elm_need_web++) return EINA_TRUE;
1107    ewk_init();
1108    return EINA_TRUE;
1109 #else
1110    return EINA_FALSE;
1111 #endif
1112 }
1113
1114 static void
1115 _elm_web_smart_add(Evas_Object *obj)
1116 {
1117    EVAS_SMART_DATA_ALLOC(obj, Elm_Web_Smart_Data);
1118
1119 #ifdef HAVE_ELEMENTARY_WEB
1120    ELM_WIDGET_DATA(priv)->resize_obj = _view_add(obj);
1121 #else
1122    ELM_WIDGET_DATA(priv)->resize_obj = elm_label_add(obj);
1123    elm_object_text_set
1124      (ELM_WIDGET_DATA(priv)->resize_obj, "WebKit not supported!");
1125    evas_object_show(ELM_WIDGET_DATA(priv)->resize_obj);
1126 #endif
1127
1128    _elm_web_parent_sc->base.add(obj);
1129
1130 #ifdef HAVE_ELEMENTARY_WEB
1131    ewk_view_setting_user_agent_set
1132      (ELM_WIDGET_DATA(priv)->resize_obj, ELM_WEB_USER_AGENT);
1133
1134    priv->input_method = ELM_WIN_KEYBOARD_OFF;
1135    evas_object_smart_callback_add
1136      (ELM_WIDGET_DATA(priv)->resize_obj, "inputmethod,changed",
1137      _ewk_view_inputmethod_change_cb, priv);
1138    evas_object_smart_callback_add
1139      (ELM_WIDGET_DATA(priv)->resize_obj, "load,started",
1140      _ewk_view_load_started_cb, priv);
1141    evas_object_smart_callback_add
1142      (ELM_WIDGET_DATA(priv)->resize_obj, "popup,create",
1143      _ewk_view_popup_create_cb, priv);
1144    evas_object_smart_callback_add
1145      (ELM_WIDGET_DATA(priv)->resize_obj, "load,finished",
1146      _ewk_view_load_finished_cb, priv);
1147    evas_object_smart_callback_add
1148      (ELM_WIDGET_DATA(priv)->resize_obj, "viewport,changed",
1149      _ewk_view_viewport_changed_cb, priv);
1150    evas_object_smart_callback_add
1151      (ELM_WIDGET_DATA(priv)->resize_obj, "view,resized",
1152      _ewk_view_resized_cb, priv);
1153
1154    priv->tab_propagate = EINA_FALSE;
1155    priv->inwin_mode = _elm_config->inwin_dialogs_enable;
1156    priv->zoom.min =
1157      ewk_view_zoom_range_min_get(ELM_WIDGET_DATA(priv)->resize_obj);
1158    priv->zoom.max =
1159      ewk_view_zoom_range_max_get(ELM_WIDGET_DATA(priv)->resize_obj);
1160    priv->zoom.current = 1.0;
1161
1162    _view_smart_callback_proxy(ELM_WIDGET_DATA(priv)->resize_obj, obj);
1163    _elm_web_smart_theme(obj);
1164
1165    elm_widget_can_focus_set(obj, EINA_TRUE);
1166 #endif
1167 }
1168
1169 static void
1170 _elm_web_smart_del(Evas_Object *obj)
1171 {
1172 #ifdef HAVE_ELEMENTARY_WEB
1173    ELM_WEB_DATA_GET(obj, sd);
1174
1175    if (sd->zoom.timer)
1176      {
1177         ecore_timer_del(sd->zoom.timer);
1178         sd->zoom.timer = NULL;
1179      }
1180
1181    if (sd->bring_in.animator)
1182      {
1183         ecore_animator_del(sd->bring_in.animator);
1184         sd->bring_in.animator = NULL;
1185      }
1186 #endif
1187
1188    _elm_web_parent_sc->base.del(obj); /* handles freeing sd */
1189 }
1190
1191 static void
1192 _elm_web_smart_set_user(Elm_Web_Smart_Class *sc)
1193 {
1194    ELM_WIDGET_CLASS(sc)->base.add = _elm_web_smart_add;
1195    ELM_WIDGET_CLASS(sc)->base.del = _elm_web_smart_del;
1196
1197    ELM_WIDGET_CLASS(sc)->on_focus = _elm_web_smart_on_focus;
1198    ELM_WIDGET_CLASS(sc)->theme = _elm_web_smart_theme;
1199    ELM_WIDGET_CLASS(sc)->event = _elm_web_smart_event;
1200 }
1201
1202 EAPI const Elm_Web_Smart_Class *
1203 elm_web_smart_class_get(void)
1204 {
1205    static Elm_Web_Smart_Class _sc =
1206      ELM_WEB_SMART_CLASS_INIT_NAME_VERSION(ELM_WEB_SMART_NAME);
1207    static const Elm_Web_Smart_Class *class = NULL;
1208    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1209
1210    if (class) return class;
1211
1212    _elm_web_smart_set(&_sc);
1213    esc->callbacks = _elm_web_smart_callbacks;
1214    class = &_sc;
1215
1216    return class;
1217 }
1218
1219 EAPI Evas_Object *
1220 elm_web_add(Evas_Object *parent)
1221 {
1222    Evas_Object *obj;
1223
1224    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1225
1226    obj = elm_widget_add(_elm_web_smart_class_new(), parent);
1227    if (!obj) return NULL;
1228
1229    if (!elm_widget_sub_object_add(parent, obj))
1230      ERR("could not add %p as sub object of %p", obj, parent);
1231
1232    return obj;
1233 }
1234
1235 EAPI Evas_Object *
1236 elm_web_webkit_view_get(const Evas_Object *obj)
1237 {
1238    ELM_WEB_CHECK(obj) NULL;
1239
1240 #ifdef HAVE_ELEMENTARY_WEB
1241    ELM_WEB_DATA_GET(obj, sd);
1242
1243    return ELM_WIDGET_DATA(sd)->resize_obj;
1244 #else
1245    ERR("Elementary not compiled with EWebKit support.");
1246    return NULL;
1247 #endif
1248 }
1249
1250 EAPI void
1251 elm_web_window_create_hook_set(Evas_Object *obj,
1252                                Elm_Web_Window_Open func,
1253                                void *data)
1254 {
1255    ELM_WEB_CHECK(obj);
1256
1257 #ifdef HAVE_ELEMENTARY_WEB
1258    ELM_WEB_DATA_GET(obj, sd);
1259
1260    sd->hook.window_create = func;
1261    sd->hook.window_create_data = data;
1262 #else
1263    (void)func;
1264    (void)data;
1265 #endif
1266 }
1267
1268 EAPI void
1269 elm_web_dialog_alert_hook_set(Evas_Object *obj,
1270                               Elm_Web_Dialog_Alert func,
1271                               void *data)
1272 {
1273    ELM_WEB_CHECK(obj);
1274
1275 #ifdef HAVE_ELEMENTARY_WEB
1276    ELM_WEB_DATA_GET(obj, sd);
1277
1278    sd->hook.alert = func;
1279    sd->hook.alert_data = data;
1280 #else
1281    (void)func;
1282    (void)data;
1283 #endif
1284 }
1285
1286 EAPI void
1287 elm_web_dialog_confirm_hook_set(Evas_Object *obj,
1288                                 Elm_Web_Dialog_Confirm func,
1289                                 void *data)
1290 {
1291    ELM_WEB_CHECK(obj);
1292
1293 #ifdef HAVE_ELEMENTARY_WEB
1294    ELM_WEB_DATA_GET(obj, sd);
1295
1296    sd->hook.confirm = func;
1297    sd->hook.confirm_data = data;
1298 #else
1299    (void)func;
1300    (void)data;
1301 #endif
1302 }
1303
1304 EAPI void
1305 elm_web_dialog_prompt_hook_set(Evas_Object *obj,
1306                                Elm_Web_Dialog_Prompt func,
1307                                void *data)
1308 {
1309    ELM_WEB_CHECK(obj);
1310
1311 #ifdef HAVE_ELEMENTARY_WEB
1312    ELM_WEB_DATA_GET(obj, sd);
1313
1314    sd->hook.prompt = func;
1315    sd->hook.prompt_data = data;
1316 #else
1317    (void)func;
1318    (void)data;
1319 #endif
1320 }
1321
1322 EAPI void
1323 elm_web_dialog_file_selector_hook_set(Evas_Object *obj,
1324                                       Elm_Web_Dialog_File_Selector func,
1325                                       void *data)
1326 {
1327    ELM_WEB_CHECK(obj);
1328
1329 #ifdef HAVE_ELEMENTARY_WEB
1330    ELM_WEB_DATA_GET(obj, sd);
1331
1332    sd->hook.file_selector = func;
1333    sd->hook.file_selector_data = data;
1334 #else
1335    (void)func;
1336    (void)data;
1337 #endif
1338 }
1339
1340 EAPI void
1341 elm_web_console_message_hook_set(Evas_Object *obj,
1342                                  Elm_Web_Console_Message func,
1343                                  void *data)
1344 {
1345    ELM_WEB_CHECK(obj);
1346
1347 #ifdef HAVE_ELEMENTARY_WEB
1348    ELM_WEB_DATA_GET(obj, sd);
1349
1350    sd->hook.console_message = func;
1351    sd->hook.console_message_data = data;
1352 #else
1353    (void)func;
1354    (void)data;
1355 #endif
1356 }
1357
1358 EAPI void
1359 elm_web_useragent_set(Evas_Object *obj,
1360                       const char *user_agent)
1361 {
1362    ELM_WEB_CHECK(obj);
1363
1364 #ifdef HAVE_ELEMENTARY_WEB
1365    ELM_WEB_DATA_GET(obj, sd);
1366
1367    ewk_view_setting_user_agent_set
1368      (ELM_WIDGET_DATA(sd)->resize_obj, user_agent);
1369 #else
1370    (void)user_agent;
1371 #endif
1372 }
1373
1374 EAPI const char *
1375 elm_web_useragent_get(const Evas_Object *obj)
1376 {
1377    ELM_WEB_CHECK(obj) NULL;
1378
1379 #ifdef HAVE_ELEMENTARY_WEB
1380    ELM_WEB_DATA_GET(obj, sd);
1381
1382    return ewk_view_setting_user_agent_get(ELM_WIDGET_DATA(sd)->resize_obj);
1383 #else
1384    return NULL;
1385 #endif
1386 }
1387
1388 EAPI Eina_Bool
1389 elm_web_tab_propagate_get(const Evas_Object *obj)
1390 {
1391    ELM_WEB_CHECK(obj) EINA_FALSE;
1392
1393 #ifdef HAVE_ELEMENTARY_WEB
1394    ELM_WEB_DATA_GET(obj, sd);
1395
1396    return sd->tab_propagate;
1397 #else
1398    return EINA_FALSE;
1399 #endif
1400 }
1401
1402 EAPI void
1403 elm_web_tab_propagate_set(Evas_Object *obj,
1404                           Eina_Bool propagate)
1405 {
1406    ELM_WEB_CHECK(obj);
1407
1408 #ifdef HAVE_ELEMENTARY_WEB
1409    ELM_WEB_DATA_GET(obj, sd);
1410
1411    sd->tab_propagate = propagate;
1412 #else
1413    (void)propagate;
1414 #endif
1415 }
1416
1417 EAPI Eina_Bool
1418 elm_web_uri_set(Evas_Object *obj,
1419                 const char *uri)
1420 {
1421    ELM_WEB_CHECK(obj) EINA_FALSE;
1422
1423 #ifdef HAVE_ELEMENTARY_WEB
1424    ELM_WEB_DATA_GET(obj, sd);
1425
1426    return ewk_view_uri_set(ELM_WIDGET_DATA(sd)->resize_obj, uri);
1427 #else
1428    (void)uri;
1429    return EINA_FALSE;
1430 #endif
1431 }
1432
1433 EAPI const char *
1434 elm_web_uri_get(const Evas_Object *obj)
1435 {
1436    ELM_WEB_CHECK(obj) NULL;
1437
1438 #ifdef HAVE_ELEMENTARY_WEB
1439    ELM_WEB_DATA_GET(obj, sd);
1440
1441    return ewk_view_uri_get(ELM_WIDGET_DATA(sd)->resize_obj);
1442 #else
1443    return NULL;
1444 #endif
1445 }
1446
1447 EAPI const char *
1448 elm_web_title_get(const Evas_Object *obj)
1449 {
1450    ELM_WEB_CHECK(obj) NULL;
1451
1452 #ifdef HAVE_ELEMENTARY_WEB
1453    const Ewk_Text_With_Direction *txt;
1454
1455    ELM_WEB_DATA_GET(obj, sd);
1456
1457    txt = ewk_view_title_get(ELM_WIDGET_DATA(sd)->resize_obj);
1458    if (txt) return txt->string;
1459
1460    return NULL;
1461 #else
1462    return NULL;
1463 #endif
1464 }
1465
1466 EAPI void
1467 elm_web_bg_color_set(Evas_Object *obj,
1468                      int r,
1469                      int g,
1470                      int b,
1471                      int a)
1472 {
1473    ELM_WEB_CHECK(obj);
1474
1475 #ifdef HAVE_ELEMENTARY_WEB
1476    ELM_WEB_DATA_GET(obj, sd);
1477
1478    ewk_view_bg_color_set(ELM_WIDGET_DATA(sd)->resize_obj, r, g, b, a);
1479 #else
1480    (void)r;
1481    (void)g;
1482    (void)b;
1483    (void)a;
1484 #endif
1485 }
1486
1487 EAPI void
1488 elm_web_bg_color_get(const Evas_Object *obj,
1489                      int *r,
1490                      int *g,
1491                      int *b,
1492                      int *a)
1493 {
1494    if (r) *r = 0;
1495    if (g) *g = 0;
1496    if (b) *b = 0;
1497    if (a) *a = 0;
1498
1499    ELM_WEB_CHECK(obj);
1500
1501 #ifdef HAVE_ELEMENTARY_WEB
1502    ELM_WEB_DATA_GET(obj, sd);
1503
1504    return ewk_view_bg_color_get(ELM_WIDGET_DATA(sd)->resize_obj, r, g, b, a);
1505 #endif
1506 }
1507
1508 EAPI const char *
1509 elm_web_selection_get(const Evas_Object *obj)
1510 {
1511    ELM_WEB_CHECK(obj) NULL;
1512
1513 #ifdef HAVE_ELEMENTARY_WEB
1514    ELM_WEB_DATA_GET(obj, sd);
1515
1516    return ewk_view_selection_get(ELM_WIDGET_DATA(sd)->resize_obj);
1517 #else
1518    return NULL;
1519 #endif
1520 }
1521
1522 EAPI void
1523 elm_web_popup_selected_set(Evas_Object *obj,
1524                            int idx)
1525 {
1526    ELM_WEB_CHECK(obj);
1527
1528 #ifdef HAVE_ELEMENTARY_WEB
1529    ELM_WEB_DATA_GET(obj, sd);
1530    ewk_view_popup_selected_set(ELM_WIDGET_DATA(sd)->resize_obj, idx);
1531 #else
1532    (void)idx;
1533 #endif
1534 }
1535
1536 EAPI Eina_Bool
1537 elm_web_popup_destroy(Evas_Object *obj)
1538 {
1539    ELM_WEB_CHECK(obj) EINA_FALSE;
1540
1541 #ifdef HAVE_ELEMENTARY_WEB
1542    ELM_WEB_DATA_GET(obj, sd);
1543    return ewk_view_popup_destroy(ELM_WIDGET_DATA(sd)->resize_obj);
1544 #else
1545    return EINA_FALSE;
1546 #endif
1547 }
1548
1549 EAPI Eina_Bool
1550 elm_web_text_search(const Evas_Object *obj,
1551                     const char *string,
1552                     Eina_Bool case_sensitive,
1553                     Eina_Bool forward,
1554                     Eina_Bool wrap)
1555 {
1556    ELM_WEB_CHECK(obj) EINA_FALSE;
1557
1558 #ifdef HAVE_ELEMENTARY_WEB
1559    ELM_WEB_DATA_GET(obj, sd);
1560
1561    return ewk_view_text_search
1562             (ELM_WIDGET_DATA(sd)->resize_obj, string,
1563             case_sensitive, forward, wrap);
1564 #else
1565    (void)string;
1566    (void)case_sensitive;
1567    (void)forward;
1568    (void)wrap;
1569    return EINA_FALSE;
1570 #endif
1571 }
1572
1573 EAPI unsigned int
1574 elm_web_text_matches_mark(Evas_Object *obj,
1575                           const char *string,
1576                           Eina_Bool case_sensitive,
1577                           Eina_Bool highlight,
1578                           unsigned int limit)
1579 {
1580    ELM_WEB_CHECK(obj) 0;
1581
1582 #ifdef HAVE_ELEMENTARY_WEB
1583    ELM_WEB_DATA_GET(obj, sd);
1584    if (!sd) return 0;
1585    return ewk_view_text_matches_mark
1586             (ELM_WIDGET_DATA(sd)->resize_obj, string,
1587             case_sensitive, highlight, limit);
1588 #else
1589    (void)string;
1590    (void)case_sensitive;
1591    (void)highlight;
1592    (void)limit;
1593    return 0;
1594 #endif
1595 }
1596
1597 EAPI Eina_Bool
1598 elm_web_text_matches_unmark_all(Evas_Object *obj)
1599 {
1600    ELM_WEB_CHECK(obj) EINA_FALSE;
1601
1602 #ifdef HAVE_ELEMENTARY_WEB
1603    ELM_WEB_DATA_GET(obj, sd);
1604
1605    return ewk_view_text_matches_unmark_all(ELM_WIDGET_DATA(sd)->resize_obj);
1606 #else
1607    return EINA_FALSE;
1608 #endif
1609 }
1610
1611 EAPI Eina_Bool
1612 elm_web_text_matches_highlight_set(Evas_Object *obj,
1613                                    Eina_Bool highlight)
1614 {
1615    ELM_WEB_CHECK(obj) EINA_FALSE;
1616
1617 #ifdef HAVE_ELEMENTARY_WEB
1618    ELM_WEB_DATA_GET(obj, sd);
1619
1620    return ewk_view_text_matches_highlight_set
1621             (ELM_WIDGET_DATA(sd)->resize_obj, highlight);
1622 #else
1623    (void)highlight;
1624    return EINA_FALSE;
1625 #endif
1626 }
1627
1628 EAPI Eina_Bool
1629 elm_web_text_matches_highlight_get(const Evas_Object *obj)
1630 {
1631    ELM_WEB_CHECK(obj) EINA_FALSE;
1632
1633 #ifdef HAVE_ELEMENTARY_WEB
1634    ELM_WEB_DATA_GET(obj, sd);
1635
1636    return ewk_view_text_matches_highlight_get(ELM_WIDGET_DATA(sd)->resize_obj);
1637 #else
1638    return EINA_FALSE;
1639 #endif
1640 }
1641
1642 EAPI double
1643 elm_web_load_progress_get(const Evas_Object *obj)
1644 {
1645    ELM_WEB_CHECK(obj) - 1.0;
1646
1647 #ifdef HAVE_ELEMENTARY_WEB
1648    ELM_WEB_DATA_GET(obj, sd);
1649
1650    return ewk_view_load_progress_get(ELM_WIDGET_DATA(sd)->resize_obj);
1651 #else
1652    return EINA_FALSE;
1653 #endif
1654 }
1655
1656 EAPI Eina_Bool
1657 elm_web_stop(Evas_Object *obj)
1658 {
1659    ELM_WEB_CHECK(obj) EINA_FALSE;
1660
1661 #ifdef HAVE_ELEMENTARY_WEB
1662    ELM_WEB_DATA_GET(obj, sd);
1663
1664    return ewk_view_stop(ELM_WIDGET_DATA(sd)->resize_obj);
1665 #else
1666    return EINA_FALSE;
1667 #endif
1668 }
1669
1670 EAPI Eina_Bool
1671 elm_web_reload(Evas_Object *obj)
1672 {
1673    ELM_WEB_CHECK(obj) EINA_FALSE;
1674
1675 #ifdef HAVE_ELEMENTARY_WEB
1676    ELM_WEB_DATA_GET(obj, sd);
1677
1678    return ewk_view_reload(ELM_WIDGET_DATA(sd)->resize_obj);
1679 #else
1680    return EINA_FALSE;
1681 #endif
1682 }
1683
1684 EAPI Eina_Bool
1685 elm_web_reload_full(Evas_Object *obj)
1686 {
1687    ELM_WEB_CHECK(obj) EINA_FALSE;
1688
1689 #ifdef HAVE_ELEMENTARY_WEB
1690    ELM_WEB_DATA_GET(obj, sd);
1691
1692    return ewk_view_reload_full(ELM_WIDGET_DATA(sd)->resize_obj);
1693 #else
1694    return EINA_FALSE;
1695 #endif
1696 }
1697
1698 EAPI Eina_Bool
1699 elm_web_back(Evas_Object *obj)
1700 {
1701    ELM_WEB_CHECK(obj) EINA_FALSE;
1702
1703 #ifdef HAVE_ELEMENTARY_WEB
1704    ELM_WEB_DATA_GET(obj, sd);
1705
1706    return ewk_view_back(ELM_WIDGET_DATA(sd)->resize_obj);
1707 #else
1708    return EINA_FALSE;
1709 #endif
1710 }
1711
1712 EAPI Eina_Bool
1713 elm_web_forward(Evas_Object *obj)
1714 {
1715    ELM_WEB_CHECK(obj) EINA_FALSE;
1716
1717 #ifdef HAVE_ELEMENTARY_WEB
1718    ELM_WEB_DATA_GET(obj, sd);
1719
1720    return ewk_view_forward(ELM_WIDGET_DATA(sd)->resize_obj);
1721 #else
1722    return EINA_FALSE;
1723 #endif
1724 }
1725
1726 EAPI Eina_Bool
1727 elm_web_navigate(Evas_Object *obj,
1728                  int steps)
1729 {
1730    ELM_WEB_CHECK(obj) EINA_FALSE;
1731
1732 #ifdef HAVE_ELEMENTARY_WEB
1733    ELM_WEB_DATA_GET(obj, sd);
1734
1735    return ewk_view_navigate(ELM_WIDGET_DATA(sd)->resize_obj, steps);
1736 #else
1737    (void)steps;
1738    return EINA_FALSE;
1739 #endif
1740 }
1741
1742 EINA_DEPRECATED EAPI Eina_Bool
1743 elm_web_back_possible(Evas_Object *obj)
1744 {
1745    return elm_web_back_possible_get(obj);
1746 }
1747
1748 EAPI Eina_Bool
1749 elm_web_back_possible_get(Evas_Object *obj)
1750 {
1751    ELM_WEB_CHECK(obj) EINA_FALSE;
1752
1753 #ifdef HAVE_ELEMENTARY_WEB
1754    ELM_WEB_DATA_GET(obj, sd);
1755
1756    return ewk_view_back_possible(ELM_WIDGET_DATA(sd)->resize_obj);
1757 #else
1758    return EINA_FALSE;
1759 #endif
1760 }
1761
1762 EAPI Eina_Bool
1763 elm_web_forward_possible_get(Evas_Object *obj)
1764 {
1765    ELM_WEB_CHECK(obj) EINA_FALSE;
1766
1767 #ifdef HAVE_ELEMENTARY_WEB
1768    ELM_WEB_DATA_GET(obj, sd);
1769
1770    return ewk_view_forward_possible(ELM_WIDGET_DATA(sd)->resize_obj);
1771 #else
1772    return EINA_FALSE;
1773 #endif
1774 }
1775
1776 EAPI Eina_Bool
1777 elm_web_navigate_possible_get(Evas_Object *obj,
1778                               int steps)
1779 {
1780    ELM_WEB_CHECK(obj) EINA_FALSE;
1781
1782 #ifdef HAVE_ELEMENTARY_WEB
1783    ELM_WEB_DATA_GET(obj, sd);
1784
1785    return ewk_view_navigate_possible(ELM_WIDGET_DATA(sd)->resize_obj, steps);
1786 #else
1787    (void)steps;
1788    return EINA_FALSE;
1789 #endif
1790 }
1791
1792 EAPI Eina_Bool
1793 elm_web_history_enabled_get(const Evas_Object *obj)
1794 {
1795    ELM_WEB_CHECK(obj) EINA_FALSE;
1796
1797 #ifdef HAVE_ELEMENTARY_WEB
1798    ELM_WEB_DATA_GET(obj, sd);
1799
1800    return ewk_view_history_enable_get(ELM_WIDGET_DATA(sd)->resize_obj);
1801 #else
1802    return EINA_FALSE;
1803 #endif
1804 }
1805
1806 EAPI void
1807 elm_web_history_enabled_set(Evas_Object *obj,
1808                             Eina_Bool enable)
1809 {
1810    ELM_WEB_CHECK(obj);
1811
1812 #ifdef HAVE_ELEMENTARY_WEB
1813    ELM_WEB_DATA_GET(obj, sd);
1814
1815    ewk_view_history_enable_set(ELM_WIDGET_DATA(sd)->resize_obj, enable);
1816 #else
1817    (void)enable;
1818 #endif
1819 }
1820
1821 //EAPI Ewk_History *ewk_view_history_get(const Evas_Object *obj); // TODO:
1822
1823 EAPI void
1824 elm_web_zoom_set(Evas_Object *obj,
1825                  double zoom)
1826 {
1827    ELM_WEB_CHECK(obj);
1828
1829 #ifdef HAVE_ELEMENTARY_WEB
1830    ELM_WEB_DATA_GET(obj, sd);
1831
1832    int vw, vh, cx, cy;
1833    float z = 1.0;
1834
1835    evas_object_geometry_get
1836      (ELM_WIDGET_DATA(sd)->resize_obj, NULL, NULL, &vw, &vh);
1837    cx = vw / 2;
1838    cy = vh / 2;
1839    if (zoom > sd->zoom.max) zoom = sd->zoom.max;
1840    else if (zoom < sd->zoom.min)
1841      zoom = sd->zoom.min;
1842    if (zoom == sd->zoom.current) return;
1843
1844    sd->zoom.current = zoom;
1845    if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_MANUAL) z = zoom;
1846    else if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FIT)
1847      {
1848         Evas_Object *frame =
1849           ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj);
1850         Evas_Coord fw, fh, pw, ph;
1851
1852         if (!ewk_frame_contents_size_get(frame, &fw, &fh)) return;
1853         z = ewk_frame_page_zoom_get(frame);
1854         fw /= z;
1855         fh /= z;
1856         if ((fw > 0) && (fh > 0))
1857           {
1858              ph = (fh * vw) / fw;
1859              if (ph > vh)
1860                {
1861                   pw = (fw * vh) / fh;
1862                   ph = vh;
1863                }
1864              else
1865                pw = vw;
1866              if (fw > fh)
1867                z = (float)pw / fw;
1868              else
1869                z = (float)ph / fh;
1870           }
1871      }
1872    else if (sd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FILL)
1873      {
1874         Evas_Object *frame =
1875           ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj);
1876         Evas_Coord fw, fh, pw, ph;
1877
1878         if (!ewk_frame_contents_size_get(frame, &fw, &fh)) return;
1879         z = ewk_frame_page_zoom_get(frame);
1880         fw /= z;
1881         fh /= z;
1882         if ((fw > 0) && (fh > 0))
1883           {
1884              ph = (fh * vw) / fw;
1885              if (ph < vh)
1886                {
1887                   pw = (fw * vh) / fh;
1888                   ph = vh;
1889                }
1890              else
1891                pw = vw;
1892              if (fw > fh)
1893                z = (float)pw / fw;
1894              else
1895                z = (float)ph / fh;
1896           }
1897      }
1898    if (sd->zoom.no_anim)
1899      ewk_view_zoom_set(ELM_WIDGET_DATA(sd)->resize_obj, z, cx, cy);
1900    else
1901      ewk_view_zoom_animated_set
1902        (ELM_WIDGET_DATA(sd)->resize_obj, z,
1903        _elm_config->zoom_friction, cx, cy);
1904    sd->zoom.no_anim = EINA_FALSE;
1905 #else
1906    (void)zoom;
1907 #endif
1908 }
1909
1910 EAPI double
1911 elm_web_zoom_get(const Evas_Object *obj)
1912 {
1913    ELM_WEB_CHECK(obj) - 1.0;
1914
1915 #ifdef HAVE_ELEMENTARY_WEB
1916    ELM_WEB_DATA_GET(obj, sd);
1917
1918    return sd->zoom.current;
1919 #else
1920    return -1.0;
1921 #endif
1922 }
1923
1924 EAPI void
1925 elm_web_zoom_mode_set(Evas_Object *obj,
1926                       Elm_Web_Zoom_Mode mode)
1927 {
1928    ELM_WEB_CHECK(obj);
1929
1930 #ifdef HAVE_ELEMENTARY_WEB
1931    ELM_WEB_DATA_GET(obj, sd);
1932
1933    float tz;
1934
1935    if (mode >= ELM_WEB_ZOOM_MODE_LAST)
1936      return;
1937    if (mode == sd->zoom.mode)
1938      return;
1939
1940    sd->zoom.mode = mode;
1941    tz = sd->zoom.current;
1942    sd->zoom.current = 0.0;
1943    elm_web_zoom_set(obj, tz);
1944 #else
1945    (void)mode;
1946 #endif
1947 }
1948
1949 EAPI Elm_Web_Zoom_Mode
1950 elm_web_zoom_mode_get(const Evas_Object *obj)
1951 {
1952    ELM_WEB_CHECK(obj) ELM_WEB_ZOOM_MODE_LAST;
1953
1954 #ifdef HAVE_ELEMENTARY_WEB
1955    ELM_WEB_DATA_GET(obj, sd);
1956
1957    return sd->zoom.mode;
1958 #else
1959    return ELM_WEB_ZOOM_MODE_LAST;
1960 #endif
1961 }
1962
1963 EAPI void
1964 elm_web_region_show(Evas_Object *obj,
1965                     int x,
1966                     int y,
1967                     int w __UNUSED__,
1968                     int h __UNUSED__)
1969 {
1970    ELM_WEB_CHECK(obj);
1971
1972 #ifdef HAVE_ELEMENTARY_WEB
1973    ELM_WEB_DATA_GET(obj, sd);
1974
1975    Evas_Object *frame =
1976      ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj);
1977    int fw, fh, zw, zh, rx, ry;
1978    float zoom;
1979
1980    ewk_frame_contents_size_get(frame, &fw, &fh);
1981    zoom = ewk_frame_page_zoom_get(frame);
1982    zw = fw / zoom;
1983    zh = fh / zoom;
1984    rx = (x * fw) / zw;
1985    ry = (y * fh) / zh;
1986    if (sd->bring_in.animator)
1987      {
1988         ecore_animator_del(sd->bring_in.animator);
1989         sd->bring_in.animator = NULL;
1990      }
1991    ewk_frame_scroll_set(frame, rx, ry);
1992 #else
1993    (void)x;
1994    (void)y;
1995 #endif
1996 }
1997
1998 EAPI void
1999 elm_web_region_bring_in(Evas_Object *obj,
2000                         int x,
2001                         int y,
2002                         int w __UNUSED__,
2003                         int h __UNUSED__)
2004 {
2005    ELM_WEB_CHECK(obj);
2006
2007 #ifdef HAVE_ELEMENTARY_WEB
2008    ELM_WEB_DATA_GET(obj, sd);
2009
2010    Evas_Object *frame =
2011      ewk_view_frame_main_get(ELM_WIDGET_DATA(sd)->resize_obj);
2012    int fw, fh, zw, zh, rx, ry, sx, sy;
2013    float zoom;
2014
2015    ewk_frame_contents_size_get(frame, &fw, &fh);
2016    ewk_frame_scroll_pos_get(frame, &sx, &sy);
2017    zoom = ewk_frame_page_zoom_get(frame);
2018    zw = fw / zoom;
2019    zh = fh / zoom;
2020    rx = (x * fw) / zw;
2021    ry = (y * fh) / zh;
2022    if ((sd->bring_in.end.x == rx) && (sd->bring_in.end.y == ry))
2023      return;
2024    sd->bring_in.start.x = sx;
2025    sd->bring_in.start.y = sy;
2026    sd->bring_in.end.x = rx;
2027    sd->bring_in.end.y = ry;
2028    if (sd->bring_in.animator)
2029      ecore_animator_del(sd->bring_in.animator);
2030    sd->bring_in.animator = ecore_animator_timeline_add(
2031        _elm_config->bring_in_scroll_friction, _bring_in_anim_cb, sd);
2032 #else
2033    (void)x;
2034    (void)y;
2035 #endif
2036 }
2037
2038 EAPI void
2039 elm_web_inwin_mode_set(Evas_Object *obj,
2040                        Eina_Bool value)
2041 {
2042    ELM_WEB_CHECK(obj);
2043
2044 #ifdef HAVE_ELEMENTARY_WEB
2045    ELM_WEB_DATA_GET(obj, sd);
2046
2047    sd->inwin_mode = value;
2048 #else
2049    (void)value;
2050 #endif
2051 }
2052
2053 EAPI Eina_Bool
2054 elm_web_inwin_mode_get(const Evas_Object *obj)
2055 {
2056    ELM_WEB_CHECK(obj) EINA_FALSE;
2057
2058 #ifdef HAVE_ELEMENTARY_WEB
2059    ELM_WEB_DATA_GET(obj, sd);
2060
2061    return sd->inwin_mode;
2062 #else
2063    return EINA_FALSE;
2064 #endif
2065 }
2066
2067 EAPI void
2068 elm_web_window_features_ref(Elm_Web_Window_Features *wf)
2069 {
2070 #ifdef HAVE_ELEMENTARY_WEB
2071    ewk_window_features_ref((Ewk_Window_Features *)wf);
2072 #else
2073    (void)wf;
2074 #endif
2075 }
2076
2077 EAPI void
2078 elm_web_window_features_unref(Elm_Web_Window_Features *wf)
2079 {
2080 #ifdef HAVE_ELEMENTARY_WEB
2081    ewk_window_features_unref((Ewk_Window_Features *)wf);
2082 #else
2083    (void)wf;
2084 #endif
2085 }
2086
2087 EAPI Eina_Bool
2088 elm_web_window_features_property_get(const Elm_Web_Window_Features *wf,
2089                                      Elm_Web_Window_Feature_Flag flag)
2090 {
2091 #ifdef HAVE_ELEMENTARY_WEB
2092    Eina_Bool toolbar_visible, statusbar_visible;
2093    Eina_Bool scrollbars_visible, menubar_visible;
2094    Eina_Bool locationbar_visible, fullscreen;
2095
2096    ewk_window_features_bool_property_get
2097      ((const Ewk_Window_Features *)wf, &toolbar_visible, &statusbar_visible,
2098      &scrollbars_visible, &menubar_visible, &locationbar_visible,
2099      &fullscreen);
2100
2101    //TODO : Improve ewk API usage to get one value.
2102    switch (flag)
2103      {
2104       case ELM_WEB_WINDOW_FEATURE_TOOLBAR:
2105         return toolbar_visible;
2106         break;
2107
2108       case ELM_WEB_WINDOW_FEATURE_STATUSBAR:
2109         return statusbar_visible;
2110         break;
2111
2112       case ELM_WEB_WINDOW_FEATURE_SCROLLBARS:
2113         return scrollbars_visible;
2114         break;
2115
2116       case ELM_WEB_WINDOW_FEATURE_MENUBAR:
2117         return menubar_visible;
2118         break;
2119
2120       case ELM_WEB_WINDOW_FEATURE_LOCATIONBAR:
2121         return locationbar_visible;
2122         break;
2123
2124       case ELM_WEB_WINDOW_FEATURE_FULLSCREEN:
2125         return fullscreen;
2126         break;
2127      }
2128 #else
2129
2130    if (!wf) return EINA_FALSE;
2131    if (flag == ELM_WEB_WINDOW_FEATURE_TOOLBAR)
2132      {
2133         //TODO Handle unused variable warnings when
2134         //ewk is not installed.
2135      }
2136
2137    /* What to do with these ?
2138       (void)wf;
2139       (void)toolbar_visible;
2140       (void)statusbar_visible;
2141       (void)scrollbars_visible;
2142       (void)menubar_visible;
2143       (void)locationbar_visible;
2144       (void)fullscreen;
2145     */
2146
2147 #endif
2148    return EINA_FALSE;
2149 }
2150
2151 EAPI void
2152 elm_web_window_features_region_get(const Elm_Web_Window_Features *wf,
2153                                    Evas_Coord *x,
2154                                    Evas_Coord *y,
2155                                    Evas_Coord *w,
2156                                    Evas_Coord *h)
2157 {
2158 #ifdef HAVE_ELEMENTARY_WEB
2159    ewk_window_features_int_property_get
2160      ((const Ewk_Window_Features *)wf, x, y, w, h);
2161 #else
2162
2163    if (!wf || !x || !y || !w || !h) return;
2164    /* What to do with these ?
2165       (void)wf;
2166       (void)x;
2167       (void)y;
2168       (void)w;
2169       (void)h;
2170     */
2171
2172 #endif
2173 }
2174
2175 // TODO: use all ewk_view_zoom stuff to implement bring-in and
2176 // animated zoom like elm_photocam. Should be simple to use, must not
2177 // expose every single bit to users!
2178
2179 #endif