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