bdea84d2143dbd6029aa92ef19f65693e655a553
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_view.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2011 Samsung Electronics
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #define __STDC_FORMAT_MACROS
22 #include "config.h"
23 #include "ewk_view.h"
24
25 #include "BackForwardListImpl.h"
26 #include "Chrome.h"
27 #include "ChromeClientEfl.h"
28 #include "ContextMenuController.h"
29 #include "DocumentLoader.h"
30 #include "DragClientEfl.h"
31 #include "EWebKit.h"
32 #include "EditorClientEfl.h"
33 #include "EventHandler.h"
34 #include "FocusController.h"
35 #include "FrameLoaderClientEfl.h"
36 #include "FrameView.h"
37 #include "GraphicsContext.h"
38 #include "HTMLElement.h"
39 #include "HTMLInputElement.h"
40 #include "HTMLNames.h"
41 #include "InspectorClientEfl.h"
42 #include "IntSize.h"
43 #include "PlatformMouseEvent.h"
44 #include "PopupMenuClient.h"
45 #include "ProgressTracker.h"
46 #include "ewk_private.h"
47
48 #include <Ecore.h>
49 #include <Eina.h>
50 #include <Evas.h>
51 #include <eina_safety_checks.h>
52 #include <inttypes.h>
53 #include <sys/time.h>
54
55 #define ZOOM_MIN (0.05)
56 #define ZOOM_MAX (4.0)
57
58 #define DEVICE_PIXEL_RATIO (1.0)
59
60 static const char EWK_VIEW_TYPE_STR[] = "EWK_View";
61
62 static const size_t EWK_VIEW_REPAINTS_SIZE_INITIAL = 32;
63 static const size_t EWK_VIEW_REPAINTS_SIZE_STEP = 8;
64 static const size_t EWK_VIEW_REPAINTS_SIZE_MAX_FREE = 64;
65
66 static const size_t EWK_VIEW_SCROLLS_SIZE_INITIAL = 8;
67 static const size_t EWK_VIEW_SCROLLS_SIZE_STEP = 2;
68 static const size_t EWK_VIEW_SCROLLS_SIZE_MAX_FREE = 32;
69
70 struct _Ewk_View_Private_Data {
71     WebCore::Page* page;
72     WebCore::Settings* page_settings;
73     WebCore::Frame* main_frame;
74     WebCore::ViewportArguments viewport_arguments;
75     Ewk_History* history;
76     struct {
77         Ewk_Menu menu;
78         WebCore::PopupMenuClient* menu_client;
79     } popup;
80     struct {
81         Eina_Rectangle* array;
82         size_t count;
83         size_t allocated;
84     } repaints;
85     struct {
86         Ewk_Scroll_Request* array;
87         size_t count;
88         size_t allocated;
89     } scrolls;
90     unsigned int imh; /**< input method hints */
91     struct {
92         Eina_Bool view_cleared:1;
93         Eina_Bool need_touch_events:1;
94     } flags;
95     struct {
96         const char* user_agent;
97         const char* user_stylesheet;
98         const char* encoding_default;
99         const char* encoding_custom;
100         const char* theme;
101         const char* local_storage_database_path;
102         int font_minimum_size;
103         int font_minimum_logical_size;
104         int font_default_size;
105         int font_monospace_size;
106         const char* font_standard;
107         const char* font_cursive;
108         const char* font_monospace;
109         const char* font_fantasy;
110         const char* font_serif;
111         const char* font_sans_serif;
112         Eina_Bool auto_load_images:1;
113         Eina_Bool auto_shrink_images:1;
114         Eina_Bool enable_auto_resize_window:1;
115         Eina_Bool enable_developer_extras:1;
116         Eina_Bool enable_scripts:1;
117         Eina_Bool enable_plugins:1;
118         Eina_Bool enable_frame_flattening:1;
119         Eina_Bool encoding_detector:1;
120         Eina_Bool scripts_window_open:1;
121         Eina_Bool resizable_textareas:1;
122         Eina_Bool private_browsing:1;
123         Eina_Bool caret_browsing:1;
124         Eina_Bool spatial_navigation:1;
125         Eina_Bool local_storage:1;
126         Eina_Bool offline_app_cache: 1;
127         Eina_Bool page_cache: 1;
128         struct {
129             float min_scale;
130             float max_scale;
131             Eina_Bool user_scalable:1;
132         } zoom_range;
133         float device_pixel_ratio;
134     } settings;
135     struct {
136         struct {
137             double start;
138             double end;
139             double duration;
140         } time;
141         struct {
142             float start;
143             float end;
144             float range;
145         } zoom;
146         struct {
147             Evas_Coord x, y;
148         } center;
149         Ecore_Animator* animator;
150     } animated_zoom;
151 };
152
153 #ifndef EWK_TYPE_CHECK
154 #define EWK_VIEW_TYPE_CHECK(o, ...) do { } while (0)
155 #else
156 #define EWK_VIEW_TYPE_CHECK(o, ...)                                     \
157     do {                                                                \
158         const char* _tmp_otype = evas_object_type_get(o);               \
159         const Evas_Smart* _tmp_s = evas_object_smart_smart_get(o);      \
160         if (EINA_UNLIKELY(!_tmp_s)) {                                   \
161             EINA_LOG_CRIT                                               \
162                 ("%p (%s) is not a smart object!", o,                   \
163                  _tmp_otype ? _tmp_otype : "(null)");                   \
164             return __VA_ARGS__;                                         \
165         }                                                               \
166         const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \
167         if (EINA_UNLIKELY(!_tmp_sc)) {                                  \
168             EINA_LOG_CRIT                                               \
169                 ("%p (%s) is not a smart object!", o,                   \
170                  _tmp_otype ? _tmp_otype : "(null)");                   \
171             return __VA_ARGS__;                                         \
172         }                                                               \
173         if (EINA_UNLIKELY(_tmp_sc->data != EWK_VIEW_TYPE_STR)) {        \
174             EINA_LOG_CRIT                                               \
175                 ("%p (%s) is not of an ewk_view (need %p, got %p)!",    \
176                  o, _tmp_otype ? _tmp_otype : "(null)",                 \
177                  EWK_VIEW_TYPE_STR, _tmp_sc->data);                     \
178             return __VA_ARGS__;                                         \
179         }                                                               \
180     } while (0)
181 #endif
182
183 #define EWK_VIEW_SD_GET(o, ptr)                                 \
184     Ewk_View_Smart_Data* ptr = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o)
185
186 #define EWK_VIEW_SD_GET_OR_RETURN(o, ptr, ...)          \
187     EWK_VIEW_TYPE_CHECK(o, __VA_ARGS__);                \
188     EWK_VIEW_SD_GET(o, ptr);                            \
189     if (!ptr) {                                         \
190         CRITICAL("no smart data for object %p (%s)",    \
191                  o, evas_object_type_get(o));           \
192         return __VA_ARGS__;                             \
193     }
194
195 #define EWK_VIEW_PRIV_GET(sd, ptr)              \
196     Ewk_View_Private_Data* ptr = sd->_priv
197
198 #define EWK_VIEW_PRIV_GET_OR_RETURN(sd, ptr, ...)               \
199     EWK_VIEW_PRIV_GET(sd, ptr);                                 \
200     if (!ptr) {                                                 \
201         CRITICAL("no private data for object %p (%s)",          \
202                  sd->self, evas_object_type_get(sd->self));     \
203         return __VA_ARGS__;                                     \
204     }
205
206 static void _ewk_view_smart_changed(Ewk_View_Smart_Data* sd)
207 {
208     if (sd->changed.any)
209         return;
210     sd->changed.any = EINA_TRUE;
211     evas_object_smart_changed(sd->self);
212 }
213
214 static Eina_Bool _ewk_view_repaints_resize(Ewk_View_Private_Data* priv, size_t size)
215 {
216     void* tmp = realloc(priv->repaints.array, size * sizeof(Eina_Rectangle));
217     if (!tmp) {
218         CRITICAL("could not realloc repaints array to %zu elements.", size);
219         return EINA_FALSE;
220     }
221     priv->repaints.allocated = size;
222     priv->repaints.array = (Eina_Rectangle*)tmp;
223     return EINA_TRUE;
224 }
225
226 static void _ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
227 {
228     Eina_Rectangle* r;
229
230     // fprintf(stderr, ">>> repaint requested: %d,%d+%dx%d\n", x, y, w, h);
231     if (priv->repaints.allocated == priv->repaints.count) {
232         size_t size;
233         if (!priv->repaints.allocated)
234             size = EWK_VIEW_REPAINTS_SIZE_INITIAL;
235         else
236             size = priv->repaints.allocated + EWK_VIEW_REPAINTS_SIZE_STEP;
237         if (!_ewk_view_repaints_resize(priv, size))
238             return;
239     }
240
241     r = priv->repaints.array + priv->repaints.count;
242     priv->repaints.count++;
243
244     r->x = x;
245     r->y = y;
246     r->w = w;
247     r->h = h;
248
249     DBG("add repaint %d,%d+%dx%d", x, y, w, h);
250 }
251
252 static void _ewk_view_repaints_flush(Ewk_View_Private_Data* priv)
253 {
254     priv->repaints.count = 0;
255     if (priv->repaints.allocated <= EWK_VIEW_REPAINTS_SIZE_MAX_FREE)
256         return;
257     _ewk_view_repaints_resize(priv, EWK_VIEW_REPAINTS_SIZE_MAX_FREE);
258 }
259
260 static Eina_Bool _ewk_view_scrolls_resize(Ewk_View_Private_Data* priv, size_t size)
261 {
262     void* tmp = realloc(priv->scrolls.array, size * sizeof(Ewk_Scroll_Request));
263     if (!tmp) {
264         CRITICAL("could not realloc scrolls array to %zu elements.", size);
265         return EINA_FALSE;
266     }
267     priv->scrolls.allocated = size;
268     priv->scrolls.array = (Ewk_Scroll_Request*)tmp;
269     return EINA_TRUE;
270 }
271
272 static void _ewk_view_scroll_add(Ewk_View_Private_Data* priv, Evas_Coord dx, Evas_Coord dy, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool main_scroll)
273 {
274     Ewk_Scroll_Request* r;
275     Ewk_Scroll_Request* r_end;
276     Evas_Coord x2 = x + w, y2 = y + h;
277
278     r = priv->scrolls.array;
279     r_end = r + priv->scrolls.count;
280     for (; r < r_end; r++) {
281         if (r->x == x && r->y == y && r->w == w && r->h == h) {
282             DBG("region already scrolled %d,%d+%dx%d %+03d,%+03d add "
283                 "%+03d,%+03d",
284                 r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy);
285             r->dx += dx;
286             r->dy += dy;
287             return;
288         }
289         if ((x <= r->x && x2 >= r->x2) && (y <= r->y && y2 >= r->y2)) {
290             DBG("old viewport (%d,%d+%dx%d %+03d,%+03d) was scrolled itself, "
291                 "add %+03d,%+03d",
292                 r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy);
293             r->x += dx;
294             r->y += dy;
295         }
296     }
297
298     if (priv->scrolls.allocated == priv->scrolls.count) {
299         size_t size;
300         if (!priv->scrolls.allocated)
301             size = EWK_VIEW_SCROLLS_SIZE_INITIAL;
302         else
303             size = priv->scrolls.allocated + EWK_VIEW_SCROLLS_SIZE_STEP;
304         if (!_ewk_view_scrolls_resize(priv, size))
305             return;
306     }
307
308     r = priv->scrolls.array + priv->scrolls.count;
309     priv->scrolls.count++;
310
311     r->x = x;
312     r->y = y;
313     r->w = w;
314     r->h = h;
315     r->x2 = x2;
316     r->y2 = y2;
317     r->dx = dx;
318     r->dy = dy;
319     r->main_scroll = main_scroll;
320     DBG("add scroll in region: %d,%d+%dx%d %+03d,%+03d", x, y, w, h, dx, dy);
321
322     Eina_Rectangle* pr;
323     Eina_Rectangle* pr_end;
324     size_t count;
325     pr = priv->repaints.array;
326     count = priv->repaints.count;
327     pr_end = pr + count;
328     for (; pr < pr_end; pr++) {
329         pr->x += dx;
330         pr->y += dy;
331     }
332 }
333
334 static void _ewk_view_scrolls_flush(Ewk_View_Private_Data* priv)
335 {
336     priv->scrolls.count = 0;
337     if (priv->scrolls.allocated <= EWK_VIEW_SCROLLS_SIZE_MAX_FREE)
338         return;
339     _ewk_view_scrolls_resize(priv, EWK_VIEW_SCROLLS_SIZE_MAX_FREE);
340 }
341
342 // Default Event Handling //////////////////////////////////////////////
343 static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* sd)
344 {
345     EWK_VIEW_PRIV_GET(sd, priv);
346     WebCore::FocusController* fc = priv->page->focusController();
347     DBG("o=%p, fc=%p", sd->self, fc);
348     EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE);
349
350     fc->setActive(true);
351     fc->setFocused(true);
352     return EINA_TRUE;
353 }
354
355 static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* sd)
356 {
357     EWK_VIEW_PRIV_GET(sd, priv);
358     WebCore::FocusController* fc = priv->page->focusController();
359     DBG("o=%p, fc=%p", sd->self, fc);
360     EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE);
361
362     fc->setActive(false);
363     fc->setFocused(false);
364     return EINA_TRUE;
365 }
366
367 static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Wheel* ev)
368 {
369     return ewk_frame_feed_mouse_wheel(sd->main_frame, ev);
370 }
371
372 static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Down* ev)
373 {
374     return ewk_frame_feed_mouse_down(sd->main_frame, ev);
375 }
376
377 static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Up* ev)
378 {
379     return ewk_frame_feed_mouse_up(sd->main_frame, ev);
380 }
381
382 static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Move* ev)
383 {
384     return ewk_frame_feed_mouse_move(sd->main_frame, ev);
385 }
386
387 static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Down* ev)
388 {
389     Evas_Object* frame = ewk_view_frame_focused_get(sd->self);
390
391     if (!frame)
392         frame = sd->main_frame;
393
394     return ewk_frame_feed_key_down(frame, ev);
395 }
396
397 static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Up* ev)
398 {
399     Evas_Object* frame = ewk_view_frame_focused_get(sd->self);
400
401     if (!frame)
402         frame = sd->main_frame;
403
404     return ewk_frame_feed_key_up(frame, ev);
405 }
406
407 static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data* sd, const char* message, unsigned int lineNumber, const char* sourceID)
408 {
409     INF("console message: %s @%d: %s\n", sourceID, lineNumber, message);
410 }
411
412 static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message)
413 {
414     INF("javascript alert: %s\n", message);
415 }
416
417 static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message)
418 {
419     INF("javascript confirm: %s", message);
420     INF("javascript confirm (HARD CODED)? YES");
421     return EINA_TRUE;
422 }
423
424 static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data* sd)
425 {
426     INF("should interrupt javascript?\n"
427             "\t(HARD CODED) NO");
428     return EINA_FALSE;
429 }
430
431 static Eina_Bool _ewk_view_smart_run_javascript_prompt(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
432 {
433     *value = strdup("test");
434     Eina_Bool ret = EINA_TRUE;
435     INF("javascript prompt:\n"
436             "\t      message: %s\n"
437             "\tdefault value: %s\n"
438             "\tgiving answer: %s\n"
439             "\t       button: %s", message, defaultValue, *value, ret?"ok":"cancel");
440
441     return ret;
442 }
443
444 // Event Handling //////////////////////////////////////////////////////
445 static void _ewk_view_on_focus_in(void* data, Evas* e, Evas_Object* o, void* event_info)
446 {
447     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
448     EINA_SAFETY_ON_NULL_RETURN(sd->api);
449     EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_in);
450     sd->api->focus_in(sd);
451 }
452
453 static void _ewk_view_on_focus_out(void* data, Evas* e, Evas_Object* o, void* event_info)
454 {
455     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
456     EINA_SAFETY_ON_NULL_RETURN(sd->api);
457     EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_out);
458     sd->api->focus_out(sd);
459 }
460
461 static void _ewk_view_on_mouse_wheel(void* data, Evas* e, Evas_Object* o, void* event_info)
462 {
463     Evas_Event_Mouse_Wheel* ev = (Evas_Event_Mouse_Wheel*)event_info;
464     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
465     EINA_SAFETY_ON_NULL_RETURN(sd->api);
466     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_wheel);
467     sd->api->mouse_wheel(sd, ev);
468 }
469
470 static void _ewk_view_on_mouse_down(void* data, Evas* e, Evas_Object* o, void* event_info)
471 {
472     Evas_Event_Mouse_Down* ev = (Evas_Event_Mouse_Down*)event_info;
473     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
474     EINA_SAFETY_ON_NULL_RETURN(sd->api);
475     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down);
476     sd->api->mouse_down(sd, ev);
477 }
478
479 static void _ewk_view_on_mouse_up(void* data, Evas* e, Evas_Object* o, void* event_info)
480 {
481     Evas_Event_Mouse_Up* ev = (Evas_Event_Mouse_Up*)event_info;
482     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
483     EINA_SAFETY_ON_NULL_RETURN(sd->api);
484     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up);
485     sd->api->mouse_up(sd, ev);
486 }
487
488 static void _ewk_view_on_mouse_move(void* data, Evas* e, Evas_Object* o, void* event_info)
489 {
490     Evas_Event_Mouse_Move* ev = (Evas_Event_Mouse_Move*)event_info;
491     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
492     EINA_SAFETY_ON_NULL_RETURN(sd->api);
493     EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move);
494     sd->api->mouse_move(sd, ev);
495 }
496
497 static void _ewk_view_on_key_down(void* data, Evas* e, Evas_Object* o, void* event_info)
498 {
499     Evas_Event_Key_Down* ev = (Evas_Event_Key_Down*)event_info;
500     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
501     EINA_SAFETY_ON_NULL_RETURN(sd->api);
502     EINA_SAFETY_ON_NULL_RETURN(sd->api->key_down);
503     sd->api->key_down(sd, ev);
504 }
505
506 static void _ewk_view_on_key_up(void* data, Evas* e, Evas_Object* o, void* event_info)
507 {
508     Evas_Event_Key_Up* ev = (Evas_Event_Key_Up*)event_info;
509     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
510     EINA_SAFETY_ON_NULL_RETURN(sd->api);
511     EINA_SAFETY_ON_NULL_RETURN(sd->api->key_up);
512     sd->api->key_up(sd, ev);
513 }
514
515 static WTF::PassRefPtr<WebCore::Frame> _ewk_view_core_frame_new(Ewk_View_Smart_Data* sd, Ewk_View_Private_Data* priv, WebCore::HTMLFrameOwnerElement* owner)
516 {
517     WebCore::FrameLoaderClientEfl* flc = new WebCore::FrameLoaderClientEfl(sd->self);
518     if (!flc) {
519         CRITICAL("Could not create frame loader client.");
520         return 0;
521     }
522     flc->setCustomUserAgent(String::fromUTF8(priv->settings.user_agent));
523
524     return WebCore::Frame::create(priv->page, owner, flc);
525 }
526
527 static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
528
529 static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* sd)
530 {
531     Ewk_View_Private_Data* priv =
532         (Ewk_View_Private_Data*)calloc(1, sizeof(Ewk_View_Private_Data));
533     AtomicString s;
534     WebCore::KURL url;
535
536     if (!priv) {
537         CRITICAL("could not allocate Ewk_View_Private_Data");
538         return 0;
539     }
540
541     WebCore::Page::PageClients pageClients;
542     pageClients.chromeClient = static_cast<WebCore::ChromeClient*>(new WebCore::ChromeClientEfl(sd->self));
543     pageClients.editorClient = static_cast<WebCore::EditorClient*>(new WebCore::EditorClientEfl(sd->self));
544     pageClients.dragClient = static_cast<WebCore::DragClient*>(new WebCore::DragClientEfl);
545     pageClients.inspectorClient = static_cast<WebCore::InspectorClient*>(new WebCore::InspectorClientEfl);
546     priv->page = new WebCore::Page(pageClients);
547     if (!priv->page) {
548         CRITICAL("Could not create WebKit Page");
549         goto error_page;
550     }
551
552     priv->page_settings = priv->page->settings();
553     if (!priv->page_settings) {
554         CRITICAL("Could not get page settings.");
555         goto error_settings;
556     }
557
558     priv->viewport_arguments.width = WebCore::ViewportArguments::ValueAuto;
559     priv->viewport_arguments.height = WebCore::ViewportArguments::ValueAuto;
560     priv->viewport_arguments.initialScale = WebCore::ViewportArguments::ValueAuto;
561     priv->viewport_arguments.minimumScale = WebCore::ViewportArguments::ValueAuto;
562     priv->viewport_arguments.maximumScale = WebCore::ViewportArguments::ValueAuto;
563     priv->viewport_arguments.targetDensityDpi = WebCore::ViewportArguments::ValueAuto;
564     priv->viewport_arguments.userScalable = EINA_TRUE;
565
566     priv->page_settings->setLoadsImagesAutomatically(true);
567     priv->page_settings->setDefaultFixedFontSize(12);
568     priv->page_settings->setDefaultFontSize(16);
569     priv->page_settings->setSerifFontFamily("serif");
570     priv->page_settings->setFixedFontFamily("monotype");
571     priv->page_settings->setSansSerifFontFamily("sans");
572     priv->page_settings->setStandardFontFamily("sans");
573     priv->page_settings->setJavaScriptEnabled(true);
574     priv->page_settings->setPluginsEnabled(true);
575     priv->page_settings->setLocalStorageEnabled(true);
576     priv->page_settings->setOfflineWebApplicationCacheEnabled(true);
577     priv->page_settings->setUsesPageCache(true);
578     priv->page_settings->setUsesEncodingDetector(false);
579
580     url = priv->page_settings->userStyleSheetLocation();
581     priv->settings.user_stylesheet = eina_stringshare_add(url.string().utf8().data());
582
583     priv->settings.encoding_default = eina_stringshare_add
584         (priv->page_settings->defaultTextEncodingName().utf8().data());
585     priv->settings.encoding_custom = 0;
586
587     s = priv->page_settings->localStorageDatabasePath();
588     priv->settings.local_storage_database_path = eina_stringshare_add(s.string().utf8().data());
589
590     priv->settings.font_minimum_size = priv->page_settings->minimumFontSize();
591     priv->settings.font_minimum_logical_size = priv->page_settings->minimumLogicalFontSize();
592     priv->settings.font_default_size = priv->page_settings->defaultFontSize();
593     priv->settings.font_monospace_size = priv->page_settings->defaultFixedFontSize();
594
595     s = priv->page_settings->standardFontFamily();
596     priv->settings.font_standard = eina_stringshare_add(s.string().utf8().data());
597     s = priv->page_settings->cursiveFontFamily();
598     priv->settings.font_cursive = eina_stringshare_add(s.string().utf8().data());
599     s = priv->page_settings->fixedFontFamily();
600     priv->settings.font_monospace = eina_stringshare_add(s.string().utf8().data());
601     s = priv->page_settings->fantasyFontFamily();
602     priv->settings.font_fantasy = eina_stringshare_add(s.string().utf8().data());
603     s = priv->page_settings->serifFontFamily();
604     priv->settings.font_serif = eina_stringshare_add(s.string().utf8().data());
605     s = priv->page_settings->sansSerifFontFamily();
606     priv->settings.font_sans_serif = eina_stringshare_add(s.string().utf8().data());
607
608     priv->settings.auto_load_images = priv->page_settings->loadsImagesAutomatically();
609     priv->settings.auto_shrink_images = priv->page_settings->shrinksStandaloneImagesToFit();
610     priv->settings.enable_auto_resize_window = EINA_TRUE;
611     priv->settings.enable_developer_extras = priv->page_settings->developerExtrasEnabled();
612     priv->settings.enable_scripts = priv->page_settings->isJavaScriptEnabled();
613     priv->settings.enable_plugins = priv->page_settings->arePluginsEnabled();
614     priv->settings.enable_frame_flattening = priv->page_settings->frameFlatteningEnabled();
615     priv->settings.scripts_window_open = priv->page_settings->allowScriptsToCloseWindows();
616     priv->settings.resizable_textareas = priv->page_settings->textAreasAreResizable();
617     priv->settings.private_browsing = priv->page_settings->privateBrowsingEnabled();
618     priv->settings.caret_browsing = priv->page_settings->caretBrowsingEnabled();
619     priv->settings.spatial_navigation = priv->page_settings->isSpatialNavigationEnabled();
620     priv->settings.local_storage = priv->page_settings->localStorageEnabled();
621     priv->settings.offline_app_cache = true; // XXX no function to read setting; this keeps the original setting
622     priv->settings.page_cache = priv->page_settings->usesPageCache();
623     priv->settings.encoding_detector = priv->page_settings->usesEncodingDetector();
624
625     priv->settings.user_agent = ewk_settings_default_user_agent_get();
626
627     // Since there's no scale separated from zooming in webkit-efl, this functionality of
628     // viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl,
629     // this functionality will be modified by the scale zoom patch.
630     priv->settings.zoom_range.min_scale = ZOOM_MIN;
631     priv->settings.zoom_range.max_scale = ZOOM_MAX;
632     priv->settings.zoom_range.user_scalable = EINA_TRUE;
633     priv->settings.device_pixel_ratio = DEVICE_PIXEL_RATIO;
634
635     priv->main_frame = _ewk_view_core_frame_new(sd, priv, 0).get();
636     if (!priv->main_frame) {
637         CRITICAL("Could not create main frame.");
638         goto error_main_frame;
639     }
640
641     priv->history = ewk_history_new(static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList()));
642     if (!priv->history) {
643         CRITICAL("Could not create history instance for view.");
644         goto error_history;
645     }
646
647     return priv;
648
649 error_history:
650     // delete priv->main_frame; /* do not delete priv->main_frame */
651 error_main_frame:
652 error_settings:
653     delete priv->page;
654 error_page:
655     free(priv);
656     return 0;
657 }
658
659 static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
660 {
661     if (!priv)
662         return;
663
664     /* do not delete priv->main_frame */
665
666     free(priv->repaints.array);
667     free(priv->scrolls.array);
668
669     eina_stringshare_del(priv->settings.user_agent);
670     eina_stringshare_del(priv->settings.user_stylesheet);
671     eina_stringshare_del(priv->settings.encoding_default);
672     eina_stringshare_del(priv->settings.encoding_custom);
673     eina_stringshare_del(priv->settings.font_standard);
674     eina_stringshare_del(priv->settings.font_cursive);
675     eina_stringshare_del(priv->settings.font_monospace);
676     eina_stringshare_del(priv->settings.font_fantasy);
677     eina_stringshare_del(priv->settings.font_serif);
678     eina_stringshare_del(priv->settings.font_sans_serif);
679     eina_stringshare_del(priv->settings.local_storage_database_path);
680
681     if (priv->animated_zoom.animator)
682         ecore_animator_del(priv->animated_zoom.animator);
683
684     ewk_history_free(priv->history);
685
686     delete priv->page;
687     free(priv);
688 }
689
690 static void _ewk_view_smart_add(Evas_Object* o)
691 {
692     const Evas_Smart* smart = evas_object_smart_smart_get(o);
693     const Evas_Smart_Class* sc = evas_smart_class_get(smart);
694     const Ewk_View_Smart_Class* api = (const Ewk_View_Smart_Class*)sc;
695     EINA_SAFETY_ON_NULL_RETURN(api->backing_store_add);
696     EWK_VIEW_SD_GET(o, sd);
697
698     if (!sd) {
699         sd = (Ewk_View_Smart_Data*)calloc(1, sizeof(Ewk_View_Smart_Data));
700         if (!sd)
701             CRITICAL("could not allocate Ewk_View_Smart_Data");
702         else
703             evas_object_smart_data_set(o, sd);
704     }
705
706     sd->bg_color.r = 255;
707     sd->bg_color.g = 255;
708     sd->bg_color.b = 255;
709     sd->bg_color.a = 255;
710
711     sd->self = o;
712     sd->_priv = _ewk_view_priv_new(sd);
713     sd->api = api;
714
715     _parent_sc.add(o);
716
717     if (!sd->_priv)
718         return;
719
720     EWK_VIEW_PRIV_GET(sd, priv);
721
722     sd->backing_store = api->backing_store_add(sd);
723     if (!sd->backing_store) {
724         ERR("Could not create backing store object.");
725         return;
726     }
727
728     evas_object_smart_member_add(sd->backing_store, o);
729     evas_object_show(sd->backing_store);
730     evas_object_pass_events_set(sd->backing_store, EINA_TRUE);
731
732     sd->events_rect = evas_object_rectangle_add(sd->base.evas);
733     evas_object_color_set(sd->events_rect, 0, 0, 0, 0);
734     evas_object_smart_member_add(sd->events_rect, o);
735     evas_object_show(sd->events_rect);
736
737     sd->main_frame = ewk_frame_add(sd->base.evas);
738     if (!sd->main_frame) {
739         ERR("Could not create main frame object.");
740         return;
741     }
742
743     if (!ewk_frame_init(sd->main_frame, o, priv->main_frame)) {
744         ERR("Could not initialize main frme object.");
745         evas_object_del(sd->main_frame);
746         sd->main_frame = 0;
747
748         delete priv->main_frame;
749         priv->main_frame = 0;
750         return;
751     }
752
753     evas_object_name_set(sd->main_frame, "EWK_Frame:main");
754     evas_object_smart_member_add(sd->main_frame, o);
755     evas_object_show(sd->main_frame);
756
757 #define CONNECT(s, c) evas_object_event_callback_add(o, s, c, sd)
758     CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in);
759     CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out);
760     CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel);
761     CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down);
762     CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up);
763     CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move);
764     CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down);
765     CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up);
766 #undef CONNECT
767 }
768
769 static void _ewk_view_smart_del(Evas_Object* o)
770 {
771     EWK_VIEW_SD_GET(o, sd);
772     Ewk_View_Private_Data* priv = sd ? sd->_priv : 0;
773
774     ewk_view_stop(o);
775     _parent_sc.del(o);
776     _ewk_view_priv_del(priv);
777 }
778
779 static void _ewk_view_smart_resize(Evas_Object* o, Evas_Coord w, Evas_Coord h)
780 {
781     EWK_VIEW_SD_GET(o, sd);
782
783     // these should be queued and processed in calculate as well!
784     evas_object_resize(sd->backing_store, w, h);
785
786     sd->changed.size = EINA_TRUE;
787     _ewk_view_smart_changed(sd);
788 }
789
790 static void _ewk_view_smart_move(Evas_Object* o, Evas_Coord x, Evas_Coord y)
791 {
792     EWK_VIEW_SD_GET(o, sd);
793     sd->changed.position = EINA_TRUE;
794     _ewk_view_smart_changed(sd);
795 }
796
797 static void _ewk_view_smart_calculate(Evas_Object* o)
798 {
799     EWK_VIEW_SD_GET(o, sd);
800     EWK_VIEW_PRIV_GET(sd, priv);
801     EINA_SAFETY_ON_NULL_RETURN(sd->api->contents_resize);
802     EINA_SAFETY_ON_NULL_RETURN(sd->api->scrolls_process);
803     EINA_SAFETY_ON_NULL_RETURN(sd->api->repaints_process);
804     Evas_Coord x, y, w, h;
805
806     sd->changed.any = EINA_FALSE;
807
808     if (!sd->main_frame || !priv->main_frame)
809         return;
810
811     evas_object_geometry_get(o, &x, &y, &w, &h);
812
813     DBG("o=%p geo=[%d, %d + %dx%d], changed: size=%hhu, "
814         "scrolls=%zu, repaints=%zu",
815         o, x, y, w, h, sd->changed.size,
816         priv->scrolls.count, priv->repaints.count);
817
818     if (sd->changed.size && ((w != sd->view.w) || (h != sd->view.h))) {
819         WebCore::FrameView* view = priv->main_frame->view();
820         if (view) {
821             view->resize(w, h);
822             view->forceLayout();
823             view->adjustViewSize();
824         }
825         evas_object_resize(sd->main_frame, w, h);
826         evas_object_resize(sd->events_rect, w, h);
827         sd->changed.frame_rect = EINA_TRUE;
828         sd->view.w = w;
829         sd->view.h = h;
830
831         // This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set).
832         evas_object_smart_callback_call(o, "view,resized", 0);
833     }
834     sd->changed.size = EINA_FALSE;
835
836     if (sd->changed.position && ((x != sd->view.x) || (y != sd->view.y))) {
837         evas_object_move(sd->main_frame, x, y);
838         evas_object_move(sd->backing_store, x, y);
839         evas_object_move(sd->events_rect, x, y);
840         sd->changed.frame_rect = EINA_TRUE;
841         sd->view.x = x;
842         sd->view.y = y;
843     }
844     sd->changed.position = EINA_FALSE;
845
846     ewk_view_layout_if_needed_recursive(sd->_priv);
847
848     if (!sd->api->scrolls_process(sd))
849         ERR("failed to process scrolls.");
850     _ewk_view_scrolls_flush(priv);
851
852     if (!sd->api->repaints_process(sd))
853         ERR("failed to process repaints.");
854     _ewk_view_repaints_flush(priv);
855
856     if (sd->changed.frame_rect) {
857         WebCore::FrameView* view = priv->main_frame->view();
858         view->frameRectsChanged(); /* force tree to get position from root */
859         sd->changed.frame_rect = EINA_FALSE;
860     }
861 }
862
863 static void _ewk_view_smart_show(Evas_Object *o)
864 {
865     EWK_VIEW_SD_GET(o, sd);
866
867     if (evas_object_clipees_get(sd->base.clipper))
868         evas_object_show(sd->base.clipper);
869     evas_object_show(sd->backing_store);
870 }
871
872 static void _ewk_view_smart_hide(Evas_Object *o)
873 {
874     EWK_VIEW_SD_GET(o, sd);
875
876     evas_object_hide(sd->base.clipper);
877     evas_object_hide(sd->backing_store);
878 }
879
880 static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data* sd, int w, int h)
881 {
882     return EINA_TRUE;
883 }
884
885 static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* sd, float zoom, Evas_Coord cx, Evas_Coord cy)
886 {
887     double px, py;
888     Evas_Coord x, y, w, h;
889     Eina_Bool ret;
890
891     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
892     ewk_frame_scroll_pos_get(sd->main_frame, &x, &y);
893
894     if (w + sd->view.w > 0)
895         px = (double)(x + cx) / (w + sd->view.w);
896     else
897         px = 0.0;
898
899     if (h + sd->view.h > 0)
900         py = (double)(y + cy) / (h + sd->view.h);
901     else
902         py = 0.0;
903
904     ret = ewk_frame_zoom_set(sd->main_frame, zoom);
905
906     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
907     x = (w + sd->view.w) * px - cx;
908     y = (h + sd->view.h) * py - cy;
909     ewk_frame_scroll_set(sd->main_frame, x, y);
910     return ret;
911 }
912
913 static void _ewk_view_smart_flush(Ewk_View_Smart_Data* sd)
914 {
915     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
916     _ewk_view_repaints_flush(priv);
917     _ewk_view_scrolls_flush(priv);
918 }
919
920 static Eina_Bool _ewk_view_smart_pre_render_region(Ewk_View_Smart_Data* sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
921 {
922     WRN("not supported by engine. sd=%p area=%d,%d+%dx%d, zoom=%f",
923         sd, x, y, w, h, zoom);
924     return EINA_FALSE;
925 }
926
927 static Eina_Bool _ewk_view_smart_pre_render_relative_radius(Ewk_View_Smart_Data* sd, unsigned int n, float zoom)
928 {
929     WRN("not supported by engine. sd=%p, n=%u zoom=%f",
930         sd, n, zoom);
931     return EINA_FALSE;
932 }
933
934 static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* sd)
935 {
936     WRN("not supported by engine. sd=%p", sd);
937 }
938
939 static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* sd)
940 {
941     sd->animated_zoom.zoom.start = 0.0;
942     sd->animated_zoom.zoom.end = 0.0;
943     sd->animated_zoom.zoom.current = 0.0;
944 }
945
946 static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* sd)
947 {
948     EWK_VIEW_PRIV_GET(sd, priv);
949     ecore_animator_del(priv->animated_zoom.animator);
950     priv->animated_zoom.animator = 0;
951     _ewk_view_zoom_animated_mark_stop(sd);
952     evas_object_smart_callback_call(sd->self, "zoom,animated,end", 0);
953 }
954
955 static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv)
956 {
957     double now = ecore_loop_time_get();
958     double delta = now - priv->animated_zoom.time.start;
959
960     if (delta > priv->animated_zoom.time.duration)
961         delta = priv->animated_zoom.time.duration;
962     if (delta < 0.0) // time went back, clock adjusted?
963         delta = 0.0;
964
965     delta /= priv->animated_zoom.time.duration;
966
967     return ((priv->animated_zoom.zoom.range * delta)
968             + priv->animated_zoom.zoom.start);
969 }
970
971 static Eina_Bool _ewk_view_zoom_animator_cb(void* data)
972 {
973     Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data;
974     Evas_Coord cx, cy;
975     EWK_VIEW_PRIV_GET(sd, priv);
976     double now = ecore_loop_time_get();
977
978     cx = priv->animated_zoom.center.x;
979     cy = priv->animated_zoom.center.y;
980
981     // TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2)
982     if (cx >= sd->view.w)
983         cx = sd->view.w - 1;
984     if (cy >= sd->view.h)
985         cy = sd->view.h - 1;
986
987     if ((now >= priv->animated_zoom.time.end)
988         || (now < priv->animated_zoom.time.start)) {
989         _ewk_view_zoom_animated_finish(sd);
990         ewk_view_zoom_set(sd->self, priv->animated_zoom.zoom.end, cx, cy);
991         sd->api->sc.calculate(sd->self);
992         return EINA_FALSE;
993     }
994
995     sd->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv);
996     sd->api->zoom_weak_set(sd, sd->animated_zoom.zoom.current, cx, cy);
997     return EINA_TRUE;
998 }
999
1000 static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* sd)
1001 {
1002     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1003     if (priv->animated_zoom.animator)
1004         return;
1005     priv->animated_zoom.animator = ecore_animator_add
1006         (_ewk_view_zoom_animator_cb, sd);
1007 }
1008
1009 static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(Evas_Object* o)
1010 {
1011     EWK_VIEW_SD_GET(o, sd);
1012     EWK_VIEW_PRIV_GET(sd, priv);
1013
1014     int desktop_width = 980;
1015     int device_dpi = ewk_util_dpi_get();
1016
1017     int available_width = (int) priv->page->chrome()->client()->pageRect().width();
1018     int available_height = (int) priv->page->chrome()->client()->pageRect().height();
1019
1020     int device_width = (int) priv->page->chrome()->client()->windowRect().width();
1021     int device_height = (int) priv->page->chrome()->client()->windowRect().height();
1022
1023     WebCore::IntSize available_size = WebCore::IntSize(available_width, available_height);
1024     WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewport_arguments, desktop_width, device_width, device_height, device_dpi, available_size);
1025
1026     return attributes;
1027 }
1028
1029 static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data *sd)
1030 {
1031     WRN("not supported by engine. sd=%p", sd);
1032     return EINA_FALSE;
1033 }
1034
1035 static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data *sd)
1036 {
1037     WRN("not supported by engine. sd=%p", sd);
1038     return EINA_FALSE;
1039 }
1040
1041 /**
1042  * Sets the smart class api without any backing store, enabling view
1043  * to be inherited.
1044  *
1045  * @param api class definition to be set, all members with the
1046  *        exception of Evas_Smart_Class->data may be overridden. Must
1047  *        @b not be @c 0.
1048  *
1049  * @note Evas_Smart_Class->data is used to implement type checking and
1050  *       is not supposed to be changed/overridden. If you need extra
1051  *       data for your smart class to work, just extend
1052  *       Ewk_View_Smart_Class instead.
1053  *
1054  * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably
1055  *         version mismatch).
1056  *
1057  * @see ewk_view_single_smart_set()
1058  * @see ewk_view_tiled_smart_set()
1059  */
1060 Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class* api)
1061 {
1062     EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE);
1063
1064     if (api->version != EWK_VIEW_SMART_CLASS_VERSION) {
1065         EINA_LOG_CRIT
1066             ("Ewk_View_Smart_Class %p is version %lu while %lu was expected.",
1067              api, api->version, EWK_VIEW_SMART_CLASS_VERSION);
1068         return EINA_FALSE;
1069     }
1070
1071     if (EINA_UNLIKELY(!_parent_sc.add))
1072         evas_object_smart_clipped_smart_set(&_parent_sc);
1073
1074     evas_object_smart_clipped_smart_set(&api->sc);
1075     api->sc.add = _ewk_view_smart_add;
1076     api->sc.del = _ewk_view_smart_del;
1077     api->sc.resize = _ewk_view_smart_resize;
1078     api->sc.move = _ewk_view_smart_move;
1079     api->sc.calculate = _ewk_view_smart_calculate;
1080     api->sc.show = _ewk_view_smart_show;
1081     api->sc.hide = _ewk_view_smart_hide;
1082     api->sc.data = EWK_VIEW_TYPE_STR; /* used by type checking */
1083
1084     api->contents_resize = _ewk_view_smart_contents_resize;
1085     api->zoom_set = _ewk_view_smart_zoom_set;
1086     api->flush = _ewk_view_smart_flush;
1087     api->pre_render_region = _ewk_view_smart_pre_render_region;
1088     api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius;
1089     api->pre_render_cancel = _ewk_view_smart_pre_render_cancel;
1090     api->disable_render = _ewk_view_smart_disable_render;
1091     api->enable_render = _ewk_view_smart_enable_render;
1092
1093     api->focus_in = _ewk_view_smart_focus_in;
1094     api->focus_out = _ewk_view_smart_focus_out;
1095     api->mouse_wheel = _ewk_view_smart_mouse_wheel;
1096     api->mouse_down = _ewk_view_smart_mouse_down;
1097     api->mouse_up = _ewk_view_smart_mouse_up;
1098     api->mouse_move = _ewk_view_smart_mouse_move;
1099     api->key_down = _ewk_view_smart_key_down;
1100     api->key_up = _ewk_view_smart_key_up;
1101
1102     api->add_console_message = _ewk_view_smart_add_console_message;
1103     api->run_javascript_alert = _ewk_view_smart_run_javascript_alert;
1104     api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm;
1105     api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt;
1106     api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript;
1107
1108     return EINA_TRUE;
1109 }
1110
1111 /**
1112  * Set a fixed layout size to be used, dissociating it from viewport size.
1113  *
1114  * Setting a width different than zero enables fixed layout on that
1115  * size. It's automatically scaled based on zoom, but will not change
1116  * if viewport changes.
1117  *
1118  * Setting both @a w and @a h to zero will disable fixed layout.
1119  *
1120  * @param o view object to change fixed layout.
1121  * @param w fixed width to use. This size will be automatically scaled
1122  *        based on zoom level.
1123  * @param h fixed height to use. This size will be automatically scaled
1124  *        based on zoom level.
1125  */
1126 void ewk_view_fixed_layout_size_set(Evas_Object* o, Evas_Coord w, Evas_Coord h)
1127 {
1128     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1129     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1130
1131     WebCore::FrameView* view = priv->main_frame->view();
1132     if (w <= 0 && h <= 0) {
1133         if (!view->useFixedLayout())
1134             return;
1135         view->setUseFixedLayout(EINA_FALSE);
1136     } else {
1137         WebCore::IntSize size = view->fixedLayoutSize();
1138         if (size.width() == w && size.height() == h)
1139             return;
1140         if (view)
1141             view->setFixedLayoutSize(WebCore::IntSize(w, h));
1142     }
1143
1144     if (!view)
1145         return;
1146     view->setUseFixedLayout(EINA_TRUE);
1147     view->forceLayout();
1148 }
1149
1150 /**
1151  * Get fixed layout size in use.
1152  *
1153  * @param o view object to query fixed layout size.
1154  * @param w where to return width. Returns 0 on error or if no fixed
1155  *        layout in use.
1156  * @param h where to return height. Returns 0 on error or if no fixed
1157  *        layout in use.
1158  */
1159 void ewk_view_fixed_layout_size_get(Evas_Object* o, Evas_Coord* w, Evas_Coord* h)
1160 {
1161     if (w)
1162         *w = 0;
1163     if (h)
1164         *h = 0;
1165     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1166     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1167     WebCore::FrameView* view = priv->main_frame->view();
1168     if (view->useFixedLayout()) {
1169         WebCore::IntSize size = view->fixedLayoutSize();
1170         if (w)
1171             *w = size.width();
1172         if (h)
1173             *h = size.height();
1174     }
1175 }
1176
1177 /**
1178  * Set the theme path to be used by this view.
1179  *
1180  * This also sets the theme on the main frame. As frames inherit theme
1181  * from their parent, this will have all frames with unset theme to
1182  * use this one.
1183  *
1184  * @param o view object to change theme.
1185  * @param path theme path, may be @c 0 to reset to default.
1186  */
1187 void ewk_view_theme_set(Evas_Object* o, const char* path)
1188 {
1189     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1190     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
1191     if (!eina_stringshare_replace(&priv->settings.theme, path))
1192         return;
1193     ewk_frame_theme_set(sd->main_frame, path);
1194 }
1195
1196 /**
1197  * Gets the theme set on this frame.
1198  *
1199  * This returns the value set by ewk_view_theme_set().
1200  *
1201  * @param o view object to get theme path.
1202  *
1203  * @return theme path, may be @c 0 if not set.
1204  */
1205 const char* ewk_view_theme_get(Evas_Object* o)
1206 {
1207     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1208     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1209     return priv->settings.theme;
1210 }
1211
1212 /**
1213  * Get the object that represents the main frame.
1214  *
1215  * @param o view object to get main frame.
1216  *
1217  * @return ewk_frame object or @c 0 if none yet.
1218  */
1219 Evas_Object* ewk_view_frame_main_get(const Evas_Object* o)
1220 {
1221     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1222     return sd->main_frame;
1223 }
1224
1225 /**
1226  * Get the currently focused frame object.
1227  *
1228  * @param o view object to get focused frame.
1229  *
1230  * @return ewk_frame object or @c 0 if none yet.
1231  */
1232 Evas_Object* ewk_view_frame_focused_get(const Evas_Object* o)
1233 {
1234     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1235     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1236
1237     WebCore::Frame* core = priv->page->focusController()->focusedFrame();
1238     if (!core)
1239         return 0;
1240
1241     WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(core->loader()->client());
1242     if (!client)
1243         return 0;
1244     return client->webFrame();
1245 }
1246
1247 /**
1248  * Ask main frame to load the given URI.
1249  *
1250  * @param o view object to load uri.
1251  * @param uri uniform resource identifier to load.
1252  *
1253  * @return @c EINA_TRUE on successful request, @c EINA_FALSE on failure.
1254  *         Note that it means the request was done, not that it was
1255  *         satisfied.
1256  */
1257 Eina_Bool ewk_view_uri_set(Evas_Object* o, const char* uri)
1258 {
1259     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1260     return ewk_frame_uri_set(sd->main_frame, uri);
1261 }
1262
1263 /**
1264  * Get the current uri loaded by main frame.
1265  *
1266  * @param o view object to get current uri.
1267  *
1268  * @return current uri reference or @c 0. It's internal, don't change.
1269  */
1270 const char* ewk_view_uri_get(const Evas_Object* o)
1271 {
1272     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1273     return ewk_frame_uri_get(sd->main_frame);
1274 }
1275
1276 /**
1277  * Get the current title of main frame.
1278  *
1279  * @param o view object to get current title.
1280  *
1281  * @return current title reference or @c 0. It's internal, don't change.
1282  */
1283 const char* ewk_view_title_get(const Evas_Object* o)
1284 {
1285     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1286     return ewk_frame_title_get(sd->main_frame);
1287 }
1288
1289 /**
1290  * Gets if main frame is editable.
1291  *
1292  * @param o view object to get editable state.
1293  *
1294  * @return @c EINA_TRUE if editable, @c EINA_FALSE otherwise.
1295  */
1296 Eina_Bool ewk_view_editable_get(const Evas_Object* o)
1297 {
1298     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1299     return ewk_frame_editable_get(sd->main_frame);
1300 }
1301
1302 /**
1303  * Set background color and transparency
1304  *
1305  * Just as in Evas, colors are pre-multiplied, so 50% red is
1306  * (128, 0, 0, 128) and not (255, 0, 0, 128)!
1307  *
1308  * @warning Watch out performance issues with transparency! Object
1309  *          will be handled as transparent image by evas even if the
1310  *          webpage specifies a background color. That mean you'll pay
1311  *          a price even if it's not really transparent, thus
1312  *          scrolling/panning and zooming will be likely slower than
1313  *          if transparency is off.
1314  *
1315  * @param o view object to change.
1316  * @param r red component.
1317  * @param g green component.
1318  * @param b blue component.
1319  * @param a transparency.
1320  */
1321 void ewk_view_bg_color_set(Evas_Object* o, int r, int g, int b, int a)
1322 {
1323     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1324     EINA_SAFETY_ON_NULL_RETURN(sd->api);
1325     EINA_SAFETY_ON_NULL_RETURN(sd->api->bg_color_set);
1326
1327     if (a < 0) {
1328         WRN("Alpha less than zero (%d).", a);
1329         a = 0;
1330     } else if (a > 255) {
1331         WRN("Alpha is larger than 255 (%d).", a);
1332         a = 255;
1333     }
1334
1335 #define CHECK_PREMUL_COLOR(c, a)                                        \
1336     if (c < 0) {                                                        \
1337         WRN("Color component "#c" is less than zero (%d).", c);         \
1338         c = 0;                                                          \
1339     } else if (c > a) {                                                 \
1340         WRN("Color component "#c" is greater than alpha (%d, alpha=%d).", \
1341             c, a);                                                      \
1342         c = a;                                                          \
1343     }
1344     CHECK_PREMUL_COLOR(r, a);
1345     CHECK_PREMUL_COLOR(g, a);
1346     CHECK_PREMUL_COLOR(b, a);
1347 #undef CHECK_PREMUL_COLOR
1348
1349     sd->bg_color.r = r;
1350     sd->bg_color.g = g;
1351     sd->bg_color.b = b;
1352     sd->bg_color.a = a;
1353
1354     sd->api->bg_color_set(sd, r, g, b, a);
1355
1356     WebCore::FrameView* view = sd->_priv->main_frame->view();
1357     if (view) {
1358         WebCore::Color color;
1359
1360         if (!a)
1361             color = WebCore::Color(0, 0, 0, 0);
1362         else if (a == 255)
1363             color = WebCore::Color(r, g, b, a);
1364         else
1365             color = WebCore::Color(r * 255 / a, g * 255 / a, b * 255 / a, a);
1366
1367         view->updateBackgroundRecursively(color, !a);
1368     }
1369 }
1370
1371 /**
1372  * Query if view object background color.
1373  *
1374  * Just as in Evas, colors are pre-multiplied, so 50% red is
1375  * (128, 0, 0, 128) and not (255, 0, 0, 128)!
1376  *
1377  * @param o view object to query.
1378  * @param r where to return red color component.
1379  * @param g where to return green color component.
1380  * @param b where to return blue color component.
1381  * @param a where to return alpha value.
1382  */
1383 void ewk_view_bg_color_get(const Evas_Object* o, int* r, int* g, int* b, int* a)
1384 {
1385     if (r)
1386         *r = 0;
1387     if (g)
1388         *g = 0;
1389     if (b)
1390         *b = 0;
1391     if (a)
1392         *a = 0;
1393     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1394     if (r)
1395         *r = sd->bg_color.r;
1396     if (g)
1397         *g = sd->bg_color.g;
1398     if (b)
1399         *b = sd->bg_color.b;
1400     if (a)
1401         *a = sd->bg_color.a;
1402 }
1403
1404 /**
1405  * Search the given text string in document.
1406  *
1407  * @param o view object where to search text.
1408  * @param string reference string to search.
1409  * @param case_sensitive if search should be case sensitive or not.
1410  * @param forward if search is from cursor and on or backwards.
1411  * @param wrap if search should wrap at end.
1412  *
1413  * @return @c EINA_TRUE if found, @c EINA_FALSE if not or failure.
1414  */
1415 Eina_Bool ewk_view_text_search(const Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap)
1416 {
1417     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1418     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1419     EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE);
1420     WTF::TextCaseSensitivity sensitive;
1421     WebCore::FindDirection direction;
1422
1423     if (case_sensitive)
1424         sensitive = WTF::TextCaseSensitive;
1425     else
1426         sensitive = WTF::TextCaseInsensitive;
1427
1428     if (forward)
1429         direction = WebCore::FindDirectionForward;
1430     else
1431         direction = WebCore::FindDirectionBackward;
1432
1433     return priv->page->findString(String::fromUTF8(string), sensitive, direction, wrap);
1434 }
1435
1436 /**
1437  * Mark matches the given text string in document.
1438  *
1439  * @param o view object where to search text.
1440  * @param string reference string to match.
1441  * @param case_sensitive if match should be case sensitive or not.
1442  * @param highlight if matches should be highlighted.
1443  * @param limit maximum amount of matches, or zero to unlimited.
1444  *
1445  * @return number of matches.
1446  */
1447 unsigned int ewk_view_text_matches_mark(Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit)
1448 {
1449     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1450     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1451     EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0);
1452     WTF::TextCaseSensitivity sensitive;
1453
1454     if (case_sensitive)
1455         sensitive = WTF::TextCaseSensitive;
1456     else
1457         sensitive = WTF::TextCaseInsensitive;
1458
1459     return priv->page->markAllMatchesForText(String::fromUTF8(string), sensitive, highlight, limit);
1460 }
1461
1462 /**
1463  * Reverses the effect of ewk_view_text_matches_mark()
1464  *
1465  * @param o view object where to search text.
1466  *
1467  * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
1468  */
1469 Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* o)
1470 {
1471     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1472     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1473     priv->page->unmarkAllTextMatches();
1474     return EINA_TRUE;
1475 }
1476
1477 /**
1478  * Set if should highlight matches marked with ewk_view_text_matches_mark().
1479  *
1480  * @param o view object where to set if matches are highlighted or not.
1481  * @param highlight if @c EINA_TRUE, matches will be highlighted.
1482  *
1483  * @return @c EINA_TRUE on success, @c EINA_FALSE for failure.
1484  */
1485 Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlight)
1486 {
1487     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1488     return ewk_frame_text_matches_highlight_set(sd->main_frame, highlight);
1489 }
1490
1491 /**
1492  * Get if should highlight matches marked with ewk_view_text_matches_mark().
1493  *
1494  * @param o view object to query if matches are highlighted or not.
1495  *
1496  * @return @c EINA_TRUE if they are highlighted, @c EINA_FALSE otherwise.
1497  */
1498 Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* o)
1499 {
1500     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1501     return ewk_frame_text_matches_highlight_get(sd->main_frame);
1502 }
1503
1504 /**
1505  * Sets if main frame is editable.
1506  *
1507  * @param o view object to set editable state.
1508  * @param editable new state.
1509  *
1510  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1511  */
1512 Eina_Bool ewk_view_editable_set(Evas_Object* o, Eina_Bool editable)
1513 {
1514     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1515     return ewk_frame_editable_set(sd->main_frame, editable);
1516 }
1517
1518 /**
1519  * Get the copy of the selection text.
1520  *
1521  * @param o view object to get selection text.
1522  *
1523  * @return newly allocated string or @c 0 if nothing is selected or failure.
1524  */
1525 char* ewk_view_selection_get(const Evas_Object* o)
1526 {
1527     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1528     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1529     CString s = priv->page->focusController()->focusedOrMainFrame()->editor()->selectedText().utf8();
1530     if (s.isNull())
1531         return 0;
1532     return strdup(s.data());
1533 }
1534
1535 static Eina_Bool _ewk_view_editor_command(Ewk_View_Private_Data* priv, const char* command, const char* value = 0)
1536 {
1537     return priv->page->focusController()->focusedOrMainFrame()->editor()->command(WTF::String::fromUTF8(command)).execute(value);
1538 }
1539
1540 /**
1541  * Executes editor command.
1542  *
1543  * @param o view object to execute command.
1544  * @param command editor command to be executed.
1545  * @param value value to be passed into command.
1546  *
1547  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1548  */
1549 Eina_Bool ewk_view_execute_editor_command(Evas_Object* o, const Ewk_Editor_Command command, const char* value)
1550 {
1551     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1552     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1553
1554     switch (command) {
1555     case EWK_EDITOR_COMMAND_INSERT_IMAGE:
1556         return _ewk_view_editor_command(priv, "InsertImage", value);
1557     case EWK_EDITOR_COMMAND_INSERT_TEXT:
1558         return _ewk_view_editor_command(priv, "InsertText", value);
1559     case EWK_EDITOR_COMMAND_SELECT_NONE:
1560         return _ewk_view_editor_command(priv, "Unselect");
1561     case EWK_EDITOR_COMMAND_SELECT_ALL:
1562         return _ewk_view_editor_command(priv, "SelectAll");
1563     case EWK_EDITOR_COMMAND_SELECT_PARAGRAPH:
1564         return _ewk_view_editor_command(priv, "SelectParagraph");
1565     case EWK_EDITOR_COMMAND_SELECT_SENTENCE:
1566         return _ewk_view_editor_command(priv, "SelectSentence");
1567     case EWK_EDITOR_COMMAND_SELECT_LINE:
1568         return _ewk_view_editor_command(priv, "SelectLine");
1569     case EWK_EDITOR_COMMAND_SELECT_WORD:
1570         return _ewk_view_editor_command(priv, "SelectWord");
1571     default:
1572         return EINA_FALSE;
1573     }
1574 }
1575
1576 #if ENABLE(CONTEXT_MENUS)
1577
1578 /**
1579  * Forwards a request of new Context Menu to WebCore.
1580  *
1581  * @param o View.
1582  * @param ev Event data.
1583  *
1584  * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise.
1585  */
1586 Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* o, const Evas_Event_Mouse_Down* ev)
1587 {
1588     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1589     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1590     Eina_Bool mouse_press_handled = EINA_FALSE;
1591
1592     priv->page->contextMenuController()->clearContextMenu();
1593     WebCore::Frame* main_frame = priv->page->mainFrame();
1594     Evas_Coord x, y;
1595     evas_object_geometry_get(sd->self, &x, &y, 0, 0);
1596
1597     WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y));
1598
1599     if (main_frame->view()) {
1600         mouse_press_handled =
1601             main_frame->eventHandler()->handleMousePressEvent(event);
1602     }
1603
1604     if (main_frame->eventHandler()->sendContextMenuEvent(event))
1605         return EINA_FALSE;
1606
1607     WebCore::ContextMenu* coreMenu =
1608         priv->page->contextMenuController()->contextMenu();
1609     if (!coreMenu) {
1610         // WebCore decided not to create a context menu, return true if event
1611         // was handled by handleMouseReleaseEvent
1612         return mouse_press_handled;
1613     }
1614
1615     return EINA_TRUE;
1616 }
1617
1618 #endif
1619
1620 /**
1621  * Get current load progress estimate from 0.0 to 1.0.
1622  *
1623  * @param o view object to get current progress.
1624  *
1625  * @return progres value from 0.0 to 1.0 or -1.0 on error.
1626  */
1627 double ewk_view_load_progress_get(const Evas_Object* o)
1628 {
1629     EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0);
1630     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, -1.0);
1631     return priv->page->progress()->estimatedProgress();
1632 }
1633
1634 /**
1635  * Ask main frame to stop loading.
1636  *
1637  * @param o view object to stop loading.
1638  *
1639  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1640  *
1641  * @see ewk_frame_stop()
1642  */
1643 Eina_Bool ewk_view_stop(Evas_Object* o)
1644 {
1645     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1646     return ewk_frame_stop(sd->main_frame);
1647 }
1648
1649 /**
1650  * Ask main frame to reload current document.
1651  *
1652  * @param o view object to reload.
1653  *
1654  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1655  *
1656  * @see ewk_frame_reload()
1657  */
1658 Eina_Bool ewk_view_reload(Evas_Object* o)
1659 {
1660     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1661     return ewk_frame_reload(sd->main_frame);
1662 }
1663
1664 /**
1665  * Ask main frame to fully reload current document, using no caches.
1666  *
1667  * @param o view object to reload.
1668  *
1669  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1670  *
1671  * @see ewk_frame_reload_full()
1672  */
1673 Eina_Bool ewk_view_reload_full(Evas_Object* o)
1674 {
1675     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1676     return ewk_frame_reload_full(sd->main_frame);
1677 }
1678
1679 /**
1680  * Ask main frame to navigate back in history.
1681  *
1682  * @param o view object to navigate back.
1683  *
1684  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1685  *
1686  * @see ewk_frame_back()
1687  */
1688 Eina_Bool ewk_view_back(Evas_Object* o)
1689 {
1690     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1691     return ewk_frame_back(sd->main_frame);
1692 }
1693
1694 /**
1695  * Ask main frame to navigate forward in history.
1696  *
1697  * @param o view object to navigate forward.
1698  *
1699  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1700  *
1701  * @see ewk_frame_forward()
1702  */
1703 Eina_Bool ewk_view_forward(Evas_Object* o)
1704 {
1705     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1706     return ewk_frame_forward(sd->main_frame);
1707 }
1708
1709 /**
1710  * Navigate back or forward in history.
1711  *
1712  * @param o view object to navigate.
1713  * @param steps if positive navigates that amount forwards, if negative
1714  *        does backwards.
1715  *
1716  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1717  *
1718  * @see ewk_frame_navigate()
1719  */
1720 Eina_Bool ewk_view_navigate(Evas_Object* o, int steps)
1721 {
1722     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1723     return ewk_frame_navigate(sd->main_frame, steps);
1724 }
1725
1726 /**
1727  * Check if it is possible to navigate backwards one item in history.
1728  *
1729  * @param o view object to check if backward navigation is possible.
1730  *
1731  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1732  *
1733  * @see ewk_view_navigate_possible()
1734  */
1735 Eina_Bool ewk_view_back_possible(Evas_Object* o)
1736 {
1737     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1738     return ewk_frame_back_possible(sd->main_frame);
1739 }
1740
1741 /**
1742  * Check if it is possible to navigate forwards one item in history.
1743  *
1744  * @param o view object to check if forward navigation is possible.
1745  *
1746  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1747  *
1748  * @see ewk_view_navigate_possible()
1749  */
1750 Eina_Bool ewk_view_forward_possible(Evas_Object* o)
1751 {
1752     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1753     return ewk_frame_forward_possible(sd->main_frame);
1754 }
1755
1756 /**
1757  * Check if it is possible to navigate given @a steps in history.
1758  *
1759  * @param o view object to navigate.
1760  * @param steps if positive navigates that amount forwards, if negative
1761  *        does backwards.
1762  *
1763  * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise.
1764  */
1765 Eina_Bool ewk_view_navigate_possible(Evas_Object* o, int steps)
1766 {
1767     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1768     return ewk_frame_navigate_possible(sd->main_frame, steps);
1769 }
1770
1771 /**
1772  * Check if navigation history (back-forward lists) is enabled.
1773  *
1774  * @param o view object to check if navigation history is enabled.
1775  *
1776  * @return @c EINA_TRUE if view keeps history, @c EINA_FALSE otherwise.
1777  */
1778 Eina_Bool ewk_view_history_enable_get(const Evas_Object* o)
1779 {
1780     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1781     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1782     return static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled();
1783 }
1784
1785 /**
1786  * Sets if navigation history (back-forward lists) is enabled.
1787  *
1788  * @param o view object to set if navigation history is enabled.
1789  * @param enable @c EINA_TRUE if we want to enable navigation history;
1790  * @c EINA_FALSE otherwise.
1791  *
1792  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1793  */
1794 Eina_Bool ewk_view_history_enable_set(Evas_Object* o, Eina_Bool enable)
1795 {
1796     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1797     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
1798     static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->setEnabled(enable);
1799     return EINA_TRUE;
1800 }
1801
1802 /**
1803  * Gets the history (back-forward list) associated with this view.
1804  *
1805  * @param o view object to get navigation history from.
1806  *
1807  * @return returns the history instance handle associated with this
1808  *         view or @c 0 on errors (including when history is not
1809  *         enabled with ewk_view_history_enable_set()). This instance
1810  *         is unique for this view and thus multiple calls to this
1811  *         function with the same view as parameter returns the same
1812  *         handle. This handle is alive while view is alive, thus one
1813  *         might want to listen for EVAS_CALLBACK_DEL on given view
1814  *         (@a o) to know when to stop using returned handle.
1815  *
1816  * @see ewk_view_history_enable_set()
1817  */
1818 Ewk_History* ewk_view_history_get(const Evas_Object* o)
1819 {
1820     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
1821     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
1822     if (!static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled()) {
1823         ERR("asked history, but it's disabled! Returning 0!");
1824         return 0;
1825     }
1826     return priv->history;
1827 }
1828
1829 /**
1830  * Get the current zoom level of main frame.
1831  *
1832  * @param o view object to query zoom level.
1833  *
1834  * @return current zoom level in use or -1.0 on error.
1835  */
1836 float ewk_view_zoom_get(const Evas_Object* o)
1837 {
1838     EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0);
1839     return ewk_frame_zoom_get(sd->main_frame);
1840 }
1841
1842 /**
1843  * Set the current zoom level of main frame.
1844  *
1845  * @param o view object to set zoom level.
1846  * @param zoom new level to use.
1847  * @param cx x of center coordinate
1848  * @param cy y of center coordinate
1849  *
1850  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1851  */
1852 Eina_Bool ewk_view_zoom_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy)
1853 {
1854     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1855     EWK_VIEW_PRIV_GET(sd, priv);
1856
1857     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
1858     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_set, EINA_FALSE);
1859
1860     if (!priv->settings.zoom_range.user_scalable) {
1861         WRN("userScalable is false");
1862         return EINA_FALSE;
1863     }
1864
1865     if (zoom < priv->settings.zoom_range.min_scale) {
1866         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
1867         return EINA_FALSE;
1868     }
1869     if (zoom > priv->settings.zoom_range.max_scale) {
1870         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
1871         return EINA_FALSE;
1872     }
1873
1874     _ewk_view_zoom_animated_mark_stop(sd);
1875     return sd->api->zoom_set(sd, zoom, cx, cy);
1876 }
1877
1878 Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* o)
1879 {
1880     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1881     return sd->zoom_weak_smooth_scale;
1882 }
1883
1884 void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* o, Eina_Bool smooth_scale)
1885 {
1886     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
1887     smooth_scale = !!smooth_scale;
1888     if (sd->zoom_weak_smooth_scale == smooth_scale)
1889         return;
1890     sd->zoom_weak_smooth_scale = smooth_scale;
1891     EINA_SAFETY_ON_NULL_RETURN(sd->api);
1892     EINA_SAFETY_ON_NULL_RETURN(sd->api->zoom_weak_smooth_scale_set);
1893     sd->api->zoom_weak_smooth_scale_set(sd, smooth_scale);
1894 }
1895
1896 /**
1897  * Set the current zoom level of backing store, centered at given point.
1898  *
1899  * Unlike ewk_view_zoom_set(), this call do not ask WebKit to render
1900  * at new size, but scale what is already rendered, being much faster
1901  * but worse quality.
1902  *
1903  * Often one should use ewk_view_zoom_animated_set(), it will call the
1904  * same machinery internally.
1905  *
1906  * @note this will set variables used by ewk_view_zoom_animated_set()
1907  *       so sub-classes will not reset internal state on their
1908  *       "calculate" phase. To unset those and enable sub-classes to
1909  *       reset their internal state, call
1910  *       ewk_view_zoom_animated_mark_stop(). Namely, this call will
1911  *       set ewk_view_zoom_animated_mark_start() to actual webkit zoom
1912  *       level, ewk_view_zoom_animated_mark_end() and
1913  *       ewk_view_zoom_animated_mark_current() to given zoom level.
1914  *
1915  * @param o view object to set weak zoom level.
1916  * @param zoom level to scale backing store.
1917  * @param cx horizontal center offset, relative to object (w/2 is middle).
1918  * @param cy vertical center offset, relative to object (h/2 is middle).
1919  *
1920  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1921  */
1922 Eina_Bool ewk_view_zoom_weak_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy)
1923 {
1924     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1925     EWK_VIEW_PRIV_GET(sd, priv);
1926
1927     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
1928     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE);
1929
1930     if (!priv->settings.zoom_range.user_scalable) {
1931         WRN("userScalable is false");
1932         return EINA_FALSE;
1933     }
1934
1935     if (zoom < priv->settings.zoom_range.min_scale) {
1936         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
1937         return EINA_FALSE;
1938     }
1939     if (zoom > priv->settings.zoom_range.max_scale) {
1940         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
1941         return EINA_FALSE;
1942     }
1943
1944     sd->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame);
1945     sd->animated_zoom.zoom.end = zoom;
1946     sd->animated_zoom.zoom.current = zoom;
1947     return sd->api->zoom_weak_set(sd, zoom, cx, cy);
1948 }
1949
1950 /**
1951  * Mark internal zoom animation state to given zoom.
1952  *
1953  * This does not modify any actual zoom in WebKit or backing store,
1954  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.start so
1955  * sub-classes will know they should not reset their internal state.
1956  *
1957  * @param o view object to change value.
1958  * @param zoom new start value.
1959  *
1960  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1961  *
1962  * @see ewk_view_zoom_animated_set()
1963  * @see ewk_view_zoom_weak_set()
1964  * @see ewk_view_zoom_animated_mark_stop()
1965  * @see ewk_view_zoom_animated_mark_end()
1966  * @see ewk_view_zoom_animated_mark_current()
1967  */
1968 Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* o, float zoom)
1969 {
1970     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1971     sd->animated_zoom.zoom.start = zoom;
1972     return EINA_TRUE;
1973 }
1974
1975 /**
1976  * Mark internal zoom animation state to given zoom.
1977  *
1978  * This does not modify any actual zoom in WebKit or backing store,
1979  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.end so
1980  * sub-classes will know they should not reset their internal state.
1981  *
1982  * @param o view object to change value.
1983  * @param zoom new end value.
1984  *
1985  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
1986  *
1987  * @see ewk_view_zoom_animated_set()
1988  * @see ewk_view_zoom_weak_set()
1989  * @see ewk_view_zoom_animated_mark_stop()
1990  * @see ewk_view_zoom_animated_mark_start()
1991  * @see ewk_view_zoom_animated_mark_current()
1992  */
1993 Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* o, float zoom)
1994 {
1995     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
1996     sd->animated_zoom.zoom.end = zoom;
1997     return EINA_TRUE;
1998 }
1999
2000 /**
2001  * Mark internal zoom animation state to given zoom.
2002  *
2003  * This does not modify any actual zoom in WebKit or backing store,
2004  * just set the Ewk_View_Smart_Data->animated_zoom.zoom.current so
2005  * sub-classes will know they should not reset their internal state.
2006  *
2007  * @param o view object to change value.
2008  * @param zoom new current value.
2009  *
2010  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2011  *
2012  * @see ewk_view_zoom_animated_set()
2013  * @see ewk_view_zoom_weak_set()
2014  * @see ewk_view_zoom_animated_mark_stop()
2015  * @see ewk_view_zoom_animated_mark_start()
2016  * @see ewk_view_zoom_animated_mark_end()
2017  */
2018 Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* o, float zoom)
2019 {
2020     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2021     sd->animated_zoom.zoom.current = zoom;
2022     return EINA_TRUE;
2023 }
2024
2025 /**
2026  * Unmark internal zoom animation state.
2027  *
2028  * This zero all start, end and current values.
2029  *
2030  * @param o view object to mark as animated is stopped.
2031  *
2032  * @see ewk_view_zoom_animated_mark_start()
2033  * @see ewk_view_zoom_animated_mark_end()
2034  * @see ewk_view_zoom_animated_mark_current()
2035  * @see ewk_view_zoom_weak_set()
2036  */
2037 Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* o)
2038 {
2039     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2040     _ewk_view_zoom_animated_mark_stop(sd);
2041     return EINA_TRUE;
2042 }
2043
2044 /**
2045  * Set the current zoom level while animating.
2046  *
2047  * If the view was already animating to another zoom, it will start
2048  * from current point to the next provided zoom (@a zoom parameter)
2049  * and duration (@a duration parameter).
2050  *
2051  * This is the recommended way to do transitions from one level to
2052  * another. However, one may wish to do those from outside, in that
2053  * case use ewk_view_zoom_weak_set() and later control intermediate
2054  * states with ewk_view_zoom_animated_mark_current(),
2055  * ewk_view_zoom_animated_mark_end() and
2056  * ewk_view_zoom_animated_mark_stop().
2057  *
2058  * @param o view object to animate.
2059  * @param zoom final zoom level to use.
2060  * @param duration time in seconds the animation should take.
2061  * @param cx offset inside object that defines zoom center. 0 is left side.
2062  * @param cy offset inside object that defines zoom center. 0 is top side.
2063  * @return @c EINA_TRUE if animation will be started, @c EINA_FALSE if not
2064  *            because zoom is too small/big.
2065  */
2066 Eina_Bool ewk_view_zoom_animated_set(Evas_Object* o, float zoom, float duration, Evas_Coord cx, Evas_Coord cy)
2067 {
2068     double now;
2069     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2070     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2071     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
2072     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE);
2073
2074     if (!priv->settings.zoom_range.user_scalable) {
2075         WRN("userScalable is false");
2076         return EINA_FALSE;
2077     }
2078
2079     if (zoom < priv->settings.zoom_range.min_scale) {
2080         WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom);
2081         return EINA_FALSE;
2082     }
2083     if (zoom > priv->settings.zoom_range.max_scale) {
2084         WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom);
2085         return EINA_FALSE;
2086     }
2087
2088     if (priv->animated_zoom.animator)
2089         priv->animated_zoom.zoom.start = _ewk_view_zoom_animated_current(priv);
2090     else {
2091         priv->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame);
2092         _ewk_view_zoom_animation_start(sd);
2093     }
2094
2095     if (cx < 0)
2096         cx = 0;
2097     if (cy < 0)
2098         cy = 0;
2099
2100     now = ecore_loop_time_get();
2101     priv->animated_zoom.time.start = now;
2102     priv->animated_zoom.time.end = now + duration;
2103     priv->animated_zoom.time.duration = duration;
2104     priv->animated_zoom.zoom.end = zoom;
2105     priv->animated_zoom.zoom.range = (priv->animated_zoom.zoom.end - priv->animated_zoom.zoom.start);
2106     priv->animated_zoom.center.x = cx;
2107     priv->animated_zoom.center.y = cy;
2108     sd->animated_zoom.zoom.current = priv->animated_zoom.zoom.start;
2109     sd->animated_zoom.zoom.start = priv->animated_zoom.zoom.start;
2110     sd->animated_zoom.zoom.end = priv->animated_zoom.zoom.end;
2111
2112     return EINA_TRUE;
2113 }
2114
2115 /**
2116  * Query if zoom level just applies to text and not other elements.
2117  *
2118  * @param o view to query setting.
2119  *
2120  * @return @c EINA_TRUE if just text are scaled, @c EINA_FALSE otherwise.
2121  */
2122 Eina_Bool ewk_view_zoom_text_only_get(const Evas_Object* o)
2123 {
2124     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2125     return ewk_frame_zoom_text_only_get(sd->main_frame);
2126 }
2127
2128 /**
2129  * Set if zoom level just applies to text and not other elements.
2130  *
2131  * @param o view to change setting.
2132  * @param setting @c EINA_TRUE if zoom should just be applied to text.
2133  *
2134  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2135  */
2136 Eina_Bool ewk_view_zoom_text_only_set(Evas_Object* o, Eina_Bool setting)
2137 {
2138     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2139     return ewk_frame_zoom_text_only_set(sd->main_frame, setting);
2140 }
2141
2142 /**
2143  * Hint engine to pre-render region.
2144  *
2145  * Engines and backing store might be able to pre-render regions in
2146  * order to speed up zooming or scrolling to that region. Not all
2147  * engines might implement that and they will return @c EINA_FALSE
2148  * in that case.
2149  *
2150  * The given region is a hint. Engines might do bigger or smaller area
2151  * that covers that region. Pre-render might not be immediate, it may
2152  * be postponed to a thread, operated cooperatively in the main loop
2153  * and may be even ignored or cancelled afterwards.
2154  *
2155  * Multiple requests might be queued by engines. One can clear/forget
2156  * about them with ewk_view_pre_render_cancel().
2157  *
2158  * @param o view to ask pre-render of given region.
2159  * @param x absolute coordinate (0=left) to pre-render at zoom.
2160  * @param y absolute coordinate (0=top) to pre-render at zoom.
2161  * @param w width to pre-render starting from @a x at zoom.
2162  * @param h height to pre-render starting from @a y at zoom.
2163  * @param zoom desired zoom.
2164  *
2165  * @return @c EINA_TRUE if request was accepted, @c EINA_FALSE
2166  *         otherwise (errors, pre-render not supported, etc).
2167  *
2168  * @see ewk_view_pre_render_cancel()
2169  */
2170 Eina_Bool ewk_view_pre_render_region(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
2171 {
2172     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2173     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2174     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_region, EINA_FALSE);
2175     float cur_zoom;
2176     Evas_Coord cw, ch;
2177
2178     /* When doing animated zoom it's not possible to call pre-render since it
2179      * would screw up parameters that animation is currently using
2180      */
2181     if (priv->animated_zoom.animator)
2182         return EINA_FALSE;
2183
2184     cur_zoom = ewk_frame_zoom_get(sd->main_frame);
2185
2186     if (cur_zoom < 0.00001)
2187         return EINA_FALSE;
2188     if (!ewk_frame_contents_size_get(sd->main_frame, &cw, &ch))
2189         return EINA_FALSE;
2190
2191     cw *= zoom / cur_zoom;
2192     ch *= zoom / cur_zoom;
2193     DBG("region %d,%d+%dx%d @ %f contents=%dx%d", x, y, w, h, zoom, cw, ch);
2194
2195     if (x + w > cw)
2196         w = cw - x;
2197
2198     if (y + h > ch)
2199         h = ch - y;
2200
2201     if (x < 0) {
2202         w += x;
2203         x = 0;
2204     }
2205     if (y < 0) {
2206         h += y;
2207         y = 0;
2208     }
2209
2210     return sd->api->pre_render_region(sd, x, y, w, h, zoom);
2211 }
2212
2213 /**
2214  * Hint engine to pre-render region, given n extra cols/rows
2215  *
2216  * This is an alternative method to ewk_view_pre_render_region(). It does not
2217  * make sense in all engines and therefore it might not be implemented at all.
2218  *
2219  * It's only useful if engine divide the area being rendered in smaller tiles,
2220  * forming a grid. Then, browser could call this function to pre-render @param n
2221  * rows/cols involving the current viewport.
2222  *
2223  * @param o view to ask pre-render on.
2224  * @param n number of cols/rows that must be part of the region pre-rendered
2225  *
2226  * @see ewk_view_pre_render_region()
2227  */
2228 Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object* o, unsigned int n)
2229 {
2230     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2231     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2232     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_relative_radius, EINA_FALSE);
2233     float cur_zoom;
2234
2235     if (priv->animated_zoom.animator)
2236         return EINA_FALSE;
2237
2238     cur_zoom = ewk_frame_zoom_get(sd->main_frame);
2239     return sd->api->pre_render_relative_radius(sd, n, cur_zoom);
2240 }
2241
2242 /**
2243  * Get input method hints
2244  *
2245  * @param o View.
2246  *
2247  * @return input method hints
2248  */
2249 unsigned int ewk_view_imh_get(Evas_Object *o)
2250 {
2251     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2252     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2253     return priv->imh;
2254 }
2255
2256 /**
2257  * Cancel (clear) previous pre-render requests.
2258  *
2259  * @param o view to clear pre-render requests.
2260  */
2261 void ewk_view_pre_render_cancel(Evas_Object* o)
2262 {
2263     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
2264     EINA_SAFETY_ON_NULL_RETURN(sd->api->pre_render_cancel);
2265     sd->api->pre_render_cancel(sd);
2266 }
2267
2268 /**
2269   * Enable processing of update requests.
2270   *
2271   * @param o view to enable rendering.
2272   *
2273   * @return @c EINA_TRUE if render was enabled, @c EINA_FALSE
2274             otherwise (errors, rendering suspension not supported).
2275   */
2276 Eina_Bool ewk_view_enable_render(const Evas_Object *o)
2277 {
2278     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2279     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->enable_render, EINA_FALSE);
2280     return sd->api->enable_render(sd);
2281 }
2282
2283 /**
2284   * Disable processing of update requests.
2285   *
2286   * @param o view to disable rendering.
2287   *
2288   * @return @c EINA_TRUE if render was disabled, @c EINA_FALSE
2289             otherwise (errors, rendering suspension not supported).
2290   */
2291 Eina_Bool ewk_view_disable_render(const Evas_Object *o)
2292 {
2293     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2294     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->disable_render, EINA_FALSE);
2295     return sd->api->disable_render(sd);
2296 }
2297
2298 const char* ewk_view_setting_user_agent_get(const Evas_Object* o)
2299 {
2300     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2301     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2302     return priv->settings.user_agent;
2303 }
2304
2305 Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* o, const char* user_agent)
2306 {
2307     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2308     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2309     if (eina_stringshare_replace(&priv->settings.user_agent, user_agent)) {
2310         WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(priv->main_frame->loader()->client());
2311         client->setCustomUserAgent(String::fromUTF8(user_agent));
2312     }
2313     return EINA_TRUE;
2314 }
2315
2316 const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* o)
2317 {
2318     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2319     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2320     return priv->settings.user_stylesheet;
2321 }
2322
2323 Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* o, const char* uri)
2324 {
2325     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2326     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2327     if (eina_stringshare_replace(&priv->settings.user_stylesheet, uri)) {
2328         WebCore::KURL kurl(WebCore::KURL(), String::fromUTF8(uri));
2329         priv->page_settings->setUserStyleSheetLocation(kurl);
2330     }
2331     return EINA_TRUE;
2332 }
2333
2334 Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* o)
2335 {
2336     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2337     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2338     return priv->settings.auto_load_images;
2339 }
2340
2341 Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* o, Eina_Bool automatic)
2342 {
2343     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2344     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2345     automatic = !!automatic;
2346     if (priv->settings.auto_load_images != automatic) {
2347         priv->page_settings->setLoadsImagesAutomatically(automatic);
2348         priv->settings.auto_load_images = automatic;
2349     }
2350     return EINA_TRUE;
2351 }
2352
2353 Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* o)
2354 {
2355     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2356     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2357     return priv->settings.auto_shrink_images;
2358 }
2359
2360 Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* o, Eina_Bool automatic)
2361 {
2362     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2363     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2364     automatic = !!automatic;
2365     if (priv->settings.auto_shrink_images != automatic) {
2366         priv->page_settings->setShrinksStandaloneImagesToFit(automatic);
2367         priv->settings.auto_shrink_images = automatic;
2368     }
2369     return EINA_TRUE;
2370 }
2371
2372 /**
2373  * Gets if view can be resized automatically.
2374  *
2375  * @param o view to check status
2376  *
2377  * @return EINA_TRUE if view can be resized, EINA_FALSE
2378  *         otherwise (errors, cannot be resized).
2379  */
2380 Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* o)
2381 {
2382     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2383     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2384     return priv->settings.enable_auto_resize_window;
2385 }
2386
2387 /**
2388  * Sets if view can be resized automatically.
2389  *
2390  * @param o View.
2391  * @param resizable @c EINA_TRUE if we want to resize automatically;
2392  * @c EINA_FALSE otherwise. It defaults to @c EINA_TRUE
2393  *
2394  * @return EINA_TRUE if auto_resize_window status set, EINA_FALSE
2395  *         otherwise (errors).
2396  */
2397 Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* o, Eina_Bool resizable)
2398 {
2399     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2400     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2401     priv->settings.enable_auto_resize_window = resizable;
2402     return EINA_TRUE;
2403 }
2404
2405 Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* o)
2406 {
2407     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2408     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2409     return priv->settings.enable_scripts;
2410 }
2411
2412 Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* o, Eina_Bool enable)
2413 {
2414     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2415     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2416     enable = !!enable;
2417     if (priv->settings.enable_scripts != enable) {
2418         priv->page_settings->setJavaScriptEnabled(enable);
2419         priv->settings.enable_scripts = enable;
2420     }
2421     return EINA_TRUE;
2422 }
2423
2424 Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* o)
2425 {
2426     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2427     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2428     return priv->settings.enable_plugins;
2429 }
2430
2431 Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* o, Eina_Bool enable)
2432 {
2433     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2434     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2435     enable = !!enable;
2436     if (priv->settings.enable_plugins != enable) {
2437         priv->page_settings->setPluginsEnabled(enable);
2438         priv->settings.enable_plugins = enable;
2439     }
2440     return EINA_TRUE;
2441 }
2442
2443 /**
2444  * Get status of frame flattening.
2445  *
2446  * @param o view to check status
2447  *
2448  * @return EINA_TRUE if flattening is enabled, EINA_FALSE
2449  *         otherwise (errors, flattening disabled).
2450  */
2451 Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* o)
2452 {
2453     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2454     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2455     return priv->settings.enable_frame_flattening;
2456 }
2457
2458 /**
2459  * Set frame flattening.
2460  *
2461  * @param o view to set flattening
2462  *
2463  * @return EINA_TRUE if flattening status set, EINA_FALSE
2464  *         otherwise (errors).
2465  */
2466 Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* o, Eina_Bool enable)
2467 {
2468     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2469     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2470     enable = !!enable;
2471     if (priv->settings.enable_frame_flattening != enable) {
2472         priv->page_settings->setFrameFlatteningEnabled(enable);
2473         priv->settings.enable_frame_flattening = enable;
2474     }
2475     return EINA_TRUE;
2476 }
2477
2478 Eina_Bool ewk_view_setting_scripts_window_open_get(const Evas_Object* o)
2479 {
2480     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2481     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2482     return priv->settings.scripts_window_open;
2483 }
2484
2485 Eina_Bool ewk_view_setting_scripts_window_open_set(Evas_Object* o, Eina_Bool allow)
2486 {
2487     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2488     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2489     allow = !!allow;
2490     if (priv->settings.scripts_window_open != allow) {
2491         priv->page_settings->setJavaScriptCanOpenWindowsAutomatically(allow);
2492         priv->settings.scripts_window_open = allow;
2493     }
2494     return EINA_TRUE;
2495 }
2496
2497 Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* o)
2498 {
2499     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2500     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2501     return priv->settings.resizable_textareas;
2502 }
2503
2504 Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* o, Eina_Bool enable)
2505 {
2506     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2507     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2508     enable = !!enable;
2509     if (priv->settings.resizable_textareas != enable) {
2510         priv->page_settings->setTextAreasAreResizable(enable);
2511         priv->settings.resizable_textareas = enable;
2512     }
2513     return EINA_TRUE;
2514 }
2515
2516 Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* o)
2517 {
2518     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2519     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2520     return priv->settings.private_browsing;
2521 }
2522
2523 Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* o, Eina_Bool enable)
2524 {
2525     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2526     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2527     enable = !!enable;
2528     if (priv->settings.private_browsing != enable) {
2529         priv->page_settings->setPrivateBrowsingEnabled(enable);
2530         priv->settings.private_browsing = enable;
2531     }
2532     return EINA_TRUE;
2533 }
2534
2535 Eina_Bool ewk_view_setting_offline_app_cache_get(const Evas_Object* o)
2536 {
2537     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2538     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2539     return priv->settings.offline_app_cache;
2540 }
2541
2542 Eina_Bool ewk_view_setting_offline_app_cache_set(Evas_Object* o, Eina_Bool enable)
2543 {
2544     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2545     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2546     enable = !!enable;
2547     if (priv->settings.offline_app_cache != enable) {
2548         priv->page_settings->setOfflineWebApplicationCacheEnabled(enable);
2549         priv->settings.offline_app_cache = enable;
2550     }
2551     return EINA_TRUE;
2552 }
2553
2554
2555 Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* o)
2556 {
2557     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2558     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2559     return priv->settings.caret_browsing;
2560 }
2561
2562 Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* o, Eina_Bool enable)
2563 {
2564     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2565     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2566     enable = !!enable;
2567     if (priv->settings.caret_browsing != enable) {
2568         priv->page_settings->setCaretBrowsingEnabled(enable);
2569         priv->settings.caret_browsing = enable;
2570     }
2571     return EINA_TRUE;
2572 }
2573
2574 /**
2575  * Get current encoding of this View.
2576  *
2577  * @param o View.
2578  *
2579  * @return A pointer to an eina_strinshare containing the current custom
2580  * encoding for View object @param o, or @c 0 if it's not set.
2581  */
2582 const char* ewk_view_setting_encoding_custom_get(const Evas_Object* o)
2583 {
2584     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2585     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2586     Evas_Object* main_frame = ewk_view_frame_main_get(o);
2587     WebCore::Frame* core_frame = ewk_frame_core_get(main_frame);
2588
2589     String overrideEncoding = core_frame->loader()->documentLoader()->overrideEncoding();
2590
2591     if (overrideEncoding.isEmpty())
2592         return 0;
2593
2594     eina_stringshare_replace(&priv->settings.encoding_custom, overrideEncoding.utf8().data());
2595     return priv->settings.encoding_custom;
2596 }
2597
2598 /**
2599  * Set encoding of this View and reload page.
2600  *
2601  * @param o View.
2602  * @param encoding The new encoding or @c 0 to restore the default encoding.
2603  *
2604  * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
2605  */
2606 Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* o, const char *encoding)
2607 {
2608     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2609     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2610     Evas_Object* main_frame = ewk_view_frame_main_get(o);
2611     WebCore::Frame* core_frame = ewk_frame_core_get(main_frame);
2612 DBG("%s", encoding);
2613     eina_stringshare_replace(&priv->settings.encoding_custom, encoding);
2614     core_frame->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding));
2615
2616     return EINA_TRUE;
2617 }
2618
2619 const char* ewk_view_setting_encoding_default_get(const Evas_Object* o)
2620 {
2621     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2622     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2623     return priv->settings.encoding_default;
2624 }
2625
2626 Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* o, const char* encoding)
2627 {
2628     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2629     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2630     if (eina_stringshare_replace(&priv->settings.encoding_default, encoding))
2631         priv->page_settings->setDefaultTextEncodingName(String::fromUTF8(encoding));
2632     return EINA_TRUE;
2633 }
2634
2635 /**
2636  * Sets the encoding detector.
2637  *
2638  * @param o view object to set if encoding detector is enabled.
2639  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2640  */
2641 Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* o, Eina_Bool enable)
2642 {
2643     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2644     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2645     enable = !!enable;
2646     if (priv->settings.encoding_detector != enable) {
2647         priv->page_settings->setUsesEncodingDetector(enable);
2648         priv->settings.encoding_detector = enable;
2649     }
2650     return EINA_TRUE;
2651 }
2652
2653 /**
2654  * Gets if the encoding detector is enabled.
2655  *
2656  * @param o view object to get if encoding detector is enabled.
2657  * @return @c EINA_TRUE if encoding detector is enabled, @c EINA_FALSE if not or on errors.
2658  */
2659 Eina_Bool ewk_view_setting_encoding_detector_get(Evas_Object* o)
2660 {
2661     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2662     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2663     return priv->settings.encoding_detector;
2664 }
2665
2666 /**
2667  * Returns whether developer extensions are enabled for the given view.
2668  *
2669  * Currently, this is used to know whether the Web Inspector is enabled for a
2670  * given view.
2671  *
2672  * @param o view object to check.
2673  *
2674  * @return @c EINA_TRUE if developer extensions are enabled, @c EINA_FALSE
2675  *         otherwise.
2676  */
2677 Eina_Bool ewk_view_setting_enable_developer_extras_get(Evas_Object* o)
2678 {
2679     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2680     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2681     return priv->settings.enable_developer_extras;
2682 }
2683
2684 /**
2685  * Enables/disables developer extensions for the given view.
2686  *
2687  * This currently controls whether the Web Inspector should be enabled.
2688  *
2689  * @param o The view whose setting will be changed.
2690  * @param enable @c EINA_TRUE to enable developer extras, @c EINA_FALSE to
2691  *               disable.
2692  *
2693  * @return @c EINA_TRUE on success, @EINA_FALSE on failure.
2694  */
2695 Eina_Bool ewk_view_setting_enable_developer_extras_set(Evas_Object* o, Eina_Bool enable)
2696 {
2697     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2698     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2699     enable = !!enable;
2700     if (priv->settings.enable_developer_extras != enable) {
2701         priv->page_settings->setDeveloperExtrasEnabled(enable);
2702         priv->settings.enable_developer_extras = enable;
2703     }
2704     return EINA_TRUE;
2705 }
2706
2707 int ewk_view_setting_font_minimum_size_get(const Evas_Object* o)
2708 {
2709     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2710     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2711     return priv->settings.font_minimum_size;
2712 }
2713
2714 Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* o, int size)
2715 {
2716     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2717     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2718     if (priv->settings.font_minimum_size != size) {
2719         priv->page_settings->setMinimumFontSize(size);
2720         priv->settings.font_minimum_size = size;
2721     }
2722     return EINA_TRUE;
2723 }
2724
2725 int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* o)
2726 {
2727     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2728     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2729     return priv->settings.font_minimum_logical_size;
2730 }
2731
2732 Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* o, int size)
2733 {
2734     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2735     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2736     if (priv->settings.font_minimum_logical_size != size) {
2737         priv->page_settings->setMinimumLogicalFontSize(size);
2738         priv->settings.font_minimum_logical_size = size;
2739     }
2740     return EINA_TRUE;
2741 }
2742
2743 int ewk_view_setting_font_default_size_get(const Evas_Object* o)
2744 {
2745     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2746     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2747     return priv->settings.font_default_size;
2748 }
2749
2750 Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object* o, int size)
2751 {
2752     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2753     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2754     if (priv->settings.font_default_size != size) {
2755         priv->page_settings->setDefaultFontSize(size);
2756         priv->settings.font_default_size = size;
2757     }
2758     return EINA_TRUE;
2759 }
2760
2761 int ewk_view_setting_font_monospace_size_get(const Evas_Object* o)
2762 {
2763     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2764     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2765     return priv->settings.font_monospace_size;
2766 }
2767
2768 Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object* o, int size)
2769 {
2770     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2771     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2772     if (priv->settings.font_monospace_size != size) {
2773         priv->page_settings->setDefaultFixedFontSize(size);
2774         priv->settings.font_monospace_size = size;
2775     }
2776     return EINA_TRUE;
2777 }
2778
2779 const char* ewk_view_setting_font_standard_get(const Evas_Object* o)
2780 {
2781     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2782     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2783     return priv->settings.font_standard;
2784 }
2785
2786 Eina_Bool ewk_view_setting_font_standard_set(Evas_Object* o, const char* family)
2787 {
2788     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2789     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2790     if (eina_stringshare_replace(&priv->settings.font_standard, family))
2791         priv->page_settings->setStandardFontFamily(AtomicString::fromUTF8(family));
2792     return EINA_TRUE;
2793 }
2794
2795 const char* ewk_view_setting_font_cursive_get(const Evas_Object* o)
2796 {
2797     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2798     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2799     return priv->settings.font_cursive;
2800 }
2801
2802 Eina_Bool ewk_view_setting_font_cursive_set(Evas_Object* o, const char* family)
2803 {
2804     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2805     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2806     if (eina_stringshare_replace(&priv->settings.font_cursive, family))
2807         priv->page_settings->setCursiveFontFamily(AtomicString::fromUTF8(family));
2808     return EINA_TRUE;
2809 }
2810
2811 const char* ewk_view_setting_font_fantasy_get(const Evas_Object* o)
2812 {
2813     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2814     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2815     return priv->settings.font_fantasy;
2816 }
2817
2818 Eina_Bool ewk_view_setting_font_fantasy_set(Evas_Object* o, const char* family)
2819 {
2820     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2821     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2822     if (eina_stringshare_replace(&priv->settings.font_fantasy, family))
2823         priv->page_settings->setFantasyFontFamily(AtomicString::fromUTF8(family));
2824     return EINA_TRUE;
2825 }
2826
2827 const char* ewk_view_setting_font_monospace_get(const Evas_Object* o)
2828 {
2829     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2830     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2831     return priv->settings.font_monospace;
2832 }
2833
2834 Eina_Bool ewk_view_setting_font_monospace_set(Evas_Object* o, const char* family)
2835 {
2836     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2837     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2838     if (eina_stringshare_replace(&priv->settings.font_monospace, family))
2839         priv->page_settings->setFixedFontFamily(AtomicString::fromUTF8(family));
2840     return EINA_TRUE;
2841 }
2842
2843 const char* ewk_view_setting_font_serif_get(const Evas_Object* o)
2844 {
2845     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2846     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2847     return priv->settings.font_serif;
2848 }
2849
2850 Eina_Bool ewk_view_setting_font_serif_set(Evas_Object* o, const char* family)
2851 {
2852     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2853     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2854     if (eina_stringshare_replace(&priv->settings.font_serif, family))
2855         priv->page_settings->setSerifFontFamily(AtomicString::fromUTF8(family));
2856     return EINA_TRUE;
2857 }
2858
2859 const char* ewk_view_setting_font_sans_serif_get(const Evas_Object* o)
2860 {
2861     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2862     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2863     return priv->settings.font_sans_serif;
2864 }
2865   
2866 Eina_Bool ewk_view_setting_font_sans_serif_set(Evas_Object* o, const char* family)
2867 {
2868     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2869     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2870     if (eina_stringshare_replace(&priv->settings.font_sans_serif, family))
2871         priv->page_settings->setSansSerifFontFamily(AtomicString::fromUTF8(family));
2872     return EINA_TRUE;
2873 }
2874
2875 /**
2876  * Gets if the spatial naviagtion is enabled.
2877  *
2878  * @param o view object to get spatial navigation setting.
2879  * @return @c EINA_TRUE if spatial navigation is enabled, @c EINA_FALSE if not or on errors.
2880  */
2881 Eina_Bool ewk_view_setting_spatial_navigation_get(Evas_Object* o)
2882 {
2883     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2884     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2885     return priv->settings.spatial_navigation;
2886 }
2887
2888 /**
2889  * Sets the spatial navigation.
2890  *
2891  * @param o view object to set spatial navigation setting.
2892  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2893  */
2894 Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* o, Eina_Bool enable)
2895 {
2896     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2897     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2898     enable = !!enable;
2899     if (priv->settings.spatial_navigation != enable) {
2900         priv->page_settings->setSpatialNavigationEnabled(enable);
2901         priv->settings.spatial_navigation = enable;
2902     }
2903     return EINA_TRUE;
2904 }
2905
2906 /**
2907  * Gets if the local storage is enabled.
2908  *
2909  * @param o view object to get if local storage is enabled.
2910  * @return @c EINA_TRUE if local storage is enabled, @c EINA_FALSE if not or on errors.
2911  */
2912 Eina_Bool ewk_view_setting_local_storage_get(Evas_Object* o)
2913 {
2914     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2915     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2916     return priv->settings.local_storage;
2917 }
2918
2919 /**
2920  * Sets the local storage of HTML5.
2921  *
2922  * @param o view object to set if local storage is enabled.
2923  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2924  */
2925 Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* o, Eina_Bool enable)
2926 {
2927     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2928     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2929     enable = !!enable;
2930     if (priv->settings.local_storage != enable) {
2931         priv->page_settings->setLocalStorageEnabled(enable);
2932         priv->settings.local_storage = enable;
2933     }
2934     return EINA_TRUE;
2935 }
2936
2937 /**
2938  * Gets if the page cache is enabled.
2939  *
2940  * @param o view object to set if page cache is enabled.
2941  * @return @c EINA_TRUE if page cache is enabled, @c EINA_FALSE if not.
2942  */
2943 Eina_Bool ewk_view_setting_page_cache_get(Evas_Object* o)
2944 {
2945     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2946     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2947     return priv->settings.page_cache;
2948 }
2949
2950 /**
2951  * Sets the page cache.
2952  *
2953  * @param o view object to set if page cache is enabled.
2954  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2955  */
2956 Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* o, Eina_Bool enable)
2957 {
2958     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2959     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2960     enable = !!enable;
2961     if (priv->settings.page_cache != enable) {
2962         priv->page_settings->setUsesPageCache(enable);
2963         priv->settings.page_cache = enable;
2964     }
2965     return EINA_TRUE;
2966 }
2967
2968 /*
2969  * Gets the local storage database path.
2970  *
2971  * @param o view object to get the local storage database path.
2972  * @return the local storage database path.
2973  */
2974 const char* ewk_view_setting_local_storage_database_path_get(const Evas_Object* o)
2975 {
2976     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
2977     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
2978     return priv->settings.local_storage_database_path;
2979 }
2980
2981 /**
2982  * Sets the local storage database path.
2983  *
2984  * @param o view object to set the local storage database path.
2985  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure
2986  */
2987 Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object* o, const char* path)
2988 {
2989     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
2990     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
2991     if (eina_stringshare_replace(&priv->settings.local_storage_database_path, path))
2992         priv->page_settings->setLocalStorageDatabasePath(String::fromUTF8(path));
2993     return EINA_TRUE;
2994 }
2995
2996 /**
2997  * Similar to evas_object_smart_data_get(), but does type checking.
2998  *
2999  * @param o view object to query internal data.
3000  * @return internal data or @c 0 on errors (ie: incorrect type of @a o).
3001  */
3002 Ewk_View_Smart_Data* ewk_view_smart_data_get(const Evas_Object* o)
3003 {
3004     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3005     return sd;
3006 }
3007
3008 /**
3009  * Gets the internal array of repaint requests.
3010  *
3011  * This array should not be modified anyhow. It should be processed
3012  * immediately as any further ewk_view call might change it, like
3013  * those that add repaints or flush them, so be sure that your code
3014  * does not call any of those while you process the repaints,
3015  * otherwise copy the array.
3016  *
3017  * @param priv private handle pointer of the view to get repaints.
3018  * @param count where to return the number of elements of returned array.
3019  *
3020  * @return reference to array of requested repaints.
3021  *
3022  * @note this is not for general use but just for subclasses that want
3023  *       to define their own backing store.
3024  */
3025 const Eina_Rectangle* ewk_view_repaints_get(const Ewk_View_Private_Data* priv, size_t* count)
3026 {
3027     EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
3028     if (count)
3029         *count = 0;
3030     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3031     if (count)
3032         *count = priv->repaints.count;
3033     return priv->repaints.array;
3034 }
3035
3036 /**
3037  * Gets the internal array of scroll requests.
3038  *
3039  * This array should not be modified anyhow. It should be processed
3040  * immediately as any further ewk_view call might change it, like
3041  * those that add scrolls or flush them, so be sure that your code
3042  * does not call any of those while you process the scrolls,
3043  * otherwise copy the array.
3044  *
3045  * @param priv private handle pointer of the view to get scrolls.
3046  * @param count where to return the number of elements of returned array.
3047  *
3048  * @return reference to array of requested scrolls.
3049  *
3050  * @note this is not for general use but just for subclasses that want
3051  *       to define their own backing store.
3052  */
3053 const Ewk_Scroll_Request* ewk_view_scroll_requests_get(const Ewk_View_Private_Data* priv, size_t* count)
3054 {
3055     EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0);
3056     if (count)
3057         *count = 0;
3058     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3059     if (count)
3060         *count = priv->scrolls.count;
3061     return priv->scrolls.array;
3062 }
3063
3064 /**
3065  * Add a new repaint request to queue.
3066  *
3067  * The repaints are assumed to be relative to current viewport.
3068  *
3069  * @param priv private handle pointer of the view to add repaint request.
3070  * @param x horizontal position relative to current view port (scrolled).
3071  * @param y vertical position relative to current view port (scrolled).
3072  * @param w width of area to be repainted
3073  * @param h height of area to be repainted
3074  *
3075  * @note this is not for general use but just for subclasses that want
3076  *       to define their own backing store.
3077  */
3078 void ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
3079 {
3080     EINA_SAFETY_ON_NULL_RETURN(priv);
3081     _ewk_view_repaint_add(priv, x, y, w, h);
3082 }
3083
3084 /**
3085  * Do layout if required, applied recursively.
3086  *
3087  * @param priv private handle pointer of the view to layout.
3088  *
3089  * @note this is not for general use but just for subclasses that want
3090  *       to define their own backing store.
3091  */
3092 void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data* priv)
3093 {
3094     EINA_SAFETY_ON_NULL_RETURN(priv);
3095
3096     WebCore::FrameView* v = priv->main_frame->view();
3097     if (!v) {
3098         ERR("no main frame view");
3099         return;
3100     }
3101     v->updateLayoutAndStyleIfNeededRecursive();
3102 }
3103
3104 void ewk_view_scrolls_process(Ewk_View_Smart_Data* sd)
3105 {
3106     EINA_SAFETY_ON_NULL_RETURN(sd);
3107     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
3108     if (!sd->api->scrolls_process(sd))
3109         ERR("failed to process scrolls.");
3110     _ewk_view_scrolls_flush(priv);
3111 }
3112
3113 struct _Ewk_View_Paint_Context {
3114     WebCore::GraphicsContext* gc;
3115     WebCore::FrameView* view;
3116     cairo_t* cr;
3117 };
3118
3119 /**
3120  * Create a new paint context using the view as source and cairo as output.
3121  *
3122  * @param priv private handle pointer of the view to use as paint source.
3123  * @param cr cairo context to use as paint destination. A new
3124  *        reference is taken, so it's safe to call cairo_destroy()
3125  *        after this function returns.
3126  *
3127  * @return newly allocated instance or @c 0 on errors.
3128  *
3129  * @note this is not for general use but just for subclasses that want
3130  *       to define their own backing store.
3131  */
3132 Ewk_View_Paint_Context* ewk_view_paint_context_new(Ewk_View_Private_Data* priv, cairo_t* cr)
3133 {
3134     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0);
3135     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, 0);
3136     EINA_SAFETY_ON_NULL_RETURN_VAL(priv->main_frame, 0);
3137     WebCore::FrameView* view = priv->main_frame->view();
3138     EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0);
3139     Ewk_View_Paint_Context* ctxt = (Ewk_View_Paint_Context*)malloc(sizeof(*ctxt));
3140     EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, 0);
3141
3142     ctxt->gc = new WebCore::GraphicsContext(cr);
3143     if (!ctxt->gc) {
3144         free(ctxt);
3145         return 0;
3146     }
3147     ctxt->view = view;
3148     ctxt->cr = cairo_reference(cr);
3149     return ctxt;
3150 }
3151
3152 /**
3153  * Destroy previously created paint context.
3154  *
3155  * @param ctxt paint context to destroy. Must @b not be @c 0.
3156  *
3157  * @note this is not for general use but just for subclasses that want
3158  *       to define their own backing store.
3159  */
3160 void ewk_view_paint_context_free(Ewk_View_Paint_Context* ctxt)
3161 {
3162     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3163     delete ctxt->gc;
3164     cairo_destroy(ctxt->cr);
3165     free(ctxt);
3166 }
3167
3168 /**
3169  * Save (push to stack) paint context status.
3170  *
3171  * @param ctxt paint context to save. Must @b not be @c 0.
3172  *
3173  * @see ewk_view_paint_context_restore()
3174  *
3175  * @note this is not for general use but just for subclasses that want
3176  *       to define their own backing store.
3177  */
3178 void ewk_view_paint_context_save(Ewk_View_Paint_Context* ctxt)
3179 {
3180     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3181     cairo_save(ctxt->cr);
3182     ctxt->gc->save();
3183 }
3184
3185 /**
3186  * Restore (pop from stack) paint context status.
3187  *
3188  * @param ctxt paint context to restore. Must @b not be @c 0.
3189  *
3190  * @see ewk_view_paint_context_save()
3191  *
3192  * @note this is not for general use but just for subclasses that want
3193  *       to define their own backing store.
3194  */
3195 void ewk_view_paint_context_restore(Ewk_View_Paint_Context* ctxt)
3196 {
3197     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3198     ctxt->gc->restore();
3199     cairo_restore(ctxt->cr);
3200 }
3201
3202 /**
3203  * Clip paint context drawings to given area.
3204  *
3205  * @param ctxt paint context to clip. Must @b not be @c 0.
3206  * @param area clip area to use.
3207  *
3208  * @see ewk_view_paint_context_save()
3209  * @see ewk_view_paint_context_restore()
3210  *
3211  * @note this is not for general use but just for subclasses that want
3212  *       to define their own backing store.
3213  */
3214 void ewk_view_paint_context_clip(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3215 {
3216     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3217     EINA_SAFETY_ON_NULL_RETURN(area);
3218     ctxt->gc->clip(WebCore::IntRect(area->x, area->y, area->w, area->h));
3219 }
3220
3221 /**
3222  * Paint using context using given area.
3223  *
3224  * @param ctxt paint context to paint. Must @b not be @c 0.
3225  * @param area paint area to use. Coordinates are relative to current viewport,
3226  *        thus "scrolled".
3227  *
3228  * @note one may use cairo functions on the cairo context to
3229  *       translate, scale or any modification that may fit his desires.
3230  *
3231  * @see ewk_view_paint_context_clip()
3232  * @see ewk_view_paint_context_paint_contents()
3233  *
3234  * @note this is not for general use but just for subclasses that want
3235  *       to define their own backing store.
3236  */
3237 void ewk_view_paint_context_paint(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3238 {
3239     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3240     EINA_SAFETY_ON_NULL_RETURN(area);
3241
3242     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3243
3244     if (ctxt->view->isTransparent())
3245         ctxt->gc->clearRect(rect);
3246     ctxt->view->paint(ctxt->gc, rect);
3247 }
3248
3249 /**
3250  * Paint just contents using context using given area.
3251  *
3252  * Unlike ewk_view_paint_context_paint(), this function paint just
3253  * bare contents and ignores any scrolling, scrollbars and extras. It
3254  * will walk the rendering tree and paint contents inside the given
3255  * area to the cairo context specified in @a ctxt.
3256  *
3257  * @param ctxt paint context to paint. Must @b not be @c 0.
3258  * @param area paint area to use. Coordinates are absolute to page.
3259  *
3260  * @note one may use cairo functions on the cairo context to
3261  *       translate, scale or any modification that may fit his desires.
3262  *
3263  * @see ewk_view_paint_context_clip()
3264  * @see ewk_view_paint_context_paint()
3265  *
3266  * @note this is not for general use but just for subclasses that want
3267  *       to define their own backing store.
3268  */
3269 void ewk_view_paint_context_paint_contents(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area)
3270 {
3271     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3272     EINA_SAFETY_ON_NULL_RETURN(area);
3273
3274     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3275
3276     if (ctxt->view->isTransparent())
3277         ctxt->gc->clearRect(rect);
3278
3279     ctxt->view->paintContents(ctxt->gc, rect);
3280 }
3281
3282 /**
3283  * Scale the contents by the given factors.
3284  *
3285  * This function applies a scaling transformation using Cairo.
3286  *
3287  * @param ctxt    paint context to paint. Must @b not be @c 0.
3288  * @param scale_x scale factor for the X dimension.
3289  * @param scale_y scale factor for the Y dimension.
3290  */
3291 void ewk_view_paint_context_scale(Ewk_View_Paint_Context* ctxt, float scale_x, float scale_y)
3292 {
3293     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3294
3295     ctxt->gc->scale(WebCore::FloatSize(scale_x, scale_y));
3296 }
3297
3298 /**
3299  * Performs a translation of the origin coordinates.
3300  *
3301  * This function moves the origin coordinates by @p x and @p y pixels.
3302  *
3303  * @param ctxt paint context to paint. Must @b not be @c 0.
3304  * @param x    amount of pixels to translate in the X dimension.
3305  * @param y    amount of pixels to translate in the Y dimension.
3306  */
3307 void ewk_view_paint_context_translate(Ewk_View_Paint_Context* ctxt, float x, float y)
3308 {
3309     EINA_SAFETY_ON_NULL_RETURN(ctxt);
3310
3311     ctxt->gc->translate(x, y);
3312 }
3313
3314 /**
3315  * Paint using given graphics context the given area.
3316  *
3317  * This uses viewport relative area and will also handle scrollbars
3318  * and other extra elements. See ewk_view_paint_contents() for the
3319  * alternative function.
3320  *
3321  * @param priv private handle pointer of view to use as paint source.
3322  * @param cr cairo context to use as paint destination. Its state will
3323  *        be saved before operation and restored afterwards.
3324  * @param area viewport relative geometry to paint.
3325  *
3326  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like
3327  *         incorrect parameters.
3328  *
3329  * @note this is an easy to use version, but internal structures are
3330  *       always created, then graphics context is clipped, then
3331  *       painted, restored and destroyed. This might not be optimum,
3332  *       so using #Ewk_View_Paint_Context may be a better solutions
3333  *       for large number of operations.
3334  *
3335  * @see ewk_view_paint_contents()
3336  * @see ewk_view_paint_context_paint()
3337  *
3338  * @note this is not for general use but just for subclasses that want
3339  *       to define their own backing store.
3340  */
3341 Eina_Bool ewk_view_paint(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
3342 {
3343     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
3344     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
3345     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
3346     WebCore::FrameView* view = priv->main_frame->view();
3347     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
3348
3349     if (view->needsLayout())
3350         view->forceLayout();
3351     WebCore::GraphicsContext gc(cr);
3352     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3353
3354     cairo_save(cr);
3355     gc.save();
3356     gc.clip(rect);
3357     if (view->isTransparent())
3358         gc.clearRect(rect);
3359     view->paint(&gc,  rect);
3360     gc.restore();
3361     cairo_restore(cr);
3362
3363     return EINA_TRUE;
3364 }
3365
3366 /**
3367  * Paint just contents using given graphics context the given area.
3368  *
3369  * This uses absolute coordinates for area and will just handle
3370  * contents, no scrollbars or extras. See ewk_view_paint() for the
3371  * alternative solution.
3372  *
3373  * @param priv private handle pointer of view to use as paint source.
3374  * @param cr cairo context to use as paint destination. Its state will
3375  *        be saved before operation and restored afterwards.
3376  * @param area absolute geometry to paint.
3377  *
3378  * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like
3379  *         incorrect parameters.
3380  *
3381  * @note this is an easy to use version, but internal structures are
3382  *       always created, then graphics context is clipped, then
3383  *       painted, restored and destroyed. This might not be optimum,
3384  *       so using #Ewk_View_Paint_Context may be a better solutions
3385  *       for large number of operations.
3386  *
3387  * @see ewk_view_paint()
3388  * @see ewk_view_paint_context_paint_contents()
3389  *
3390  * @note this is not for general use but just for subclasses that want
3391  *       to define their own backing store.
3392  */
3393 Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area)
3394 {
3395     EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
3396     EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE);
3397     EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE);
3398     WebCore::FrameView* view = priv->main_frame->view();
3399     EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE);
3400
3401     WebCore::GraphicsContext gc(cr);
3402     WebCore::IntRect rect(area->x, area->y, area->w, area->h);
3403
3404     cairo_save(cr);
3405     gc.save();
3406     gc.clip(rect);
3407     if (view->isTransparent())
3408         gc.clearRect(rect);
3409     view->paintContents(&gc,  rect);
3410     gc.restore();
3411     cairo_restore(cr);
3412
3413     return EINA_TRUE;
3414 }
3415
3416
3417 /* internal methods ****************************************************/
3418 /**
3419  * @internal
3420  * Reports the view is ready to be displayed as all elements are aready.
3421  *
3422  * Emits signal: "ready" with no parameters.
3423  */
3424 void ewk_view_ready(Evas_Object* o)
3425 {
3426     DBG("o=%p", o);
3427     evas_object_smart_callback_call(o, "ready", 0);
3428 }
3429
3430 /**
3431  * @internal
3432  * Reports the state of input method changed. This is triggered, for example
3433  * when a input field received/lost focus
3434  *
3435  * Emits signal: "inputmethod,changed" with a boolean indicating whether it's
3436  * enabled or not.
3437  */
3438 void ewk_view_input_method_state_set(Evas_Object* o, Eina_Bool active)
3439 {
3440     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3441     EWK_VIEW_PRIV_GET(sd, priv);
3442     WebCore::Frame* focusedFrame = priv->page->focusController()->focusedOrMainFrame();
3443
3444     priv->imh = 0;
3445     if (focusedFrame
3446         && focusedFrame->document()
3447         && focusedFrame->document()->focusedNode()
3448         && focusedFrame->document()->focusedNode()->hasTagName(WebCore::HTMLNames::inputTag)) {
3449         WebCore::HTMLInputElement* inputElement;
3450
3451         inputElement = static_cast<WebCore::HTMLInputElement*>(focusedFrame->document()->focusedNode());
3452         if (inputElement) {
3453             // for password fields, active == false
3454             if (!active) {
3455                 active = inputElement->isPasswordField();
3456                 priv->imh = inputElement->isPasswordField() * EWK_IMH_PASSWORD;
3457             } else {
3458                 // Set input method hints for "number", "tel", "email", and "url" input elements.
3459                 priv->imh |= inputElement->isTelephoneField() * EWK_IMH_TELEPHONE;
3460                 priv->imh |= inputElement->isNumberField() * EWK_IMH_NUMBER;
3461                 priv->imh |= inputElement->isEmailField() * EWK_IMH_EMAIL;
3462                 priv->imh |= inputElement->isURLField() * EWK_IMH_URL;
3463             }
3464         }
3465     }
3466
3467     evas_object_smart_callback_call(o, "inputmethod,changed", (void*)active);
3468 }
3469
3470 /**
3471  * @internal
3472  * The view title was changed by the frame loader.
3473  *
3474  * Emits signal: "title,changed" with pointer to new title string.
3475  */
3476 void ewk_view_title_set(Evas_Object* o, const char* title)
3477 {
3478     DBG("o=%p, title=%s", o, title ? title : "(null)");
3479     evas_object_smart_callback_call(o, "title,changed", (void*)title);
3480 }
3481
3482 /**
3483  * @internal
3484  * Reports that main frame's uri changed.
3485  *
3486  * Emits signal: "uri,changed" with pointer to the new uri string.
3487  */
3488 void ewk_view_uri_changed(Evas_Object* o)
3489 {
3490     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3491     const char* uri = ewk_frame_uri_get(sd->main_frame);
3492     DBG("o=%p, uri=%s", o, uri ? uri : "(null)");
3493     evas_object_smart_callback_call(o, "uri,changed", (void*)uri);
3494 }
3495
3496 /**
3497  * @internal
3498  * Reports the view started loading something.
3499  *
3500  * @param o View.
3501  *
3502  * Emits signal: "load,started" with no parameters.
3503  */
3504 void ewk_view_load_started(Evas_Object* o)
3505 {
3506     DBG("o=%p", o);
3507     evas_object_smart_callback_call(o, "load,started", 0);
3508 }
3509
3510 /**
3511  * Reports the frame started loading something.
3512  *
3513  * @param o View.
3514  *
3515  * Emits signal: "load,started" on main frame with no parameters.
3516  */
3517 void ewk_view_frame_main_load_started(Evas_Object* o)
3518 {
3519     DBG("o=%p", o);
3520     Evas_Object* frame = ewk_view_frame_main_get(o);
3521     evas_object_smart_callback_call(frame, "load,started", 0);
3522 }
3523
3524 /**
3525  * @internal
3526  * Reports the main frame started provisional load.
3527  *
3528  * @param o View.
3529  *
3530  * Emits signal: "load,provisional" on View with no parameters.
3531  */
3532 void ewk_view_load_provisional(Evas_Object* o)
3533 {
3534     DBG("o=%p", o);
3535     evas_object_smart_callback_call(o, "load,provisional", 0);
3536 }
3537
3538 /**
3539  * @internal
3540  * Reports view can be shown after a new window is created.
3541  *
3542  * @param o Frame.
3543  *
3544  * Emits signal: "load,newwindow,show" on view with no parameters.
3545  */
3546 void ewk_view_load_show(Evas_Object* o)
3547 {
3548     DBG("o=%p", o);
3549     evas_object_smart_callback_call(o, "load,newwindow,show", 0);
3550 }
3551
3552
3553 /**
3554  * @internal
3555  * Reports the main frame was cleared.
3556  *
3557  * @param o View.
3558  */
3559 void ewk_view_frame_main_cleared(Evas_Object* o)
3560 {
3561     DBG("o=%p", o);
3562     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3563     EINA_SAFETY_ON_NULL_RETURN(sd->api->flush);
3564     sd->api->flush(sd);
3565 }
3566
3567 /**
3568  * @internal
3569  * Reports the main frame received an icon.
3570  *
3571  * @param o View.
3572  *
3573  * Emits signal: "icon,received" with no parameters.
3574  */
3575 void ewk_view_frame_main_icon_received(Evas_Object* o)
3576 {
3577     DBG("o=%p", o);
3578     Evas_Object* frame = ewk_view_frame_main_get(o);
3579     evas_object_smart_callback_call(frame, "icon,received", 0);
3580 }
3581
3582 /**
3583  * @internal
3584  * Reports load finished, optionally with error information.
3585  *
3586  * Emits signal: "load,finished" with pointer to #Ewk_Frame_Load_Error
3587  * if any error, or @c 0 if successful load.
3588  *
3589  * @note there should not be any error stuff here, but trying to be
3590  *       compatible with previous WebKit.
3591  */
3592 void ewk_view_load_finished(Evas_Object* o, const Ewk_Frame_Load_Error* error)
3593 {
3594     DBG("o=%p, error=%p", o, error);
3595     evas_object_smart_callback_call(o, "load,finished", (void*)error);
3596 }
3597
3598 /**
3599  * @internal
3600  * Reports load failed with error information.
3601  *
3602  * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error.
3603  */
3604 void ewk_view_load_error(Evas_Object* o, const Ewk_Frame_Load_Error* error)
3605 {
3606     DBG("o=%p, error=%p", o, error);
3607     evas_object_smart_callback_call(o, "load,error", (void*)error);
3608 }
3609
3610 /**
3611  * @internal
3612  * Reports load progress changed.
3613  *
3614  * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0.
3615  */
3616 void ewk_view_load_progress_changed(Evas_Object* o)
3617 {
3618     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3619     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
3620
3621     // Evas_Coord w, h;
3622     double progress = priv->page->progress()->estimatedProgress();
3623
3624     DBG("o=%p (p=%0.3f)", o, progress);
3625
3626     evas_object_smart_callback_call(o, "load,progress", &progress);
3627 }
3628
3629 /**
3630  * @internal
3631  * Reports view @param o should be restored to default conditions
3632  *
3633  * @param o View.
3634  * @param frame Frame that originated restore.
3635  *
3636  * Emits signal: "restore" with frame.
3637  */
3638 void ewk_view_restore_state(Evas_Object* o, Evas_Object* frame)
3639 {
3640     evas_object_smart_callback_call(o, "restore", frame);
3641 }
3642
3643 /**
3644  * @internal
3645  * Delegates to browser the creation of a new window. If it is not implemented,
3646  * current view is returned, so navigation might continue in same window. If
3647  * browser supports the creation of new windows, a new Ewk_Window_Features is
3648  * created and passed to browser. If it intends to keep the request for opening
3649  * the window later it must increments the Ewk_Winwdow_Features ref count by
3650  * calling ewk_window_features_ref(window_features). Otherwise this struct will
3651  * be freed after returning to this function.
3652  *
3653  * @param o Current view.
3654  * @param javascript @c EINA_TRUE if the new window is originated from javascript,
3655  * @c EINA_FALSE otherwise
3656  * @param window_features Features of the new window being created. If it's @c
3657  * NULL, it will be created a window with default features.
3658  *
3659  * @return New view, in case smart class implements the creation of new windows;
3660  * else, current view @param o.
3661  *
3662  * @see ewk_window_features_ref().
3663  */
3664 Evas_Object* ewk_view_window_create(Evas_Object* o, Eina_Bool javascript, const WebCore::WindowFeatures* coreFeatures)
3665 {
3666     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3667
3668     if (!sd->api->window_create)
3669         return o;
3670
3671     Ewk_Window_Features* window_features = ewk_window_features_new_from_core(coreFeatures);
3672     Evas_Object* view = sd->api->window_create(sd, javascript, window_features);
3673     ewk_window_features_unref(window_features);
3674
3675     return view;
3676 }
3677
3678 /**
3679  * @internal
3680  * Reports a window should be closed. It's client responsibility to decide if
3681  * the window should in fact be closed. So, if only windows created by javascript
3682  * are allowed to be closed by this call, browser needs to save the javascript
3683  * flag when the window is created. Since a window can close itself (for example
3684  * with a 'self.close()' in Javascript) browser must postpone the deletion to an
3685  * idler.
3686  *
3687  * @param o View to be closed.
3688  */
3689 void ewk_view_window_close(Evas_Object* o)
3690 {
3691     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3692
3693     ewk_view_stop(o);
3694     if (!sd->api->window_close)
3695         return;
3696     sd->api->window_close(sd);
3697 }
3698
3699 /**
3700  * @internal
3701  * Reports mouse has moved over a link.
3702  *
3703  * Emits signal: "link,hover,in"
3704  */
3705 void ewk_view_mouse_link_hover_in(Evas_Object* o, void* data)
3706 {
3707     evas_object_smart_callback_call(o, "link,hover,in", data);
3708 }
3709
3710 /**
3711  * @internal
3712  * Reports mouse is not over a link anymore.
3713  *
3714  * Emits signal: "link,hover,out"
3715  */
3716 void ewk_view_mouse_link_hover_out(Evas_Object* o)
3717 {
3718     evas_object_smart_callback_call(o, "link,hover,out", 0);
3719 }
3720
3721 /**
3722  * @internal
3723  * Set toolbar visible.
3724  *
3725  * Emits signal: "toolbars,visible,set" with a pointer to a boolean.
3726  */
3727 void ewk_view_toolbars_visible_set(Evas_Object* o, Eina_Bool visible)
3728 {
3729     DBG("o=%p (visible=%d)", o, !!visible);
3730     evas_object_smart_callback_call(o, "toolbars,visible,set", &visible);
3731 }
3732
3733 /**
3734  * @internal
3735  * Get toolbar visibility.
3736  *
3737  * @param o View.
3738  * @param visible boolean pointer in which to save the result. It defaults
3739  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3740  * there are no toolbars and therefore they are not visible.
3741  *
3742  * Emits signal: "toolbars,visible,get" with a pointer to a boolean.
3743  */
3744 void ewk_view_toolbars_visible_get(Evas_Object* o, Eina_Bool* visible)
3745 {
3746     DBG("%s, o=%p", __func__, o);
3747     *visible = EINA_FALSE;
3748     evas_object_smart_callback_call(o, "toolbars,visible,get", visible);
3749 }
3750
3751 /**
3752  * @internal
3753  * Set statusbar visible.
3754  *
3755  * @param o View.
3756  * @param visible @c TRUE if statusbar are visible, @c FALSE otherwise.
3757  *
3758  * Emits signal: "statusbar,visible,set" with a pointer to a boolean.
3759  */
3760 void ewk_view_statusbar_visible_set(Evas_Object* o, Eina_Bool visible)
3761 {
3762     DBG("o=%p (visible=%d)", o, !!visible);
3763     evas_object_smart_callback_call(o, "statusbar,visible,set", &visible);
3764 }
3765
3766 /**
3767  * @internal
3768  * Get statusbar visibility.
3769  *
3770  * @param o View.
3771  * @param visible boolean pointer in which to save the result. It defaults
3772  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3773  * there is no statusbar and therefore it is not visible.
3774  *
3775  * Emits signal: "statusbar,visible,get" with a pointer to a boolean.
3776  */
3777 void ewk_view_statusbar_visible_get(Evas_Object* o, Eina_Bool* visible)
3778 {
3779     DBG("%s, o=%p", __func__, o);
3780     *visible = EINA_FALSE;
3781     evas_object_smart_callback_call(o, "statusbar,visible,get", visible);
3782 }
3783
3784 /**
3785  * @internal
3786  * Set text of statusbar
3787  *
3788  * @param o View.
3789  * @param text New text to put on statusbar.
3790  *
3791  * Emits signal: "statusbar,text,set" with a string.
3792  */
3793 void ewk_view_statusbar_text_set(Evas_Object* o, const char* text)
3794 {
3795     DBG("o=%p (text=%s)", o, text);
3796     INF("status bar text set: %s", text);
3797     evas_object_smart_callback_call(o, "statusbar,text,set", (void *)text);
3798 }
3799
3800 /**
3801  * @internal
3802  * Set scrollbars visible.
3803  *
3804  * @param o View.
3805  * @param visible @c TRUE if scrollbars are visible, @c FALSE otherwise.
3806  *
3807  * Emits signal: "scrollbars,visible,set" with a pointer to a boolean.
3808  */
3809 void ewk_view_scrollbars_visible_set(Evas_Object* o, Eina_Bool visible)
3810 {
3811     DBG("o=%p (visible=%d)", o, !!visible);
3812     evas_object_smart_callback_call(o, "scrollbars,visible,set", &visible);
3813 }
3814
3815 /**
3816  * @internal
3817  * Get scrollbars visibility.
3818  *
3819  * @param o View.
3820  * @param visible boolean pointer in which to save the result. It defaults
3821  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3822  * there are no scrollbars and therefore they are not visible.
3823  *
3824  * Emits signal: "scrollbars,visible,get" with a pointer to a boolean.
3825  */
3826 void ewk_view_scrollbars_visible_get(Evas_Object* o, Eina_Bool* visible)
3827 {
3828     DBG("%s, o=%p", __func__, o);
3829     *visible = EINA_FALSE;
3830     evas_object_smart_callback_call(o, "scrollbars,visible,get", visible);
3831 }
3832
3833 /**
3834  * @internal
3835  * Set menubar visible.
3836  *
3837  * @param o View.
3838  * @param visible @c TRUE if menubar is visible, @c FALSE otherwise.
3839  *
3840  * Emits signal: "menubar,visible,set" with a pointer to a boolean.
3841  */
3842 void ewk_view_menubar_visible_set(Evas_Object* o, Eina_Bool visible)
3843 {
3844     DBG("o=%p (visible=%d)", o, !!visible);
3845     evas_object_smart_callback_call(o, "menubar,visible,set", &visible);
3846 }
3847
3848 /**
3849  * @internal
3850  * Get menubar visibility.
3851  *
3852  * @param o View.
3853  * @param visible boolean pointer in which to save the result. It defaults
3854  * to @c FALSE, i.e. if browser does no listen to emitted signal, it means
3855  * there is no menubar and therefore it is not visible.
3856  *
3857  * Emits signal: "menubar,visible,get" with a pointer to a boolean.
3858  */
3859 void ewk_view_menubar_visible_get(Evas_Object* o, Eina_Bool* visible)
3860 {
3861     DBG("%s, o=%p", __func__, o);
3862     *visible = EINA_FALSE;
3863     evas_object_smart_callback_call(o, "menubar,visible,get", visible);
3864 }
3865
3866 /**
3867  * @internal
3868  * Set tooltip text and display if it is currently hidden.
3869  *
3870  * @param o View.
3871  * @param text Text to set tooltip to.
3872  *
3873  * Emits signal: "tooltip,text,set" with a string. If tooltip must be actually
3874  * removed, text will be 0 or '\0'
3875  */
3876 void ewk_view_tooltip_text_set(Evas_Object* o, const char* text)
3877 {
3878     DBG("o=%p text=%s", o, text);
3879     evas_object_smart_callback_call(o, "tooltip,text,set", (void *)text);
3880 }
3881
3882 /**
3883  * @internal
3884  *
3885  * @param o View.
3886  * @param message String to show on console.
3887  * @param lineNumber Line number.
3888  * @sourceID Source id.
3889  *
3890  */
3891 void ewk_view_add_console_message(Evas_Object* o, const char* message, unsigned int lineNumber, const char* sourceID)
3892 {
3893     DBG("o=%p message=%s lineNumber=%u sourceID=%s", o, message, lineNumber, sourceID);
3894     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3895     EINA_SAFETY_ON_NULL_RETURN(sd->api);
3896     EINA_SAFETY_ON_NULL_RETURN(sd->api->add_console_message);
3897     sd->api->add_console_message(sd, message, lineNumber, sourceID);
3898 }
3899
3900 void ewk_view_run_javascript_alert(Evas_Object* o, Evas_Object* frame, const char* message)
3901 {
3902     DBG("o=%p frame=%p message=%s", o, frame, message);
3903     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
3904     EINA_SAFETY_ON_NULL_RETURN(sd->api);
3905
3906     if (!sd->api->run_javascript_alert)
3907         return;
3908
3909     sd->api->run_javascript_alert(sd, frame, message);
3910 }
3911
3912 Eina_Bool ewk_view_run_javascript_confirm(Evas_Object* o, Evas_Object* frame, const char* message)
3913 {
3914     DBG("o=%p frame=%p message=%s", o, frame, message);
3915     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3916     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3917
3918     if (!sd->api->run_javascript_confirm)
3919         return EINA_FALSE;
3920
3921     return sd->api->run_javascript_confirm(sd, frame, message);
3922 }
3923
3924 Eina_Bool ewk_view_run_javascript_prompt(Evas_Object* o, Evas_Object* frame, const char* message, const char* defaultValue, char** value)
3925 {
3926     DBG("o=%p frame=%p message=%s", o, frame, message);
3927     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3928     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3929
3930     if (!sd->api->run_javascript_prompt)
3931         return EINA_FALSE;
3932
3933     return sd->api->run_javascript_prompt(sd, frame, message, defaultValue, value);
3934 }
3935
3936 /**
3937  * @internal
3938  * Delegates to client to decide whether a script must be stopped because it's
3939  * running for too long. If client does not implement it, it goes to default
3940  * implementation, which logs and returns EINA_FALSE. Client may remove log by
3941  * setting this function 0, which will just return EINA_FALSE.
3942  *
3943  * @param o View.
3944  *
3945  * @return @c EINA_TRUE if script should be stopped; @c EINA_FALSE otherwise
3946  */
3947 Eina_Bool ewk_view_should_interrupt_javascript(Evas_Object* o)
3948 {
3949     DBG("o=%p", o);
3950     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
3951     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
3952
3953     if (!sd->api->should_interrupt_javascript)
3954         return EINA_FALSE;
3955
3956     return sd->api->should_interrupt_javascript(sd);
3957 }
3958
3959 /**
3960  * @internal
3961  * This is called whenever the web site shown in @param frame is asking to store data
3962  * to the database @param databaseName and the quota allocated to that web site
3963  * is exceeded. Browser may use this to increase the size of quota before the
3964  * originating operationa fails.
3965  *
3966  * @param o View.
3967  * @param frame The frame whose web page exceeded its database quota.
3968  * @param databaseName Database name.
3969  * @param current_size Current size of this database
3970  * @param expected_size The expected size of this database in order to fulfill
3971  * site's requirement.
3972  */
3973 uint64_t ewk_view_exceeded_database_quota(Evas_Object* o, Evas_Object* frame, const char* databaseName, uint64_t current_size, uint64_t expected_size)
3974 {
3975     DBG("o=%p", o);
3976     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
3977     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, 0);
3978     if (!sd->api->exceeded_database_quota)
3979         return 0;
3980
3981     INF("current_size=%"PRIu64" expected_size=%"PRIu64, current_size, expected_size);
3982     return sd->api->exceeded_database_quota(sd, frame, databaseName, current_size, expected_size);
3983 }
3984
3985 /**
3986  * @internal
3987  * Open panel to choose a file.
3988  *
3989  * @param o View.
3990  * @param frame Frame in which operation is required.
3991  * @param allows_multiple_files @c EINA_TRUE when more than one file may be
3992  * selected, @c EINA_FALSE otherwise
3993  * @suggested_filenames List of suggested files to select. It's advisable to
3994  * just ignore this value, since it's a source of security flaw.
3995  * @selected_filenames List of files selected.
3996  *
3997  * @return @EINA_FALSE if user canceled file selection; @EINA_TRUE if confirmed.
3998  */
3999 Eina_Bool ewk_view_run_open_panel(Evas_Object* o, Evas_Object* frame, Eina_Bool allows_multiple_files, const Eina_List* suggested_filenames, Eina_List** selected_filenames)
4000 {
4001     DBG("o=%p frame=%p allows_multiple_files=%d", o, frame, allows_multiple_files);
4002     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
4003     EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE);
4004     Eina_Bool confirm;
4005
4006     if (!sd->api->run_open_panel)
4007         return EINA_FALSE;
4008
4009     *selected_filenames = 0;
4010
4011     confirm = sd->api->run_open_panel(sd, frame, allows_multiple_files, suggested_filenames, selected_filenames);
4012     if (!confirm && *selected_filenames)
4013         ERR("Canceled file selection, but selected filenames != 0. Free names before return.");
4014     return confirm;
4015 }
4016
4017 void ewk_view_repaint(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
4018 {
4019     DBG("o=%p, region=%d,%d + %dx%d", o, x, y, w, h);
4020     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4021     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4022
4023     if (!priv->main_frame->contentRenderer()) {
4024         ERR("no main frame content renderer.");
4025         return;
4026     }
4027
4028     _ewk_view_repaint_add(priv, x, y, w, h);
4029     _ewk_view_smart_changed(sd);
4030 }
4031
4032 void ewk_view_scroll(Evas_Object* o, Evas_Coord dx, Evas_Coord dy, Evas_Coord sx, Evas_Coord sy, Evas_Coord sw, Evas_Coord sh, Evas_Coord cx, Evas_Coord cy, Evas_Coord cw, Evas_Coord ch, Eina_Bool main_frame)
4033 {
4034     DBG("o=%p, delta: %d,%d, scroll: %d,%d+%dx%d, clip: %d,%d+%dx%d",
4035         o, dx, dy, sx, sy, sw, sh, cx, cy, cw, ch);
4036
4037     if ((sx != cx) || (sy != cy) || (sw != cw) || (sh != ch))
4038         WRN("scroll region and clip are different! %d,%d+%dx%d and %d,%d+%dx%d",
4039             sx, sy, sw, sh, cx, cy, cw, ch);
4040
4041     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4042     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4043     EINA_SAFETY_ON_TRUE_RETURN(!dx && !dy);
4044
4045     _ewk_view_scroll_add(priv, dx, dy, sx, sy, sw, sh, main_frame);
4046
4047     _ewk_view_smart_changed(sd);
4048 }
4049
4050 WebCore::Page* ewk_view_core_page_get(const Evas_Object* o)
4051 {
4052     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4053     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
4054     return priv->page;
4055 }
4056
4057 /**
4058  * Creates a new frame for given url and owner element.
4059  *
4060  * Emits "frame,created" with the new frame object on success.
4061  */
4062 WTF::PassRefPtr<WebCore::Frame> ewk_view_frame_create(Evas_Object* o, Evas_Object* frame, const WTF::String& name, WebCore::HTMLFrameOwnerElement* ownerElement, const WebCore::KURL& url, const WTF::String& referrer)
4063 {
4064     DBG("o=%p, frame=%p, name=%s, ownerElement=%p, url=%s, referrer=%s",
4065         o, frame, name.utf8().data(), ownerElement,
4066         url.string().utf8().data(), referrer.utf8().data());
4067
4068     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4069     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0);
4070
4071     WTF::RefPtr<WebCore::Frame> cf = _ewk_view_core_frame_new
4072         (sd, priv, ownerElement);
4073     if (!cf) {
4074         ERR("Could not create child core frame '%s'", name.utf8().data());
4075         return 0;
4076     }
4077
4078     if (!ewk_frame_child_add(frame, cf, name, url, referrer)) {
4079         ERR("Could not create child frame object '%s'", name.utf8().data());
4080         return 0;
4081     }
4082
4083     // The creation of the frame may have removed itself already.
4084     if (!cf->page() || !cf->tree() || !cf->tree()->parent())
4085         return 0;
4086
4087     sd->changed.frame_rect = EINA_TRUE;
4088     _ewk_view_smart_changed(sd);
4089
4090     evas_object_smart_callback_call(o, "frame,created", frame);
4091     return cf.release();
4092 }
4093
4094 WTF::PassRefPtr<WebCore::Widget> ewk_view_plugin_create(Evas_Object* o, Evas_Object* frame, const WebCore::IntSize& pluginSize, WebCore::HTMLPlugInElement* element, const WebCore::KURL& url, const WTF::Vector<WTF::String>& paramNames, const WTF::Vector<WTF::String>& paramValues, const WTF::String& mimeType, bool loadManually)
4095 {
4096     DBG("o=%p, frame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s",
4097         o, frame, pluginSize.width(), pluginSize.height(), element,
4098         url.string().utf8().data(), mimeType.utf8().data());
4099
4100     EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0);
4101     sd->changed.frame_rect = EINA_TRUE;
4102     _ewk_view_smart_changed(sd);
4103
4104     return ewk_frame_plugin_create
4105         (frame, pluginSize, element, url, paramNames, paramValues,
4106          mimeType, loadManually);
4107 }
4108
4109
4110 /**
4111  * @internal
4112  *
4113  * Creates a new popup with options when a select widget was clicked.
4114  *
4115  * @param client PopupMenuClient instance that allows communication with webkit.
4116  * @param selected Selected item.
4117  * @param rect Menu's position.
4118  *
4119  * Emits: "popup,create" with a list of Ewk_Menu containing each item's data
4120  */
4121 void ewk_view_popup_new(Evas_Object* o, WebCore::PopupMenuClient* client, int selected, const WebCore::IntRect& rect)
4122 {
4123     INF("o=%p", o);
4124     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4125     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4126
4127     if (priv->popup.menu_client)
4128         ewk_view_popup_destroy(o);
4129
4130     priv->popup.menu_client = client;
4131
4132     // populate items
4133     const int size = client->listSize();
4134     for (int i = 0; i < size; ++i) {
4135         Ewk_Menu_Item* item = (Ewk_Menu_Item*) malloc(sizeof(*item));
4136         if (client->itemIsSeparator(i))
4137             item->type = EWK_MENU_SEPARATOR;
4138         else if (client->itemIsLabel(i))
4139             item->type = EWK_MENU_GROUP;
4140         else
4141             item->type = EWK_MENU_OPTION;
4142         item->text = eina_stringshare_add(client->itemText(i).utf8().data());
4143
4144         priv->popup.menu.items = eina_list_append(priv->popup.menu.items, item);
4145     }
4146
4147     priv->popup.menu.x = rect.x();
4148     priv->popup.menu.y = rect.y();
4149     priv->popup.menu.width = rect.width();
4150     priv->popup.menu.height = rect.height();
4151     evas_object_smart_callback_call(o, "popup,create", &priv->popup.menu);
4152 }
4153
4154 /**
4155  * Destroy a previously created menu.
4156  *
4157  * Before destroying, it informs client that menu's data is ready to be
4158  * destroyed by sending a "popup,willdelete" with a list of menu items. Then it
4159  * removes any reference to menu inside webkit. It's safe to call this
4160  * function either from inside webkit or from browser.
4161  *
4162  * @param o View.
4163  *
4164  * @returns EINA_TRUE in case menu was successfully destroyed or EINA_TRUE in
4165  * case there wasn't any menu to be destroyed.
4166  */
4167 Eina_Bool ewk_view_popup_destroy(Evas_Object* o)
4168 {
4169     INF("o=%p", o);
4170     EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE);
4171     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE);
4172
4173     if (!priv->popup.menu_client)
4174         return EINA_FALSE;
4175
4176     evas_object_smart_callback_call(o, "popup,willdelete", &priv->popup.menu);
4177
4178     void* itemv;
4179     EINA_LIST_FREE(priv->popup.menu.items, itemv) {
4180         Ewk_Menu_Item* item = (Ewk_Menu_Item*)itemv;
4181         eina_stringshare_del(item->text);
4182         free(item);
4183     }
4184     priv->popup.menu_client->popupDidHide();
4185     priv->popup.menu_client = 0;
4186
4187     return EINA_TRUE;
4188 }
4189
4190 /**
4191  * Changes currently selected item.
4192  *
4193  * Changes the option selected in select widget. This is called by browser
4194  * whenever user has chosen a different item. Most likely after calling this, a
4195  * call to ewk_view_popup_destroy might be made in order to close the popup.
4196  *
4197  * @param o View.
4198  * @index Index of selected item.
4199  *
4200  */
4201 void ewk_view_popup_selected_set(Evas_Object* o, int index)
4202 {
4203     INF("o=%p", o);
4204     EWK_VIEW_SD_GET_OR_RETURN(o, sd);
4205     EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv);
4206     EINA_SAFETY_ON_NULL_RETURN(priv->popup.menu_client);
4207
4208     priv->popup.menu_client->valueChanged(index);
4209 }
4210
4211 /**
4212  * @internal
4213  * Request a download to user.
4214  *
4215  * @param o View.
4216  * @oaram download Ewk_Download struct to be sent.
4217  *
4218  * Emits: "download,request" with an Ewk_Download containing the details of the
4219  * requested download. The download per se must be handled outside of webkit.
4220  */
4221 void ewk_view_download_request(Evas_Object* o, Ewk_Download* download)
4222 {
4223     DBG("view=%p", o);
4224     evas_object_smart_callback_call(o, "download,request", download);
4225 }
4226
4227 /**
4228  * @internal
4229  * Reports the viewport has changed.
4230  *
4231  * @param arguments viewport argument.
4232  *
4233  * Emits signal: "viewport,changed" with no parameters.
4234  */
4235 void ewk_view_viewport_attributes_set(Evas_Object *o, const WebCore::ViewportArguments& arguments)
4236 {
4237     EWK_VIEW_SD_GET(o, sd);
4238     EWK_VIEW_PRIV_GET(sd, priv);
4239     
4240     priv->viewport_arguments = arguments;
4241     evas_object_smart_callback_call(o, "viewport,changed", 0);
4242 }
4243
4244 /**
4245  * Gets attributes of viewport meta tag.
4246  *
4247  * @param o view.
4248  * @param w width.
4249  * @param h height.
4250  * @param init_scale initial Scale value.
4251  * @param max_scale maximum Scale value.
4252  * @param min_scale minimum Scale value.
4253  * @param device_pixel_ratio value.
4254  * @param user_scalable user Scalable value.
4255  */
4256 void ewk_view_viewport_attributes_get(Evas_Object *o, float* w, float* h, float* init_scale, float* max_scale, float* min_scale, float* device_pixel_ratio, Eina_Bool* user_scalable)
4257 {
4258     WebCore::ViewportAttributes attributes = _ewk_view_viewport_attributes_compute(o);
4259
4260     if (w)
4261         *w = attributes.layoutSize.width();
4262     if (h)
4263         *h = attributes.layoutSize.height();
4264     if (init_scale)
4265         *init_scale = attributes.initialScale;
4266     if (max_scale)
4267         *max_scale = attributes.maximumScale;
4268     if (min_scale)
4269         *min_scale = attributes.minimumScale;
4270     if (device_pixel_ratio)
4271         *device_pixel_ratio = attributes.devicePixelRatio;
4272     if (user_scalable)
4273         *user_scalable = static_cast<bool>(attributes.userScalable);
4274 }
4275
4276 /**
4277  * Sets the zoom range.
4278  *
4279  * @param o view.
4280  * @param min_scale minimum value of zoom range.
4281  * @param max_scale maximum value of zoom range.
4282  * 
4283  * @return @c EINA_TRUE if zoom range is changed, @c EINA_FALSE if not or failure.
4284  */
4285 Eina_Bool ewk_view_zoom_range_set(Evas_Object* o, float min_scale, float max_scale)
4286 {
4287     EWK_VIEW_SD_GET(o, sd);
4288     EWK_VIEW_PRIV_GET(sd, priv);
4289
4290     if (max_scale < min_scale) {
4291         WRN("min_scale is larger than max_scale");
4292         return EINA_FALSE;
4293     }
4294
4295     priv->settings.zoom_range.min_scale = min_scale;
4296     priv->settings.zoom_range.max_scale = max_scale;
4297
4298     return EINA_TRUE;
4299 }
4300
4301 /**
4302  * Gets the minimum value of zoom range.
4303  *
4304  * @param o view.
4305  *
4306  * @return minimum value of zoom range.
4307  */
4308 float ewk_view_zoom_range_min_get(Evas_Object* o)
4309 {
4310     EWK_VIEW_SD_GET(o, sd);
4311     EWK_VIEW_PRIV_GET(sd, priv);
4312
4313     return priv->settings.zoom_range.min_scale;
4314 }
4315
4316 /**
4317  * Gets the maximum value of zoom range.
4318  *
4319  * @param o view.