diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit/efl | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit/efl')
112 files changed, 22830 insertions, 0 deletions
diff --git a/Source/WebKit/efl/CMakeListsEfl.txt b/Source/WebKit/efl/CMakeListsEfl.txt new file mode 100644 index 0000000..7e68afd --- /dev/null +++ b/Source/WebKit/efl/CMakeListsEfl.txt @@ -0,0 +1,218 @@ +INCLUDE(WebKitEfl) + +LIST(APPEND WebKit_LINK_FLAGS + ${ECORE_X_LDFLAGS} + ${EDJE_LDFLAGS} + ${EFLDEPS_LDFLAGS} + ${EVAS_LDFLAGS} +) + +LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBKIT_DIR}/efl/ewk" + "${WEBKIT_DIR}/efl/WebCoreSupport" + "${WEBCORE_DIR}/platform/efl" + "${WEBCORE_DIR}/platform/graphics/cairo" + ${Cairo_INCLUDE_DIRS} + ${ECORE_X_INCLUDE_DIRS} + ${EDJE_INCLUDE_DIRS} + ${EFLDEPS_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${LIBXML2_INCLUDE_DIR} + ${LIBXSLT_INCLUDE_DIRS} + ${SQLITE_INCLUDE_DIRS} +) + +IF (ENABLE_VIDEO) +LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/platform/graphics/gstreamer" + ${GStreamer-App_INCLUDE_DIRS} + ${GStreamer-Interfaces_INCLUDE_DIRS} + ${GStreamer-Pbutils_INCLUDE_DIRS} + ${GStreamer-Video_INCLUDE_DIRS} +) +ENDIF() + +IF (WTF_USE_FREETYPE) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/platform/graphics/freetype" + ) +ENDIF () + +IF (WTF_USE_PANGO) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + "${WEBCORE_DIR}/platform/graphics/pango" + ${Pango_INCLUDE_DIRS} + ) + LIST(APPEND WebKit_LIBRARIES + ${Pango_LIBRARIES} + ) +ENDIF () + +LIST(APPEND WebKit_SOURCES + efl/WebCoreSupport/ChromeClientEfl.cpp + efl/WebCoreSupport/DragClientEfl.cpp + efl/WebCoreSupport/EditorClientEfl.cpp + efl/WebCoreSupport/FrameLoaderClientEfl.cpp + efl/WebCoreSupport/FullscreenVideoControllerEfl.cpp + efl/WebCoreSupport/InspectorClientEfl.cpp + + efl/ewk/ewk_contextmenu.cpp + efl/ewk/ewk_cookies.cpp + efl/ewk/ewk_frame.cpp + efl/ewk/ewk_history.cpp + efl/ewk/ewk_main.cpp + efl/ewk/ewk_settings.cpp + efl/ewk/ewk_tiled_backing_store.c + efl/ewk/ewk_tiled_matrix.c + efl/ewk/ewk_tiled_model.c + efl/ewk/ewk_util.cpp + efl/ewk/ewk_view.cpp + efl/ewk/ewk_view_single.c + efl/ewk/ewk_view_tiled.c + efl/ewk/ewk_window_features.cpp +) + +LIST(APPEND WebKit_LIBRARIES + ${Cairo_LIBRARIES} + ${ECORE_X_LIBRARIES} + ${EFLDEPS_LIBRARIES} + ${Freetype_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${SQLITE_LIBRARIES} + ${FONTCONFIG_LIBRARIES} + ${PNG_LIBRARY} + ${JPEG_LIBRARY} + ${CMAKE_DL_LIBS} +) + +IF (ENABLE_GLIB_SUPPORT) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES + ${Gdk_INCLUDE_DIRS} + ${Glib_INCLUDE_DIRS} + ${JAVASCRIPTCORE_DIR}/wtf/gobject + ) + LIST(APPEND WebKit_LIBRARIES + ${Glib_LIBRARIES} + ${Gdk_LIBRARIES} + ) +ENDIF () + +IF (WTF_USE_SOUP) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES ${LIBSOUP24_INCLUDE_DIRS}) + LIST(APPEND WebKit_LIBRARIES ${LIBSOUP24_LIBRARIES}) +ENDIF () + +IF (WTF_USE_CURL) + LIST(APPEND WebKit_INCLUDE_DIRECTORIES ${CURL_INCLUDE_DIRS}) + LIST(APPEND WebKit_LIBRARIES ${CURL_LIBRARIES}) +ENDIF () + +SET(BUILD_DATA_DIR ${CMAKE_BINARY_DIR}/WebKit/efl/DefaultTheme) +SET(BUILD_DATA_DIR ${BUILD_DATA_DIR} PARENT_SCOPE) +FILE(MAKE_DIRECTORY ${BUILD_DATA_DIR}) + +SET(WebKit_THEME_DEFINITION "") +IF (ENABLE_PROGRESS_TAG) + LIST(APPEND WebKit_THEME_DEFINITION "-DENABLE_PROGRESS_TAG") +ENDIF () + +SET(WebKit_THEME ${BUILD_DATA_DIR}/default.edj) +ADD_CUSTOM_COMMAND( + OUTPUT ${WebKit_THEME} + COMMAND ${EDJE_CC_EXECUTABLE} -v -id ${WEBKIT_DIR}/efl/DefaultTheme ${WebKit_THEME_DEFINITION} ${WEBKIT_DIR}/efl/DefaultTheme/default.edc ${WebKit_THEME} + DEPENDS + ${WEBKIT_DIR}/efl/DefaultTheme/default.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_knob_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_knob_press_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_knob_press_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_knob_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_fill_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_fill_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/slider/slider_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_focus_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_press.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/icon.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_normal.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_normal_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_hover_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/combo/combo_press_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/decoration/search_decoration.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/decoration/decoration_normal_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/field/field_hovered.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/field/search_field.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/field/field_normal.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/field/field_focused.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/cancel/cancel_normal_button.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/cancel/cancel_normal_button2.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/search/cancel/search_cancel.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_off_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/check.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_on_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_on_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_off_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_off.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/check/img_check_on.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_on.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_off_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_off_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_on_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/radio.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_off.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/radio/img_radio_on_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/button/img_button_normal.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/button/img_button_press.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/button/img_button_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/button/img_button_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/button/button.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/entry/entry.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/entry/img_normal.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/entry/img_focused.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/entry/img_hovered.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/scrollbar/scrollbar_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/scrollbar/scrollbar_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_v.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_h.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/scrollbar/scrollbar.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/file/file_normal.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/file/file_press.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/file/file_hover.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/file/file_focus.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/file/file.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/progressbar/progressbar.edc + ${WEBKIT_DIR}/efl/DefaultTheme/widget/progressbar/shelf_inset.png + ${WEBKIT_DIR}/efl/DefaultTheme/widget/progressbar/bt_base.png + VERBATIM +) + +LIST(APPEND WebKit_SOURCES + ${WebKit_THEME} +) + +IF (SHARED_CORE) + SET(LIBS_PRIVATE "-l${WTF_LIBRARY_NAME} -l${JavaScriptCore_LIBRARY_NAME} -l${WebCore_LIBRARY_NAME}") +ELSE () + SET(LIBS_PRIVATE "") +ENDIF () + +CONFIGURE_FILE( + efl/ewebkit.pc.in + ${CMAKE_BINARY_DIR}/WebKit/efl/ewebkit.pc + @ONLY) +INSTALL(FILES ${CMAKE_BINARY_DIR}/WebKit/efl/ewebkit.pc + DESTINATION lib/pkgconfig) + +UNSET(LIBS_PRIVATE) + +FILE(GLOB EWebKit_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/efl/ewk/*.h") +LIST(REMOVE_ITEM EWebKit_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/efl/ewk/ewk_private.h") + +INSTALL(FILES ${EWebKit_HEADERS} + DESTINATION include/${WebKit_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR}) + +INSTALL(FILES ${WebKit_THEME} + DESTINATION share/${WebKit_LIBRARY_NAME}-${PROJECT_VERSION_MAJOR}/themes) diff --git a/Source/WebKit/efl/ChangeLog b/Source/WebKit/efl/ChangeLog new file mode 100644 index 0000000..5dcc5cf --- /dev/null +++ b/Source/WebKit/efl/ChangeLog @@ -0,0 +1,1874 @@ +2011-01-14 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Try to fix EFL build. + + * ewk/ewk_frame.cpp: + (ewk_frame_scroll_add): Added WebCore namespace to IntSize. + * ewk/ewk_view.cpp: + (_ewk_view_viewport_attributes_compute): Ditto. + +2011-01-14 Tony Gentilcore <tonyg@chromium.org> + + Unreviewed build fix. + + Fix Qt build after r75837 + https://bugs.webkit.org/show_bug.cgi?id=52494 + + * ewk/ewk_view.cpp: + +2011-01-09 Xianzhu Wang <phnixwxz@gmail.com> + + Reviewed by Darin Fisher. + + https://bugs.webkit.org/show_bug.cgi?id=41441 + createWindow method should only do window-creating without URL navigation + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::createWindow): + +2010-12-27 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Set the frame smart object base clipper to non-static. + https://bugs.webkit.org/show_bug.cgi?id=51552 + + The base clipper of the clipped smart object, which is the parent + class of the ewk_frame class is a static clipper. It's normally only + used for showing/hiding the object, but in the case of the ewk_frame, + it needs to clip the object to its dimension, in order to clip + scrollbars of inner frames. + + Setting it to non-static makes the clipper to be automatically moved + by the parent class, thus staying on the correct position when the + frame is moved. + + This change needed to be done after the adoption of the static clipper + on the clipped smart base class. + + * ewk/ewk_frame.cpp: + (_ewk_frame_smart_add): + +2010-12-24 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Add option to enable Touch Events. + https://bugs.webkit.org/show_bug.cgi?id=49125 + + Implement ewk_frame_feed_touch_event to feed touch events. Because EFL + doesn't have touch events, Application should generate and pass it. + + * WebCoreSupport/ChromeClientEfl.h: + (WebCore::ChromeClientEfl::needTouchEvents): + * ewk/ewk_frame.cpp: + (ewk_frame_feed_touch_event): + * ewk/ewk_frame.h: + +2010-12-22 Sam Weinig <sam@webkit.org> + + Reviewed by Darin Adler. + + WebKit2 needs to mirror the frame tree in the UIProcess + https://bugs.webkit.org/show_bug.cgi?id=51546 + + - Add client functions to notify that a frame has been added or + removed from the page cache. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::didSaveToPageCache): + (WebCore::FrameLoaderClientEfl::didRestoreFromPageCache): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-12-22 Ryosuke Niwa <rniwa@webkit.org> + + Reviewed by Eric Seidel. + + Editor.h doesn't need to include SelectionController.h + https://bugs.webkit.org/show_bug.cgi?id=51441 + + Renamed SelectionController::EDirection to SelectionDirection. + + * WebCoreSupport/EditorClientEfl.cpp: + (WebCore::EditorClientEfl::handleEditingKeyboardEvent): + +2010-12-23 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Fix ContextMenu removal + https://bugs.webkit.org/show_bug.cgi?id=51530 + + Fix ContextMenu removal + + In r74207 the support for ContextMenu was removed from EFL while the + code is being ported to the new CROSS_PLATFORM_MENUS due to build + breakage. However there were some missing removals in the shutdown + logic that introduced a bug, leading to a segmentation fault when + ContexController was destroyed. + + The best way to effectively disable the ContextMenu is to conditionally + compile the meaningful stuff by surrounding with "#if + ENABLE(CONTEXT_MENUS)" and then disabling it in CMake. + + * ewk/ewk_contextmenu.cpp: surround need parts with #if + ENABLE(CONTEXT_MENUS). + (ewk_context_menu_destroy): ditto. + (ewk_context_menu_item_select): ditto. + * ewk/ewk_private.h: ditto. + * ewk/ewk_view.cpp: ditto. + +2010-12-23 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Clean warnings in Tiled Backing Store + https://bugs.webkit.org/show_bug.cgi?id=51529 + + Tiled backing store in EFL was giving the following warnings that are + gone now: + + - Static function defined but not used; + - Comparison between signed and unsigned integer expressions; + + * ewk/ewk_tiled_backing_store.c: + (_ewk_tiled_backing_store_item_fill): + (_ewk_tiled_backing_store_smart_calculate): + * ewk/ewk_tiled_matrix.c: + (_ewk_tile_matrix_slicer_setup): + +2010-12-23 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed build warning fix. + + [EFL] Remove warning messages during the webkit efl compiling + https://bugs.webkit.org/show_bug.cgi?id=51520 + + Remove build warning messages. + + * ewk/ewk_view.cpp: + (_ewk_view_smart_show): + (_ewk_view_smart_hide): + * ewk/ewk_view.h: + +2010-12-22 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Sets default user agent + https://bugs.webkit.org/show_bug.cgi?id=47903 + + If applcation(e.g EWebLauncher) doesn't set user agent, WebKit EFL doesn't + set user agent. However, we need to set user agent by default. Because, some + web sites send different pages according to user agent. + + * ewk/ewk_private.h: + * ewk/ewk_settings.cpp: + (_ewk_settings_webkit_platform): + (_ewk_settings_webkit_os_version): + (ewk_settings_default_user_agent_get): + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2010-12-16 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed build fix. + + Disable ContextMenu support for now while support for + CROSS_PLATFORM_MENUS is written. + + * CMakeListsEfl.txt: + * WebCoreSupport/ContextMenuClientEfl.cpp: Removed. + * WebCoreSupport/ContextMenuClientEfl.h: Removed. + * ewk/ewk_contextmenu.cpp: + (ewk_context_menu_item_append): + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2010-12-13 Alex Bredariol Grilo <abgrilo@profusion.mobi> + + Reviewed by Andreas Kling. + + Remove adjacent tiles rendering queue. + https://bugs.webkit.org/show_bug.cgi?id=50023 + + In the current implementation of the tiled backing store, one extra row + and column of tiles are needed to render the entire viewport. These + extra row/col proved to be expensive when being rendered, and were + postponed to a queue that would render them after rendering the other + tiles of the viewport first. This approach complicated unnecessarily + the logics with no gain for keeping the extra row and column. This + change removes this rendering queue, for later removing the extra row + and column of tiles. + + * ewk/ewk_tiled_backing_store.c: + (_ewk_tiled_backing_store_pre_render_request_add): + (_ewk_tiled_backing_store_pre_render_request_flush): + (_ewk_tiled_backing_store_pre_render_request_clear): + (_ewk_tiled_backing_store_pre_render_request_process_single): + (_ewk_tiled_backing_store_item_fill): + (_ewk_tiled_backing_store_item_add): + (_ewk_tiled_backing_store_item_del): + (_ewk_tiled_backing_store_recalc_renderers): + (ewk_tiled_backing_store_pre_render_region): + (ewk_tiled_backing_store_pre_render_relative_radius): + (ewk_tiled_backing_store_pre_render_cancel): + +2010-12-13 Alex Bredariol Grilo <abgrilo@profusion.mobi> + + Reviewed by Andreas Kling. + + Remove one row/column of renderers. + https://bugs.webkit.org/show_bug.cgi?id=50456 + + This changes the algorithm in a way that it will require one less column + and row of renderers to fill the viewport. The direct result of this is + that now less tiles need to be rendered at once when displaying the + viewport. + + * ewk/ewk_tiled_backing_store.c: + (_ewk_tiled_backing_store_smart_add): + (_ewk_tiled_backing_store_recalc_renderers): + (_ewk_tiled_backing_store_view_wrap_up): + (_ewk_tiled_backing_store_view_wrap_down): + (_ewk_tiled_backing_store_view_wrap_left): + (_ewk_tiled_backing_store_view_wrap_right): + (_ewk_tiled_backing_store_smart_calculate_offset_force): + (_ewk_tiled_backing_store_smart_calculate_offset): + (_ewk_tiled_backing_store_smart_calculate): + (_ewk_tiled_backing_store_zoom_set_internal): + (ewk_tiled_backing_store_zoom_weak_set): + (ewk_tiled_backing_store_fix_offsets): + (ewk_tiled_backing_store_flush): + +2010-10-28 MORITA Hajime <morrita@google.com> + + Reviewed by Ojan Vafai. + + spellcheck does not check pasted text + https://bugs.webkit.org/show_bug.cgi?id=40092 + + Added a stub implememntation. + + * WebCoreSupport/EditorClientEfl.h: + (WebCore::EditorClientEfl::requestCheckingOfString): + +2010-12-09 Alex Bredariol Grilo <abgrilo@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Add missing function in WebKit-EFL API + + Add ewk_tiled_backing_store_zoom_weak_smooth_scale_set function in + WebKit-EFL API. This function was already implemented but missing in + header file. + + * ewk/ewk_tiled_backing_store.h: + +2010-12-09 Alex Bredariol Grilo <abgrilo@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Fix scroll operation in WebKit-EFL + https://bugs.webkit.org/show_bug.cgi?id=50752 + + Add the _ewk_view_scroll_add call in WebKit-EFL scroll function. This + call was wrongly removed in previous commit and performs the scroll + operation on the page. + + * ewk/ewk_view.cpp: + (ewk_view_scroll): + +2010-12-03 Alex Bredariol Grilo <abgrilo@profusion.mobi> + + Reviewed by Andreas Kling. + + Update usage of Eina_Iterator due to EFL changes. + https://bugs.webkit.org/show_bug.cgi?id=50457 + + * ewk/ewk_tiled_model.c: + (ewk_tile_updates_process): + +2010-12-01 Jia Pu <jpu@apple.com> + + Reviewed by Darin Adler. + + Support multiple correction candidates panel for misspelled word on Mac OS X. + https://bugs.webkit.org/show_bug.cgi?id=50137 + <rdar://problem/8568059> + + Adopted new function signature defined in base class. + + * WebCoreSupport/EditorClientEfl.cpp: + (WebCore::EditorClientEfl::getGuessesForWord): + * WebCoreSupport/EditorClientEfl.h: + +2010-11-22 Alex Grilo <abgrilo@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Tiled Backing Store for Webkit-Efl + https://bugs.webkit.org/show_bug.cgi?id=45397 + + This tile based backing store is a grid of tiles where each tile is + an Evas_Object showing a piece of the page content. The + new ewk_view_tiled.c is an implementation of some of the functions of + the original ewk_view, that makes calls to the Tiled Backing Store + specific functions. + + The rendering occurs in the pixels stored in each tile (Evas_Object), + in the same way as the previous single backing store. Tiles not being + shown in the viewport are stored in a cache, and can be reused later + to avoid having to be rendered again. + + Scrolling occurs as just moving the tiles, using Evas move operations, + and when more than one tile size is scrolled, a shift of rows or + columns needs to be done. + + * CMakeListsEfl.txt: + * ewk/ewk_tiled_backing_store.c: Added. + (_ewk_tiled_backing_store_updates_process): + (_ewk_tiled_backing_store_flush): + (_ewk_tiled_backing_store_tile_new): + (_ewk_tiled_backing_store_item_move): + (_ewk_tiled_backing_store_item_resize): + (_ewk_tiled_backing_store_tile_associate): + (_ewk_tiled_backing_store_tile_dissociate): + (_ewk_tiled_backing_store_tile_dissociate_all): + (_ewk_tiled_backing_store_pre_render_request_add): + (_ewk_tiled_backing_store_pre_render_request_del): + (_ewk_tiled_backing_store_pre_render_request_first): + (_ewk_tiled_backing_store_pre_render_request_flush): + (_ewk_tiled_backing_store_pre_render_request_remove_unassociated): + (_ewk_tiled_backing_store_pre_render_request_remove_associated): + (_ewk_tiled_backing_store_pre_render_request_process_single): + (_ewk_tiled_backing_store_item_process_idler_cb): + (_ewk_tiled_backing_store_item_process_idler_stop): + (_ewk_tiled_backing_store_item_process_idler_start): + (_ewk_tiled_backing_store_item_request_del): + (_ewk_tiled_backing_store_item_request_add): + (_ewk_tiled_backing_store_disable_render): + (_ewk_tiled_backing_store_enable_render): + (_ewk_tiled_backing_store_visible_tiles_rect): + (_ewk_tiled_backing_store_tile_is_inside_viewport): + (_ewk_tiled_backing_store_tile_is_adjacent_to_viewport): + (_ewk_tiled_backing_store_item_fill): + (_ewk_tiled_backing_store_item_add): + (_ewk_tiled_backing_store_item_del): + (_ewk_tiled_backing_store_item_smooth_scale_set): + (_ewk_tiled_backing_store_changed): + (_ewk_tiled_backing_store_view_cols_end_del): + (_ewk_tiled_backing_store_view_cols_end_add): + (_ewk_tiled_backing_store_view_row_del): + (_ewk_tiled_backing_store_view_rows_range_del): + (_ewk_tiled_backing_store_view_rows_all_del): + (_ewk_tiled_backing_store_render): + (_ewk_tiled_backing_store_model_matrix_create): + (_ewk_tiled_backing_store_smart_member_del): + (_ewk_tiled_backing_store_smart_member_add): + (_ewk_tiled_backing_store_mem_dbg): + (_ewk_tiled_backing_store_sig_usr): + (_ewk_tiled_backing_store_smart_add): + (_ewk_tiled_backing_store_smart_del): + (_ewk_tiled_backing_store_smart_move): + (_ewk_tiled_backing_store_smart_resize): + (_ewk_tiled_backing_store_recalc_renderers): + (_ewk_tiled_backing_store_smart_calculate_size): + (_ewk_tiled_backing_store_view_dbg): + (_ewk_tiled_backing_store_view_wrap_up): + (_ewk_tiled_backing_store_view_wrap_down): + (_ewk_tiled_backing_store_view_wrap_left): + (_ewk_tiled_backing_store_view_wrap_right): + (_ewk_tiled_backing_store_view_refill): + (_ewk_tiled_backing_store_view_pos_apply): + (_ewk_tiled_backing_store_smart_calculate_offset_force): + (_ewk_tiled_backing_store_smart_calculate_offset): + (_ewk_tiled_backing_store_smart_calculate_pos): + (_ewk_tiled_backing_store_fill_renderers): + (_ewk_tiled_backing_store_smart_calculate): + (ewk_tiled_backing_store_add): + (ewk_tiled_backing_store_render_cb_set): + (ewk_tiled_backing_store_tile_unused_cache_get): + (ewk_tiled_backing_store_tile_unused_cache_set): + (_ewk_tiled_backing_store_scroll_full_offset_set_internal): + (ewk_tiled_backing_store_scroll_full_offset_set): + (ewk_tiled_backing_store_scroll_full_offset_add): + (_ewk_tiled_backing_store_zoom_set_internal): + (ewk_tiled_backing_store_zoom_set): + (ewk_tiled_backing_store_zoom_weak_set): + (ewk_tiled_backing_store_fix_offsets): + (ewk_tiled_backing_store_zoom_weak_smooth_scale_set): + (ewk_tiled_backing_store_update): + (ewk_tiled_backing_store_updates_process_pre_set): + (ewk_tiled_backing_store_updates_process_post_set): + (ewk_tiled_backing_store_updates_process): + (ewk_tiled_backing_store_updates_clear): + (ewk_tiled_backing_store_contents_resize): + (ewk_tiled_backing_store_disabled_update_set): + (ewk_tiled_backing_store_flush): + (ewk_tiled_backing_store_pre_render_region): + (ewk_tiled_backing_store_pre_render_relative_radius): + (ewk_tiled_backing_store_pre_render_cancel): + (ewk_tiled_backing_store_disable_render): + (ewk_tiled_backing_store_enable_render): + (ewk_tiled_backing_store_process_entire_queue_set): + * ewk/ewk_tiled_backing_store.h: Added. + * ewk/ewk_tiled_matrix.c: Added. + (_ewk_tile_matrix_cell_free): + (_ewk_tile_matrix_tile_free): + (ewk_tile_matrix_new): + (ewk_tile_matrix_free): + (ewk_tile_matrix_resize): + (ewk_tile_matrix_unused_cache_get): + (ewk_tile_matrix_tile_exact_get): + (ewk_tile_matrix_tile_exact_exists): + (ewk_tile_matrix_tile_nearest_get): + (ewk_tile_matrix_tile_new): + (ewk_tile_matrix_tile_put): + (ewk_tile_matrix_tile_update): + (ewk_tile_matrix_tile_update_full): + (ewk_tile_matrix_tile_updates_clear): + (_ewk_tile_matrix_slicer_setup): + (ewk_tile_matrix_update): + (ewk_tile_matrix_updates_process): + (ewk_tile_matrix_updates_clear): + (ewk_tile_matrix_dbg): + (ewk_tile_matrix_freeze): + (ewk_tile_matrix_thaw): + * ewk/ewk_tiled_matrix.h: Added. + * ewk/ewk_tiled_model.c: Added. + (_ewk_tile_account_get): + (_ewk_tile_account_allocated): + (_ewk_tile_account_freed): + (ewk_tile_accounting_dbg): + (_ewk_tile_paint_rgb888): + (_ewk_tile_paint_rgb565): + (_ewk_tile_paint): + (ewk_tile_new): + (ewk_tile_free): + (ewk_tile_show): + (ewk_tile_hide): + (ewk_tile_visible_get): + (ewk_tile_update_full): + (ewk_tile_update_area): + (ewk_tile_updates_process): + (ewk_tile_updates_clear): + (ewk_tile_unused_cache_new): + (ewk_tile_unused_cache_lock_area): + (ewk_tile_unused_cache_unlock_area): + (ewk_tile_unused_cache_free): + (ewk_tile_unused_cache_clear): + (ewk_tile_unused_cache_ref): + (ewk_tile_unused_cache_unref): + (ewk_tile_unused_cache_max_set): + (ewk_tile_unused_cache_max_get): + (ewk_tile_unused_cache_used_get): + (ewk_tile_unused_cache_flush): + (ewk_tile_unused_cache_auto_flush): + (ewk_tile_unused_cache_dirty): + (ewk_tile_unused_cache_freeze): + (ewk_tile_unused_cache_thaw): + (ewk_tile_unused_cache_tile_get): + (ewk_tile_unused_cache_tile_put): + (ewk_tile_unused_cache_dbg): + * ewk/ewk_tiled_model.h: Added. + * ewk/ewk_tiled_private.h: Added. + * ewk/ewk_view.cpp: + (_ewk_view_smart_add): + (_ewk_view_smart_calculate): + (_ewk_view_smart_show): + (_ewk_view_smart_hide): + (_ewk_view_smart_pre_render_relative_radius): + (_ewk_view_zoom_animator_cb): + (_ewk_view_smart_disable_render): + (_ewk_view_smart_enable_render): + (ewk_view_base_smart_set): + (ewk_view_pre_render_region): + (ewk_view_pre_render_relative_radius): + (ewk_view_enable_render): + (ewk_view_disable_render): + (ewk_view_scroll): + (ewk_view_did_first_visually_nonempty_layout): + (ewk_view_dispatch_did_finish_loading): + (ewk_view_transition_to_commited_for_newpage): + * ewk/ewk_view.h: + * ewk/ewk_view_tiled.c: Added. + (_ewk_view_tiled_render_cb): + (_ewk_view_tiled_updates_process_pre): + (_ewk_view_tiled_smart_backing_store_add): + (_ewk_view_tiled_contents_size_changed_cb): + (_ewk_view_tiled_smart_add): + (_ewk_view_tiled_smart_scrolls_process): + (_ewk_view_tiled_smart_repaints_process): + (_ewk_view_tiled_smart_contents_resize): + (_ewk_view_tiled_smart_zoom_set): + (_ewk_view_tiled_smart_zoom_weak_set): + (_ewk_view_tiled_smart_zoom_weak_smooth_scale_set): + (_ewk_view_tiled_smart_flush): + (_ewk_view_tiled_smart_pre_render_region): + (_ewk_view_tiled_smart_pre_render_relative_radius): + (_ewk_view_tiled_smart_pre_render_cancel): + (_ewk_view_tiled_smart_disable_render): + (_ewk_view_tiled_smart_enable_render): + (ewk_view_tiled_smart_set): + (_ewk_view_tiled_smart_class_new): + (ewk_view_tiled_add): + (ewk_view_tiled_unused_cache_get): + (ewk_view_tiled_unused_cache_set): + (ewk_view_tiled_process_entire_queue_set): + +2010-11-16 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed. Build fix. + + * WebCoreSupport/FrameLoaderClientEfl.h: Also include + ResourceError.h. + +2010-11-16 Patrick Gansterer <paroga@webkit.org> + + Reviewed by Andreas Kling. + + [CMake] Add platform dependent include directories + https://bugs.webkit.org/show_bug.cgi?id=49553 + + * CMakeListsEfl.txt: + +2010-11-14 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Martin Robinson. + + [EFL] add pango support + https://bugs.webkit.org/show_bug.cgi?id=46029 + + Add pango in include and libs. + + * CMakeListsEfl.txt: + +2010-11-11 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Adam Barth. + + [GTK] Move font related files. + https://bugs.webkit.org/show_bug.cgi?id=48116 + + Add freetype/ to include path. + + * CMakeListsEfl.txt: + +2010-11-08 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Change the usage of eina_iterator_next due to latest EFL changes. + https://bugs.webkit.org/show_bug.cgi?id=49082 + + A change on how the iterator for a tiler is used in EFL needs to be + reflected in WebKit-EFL. The iterator now receives a pointer to an + Eina_Rectangle and makes it point to its internal structure. The old + usage was to receive a reference to a pre-allocated Eina_Rectangle. + + * ewk/ewk_view_single.c: + (_ewk_view_single_smart_repaints_process): + +2010-11-08 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48685 + Notify UI process about focused frame + + Added an empty implementation of the new ChromeClient method. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::focusedFrameChanged): + * WebCoreSupport/ChromeClientEfl.h: + +2010-11-05 Patrick Gansterer <paroga@webkit.org> + + Reviewed by David Kilzer. + + Replace ARRAYSIZE with WTF_ARRAY_LENGTH + https://bugs.webkit.org/show_bug.cgi?id=48903 + + * WebCoreSupport/EditorClientEfl.cpp: + (WebCore::EditorClientEfl::interpretKeyEvent): + +2010-11-04 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Adam Barth. + + [EFL] Reflect latest EFL changes related to stride. + https://bugs.webkit.org/show_bug.cgi?id=48971 + + Remove adjustment code to compare stride of cairo_image_surfece and evas_object_image, as following changes of latest EFL. + + * ewk/ewk_util.cpp: + (ewk_util_image_from_cairo_surface_add): + +2010-11-03 Daniel Bates <dbates@rim.com> + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Part 1 of 2. + + Substitute FrameTree::uniqueName() for FrameTree::name() in the EFL port. + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + +2010-11-02 Daniel Bates <dbates@rim.com> + + Reviewed by Martin Robinson. + + Set frame name before appending it to the frame tree in the Apple Windows, + GTK, and EFL ports + https://bugs.webkit.org/show_bug.cgi?id=48806 + + Make the frame creation process in the EFL-port consistent with the + Mac, Qt, and Haiku ports. In particular, set the name of the new + frame before it's appended to the frame tree. + + At this time we cannot test this change since it is being masked by + HTMLFrameElementBase::setName() <http://trac.webkit.org/browser/trunk/WebCore/html/HTMLFrameElementBase.cpp?rev=70976#L160>. + We'll be able to test this once we fix bug #6751. + + * ewk/ewk_frame.cpp: + (ewk_frame_child_add): + +2010-11-01 Brady Eidson <beidson@apple.com> + + Reviewed by Anders Carlsson. + + <rdar://problem/7660547> and https://bugs.webkit.org/show_bug.cgi?id=48699 + Context menu support for WebKit 2. + + * WebCoreSupport/ChromeClientEfl.h: + (WebCore::ChromeClientEfl::showContextMenu): + +2010-10-29 Daniel Bates <dbates@rim.com> + + No review, rolling out 70971. + http://trac.webkit.org/changeset/70971 + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Rolling out changeset 70971 <http://trac.webkit.org/changeset/70971> since + it caused layout test failures on all bots. In particular, the + child count in a generated frame name differs after this patch. We need + to look into this further. + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + +2010-10-29 Daniel Bates <dbates@rim.com> + + Reviewed by Adam Barth. + + For unnamed frames, window.name returns a generated name + https://bugs.webkit.org/show_bug.cgi?id=6751 + + Modified EFL-port to use FrameTree::uniqueName(). + + * ewk/ewk_frame.cpp: + (ewk_frame_name_get): + +2010-10-29 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Change BackForwardList clients to use BackForwardListImpl to prepare for further refactoring + https://bugs.webkit.org/show_bug.cgi?id=48574 + + * ewk/ewk_history.cpp: + (ewk_history_new): + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (ewk_view_history_enable_get): + (ewk_view_history_enable_set): + (ewk_view_history_get): + Use BackForwardListImpl. + +2010-10-29 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=48576 + Let WebKit2 client know when a frame is a frameset + + Added a blank implementation of the new FrameLoaderClient method. + + * WebCoreSupport/FrameLoaderClientEfl.h: + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::dispatchDidBecomeFrameset): + +2010-10-26 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Dmitry Titov. + + Resource tracking failure when trying to move a frame between documents + https://bugs.webkit.org/show_bug.cgi?id=44713 + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::transferLoadingResourceFromPage): + Empty method. + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-10-22 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + WebKit2 needs to pass the current event modifier flags when requesting a new window + https://bugs.webkit.org/show_bug.cgi?id=48140 + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::createWindow): + * WebCoreSupport/ChromeClientEfl.h: + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::dispatchCreatePage): + * WebCoreSupport/FrameLoaderClientEfl.h: + Add NavigationAction parameter. + +2010-10-19 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Eric Seidel. + + [EFL] Add setting api for disabling auto resize window + https://bugs.webkit.org/show_bug.cgi?id=47787 + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::setWindowRect): Return when + auto_resize_window was disabled. + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (ewk_view_setting_enable_auto_resize_window_get): Added. + (ewk_view_setting_enable_auto_resize_window_set): Added. + * ewk/ewk_view.h: + +2010-10-15 Nikolas Zimmermann <nzimmermann@rim.com> + + Reviewed by Dirk Schulze. + + Replace some String::format() usages by StringConcatenate in WebKit + https://bugs.webkit.org/show_bug.cgi?id=47714 + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::agentOS): + +2010-10-14 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Eric Seidel. + + [EFL] Use data_set after data_get to keep refcount correct. + https://bugs.webkit.org/show_bug.cgi?id=47110 + + The call to evas_object_image_data_set was missed in this function, + which caused the refcount of the data being always increased on every + scroll. + + * ewk/ewk_view_single.c: + (_ewk_view_single_smart_scrolls_process): + +2010-10-14 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Eric Seidel. + + [EFL] Add setting api for enabling encoding detector + https://bugs.webkit.org/show_bug.cgi?id=45427 + + Add settings api for enabling encoding detector. + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (ewk_view_setting_encoding_detector_set): + (ewk_view_setting_encoding_detector_get): + * ewk/ewk_view.h: + +2010-10-13 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed. Build fix. + + * WebCoreSupport/FrameLoaderClientEfl.h: Use String instead of + WebCore::String. + +2010-10-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=43987 + Switch XMLHttpRequest, FileReader, and FileReaderSync to use a Stringbuilder + to construct their internal result string. Remove ScriptString (this is now + redundant). + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::dispatchDidLoadResourceByXMLHttpRequest): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-10-13 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Support viewport configuration and add new arguments for WebKit EFL + https://bugs.webkit.org/show_bug.cgi?id=47084 + + Opera spec regarding to viewport meta tag was adjusted to WebCore. So, EFL port + needs to be modified according to the changes. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::dispatchViewportDataDidChange): + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::dispatchDidCommitLoad): + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (_ewk_view_viewport_attributes_compute): + (ewk_view_viewport_attributes_set): + (ewk_view_viewport_attributes_get): + (ewk_view_device_pixel_ratio_get): + * ewk/ewk_view.h: + +2010-10-12 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Add a method to get target's dpi value + https://bugs.webkit.org/show_bug.cgi?id=47537 + + Add a method to get target dpi value using Ecore_X. + When we set layout size, we need to use the dpi value. + + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (ewk_view_page_rect_get): + (ewk_view_dpi_get): + +2010-10-07 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Implement pageRect() function + https://bugs.webkit.org/show_bug.cgi?id=47395 + + Implement pageRect() in ChromeClientEfl using frameRect(). + + * CMakeListsEfl.txt: + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::pageRect): + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (ewk_view_page_rect_get): Added. + +2010-10-06 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Support Progress Tag + https://bugs.webkit.org/show_bug.cgi?id=45951 + + Implement progressbar.edc to support progress tag + + * CMakeListsEfl.txt: + * DefaultTheme/default.edc: + * DefaultTheme/widget/progressbar: Added. + * DefaultTheme/widget/progressbar/bt_base.png: Added. + * DefaultTheme/widget/progressbar/progressbar.edc: Added. + * DefaultTheme/widget/progressbar/shelf_inset.png: Added. + +2010-10-05 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Remove strdup in ewk_setting.cpp using eina_stringshare + https://bugs.webkit.org/show_bug.cgi?id=46613 + + Add variables shared by eina_stringshare and remove strdup. + + * ewk/ewk_main.cpp: + (_ewk_init_body): + * ewk/ewk_settings.cpp: + (ewk_settings_web_database_path_set): + (ewk_settings_web_database_path_get): + (ewk_settings_icon_database_path_set): + (ewk_settings_icon_database_path_get): + * ewk/ewk_settings.h: + +2010-10-04 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Viewport data change notification by Bug 46755 + https://bugs.webkit.org/show_bug.cgi?id=46772 + + Bug 46755 changes virtual function regarding to viewport metatag. Thus, EFL port + should change the function as well in order to get viewport arguments. + + And, setInitLayoutCompleted / getInitLayoutCompleted() are removed because these functions + aren't needed anymore. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::dispatchViewportDataDidChange): + * WebCoreSupport/ChromeClientEfl.h: + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::FrameLoaderClientEfl): + (WebCore::FrameLoaderClientEfl::dispatchDidCommitLoad): + (WebCore::FrameLoaderClientEfl::dispatchDidFirstLayout): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-10-01 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Remove check for InitLayoutCompleted on fixed_layout_size_set. + https://bugs.webkit.org/show_bug.cgi?id=47006 + + This check isn't needed and isn't done on the other ports. The fixed + layout property can be set before we have the first layout. + + * ewk/ewk_view.cpp: + (ewk_view_fixed_layout_size_set): + +2010-10-01 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Call contents_resize when the main frame gets resized. + https://bugs.webkit.org/show_bug.cgi?id=47004 + + The previous implementation was just calling contents_resize when the + viewport size had changed. That's not enough, and contents_resize + shouldn't be called if the contents size didn't change. + + Now the contents_size_changed function is called directly from the + ChromeClientEfl. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::contentsSizeChanged): + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (_ewk_view_smart_calculate): + (ewk_view_fixed_layout_size_set): + (ewk_view_contents_size_changed): + +2010-09-29 João Paulo Rechi Vita <jprvita@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] General small fixes. + https://bugs.webkit.org/show_bug.cgi?id=46813 + + This commit spots a comparison between signed and unsigned integer + expressions, a missing return and a never-called function. + + * WebCoreSupport/FullscreenVideoControllerEfl.cpp: + (FullscreenVideoController::canPlay): + +2010-09-28 Jenn Braithwaite <jennb@chromium.org> + + Reviewed by Dmitry Titov. + + Added oldPage param to FrameLoaderClient::didTransferChildFrameToNewDocument. + https://bugs.webkit.org/show_bug.cgi?id=46663 + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::didTransferChildFrameToNewDocument): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-09-26 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Add setting API to set a local storage database path. + https://bugs.webkit.org/show_bug.cgi?id=45446 + + Add a setting API to set local storage database path. + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (_ewk_view_priv_del): + (ewk_view_setting_local_storage_database_path_get): Added. + (ewk_view_setting_local_storage_database_path_set): Added. + * ewk/ewk_view.h: + +2010-09-23 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Csaba Osztrogonác. + + [EFL] Fix warnings during build + https://bugs.webkit.org/show_bug.cgi?id=46354 + + * ewk/ewk_frame.cpp: + (ewk_frame_text_matches_nth_pos_get): Change argument type because + it's meant to be always positive. + * ewk/ewk_frame.h: Ditto. + * ewk/ewk_view.cpp: + (ewk_view_exceeded_database_quota): Add missing "%" causing warning about number of + arguments to printf-like function. + * ewk/ewk_view.h: Add missing initialization. + +2010-09-21 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Get fresh theme when running EWebLauncher + https://bugs.webkit.org/show_bug.cgi?id=46210 + + If user tried to run EWebLauncher outside of the build tree, it would + not find the theme and fallback to the installed one. However, since + EWebLauncher is not installed, we always want to take the theme from + the just compiled source code. If user had never installed WebKit's + EFL port it could even receive a segv since no theme would be found. + + Now EWebLauncher does not fallback to the installed theme and CMake + gives as DATA_DIR the directory of the theme it has just built. + + + * CMakeListsEfl.txt: export DATA_DIR to parent CMakeLists.txt in order + to be used by EWebLauncher. + +2010-09-17 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + REGRESSION (r60104): Zoom level is unexpectedly reset on page reload + https://bugs.webkit.org/show_bug.cgi?id=42863 + + * ewk/ewk_frame.cpp: + (ewk_frame_zoom_get): + (ewk_frame_zoom_set): + (ewk_frame_zoom_text_only_set): + Call functions on Frame instead of FrameView. + +2010-09-16 Darin Adler <darin@apple.com> + + Fix build. + + * ewk/ewk_view.cpp: + (ewk_view_input_method_state_set): Updated for change + in name of isUrlField to isURLField. + +2010-09-14 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] ewk_frame_view_create_for_view set null as theme. + https://bugs.webkit.org/show_bug.cgi?id=45741 + + Add theme in ewk_view to use instead of frame's theme which is null in + ewk_frame_view_create_for_view. + + * ewk/ewk_frame.cpp: + (ewk_frame_view_create_for_view): + * ewk/ewk_view.cpp: + (ewk_view_theme_set): + (ewk_view_theme_get): + +2010-09-14 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed build fix: remove "virtual" keyword from + implementation file. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::canShowMIMETypeAsHTML): + +2010-09-13 Rafael Antognolli <antognolli@profusion.mobi> + + Unreviewed build fix. + + [EFL] Fix build break when enabling HTML5 video support + https://bugs.webkit.org/show_bug.cgi?id=45674 + + The correct include variable for LibXml2 in cmake is + LIBXML2_INCLUDE_DIR instead of LIBXML2_INCLUDE_DIRS. + + * CMakeListsEfl.txt: + +2010-09-13 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Add setting API for enabling page cache + https://bugs.webkit.org/show_bug.cgi?id=44931 + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (ewk_view_setting_page_cache_get): Added. + (ewk_view_setting_page_cache_set): Added. + * ewk/ewk_view.h: + +2010-09-13 Enrica Casucci <enrica@apple.com> + + Reviewed by Sam Weinig. + + Paste should be implemented in WebCore like Copy and Cut for Mac also. + https://bugs.webkit.org/show_bug.cgi?id=45494 + <rdar://problem/7660537> + + On the Mac platform, the implementation of the paste operation is all done + at the WebKit level. In order to support it on WebKit2 it is necessary to + refactor the code and move this functionality at the level of WebCore like + we already have on Windows. + The original code relies on some in AppKit functions that call back into + WebKit causing problems in WebKit2. All this functionality has been moved + at the level of the editor client where it can be dealt with appropriately. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::canShowMIMETypeAsHTML): Added stub. + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-09-11 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Fix EFL build after r67274 + https://bugs.webkit.org/show_bug.cgi?id=45584 + + Remove include of ZoomMode.h and change setZoomFactor and zoomFactor + to proper apis chaged by r67264. + + * ewk/ewk_frame.cpp: + (ewk_frame_zoom_get): + (ewk_frame_zoom_set): + (ewk_frame_zoom_text_only_get): + (ewk_frame_zoom_text_only_set): + +2010-09-10 Adam Barth <abarth@webkit.org> + + Reviewed by Darin Fisher. + + Move code from WebKit-layer to DocumentLoader + https://bugs.webkit.org/show_bug.cgi?id=45569 + + This code didn't know that setEncoding could be called multiple times + safely. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::FrameLoaderClientEfl): + (WebCore::FrameLoaderClientEfl::committedLoad): + (WebCore::FrameLoaderClientEfl::dispatchDidReceiveResponse): + (WebCore::FrameLoaderClientEfl::finishedLoading): + (WebCore::FrameLoaderClientEfl::dispatchDidFailLoading): + (WebCore::FrameLoaderClientEfl::setMainDocumentError): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-09-10 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Main resource bytes shouldn't bounce through FrameLoader + https://bugs.webkit.org/show_bug.cgi?id=45496 + + Now return the bytes to the DocumentLoader. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::committedLoad): + +2010-09-08 Darin Adler <darin@apple.com> + + Reviewed by Adam Barth. + + Move functions from Frame to Editor as planned + https://bugs.webkit.org/show_bug.cgi?id=45218 + + * ewk/ewk_frame.cpp: + (ewk_frame_editable_set): + (ewk_frame_selection_get): + (ewk_frame_text_search): + (ewk_frame_text_matches_mark): + (ewk_frame_text_matches_highlight_set): + (ewk_frame_text_matches_highlight_get): + * ewk/ewk_view.cpp: + (ewk_view_selection_get): + Changed call sites to use editor(). + +2010-09-09 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed build fix. + + [EFL] Fix duplicate gstreamer macro in CMakeListEfl.txt + https://bugs.webkit.org/show_bug.cgi?id=45433 + + In WebKit/efl/CMakeListEfl.txt, duplicated ENABLE_VIDEO macros were added. + So, unnecessary ENABLE_VIDEO macro is deleted. + + * CMakeListsEfl.txt: + +2010-09-08 Ryuan Choi <ryuan.choi@samsung.com> + + Unreviewed build fix. + + [EFL] Need to add custom dependencies. + https://bugs.webkit.org/show_bug.cgi?id=45247 + + Add WebKit_Theme into WebKit_SOURCES to make it while building. + + * CMakeListsEfl.txt: + +2010-09-08 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Export data directory through pkg-config + https://bugs.webkit.org/show_bug.cgi?id=45385 + + Using pkg-config it's possible for a browser to know the location of + installed themes. When compiling the browser, a variable might be + defined with the datadir, like below: + + gcc -o browser browser.c $(pkg-config --libs --cflags ewebkit) \ + -DEWEBKIT_DATA_DIR=$(pkg-config --variable=datadir) + + * ewebkit.pc.in: Export datadir variable. + +2010-09-06 Ryuan Choi <ryuan.choi@samsung.com> + + Unreviewed build fix. + + [EFL] REGRESSION(66794) Need to fix build break. + https://bugs.webkit.org/show_bug.cgi?id=45241 + + Add dummy class(FrameNetworkingContextEfl) like GTK+ port and implement + as EFL style. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::createNetworkingContext): + * WebCoreSupport/FrameNetworkingContextEfl.h: Added. + (WebCore::FrameNetworkingContextEfl::create): + (WebCore::FrameNetworkingContextEfl::coreFrame): + (WebCore::FrameNetworkingContextEfl::FrameNetworkingContextEfl): + +2010-09-04 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Move test browser to WebKitTools directory + https://bugs.webkit.org/show_bug.cgi?id=45212 + + Follow other ports like QT and GTK which moved the test browser to + WebKitTools directory. + + * CMakeListsEfl.txt: Remove build for test browser. + * EWebLauncher/main.c: Removed. + +2010-09-03 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org> + + Reviewed by Darin Adler. + + Add NetworkingContext to avoid layer violations + https://bugs.webkit.org/show_bug.cgi?id=42292 + + Add createNetworkingContext to EFL's FrameLoaderClient. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::createNetworkingContext): + * WebCoreSupport/FrameLoaderClientEfl.h: + +2010-09-03 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Martin Robinson. + + [EFL] Regression (66531) Build break with Glib Support + https://bugs.webkit.org/show_bug.cgi?id=45011 + + Move GtkTypedefs.h to GTypedefs.h and let it inside gobject directory + since when glib is enabled, EFL port needs it, too. + + * CMakeListsEfl.txt: Include gobject directory to find new header + file. + +2010-09-03 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Install default theme + https://bugs.webkit.org/show_bug.cgi?id=45154 + + Since a theme is needed in order to create a new browser, install the + default one to serve as example and fall-back. + + * CMakeListsEfl.txt: + +2010-09-02 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Name install directories according to library name + https://bugs.webkit.org/show_bug.cgi?id=45126 + + * CMakeListsEfl.txt: include diretory follows library name. + * ewebkit.pc.in: Ditto. + +2010-08-31 Dave Hyatt <hyatt@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=44863, disentangle style recalc from layout, so that + the former can occur in more places without having to do the latter. + + * ewk/ewk_view.cpp: + (ewk_view_layout_if_needed_recursive): + +2010-08-31 Sam Weinig <sam@webkit.org> + + Reviewed by Darin Adler. + + Add ability to count text matches without marking + https://bugs.webkit.org/show_bug.cgi?id=43996 + + * ewk/ewk_frame.cpp: + (ewk_frame_text_matches_mark): Switched to call + countMatchesForText() instead of markAllMatchesForText(). + +2010-08-31 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Unreviewed build fix. + + [EFL] Build break for r66456 + https://bugs.webkit.org/post_bug.cgi + + Replace firstRectsForMarkers with renderedRectsForMarkers. + + * ewk/ewk_frame.cpp: + (ewk_frame_text_matches_nth_pos_get): + +2010-08-30 Kamil Blank <k.blank@samsung.com> + + Reviewed by Adam Barth. + + [EFL] Added API which returns position of n-th text matches mark + https://bugs.webkit.org/show_bug.cgi?id=44258 + + * ewk/ewk_frame.cpp: + (_ewk_frame_rect_cmp_less_than): Private. + (_ewk_frame_rect_is_negative_value): Private. + (ewk_frame_text_matches_nth_pos_get): Added. Function returns position of + n-th text match in frame. + * ewk/ewk_frame.h: + +2010-08-30 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Adam Barth. + + [EFL]Url of HistoryItem was broken for special character like korean + https://bugs.webkit.org/show_bug.cgi?id=44495 + + Remove unnecessary code. This makes a bug with complicated URL. + + * ewk/ewk_frame.cpp: + (ewk_frame_view_state_save): + +2010-08-30 Mikołaj Małecki <m.malecki@samsung.com> + + Reviewed by Kenneth Rohde Christiansen + + [EFL] Added initial setting to turn on offline pages. + https://bugs.webkit.org/show_bug.cgi?id=44239 + + * ewk/ewk_main.cpp: Torn off non-EFL init to _ewk_init_body + (ewk_init): Changed non-EFL init to call _ewk_init_body + (_ewk_init_body): Moved internal init here and added cache directory path setting. + * ewk/ewk_view.cpp: Added new config items: offline_app_cache and cache_directory + (_ewk_view_priv_new): creating cache_directory string + (_ewk_view_priv_del): deleting cache_directory string + (ewk_view_setting_offline_app_cache_get): + (ewk_view_setting_offline_app_cache_set): + (ewk_view_setting_cache_directory_get): + (ewk_view_setting_cache_directory_set): + * ewk/ewk_view.h: added offline_app_cache and cache_directory props to ewk API + +2010-08-26 Miroslaw Szymanski <miroslaw.s@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Added new callback when view's size is changed to fix issue with changing layout size + https://bugs.webkit.org/show_bug.cgi?id=44337 + + * ewk/ewk_view.cpp: + (_ewk_view_smart_calculate): + +2010-08-25 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Add dummy FullScreenVideoControllerEfl to WebKit EFL + https://bugs.webkit.org/show_bug.cgi?id=44590 + + Add FullScreenVideoControllerEfl to WebCoreSupport. However, + this is not implemented yet. + + * CMakeListsEfl.txt: + * WebCoreSupport/FullscreenVideoControllerEfl.cpp: Added. + (FullscreenVideoController::FullscreenVideoController): + (FullscreenVideoController::~FullscreenVideoController): + (FullscreenVideoController::setMediaElement): + (FullscreenVideoController::showHud): + (FullscreenVideoController::hideHud): + (FullscreenVideoController::enterFullscreen): + (FullscreenVideoController::updateHudPosition): + (FullscreenVideoController::exitOnUserRequest): + (FullscreenVideoController::exitFullscreen): + (FullscreenVideoController::canPlay): + (FullscreenVideoController::play): + (FullscreenVideoController::pause): + (FullscreenVideoController::playStateChanged): + (FullscreenVideoController::togglePlay): + (FullscreenVideoController::volume): + (FullscreenVideoController::muted): + (FullscreenVideoController::setVolume): + (FullscreenVideoController::volumeChanged): + (FullscreenVideoController::muteChanged): + (FullscreenVideoController::currentTime): + (FullscreenVideoController::setCurrentTime): + (FullscreenVideoController::duration): + (FullscreenVideoController::percentLoaded): + (FullscreenVideoController::beginSeek): + (FullscreenVideoController::doSeek): + (FullscreenVideoController::endSeek): + (timeToString): + (FullscreenVideoController::updateHudProgressBar): + (FullscreenVideoController::createHud): + * WebCoreSupport/FullscreenVideoControllerEfl.h: Added. + (FullscreenVideoController::mediaElement): + +2010-08-25 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Add setting API for enabling local storage. + https://bugs.webkit.org/show_bug.cgi?id=44319 + + Add API for enabling/disabling local storage. + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + (ewk_view_setting_local_storage_get): Added + (ewk_view_setting_local_storage_set): Added + * ewk/ewk_view.h: + +2010-08-25 Jaehun Lim <ljaehun.lim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] enable libsoup's content decode feature + https://bugs.webkit.org/show_bug.cgi?id=44147 + + libsoup's content decode feature is enabled during initializaton. + + * ewk/ewk_main.cpp: + (ewk_init): + +2010-08-25 Rafael Antognolli <antognolli@profusion.mobi> + + Unreviewed build fix. + + [EFL] Build fix for revision 65332 + https://bugs.webkit.org/show_bug.cgi?id=44543 + + Use Gthread_LIBRARIES instead of GTHREAD_LIBRARIES. This fix + the build when using ENABLE_GLIB_SUPPORT=ON and NETWORK_BACKEND=curl. + + * CMakeListsEfl.txt: + +2010-08-24 Lukasz Slachciak <l.slachciak@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Extended EFL WebView API to allow enable/disable Frame Flattening + https://bugs.webkit.org/show_bug.cgi?id=44253 + + * ewk/ewk_view.cpp: + (ewk_view_setting_enable_frame_flattening_get): + (ewk_view_setting_enable_frame_flattening_set): + * ewk/ewk_view.h: + +2010-08-23 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Build fix for platforms that do not require linking with "dl". + CMake includes the variable CMAKE_DL_LIBS that evaluates to the + platform-specific libraries. + + * CMakeListsEfl.txt: Use ${CMAKE_DL_LIBS} instead of dl. + +2010-08-22 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Remove duplicated include entry from default theme. + https://bugs.webkit.org/show_bug.cgi?id=44345 + + This used to create the group webkit/widget/entry twice in + the theme. It's leading to a bug with the newer versions of + EFL. + + * DefaultTheme/default.edc: + +2010-08-22 Daniel Bates <dbates@rim.com> + + Reviewed by Eric Seidel. + + Encapsulate document marker management into DocumentMarkerController + https://bugs.webkit.org/show_bug.cgi?id=44383 + + Modify call sites in the EFL port to use DocumentMarkerController. + + No functionality was changed, so no new tests. + + * ewk/ewk_frame.cpp: + (ewk_frame_text_matches_unmark_all): + +2010-08-20 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Unreviewed. Fix build when using GNU gold. + When linking with GNU gold, some symbols are not found: explicitly + link with the required libraries. + + * CMakeListsEfl.txt: Depend on Fontconfig, PNG, JPEG and dl + libraries. + +2010-08-15 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Antonio Gomes. + + [EFL] Enable localStorage of HTML5 for WebKit EFL + https://bugs.webkit.org/show_bug.cgi?id=44020 + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2010-08-11 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Adding new theme for widgets. + https://bugs.webkit.org/show_bug.cgi?id=43860 + + Original theme was there for a long time. This is a new + fresh one. + + * DefaultTheme/default.edc: + * DefaultTheme/widget/button/button.edc: + * DefaultTheme/widget/button/img_button_focus.png: + * DefaultTheme/widget/button/img_button_hover.png: + * DefaultTheme/widget/button/img_button_normal.png: + * DefaultTheme/widget/button/img_button_press.png: + * DefaultTheme/widget/check/check.edc: + * DefaultTheme/widget/check/img_check_off.png: + * DefaultTheme/widget/check/img_check_off_focus.png: + * DefaultTheme/widget/check/img_check_off_hover.png: + * DefaultTheme/widget/check/img_check_on.png: + * DefaultTheme/widget/check/img_check_on_focus.png: + * DefaultTheme/widget/check/img_check_on_hover.png: + * DefaultTheme/widget/combo/combo.edc: + * DefaultTheme/widget/combo/combo_focus.png: + * DefaultTheme/widget/combo/combo_focus_button.png: + * DefaultTheme/widget/combo/combo_hover.png: + * DefaultTheme/widget/combo/combo_hover_button.png: + * DefaultTheme/widget/combo/combo_normal.png: + * DefaultTheme/widget/combo/combo_normal_button.png: + * DefaultTheme/widget/combo/combo_press.png: + * DefaultTheme/widget/combo/combo_press_button.png: + * DefaultTheme/widget/combo/icon.png: + * DefaultTheme/widget/entry/img_focused.png: + * DefaultTheme/widget/entry/img_hovered.png: + * DefaultTheme/widget/entry/img_normal.png: + * DefaultTheme/widget/file/file_focus.png: + * DefaultTheme/widget/file/file_hover.png: + * DefaultTheme/widget/file/file_normal.png: + * DefaultTheme/widget/file/file_press.png: + * DefaultTheme/widget/radio/img_radio_off.png: + * DefaultTheme/widget/radio/img_radio_off_focus.png: + * DefaultTheme/widget/radio/img_radio_off_hover.png: + * DefaultTheme/widget/radio/img_radio_on.png: + * DefaultTheme/widget/radio/img_radio_on_focus.png: + * DefaultTheme/widget/radio/img_radio_on_hover.png: + * DefaultTheme/widget/radio/radio.edc: + * DefaultTheme/widget/scrollbar/scrollbar.edc: + * DefaultTheme/widget/scrollbar/scrollbar_h.png: + * DefaultTheme/widget/scrollbar/scrollbar_hilight.png: Removed. + * DefaultTheme/widget/scrollbar/scrollbar_knob_h.png: + * DefaultTheme/widget/scrollbar/scrollbar_knob_v.png: + * DefaultTheme/widget/scrollbar/scrollbar_v.png: + * DefaultTheme/widget/search/cancel/cancel_normal_button2.png: + * DefaultTheme/widget/search/decoration/decoration_normal_button.png: + * DefaultTheme/widget/search/field/field_focused.png: + * DefaultTheme/widget/search/field/field_hovered.png: + * DefaultTheme/widget/search/field/field_normal.png: + * DefaultTheme/widget/slider/slider.edc: + * DefaultTheme/widget/slider/slider_fill_h.png: Added. + * DefaultTheme/widget/slider/slider_fill_v.png: Added. + * DefaultTheme/widget/slider/slider_h.png: + * DefaultTheme/widget/slider/slider_hilight.png: Removed. + * DefaultTheme/widget/slider/slider_knob_h.png: + * DefaultTheme/widget/slider/slider_knob_press_h.png: Added. + * DefaultTheme/widget/slider/slider_knob_press_v.png: Added. + * DefaultTheme/widget/slider/slider_knob_v.png: + * DefaultTheme/widget/slider/slider_v.png: + +2010-08-12 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Making CMake keep track of theme dependencies. + https://bugs.webkit.org/show_bug.cgi?id=43862 + + Adding theme source files and images as dependencies of the theme. + + * CMakeListsEfl.txt: + +2010-08-11 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Add setting for enabling spatial navigation. + https://bugs.webkit.org/show_bug.cgi?id=43569 + + Adding api for enabling/disabling spatial navigation. + + * ewk/ewk_view.cpp: Both functions below added. + (ewk_view_setting_spatial_navigation_get): + (ewk_view_setting_spatial_navigation_set): + * ewk/ewk_view.h: same as ewk_view.cpp. + +2010-08-11 Ryuan Choi <ryuan.choi@samsung.com> + + Reviewed by Antonio Gomes. + + Implementation dispatchDecidePolicyForNavigationAction + https://bugs.webkit.org/show_bug.cgi?id=43544 + + Add ewk_view_navigation_policy_decision to decide whether url which + user clicked will be loaded or not. + + * WebCoreSupport/FrameLoaderClientEfl.cpp: + (WebCore::FrameLoaderClientEfl::dispatchDecidePolicyForNavigationAction): + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (ewk_view_navigation_policy_decision): + * ewk/ewk_view.h: + +2010-08-10 Ryuan Choi <ryuan.choi@samsung.com> + + Unreviewed build fix. + + [EFL]REGRESSION(65021) need to fix build break + https://bugs.webkit.org/show_bug.cgi?id=43767 + + Remove AtomicStringWTF and change namespace TextCaseInsensitive. + + * ewk/ewk_frame.cpp: + (ewk_frame_plugin_create): + * ewk/ewk_view.cpp: + (ewk_view_text_search): + (ewk_view_text_matches_mark): + (ewk_view_setting_font_cursive_set): + +2010-08-06 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig + + Bug 43594 - Add string forwards to Forward.h + This allows us to remove forward declarations for these classes from + WebCore/WebKit (a step in moving these class from WebCore:: to WTF::). + + * WebCoreSupport/InspectorClientEfl.h: + +2010-08-06 Jessie Berlin <jberlin@apple.com> + + Roll out http://trac.webkit.org/changeset/64801, which broke the Safari Windows Build. + Unreviewed. + + * WebCoreSupport/InspectorClientEfl.h: + +2010-08-03 Leandro Pereira <leandro@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + Implement HTML5 slider theme (using the scrollbar theme as base). + https://bugs.webkit.org/show_bug.cgi?id=43430 + + * DefaultTheme/default.edc: Include slider.edc. + * DefaultTheme/widget/slider/slider.edc: Added. + * DefaultTheme/widget/slider/slider_h.png: Copied from WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_h.png. + * DefaultTheme/widget/slider/slider_hilight.png: Copied from WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_hilight.png. + * DefaultTheme/widget/slider/slider_knob_h.png: Copied from WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_h.png. + * DefaultTheme/widget/slider/slider_knob_v.png: Copied from WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_v.png. + * DefaultTheme/widget/slider/slider_v.png: Copied from WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_v.png. + +2010-08-03 ryuan choi <ryuan.choi@samsung.com> + + Reviewed by Darin Adler. + + [EFL] REGRESSION(64425) need to fix build break + https://bugs.webkit.org/show_bug.cgi?id=43322 + + just add include path missed after r64425 + + * CMakeListsEfl.txt: + +2010-07-27 Luiz Agostini <luiz.agostini@openbossa.org> + + Reviewed by Darin Fisher. + + PopupMenu refactoring in preparation to WebKit2 + https://bugs.webkit.org/show_bug.cgi?id=42592 + + As ChromeClient was made responsible for providing PopupMenu and SearchPopupMenu + instances, concrete classes that inherit from ChromeClient needed to be changed to + implement the new methods. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::selectItemWritingDirectionIsNatural): + (WebCore::ChromeClientEfl::createPopupMenu): + (WebCore::ChromeClientEfl::createSearchPopupMenu): + * WebCoreSupport/ChromeClientEfl.h: + +2010-08-02 Jeremy Orlow <jorlow@chromium.org> + + Speculative revert of 64425 due to Chromium instability + https://bugs.webkit.org/show_bug.cgi?id=43347 + + * WebCoreSupport/ChromeClientEfl.cpp: + * WebCoreSupport/ChromeClientEfl.h: + +2010-07-27 Luiz Agostini <luiz.agostini@openbossa.org> + + Reviewed by Darin Fisher. + + PopupMenu refactoring in preparation to WebKit2 + https://bugs.webkit.org/show_bug.cgi?id=42592 + + As ChromeClient was made responsible for providing PopupMenu and SearchPopupMenu + instances, concrete classes that inherit from ChromeClient needed to be changed to + implement the new methods. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::selectItemWritingDirectionIsNatural): + (WebCore::ChromeClientEfl::createPopupMenu): + (WebCore::ChromeClientEfl::createSearchPopupMenu): + * WebCoreSupport/ChromeClientEfl.h: + +2010-07-31 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r64422. + http://trac.webkit.org/changeset/64422 + https://bugs.webkit.org/show_bug.cgi?id=43304 + + Build fixes are needed for Snow Leopard and Windows. + (Requested by lca on #webkit). + + * WebCoreSupport/ChromeClientEfl.cpp: + * WebCoreSupport/ChromeClientEfl.h: + +2010-07-27 Luiz Agostini <luiz.agostini@openbossa.org> + + Reviewed by Darin Fisher. + + PopupMenu refactoring in preparation to WebKit2 + https://bugs.webkit.org/show_bug.cgi?id=42592 + + As ChromeClient was made responsible for providing PopupMenu and SearchPopupMenu + instances, concrete classes that inherit from ChromeClient needed to be changed to + implement the new methods. + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::selectItemWritingDirectionIsNatural): + (WebCore::ChromeClientEfl::createPopupMenu): + (WebCore::ChromeClientEfl::createSearchPopupMenu): + * WebCoreSupport/ChromeClientEfl.h: + +2010-07-26 Steve Block <steveblock@google.com> + + Reviewed by Jeremy Orlow. + + Page clients should be passed to Page constructor via structure of pointers + https://bugs.webkit.org/show_bug.cgi?id=42834 + + * ewk/ewk_view.cpp: + (_ewk_view_priv_new): + +2010-07-26 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Move CMakeListsEfl.txt to WebKit/efl/ + https://bugs.webkit.org/show_bug.cgi?id=43002 + + This should reduce the noise in WebKit/ChangeLog that comes from EFL + port. Most of the changes on EFL port should be logged in + WebKit/efl/ChangeLog. + + * CMakeListsEfl.txt: Renamed from WebKit/CMakeListsEfl.txt. + +2010-07-23 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Cleanup glib support (make it optional) + https://bugs.webkit.org/show_bug.cgi?id=42480 + + Put some ifdefs on glib calls. + + * ewk/ewk_main.cpp: + (ewk_init): + +2010-07-23 Rafael Antognolli <antognolli@profusion.mobi> + + Reviewed by Antonio Gomes. + + [EFL] Add support for using libcurl network backend. + https://bugs.webkit.org/show_bug.cgi?id=42286 + + Put some ifdefs around soup calls. + + * ewk/ewk_cookies.cpp: + (ewk_cookies_file_set): + (ewk_cookies_clear): + (ewk_cookies_get_all): + (ewk_cookies_cookie_del): + (ewk_cookies_cookie_free): + (ewk_cookies_policy_set): + (ewk_cookies_policy_get): + * ewk/ewk_main.cpp: + (ewk_init): + +2010-07-23 Lucas De Marchi <lucas.demarchi@profusion.mobi> + + Reviewed by Kenneth Rohde Christiansen. + + Notify browser when window shall be closed. + + This is used for window.close() events Javascript, though it would be + triggered for any event on WebCore that might ask for the window to be + closed. + + https://bugs.webkit.org/show_bug.cgi?id=42890 + + * WebCoreSupport/ChromeClientEfl.cpp: + (WebCore::ChromeClientEfl::closeWindowSoon): call new function and moves its + previous functionality there. + * ewk/ewk_private.h: + * ewk/ewk_view.cpp: + (ewk_view_window_close): stop all loaders as was being done previously and + notify browser afterwards. + * ewk/ewk_view.h: declare new virtual method. + +2010-07-23 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + Reviewed by Kenneth Rohde Christiansen. + + [EFL] Set proxy address for Soup + https://bugs.webkit.org/show_bug.cgi?id=42721 + + Sets the given proxy URI for libsoup network backend. This method will + support libcurl network backend later. + + * EWebLauncher/main.c: + (main): Invoke proxy set method + * ewk/ewk_settings.cpp: + (ewk_settings_proxy_uri_set): Sets proxy URI. + * ewk/ewk_settings.h: + +2010-07-16 Leandro Pereira <leandro@profusion.mobi> + + Reviewed by Gustavo Noronha Silva. + + Creating ChangeLog for the EFL port. diff --git a/Source/WebKit/efl/DefaultTheme/default.edc b/Source/WebKit/efl/DefaultTheme/default.edc new file mode 100644 index 0000000..7d750f4 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/default.edc @@ -0,0 +1,79 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +color_classes { + color_class { + name: "webkit/selection/active"; + color: 255 255 255 255; /* foreground */ + color2: 86 86 209 255; /* background */ + } + color_class { + name: "webkit/selection/inactive"; + color: 255 255 255 255; /* foreground */ + color2: 0 0 128 128; /* background */ + } + color_class { + name: "webkit/focus_ring"; + color: 26 26 226 255; /* foreground */ + /* no background, consider transparent */ + } + color_class { + name: "webkit/button/text"; + color: 32 32 32 255; + /* no background, consider transparent */ + } + color_class { + name: "webkit/combo/text"; + color: 32 32 32 255; + /* no background, consider transparent */ + } + color_class { + name: "webkit/entry/text"; + color: 32 32 32 255; + /* no background, consider transparent */ + } + color_class { + name: "webkit/search/text"; + color: 32 32 32 255; + /* no background, consider transparent */ + } +} + +collections { + group { name: "webkit/base"; + /* specific colors and all, used to listen for color_class changes */ + } + +#include "widget/button/button.edc" +#include "widget/scrollbar/scrollbar.edc" +#include "widget/radio/radio.edc" +#include "widget/check/check.edc" +#include "widget/entry/entry.edc" +#include "widget/combo/combo.edc" +#ifdef ENABLE_PROGRESS_TAG +#include "widget/progressbar/progressbar.edc" +#endif +#include "widget/file/file.edc" +#include "widget/search/field/search_field.edc" +#include "widget/search/cancel/search_cancel.edc" +#include "widget/search/decoration/search_decoration.edc" +#include "widget/slider/slider.edc" +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/button/button.edc b/Source/WebKit/efl/DefaultTheme/widget/button/button.edc new file mode 100644 index 0000000..78cc72a --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/button/button.edc @@ -0,0 +1,176 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + group { + name: "webkit/widget/button"; + + images { + image: "widget/button/img_button_normal.png" COMP; + image: "widget/button/img_button_press.png" COMP; + image: "widget/button/img_button_hover.png" COMP; + image: "widget/button/img_button_focus.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + + if (get_int(isEnabled) == 1) { + set_state(PART:"button", "default", 0.0); + if (get_int(isFocused) == 1) { + set_state(PART:"button", "focused", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"button", "pressed", 0.0); + } + else if (get_int(isHovered) == 1) { + set_state(PART:"button", "hovered", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"button", "pressed", 0.0); + + } + } + else + set_state(PART:"button", "disabled", 0.0); + } + } + + parts { + + part { + name: "button"; + type: IMAGE; + description { + state: "default" 0.0; + min: 25 25; + image { + normal: "widget/button/img_button_normal.png"; + border: 6 10 8 10; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/button/img_button_press.png"; + border: 6 10 8 10; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/button/img_button_hover.png"; + border: 6 10 8 10; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/button/img_button_focus.png"; + border: 6 10 8 10; + } + } + } + + part { + name: "text_confinement"; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + rel1 { + relative: 0.0 0.0; + offset: 15 8; + } + rel2 { + relative: 1.0 1.0; + offset: -16 -11; + } + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/button/img_button_focus.png b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_focus.png Binary files differnew file mode 100644 index 0000000..9e91fe8 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/button/img_button_hover.png b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_hover.png Binary files differnew file mode 100644 index 0000000..9e91fe8 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/button/img_button_normal.png b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_normal.png Binary files differnew file mode 100644 index 0000000..bd9dee9 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_normal.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/button/img_button_press.png b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_press.png Binary files differnew file mode 100644 index 0000000..b8b5163 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/button/img_button_press.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/check.edc b/Source/WebKit/efl/DefaultTheme/widget/check/check.edc new file mode 100644 index 0000000..0e09303 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/check.edc @@ -0,0 +1,181 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + group { + + name: "webkit/widget/checkbox"; + min: 12 12; + + images { + image: "widget/check/img_check_on.png" COMP; + image: "widget/check/img_check_off.png" COMP; + image: "widget/check/img_check_off_focus.png" COMP; + image: "widget/check/img_check_on_focus.png" COMP; + image: "widget/check/img_check_off_hover.png" COMP; + image: "widget/check/img_check_on_hover.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"check_button", "default", 0.0); + if (get_int(isChecked) == 1) { + set_state(PART:"check_button", "enabled_checked", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"check_button", "focus_checked", 0.0); + if (get_int(isHovered) == 1 && get_int(isFocused) == 0) + set_state(PART:"check_button", "hovered_checked", 0.0); + } + else { + if (get_int(isFocused) == 1) + set_state(PART:"check_button", "focused", 0.0); + if (get_int(isHovered) == 1 && get_int(isFocused) == 0) + set_state(PART:"check_button", "hovered", 0.0); + } + } + else { + set_state(PART:"check_button", "disabled", 0.0); + if (get_int(isChecked) == 1) + set_state(PART:"check_button", "disabled_checked", 0.0); + } + } + } + + parts { + part { + name: "check_button"; + type: IMAGE; + description { + state: "default" 0.0; + min: 12 12; + max: 12 12; + image { + normal: "widget/check/img_check_off.png"; + } + } + description { + state: "enabled_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/check/img_check_on.png"; + } + } + description { + state: "disabled_checked" 0.0; + inherit: "enabled_checked" 0.0; + color: 255 255 255 150; + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/check/img_check_on_hover.png"; + } + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/check/img_check_off_hover.png"; + } + } + description { + state: "focus_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/check/img_check_on_focus.png"; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/check/img_check_off_focus.png"; + } + } + } + } + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off.png Binary files differnew file mode 100644 index 0000000..167fa4e --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_focus.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_focus.png Binary files differnew file mode 100644 index 0000000..18bee2a --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_hover.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_hover.png Binary files differnew file mode 100644 index 0000000..18bee2a --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_off_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on.png Binary files differnew file mode 100644 index 0000000..87d13ed --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_focus.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_focus.png Binary files differnew file mode 100644 index 0000000..1f40566 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_hover.png b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_hover.png Binary files differnew file mode 100644 index 0000000..1f40566 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/check/img_check_on_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo.edc b/Source/WebKit/efl/DefaultTheme/widget/combo/combo.edc new file mode 100644 index 0000000..d101d60 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo.edc @@ -0,0 +1,306 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/combo"; + + images { + image: "widget/combo/combo_normal.png" COMP; + image: "widget/combo/combo_normal_button.png" COMP; + image: "widget/combo/combo_hover.png" COMP; + image: "widget/combo/combo_hover_button.png" COMP; + image: "widget/combo/combo_focus.png" COMP; + image: "widget/combo/combo_focus_button.png" COMP; + image: "widget/combo/combo_press.png" COMP; + image: "widget/combo/combo_press_button.png" COMP; + image: "widget/combo/icon.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"combo", "default", 0.0); + set_state(PART:"combo_button", "default", 0.0); + set_state(PART:"combo_button_icon", "default", 0.0); + if (get_int(isFocused) == 1) { + set_state(PART:"combo", "focused", 0.0); + set_state(PART:"combo_button", "focused", 0.0); + if (get_int(isPressed) == 1) { + set_state(PART:"combo", "pressed", 0.0); + set_state(PART:"combo_button", "pressed", 0.0); + } + } + else if (get_int(isHovered) == 1) { + set_state(PART:"combo", "hovered", 0.0); + set_state(PART:"combo_button", "hovered", 0.0); + if (get_int(isPressed) == 1) { + set_state(PART:"combo", "pressed", 0.0); + set_state(PART:"combo_button", "pressed", 0.0); + } + } + } + else { + set_state(PART:"combo", "disabled", 0.0); + set_state(PART:"combo_button", "disabled", 0.0); + set_state(PART:"combo_button_icon", "disabled", 0.0); + } + } + } + + parts { + part { + name: "clipper"; + type: RECT; + description { + min: 35 27; + state: "default" 0.0; + } + } + + part { + name: "combo_clipper"; + type: RECT; + clip_to: "clipper"; + description { + state: "default" 0.0; + rel1.to: "clipper"; + rel2 { + to: "clipper"; + offset: -32 -1; + } + } + } + + part { + name: "combo"; + type: IMAGE; + clip_to: "combo_clipper"; + description { + state: "default" 0.0; + min: 36 20; + image { + normal: "widget/combo/combo_normal.png"; + border: 15 0 8 11; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/combo/combo_hover.png"; + border: 15 0 8 11; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/combo/combo_focus.png"; + border: 15 0 8 11; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/combo/combo_press.png"; + border: 15 0 8 11; + } + } + } + + part { + name: "bt_combo_clipper"; + type: RECT; + clip_to: "clipper"; + description { + state: "default" 0.0; + rel1 { + to: "combo_clipper"; + relative: 1.0 0.0; + } + rel2 { + to: "clipper"; + relative: 1.0 1.0; + } + } + } + + part { + name: "combo_button"; + type: IMAGE; + clip_to: "bt_combo_clipper"; + description { + state: "default" 0.0; + min: 18 20; // 3 + 5 + image width (10), 5 + 5 + image height (10) + rel1.to: "bt_combo_clipper"; + image { + normal: "widget/combo/combo_normal_button.png"; + border: 1 15 8 10; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + rel1.to: "bt_combo_clipper"; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + rel1.to: "bt_combo_clipper"; + image { + normal: "widget/combo/combo_hover_button.png"; + border: 1 15 8 10; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + rel1.to: "bt_combo_clipper"; + image { + normal: "widget/combo/combo_focus_button.png"; + border: 1 15 8 10; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + rel1.to: "bt_combo_clipper"; + image { + normal: "widget/combo/combo_press_button.png"; + border: 1 15 8 10; + } + } + } + + + part { + name: "combo_button_icon"; + type: IMAGE; + clip_to: "bt_combo_clipper"; + description { + state: "default" 0.0; + min: 12 10; + max: 12 10; + color: 255 255 255 150; + rel1 { + to: "bt_combo_clipper"; + relative: 0.5 0.5; + offset: 0 1; + } + rel2 { + to: "bt_combo_clipper"; + relative: 0.5 0.5; + } + fixed: 1 1; + image { + normal: "widget/combo/icon.png"; + border: 5 5 0 0; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 50; + image { + normal: "widget/combo/icon.png"; + border: 5 5 0 0; + } + } + } + + part { + name: "text_confinement"; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + rel1 { + to: "combo_clipper"; + offset: 15 10; + } + rel2 { + to: "combo_clipper"; + offset: -11 -11; + } + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus.png Binary files differnew file mode 100644 index 0000000..3b1574b --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus_button.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus_button.png Binary files differnew file mode 100644 index 0000000..eaf137b --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_focus_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover.png Binary files differnew file mode 100644 index 0000000..3b1574b --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover_button.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover_button.png Binary files differnew file mode 100644 index 0000000..eaf137b --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_hover_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal.png Binary files differnew file mode 100644 index 0000000..fc461a7 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal_button.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal_button.png Binary files differnew file mode 100644 index 0000000..1cbcb11 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_normal_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press.png Binary files differnew file mode 100644 index 0000000..97c88c5 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press_button.png b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press_button.png Binary files differnew file mode 100644 index 0000000..17233af --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/combo_press_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/combo/icon.png b/Source/WebKit/efl/DefaultTheme/widget/combo/icon.png Binary files differnew file mode 100644 index 0000000..1534c2c --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/combo/icon.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/entry/entry.edc b/Source/WebKit/efl/DefaultTheme/widget/entry/entry.edc new file mode 100644 index 0000000..613ee59 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/entry/entry.edc @@ -0,0 +1,167 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + group { + name: "webkit/widget/entry"; + + images { + image: "widget/entry/img_normal.png" COMP; + image: "widget/entry/img_focused.png" COMP; + image: "widget/entry/img_hovered.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"entry", "default", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"entry", "pressed", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"entry", "focused", 0.0); + if (get_int(isHovered) == 1 && get_int(isFocused) == 0) + set_state(PART:"entry", "hovered", 0.0); + } + else + set_state(PART:"entry", "disabled", 0.0); + } + + } + + parts { + part { + name: "entry"; + type: IMAGE; + description { + state: "default" 0.0; + min: 14 14; + rel1 { + relative: 0.0 0.0; + offset: 0 0; + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + image { + normal: "widget/entry/img_normal.png"; + border: 7 7 7 7; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/entry/img_focused.png"; + border: 7 7 7 7; + } + } + description { + state: "pressed" 0.0; + inherit: "focused" 0.0; + } + description { + state: "hovered" 0.0; + inherit: "focused" 0.0; + image { + normal: "widget/entry/img_hovered.png"; + border: 7 7 7 7; + } + } + } + + part { + name: "text_confinement"; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + rel1.offset: 4 6; // <- 6 because of the blink cursor + rel2.offset: -4 -5; // <- due to the image + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/entry/img_focused.png b/Source/WebKit/efl/DefaultTheme/widget/entry/img_focused.png Binary files differnew file mode 100644 index 0000000..f4b17a9 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/entry/img_focused.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/entry/img_hovered.png b/Source/WebKit/efl/DefaultTheme/widget/entry/img_hovered.png Binary files differnew file mode 100644 index 0000000..f4b17a9 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/entry/img_hovered.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/entry/img_normal.png b/Source/WebKit/efl/DefaultTheme/widget/entry/img_normal.png Binary files differnew file mode 100644 index 0000000..88d53f4 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/entry/img_normal.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/file/file.edc b/Source/WebKit/efl/DefaultTheme/widget/file/file.edc new file mode 100644 index 0000000..40afcc7 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/file/file.edc @@ -0,0 +1,148 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/file"; + + images { + image: "widget/file/file_normal.png" COMP; + image: "widget/file/file_hover.png" COMP; + image: "widget/file/file_focus.png" COMP; + image: "widget/file/file_press.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"file", "default", 0.0); + if (get_int(isFocused) == 1) { + set_state(PART:"file", "focused", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"file", "pressed", 0.0); + } + else if (get_int(isHovered) == 1) { + set_state(PART:"file", "hovered", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"file", "pressed", 0.0); + + } + } + else + set_state(PART:"file", "disabled", 0.0); + } + } + + parts { + part { + name: "file"; + type: IMAGE; + description { + state: "default" 0.0; + image { + normal: "widget/file/file_normal.png"; + border: 8 8 8 8; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/file/file_hover.png"; + border: 8 8 8 8; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/file/file_focus.png"; + border: 8 8 8 8; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/file/file_press.png"; + border: 8 8 8 8; + } + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/file/file_focus.png b/Source/WebKit/efl/DefaultTheme/widget/file/file_focus.png Binary files differnew file mode 100644 index 0000000..cc93b27 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/file/file_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/file/file_hover.png b/Source/WebKit/efl/DefaultTheme/widget/file/file_hover.png Binary files differnew file mode 100644 index 0000000..41285a1 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/file/file_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/file/file_normal.png b/Source/WebKit/efl/DefaultTheme/widget/file/file_normal.png Binary files differnew file mode 100644 index 0000000..a6d0653 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/file/file_normal.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/file/file_press.png b/Source/WebKit/efl/DefaultTheme/widget/file/file_press.png Binary files differnew file mode 100644 index 0000000..f18f8fd --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/file/file_press.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/progressbar/bt_base.png b/Source/WebKit/efl/DefaultTheme/widget/progressbar/bt_base.png Binary files differnew file mode 100644 index 0000000..2d1f179 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/progressbar/bt_base.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/progressbar/progressbar.edc b/Source/WebKit/efl/DefaultTheme/widget/progressbar/progressbar.edc new file mode 100644 index 0000000..2a34d54 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/progressbar/progressbar.edc @@ -0,0 +1,108 @@ +/* + Copyright (C) 2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +group { + name: "webkit/widget/progressbar"; + min: 0 11; /* if > 0, this is the minimum size that will be allocated. + * If wants to draw on top, just overflow usign edje's rel1/rel2 + */ + max: 999999 999999; + + images { + image: "widget/progressbar/shelf_inset.png" COMP; + image: "widget/progressbar/bt_base.png" COMP; + } + + script { + public message(Msg_Type:type, id, ...) { + if ((id == 0) && (type == MSG_FLOAT_SET)) { + new Float:x, Float:sx; + x = getfarg(2); + sx = getfarg(3); + + if (sx >= 0.0) { + set_drag_size(PART:"img.progressbar_fill", sx, 1.0); + set_drag(PART:"img.progressbar_fill", x, 0.0); + } + } + } + } + + parts { + part { + name: "rect.base"; + type: RECT; + description { + state: "default" 0.0; + min: 29 11; + max: 999999 99999; + color: 255 255 255 0; + } + } + part { + name: "rect.clipper"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 255; + } + description { + state: "hidden" 0.0; + color: 255 255 255 128; + } + } + + part { + name: "img.progressbar"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 29 5; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + align: 0.5 0.5; + image { + normal: "widget/progressbar/shelf_inset.png"; + border: 8 8 8 8; + } + } + } + part { + name: "img.progressbar_fill"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + dragable { + x: 1 1 0; + y: 0 0 0; + confine: "rect.base"; + } + description { + state: "default" 0.0; + min: 0 5; + align: 0.5 0.5; + image { + normal: "widget/progressbar/bt_base.png"; + border: 7 7 0 0; + } + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/progressbar/shelf_inset.png b/Source/WebKit/efl/DefaultTheme/widget/progressbar/shelf_inset.png Binary files differnew file mode 100644 index 0000000..bb1989d --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/progressbar/shelf_inset.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off.png Binary files differnew file mode 100644 index 0000000..cd64cd8 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_focus.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_focus.png Binary files differnew file mode 100644 index 0000000..87d31e2 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_hover.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_hover.png Binary files differnew file mode 100644 index 0000000..87d31e2 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_off_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on.png Binary files differnew file mode 100644 index 0000000..b8d8ecb --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_focus.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_focus.png Binary files differnew file mode 100644 index 0000000..bf8a970 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_focus.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_hover.png b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_hover.png Binary files differnew file mode 100644 index 0000000..bf8a970 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/img_radio_on_hover.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/radio/radio.edc b/Source/WebKit/efl/DefaultTheme/widget/radio/radio.edc new file mode 100644 index 0000000..f07b9b2 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/radio/radio.edc @@ -0,0 +1,181 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + group { + name: "webkit/widget/radio"; + min: 12 12; + + images { + image: "widget/radio/img_radio_on.png" COMP; + image: "widget/radio/img_radio_off.png" COMP; + image: "widget/radio/img_radio_on_focus.png" COMP; + image: "widget/radio/img_radio_off_focus.png" COMP; + image: "widget/radio/img_radio_on_hover.png" COMP; + image: "widget/radio/img_radio_off_hover.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"radio_button", "default", 0.0); + if (get_int(isChecked) == 1) { + set_state(PART:"radio_button", "enabled_checked", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"radio_button", "focus_checked", 0.0); + if (get_int(isHovered) == 1 && get_int(isFocused) == 0) + set_state(PART:"radio_button", "hovered_checked", 0.0); + } + else { + if (get_int(isFocused) == 1) + set_state(PART:"radio_button", "focused", 0.0); + if (get_int(isHovered) == 1 && get_int(isFocused) == 0) + set_state(PART:"radio_button", "hovered", 0.0); + } + } + else { + set_state(PART:"radio_button", "disabled", 0.0); + if (get_int(isChecked) == 1) + set_state(PART:"radio_button", "disabled_checked", 0.0); + } + } + } + + parts { + part { + name: "radio_button"; + type: IMAGE; + description { + state: "default" 0.0; + min: 12 12; + max: 12 12; + image { + normal: "widget/radio/img_radio_off.png"; + } + } + description { + state: "enabled_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/radio/img_radio_on.png"; + } + } + description { + state: "disabled_checked" 0.0; + inherit: "enabled_checked" 0.0; + color: 255 255 255 150; + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/radio/img_radio_on_hover.png"; + } + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/radio/img_radio_off_hover.png"; + } + } + description { + state: "focus_checked" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/radio/img_radio_on_focus.png"; + } + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/radio/img_radio_off_focus.png"; + } + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar.edc b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar.edc new file mode 100644 index 0000000..b4eead0 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar.edc @@ -0,0 +1,372 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "scrollbar.vertical"; + + min: 0 0; /* if > 0, this is the minimum size that will be allocated. + * If wants to draw on top, just overflow usign edje's rel1/rel2 + */ + + images { + image: "widget/scrollbar/scrollbar_v.png" COMP; + image: "widget/scrollbar/scrollbar_knob_v.png" COMP; + } + + script { + public hide_timer; + + public hide_timer_cb(val) { + run_program(PROGRAM:"hide"); + return 0; + } + + public hide_timer_stop() { + new id = get_int(hide_timer); + if (id <= 0) + return; + + cancel_timer(id); + set_int(hide_timer, 0); + } + + public hide_timer_start() { + set_int(hide_timer, timer(1.0, "hide_timer_cb", 0)); + } + + public message(Msg_Type:type, id, ...) { + if ((id == 0) && (type == MSG_FLOAT_SET)) { + new Float:vy, Float:sy; + + vy = getfarg(2); + sy = getfarg(3); + + if (vy >= 0.0) { + set_drag_size(PART:"img.knob", 1.0, sy); + set_drag(PART:"img.knob", 0.0, vy); + run_program(PROGRAM:"show"); + } else + run_program(PROGRAM:"hide"); + + hide_timer_stop(); + hide_timer_start(); + } + } + + public update_drag_pos() { + new Float:x, Float:y; + get_drag(PART:"img.knob", x, y); + send_message(MSG_FLOAT, 1, y); + } + } + + parts { + part { + name: "rect.base"; + type: RECT; + description { + min: 10 0; + max: 10 999999; + align: 1.0 0.5; + state: "default" 0.0; + color: 255 255 255 0; + } + } + + part { + name: "rect.clipper"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 255; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + description { + state: "hidden" 0.0; + color: 255 255 255 64; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + part { + name: "img.scrollbar"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 1 30; + max: 1 999999; + align: 0.5 0.5; + image { + normal: "widget/scrollbar/scrollbar_v.png"; + border: 0 0 15 15; + middle: SOLID; + } + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + part { + name: "rect.knobarea"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 0; + min: 5 5; + max: 5 999999; + align: 0.5 0.5; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + part { + name: "img.knob"; + type: IMAGE; + mouse_events: 1; + clip_to: "rect.clipper"; + dragable { + x: 0 0 0; + y: 1 1 0; + confine: "rect.knobarea"; + } + description { + state: "default" 0.0; + min: 5 5; + max: 5 999999; + align: 0.5 0.5; + image { + normal: "widget/scrollbar/scrollbar_knob_v.png"; + border: 3 3 3 3; + middle: SOLID; + } + } + } + } + programs { + program { + name: "load"; + signal: "load"; + action: STATE_SET "hidden" 0.0; + target: "rect.clipper"; + } + program { + name: "hide"; + action: STATE_SET "hidden" 0.0; + transition: ACCELERATE 0.5; + target: "rect.clipper"; + } + + program { + name: "show"; + action: STATE_SET "default" 0.0; + target: "rect.clipper"; + } + + program { + name: "dragged"; + signal: "drag"; + source: "img.knob"; + script { + update_drag_pos(); + } + } + } +} + +group { + name: "scrollbar.horizontal"; + + min: 0 0; /* if > 0, this is the minimum size that will be allocated. + * If wants to draw on top, just overflow usign edje's rel1/rel2 + */ + + images { + image: "widget/scrollbar/scrollbar_h.png" COMP; + image: "widget/scrollbar/scrollbar_knob_h.png" COMP; + } + + script { + public hide_timer; + + public hide_timer_cb(val) { + run_program(PROGRAM:"hide"); + return 0; + } + + public hide_timer_stop() { + new id = get_int(hide_timer); + if (id <= 0) + return; + + cancel_timer(id); + set_int(hide_timer, 0); + } + + public hide_timer_start() { + set_int(hide_timer, timer(1.0, "hide_timer_cb", 0)); + } + + public message(Msg_Type:type, id, ...) { + if ((id == 0) && (type == MSG_FLOAT_SET)) { + new Float:vx, Float:sx; + + vx = getfarg(2); + sx = getfarg(3); + + if (vx >= 0.0) { + set_drag_size(PART:"img.knob", sx, 1.0); + set_drag(PART:"img.knob", vx, 0.0); + run_program(PROGRAM:"show"); + } else + run_program(PROGRAM:"hide"); + + hide_timer_stop(); + hide_timer_start(); + } + } + + public update_drag_pos() { + new Float:x, Float:y; + get_drag(PART:"img.knob", x, y); + send_message(MSG_FLOAT, 1, x); + } + } + + parts { + part { + name: "rect.base"; + type: RECT; + description { + state: "default" 0.0; + min: 0 10; + max: 999999 10; + align: 0.5 1.0; + color: 255 255 255 0; + } + } + + part { + name: "rect.clipper"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 255; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + description { + state: "hidden" 0.0; + color: 255 255 255 64; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + part { + name: "img.scrollbar"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 30 1; + max: 999999 1; + align: 0.5 0.5; + image { + normal: "widget/scrollbar/scrollbar_h.png"; + border: 15 15 0 0; + middle: SOLID; + } + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + + part { + name: "rect.knobarea"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 0; + min: 5 5; + max: 999999 5; + align: 0.5 0.5; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + } + } + + part { + name: "img.knob"; + type: IMAGE; + mouse_events: 1; + clip_to: "rect.clipper"; + dragable { + x: 1 1 0; + y: 0 0 0; + confine: "rect.knobarea"; + } + description { + state: "default" 0.0; + min: 5 5; + max: 999999 5; + image { + normal: "widget/scrollbar/scrollbar_knob_h.png"; + border: 3 3 3 3; + middle: SOLID; + } + } + } + } + programs { + program { + name: "load"; + signal: "load"; + action: STATE_SET "hidden" 0.0; + target: "rect.clipper"; + } + program { + name: "hide"; + action: STATE_SET "hidden" 0.0; + transition: ACCELERATE 0.5; + target: "rect.clipper"; + } + + program { + name: "show"; + action: STATE_SET "default" 0.0; + target: "rect.clipper"; + } + + program { + name: "dragged"; + signal: "drag"; + source: "img.knob"; + script { + update_drag_pos(); + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_h.png b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_h.png Binary files differnew file mode 100644 index 0000000..6703ea8 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_h.png b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_h.png Binary files differnew file mode 100644 index 0000000..b64d5ce --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_v.png b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_v.png Binary files differnew file mode 100644 index 0000000..9aa37ec --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_knob_v.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_v.png b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_v.png Binary files differnew file mode 100644 index 0000000..364be0a --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/scrollbar/scrollbar_v.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button.png b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button.png Binary files differnew file mode 100644 index 0000000..d496599 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button2.png b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button2.png Binary files differnew file mode 100644 index 0000000..3120cfb --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/cancel_normal_button2.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/cancel/search_cancel.edc b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/search_cancel.edc new file mode 100644 index 0000000..d4a1a20 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/cancel/search_cancel.edc @@ -0,0 +1,131 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/search/cancel_button"; + alias: "webkit/widget/search/results_button"; // TODO + + images { + image: "widget/search/cancel/cancel_normal_button2.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"cancel_button", "default", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"cancel_button", "focused", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"cancel_button", "pressed", 0.0); + if (get_int(isHovered) == 1) + set_state(PART:"cancel_button", "hovered", 0.0); + } + else + set_state(PART:"cancel_button", "disabled", 0.0); + } + } + + parts { + part { + name: "cancel_button"; + type: IMAGE; + description { + state: "default" 0.0; + min: 21 20; + rel1.offset: 0 -6; + rel2.offset: -1 0; + image { + normal: "widget/search/cancel/cancel_normal_button2.png"; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/decoration/decoration_normal_button.png b/Source/WebKit/efl/DefaultTheme/widget/search/decoration/decoration_normal_button.png Binary files differnew file mode 100644 index 0000000..6e7f418 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/decoration/decoration_normal_button.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/decoration/search_decoration.edc b/Source/WebKit/efl/DefaultTheme/widget/search/decoration/search_decoration.edc new file mode 100644 index 0000000..4159138 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/decoration/search_decoration.edc @@ -0,0 +1,132 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/search/decoration"; + alias: "webkit/widget/search/results_decoration"; //TODO + + images { + image: "widget/search/decoration/decoration_normal_button.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"decoration", "default", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"decoration", "focused", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"decoration", "pressed", 0.0); + if (get_int(isHovered) == 1) + set_state(PART:"decoration", "hovered", 0.0); + } + else + set_state(PART:"decoration", "disabled", 0.0); + } + } + + parts { + part { + name: "decoration"; + type: IMAGE; + description { + state: "default" 0.0; + min: 20 20; + rel1.offset: 0 -4; + rel2.offset: -1 0; + image { + normal: "widget/search/decoration/decoration_normal_button.png"; + border: 0 0 8 8; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "hovered" 0.0; + inherit: "default" 0.0; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + } + } + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/field/field_focused.png b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_focused.png Binary files differnew file mode 100644 index 0000000..f4b17a9 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_focused.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/field/field_hovered.png b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_hovered.png Binary files differnew file mode 100644 index 0000000..f4b17a9 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_hovered.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/field/field_normal.png b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_normal.png Binary files differnew file mode 100644 index 0000000..88d53f4 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/field/field_normal.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/search/field/search_field.edc b/Source/WebKit/efl/DefaultTheme/widget/search/field/search_field.edc new file mode 100644 index 0000000..e9be229 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/search/field/search_field.edc @@ -0,0 +1,151 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/search/field"; + + images { + image: "widget/search/field/field_normal.png" COMP; + image: "widget/search/field/field_focused.png" COMP; + image: "widget/search/field/field_hovered.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + if (get_int(isEnabled) == 1) { + set_state(PART:"search_field", "default", 0.0); + if (get_int(isFocused) == 1) + set_state(PART:"search_field", "focused", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"search_field", "pressed", 0.0); + if (get_int(isFocused) == 0 && get_int(isHovered) == 1) + set_state(PART:"search_field", "hovered", 0.0); + } + else + set_state(PART:"search_field", "disabled", 0.0); + } + } + + parts { + part { + name: "search_field"; + type: IMAGE; + description { + state: "default" 0.0; + min: 89 20; + image { + normal: "widget/search/field/field_normal.png"; + border: 8 8 8 8; + } + } + description { + state: "disabled" 0.0; + inherit: "default" 0.0; + color: 255 255 255 150; + } + description { + state: "focused" 0.0; + inherit: "default" 0.0; + image { + normal: "widget/search/field/field_focused.png"; + border: 8 8 8 8; + } + } + description { + state: "hovered" 0.0; + inherit: "focused" 0.0; + image { + normal: "widget/search/field/field_hovered.png"; + border: 8 8 8 8; + } + } + description { + state: "pressed" 0.0; + inherit: "focused" 0.0; + } + } + + part { + name: "text_confinement"; + type: RECT; + description { + state: "default" 0.0; + color: 0 0 0 0; + rel1.offset: 4 6; // <- 6 because of the blink cursor + rel2.offset: -4 -5; // <- due to the image + } + } + + } + + programs { + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } + } diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider.edc b/Source/WebKit/efl/DefaultTheme/widget/slider/slider.edc new file mode 100644 index 0000000..9e339e5 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider.edc @@ -0,0 +1,491 @@ +/* + Copyright (C) 2008,2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009,2010 ProFUSION embedded systems + Copyright (C) 2009,2010 Samsung Electronics + + This file is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +group { + name: "webkit/widget/slider/vertical"; + + min: 11 0; /* if > 0, this is the minimum size that will be allocated. + * If wants to draw on top, just overflow usign edje's rel1/rel2 + */ + max: 11 999999; + + images { + image: "widget/slider/slider_v.png" COMP; + image: "widget/slider/slider_knob_v.png" COMP; + image: "widget/slider/slider_knob_press_v.png" COMP; + image: "widget/slider/slider_fill_v.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + + if (get_int(isEnabled) == 1) { + set_state(PART:"img.knob", "default", 0.0); + if (get_int(isFocused) == 1) { + set_state(PART:"img.knob", "pressed", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"img.knob", "pressed", 0.0); + } + else if (get_int(isHovered) == 1) { + set_state(PART:"img.knob", "pressed", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"img.knob", "pressed", 0.0); + } + } + else + set_state(PART:"img.knob", "default", 0.0); + } + + public message(Msg_Type:type, id, ...) { + if ((id == 0) && (type == MSG_FLOAT_SET)) { + new Float:vy, Float:sy; + + vy = getfarg(2); + sy = getfarg(3); + + if (vy >= 0.0) { + set_drag_size(PART:"img.knob", 1.0, sy); + set_drag(PART:"img.knob", 0.0, vy); + run_program(PROGRAM:"show"); + } else + run_program(PROGRAM:"hide"); + } + } + + public update_drag_pos() { + new Float:x, Float:y; + get_drag(PART:"img.knob", x, y); + send_message(MSG_FLOAT, 1, y); + } + } + + parts { + part { + name: "rect.base"; + type: RECT; + description { + min: 11 29; + max: 11 999999; + state: "default" 0.0; + color: 255 255 255 0; + } + } + part { + name: "rect.clipper"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 255; + } + description { + state: "hidden" 0.0; + color: 255 255 255 128; + } + } + + part { + name: "img.slider"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 5 29; + max: 5 999999; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + image { + normal: "widget/slider/slider_v.png"; + border: 0 0 5 5; + } + } + } + + part { + name: "img.slider_fill"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 5 29; + max: 5 999999; + rel1.to: "img.knob"; + rel2.to: "rect.base"; + align: 0.5 0.5; + image { + normal: "widget/slider/slider_fill_v.png"; + border: 0 0 5 5; + } + } + } + + part { + name: "img.knob"; + type: IMAGE; + mouse_events: 1; + clip_to: "rect.clipper"; + dragable { + x: 0 0 0; + y: 1 1 1; + confine: "rect.base"; + } + description { + state: "default" 0.0; + min: 11 29; + align: 0.5 0.5; + image { + normal: "widget/slider/slider_knob_v.png"; + border: 0 0 6 6; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: "widget/slider/slider_knob_press_v.png"; + } + } + } + programs { + program { + name: "load"; + signal: "load"; + action: STATE_SET "hidden" 0.0; + target: "rect.clipper"; + } + program { + name: "hide"; + action: STATE_SET "hidden" 0.0; + transition: ACCELERATE 0.5; + target: "rect.clipper"; + } + + program { + name: "show"; + action: STATE_SET "default" 0.0; + target: "rect.clipper"; + } + + program { + name: "dragged"; + signal: "drag"; + source: "img.knob"; + script { + update_drag_pos(); + } + } + + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } +} + +group { + name: "webkit/widget/slider/horizontal"; + + min: 0 11; /* if > 0, this is the minimum size that will be allocated. + * If wants to draw on top, just overflow usign edje's rel1/rel2 + */ + max: 999999 11; + + images { + image: "widget/slider/slider_h.png" COMP; + image: "widget/slider/slider_knob_h.png" COMP; + image: "widget/slider/slider_knob_press_h.png" COMP; + image: "widget/slider/slider_fill_h.png" COMP; + } + + script { + public isEnabled; + public isPressed; + public isChecked; + public isFocused; + public isHovered; + + public show() { + + if (get_int(isEnabled) == 1) { + set_state(PART:"img.knob", "default", 0.0); + if (get_int(isFocused) == 1) { + set_state(PART:"img.knob", "pressed", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"img.knob", "pressed", 0.0); + } + else if (get_int(isHovered) == 1) { + set_state(PART:"img.knob", "pressed", 0.0); + if (get_int(isPressed) == 1) + set_state(PART:"img.knob", "pressed", 0.0); + } + } + else + set_state(PART:"img.knob", "default", 0.0); + } + + public message(Msg_Type:type, id, ...) { + if ((id == 0) && (type == MSG_FLOAT_SET)) { + new Float:vx, Float:sx; + + vx = getfarg(2); + sx = getfarg(3); + + if (vx >= 0.0) { + set_drag_size(PART:"img.knob", sx, 1.0); + set_drag(PART:"img.knob", vx, 0.0); + run_program(PROGRAM:"show"); + } else + run_program(PROGRAM:"hide"); + } + } + + public update_drag_pos() { + new Float:x, Float:y; + get_drag(PART:"img.knob", x, y); + send_message(MSG_FLOAT, 1, x); + } + } + + parts { + part { + name: "rect.base"; + type: RECT; + description { + state: "default" 0.0; + min: 29 11; + max: 999999 11; + color: 255 255 255 0; + } + } + part { + name: "rect.clipper"; + type: RECT; + description { + state: "default" 0.0; + color: 255 255 255 255; + } + description { + state: "hidden" 0.0; + color: 255 255 255 128; + } + } + + part { + name: "img.slider"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 29 5; + max: 999999 5; + rel1.to: "rect.base"; + rel2.to: "rect.base"; + align: 0.5 0.5; + image { + normal: "widget/slider/slider_h.png"; + border: 5 5 0 0; + } + } + } + + part { + name: "img.slider_fill"; + type: IMAGE; + mouse_events: 0; + clip_to: "rect.clipper"; + description { + state: "default" 0.0; + min: 29 5; + max: 999999 5; + rel1.to: "rect.base"; + rel2.to: "img.knob"; + align: 0.5 0.5; + image { + normal: "widget/slider/slider_fill_h.png"; + border: 5 5 0 0; + } + } + } + + part { + name: "img.knob"; + type: IMAGE; + mouse_events: 1; + clip_to: "rect.clipper"; + dragable { + x: 1 1 0; + y: 0 0 0; + confine: "rect.base"; + } + description { + state: "default" 0.0; + min: 29 11; + align: 0.5 0.5; + image { + normal: "widget/slider/slider_knob_h.png"; + border: 6 6 0 0; + } + } + description { + state: "pressed" 0.0; + inherit: "default" 0.0; + image.normal: "widget/slider/slider_knob_press_h.png"; + } + } + } + programs { + program { + name: "load"; + signal: "load"; + action: STATE_SET "hidden" 0.0; + target: "rect.clipper"; + } + program { + name: "hide"; + action: STATE_SET "hidden" 0.0; + transition: ACCELERATE 0.5; + target: "rect.clipper"; + } + + program { + name: "show"; + action: STATE_SET "default" 0.0; + target: "rect.clipper"; + } + + program { + name: "dragged"; + signal: "drag"; + source: "img.knob"; + script { + update_drag_pos(); + } + } + + program { + name: "enabled"; + signal: "enabled"; + script { + set_int(isEnabled, 1); + show(); + } + } + program { + name: "pressed"; + signal: "pressed"; + script { + set_int(isPressed, 1); + show(); + } + } + program { + name: "checked"; + signal: "checked"; + script { + set_int(isChecked, 1); + show(); + } + } + program { + name: "focused"; + signal: "focused"; + script { + set_int(isFocused, 1); + show(); + } + } + program { + name: "hovered"; + signal: "hovered"; + script { + set_int(isHovered, 1); + show(); + } + } + program { + name: "reset"; + signal: "reset"; + script { + set_int(isEnabled, 0); + set_int(isPressed, 0); + set_int(isChecked, 0); + set_int(isFocused, 0); + set_int(isHovered, 0); + show(); + } + } + } +} diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_h.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_h.png Binary files differnew file mode 100644 index 0000000..abe9d2c --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_v.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_v.png Binary files differnew file mode 100644 index 0000000..5184cad --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_fill_v.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_h.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_h.png Binary files differnew file mode 100644 index 0000000..befd4a0 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_h.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_h.png Binary files differnew file mode 100644 index 0000000..22454af --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_h.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_h.png Binary files differnew file mode 100644 index 0000000..1421cd8 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_h.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_v.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_v.png Binary files differnew file mode 100644 index 0000000..293813c --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_press_v.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_v.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_v.png Binary files differnew file mode 100644 index 0000000..051f3c3 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_knob_v.png diff --git a/Source/WebKit/efl/DefaultTheme/widget/slider/slider_v.png b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_v.png Binary files differnew file mode 100644 index 0000000..7243929 --- /dev/null +++ b/Source/WebKit/efl/DefaultTheme/widget/slider/slider_v.png diff --git a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp new file mode 100644 index 0000000..e9904c6 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.cpp @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Kenneth Rohde Christiansen + * Copyright (C) 2008 Diego Gonzalez + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ChromeClientEfl.h" + +#if ENABLE(DATABASE) +#include "DatabaseDetails.h" +#include "DatabaseTracker.h" +#endif +#include "EWebKit.h" +#include "FileChooser.h" +#include "FloatRect.h" +#include "FrameLoader.h" +#include "FrameLoaderClientEfl.h" +#include "HitTestResult.h" +#include "IntRect.h" +#include "KURL.h" +#include "NavigationAction.h" +#include "NotImplemented.h" +#include "PlatformString.h" +#include "SecurityOrigin.h" +#include "PopupMenuEfl.h" +#include "SearchPopupMenuEfl.h" +#include "ViewportArguments.h" +#include "WindowFeatures.h" +#include "ewk_private.h" +#include <Ecore_Evas.h> +#include <Evas.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +static inline Evas_Object* kit(Frame* frame) +{ + if (!frame) + return 0; + + FrameLoaderClientEfl* client = static_cast<FrameLoaderClientEfl*>(frame->loader()->client()); + return client ? client->webFrame() : 0; +} + +namespace WebCore { + +ChromeClientEfl::ChromeClientEfl(Evas_Object* view) + : m_view(view) +{ +} + +ChromeClientEfl::~ChromeClientEfl() +{ +} + +void ChromeClientEfl::chromeDestroyed() +{ + delete this; +} + +void ChromeClientEfl::focusedNodeChanged(Node*) +{ + notImplemented(); +} + +void ChromeClientEfl::focusedFrameChanged(Frame*) +{ +} + +FloatRect ChromeClientEfl::windowRect() +{ + Ecore_Evas* ee = 0; + int x, y, w, h; + + if (!m_view) + return FloatRect(); + + ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view)); + ecore_evas_geometry_get(ee, &x, &y, &w, &h); + return FloatRect(x, y, w, h); +} + +void ChromeClientEfl::setWindowRect(const FloatRect& rect) +{ + Ecore_Evas* ee = 0; + IntRect intrect = IntRect(rect); + + if (!m_view) + return; + + if (!ewk_view_setting_enable_auto_resize_window_get(m_view)) + return; + + ee = ecore_evas_ecore_evas_get(evas_object_evas_get(m_view)); + ecore_evas_move(ee, intrect.x(), intrect.y()); + ecore_evas_resize(ee, intrect.width(), intrect.height()); +} + +FloatRect ChromeClientEfl::pageRect() +{ + if (!m_view) + return FloatRect(); + + return ewk_view_page_rect_get(m_view); +} + +float ChromeClientEfl::scaleFactor() +{ + notImplemented(); + return 1.0; +} + +void ChromeClientEfl::focus() +{ + evas_object_focus_set(m_view, EINA_TRUE); +} + +void ChromeClientEfl::unfocus() +{ + evas_object_focus_set(m_view, EINA_FALSE); +} + +Page* ChromeClientEfl::createWindow(Frame*, const FrameLoadRequest& frameLoadRequest, const WindowFeatures& features, const NavigationAction&) +{ + Evas_Object* newView = ewk_view_window_create(m_view, EINA_TRUE, &features); + if (!newView) + return 0; + + return ewk_view_core_page_get(newView); +} + +void ChromeClientEfl::show() +{ + ewk_view_ready(m_view); +} + +bool ChromeClientEfl::canRunModal() +{ + notImplemented(); + return false; +} + +void ChromeClientEfl::runModal() +{ + notImplemented(); +} + +void ChromeClientEfl::setToolbarsVisible(bool visible) +{ + ewk_view_toolbars_visible_set(m_view, visible); +} + +bool ChromeClientEfl::toolbarsVisible() +{ + Eina_Bool visible; + + ewk_view_toolbars_visible_get(m_view, &visible); + return visible; +} + +void ChromeClientEfl::setStatusbarVisible(bool visible) +{ + ewk_view_statusbar_visible_set(m_view, visible); +} + +bool ChromeClientEfl::statusbarVisible() +{ + Eina_Bool visible; + + ewk_view_statusbar_visible_get(m_view, &visible); + return visible; +} + +void ChromeClientEfl::setScrollbarsVisible(bool visible) +{ + ewk_view_scrollbars_visible_set(m_view, visible); +} + +bool ChromeClientEfl::scrollbarsVisible() +{ + Eina_Bool visible; + + ewk_view_scrollbars_visible_get(m_view, &visible); + return visible; +} + +void ChromeClientEfl::setMenubarVisible(bool visible) +{ + ewk_view_menubar_visible_set(m_view, visible); +} + +bool ChromeClientEfl::menubarVisible() +{ + Eina_Bool visible; + + ewk_view_menubar_visible_get(m_view, &visible); + return visible; +} + +void ChromeClientEfl::createSelectPopup(PopupMenuClient* client, int selected, const IntRect& rect) +{ + ewk_view_popup_new(m_view, client, selected, rect); +} + +bool ChromeClientEfl::destroySelectPopup() +{ + return ewk_view_popup_destroy(m_view); +} + +void ChromeClientEfl::setResizable(bool) +{ + notImplemented(); +} + +void ChromeClientEfl::closeWindowSoon() +{ + ewk_view_window_close(m_view); +} + +bool ChromeClientEfl::canTakeFocus(FocusDirection) +{ + // This is called when cycling through links/focusable objects and we + // reach the last focusable object. + return false; +} + +void ChromeClientEfl::takeFocus(FocusDirection) +{ + unfocus(); +} + +bool ChromeClientEfl::canRunBeforeUnloadConfirmPanel() +{ + return true; +} + +bool ChromeClientEfl::runBeforeUnloadConfirmPanel(const String& message, Frame* frame) +{ + return runJavaScriptConfirm(frame, message); +} + +void ChromeClientEfl::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, + unsigned int lineNumber, const String& sourceID) +{ + ewk_view_add_console_message(m_view, message.utf8().data(), lineNumber, sourceID.utf8().data()); +} + +void ChromeClientEfl::runJavaScriptAlert(Frame* frame, const String& message) +{ + ewk_view_run_javascript_alert(m_view, kit(frame), message.utf8().data()); +} + +bool ChromeClientEfl::runJavaScriptConfirm(Frame* frame, const String& message) +{ + return ewk_view_run_javascript_confirm(m_view, kit(frame), message.utf8().data()); +} + +bool ChromeClientEfl::runJavaScriptPrompt(Frame* frame, const String& message, const String& defaultValue, String& result) +{ + char* value = 0; + ewk_view_run_javascript_prompt(m_view, kit(frame), message.utf8().data(), defaultValue.utf8().data(), &value); + if (value) { + result = String::fromUTF8(value); + free(value); + return true; + } + return false; +} + +void ChromeClientEfl::setStatusbarText(const String& string) +{ + ewk_view_statusbar_text_set(m_view, string.utf8().data()); +} + +bool ChromeClientEfl::shouldInterruptJavaScript() +{ + return ewk_view_should_interrupt_javascript(m_view); +} + +bool ChromeClientEfl::tabsToLinks() const +{ + return true; +} + +IntRect ChromeClientEfl::windowResizerRect() const +{ + notImplemented(); + // Implementing this function will make repaint being + // called during resize, but as this will be done with + // a minor delay it adds a weird "filling" effect due + // to us using an evas image for showing the cairo + // context. So instead of implementing this function + // we call paint directly during resize with + // the new object size as its argument. + return IntRect(); +} + +void ChromeClientEfl::contentsSizeChanged(Frame* frame, const IntSize& size) const +{ + ewk_frame_contents_size_changed(kit(frame), size.width(), size.height()); + if (ewk_view_frame_main_get(m_view) == kit(frame)) + ewk_view_contents_size_changed(m_view, size.width(), size.height()); +} + +IntRect ChromeClientEfl::windowToScreen(const IntRect& rect) const +{ + notImplemented(); + return rect; +} + +IntPoint ChromeClientEfl::screenToWindow(const IntPoint& point) const +{ + notImplemented(); + return point; +} + +PlatformPageClient ChromeClientEfl::platformPageClient() const +{ + return m_view; +} + +void ChromeClientEfl::scrollbarsModeDidChange() const +{ +} + +void ChromeClientEfl::mouseDidMoveOverElement(const HitTestResult& hit, unsigned modifierFlags) +{ + // FIXME, compare with old link, look at Qt impl. + bool isLink = hit.isLiveLink(); + if (isLink) { + KURL url = hit.absoluteLinkURL(); + if (!url.isEmpty() && url != m_hoveredLinkURL) { + const char* link[2]; + TextDirection dir; + CString urlStr = url.prettyURL().utf8(); + CString titleStr = hit.title(dir).utf8(); + link[0] = urlStr.data(); + link[1] = titleStr.data(); + ewk_view_mouse_link_hover_in(m_view, link); + m_hoveredLinkURL = url; + } + } else if (!isLink && !m_hoveredLinkURL.isEmpty()) { + ewk_view_mouse_link_hover_out(m_view); + m_hoveredLinkURL = KURL(); + } +} + +void ChromeClientEfl::setToolTip(const String& toolTip, TextDirection) +{ + ewk_view_tooltip_text_set(m_view, toolTip.utf8().data()); +} + +void ChromeClientEfl::print(Frame* frame) +{ + notImplemented(); +} + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) +void ChromeClientEfl::reachedMaxAppCacheSize(int64_t spaceNeeded) +{ + // FIXME: Free some space. + notImplemented(); +} + +void ChromeClientEfl::reachedApplicationCacheOriginQuota(SecurityOrigin*) +{ + notImplemented(); +} +#endif + +#if ENABLE(DATABASE) +void ChromeClientEfl::exceededDatabaseQuota(Frame* frame, const String& databaseName) +{ + uint64_t quota; + SecurityOrigin* origin = frame->document()->securityOrigin(); + + DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, origin); + quota = ewk_view_exceeded_database_quota(m_view, + kit(frame), databaseName.utf8().data(), + details.currentUsage(), details.expectedUsage()); + + /* if client did not set quota, and database is being created now, the + * default quota is applied + */ + if (!quota && !DatabaseTracker::tracker().hasEntryForOrigin(origin)) + quota = ewk_settings_web_database_default_quota_get(); + + DatabaseTracker::tracker().setQuota(origin, quota); +} +#endif + +void ChromeClientEfl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser) +{ + RefPtr<FileChooser> chooser = prpFileChooser; + bool confirm; + Eina_List* selectedFilenames = 0; + Eina_List* suggestedFilenames = 0; + void* filename; + Vector<String> filenames; + + for (unsigned i = 0; i < chooser->filenames().size(); i++) { + CString str = chooser->filenames()[i].utf8(); + filename = strdup(str.data()); + suggestedFilenames = eina_list_append(suggestedFilenames, filename); + } + + confirm = ewk_view_run_open_panel(m_view, kit(frame), chooser->allowsMultipleFiles(), suggestedFilenames, &selectedFilenames); + EINA_LIST_FREE(suggestedFilenames, filename) + free(filename); + + if (!confirm) + return; + + EINA_LIST_FREE(selectedFilenames, filename) { + filenames.append((char *)filename); + free(filename); + } + + if (chooser->allowsMultipleFiles()) + chooser->chooseFiles(filenames); + else + chooser->chooseFile(filenames[0]); +} + +void ChromeClientEfl::formStateDidChange(const Node*) +{ + notImplemented(); +} + +void ChromeClientEfl::setCursor(const Cursor&) +{ + notImplemented(); +} + +void ChromeClientEfl::requestGeolocationPermissionForFrame(Frame*, Geolocation*) +{ + // See the comment in WebCore/page/ChromeClient.h + notImplemented(); +} + +void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) +{ + notImplemented(); +} + +void ChromeClientEfl::cancelGeolocationPermissionForFrame(Frame*, Geolocation*) +{ + notImplemented(); +} + +void ChromeClientEfl::invalidateContents(const IntRect& updateRect, bool immediate) +{ + notImplemented(); +} + +void ChromeClientEfl::invalidateWindow(const IntRect& updateRect, bool immediate) +{ + notImplemented(); +} + +void ChromeClientEfl::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate) +{ + Evas_Coord x, y, w, h; + + x = updateRect.x(); + y = updateRect.y(); + w = updateRect.width(); + h = updateRect.height(); + ewk_view_repaint(m_view, x, y, w, h); +} + +void ChromeClientEfl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + invalidateContentsAndWindow(updateRect, immediate); +} + +void ChromeClientEfl::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) +{ + ewk_view_scroll(m_view, scrollDelta.width(), scrollDelta.height(), rectToScroll.x(), rectToScroll.y(), rectToScroll.width(), rectToScroll.height(), clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height(), EINA_TRUE); +} + +void ChromeClientEfl::cancelGeolocationPermissionRequestForFrame(Frame*) +{ + notImplemented(); +} + +void ChromeClientEfl::iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>) +{ + notImplemented(); +} + +void ChromeClientEfl::chooseIconForFiles(const Vector<String>&, FileChooser*) +{ + notImplemented(); +} + +void ChromeClientEfl::dispatchViewportDataDidChange(const ViewportArguments& arguments) const +{ + ewk_view_viewport_attributes_set(m_view, arguments); +} + +bool ChromeClientEfl::selectItemWritingDirectionIsNatural() +{ + return true; +} + +PassRefPtr<PopupMenu> ChromeClientEfl::createPopupMenu(PopupMenuClient* client) const +{ + return adoptRef(new PopupMenuEfl(client)); +} + +PassRefPtr<SearchPopupMenu> ChromeClientEfl::createSearchPopupMenu(PopupMenuClient* client) const +{ + return adoptRef(new SearchPopupMenuEfl(client)); +} + +} diff --git a/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h new file mode 100644 index 0000000..a714dd4 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/ChromeClientEfl.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ChromeClientEfl_h +#define ChromeClientEfl_h + +#include "ChromeClient.h" +#include "KURL.h" +#include "PopupMenu.h" + +typedef struct _Evas_Object Evas_Object; + +namespace WebCore { + +class ChromeClientEfl : public ChromeClient { +public: + explicit ChromeClientEfl(Evas_Object* view); + virtual ~ChromeClientEfl(); + + virtual void chromeDestroyed(); + + virtual void setWindowRect(const FloatRect&); + virtual FloatRect windowRect(); + + virtual FloatRect pageRect(); + + virtual float scaleFactor(); + + virtual void focus(); + virtual void unfocus(); + + virtual bool canTakeFocus(FocusDirection); + virtual void takeFocus(FocusDirection); + + virtual void focusedNodeChanged(Node*); + virtual void focusedFrameChanged(Frame*); + + virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); + virtual void show(); + + virtual bool canRunModal(); + virtual void runModal(); + + virtual void setToolbarsVisible(bool); + virtual bool toolbarsVisible(); + + virtual void setStatusbarVisible(bool); + virtual bool statusbarVisible(); + + virtual void setScrollbarsVisible(bool); + virtual bool scrollbarsVisible(); + + virtual void setMenubarVisible(bool); + virtual bool menubarVisible(); + + virtual void createSelectPopup(PopupMenuClient*, int selected, const IntRect& rect); + virtual bool destroySelectPopup(); + + virtual void setResizable(bool); + + virtual void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, + unsigned int lineNumber, const String& sourceID); + + virtual bool canRunBeforeUnloadConfirmPanel(); + virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame); + + virtual void closeWindowSoon(); + + virtual void runJavaScriptAlert(Frame*, const String&); + virtual bool runJavaScriptConfirm(Frame*, const String&); + virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result); + virtual void setStatusbarText(const String&); + virtual bool shouldInterruptJavaScript(); + virtual bool tabsToLinks() const; + + virtual IntRect windowResizerRect() const; + + virtual void contentsSizeChanged(Frame*, const IntSize&) const; + virtual IntPoint screenToWindow(const IntPoint&) const; + virtual IntRect windowToScreen(const IntRect&) const; + virtual PlatformPageClient platformPageClient() const; + + virtual void scrollbarsModeDidChange() const; + virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); + + virtual void setToolTip(const String&, TextDirection); + + virtual void print(Frame*); + +#if ENABLE(DATABASE) + virtual void exceededDatabaseQuota(Frame*, const String&); +#endif + +#if ENABLE(OFFLINE_WEB_APPLICATIONS) + virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); + virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*); +#endif + +#if ENABLE(CONTEXT_MENUS) + virtual void showContextMenu() { } +#endif + +#if ENABLE(TOUCH_EVENTS) + virtual void needTouchEvents(bool) { } +#endif + + virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); + virtual void chooseIconForFiles(const Vector<String>&, FileChooser*); + virtual void formStateDidChange(const Node*); + + virtual PassOwnPtr<HTMLParserQuirks> createHTMLParserQuirks() { return 0; } + + virtual void setCursor(const Cursor&); + + virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const {} + + virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*); + virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*); + virtual void cancelGeolocationPermissionForFrame(Frame*, Geolocation*); + + virtual void invalidateContents(const IntRect&, bool); + virtual void invalidateWindow(const IntRect&, bool); + virtual void invalidateContentsAndWindow(const IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const IntRect&, bool); + virtual void scroll(const IntSize&, const IntRect&, const IntRect&); + virtual void cancelGeolocationPermissionRequestForFrame(Frame*); + virtual void iconForFiles(const Vector<String, 0u>&, PassRefPtr<FileChooser>); + + virtual void dispatchViewportDataDidChange(const ViewportArguments&) const; + + virtual bool selectItemWritingDirectionIsNatural(); + virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const; + virtual PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const; + + Evas_Object* m_view; + KURL m_hoveredLinkURL; +}; +} + +#endif // ChromeClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/DragClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/DragClientEfl.cpp new file mode 100644 index 0000000..d6610e1 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/DragClientEfl.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DragClientEfl.h" + +#include "NotImplemented.h" + +using namespace WebCore; + +namespace WebCore { + +void DragClientEfl::willPerformDragDestinationAction(DragDestinationAction, DragData*) +{ + notImplemented(); +} + +void DragClientEfl::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) +{ + notImplemented(); +} + +DragDestinationAction DragClientEfl::actionMaskForDrag(DragData*) +{ + return DragDestinationActionAny; +} + +DragSourceAction DragClientEfl::dragSourceActionMaskForPoint(const IntPoint&) +{ + return DragSourceActionAny; +} + +void DragClientEfl::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) +{ + notImplemented(); +} + +DragImageRef DragClientEfl::createDragImageForLink(KURL&, const String& label, Frame*) +{ + return 0; +} + +void DragClientEfl::dragControllerDestroyed() +{ + delete this; +} + +} diff --git a/Source/WebKit/efl/WebCoreSupport/DragClientEfl.h b/Source/WebKit/efl/WebCoreSupport/DragClientEfl.h new file mode 100644 index 0000000..f73116c --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/DragClientEfl.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Holger Hans Peter Freyther + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DragClientEfl_h +#define DragClientEfl_h + +#include "DragClient.h" + +namespace WebCore { +class DragClientEfl : public WebCore::DragClient { +public: + virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*); + virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*); + virtual WebCore::DragDestinationAction actionMaskForDrag(WebCore::DragData*); + + virtual WebCore::DragSourceAction dragSourceActionMaskForPoint(const WebCore::IntPoint& windowPoint); + + virtual void startDrag(WebCore::DragImageRef dragImage, const WebCore::IntPoint& dragImageOrigin, const WebCore::IntPoint& eventPos, WebCore::Clipboard*, WebCore::Frame*, bool linkDrag = false); + virtual WebCore::DragImageRef createDragImageForLink(WebCore::KURL&, const WTF::String& label, WebCore::Frame*); + + virtual void dragControllerDestroyed(); +}; +} + +#endif // DragClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp new file mode 100644 index 0000000..a9e45dd --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Nuanti Ltd. + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "EditorClientEfl.h" + +#include "EWebKit.h" +#include "EditCommand.h" +#include "Editor.h" +#include "EventNames.h" +#include "FocusController.h" +#include "Frame.h" +#include "KeyboardEvent.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PlatformKeyboardEvent.h" +#include "WindowsKeyboardCodes.h" +#include "ewk_private.h" + +using namespace WebCore; + +namespace WebCore { + +void EditorClientEfl::willSetInputMethodState() +{ + notImplemented(); +} + +void EditorClientEfl::setInputMethodState(bool active) +{ + ewk_view_input_method_state_set(m_view, active); +} + +bool EditorClientEfl::shouldDeleteRange(Range*) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldShowDeleteInterface(HTMLElement*) +{ + return false; +} + +bool EditorClientEfl::isContinuousSpellCheckingEnabled() +{ + notImplemented(); + return false; +} + +bool EditorClientEfl::isGrammarCheckingEnabled() +{ + notImplemented(); + return false; +} + +int EditorClientEfl::spellCheckerDocumentTag() +{ + notImplemented(); + return 0; +} + +bool EditorClientEfl::shouldBeginEditing(Range*) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldEndEditing(Range*) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldInsertText(const String&, Range*, EditorInsertAction) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldChangeSelectedRange(Range*, Range*, EAffinity, bool) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldApplyStyle(CSSStyleDeclaration*, Range*) +{ + notImplemented(); + return true; +} + +bool EditorClientEfl::shouldMoveRangeAfterDelete(Range*, Range*) +{ + notImplemented(); + return true; +} + +void EditorClientEfl::didBeginEditing() +{ + notImplemented(); +} + +void EditorClientEfl::respondToChangedContents() +{ + notImplemented(); +} + +void EditorClientEfl::respondToChangedSelection() +{ + notImplemented(); +} + +void EditorClientEfl::didEndEditing() +{ + notImplemented(); +} + +void EditorClientEfl::didWriteSelectionToPasteboard() +{ + notImplemented(); +} + +void EditorClientEfl::didSetSelectionTypesForPasteboard() +{ + notImplemented(); +} + +bool EditorClientEfl::isEditable() +{ + notImplemented(); + return false; +} + +void EditorClientEfl::registerCommandForUndo(WTF::PassRefPtr<EditCommand>) +{ + notImplemented(); +} + +void EditorClientEfl::registerCommandForRedo(WTF::PassRefPtr<EditCommand>) +{ + notImplemented(); +} + +void EditorClientEfl::clearUndoRedoOperations() +{ + notImplemented(); +} + +bool EditorClientEfl::canUndo() const +{ + notImplemented(); + return false; +} + +bool EditorClientEfl::canRedo() const +{ + notImplemented(); + return false; +} + +void EditorClientEfl::undo() +{ + notImplemented(); +} + +void EditorClientEfl::redo() +{ + notImplemented(); +} + +bool EditorClientEfl::shouldInsertNode(Node*, Range*, EditorInsertAction) +{ + notImplemented(); + return true; +} + +void EditorClientEfl::pageDestroyed() +{ + delete this; +} + +bool EditorClientEfl::smartInsertDeleteEnabled() +{ + notImplemented(); + return false; +} + +bool EditorClientEfl::isSelectTrailingWhitespaceEnabled() +{ + notImplemented(); + return false; +} + +void EditorClientEfl::toggleContinuousSpellChecking() +{ + notImplemented(); +} + +void EditorClientEfl::toggleGrammarChecking() +{ + notImplemented(); +} + +static const unsigned CtrlKey = 1 << 0; +static const unsigned AltKey = 1 << 1; +static const unsigned ShiftKey = 1 << 2; + +struct KeyDownEntry { + unsigned virtualKey; + unsigned modifiers; + const char* name; +}; + +struct KeyPressEntry { + unsigned charCode; + unsigned modifiers; + const char* name; +}; + +static const KeyDownEntry keyDownEntries[] = { + { VK_LEFT, 0, "MoveLeft" }, + { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" }, + { VK_LEFT, CtrlKey, "MoveWordLeft" }, + { VK_LEFT, CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection" }, + { VK_RIGHT, 0, "MoveRight" }, + { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" }, + { VK_RIGHT, CtrlKey, "MoveWordRight" }, + { VK_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" }, + { VK_UP, 0, "MoveUp" }, + { VK_UP, ShiftKey, "MoveUpAndModifySelection" }, + { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" }, + { VK_DOWN, 0, "MoveDown" }, + { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" }, + { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, + { VK_PRIOR, 0, "MovePageUp" }, + { VK_NEXT, 0, "MovePageDown" }, + { VK_HOME, 0, "MoveToBeginningOfLine" }, + { VK_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, + { VK_HOME, CtrlKey, "MoveToBeginningOfDocument" }, + { VK_HOME, CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" }, + + { VK_END, 0, "MoveToEndOfLine" }, + { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" }, + { VK_END, CtrlKey, "MoveToEndOfDocument" }, + { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" }, + + { VK_BACK, 0, "DeleteBackward" }, + { VK_BACK, ShiftKey, "DeleteBackward" }, + { VK_DELETE, 0, "DeleteForward" }, + { VK_BACK, CtrlKey, "DeleteWordBackward" }, + { VK_DELETE, CtrlKey, "DeleteWordForward" }, + + { 'B', CtrlKey, "ToggleBold" }, + { 'I', CtrlKey, "ToggleItalic" }, + + { VK_ESCAPE, 0, "Cancel" }, + { VK_OEM_PERIOD, CtrlKey, "Cancel" }, + { VK_TAB, 0, "InsertTab" }, + { VK_TAB, ShiftKey, "InsertBacktab" }, + { VK_RETURN, 0, "InsertNewline" }, + { VK_RETURN, CtrlKey, "InsertNewline" }, + { VK_RETURN, AltKey, "InsertNewline" }, + { VK_RETURN, AltKey | ShiftKey, "InsertNewline" }, +}; + +static const KeyPressEntry keyPressEntries[] = { + { '\t', 0, "InsertTab" }, + { '\t', ShiftKey, "InsertBacktab" }, + { '\r', 0, "InsertNewline" }, + { '\r', CtrlKey, "InsertNewline" }, + { '\r', AltKey, "InsertNewline" }, + { '\r', AltKey | ShiftKey, "InsertNewline" }, +}; + +const char* EditorClientEfl::interpretKeyEvent(const KeyboardEvent* event) +{ + ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent); + + static HashMap<int, const char*>* keyDownCommandsMap = 0; + static HashMap<int, const char*>* keyPressCommandsMap = 0; + + if (!keyDownCommandsMap) { + keyDownCommandsMap = new HashMap<int, const char*>; + keyPressCommandsMap = new HashMap<int, const char*>; + + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i) + keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name); + + for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i) + keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name); + } + + unsigned modifiers = 0; + if (event->shiftKey()) + modifiers |= ShiftKey; + if (event->altKey()) + modifiers |= AltKey; + if (event->ctrlKey()) + modifiers |= CtrlKey; + + if (event->type() == eventNames().keydownEvent) { + int mapKey = modifiers << 16 | event->keyCode(); + return mapKey ? keyDownCommandsMap->get(mapKey) : 0; + } + + int mapKey = modifiers << 16 | event->charCode(); + return mapKey ? keyPressCommandsMap->get(mapKey) : 0; +} + +bool EditorClientEfl::handleEditingKeyboardEvent(KeyboardEvent* event) +{ + Node* node = event->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* keyEvent = event->keyEvent(); + if (!keyEvent) + return false; + + bool caretBrowsing = frame->settings()->caretBrowsingEnabled(); + if (caretBrowsing) { + switch (keyEvent->windowsVirtualKeyCode()) { + case VK_LEFT: + frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove, + DirectionLeft, + keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, + true); + return true; + case VK_RIGHT: + frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove, + DirectionRight, + keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity, + true); + return true; + case VK_UP: + frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove, + DirectionBackward, + keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, + true); + return true; + case VK_DOWN: + frame->selection()->modify(keyEvent->shiftKey() ? SelectionController::AlterationExtend : SelectionController::AlterationMove, + DirectionForward, + keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity, + true); + return true; + } + } + + Editor::Command command = frame->editor()->command(interpretKeyEvent(event)); + + if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) { + // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated, + // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated + // (e.g. Tab that inserts a Tab character, or Enter). + return !command.isTextInsertion() && command.execute(event); + } + + if (command.execute(event)) + return true; + + // Don't insert null or control characters as they can result in unexpected behaviour + if (event->charCode() < ' ') + return false; + + // Don't insert anything if a modifier is pressed + if (keyEvent->ctrlKey() || keyEvent->altKey()) + return false; + + return frame->editor()->insertText(event->keyEvent()->text(), event); +} + +void EditorClientEfl::handleKeyboardEvent(KeyboardEvent* event) +{ + if (handleEditingKeyboardEvent(event)) + event->setDefaultHandled(); +} + +void EditorClientEfl::handleInputMethodKeydown(KeyboardEvent* event) +{ +} + +EditorClientEfl::EditorClientEfl(Evas_Object *view) + : m_view(view) +{ + notImplemented(); +} + +EditorClientEfl::~EditorClientEfl() +{ + notImplemented(); +} + +void EditorClientEfl::textFieldDidBeginEditing(Element*) +{ +} + +void EditorClientEfl::textFieldDidEndEditing(Element*) +{ + notImplemented(); +} + +void EditorClientEfl::textDidChangeInTextField(Element*) +{ + notImplemented(); +} + +bool EditorClientEfl::doTextFieldCommandFromEvent(Element*, KeyboardEvent*) +{ + return false; +} + +void EditorClientEfl::textWillBeDeletedInTextField(Element*) +{ + notImplemented(); +} + +void EditorClientEfl::textDidChangeInTextArea(Element*) +{ + notImplemented(); +} + +void EditorClientEfl::ignoreWordInSpellDocument(const String&) +{ + notImplemented(); +} + +void EditorClientEfl::learnWord(const String&) +{ + notImplemented(); +} + +void EditorClientEfl::checkSpellingOfString(const UChar*, int, int*, int*) +{ + notImplemented(); +} + +String EditorClientEfl::getAutoCorrectSuggestionForMisspelledWord(const String&) +{ + notImplemented(); + return String(); +} + +void EditorClientEfl::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) +{ + notImplemented(); +} + +void EditorClientEfl::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) +{ + notImplemented(); +} + +void EditorClientEfl::updateSpellingUIWithMisspelledWord(const String&) +{ + notImplemented(); +} + +void EditorClientEfl::showSpellingUI(bool) +{ + notImplemented(); +} + +bool EditorClientEfl::spellingUIIsShowing() +{ + notImplemented(); + return false; +} + +void EditorClientEfl::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h new file mode 100644 index 0000000..e25b1e6 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EditorClientEfl_h +#define EditorClientEfl_h + +#include "EditorClient.h" + +#include <wtf/Forward.h> + +typedef struct _Evas_Object Evas_Object; + +namespace WebCore { +class Page; + +class EditorClientEfl : public EditorClient { +public: + EditorClientEfl(Evas_Object *view); + ~EditorClientEfl(); + + // from EditorClient + virtual void pageDestroyed(); + + virtual bool shouldDeleteRange(Range*); + virtual bool shouldShowDeleteInterface(HTMLElement*); + virtual bool smartInsertDeleteEnabled(); + virtual bool isSelectTrailingWhitespaceEnabled(); + virtual bool isContinuousSpellCheckingEnabled(); + virtual void toggleContinuousSpellChecking(); + virtual bool isGrammarCheckingEnabled(); + virtual void toggleGrammarChecking(); + virtual int spellCheckerDocumentTag(); + + virtual bool isEditable(); + + virtual bool shouldBeginEditing(Range*); + virtual bool shouldEndEditing(Range*); + virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction); + virtual bool shouldInsertText(const String&, Range*, EditorInsertAction); + virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting); + + virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*); + + virtual bool shouldMoveRangeAfterDelete(Range*, Range*); + + virtual void didBeginEditing(); + virtual void respondToChangedContents(); + virtual void respondToChangedSelection(); + virtual void didEndEditing(); + virtual void didWriteSelectionToPasteboard(); + virtual void didSetSelectionTypesForPasteboard(); + + virtual void registerCommandForUndo(WTF::PassRefPtr<EditCommand>); + virtual void registerCommandForRedo(WTF::PassRefPtr<EditCommand>); + virtual void clearUndoRedoOperations(); + + virtual bool canUndo() const; + virtual bool canRedo() const; + + virtual void undo(); + virtual void redo(); + + virtual const char* interpretKeyEvent(const KeyboardEvent* event); + virtual bool handleEditingKeyboardEvent(KeyboardEvent*); + virtual void handleKeyboardEvent(KeyboardEvent*); + virtual void handleInputMethodKeydown(KeyboardEvent*); + + virtual void textFieldDidBeginEditing(Element*); + virtual void textFieldDidEndEditing(Element*); + virtual void textDidChangeInTextField(Element*); + virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*); + virtual void textWillBeDeletedInTextField(Element*); + virtual void textDidChangeInTextArea(Element*); + + virtual void ignoreWordInSpellDocument(const String&); + virtual void learnWord(const String&); + virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength); + virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord); + virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); + virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&); + virtual void updateSpellingUIWithMisspelledWord(const String&); + virtual void showSpellingUI(bool show); + virtual bool spellingUIIsShowing(); + virtual void getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses); + virtual void willSetInputMethodState(); + virtual void setInputMethodState(bool enabled); + virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) {} + +private: + Evas_Object *m_view; +}; +} + +#endif // EditorClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp new file mode 100644 index 0000000..929b269 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.cpp @@ -0,0 +1,943 @@ +/* + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2008 Collabora Ltd. All rights reserved. + * Copyright (C) 2008 Holger Hans Peter Freyther + * Copyright (C) 2008 Kenneth Rohde Christiansen + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "FrameLoaderClientEfl.h" + +#include "DocumentLoader.h" +#include "EWebKit.h" +#include "FormState.h" +#include "FrameLoader.h" +#include "FrameNetworkingContextEfl.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "HTMLFormElement.h" +#include "Language.h" +#include "MIMETypeRegistry.h" +#include "NotImplemented.h" +#include "Page.h" +#include "PluginDatabase.h" +#include "ProgressTracker.h" +#include "RenderPart.h" +#include "ResourceRequest.h" +#include "ViewportArguments.h" +#include "ewk_private.h" +#include <wtf/text/CString.h> +#include <wtf/text/StringConcatenate.h> + +#if PLATFORM(UNIX) +#include <sys/utsname.h> +#endif + +#include <Ecore_Evas.h> + +using namespace WebCore; + +namespace WebCore { + +FrameLoaderClientEfl::FrameLoaderClientEfl(Evas_Object *view) + : m_view(view) + , m_frame(0) + , m_userAgent("") + , m_customUserAgent("") + , m_pluginView(0) + , m_hasSentResponseToPlugin(false) +{ +} + +static String agentPlatform() +{ + notImplemented(); + return "Unknown"; +} + +static String agentOS() +{ +#if PLATFORM(DARWIN) +#if PLATFORM(X86) + return "Intel Mac OS X"; +#else + return "PPC Mac OS X"; +#endif +#elif PLATFORM(UNIX) + struct utsname name; + if (uname(&name) != -1) + return makeString(name.sysname, ' ', name.machine); + + return "Unknown"; +#elif PLATFORM(WIN_OS) + // FIXME: Compute the Windows version + return "Windows"; +#else + notImplemented(); + return "Unknown"; +#endif +} + +static String composeUserAgent() +{ + // This is a liberal interpretation of http://www.mozilla.org/build/revised-user-agent-strings.html + // See also http://developer.apple.com/internet/safari/faq.html#anchor2 + + String ua; + + // Product + ua += "Mozilla/5.0"; + + // Comment + ua += " ("; + ua += agentPlatform(); // Platform + ua += "; U; "; // Security + ua += agentOS(); // OS-or-CPU + ua += "; "; + ua += defaultLanguage(); // Localization information + ua += ") "; + + // WebKit Product + // FIXME: The WebKit version is hardcoded + static const String webKitVersion = "525.1+"; + ua += "AppleWebKit/" + webKitVersion; + ua += " (KHTML, like Gecko, "; + // We mention Safari since many broken sites check for it (OmniWeb does this too) + // We re-use the WebKit version, though it doesn't seem to matter much in practice + ua += "Safari/" + webKitVersion; + ua += ") "; + + // Vendor Product + // ua += g_get_prgname(); + + return ua; +} + +void FrameLoaderClientEfl::setCustomUserAgent(const String &agent) +{ + m_customUserAgent = agent; +} + +const String& FrameLoaderClientEfl::customUserAgent() const +{ + return m_customUserAgent; +} + +String FrameLoaderClientEfl::userAgent(const KURL&) +{ + if (!m_customUserAgent.isEmpty()) + return m_customUserAgent; + + if (m_userAgent.isEmpty()) + m_userAgent = composeUserAgent(); + return m_userAgent; +} + +void FrameLoaderClientEfl::callPolicyFunction(FramePolicyFunction function, PolicyAction action) +{ + Frame* f = ewk_frame_core_get(m_frame); + ASSERT(f); + (f->loader()->policyChecker()->*function)(action); +} + +WTF::PassRefPtr<DocumentLoader> FrameLoaderClientEfl::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) +{ + RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData); + if (substituteData.isValid()) + loader->setDeferMainResourceDataLoad(false); + return loader.release(); +} + +void FrameLoaderClientEfl::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState>) +{ + // FIXME: This is surely too simple + ASSERT(function); + callPolicyFunction(function, PolicyUse); +} + +void FrameLoaderClientEfl::committedLoad(DocumentLoader* loader, const char* data, int length) +{ + if (!m_pluginView) + loader->commitData(data, length); + + // We re-check here as the plugin can have been created + if (m_pluginView) { + if (!m_hasSentResponseToPlugin) { + m_pluginView->didReceiveResponse(loader->response()); + m_hasSentResponseToPlugin = true; + } + m_pluginView->didReceiveData(data, length); + } +} + +void FrameLoaderClientEfl::dispatchDidReplaceStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidPushStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidPopStateWithinPage() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidChangeBackForwardIndex() const +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& coreRequest, const ResourceResponse& coreResponse) +{ + CString url = coreRequest.url().prettyURL().utf8(); + DBG("Resource url=%s", url.data()); + + Ewk_Frame_Resource_Request request = { 0, identifier }; + Ewk_Frame_Resource_Request orig = request; /* Initialize const fields. */ + + orig.url = request.url = url.data(); + + ewk_frame_request_will_send(m_frame, &request); + + if (request.url != orig.url) { + coreRequest.setURL(KURL(KURL(), request.url)); + + // Calling client might have changed our url pointer. + // Free the new allocated string. + free(const_cast<char*>(request.url)); + } +} + +bool FrameLoaderClientEfl::shouldUseCredentialStorage(DocumentLoader*, unsigned long) +{ + notImplemented(); + return false; +} + +void FrameLoaderClientEfl::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest& coreRequest) +{ + CString url = coreRequest.url().prettyURL().utf8(); + DBG("Resource url=%s", url.data()); + + Ewk_Frame_Resource_Request request = { 0, identifier }; + ewk_frame_request_assign_identifier(m_frame, &request); +} + +void FrameLoaderClientEfl::postProgressStartedNotification() +{ + ewk_frame_load_started(m_frame); + postProgressEstimateChangedNotification(); +} + +void FrameLoaderClientEfl::postProgressEstimateChangedNotification() +{ + ewk_frame_load_progress_changed(m_frame); +} + +void FrameLoaderClientEfl::postProgressFinishedNotification() +{ + if (m_loadError.isNull()) + ewk_frame_load_finished(m_frame, 0, 0, 0, 0, 0); + else { + ewk_frame_load_finished(m_frame, + m_loadError.domain().utf8().data(), + m_loadError.errorCode(), + m_loadError.isCancellation(), + m_loadError.localizedDescription().utf8().data(), + m_loadError.failingURL().utf8().data()); + } +} + +void FrameLoaderClientEfl::frameLoaderDestroyed() +{ + if (m_frame) + ewk_frame_core_gone(m_frame); + m_frame = 0; + + delete this; +} + +void FrameLoaderClientEfl::dispatchDidReceiveResponse(DocumentLoader*, unsigned long, const ResourceResponse& response) +{ + m_response = response; +} + +void FrameLoaderClientEfl::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& MIMEType, const ResourceRequest&) +{ + // we need to call directly here (currently callPolicyFunction does that!) + ASSERT(function); + if (canShowMIMEType(MIMEType)) + callPolicyFunction(function, PolicyUse); + else + callPolicyFunction(function, PolicyDownload); +} + +void FrameLoaderClientEfl::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest&, PassRefPtr<FormState>, const String&) +{ + ASSERT(function); + ASSERT(m_frame); + // if not acceptNavigationRequest - look at Qt -> PolicyIgnore; + // FIXME: do proper check and only reset forms when on PolicyIgnore + Frame* f = ewk_frame_core_get(m_frame); + f->loader()->resetMultipleFormSubmissionProtection(); + callPolicyFunction(function, PolicyUse); +} + +void FrameLoaderClientEfl::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>) +{ + ASSERT(function); + ASSERT(m_frame); + // if not acceptNavigationRequest - look at Qt -> PolicyIgnore; + // FIXME: do proper check and only reset forms when on PolicyIgnore + char* url = strdup(resourceRequest.url().prettyURL().utf8().data()); + Ewk_Frame_Resource_Request request = { url, 0 }; + Eina_Bool ret = ewk_view_navigation_policy_decision(m_view, &request); + free(url); + + PolicyAction policy; + if (!ret) + policy = PolicyIgnore; + else { + if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted) { + Frame* f = ewk_frame_core_get(m_frame); + f->loader()->resetMultipleFormSubmissionProtection(); + } + policy = PolicyUse; + } + callPolicyFunction(function, policy); +} + +PassRefPtr<Widget> FrameLoaderClientEfl::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) +{ + ASSERT(m_frame); + ASSERT(m_view); + + return ewk_view_plugin_create(m_view, m_frame, pluginSize, + element, url, paramNames, paramValues, + mimeType, loadManually); +} + +PassRefPtr<Frame> FrameLoaderClientEfl::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) +{ + ASSERT(m_frame); + ASSERT(m_view); + + return ewk_view_frame_create(m_view, m_frame, name, ownerElement, url, referrer); +} + +void FrameLoaderClientEfl::didTransferChildFrameToNewDocument(Page*) +{ +} + +void FrameLoaderClientEfl::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*) +{ +} + +void FrameLoaderClientEfl::redirectDataToPlugin(Widget* pluginWidget) +{ + ASSERT(!m_pluginView); + m_pluginView = static_cast<PluginView*>(pluginWidget); + m_hasSentResponseToPlugin = false; +} + +PassRefPtr<Widget> FrameLoaderClientEfl::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, + const Vector<String>& paramNames, const Vector<String>& paramValues) +{ + notImplemented(); + return 0; +} + +ObjectContentType FrameLoaderClientEfl::objectContentType(const KURL& url, const String& mimeType) +{ + if (url.isEmpty() && mimeType.isEmpty()) + return ObjectContentNone; + + // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure + String type = mimeType; + if (type.isEmpty()) + type = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1)); + + if (type.isEmpty()) + return ObjectContentFrame; + + if (MIMETypeRegistry::isSupportedImageMIMEType(type)) + return ObjectContentImage; + +#if 0 // PluginDatabase is disabled until we have Plugin system done. + if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType)) + return ObjectContentNetscapePlugin; +#endif + + if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) + return ObjectContentFrame; + + if (url.protocol() == "about") + return ObjectContentFrame; + + return ObjectContentNone; +} + +String FrameLoaderClientEfl::overrideMediaType() const +{ + notImplemented(); + return String(); +} + +void FrameLoaderClientEfl::windowObjectCleared() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::documentElementAvailable() +{ + return; +} + +void FrameLoaderClientEfl::didPerformFirstNavigation() const +{ + ewk_frame_did_perform_first_navigation(m_frame); +} + +void FrameLoaderClientEfl::registerForIconNotification(bool) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::setMainFrameDocumentReady(bool) +{ + // this is only interesting once we provide an external API for the DOM +} + +bool FrameLoaderClientEfl::hasWebView() const +{ + // notImplemented(); + return true; +} + +bool FrameLoaderClientEfl::hasFrameView() const +{ + notImplemented(); + return true; +} + +void FrameLoaderClientEfl::dispatchDidFinishLoad() +{ + m_loadError = ResourceError(); /* clears previous error */ +} + +void FrameLoaderClientEfl::frameLoadCompleted() +{ + // Note: Can be called multiple times. +} + +void FrameLoaderClientEfl::saveViewStateToItem(HistoryItem* item) +{ + ewk_frame_view_state_save(m_frame, item); +} + +void FrameLoaderClientEfl::restoreViewState() +{ + ASSERT(m_frame); + ASSERT(m_view); + + ewk_view_restore_state(m_view, m_frame); +} + +void FrameLoaderClientEfl::updateGlobalHistoryRedirectLinks() +{ +} + +bool FrameLoaderClientEfl::shouldGoToHistoryItem(HistoryItem* item) const +{ + // FIXME: This is a very simple implementation. More sophisticated + // implementation would delegate the decision to a PolicyDelegate. + // See mac implementation for example. + return item; +} + +void FrameLoaderClientEfl::didDisplayInsecureContent() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::didRunInsecureContent(SecurityOrigin*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::makeRepresentation(DocumentLoader*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::forceLayout() +{ + ewk_frame_force_layout(m_frame); +} + +void FrameLoaderClientEfl::forceLayoutForNonHTML() +{ +} + +void FrameLoaderClientEfl::setCopiesOnScroll() +{ + // apparently mac specific (Qt comment) +} + +void FrameLoaderClientEfl::detachedFromParent2() +{ +} + +void FrameLoaderClientEfl::detachedFromParent3() +{ +} + +void FrameLoaderClientEfl::loadedFromCachedPage() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidHandleOnloadEvents() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidReceiveServerRedirectForProvisionalLoad() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidCancelClientRedirect() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchWillPerformClientRedirect(const KURL&, double, double) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidChangeLocationWithinPage() +{ + ewk_frame_uri_changed(m_frame); + + if (ewk_view_frame_main_get(m_view) != m_frame) + return; + ewk_view_uri_changed(m_view); +} + +void FrameLoaderClientEfl::dispatchWillClose() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidReceiveIcon() +{ + /* report received favicon only for main frame. */ + if (ewk_view_frame_main_get(m_view) != m_frame) + return; + + ewk_view_frame_main_icon_received(m_view); +} + +void FrameLoaderClientEfl::dispatchDidStartProvisionalLoad() +{ + ewk_frame_load_provisional(m_frame); + if (ewk_view_frame_main_get(m_view) == m_frame) + ewk_view_load_provisional(m_view); +} + +void FrameLoaderClientEfl::dispatchDidReceiveTitle(const String& title) +{ + CString cs = title.utf8(); + ewk_frame_title_set(m_frame, cs.data()); + + if (ewk_view_frame_main_get(m_view) != m_frame) + return; + ewk_view_title_set(m_view, cs.data()); +} + +void FrameLoaderClientEfl::dispatchDidChangeIcons() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidCommitLoad() +{ + ewk_frame_uri_changed(m_frame); + if (ewk_view_frame_main_get(m_view) != m_frame) + return; + ewk_view_title_set(m_view, 0); + ewk_view_uri_changed(m_view); + + ViewportArguments arguments; + ewk_view_viewport_attributes_set(m_view, arguments); +} + +void FrameLoaderClientEfl::dispatchDidFinishDocumentLoad() +{ + ewk_frame_load_document_finished(m_frame); +} + +void FrameLoaderClientEfl::dispatchDidFirstLayout() +{ + ewk_frame_load_firstlayout_finished(m_frame); +} + +void FrameLoaderClientEfl::dispatchDidFirstVisuallyNonEmptyLayout() +{ + ewk_frame_load_firstlayout_nonempty_finished(m_frame); +} + +void FrameLoaderClientEfl::dispatchShow() +{ + ewk_view_load_show(m_view); +} + +void FrameLoaderClientEfl::cancelPolicyCheck() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidLoadMainResource(DocumentLoader*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::revertToProvisionalState(DocumentLoader*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::willChangeTitle(DocumentLoader*) +{ + // no need for, dispatchDidReceiveTitle is the right callback +} + +void FrameLoaderClientEfl::didChangeTitle(DocumentLoader *l) +{ + // no need for, dispatchDidReceiveTitle is the right callback +} + +bool FrameLoaderClientEfl::canHandleRequest(const ResourceRequest&) const +{ + notImplemented(); + return true; +} + +bool FrameLoaderClientEfl::canShowMIMETypeAsHTML(const String& MIMEType) const +{ + notImplemented(); + return false; +} + +bool FrameLoaderClientEfl::canShowMIMEType(const String& MIMEType) const +{ + if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType)) + return true; + + if (MIMETypeRegistry::isSupportedNonImageMIMEType(MIMEType)) + return true; + +#if 0 // PluginDatabase is disabled until we have Plugin system done. + if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType)) + return true; +#endif + + return false; +} + +bool FrameLoaderClientEfl::representationExistsForURLScheme(const String&) const +{ + return false; +} + +String FrameLoaderClientEfl::generatedMIMETypeForURLScheme(const String&) const +{ + notImplemented(); + return String(); +} + +void FrameLoaderClientEfl::finishedLoading(DocumentLoader* loader) +{ + if (!m_pluginView) + return; + m_pluginView->didFinishLoading(); + m_pluginView = 0; + m_hasSentResponseToPlugin = false; +} + + +void FrameLoaderClientEfl::provisionalLoadStarted() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::didFinishLoad() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::prepareForDataSourceReplacement() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::setTitle(const String& title, const KURL& url) +{ + // no need for, dispatchDidReceiveTitle is the right callback +} + +void FrameLoaderClientEfl::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& err) +{ + notImplemented(); +} + +bool FrameLoaderClientEfl::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length) +{ + notImplemented(); + return false; +} + +void FrameLoaderClientEfl::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const String&) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::dispatchDidFailProvisionalLoad(const ResourceError& err) +{ + dispatchDidFailLoad(err); +} + +void FrameLoaderClientEfl::dispatchDidFailLoad(const ResourceError& err) +{ + if (!shouldFallBack(err)) + return; + + m_loadError = err; + ewk_frame_load_error(m_frame, + m_loadError.domain().utf8().data(), + m_loadError.errorCode(), m_loadError.isCancellation(), + m_loadError.localizedDescription().utf8().data(), + m_loadError.failingURL().utf8().data()); +} + +void FrameLoaderClientEfl::download(ResourceHandle*, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse&) +{ + if (!m_view) + return; + + CString url = request.url().prettyURL().utf8(); + Ewk_Download download; + + download.url = url.data(); + ewk_view_download_request(m_view, &download); +} + +// copied from WebKit/Misc/WebKitErrors[Private].h +enum { + WebKitErrorCannotShowMIMEType = 100, + WebKitErrorCannotShowURL = 101, + WebKitErrorFrameLoadInterruptedByPolicyChange = 102, + WebKitErrorCannotUseRestrictedPort = 103, + WebKitErrorCannotFindPlugIn = 200, + WebKitErrorCannotLoadPlugIn = 201, + WebKitErrorJavaUnavailable = 202, +}; + +ResourceError FrameLoaderClientEfl::cancelledError(const ResourceRequest& request) +{ + ResourceError error("Error", -999, request.url().prettyURL(), + "Request cancelled"); + error.setIsCancellation(true); + return error; +} + +ResourceError FrameLoaderClientEfl::blockedError(const ResourceRequest& request) +{ + return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(), + "Request blocked"); +} + +ResourceError FrameLoaderClientEfl::cannotShowURLError(const ResourceRequest& request) +{ + return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(), + "Cannot show URL"); +} + +ResourceError FrameLoaderClientEfl::interruptForPolicyChangeError(const ResourceRequest& request) +{ + return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, + request.url().string(), "Frame load interrupted by policy change"); +} + +ResourceError FrameLoaderClientEfl::cannotShowMIMETypeError(const ResourceResponse& response) +{ + return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(), + "Cannot show mimetype"); +} + +ResourceError FrameLoaderClientEfl::fileDoesNotExistError(const ResourceResponse& response) +{ + return ResourceError("Error", -998 /* ### */, response.url().string(), + "File does not exist"); +} + +ResourceError FrameLoaderClientEfl::pluginWillHandleLoadError(const ResourceResponse&) +{ + notImplemented(); + return ResourceError("Error", 0, "", ""); +} + +bool FrameLoaderClientEfl::shouldFallBack(const ResourceError& error) +{ + return !(error.isCancellation() || (error.errorCode() == WebKitErrorFrameLoadInterruptedByPolicyChange)); +} + +bool FrameLoaderClientEfl::canCachePage() const +{ + return false; +} + +Frame* FrameLoaderClientEfl::dispatchCreatePage(const NavigationAction&) +{ + if (!m_view) + return 0; + + Evas_Object* newView = ewk_view_window_create(m_view, EINA_FALSE, 0); + Evas_Object* mainFrame; + if (!newView) + mainFrame = m_frame; + else + mainFrame = ewk_view_frame_main_get(newView); + + return ewk_frame_core_get(mainFrame); +} + +void FrameLoaderClientEfl::dispatchUnableToImplementPolicy(const ResourceError&) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::setMainDocumentError(DocumentLoader* loader, const ResourceError& error) +{ + if (!m_pluginView) + return; + m_pluginView->didFail(error); + m_pluginView = 0; + m_hasSentResponseToPlugin = false; +} + +void FrameLoaderClientEfl::startDownload(const ResourceRequest&) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::updateGlobalHistory() +{ + notImplemented(); +} + +void FrameLoaderClientEfl::savePlatformDataToCachedFrame(CachedFrame*) +{ + notImplemented(); +} + +void FrameLoaderClientEfl::transitionToCommittedFromCachedFrame(CachedFrame*) +{ +} + +void FrameLoaderClientEfl::transitionToCommittedForNewPage() +{ + ASSERT(m_frame); + ASSERT(m_view); + + ewk_frame_view_create_for_view(m_frame, m_view); + + if (m_frame == ewk_view_frame_main_get(m_view)) + ewk_view_frame_main_cleared(m_view); +} + +void FrameLoaderClientEfl::didSaveToPageCache() +{ +} + +void FrameLoaderClientEfl::didRestoreFromPageCache() +{ +} + +void FrameLoaderClientEfl::dispatchDidBecomeFrameset(bool) +{ +} + +PassRefPtr<FrameNetworkingContext> FrameLoaderClientEfl::createNetworkingContext() +{ + return FrameNetworkingContextEfl::create(ewk_frame_core_get(m_frame)); +} + +} diff --git a/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h new file mode 100644 index 0000000..cf7bdf0 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/FrameLoaderClientEfl.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Collabora Ltd. All rights reserved. + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FrameLoaderClientEfl_h +#define FrameLoaderClientEfl_h + +#include "EWebKit.h" +#include "FrameLoaderClient.h" +#include "PluginView.h" +#include "ResourceError.h" +#include "ResourceResponse.h" + +namespace WebCore { + +class FormState; + +class FrameLoaderClientEfl : public FrameLoaderClient { + public: + explicit FrameLoaderClientEfl(Evas_Object *view); + virtual ~FrameLoaderClientEfl() { } + virtual void frameLoaderDestroyed(); + + void setWebFrame(Evas_Object *frame) { m_frame = frame; } + Evas_Object* webFrame() const { return m_frame; } + Evas_Object* webView() const { return m_view; } + + void setCustomUserAgent(const String &agent); + const String& customUserAgent() const; + + virtual bool hasWebView() const; + virtual bool hasFrameView() const; + + void callPolicyFunction(FramePolicyFunction function, PolicyAction action); + + virtual void makeRepresentation(DocumentLoader*); + virtual void forceLayout(); + virtual void forceLayoutForNonHTML(); + + virtual void setCopiesOnScroll(); + + virtual void detachedFromParent2(); + virtual void detachedFromParent3(); + + virtual void loadedFromCachedPage(); + + virtual void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&); + + virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse); + virtual bool shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier); + virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); + + virtual void dispatchDidPushStateWithinPage(); + virtual void dispatchDidPopStateWithinPage(); + virtual void dispatchDidReplaceStateWithinPage(); + virtual void dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const; + virtual void dispatchDidChangeBackForwardIndex() const; + virtual void dispatchDidClearWindowObjectInWorld(WebCore::DOMWrapperWorld*); + + virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&); + virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&); + virtual void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived); + virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier); + virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&); + virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length); + virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String& sourceString); + + virtual void dispatchDidHandleOnloadEvents(); + virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); + virtual void dispatchDidCancelClientRedirect(); + virtual void dispatchWillPerformClientRedirect(const KURL&, double, double); + virtual void dispatchDidChangeLocationWithinPage(); + virtual void dispatchWillClose(); + virtual void dispatchDidReceiveIcon(); + virtual void dispatchDidStartProvisionalLoad(); + virtual void dispatchDidReceiveTitle(const String&); + virtual void dispatchDidChangeIcons(); + virtual void dispatchDidCommitLoad(); + virtual void dispatchDidFailProvisionalLoad(const ResourceError&); + virtual void dispatchDidFailLoad(const ResourceError&); + virtual void dispatchDidFinishDocumentLoad(); + virtual void dispatchDidFinishLoad(); + virtual void dispatchDidFirstLayout(); + virtual void dispatchDidFirstVisuallyNonEmptyLayout(); + + virtual Frame* dispatchCreatePage(const WebCore::NavigationAction&); + virtual void dispatchShow(); + + virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction, const String& MIMEType, const ResourceRequest&); + virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, WTF::PassRefPtr<FormState>, const String& frameName); + virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, WTF::PassRefPtr<FormState>); + virtual void cancelPolicyCheck(); + + virtual void dispatchUnableToImplementPolicy(const ResourceError&); + + virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) { } + virtual void dispatchWillSubmitForm(FramePolicyFunction, WTF::PassRefPtr<FormState>); + + virtual void dispatchDidLoadMainResource(DocumentLoader*); + virtual void revertToProvisionalState(DocumentLoader*); + virtual void setMainDocumentError(DocumentLoader*, const ResourceError&); + + virtual void postProgressStartedNotification(); + virtual void postProgressEstimateChangedNotification(); + virtual void postProgressFinishedNotification(); + + virtual PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, + const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight); + virtual void didTransferChildFrameToNewDocument(Page*); + virtual void transferLoadingResourceFromPage(unsigned long, WebCore::DocumentLoader*, const ResourceRequest&, WebCore::Page*); + + virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const WTF::Vector<String>&, const WTF::Vector<String>&, const String&, bool); + virtual void redirectDataToPlugin(Widget* pluginWidget); + virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const WTF::Vector<String>& paramNames, const WTF::Vector<String>& paramValues); + virtual String overrideMediaType() const; + virtual void windowObjectCleared(); + virtual void documentElementAvailable(); + + virtual void didPerformFirstNavigation() const; + + virtual void registerForIconNotification(bool); + + virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType); + + virtual void setMainFrameDocumentReady(bool); + + virtual void startDownload(const ResourceRequest&); + + virtual void willChangeTitle(DocumentLoader*); + virtual void didChangeTitle(DocumentLoader*); + + virtual void committedLoad(DocumentLoader*, const char*, int); + virtual void finishedLoading(DocumentLoader*); + + virtual void updateGlobalHistory(); + virtual void updateGlobalHistoryRedirectLinks(); + virtual bool shouldGoToHistoryItem(HistoryItem*) const; + virtual void didDisplayInsecureContent(); + virtual void didRunInsecureContent(SecurityOrigin*); + + virtual ResourceError cancelledError(const ResourceRequest&); + virtual ResourceError blockedError(const ResourceRequest&); + virtual ResourceError cannotShowURLError(const ResourceRequest&); + virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&); + + virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&); + virtual ResourceError fileDoesNotExistError(const ResourceResponse&); + virtual ResourceError pluginWillHandleLoadError(const ResourceResponse&); + + virtual bool shouldFallBack(const ResourceError&); + + virtual bool canHandleRequest(const ResourceRequest&) const; + virtual bool canShowMIMEType(const String&) const; + virtual bool canShowMIMETypeAsHTML(const String& MIMEType) const; + virtual bool representationExistsForURLScheme(const String&) const; + virtual String generatedMIMETypeForURLScheme(const String&) const; + + virtual void frameLoadCompleted(); + virtual void saveViewStateToItem(HistoryItem*); + virtual void restoreViewState(); + virtual void provisionalLoadStarted(); + virtual void didFinishLoad(); + virtual void prepareForDataSourceReplacement(); + + virtual WTF::PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&); + virtual void setTitle(const String& title, const KURL&); + + virtual String userAgent(const KURL&); + + virtual void savePlatformDataToCachedFrame(CachedFrame*); + virtual void transitionToCommittedFromCachedFrame(CachedFrame*); + virtual void transitionToCommittedForNewPage(); + + virtual void didSaveToPageCache(); + virtual void didRestoreFromPageCache(); + + virtual void dispatchDidBecomeFrameset(bool); + + virtual bool canCachePage() const; + virtual void download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&); + + virtual PassRefPtr<WebCore::FrameNetworkingContext> createNetworkingContext(); + private: + Evas_Object *m_view; + Evas_Object *m_frame; + + ResourceResponse m_response; + String m_userAgent; + String m_customUserAgent; + + ResourceError m_loadError; + + // Plugin view to redirect data to + PluginView* m_pluginView; + bool m_hasSentResponseToPlugin; +}; + +} + +#endif // FrameLoaderClientEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h b/Source/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h new file mode 100644 index 0000000..4e67512 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/FrameNetworkingContextEfl.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 Samsung Electronics + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FrameNetworkingContextEfl_h +#define FrameNetworkingContextEfl_h + +#include "FrameNetworkingContext.h" + +namespace WebCore { + +class FrameNetworkingContextEfl : public WebCore::FrameNetworkingContext { +public: + static PassRefPtr<FrameNetworkingContextEfl> create(WebCore::Frame* frame) + { + return adoptRef(new FrameNetworkingContextEfl(frame)); + } + + WebCore::Frame* coreFrame() const { return frame(); } + +private: + FrameNetworkingContextEfl(WebCore::Frame* frame) + : WebCore::FrameNetworkingContext(frame) + { + } +}; + +} + +#endif diff --git a/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.cpp b/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.cpp new file mode 100644 index 0000000..70deaef --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2010 Igalia S.L + * Copyright (C) 2010 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#if ENABLE(VIDEO) + +#include "FullscreenVideoControllerEfl.h" + +#include "MediaPlayer.h" +#include "NotImplemented.h" + +#include <gst/gst.h> + +using namespace std; +using namespace WebCore; + +FullscreenVideoController::FullscreenVideoController() + : m_hudTimeoutId(0) + , m_progressBarUpdateId(0) + , m_seekLock(false) + , m_window(0) + , m_hudWindow(0) +{ +} + +FullscreenVideoController::~FullscreenVideoController() +{ + exitFullscreen(); +} + +void FullscreenVideoController::setMediaElement(HTMLMediaElement* mediaElement) +{ + if (mediaElement == m_mediaElement) + return; + + m_mediaElement = mediaElement; + if (!m_mediaElement) { + // Can't do full-screen, just get out + exitFullscreen(); + } +} + +void FullscreenVideoController::showHud(bool autoHide) +{ + notImplemented(); +} + +void FullscreenVideoController::hideHud() +{ + notImplemented(); +} + +void FullscreenVideoController::enterFullscreen() +{ + notImplemented(); +} + +void FullscreenVideoController::updateHudPosition() +{ + notImplemented(); +} + +void FullscreenVideoController::exitOnUserRequest() +{ + notImplemented(); +} + +void FullscreenVideoController::exitFullscreen() +{ + notImplemented(); +} + +bool FullscreenVideoController::canPlay() const +{ + notImplemented(); + return false; +} + +void FullscreenVideoController::play() +{ + notImplemented(); +} + +void FullscreenVideoController::pause() +{ + notImplemented(); +} + +void FullscreenVideoController::playStateChanged() +{ + notImplemented(); +} + +void FullscreenVideoController::togglePlay() +{ + notImplemented(); +} + +float FullscreenVideoController::volume() const +{ + notImplemented(); + return 0; +} + +bool FullscreenVideoController::muted() const +{ + notImplemented(); + return false; +} + +void FullscreenVideoController::setVolume(float volume) +{ + notImplemented(); +} + +void FullscreenVideoController::volumeChanged() +{ + notImplemented(); +} + +void FullscreenVideoController::muteChanged() +{ + notImplemented(); +} + +float FullscreenVideoController::currentTime() const +{ + notImplemented(); + return 0; +} + +void FullscreenVideoController::setCurrentTime(float value) +{ + notImplemented(); +} + +float FullscreenVideoController::duration() const +{ + notImplemented(); + return 0; +} + +float FullscreenVideoController::percentLoaded() const +{ + notImplemented(); + return 0; +} + +void FullscreenVideoController::beginSeek() +{ + notImplemented(); +} + +void FullscreenVideoController::doSeek() +{ + notImplemented(); +} + +void FullscreenVideoController::endSeek() +{ + notImplemented(); +} + +bool FullscreenVideoController::updateHudProgressBar() +{ + notImplemented(); + return false; +} + +void FullscreenVideoController::createHud() +{ + notImplemented(); +} + +#endif diff --git a/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.h b/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.h new file mode 100644 index 0000000..4bbae25 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/FullscreenVideoControllerEfl.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010 Igalia S.L + * Copyright (C) 2010 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef FullscreenVideoControllerEfl_h +#define FullscreenVideoControllerEfl_h + +#if ENABLE(VIDEO) + +#include "GStreamerGWorld.h" +#include "HTMLMediaElement.h" +#include <wtf/RefPtr.h> + +class FullscreenVideoController : public Noncopyable { +public: + FullscreenVideoController(); + virtual ~FullscreenVideoController(); + + void setMediaElement(WebCore::HTMLMediaElement*); + WebCore::HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); } + + void enterFullscreen(); + void exitFullscreen(); + + void exitOnUserRequest(); + void togglePlay(); + void beginSeek(); + void doSeek(); + void endSeek(); + + void hideHud(); + void showHud(bool); + bool updateHudProgressBar(); + + float volume() const; + void setVolume(float); + void volumeChanged(); + void muteChanged(); + +private: + bool canPlay() const; + void play(); + void pause(); + void playStateChanged(); + + bool muted() const; + + float currentTime() const; + void setCurrentTime(float); + + float duration() const; + float percentLoaded() const; + + void createHud(); + void updateHudPosition(); + + RefPtr<WebCore::HTMLMediaElement> m_mediaElement; + RefPtr<WebCore::GStreamerGWorld> m_gstreamerGWorld; + + uint m_hudTimeoutId; + uint m_progressBarUpdateId; + uint m_progressBarFillUpdateId; + uint m_hscaleUpdateId; + uint m_volumeUpdateId; + bool m_seekLock; + PlatformWidget* m_window; + PlatformWidget* m_hudWindow; + PlatformWidget* m_timeHScale; + PlatformWidget* m_timeLabel; + PlatformWidget* m_volumeButton; +}; + +#endif + +#endif // FullscreenVideoControllerEfl_h diff --git a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp new file mode 100644 index 0000000..6bfd6ad --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "InspectorClientEfl.h" + +#include "NotImplemented.h" +#include "PlatformString.h" + +using namespace WebCore; + +namespace WebCore { + +void InspectorClientEfl::inspectorDestroyed() +{ + delete this; +} + +void InspectorClientEfl::openInspectorFrontend(InspectorController*) +{ + notImplemented(); +} + +void InspectorClientEfl::highlight(Node* node) +{ + notImplemented(); +} + +void InspectorClientEfl::hideHighlight() +{ + notImplemented(); +} + +void InspectorClientEfl::populateSetting(const String&, String*) +{ + notImplemented(); +} + +void InspectorClientEfl::storeSetting(const String&, const String&) +{ + notImplemented(); +} + +bool InspectorClientEfl::sendMessageToFrontend(const String&) +{ + notImplemented(); + return false; +} + + +} diff --git a/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h new file mode 100644 index 0000000..0c283d8 --- /dev/null +++ b/Source/WebKit/efl/WebCoreSupport/InspectorClientEfl.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia + * Copyright (C) 2009-2010 ProFUSION embedded systems + * Copyright (C) 2009-2010 Samsung Electronics + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef InspectorClientEfl_h +#define InspectorClientEfl_h + +#include "InspectorClient.h" +#include <wtf/Forward.h> + +namespace WebCore { +class Node; +class Page; + +class InspectorClientEfl : public WebCore::InspectorClient { +public: + virtual void inspectorDestroyed(); + + virtual void openInspectorFrontend(InspectorController*); + + virtual void highlight(Node*); + virtual void hideHighlight(); + + virtual void populateSetting(const String& key, String* value); + virtual void storeSetting(const String& key, const String& value); + + virtual bool sendMessageToFrontend(const String&); +}; +} + +#endif // InspectorClientEfl_h diff --git a/Source/WebKit/efl/ewebkit.pc.in b/Source/WebKit/efl/ewebkit.pc.in new file mode 100644 index 0000000..3a1c8f5 --- /dev/null +++ b/Source/WebKit/efl/ewebkit.pc.in @@ -0,0 +1,13 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${prefix}/include +datadir=${prefix}/share/@WebKit_LIBRARY_NAME@-@PROJECT_VERSION_MAJOR@ + +Name: WebKit-EFL +Description: Web content engine for EFL applications +Version: @PROJECT_VERSION@ +Requires: cairo evas ecore +Libs: -L${libdir} -lewebkit @EXTRA_EWEBKIT_LINK@ +Libs.private: @LIBS_PRIVATE@ +Cflags: -I${includedir}/@WebKit_LIBRARY_NAME@-@PROJECT_VERSION_MAJOR@ diff --git a/Source/WebKit/efl/ewk/EWebKit.h b/Source/WebKit/efl/ewk/EWebKit.h new file mode 100644 index 0000000..183e9dc --- /dev/null +++ b/Source/WebKit/efl/ewk/EWebKit.h @@ -0,0 +1,37 @@ +/* + Copyright (C) 2008-2009 INdT - Instituto Nokia de Tecnologia + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef EWebKit_h +#define EWebKit_h + +#include "ewk_contextmenu.h" +#include "ewk_cookies.h" +#include "ewk_eapi.h" +#include "ewk_frame.h" +#include "ewk_history.h" +#include "ewk_main.h" +#include "ewk_settings.h" +#include "ewk_view.h" +#include "ewk_window_features.h" + +#include <Evas.h> + +#endif // EWebKit_h diff --git a/Source/WebKit/efl/ewk/ewk_contextmenu.cpp b/Source/WebKit/efl/ewk/ewk_contextmenu.cpp new file mode 100644 index 0000000..40bd2ba --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_contextmenu.cpp @@ -0,0 +1,273 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_contextmenu.h" + +#include "ContextMenu.h" +#include "ContextMenuController.h" +#include "ContextMenuItem.h" +#include "EWebKit.h" +#include "ewk_private.h" + +#include <Eina.h> +#include <eina_safety_checks.h> +#include <wtf/text/CString.h> + +struct _Ewk_Context_Menu { + unsigned int __ref; +#if ENABLE(CONTEXT_MENUS) + WebCore::ContextMenuController* controller; +#endif + Evas_Object* view; + + Eina_List* items; +}; + +struct _Ewk_Context_Menu_Item { + Ewk_Context_Menu_Item_Type type; + Ewk_Context_Menu_Action action; + + const char* title; + Ewk_Context_Menu* submenu; + + Eina_Bool checked:1; + Eina_Bool enabled:1; +}; + +void ewk_context_menu_ref(Ewk_Context_Menu* menu) +{ + EINA_SAFETY_ON_NULL_RETURN(menu); + menu->__ref++; +} + +void ewk_context_menu_unref(Ewk_Context_Menu* menu) +{ + EINA_SAFETY_ON_NULL_RETURN(menu); + void* item; + + if (--menu->__ref) + return; + + EINA_LIST_FREE(menu->items, item) + ewk_context_menu_item_free(static_cast<Ewk_Context_Menu_Item*>(item)); + + free(menu); +} + +Eina_Bool ewk_context_menu_destroy(Ewk_Context_Menu* menu) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(menu, EINA_FALSE); +#if ENABLE(CONTEXT_MENUS) + EINA_SAFETY_ON_NULL_RETURN_VAL(menu->controller, EINA_FALSE); + + menu->controller->clearContextMenu(); +#endif + + return EINA_TRUE; +} + +const Eina_List* ewk_context_menu_item_list_get(Ewk_Context_Menu* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0); + + return o->items; +} + +Ewk_Context_Menu_Item* ewk_context_menu_item_new(Ewk_Context_Menu_Item_Type type, + Ewk_Context_Menu_Action action, Ewk_Context_Menu* submenu, + const char* title, Eina_Bool checked, Eina_Bool enabled) +{ + Ewk_Context_Menu_Item* item = (Ewk_Context_Menu_Item*) malloc(sizeof(*item)); + if (!item) + return 0; + + item->type = type; + item->action = action; + item->title = eina_stringshare_add(title); + item->submenu = submenu; + item->checked = checked; + item->enabled = enabled; + + return item; +} + +Eina_Bool ewk_context_menu_item_select(Ewk_Context_Menu* menu, Ewk_Context_Menu_Item* item) +{ +#if ENABLE(CONTEXT_MENUS) + EINA_SAFETY_ON_NULL_RETURN_VAL(menu, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(item, EINA_FALSE); + WebCore::ContextMenuAction action = static_cast<WebCore::ContextMenuAction>(item->action); + WebCore::ContextMenuItemType type = static_cast<WebCore::ContextMenuItemType>(item->type); + + // Don't care about title and submenu as they're not used after this point. + WebCore::ContextMenuItem core(type, action, WTF::String()); + menu->controller->contextMenuItemSelected(&core); +#endif + + return EINA_TRUE; +} + +void ewk_context_menu_item_free(Ewk_Context_Menu_Item* item) +{ + EINA_SAFETY_ON_NULL_RETURN(item); + + eina_stringshare_del(item->title); + free(item); +} + +Ewk_Context_Menu_Item_Type ewk_context_menu_item_type_get(Ewk_Context_Menu_Item* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EWK_ACTION_TYPE); + return o->type; +} + +Eina_Bool ewk_context_menu_item_type_set(Ewk_Context_Menu_Item* o, Ewk_Context_Menu_Item_Type type) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + o->type = type; + return EINA_TRUE; +} + +Ewk_Context_Menu_Action ewk_context_menu_item_action_get(Ewk_Context_Menu_Item* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EWK_CONTEXT_MENU_ITEM_TAG_NO_ACTION); + return o->action; +} + +Eina_Bool ewk_context_menu_item_action_set(Ewk_Context_Menu_Item* o, Ewk_Context_Menu_Action action) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + o->action = action; + return EINA_TRUE; +} + +const char* ewk_context_menu_item_title_get(Ewk_Context_Menu_Item* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0); + return o->title; +} + +const char* ewk_context_menu_item_title_set(Ewk_Context_Menu_Item* o, const char* title) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0); + eina_stringshare_replace(&o->title, title); + return o->title; +} + +Eina_Bool ewk_context_menu_item_checked_get(Ewk_Context_Menu_Item* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + return o->checked; +} + +Eina_Bool ewk_context_menu_item_checked_set(Ewk_Context_Menu_Item* o, Eina_Bool checked) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + o->checked = checked; + return EINA_TRUE; +} + +Eina_Bool ewk_context_menu_item_enabled_get(Ewk_Context_Menu_Item* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + return o->enabled; +} + +Eina_Bool ewk_context_menu_item_enabled_set(Ewk_Context_Menu_Item *o, Eina_Bool enabled) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + o->enabled = enabled; + return EINA_TRUE; +} + + +/* internal methods ****************************************************/ + +#if ENABLE(CONTEXT_MENUS) +/** + * @internal + * + * Creates context on view. + * + * @param view View. + * @param Controller Context Menu Controller. + * + * @return newly allocated context menu or @c 0 on errors. + */ +Ewk_Context_Menu* ewk_context_menu_new(Evas_Object* view, WebCore::ContextMenuController* controller) +{ + Ewk_Context_Menu* menu; + EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(controller, 0); + + menu = static_cast<Ewk_Context_Menu*>(malloc(sizeof(*menu))); + if (!menu) { + CRITICAL("Could not allocate context menu memory."); + return 0; + } + + menu->__ref = 1; + menu->view = view; + menu->controller = controller; + menu->items = 0; + evas_object_smart_callback_call(menu->view, "contextmenu,new", menu); + + return menu; +} + +Eina_Bool ewk_context_menu_free(Ewk_Context_Menu* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, EINA_FALSE); + evas_object_smart_callback_call(o->view, "contextmenu,free", o); + ewk_context_menu_unref(o); + return EINA_TRUE; +} + +void ewk_context_menu_item_append(Ewk_Context_Menu* o, WebCore::ContextMenuItem& core) +{ + Ewk_Context_Menu_Item_Type type = static_cast<Ewk_Context_Menu_Item_Type>(core.type()); + Ewk_Context_Menu_Action action = static_cast<Ewk_Context_Menu_Action>(core.action()); + + Ewk_Context_Menu_Item* menu_item = ewk_context_menu_item_new + (type, action, 0, core.title().utf8().data(), core.checked(), + core.enabled()); + EINA_SAFETY_ON_NULL_RETURN(menu_item); + + o->items = eina_list_append(o->items, menu_item); + evas_object_smart_callback_call(o->view, "contextmenu,item,appended", o); +} + +Ewk_Context_Menu* ewk_context_menu_custom_get(Ewk_Context_Menu* o) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(o, 0); + + evas_object_smart_callback_call(o->view, "contextmenu,customize", o->items); + return o; +} + +void ewk_context_menu_show(Ewk_Context_Menu* o) +{ + EINA_SAFETY_ON_NULL_RETURN(o); + + evas_object_smart_callback_call(o->view, "contextmenu,show", o); +} + +#endif diff --git a/Source/WebKit/efl/ewk/ewk_contextmenu.h b/Source/WebKit/efl/ewk/ewk_contextmenu.h new file mode 100644 index 0000000..c5adb48 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_contextmenu.h @@ -0,0 +1,147 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_contextmenu_h +#define ewk_contextmenu_h + +#include "ewk_eapi.h" + +#include <Eina.h> +#include <Evas.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// keep this in sync with ContextMenuItem.h +enum _Ewk_Context_Menu_Action { + EWK_CONTEXT_MENU_ITEM_TAG_NO_ACTION = 0, // this item is not actually in web_uidelegate.h + EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK_IN_NEW_WINDOW = 1, + EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_LINK_TO_DISK, + EWK_CONTEXT_MENU_ITEM_TAG_COPY_LINK_TO_CLIPBOARD, + EWK_CONTEXT_MENU_ITEM_TAG_OPEN_IMAGE_IN_NEW_WINDOW, + EWK_CONTEXT_MENU_ITEM_TAG_DOWNLOAD_IMAGE_TO_DISK, + EWK_CONTEXT_MENU_ITEM_TAG_COPY_IMAGE_TO_CLIPBOARD, + EWK_CONTEXT_MENU_ITEM_TAG_OPEN_FRAME_IN_NEW_WINDOW, + EWK_CONTEXT_MENU_ITEM_TAG_COPY, + EWK_CONTEXT_MENU_ITEM_TAG_GO_BACK, + EWK_CONTEXT_MENU_ITEM_TAG_GO_FORWARD, + EWK_CONTEXT_MENU_ITEM_TAG_STOP, + EWK_CONTEXT_MENU_ITEM_TAG_RELOAD, + EWK_CONTEXT_MENU_ITEM_TAG_CUT, + EWK_CONTEXT_MENU_ITEM_TAG_PASTE, + EWK_CONTEXT_MENU_ITEM_TAG_SPELLING_GUESS, + EWK_CONTEXT_MENU_ITEM_TAG_NO_GUESSES_FOUND, + EWK_CONTEXT_MENU_ITEM_TAG_IGNORE_SPELLING, + EWK_CONTEXT_MENU_ITEM_TAG_LEARN_SPELLING, + EWK_CONTEXT_MENU_ITEM_TAG_OTHER, + EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_IN_SPOTLIGHT, + EWK_CONTEXT_MENU_ITEM_TAG_SEARCH_WEB, + EWK_CONTEXT_MENU_ITEM_TAG_LOOK_UP_IN_DICTIONARY, + EWK_CONTEXT_MENU_ITEM_TAG_OPEN_WITH_DEFAULT_APPLICATION, + EWK_CONTEXT_MENU_ITEM_PDFACTUAL_SIZE, + EWK_CONTEXT_MENU_ITEM_PDFZOOM_IN, + EWK_CONTEXT_MENU_ITEM_PDFZOOM_OUT, + EWK_CONTEXT_MENU_ITEM_PDFAUTO_SIZE, + EWK_CONTEXT_MENU_ITEM_PDFSINGLE_PAGE, + EWK_CONTEXT_MENU_ITEM_PDFFACING_PAGES, + EWK_CONTEXT_MENU_ITEM_PDFCONTINUOUS, + EWK_CONTEXT_MENU_ITEM_PDFNEXT_PAGE, + EWK_CONTEXT_MENU_ITEM_PDFPREVIOUS_PAGE, + EWK_CONTEXT_MENU_ITEM_TAG_OPEN_LINK = 2000, + EWK_CONTEXT_MENU_ITEM_TAG_IGNORE_GRAMMAR, + EWK_CONTEXT_MENU_ITEM_TAG_SPELLING_MENU, // spelling or spelling/grammar sub-menu + EWK_CONTEXT_MENU_ITEM_TAG_SHOW_SPELLING_PANEL, + EWK_CONTEXT_MENU_ITEM_TAG_CHECK_SPELLING, + EWK_CONTEXT_MENU_ITEM_TAG_CHECK_SPELLING_WHILE_TYPING, + EWK_CONTEXT_MENU_ITEM_TAG_CHECK_GRAMMAR_WITH_SPELLING, + EWK_CONTEXT_MENU_ITEM_TAG_FONT_MENU, // font sub-menu + EWK_CONTEXT_MENU_ITEM_TAG_SHOW_FONTS, + EWK_CONTEXT_MENU_ITEM_TAG_BOLD, + EWK_CONTEXT_MENU_ITEM_TAG_ITALIC, + EWK_CONTEXT_MENU_ITEM_TAG_UNDERLINE, + EWK_CONTEXT_MENU_ITEM_TAG_OUTLINE, + EWK_CONTEXT_MENU_ITEM_TAG_STYLES, + EWK_CONTEXT_MENU_ITEM_TAG_SHOW_COLORS, + EWK_CONTEXT_MENU_ITEM_TAG_SPEECH_MENU, // speech sub-menu + EWK_CONTEXT_MENU_ITEM_TAG_START_SPEAKING, + EWK_CONTEXT_MENU_ITEM_TAG_STOP_SPEAKING, + EWK_CONTEXT_MENU_ITEM_TAG_WRITING_DIRECTION_MENU, // writing direction sub-menu + EWK_CONTEXT_MENU_ITEM_TAG_DEFAULT_DIRECTION, + EWK_CONTEXT_MENU_ITEM_TAG_LEFT_TO_RIGHT, + EWK_CONTEXT_MENU_ITEM_TAG_RIGHT_TO_LEFT, + EWK_CONTEXT_MENU_ITEM_TAG_PDFSINGLE_PAGE_SCROLLING, + EWK_CONTEXT_MENU_ITEM_TAG_PDFFACING_PAGES_SCROLLING, + EWK_CONTEXT_MENU_ITEM_TAG_TEXT_DIRECTION_MENU, // text direction sub-menu + EWK_CONTEXT_MENU_ITEM_TAG_TEXT_DIRECTION_DEFAULT, + EWK_CONTEXT_MENU_ITEM_TAG_TEXT_DIRECTION_LEFT_TO_RIGHT, + EWK_CONTEXT_MENU_ITEM_TAG_TEXT_DIRECTION_RIGHT_TO_LEFT, + EWK_CONTEXT_MENU_ITEM_BASE_CUSTOM_TAG = 5000, + EWK_CONTEXT_MENU_ITEM_BASE_APPLICATION_TAG = 10000 +}; +typedef enum _Ewk_Context_Menu_Action Ewk_Context_Menu_Action; + +// keep this in sync with ContextMenuItem.h +enum _Ewk_Context_Menu_Item_Type { + EWK_ACTION_TYPE, + EWK_CHECKABLE_ACTION_TYPE, + EWK_SEPARATOR_TYPE, + EWK_SUBMENU_TYPE +}; +typedef enum _Ewk_Context_Menu_Item_Type Ewk_Context_Menu_Item_Type; + +/** + * The structure to contain Context Menu data + */ +typedef struct _Ewk_Context_Menu Ewk_Context_Menu; + +/** + * Represents one item from Ewk_Context_Menu + */ +typedef struct _Ewk_Context_Menu_Item Ewk_Context_Menu_Item; + + + +/************************** Exported functions ***********************/ + +EAPI void ewk_context_menu_ref(Ewk_Context_Menu* menu); +EAPI void ewk_context_menu_unref(Ewk_Context_Menu* menu); +EAPI Eina_Bool ewk_context_menu_destroy(Ewk_Context_Menu* menu); + +EAPI const Eina_List* ewk_context_menu_item_list_get(Ewk_Context_Menu* o); + +EAPI Ewk_Context_Menu_Item* ewk_context_menu_item_new(Ewk_Context_Menu_Item_Type type, Ewk_Context_Menu_Action action, Ewk_Context_Menu* submenu, const char* title, Eina_Bool checked, Eina_Bool enabled); +EAPI void ewk_context_menu_item_free(Ewk_Context_Menu_Item* item); +EAPI Eina_Bool ewk_context_menu_item_select(Ewk_Context_Menu* menu, Ewk_Context_Menu_Item* item); +EAPI Ewk_Context_Menu_Item_Type ewk_context_menu_item_type_get(Ewk_Context_Menu_Item* o); +EAPI Eina_Bool ewk_context_menu_item_type_set(Ewk_Context_Menu_Item* o, Ewk_Context_Menu_Item_Type type); +EAPI Ewk_Context_Menu_Action ewk_context_menu_item_action_get(Ewk_Context_Menu_Item* o); +EAPI Eina_Bool ewk_context_menu_item_action_set(Ewk_Context_Menu_Item* o, Ewk_Context_Menu_Action action); +EAPI const char* ewk_context_menu_item_title_get(Ewk_Context_Menu_Item* o); +EAPI const char* ewk_context_menu_item_title_set(Ewk_Context_Menu_Item* o, const char* title); +EAPI Eina_Bool ewk_context_menu_item_checked_get(Ewk_Context_Menu_Item* o); +EAPI Eina_Bool ewk_context_menu_item_checked_set(Ewk_Context_Menu_Item* o, Eina_Bool checked); +EAPI Eina_Bool ewk_context_menu_item_enabled_get(Ewk_Context_Menu_Item* o); +EAPI Eina_Bool ewk_context_menu_item_enabled_set(Ewk_Context_Menu_Item* o, Eina_Bool enabled); + +#ifdef __cplusplus +} +#endif +#endif // ewk_contextmenu_h diff --git a/Source/WebKit/efl/ewk/ewk_cookies.cpp b/Source/WebKit/efl/ewk/ewk_cookies.cpp new file mode 100644 index 0000000..421f8dc --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_cookies.cpp @@ -0,0 +1,241 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_cookies.h" + +#ifdef WTF_USE_SOUP +#include "CookieJarSoup.h" +#endif +#include "EWebKit.h" +#include "ResourceHandle.h" + +#include <Eina.h> +#include <eina_safety_checks.h> +#ifdef WTF_USE_SOUP +#include <glib.h> +#include <libsoup/soup.h> +#endif +#include <wtf/text/CString.h> + + +/** + * Set the path where the cookies are going to be stored. Use NULL for keep + * them just in memory. + * + * @param filename path to the cookies.txt file. + * + * @returns EINA_FALSE if it wasn't possible to create the cookie jar, + * EINA_FALSE otherwise. + */ +EAPI Eina_Bool ewk_cookies_file_set(const char *filename) +{ +#ifdef WTF_USE_SOUP + SoupCookieJar* cookieJar = 0; + if (filename) + cookieJar = soup_cookie_jar_text_new(filename, FALSE); + else + cookieJar = soup_cookie_jar_new(); + + if (!cookieJar) + return EINA_FALSE; + +#ifdef HAVE_LIBSOUP_2_29_90 + soup_cookie_jar_set_accept_policy(cookieJar, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY); +#endif + + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + SoupSessionFeature* oldjar = soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR); + if (oldjar) + soup_session_remove_feature(session, oldjar); + + WebCore::setDefaultCookieJar(cookieJar); + soup_session_add_feature(session, SOUP_SESSION_FEATURE(cookieJar)); + + return EINA_TRUE; +#else + return EINA_FALSE; +#endif +} + +/** + * Clear all the cookies from the cookie jar. + */ +EAPI void ewk_cookies_clear() +{ +#ifdef WTF_USE_SOUP + GSList* l; + GSList* p; + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + + l = soup_cookie_jar_all_cookies(cookieJar); + for (p = l; p; p = p->next) + soup_cookie_jar_delete_cookie(cookieJar, (SoupCookie*)p->data); + + soup_cookies_free(l); +#endif +} + +/** + * Returns a list of cookies in the cookie jar. + * + * @returns an Eina_List with all the cookies in the cookie jar. + */ +EAPI Eina_List* ewk_cookies_get_all(void) +{ + Eina_List* el = 0; +#ifdef WTF_USE_SOUP + GSList* l; + GSList* p; + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + + l = soup_cookie_jar_all_cookies(cookieJar); + for (p = l; p; p = p->next) { + SoupCookie* cookie = static_cast<SoupCookie*>(p->data); + Ewk_Cookie* c = static_cast<Ewk_Cookie*>(malloc(sizeof(*c))); + c->name = strdup(cookie->name); + c->value = strdup(cookie->value); + c->domain = strdup(cookie->domain); + c->path = strdup(cookie->path); + c->expires = soup_date_to_time_t(cookie->expires); + c->secure = static_cast<Eina_Bool>(cookie->secure); + c->http_only = static_cast<Eina_Bool>(cookie->http_only); + el = eina_list_append(el, c); + } + + soup_cookies_free(l); +#endif + return el; +} + +/* + * Deletes a cookie from the cookie jar. + * + * Note that the fields name, value, domain and path are used to match this + * cookie in the cookie jar. + * + * @param cookie an Ewk_Cookie that has the info relative to that cookie. + */ +EAPI void ewk_cookies_cookie_del(Ewk_Cookie *cookie) +{ +#ifdef WTF_USE_SOUP + EINA_SAFETY_ON_NULL_RETURN(cookie); + GSList* l; + GSList* p; + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + SoupCookie* c1 = soup_cookie_new( + cookie->name, cookie->value, cookie->domain, cookie->path, -1); + + l = soup_cookie_jar_all_cookies(cookieJar); + for (p = l; p; p = p->next) { + SoupCookie* c2 = static_cast<SoupCookie*>(p->data); + if (soup_cookie_equal(c1, c2)) { + soup_cookie_jar_delete_cookie(cookieJar, c2); + break; + } + } + + soup_cookie_free(c1); + soup_cookies_free(l); +#endif +} + +/* + * Free the memory used by a cookie. + * + * @param cookie the Ewk_Cookie struct that will be freed. + */ +EAPI void ewk_cookies_cookie_free(Ewk_Cookie *cookie) +{ +#ifdef WTF_USE_SOUP + EINA_SAFETY_ON_NULL_RETURN(cookie); + free(cookie->name); + free(cookie->value); + free(cookie->domain); + free(cookie->path); + free(cookie); +#endif +} + +/* + * Set the cookies accept policy. + * + * Possible values are: EWK_COOKIE_JAR_ACCEPT_ALWAYS, which accepts every + * cookie sent from any page; EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, which + * accepts cookies only from the main page; and EWK_COOKIE_JAR_ACCEPT_NEVER, + * which rejects all cookies. + * + * @param p the acceptance policy + */ +EAPI void ewk_cookies_policy_set(Ewk_Cookie_Policy p) +{ +#ifdef WTF_USE_SOUP +#ifdef HAVE_LIBSOUP_2_29_90 + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + SoupCookieJarAcceptPolicy policy; + + policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + switch (p) { + case EWK_COOKIE_JAR_ACCEPT_NEVER: + policy = SOUP_COOKIE_JAR_ACCEPT_NEVER; + break; + case EWK_COOKIE_JAR_ACCEPT_ALWAYS: + policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + break; + case EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: + policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + break; + } + + soup_cookie_jar_set_accept_policy(cookieJar, policy); +#endif +#endif +} + +/* + * Gets the acceptance policy used in the current cookie jar. + * + * @returns the current acceptance policy + */ +EAPI Ewk_Cookie_Policy ewk_cookies_policy_get() +{ + Ewk_Cookie_Policy ewk_policy = EWK_COOKIE_JAR_ACCEPT_ALWAYS; +#ifdef WTF_USE_SOUP +#ifdef HAVE_LIBSOUP_2_29_90 + SoupCookieJar* cookieJar = WebCore::defaultCookieJar(); + SoupCookieJarAcceptPolicy policy; + + policy = soup_cookie_jar_get_accept_policy(cookieJar); + switch (policy) { + case SOUP_COOKIE_JAR_ACCEPT_NEVER: + ewk_policy = EWK_COOKIE_JAR_ACCEPT_NEVER; + break; + case SOUP_COOKIE_JAR_ACCEPT_ALWAYS: + ewk_policy = EWK_COOKIE_JAR_ACCEPT_ALWAYS; + break; + case SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: + ewk_policy = EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + break; + } +#endif +#endif + + return ewk_policy; +} diff --git a/Source/WebKit/efl/ewk/ewk_cookies.h b/Source/WebKit/efl/ewk/ewk_cookies.h new file mode 100644 index 0000000..6ba3c9a --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_cookies.h @@ -0,0 +1,64 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_cookies_h +#define ewk_cookies_h + +#include "ewk_eapi.h" +#include <Eina.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct _Ewk_Cookie { + char *name; + char *value; + char *domain; + char *path; + time_t expires; + Eina_Bool secure; + Eina_Bool http_only; +}; + +typedef struct _Ewk_Cookie Ewk_Cookie; + +enum _Ewk_Cookie_Policy { + EWK_COOKIE_JAR_ACCEPT_NEVER, + EWK_COOKIE_JAR_ACCEPT_ALWAYS, + EWK_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY +}; + +typedef enum _Ewk_Cookie_Policy Ewk_Cookie_Policy; + +/************************** Exported functions ***********************/ + +EAPI Eina_Bool ewk_cookies_file_set(const char *filename); +EAPI void ewk_cookies_clear(); +EAPI Eina_List* ewk_cookies_get_all(); +EAPI void ewk_cookies_cookie_del(Ewk_Cookie *cookie); +EAPI void ewk_cookies_cookie_free(Ewk_Cookie *cookie); +EAPI void ewk_cookies_policy_set(Ewk_Cookie_Policy p); +EAPI Ewk_Cookie_Policy ewk_cookies_policy_get(); + +#ifdef __cplusplus +} +#endif +#endif // ewk_cookies_h diff --git a/Source/WebKit/efl/ewk/ewk_eapi.h b/Source/WebKit/efl/ewk/ewk_eapi.h new file mode 100644 index 0000000..adb8d7b --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_eapi.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_eapi_h +#define ewk_eapi_h + +#ifdef EAPI +# undef EAPI +#endif + +#ifdef _WIN32 +# ifdef BUILDING_WEBKIT +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif /* ! DLL_EXPORT */ +# else +# define EAPI __declspec(dllimport) +# endif /* ! EFL_EINA_BUILD */ +#else +# ifdef __GNUC__ +# if __GNUC__ >= 4 +# define EAPI __attribute__ ((visibility("default"))) +# else +# define EAPI +# endif +# else +# define EAPI +# endif +#endif + +#endif // ewk_eapi_h diff --git a/Source/WebKit/efl/ewk/ewk_frame.cpp b/Source/WebKit/efl/ewk/ewk_frame.cpp new file mode 100644 index 0000000..f41caae --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_frame.cpp @@ -0,0 +1,2037 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Uncomment to view frame regions and debug messages +// #define EWK_FRAME_DEBUG + +#include "config.h" +#include "ewk_frame.h" + +#include "DocumentMarkerController.h" +#include "EWebKit.h" +#include "EventHandler.h" +#include "FocusController.h" +#include "FrameLoaderClientEfl.h" +#include "FrameTree.h" +#include "FrameView.h" +#include "HTMLPlugInElement.h" +#include "HistoryItem.h" +#include "HitTestResult.h" +#include "IntSize.h" +#include "KURL.h" +#include "PlatformKeyboardEvent.h" +#include "PlatformMouseEvent.h" +#include "PlatformTouchEvent.h" +#include "PlatformWheelEvent.h" +#include "ProgressTracker.h" +#include "RefPtr.h" +#include "RenderTheme.h" +#include "ResourceRequest.h" +#include "ScriptValue.h" +#include "SharedBuffer.h" +#include "SubstituteData.h" +#include "WindowsKeyboardCodes.h" +#include "ewk_private.h" + +#include <Eina.h> +#include <Evas.h> +#include <algorithm> +#include <eina_safety_checks.h> +#include <wtf/text/CString.h> + +static const char EWK_FRAME_TYPE_STR[] = "EWK_Frame"; + +struct Ewk_Frame_Smart_Data { + Evas_Object_Smart_Clipped_Data base; + Evas_Object* self; + Evas_Object* view; +#ifdef EWK_FRAME_DEBUG + Evas_Object* region; +#endif + WebCore::Frame* frame; + const char* theme; + const char* title; + const char* uri; + const char* name; + struct { + Evas_Coord w, h; + } contents_size; + Eina_Bool textZoom:1; + Eina_Bool editable:1; +}; + +struct Eina_Iterator_Ewk_Frame { + Eina_Iterator base; + Evas_Object* obj; + WebCore::Frame* last; +}; + +#ifndef EWK_TYPE_CHECK +#define EWK_FRAME_TYPE_CHECK(o, ...) do { } while (0) +#else +#define EWK_FRAME_TYPE_CHECK(o, ...) \ + do { \ + const char* _tmp_otype = evas_object_type_get(o); \ + if (EINA_UNLIKELY(_tmp_otype != EWK_FRAME_TYPE_STR)) { \ + EINA_LOG_CRIT \ + ("%p (%s) is not of an ewk_frame!", o, \ + _tmp_otype ? _tmp_otype : "(null)"); \ + return __VA_ARGS__; \ + } \ + } while (0) +#endif + +#define EWK_FRAME_SD_GET(o, ptr) \ + Ewk_Frame_Smart_Data* ptr = (Ewk_Frame_Smart_Data*)evas_object_smart_data_get(o) + +#define EWK_FRAME_SD_GET_OR_RETURN(o, ptr, ...) \ + EWK_FRAME_TYPE_CHECK(o, __VA_ARGS__); \ + EWK_FRAME_SD_GET(o, ptr); \ + if (!ptr) { \ + CRITICAL("no smart data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return __VA_ARGS__; \ + } + +static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL; + +#ifdef EWK_FRAME_DEBUG +static inline void _ewk_frame_debug(Evas_Object* o) +{ + Evas_Object* clip, *parent; + Evas_Coord x, y, w, h, cx, cy, cw, ch; + int r, g, b, a, cr, cg, cb, ca; + + evas_object_color_get(o, &r, &g, &b, &a); + evas_object_geometry_get(o, &x, &y, &w, &h); + + clip = evas_object_clip_get(o); + evas_object_color_get(clip, &cr, &cg, &cb, &ca); + evas_object_geometry_get(clip, &cx, &cy, &cw, &ch); + + fprintf(stderr, "%p: type=%s name=%s, visible=%d, color=%02x%02x%02x%02x, %d,%d+%dx%d, clipper=%p (%d, %02x%02x%02x%02x, %d,%d+%dx%d)\n", + o, evas_object_type_get(o), evas_object_name_get(o), evas_object_visible_get(o), + r, g, b, a, x, y, w, h, + clip, evas_object_visible_get(clip), cr, cg, cb, ca, cx, cy, cw, ch); + parent = evas_object_smart_parent_get(o); + if (!parent) + fprintf(stderr, "\n"); + else + _ewk_frame_debug(parent); +} +#endif + +static WebCore::FrameLoaderClientEfl* _ewk_frame_loader_efl_get(WebCore::Frame* frame) +{ + return static_cast<WebCore::FrameLoaderClientEfl*>(frame->loader()->client()); +} + +static inline Evas_Object* kit(WebCore::Frame* frame) +{ + if (!frame) + return 0; + WebCore::FrameLoaderClientEfl* fl = _ewk_frame_loader_efl_get(frame); + if (!fl) + return 0; + return fl->webFrame(); +} + +static Eina_Bool _ewk_frame_children_iterator_next(Eina_Iterator_Ewk_Frame* it, Evas_Object** data) +{ + EWK_FRAME_SD_GET_OR_RETURN(it->obj, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + + WebCore::FrameTree* tree = sd->frame->tree(); // check if it's still valid + EINA_SAFETY_ON_NULL_RETURN_VAL(tree, EINA_FALSE); + + WebCore::Frame* frame; + if (it->last) + frame = it->last->tree()->nextSibling(); + else + frame = tree->firstChild(); + + if (!frame) + return EINA_FALSE; + + *data = kit(frame); + return EINA_TRUE; +} + +static Evas_Object* _ewk_frame_children_iterator_get_container(Eina_Iterator_Ewk_Frame* it) +{ + return it->obj; +} + +static void _ewk_frame_smart_add(Evas_Object* o) +{ + EWK_FRAME_SD_GET(o, sd); + + if (!sd) { + sd = (Ewk_Frame_Smart_Data*)calloc(1, sizeof(Ewk_Frame_Smart_Data)); + if (!sd) + CRITICAL("could not allocate Ewk_Frame_Smart_Data"); + else + evas_object_smart_data_set(o, sd); + } + + sd->self = o; + + _parent_sc.add(o); + evas_object_static_clip_set(sd->base.clipper, EINA_FALSE); + evas_object_move(sd->base.clipper, 0, 0); + evas_object_resize(sd->base.clipper, 0, 0); + +#ifdef EWK_FRAME_DEBUG + sd->region = evas_object_rectangle_add(sd->base.evas); + static int i = 0; + switch (i) { + case 0: + evas_object_color_set(sd->region, 128, 0, 0, 128); + break; + case 1: + evas_object_color_set(sd->region, 0, 128, 0, 128); + break; + case 2: + evas_object_color_set(sd->region, 0, 0, 128, 128); + break; + case 3: + evas_object_color_set(sd->region, 128, 0, 0, 128); + break; + case 4: + evas_object_color_set(sd->region, 128, 128, 0, 128); + break; + case 5: + evas_object_color_set(sd->region, 128, 0, 128, 128); + break; + case 6: + evas_object_color_set(sd->region, 0, 128, 128, 128); + break; + default: + break; + } + i++; + if (i > 6) + i = 0; + + evas_object_smart_member_add(sd->region, o); + evas_object_hide(sd->region); +#endif +} + +static void _ewk_frame_smart_del(Evas_Object* o) +{ + WRN("o=%p", o); // XXX REMOVE ME LATER + EWK_FRAME_SD_GET(o, sd); + + if (sd) { + if (sd->frame) { + WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(sd->frame); + flc->setWebFrame(0); + sd->frame->loader()->cancelAndClear(); + sd->frame = 0; + } + + eina_stringshare_del(sd->title); + eina_stringshare_del(sd->uri); + eina_stringshare_del(sd->name); + } + + _parent_sc.del(o); +} + +static void _ewk_frame_smart_resize(Evas_Object* o, Evas_Coord w, Evas_Coord h) +{ + EWK_FRAME_SD_GET(o, sd); + evas_object_resize(sd->base.clipper, w, h); + +#ifdef EWK_FRAME_DEBUG + evas_object_resize(sd->region, w, h); + Evas_Coord x, y; + evas_object_geometry_get(sd->region, &x, &y, &w, &h); + INF("region=%p, visible=%d, geo=%d,%d + %dx%d", + sd->region, evas_object_visible_get(sd->region), x, y, w, h); + _ewk_frame_debug(o); +#endif +} + +static void _ewk_frame_smart_set(Evas_Smart_Class* api) +{ + evas_object_smart_clipped_smart_set(api); + api->add = _ewk_frame_smart_add; + api->del = _ewk_frame_smart_del; + api->resize = _ewk_frame_smart_resize; +} + +static inline Evas_Smart* _ewk_frame_smart_class_new(void) +{ + static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION(EWK_FRAME_TYPE_STR); + static Evas_Smart* smart = 0; + + if (EINA_UNLIKELY(!smart)) { + evas_object_smart_clipped_smart_set(&_parent_sc); + _ewk_frame_smart_set(&sc); + smart = evas_smart_class_new(&sc); + } + + return smart; +} + +/** + * @internal + * + * Creates a new EFL WebKit Frame object. + * + * Frames are low level entries contained in a page that is contained + * by a view. Usually one operates on the view and not directly on the + * frame. + * + * @param e canvas where to create the frame object. + * + * @return frame object or @c NULL if errors. + */ +Evas_Object* ewk_frame_add(Evas* e) +{ + return evas_object_smart_add(e, _ewk_frame_smart_class_new()); +} + +/** + * Retrieves the ewk_view object that owns this frame. + * + * @param o frame object to get view from. + * + * @return view object or @c NULL if errors. + */ +Evas_Object* ewk_frame_view_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + return sd->view; +} + +/** + * Set the theme path to be used by this frame. + * + * Frames inherit theme from their parent, this will have all frames + * with unset theme to use this one. + * + * @param o frame object to change theme. + * @param path theme path, may be @c NULL to reset to default or inherit parent. + */ +void ewk_frame_theme_set(Evas_Object* o, const char* path) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + if (!eina_stringshare_replace(&sd->theme, path)) + return; + if (sd->frame && sd->frame->view()) { + sd->frame->view()->setEdjeTheme(WTF::String(path)); + sd->frame->page()->theme()->themeChanged(); + } +} + +/** + * Gets the immediate theme set on this frame. + * + * This returns the value set by ewk_frame_theme_set(). Note that if + * it is @c NULL, the frame will inherit parent's theme. + * + * @param o frame object to get theme path. + * + * @return theme path, may be @c NULL if not set. + */ +const char* ewk_frame_theme_get(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + return sd->theme; +} + +/** + * Returns a new iterator over all direct children frames. + * + * Keep frame object intact while iteration happens otherwise frame + * may be destroyed while iterated. + * + * Iteration results are Evas_Object*, so give eina_iterator_next() a + * pointer to it. + * + * @return a newly allocated iterator, free using + * eina_iterator_free(). If not possible to create the + * iterator, @c NULL is returned. + */ +Eina_Iterator* ewk_frame_children_iterator_new(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + Eina_Iterator_Ewk_Frame* it = (Eina_Iterator_Ewk_Frame*) + calloc(1, sizeof(Eina_Iterator_Ewk_Frame)); + if (!it) + return 0; + + EINA_MAGIC_SET(&it->base, EINA_MAGIC_ITERATOR); + it->base.next = FUNC_ITERATOR_NEXT(_ewk_frame_children_iterator_next); + it->base.get_container = FUNC_ITERATOR_GET_CONTAINER(_ewk_frame_children_iterator_get_container); + it->base.free = FUNC_ITERATOR_FREE(free); + it->obj = o; + return &it->base; +} + +/** + * Finds a child frame by its name, recursively. + * + * For pre-defined names, returns @a o if @a name is "_self" or + * "_current", returns @a o's parent frame if @a name is "_parent", + * and returns the main frame if @a name is "_top". Also returns @a o + * if it is the main frame and @a name is either "_parent" or + * "_top". For other names, this function returns the first frame that + * matches @a name. This function searches @a o and its descendents + * first, then @a o's parent and its children moving up the hierarchy + * until a match is found. If no match is found in @a o's hierarchy, + * this function will search for a matching frame in other main frame + * hierarchies. + * + * @return object if found, @c NULL if nothing with that name. + */ +Evas_Object* ewk_frame_child_find(Evas_Object* o, const char* name) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(name, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0); + WTF::String s = WTF::String::fromUTF8(name); + return kit(sd->frame->tree()->find(WTF::AtomicString(s))); +} + +/** + * Ask main frame to load the given URI. + * + * @param o frame object to load uri. + * @param uri uniform resource identifier to load. + */ +Eina_Bool ewk_frame_uri_set(Evas_Object* o, const char* uri) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri)); + WebCore::ResourceRequest req(kurl); + WebCore::FrameLoader* loader = sd->frame->loader(); + loader->load(req, false); + return EINA_TRUE; +} + +/** + * Gets the uri of this frame. + * + * @param o frame object to get uri. + * + * @return frame uri or @c NULL. It's a internal string and should + * not be modified. The string is guaranteed to be stringshared. + */ +const char* ewk_frame_uri_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + return sd->uri; +} + +/** + * Gets the title of this frame. + * + * @param o frame object to get title. + * + * @return frame title or @c NULL. It's a internal string and should + * not be modified. The string is guaranteed to be stringshared. + */ +const char* ewk_frame_title_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + return sd->title; +} + +/** + * Gets the name of this frame. + * + * @param o frame object to get name. + * + * @return frame name or @c NULL. It's a internal string and should + * not be modified. The string is guaranteed to be stringshared. + */ +const char* ewk_frame_name_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + + if (sd->name) + return sd->name; + + if (!sd->frame) { + ERR("could not get name of uninitialized frame."); + return 0; + } + + WTF::String s = sd->frame->tree()->uniqueName(); + WTF::CString cs = s.utf8(); + sd->name = eina_stringshare_add_length(cs.data(), cs.length()); + return sd->name; +} + +/** + * Get last known contents size. + * + * @param o frame object to get contents size. + * @param w where to store contents size width. May be @c NULL. + * @param h where to store contents size height. May be @c NULL. + * + * @return @c EINA_TRUE on success or @c EINA_FALSE on failure and + * @a w and @a h will be zeroed. + */ +Eina_Bool ewk_frame_contents_size_get(const Evas_Object* o, Evas_Coord* w, Evas_Coord* h) +{ + if (w) + *w = 0; + if (h) + *h = 0; + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + if (w) + *w = sd->contents_size.w; + if (h) + *h = sd->contents_size.h; + return EINA_TRUE; +} + +static Eina_Bool _ewk_frame_contents_set_internal(Ewk_Frame_Smart_Data *sd, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri, const char* unreachable_uri) +{ + if (contents_size < 1) + contents_size = strlen(contents); + if (!mime_type) + mime_type = "text/html"; + if (!encoding) + encoding = "UTF-8"; + if (!base_uri) + base_uri = "about:blank"; + + WebCore::KURL baseKURL(WebCore::KURL(), WTF::String::fromUTF8(base_uri)); + WebCore::KURL unreachableKURL; + if (unreachable_uri) + unreachableKURL = WebCore::KURL(WebCore::KURL(), WTF::String::fromUTF8(unreachable_uri)); + else + unreachableKURL = WebCore::KURL(); + + WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(contents, contents_size); + WebCore::SubstituteData substituteData + (buffer.release(), + WTF::String::fromUTF8(mime_type), + WTF::String::fromUTF8(encoding), + baseKURL, unreachableKURL); + WebCore::ResourceRequest request(baseKURL); + + sd->frame->loader()->load(request, substituteData, false); + return EINA_TRUE; +} + +/** + * Requests loading the given contents in this frame. + * + * @param o frame object to load document. + * @param contents what to load into frame. Must not be @c NULL. + * @param contents_size byte size of data in @a contents. + * If zero, strlen() is used. + * @param mime_type type of @a contents data. If @c NULL "text/html" is assumed. + * @param encoding used for @a contents data. If @c NULL "UTF-8" is assumed. + * @param base_uri base uri to use for relative resources. May be @c NULL. + * If provided must be an absolute uri. + * + * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors. + */ +Eina_Bool ewk_frame_contents_set(Evas_Object* o, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE); + return _ewk_frame_contents_set_internal + (sd, contents, contents_size, mime_type, encoding, base_uri, 0); +} + +/** + * Requests loading alternative contents for unreachable URI in this frame. + * + * This is similar to ewk_frame_contents_set(), but is used when some + * URI failed to load, using the provided content instead. The main + * difference is that back-forward navigation list is not changed. + * + * @param o frame object to load document. + * @param contents what to load into frame. Must not be @c NULL. + * @param contents_size byte size of data in @a contents. + * If zero, strlen() is used. + * @param mime_type type of @a contents data. If @c NULL "text/html" is assumed. + * @param encoding used for @a contents data. If @c NULL "UTF-8" is assumed. + * @param base_uri base uri to use for relative resources. May be @c NULL. + * If provided must be an absolute uri. + * @param unreachable_uri the URI that failed to load and is getting the + * alternative representation. + * + * @return @c EINA_TRUE on successful request, @c EINA_FALSE on errors. + */ +Eina_Bool ewk_frame_contents_alternate_set(Evas_Object* o, const char* contents, size_t contents_size, const char* mime_type, const char* encoding, const char* base_uri, const char* unreachable_uri) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(contents, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(unreachable_uri, EINA_FALSE); + return _ewk_frame_contents_set_internal + (sd, contents, contents_size, mime_type, encoding, base_uri, + unreachable_uri); +} + +/** + * Requests execution of given script. + * + * @param o frame object to execute script. + * @param script java script to execute. + * + * @return @c EINA_TRUE if request was done, @c EINA_FALSE on errors. + */ +Eina_Bool ewk_frame_script_execute(Evas_Object* o, const char* script) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(script, EINA_FALSE); + sd->frame->script()->executeScript(WTF::String::fromUTF8(script), true); + return EINA_TRUE; +} + +/** + * Gets if frame is editable. + * + * @param o frame object to get editable state. + * + * @return @c EINA_TRUE if editable, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_editable_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return sd->editable; +} + +/** + * Sets if frame is editable. + * + * @param o frame object to set editable state. + * @param editable new state. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_editable_set(Evas_Object* o, Eina_Bool editable) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + editable = !!editable; + if (sd->editable == editable) + return EINA_TRUE; + if (editable) + sd->frame->editor()->applyEditingStyleToBodyElement(); + return EINA_TRUE; +} + +/** + * Get the copy of the selection text. + * + * @param o frame object to get selection text. + * + * @return newly allocated string or @c NULL if nothing is selected or failure. + */ +char* ewk_frame_selection_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0); + WTF::CString s = sd->frame->editor()->selectedText().utf8(); + if (s.isNull()) + return 0; + return strdup(s.data()); +} + +static inline Eina_Bool _ewk_frame_editor_command(Ewk_Frame_Smart_Data* sd, const char* command) +{ + return sd->frame->editor()->command(WTF::String::fromUTF8(command)).execute(); +} + +/** + * Unselects whatever was selected. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_none(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "Unselect"); +} + +/** + * Selects everything. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_all(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "SelectAll"); +} + +/** + * Selects the current paragrah. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_paragraph(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "SelectParagraph"); +} + +/** + * Selects the current sentence. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_sentence(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "SelectSentence"); +} + +/** + * Selects the current line. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_line(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "SelectLine"); +} + +/** + * Selects the current word. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_select_word(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return _ewk_frame_editor_command(sd, "SelectWord"); +} + +/** + * Search the given text string in document. + * + * @param o frame object where to search text. + * @param string reference string to search. + * @param case_sensitive if search should be case sensitive or not. + * @param forward if search is from cursor and on or backwards. + * @param wrap if search should wrap at end. + * + * @return @c EINA_TRUE if found, @c EINA_FALSE if not or failure. + */ +Eina_Bool ewk_frame_text_search(const Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE); + + return sd->frame->editor()->findString(WTF::String::fromUTF8(string), forward, case_sensitive, wrap, true); +} + +/** + * Mark matches the given text string in document. + * + * @param o frame object where to search text. + * @param string reference string to match. + * @param case_sensitive if match should be case sensitive or not. + * @param highlight if matches should be highlighted. + * @param limit maximum amount of matches, or zero to unlimited. + * + * @return number of matches. + */ +unsigned int ewk_frame_text_matches_mark(Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0); + + sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight); + return sd->frame->editor()->countMatchesForText(WTF::String::fromUTF8(string), case_sensitive, limit, true); +} + +/** + * Reverses the effect of ewk_frame_text_matches_mark() + * + * @param o frame object where to search text. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE for failure. + */ +Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + + sd->frame->document()->markers()->removeMarkers(WebCore::DocumentMarker::TextMatch); + return EINA_TRUE; +} + +/** + * Set if should highlight matches marked with ewk_frame_text_matches_mark(). + * + * @param o frame object where to set if matches are highlighted or not. + * @param highlight if @c EINA_TRUE, matches will be highlighted. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE for failure. + */ +Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlight) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + sd->frame->editor()->setMarkedTextMatchesAreHighlighted(highlight); + return EINA_TRUE; +} + +/** + * Get if should highlight matches marked with ewk_frame_text_matches_mark(). + * + * @param o frame object to query if matches are highlighted or not. + * + * @return @c EINA_TRUE if they are highlighted, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + return sd->frame->editor()->markedTextMatchesAreHighlighted(); +} + +/** + * Comparison function used by ewk_frame_text_matches_nth_pos_get + */ +static bool _ewk_frame_rect_cmp_less_than(const WebCore::IntRect& i, const WebCore::IntRect& j) +{ + return (i.y() < j.y() || (i.y() == j.y() && i.x() < j.x())); +} + +/** + * Predicate used by ewk_frame_text_matches_nth_pos_get + */ +static bool _ewk_frame_rect_is_negative_value(const WebCore::IntRect& i) +{ + return (i.x() < 0 || i.y() < 0); +} + +/** + * Get x, y position of n-th text match in frame + * + * @param o frame object where matches are highlighted. + * @param n index of element + * @param x where to return x position. May be @c NULL. + * @param y where to return y position. May be @c NULL. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE for failure - when no matches found or + * n bigger than search results. + */ +Eina_Bool ewk_frame_text_matches_nth_pos_get(Evas_Object* o, size_t n, int* x, int* y) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + + Vector<WebCore::IntRect> intRects = sd->frame->document()->markers()->renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch); + + /* remove useless values */ + std::remove_if(intRects.begin(), intRects.end(), _ewk_frame_rect_is_negative_value); + + if (intRects.isEmpty() || n > intRects.size()) + return EINA_FALSE; + + std::sort(intRects.begin(), intRects.end(), _ewk_frame_rect_cmp_less_than); + + if (x) + *x = intRects[n - 1].x(); + if (y) + *y = intRects[n - 1].y(); + return EINA_TRUE; +} + +/** + * Ask frame to stop loading. + * + * @param o frame object to stop loading. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_stop(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + sd->frame->loader()->stopAllLoaders(); + return EINA_TRUE; +} + +/** + * Ask frame to reload current document. + * + * @param o frame object to reload. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_reload_full() + */ +Eina_Bool ewk_frame_reload(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + sd->frame->loader()->reload(); + return EINA_TRUE; +} + +/** + * Ask frame to fully reload current document, using no previous caches. + * + * @param o frame object to reload. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_reload_full(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + sd->frame->loader()->reload(true); + return EINA_TRUE; +} + +/** + * Ask frame to navigate back in history. + * + * @param o frame object to navigate back. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_navigate() + */ +Eina_Bool ewk_frame_back(Evas_Object* o) +{ + return ewk_frame_navigate(o, -1); +} + +/** + * Ask frame to navigate forward in history. + * + * @param o frame object to navigate forward. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_navigate() + */ +Eina_Bool ewk_frame_forward(Evas_Object* o) +{ + return ewk_frame_navigate(o, 1); +} + +/** + * Navigate back or forward in history. + * + * @param o frame object to navigate. + * @param steps if positive navigates that amount forwards, if negative + * does backwards. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_navigate(Evas_Object* o, int steps) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + WebCore::Page* page = sd->frame->page(); + if (!page->canGoBackOrForward(steps)) + return EINA_FALSE; + page->goBackOrForward(steps); + return EINA_TRUE; +} + +/** + * Check if it is possible to navigate backwards one item in history. + * + * @param o frame object to check if backward navigation is possible. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + * + * @see ewk_frame_navigate_possible() + */ +Eina_Bool ewk_frame_back_possible(Evas_Object* o) +{ + return ewk_frame_navigate_possible(o, -1); +} + +/** + * Check if it is possible to navigate forwards one item in history. + * + * @param o frame object to check if forward navigation is possible. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + * + * @see ewk_frame_navigate_possible() + */ +Eina_Bool ewk_frame_forward_possible(Evas_Object* o) +{ + return ewk_frame_navigate_possible(o, 1); +} + +/** + * Check if it is possible to navigate given @a steps in history. + * + * @param o frame object to navigate. + * @param steps if positive navigates that amount forwards, if negative + * does backwards. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_navigate_possible(Evas_Object* o, int steps) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + WebCore::Page* page = sd->frame->page(); + return page->canGoBackOrForward(steps); +} + +/** + * Get current zoom level used by this frame. + * + * @param o frame object to query zoom level. + * + * @return zoom level or -1.0 on failure. + */ +float ewk_frame_zoom_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, -1.0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, -1.0); + + if (sd->textZoom) + return sd->frame->textZoomFactor(); + return sd->frame->pageZoomFactor(); +} + +/** + * Set current zoom level used by this frame. + * + * @param o frame object to change zoom level. + * @param zoom new level. + * + * @return @c EINA_TRUE on success or @c EINA_FALSE on failure. + * + * @see ewk_frame_zoom_text_only_set() + */ +Eina_Bool ewk_frame_zoom_set(Evas_Object* o, float zoom) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + if (sd->textZoom) + sd->frame->setTextZoomFactor(zoom); + else + sd->frame->setPageZoomFactor(zoom); + return EINA_TRUE; +} + +/** + * Query if zoom level just applies to text and not other elements. + * + * @param o frame to query setting. + * + * @return @c EINA_TRUE if just text are scaled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_zoom_text_only_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return sd->textZoom; +} + +/** + * Set if zoom level just applies to text and not other elements. + * + * @param o frame to change setting. + * @param setting @c EINA_TRUE if zoom should just be applied to text. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_zoom_text_only_set(Evas_Object* o, Eina_Bool setting) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + if (sd->textZoom == setting) + return EINA_TRUE; + + float zoom_level = sd->textZoom ? sd->frame->textZoomFactor() : sd->frame->pageZoomFactor(); + sd->textZoom = setting; + if (sd->textZoom) + sd->frame->setPageAndTextZoomFactors(1, zoom_level); + else + sd->frame->setPageAndTextZoomFactors(zoom_level, 1); + return EINA_TRUE; +} + +/** + * Free hit test created with ewk_frame_hit_test_new(). + * + * @param hit_test instance. Must @b not be @c NULL. + */ +void ewk_frame_hit_test_free(Ewk_Hit_Test* hit_test) +{ + EINA_SAFETY_ON_NULL_RETURN(hit_test); + eina_stringshare_del(hit_test->title); + eina_stringshare_del(hit_test->alternate_text); + eina_stringshare_del(hit_test->link.text); + eina_stringshare_del(hit_test->link.url); + eina_stringshare_del(hit_test->link.title); + free(hit_test); +} + +/** + * Creates a new hit test for given frame and point. + * + * @param o frame to do hit test on. + * @param x horizontal position to query. + * @param y vertical position to query. + * + * @return a newly allocated hit test on success, @c NULL otherwise. + * Free memory with ewk_frame_hit_test_free() + */ +Ewk_Hit_Test* ewk_frame_hit_test_new(const Evas_Object* o, int x, int y) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, 0); + + WebCore::FrameView* view = sd->frame->view(); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->contentRenderer(), 0); + + WebCore::HitTestResult result = sd->frame->eventHandler()->hitTestResultAtPoint + (view->windowToContents(WebCore::IntPoint(x, y)), + /*allowShadowContent*/ false, /*ignoreClipping*/ true); + + if (result.scrollbar()) + return 0; + if (!result.innerNode()) + return 0; + + Ewk_Hit_Test* hit_test = (Ewk_Hit_Test*)calloc(1, sizeof(Ewk_Hit_Test)); + if (!hit_test) { + CRITICAL("Could not allocate memory for hit test."); + return 0; + } + + hit_test->x = result.point().x(); + hit_test->y = result.point().y(); +#if 0 + // FIXME + hit_test->bounding_box.x = result.boundingBox().x(); + hit_test->bounding_box.y = result.boundingBox().y(); + hit_test->bounding_box.w = result.boundingBox().width(); + hit_test->bounding_box.h = result.boundingBox().height(); +#else + hit_test->bounding_box.x = 0; + hit_test->bounding_box.y = 0; + hit_test->bounding_box.w = 0; + hit_test->bounding_box.h = 0; +#endif + + WebCore::TextDirection dir; + hit_test->title = eina_stringshare_add(result.title(dir).utf8().data()); + hit_test->alternate_text = eina_stringshare_add(result.altDisplayString().utf8().data()); + if (result.innerNonSharedNode() && result.innerNonSharedNode()->document() + && result.innerNonSharedNode()->document()->frame()) + hit_test->frame = kit(result.innerNonSharedNode()->document()->frame()); + + hit_test->link.text = eina_stringshare_add(result.textContent().utf8().data()); + hit_test->link.url = eina_stringshare_add(result.absoluteLinkURL().prettyURL().utf8().data()); + hit_test->link.title = eina_stringshare_add(result.titleDisplayString().utf8().data()); + hit_test->link.target_frame = kit(result.targetFrame()); + + hit_test->flags.editable = result.isContentEditable(); + hit_test->flags.selected = result.isSelected(); + + return hit_test; +} + +/** + * Relative scroll of given frame. + * + * @param o frame object to scroll. + * @param dx horizontal offset to scroll. + * @param dy vertical offset to scroll. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + */ +Eina_Bool +ewk_frame_scroll_add(Evas_Object* o, int dx, int dy) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + sd->frame->view()->scrollBy(WebCore::IntSize(dx, dy)); + return EINA_TRUE; +} + +/** + * Set absolute scroll of given frame. + * + * Both values are from zero to the contents size minus the viewport + * size. See ewk_frame_scroll_size_get(). + * + * @param o frame object to scroll. + * @param x horizontal position to scroll. + * @param y vertical position to scroll. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + */ +Eina_Bool +ewk_frame_scroll_set(Evas_Object* o, int x, int y) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + sd->frame->view()->setScrollPosition(WebCore::IntPoint(x, y)); + return EINA_TRUE; +} + +/** + * Get the possible scroll size of given frame. + * + * Possible scroll size is contents size minus the viewport + * size. It's the last allowed value for ewk_frame_scroll_set() + * + * @param o frame object to scroll. + * @param w where to return horizontal size that is possible to + * scroll. May be @c NULL. + * @param h where to return vertical size that is possible to scroll. + * May be @c NULL. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and + * values are zeroed. + */ +Eina_Bool +ewk_frame_scroll_size_get(const Evas_Object* o, int* w, int* h) +{ + if (w) + *w = 0; + if (h) + *h = 0; + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + WebCore::IntPoint point = sd->frame->view()->maximumScrollPosition(); + if (w) + *w = point.x(); + if (h) + *h = point.y(); + return EINA_TRUE; +} + +/** + * Get the current scroll position of given frame. + * + * @param o frame object to scroll. + * @param x where to return horizontal position. May be @c NULL. + * @param y where to return vertical position. May be @c NULL. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and + * values are zeroed. + */ +Eina_Bool +ewk_frame_scroll_pos_get(const Evas_Object* o, int* x, int* y) +{ + if (x) + *x = 0; + if (y) + *y = 0; + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + WebCore::IntPoint pos = sd->frame->view()->scrollPosition(); + if (x) + *x = pos.x(); + if (y) + *y = pos.y(); + return EINA_TRUE; +} + +/** + * Get the current frame visible content geometry. + * + * @param o frame object to query visible content geometry. + * @param include_scrollbars whenever to include scrollbars size. + * @param x horizontal position. May be @c NULL. + * @param y vertical position. May be @c NULL. + * @param w width. May be @c NULL. + * @param h height. May be @c NULL. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise and + * values are zeroed. + */ +Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object* o, Eina_Bool include_scrollbars, int* x, int* y, int* w, int* h) +{ + if (x) + *x = 0; + if (y) + *y = 0; + if (w) + *w = 0; + if (h) + *h = 0; + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + WebCore::IntRect rect = sd->frame->view()->visibleContentRect(include_scrollbars); + if (x) + *x = rect.x(); + if (y) + *y = rect.y(); + if (w) + *w = rect.width(); + if (h) + *h = rect.height(); + return EINA_TRUE; +} + +/** + * Get the current paintsEntireContents flag. + * + * This flag tells if dirty areas should be repainted even if they are + * out of the screen. + * + * @param o frame object to query paintsEntireContents flag. + * + * @return @c EINA_TRUE if repainting any dirty area, @c EINA_FALSE + * otherwise. + */ +Eina_Bool ewk_frame_paint_full_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame->view(), EINA_FALSE); + return sd->frame->view()->paintsEntireContents(); +} + +/** + * Set the current paintsEntireContents flag. + * + * This flag tells if dirty areas should be repainted even if they are + * out of the screen. + * + * @param o frame object to set paintsEntireContents flag. + * @param flag @c EINA_TRUE if want to always repaint any dirty area, + * @c EINA_FALSE otherwise. + */ +void ewk_frame_paint_full_set(Evas_Object* o, Eina_Bool flag) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->frame); + EINA_SAFETY_ON_NULL_RETURN(sd->frame->view()); + sd->frame->view()->setPaintsEntireContents(flag); +} + +/** + * Feed the focus in signal to this frame. + * + * @param o frame object to focus. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_focus_in(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + WebCore::FocusController* c = sd->frame->page()->focusController(); + c->setFocusedFrame(sd->frame); + return EINA_TRUE; +} + +/** + * Feed the focus out signal to this frame. + * + * @param o frame object to remove focus. + */ +Eina_Bool ewk_frame_feed_focus_out(Evas_Object* o) +{ + // TODO: what to do on focus out? + ERR("what to do?"); + return EINA_FALSE; +} + +/** + * Feed the mouse wheel event to the frame. + * + * @param o frame object to feed event. + * @param ev mouse wheel event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object* o, const Evas_Event_Mouse_Wheel* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + WebCore::FrameView* view = sd->frame->view(); + DBG("o=%p, view=%p, direction=%d, z=%d, pos=%d,%d", + o, view, ev->direction, ev->z, ev->canvas.x, ev->canvas.y); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + WebCore::PlatformWheelEvent event(ev); + return sd->frame->eventHandler()->handleWheelEvent(event); +} + +/** + * Feed the mouse down event to the frame. + * + * @param o frame object to feed event. + * @param ev mouse down event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_mouse_down(Evas_Object* o, const Evas_Event_Mouse_Down* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + WebCore::FrameView* view = sd->frame->view(); + DBG("o=%p, view=%p, button=%d, pos=%d,%d", + o, view, ev->button, ev->canvas.x, ev->canvas.y); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + Evas_Coord x, y; + evas_object_geometry_get(sd->view, &x, &y, 0, 0); + + WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y)); + return sd->frame->eventHandler()->handleMousePressEvent(event); +} + +/** + * Feed the mouse up event to the frame. + * + * @param o frame object to feed event. + * @param ev mouse up event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_mouse_up(Evas_Object* o, const Evas_Event_Mouse_Up* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + WebCore::FrameView* view = sd->frame->view(); + DBG("o=%p, view=%p, button=%d, pos=%d,%d", + o, view, ev->button, ev->canvas.x, ev->canvas.y); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + Evas_Coord x, y; + evas_object_geometry_get(sd->view, &x, &y, 0, 0); + + WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y)); + return sd->frame->eventHandler()->handleMouseReleaseEvent(event); +} + +/** + * Feed the mouse move event to the frame. + * + * @param o frame object to feed event. + * @param ev mouse move event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_mouse_move(Evas_Object* o, const Evas_Event_Mouse_Move* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + WebCore::FrameView* view = sd->frame->view(); + DBG("o=%p, view=%p, pos: old=%d,%d, new=%d,%d, buttons=%d", + o, view, ev->cur.canvas.x, ev->cur.canvas.y, + ev->prev.canvas.x, ev->prev.canvas.y, ev->buttons); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + Evas_Coord x, y; + evas_object_geometry_get(sd->view, &x, &y, 0, 0); + + WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y)); + return sd->frame->eventHandler()->mouseMoved(event); +} + +Eina_Bool ewk_frame_feed_touch_event(Evas_Object* o, Ewk_Touch_Event_Type action, Eina_List* points, int metaState) +{ + Eina_Bool ret = EINA_FALSE; + +#if ENABLE(TOUCH_EVENTS) + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(points, EINA_FALSE); + + Evas_Coord x, y; + evas_object_geometry_get(sd->view, &x, &y, 0, 0); + + WebCore::TouchEventType type = WebCore::TouchStart; + switch (action) { + case EWK_TOUCH_START: + type = WebCore::TouchStart; + break; + case EWK_TOUCH_END: + type = WebCore::TouchEnd; + break; + case EWK_TOUCH_MOVE: + type = WebCore::TouchMove; + break; + case EWK_TOUCH_CANCEL: + type = WebCore::TouchCancel; + break; + default: + return EINA_FALSE; + } + + WebCore::PlatformTouchEvent te(points, WebCore::IntPoint(x, y), type, metaState); + ret = sd->frame->eventHandler()->handleTouchEvent(te); +#endif + return ret; +} + +static inline Eina_Bool _ewk_frame_handle_key_scrolling(WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent &event) +{ + WebCore::ScrollDirection direction; + WebCore::ScrollGranularity granularity; + + int keyCode = event.windowsVirtualKeyCode(); + + switch (keyCode) { + case VK_SPACE: + granularity = WebCore::ScrollByPage; + if (event.shiftKey()) + direction = WebCore::ScrollUp; + else + direction = WebCore::ScrollDown; + break; + case VK_NEXT: + granularity = WebCore::ScrollByPage; + direction = WebCore::ScrollDown; + break; + case VK_PRIOR: + granularity = WebCore::ScrollByPage; + direction = WebCore::ScrollUp; + break; + case VK_HOME: + granularity = WebCore::ScrollByDocument; + direction = WebCore::ScrollUp; + break; + case VK_END: + granularity = WebCore::ScrollByDocument; + direction = WebCore::ScrollDown; + break; + case VK_LEFT: + granularity = WebCore::ScrollByLine; + direction = WebCore::ScrollLeft; + break; + case VK_RIGHT: + granularity = WebCore::ScrollByLine; + direction = WebCore::ScrollRight; + break; + case VK_UP: + direction = WebCore::ScrollUp; + if (event.ctrlKey()) + granularity = WebCore::ScrollByDocument; + else + granularity = WebCore::ScrollByLine; + break; + case VK_DOWN: + direction = WebCore::ScrollDown; + if (event.ctrlKey()) + granularity = WebCore::ScrollByDocument; + else + granularity = WebCore::ScrollByLine; + break; + default: + return EINA_FALSE; + } + + if (frame->eventHandler()->scrollOverflow(direction, granularity)) + return EINA_FALSE; + + frame->view()->scroll(direction, granularity); + return EINA_TRUE; +} + +/** + * Feed the keyboard key down event to the frame. + * + * @param o frame object to feed event. + * @param ev keyboard key down event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_key_down(Evas_Object* o, const Evas_Event_Key_Down* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + DBG("o=%p keyname=%s (key=%s, string=%s)", + o, ev->keyname, ev->key ? ev->key : "", ev->string ? ev->string : ""); + + WebCore::PlatformKeyboardEvent event(ev); + if (sd->frame->eventHandler()->keyEvent(event)) + return EINA_TRUE; + + return _ewk_frame_handle_key_scrolling(sd->frame, event); +} + +/** + * Feed the keyboard key up event to the frame. + * + * @param o frame object to feed event. + * @param ev keyboard key up event. + * + * @return @c EINA_TRUE if it was handled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_frame_feed_key_up(Evas_Object* o, const Evas_Event_Key_Up* ev) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(ev, EINA_FALSE); + + DBG("o=%p keyname=%s (key=%s, string=%s)", + o, ev->keyname, ev->key ? ev->key : "", ev->string ? ev->string : ""); + + WebCore::PlatformKeyboardEvent event(ev); + return sd->frame->eventHandler()->keyEvent(event); +} + +/* internal methods ****************************************************/ + +/** + * @internal + * + * Initialize frame based on actual WebKit frame. + * + * This is internal and should never be called by external users. + */ +Eina_Bool ewk_frame_init(Evas_Object* o, Evas_Object* view, WebCore::Frame* frame) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + if (!sd->frame) { + WebCore::FrameLoaderClientEfl* flc = _ewk_frame_loader_efl_get(frame); + flc->setWebFrame(o); + sd->frame = frame; + sd->view = view; + frame->init(); + return EINA_TRUE; + } + + ERR("frame %p already set for %p, ignored new %p", + sd->frame, o, frame); + return EINA_FALSE; +} + +Evas_Object* ewk_frame_child_add(Evas_Object* o, WTF::PassRefPtr<WebCore::Frame> child, const WTF::String& name, const WebCore::KURL& url, const WTF::String& referrer) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + char buf[256]; + Evas_Object* frame; + WebCore::Frame* cf; + + frame = ewk_frame_add(sd->base.evas); + if (!frame) { + ERR("Could not create ewk_frame object."); + return 0; + } + + cf = child.get(); + if (cf->tree()) + cf->tree()->setName(name); + else + ERR("no tree for child object"); + sd->frame->tree()->appendChild(child); + + if (!ewk_frame_init(frame, sd->view, cf)) { + evas_object_del(frame); + return 0; + } + snprintf(buf, sizeof(buf), "EWK_Frame:child/%s", name.utf8().data()); + evas_object_name_set(frame, buf); + evas_object_smart_member_add(frame, o); + evas_object_show(frame); + + if (!cf->page()) + goto died; + + cf->loader()->loadURLIntoChildFrame(url, referrer, cf); + if (!cf->tree()->parent()) + goto died; + + // TODO: announce frame was created? + return frame; + +died: + CRITICAL("does this work: BEGIN"); + ewk_frame_core_gone(frame); // CONFIRM + evas_object_del(frame); // CONFIRM + CRITICAL("does this work: END"); + return 0; +} + +/** + * @internal + * Frame was destroyed by loader, remove internal reference. + */ +void ewk_frame_core_gone(Evas_Object* o) +{ + DBG("o=%p", o); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + sd->frame = 0; +} + +/** + * @internal + * Retrieve WebCore::Frame associated with this object. + * + * Avoid using this call from outside, add specific ewk_frame_* + * actions instead. + */ +WebCore::Frame* ewk_frame_core_get(const Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, 0); + return sd->frame; +} + + +/** + * @internal + * Reports a resource will be requested. User may override behavior of webkit by + * changing values in @param request. + * + * @param o Frame. + * @param request Request details that user may override. Whenever values on + * this struct changes, it must be properly malloc'd as it will be freed + * afterwards. + * + * Emits signal: "resource,request,willsend" + */ +void ewk_frame_request_will_send(Evas_Object *o, Ewk_Frame_Resource_Request *request) +{ + evas_object_smart_callback_call(o, "resource,request,willsend", request); +} + +/** + * @internal + * Reports that there's a new resource. + * + * @param o Frame. + * @param request New request details. No changes are allowed to fields. + * + * Emits signal: "resource,request,new" + */ +void ewk_frame_request_assign_identifier(Evas_Object *o, const Ewk_Frame_Resource_Request *request) +{ + evas_object_smart_callback_call(o, "resource,request,new", (void *)request); +} + +/** + * @internal + * Reports that first navigation occurred + * + * @param o Frame. + * + * Emits signal: "navigation,first" + */ +void ewk_frame_did_perform_first_navigation(Evas_Object *o) +{ + evas_object_smart_callback_call(o, "navigation,first", 0); +} + +/** + * @internal + * Reports frame will be saved to current state + * + * @param o Frame. + * @param item History item to save details to. + * + * Emits signal: "state,save" + */ +void ewk_frame_view_state_save(Evas_Object *o, WebCore::HistoryItem* item) +{ + evas_object_smart_callback_call(o, "state,save", 0); +} + +/** + * @internal + * Reports the frame started loading something. + * + * Emits signal: "load,started" with no parameters. + */ +void ewk_frame_load_started(Evas_Object* o) +{ + Evas_Object* main_frame; + DBG("o=%p", o); + evas_object_smart_callback_call(o, "load,started", 0); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + ewk_view_load_started(sd->view); + + main_frame = ewk_view_frame_main_get(sd->view); + if (main_frame == o) + ewk_view_frame_main_load_started(sd->view); +} + +/** + * @internal + * Reports the frame started provisional load. + * + * @param o Frame. + * + * Emits signal: "load,provisional" with no parameters. + */ +void ewk_frame_load_provisional(Evas_Object* o) +{ + evas_object_smart_callback_call(o, "load,provisional", 0); +} + +/** + * @internal + * Reports the frame finished first layout. + * + * @param o Frame. + * + * Emits signal: "load,firstlayout,finished" with no parameters. + */ +void ewk_frame_load_firstlayout_finished(Evas_Object *o) +{ + evas_object_smart_callback_call(o, "load,firstlayout,finished", 0); +} + +/** + * @internal + * Reports the frame finished first non empty layout. + * + * @param o Frame. + * + * Emits signal: "load,nonemptylayout,finished" with no parameters. + */ +void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object *o) +{ + evas_object_smart_callback_call(o, "load,nonemptylayout,finished", 0); +} + +/** + * @internal + * Reports the loading of a document has finished on frame. + * + * @param o Frame. + * + * Emits signal: "load,document,finished" with no parameters. + */ +void ewk_frame_load_document_finished(Evas_Object *o) +{ + evas_object_smart_callback_call(o, "load,document,finished", 0); +} + +/** + * @internal + * Reports load finished, optionally with error information. + * + * Emits signal: "load,finished" with pointer to Ewk_Frame_Load_Error + * if any error, or @c NULL if successful load. + * + * @note there should notbe any error stuff here, but trying to be + * compatible with previous WebKit. + */ +void ewk_frame_load_finished(Evas_Object* o, const char* error_domain, int error_code, Eina_Bool is_cancellation, const char* error_description, const char* failing_url) +{ + Ewk_Frame_Load_Error buf, *error; + if (!error_domain) { + DBG("o=%p, success.", o); + error = 0; + } else { + DBG("o=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s", + o, error_domain, error_code, is_cancellation, + error_description, failing_url); + + buf.domain = error_domain; + buf.code = error_code; + buf.is_cancellation = is_cancellation; + buf.description = error_description; + buf.failing_url = failing_url; + buf.frame = o; + error = &buf; + } + evas_object_smart_callback_call(o, "load,finished", error); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + ewk_view_load_finished(sd->view, error); +} + +/** + * @internal + * Reports load failed with error information. + * + * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error. + */ +void ewk_frame_load_error(Evas_Object* o, const char* error_domain, int error_code, Eina_Bool is_cancellation, const char* error_description, const char* failing_url) +{ + Ewk_Frame_Load_Error error; + + DBG("o=%p, error=%s (%d, cancellation=%hhu) \"%s\", url=%s", + o, error_domain, error_code, is_cancellation, + error_description, failing_url); + + EINA_SAFETY_ON_NULL_RETURN(error_domain); + + error.code = error_code; + error.is_cancellation = is_cancellation; + error.domain = error_domain; + error.description = error_description; + error.failing_url = failing_url; + error.frame = o; + evas_object_smart_callback_call(o, "load,error", &error); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + ewk_view_load_error(sd->view, &error); +} + +/** + * @internal + * Reports load progress changed. + * + * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0. + */ +void ewk_frame_load_progress_changed(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->frame); + + // TODO: this is per page, there should be a way to have per-frame. + double progress = sd->frame->page()->progress()->estimatedProgress(); + + DBG("o=%p (p=%0.3f)", o, progress); + + evas_object_smart_callback_call(o, "load,progress", &progress); + ewk_view_load_progress_changed(sd->view); +} + + +/** + * @internal + * + * Reports contents size changed. + */ +void ewk_frame_contents_size_changed(Evas_Object* o, Evas_Coord w, Evas_Coord h) +{ + DBG("o=%p: %dx%d", o, w, h); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + if (sd->contents_size.w == w && sd->contents_size.h == h) + return; + sd->contents_size.w = w; + sd->contents_size.h = h; + // TODO: update something else internally? + + Evas_Coord size[2] = {w, h}; + evas_object_smart_callback_call(o, "contents,size,changed", size); +} + +/** + * @internal + * + * Reports title changed. + */ +void ewk_frame_title_set(Evas_Object* o, const char* title) +{ + DBG("o=%p, title=%s", o, title ? title : "(null)"); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + if (!eina_stringshare_replace(&sd->title, title)) + return; + evas_object_smart_callback_call(o, "title,changed", (void*)sd->title); +} + +void ewk_frame_view_create_for_view(Evas_Object* o, Evas_Object* view) +{ + DBG("o=%p, view=%p", o, view); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->frame); + Evas_Coord w, h; + + if (sd->frame->view()) + return; + + evas_object_geometry_get(view, 0, 0, &w, &h); + + WebCore::IntSize size(w, h); + int r, g, b, a; + WebCore::Color bg; + + ewk_view_bg_color_get(view, &r, &g, &b, &a); + if (!a) + bg = WebCore::Color(0, 0, 0, 0); + else if (a == 255) + bg = WebCore::Color(r, g, b, a); + else + bg = WebCore::Color(r * 255 / a, g * 255 / a, b * 255 / a, a); + + sd->frame->createView(size, bg, !a, WebCore::IntSize(), false); + if (!sd->frame->view()) + return; + + const char* theme = ewk_view_theme_get(view); + sd->frame->view()->setEdjeTheme(theme); + sd->frame->view()->setEvasObject(o); +} + +/** + * @internal + * Reports uri changed and swap internal string reference. + * + * Emits signal: "uri,changed" with new uri as parameter. + */ +Eina_Bool ewk_frame_uri_changed(Evas_Object* o) +{ + EWK_FRAME_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->frame, EINA_FALSE); + WTF::CString uri(sd->frame->loader()->url().prettyURL().utf8()); + + INF("uri=%s", uri.data()); + if (!uri.data()) { + ERR("no uri"); + return EINA_FALSE; + } + + eina_stringshare_replace(&sd->uri, uri.data()); + evas_object_smart_callback_call(o, "uri,changed", (void*)sd->uri); + return EINA_TRUE; +} + +void ewk_frame_force_layout(Evas_Object* o) +{ + DBG("o=%p", o); + EWK_FRAME_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->frame); + WebCore::FrameView* view = sd->frame->view(); + if (view) + view->forceLayout(true); +} + +WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* o, 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) +{ + return 0; +} diff --git a/Source/WebKit/efl/ewk/ewk_frame.h b/Source/WebKit/efl/ewk/ewk_frame.h new file mode 100644 index 0000000..63936f3 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_frame.h @@ -0,0 +1,231 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_frame_h +#define ewk_frame_h + +#include "ewk_eapi.h" +#include <Evas.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * + * WebKit frame smart object. + * + * This object is the low level access to WebKit-EFL browser + * component. It represents both the main and internal frames that + * HTML pages contain. + * + * Every ewk_view has at least one frame, called "main frame" and + * retrieved with ewk_view_frame_main_get(). One can retrieve frame's + * owner view with ewk_frame_view_get(). Parent frame can be retrieved + * with standard smart object's evas_object_smart_parent_get(). + * Children can be accessed with ewk_frame_children_iterator_new() or + * ewk_frame_child_find(). + * + * The following signals (see evas_object_smart_callback_add()) are emitted: + * + * - "title,changed", const char*: title of the main frame changed. + * - "uri,changed", const char*: uri of the main frame changed. + * - "load,document,finished", void: loading of a document has + * finished on this frame. + * - "load,nonemptylayout,finished", void: frame finished first + * non-empty layout. + * - "load,started", void: frame started loading. + * - "load,progress", double*: load progress changed (overall value + * from 0.0 to 1.0, connect to individual frames for fine grained). + * - "load,finished", const Ewk_Frame_Load_Error*: reports load + * finished and as argument @c NULL if successfully or pointer to + * structure defining the error. + * - "load,provisional", void: frame started provisional load. + * - "load,firstlayout,finished", void: frame finished first layout. + * - "load,error", const Ewk_Frame_Load_Error*: reports load failed + * and as argument a pointer to structure defining the error. + * - "contents,size,changed", Evas_Coord[2]: reports contents size + * changed due new layout, script actions or any other events. + * - "navigation,first", void: first navigation occurred. + * - "resource,request,new", Ewk_Frame_Resource_Request*: reports that + * there's a new resource request. + * - "resource,request,willsend", Ewk_Frame_Resource_Request*: a resource will + * be requested. + * - "state,save", void: frame's state will be saved as a history item. + */ + + +/** + * Structure used to report load errors. + * + * Load errors are reported as signal by ewk_view. All the strings are + * temporary references and should @b not be used after the signal + * callback returns. If required, make copies with strdup() or + * eina_stringshare_add() (they are not even guaranteed to be + * stringshared, so must use eina_stringshare_add() and not + * eina_stringshare_ref()). + */ +typedef struct _Ewk_Frame_Load_Error Ewk_Frame_Load_Error; +struct _Ewk_Frame_Load_Error { + int code; /**< numeric error code */ + Eina_Bool is_cancellation; /**< if load failed because it was canceled */ + const char *domain; /**< error domain name */ + const char *description; /**< error description already localized */ + const char *failing_url; /**< the url that failed to load */ + Evas_Object *frame; /**< frame where the failure happened */ +}; + +/** + * Structure used to report resource requests + * + * Details given before a resource is loaded on a given frame. It's used by + * ewk_frame_request_will_send() to inform the details of a to-be-loaded + * resource, allowing them to be overridden. + */ +typedef struct _Ewk_Frame_Resource_Request Ewk_Frame_Resource_Request; +struct _Ewk_Frame_Resource_Request { + const char *url; /**< url of this resource */ + const unsigned long identifier; /**< resource's identifier. Can not be changed */ +}; + +/** + * Structure used to report hit test results. + */ +typedef struct _Ewk_Hit_Test Ewk_Hit_Test; +struct _Ewk_Hit_Test { + int x, y; + struct { + int x, y, w, h; + } bounding_box; + const char *title; + const char *alternate_text; /**< for image, area, input and applet */ + Evas_Object *frame; + struct { + const char *text; + const char *url; + const char *title; + Evas_Object *target_frame; + } link; + struct { + Eina_Bool editable:1; + Eina_Bool selected:1; + } flags; +}; + +typedef enum { + EWK_TOUCH_START, + EWK_TOUCH_END, + EWK_TOUCH_MOVE, + EWK_TOUCH_CANCEL +} Ewk_Touch_Event_Type; + +typedef enum { + EWK_TOUCH_POINT_PRESSED, + EWK_TOUCH_POINT_RELEASED, + EWK_TOUCH_POINT_MOVED, + EWK_TOUCH_POINT_CANCELLED +} Ewk_Touch_Point_Type; + +typedef struct _Ewk_Touch_Point Ewk_Touch_Point; +struct _Ewk_Touch_Point { + unsigned int id; + int x, y; + Ewk_Touch_Point_Type state; +}; + +EAPI Evas_Object *ewk_frame_view_get(const Evas_Object *o); +EAPI void ewk_frame_theme_set(Evas_Object *o, const char *path); +EAPI const char *ewk_frame_theme_get(Evas_Object *o); + +EAPI Eina_Iterator *ewk_frame_children_iterator_new(Evas_Object *o); +EAPI Evas_Object *ewk_frame_child_find(Evas_Object *o, const char *name); + +EAPI Eina_Bool ewk_frame_uri_set(Evas_Object *o, const char *uri); +EAPI const char *ewk_frame_uri_get(const Evas_Object *o); +EAPI const char *ewk_frame_title_get(const Evas_Object *o); +EAPI const char *ewk_frame_name_get(const Evas_Object *o); +EAPI Eina_Bool ewk_frame_contents_size_get(const Evas_Object *o, Evas_Coord *w, Evas_Coord *h); + +EAPI Eina_Bool ewk_frame_contents_set(Evas_Object *o, const char *contents, size_t contents_size, const char *mime_type, const char *encoding, const char *base_uri); +EAPI Eina_Bool ewk_frame_contents_alternate_set(Evas_Object *o, const char *contents, size_t contents_size, const char *mime_type, const char *encoding, const char *base_uri, const char *unreachable_uri); + +EAPI Eina_Bool ewk_frame_script_execute(Evas_Object *o, const char *script); + +EAPI Eina_Bool ewk_frame_editable_get(const Evas_Object *o); +EAPI Eina_Bool ewk_frame_editable_set(Evas_Object *o, Eina_Bool editable); + +EAPI char *ewk_frame_selection_get(const Evas_Object *o); + +EAPI Eina_Bool ewk_frame_text_search(const Evas_Object *o, const char *string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap); + +EAPI unsigned int ewk_frame_text_matches_mark(Evas_Object *o, const char *string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit); +EAPI Eina_Bool ewk_frame_text_matches_unmark_all(Evas_Object *o); +EAPI Eina_Bool ewk_frame_text_matches_highlight_set(Evas_Object *o, Eina_Bool highlight); +EAPI Eina_Bool ewk_frame_text_matches_highlight_get(const Evas_Object *o); +EAPI Eina_Bool ewk_frame_text_matches_nth_pos_get(Evas_Object *o, size_t n, int *x, int *y); + +EAPI Eina_Bool ewk_frame_stop(Evas_Object *o); +EAPI Eina_Bool ewk_frame_reload(Evas_Object *o); +EAPI Eina_Bool ewk_frame_reload_full(Evas_Object *o); + +EAPI Eina_Bool ewk_frame_back(Evas_Object *o); +EAPI Eina_Bool ewk_frame_forward(Evas_Object *o); +EAPI Eina_Bool ewk_frame_navigate(Evas_Object *o, int steps); + +EAPI Eina_Bool ewk_frame_back_possible(Evas_Object *o); +EAPI Eina_Bool ewk_frame_forward_possible(Evas_Object *o); +EAPI Eina_Bool ewk_frame_navigate_possible(Evas_Object *o, int steps); + +EAPI float ewk_frame_zoom_get(const Evas_Object *o); +EAPI Eina_Bool ewk_frame_zoom_set(Evas_Object *o, float zoom); +EAPI Eina_Bool ewk_frame_zoom_text_only_get(const Evas_Object *o); +EAPI Eina_Bool ewk_frame_zoom_text_only_set(Evas_Object *o, Eina_Bool setting); + +EAPI void ewk_frame_hit_test_free(Ewk_Hit_Test *hit_test); +EAPI Ewk_Hit_Test *ewk_frame_hit_test_new(const Evas_Object *o, int x, int y); + +EAPI Eina_Bool ewk_frame_scroll_add(Evas_Object *o, int dx, int dy); +EAPI Eina_Bool ewk_frame_scroll_set(Evas_Object *o, int x, int y); + +EAPI Eina_Bool ewk_frame_scroll_size_get(const Evas_Object *o, int *w, int *h); +EAPI Eina_Bool ewk_frame_scroll_pos_get(const Evas_Object *o, int *x, int *y); + +EAPI Eina_Bool ewk_frame_visible_content_geometry_get(const Evas_Object *o, Eina_Bool include_scrollbars, int *x, int *y, int *w, int *h); + +EAPI Eina_Bool ewk_frame_paint_full_get(const Evas_Object *o); +EAPI void ewk_frame_paint_full_set(Evas_Object *o, Eina_Bool flag); + +EAPI Eina_Bool ewk_frame_feed_focus_in(Evas_Object *o); +EAPI Eina_Bool ewk_frame_feed_focus_out(Evas_Object *o); + +EAPI Eina_Bool ewk_frame_feed_mouse_wheel(Evas_Object *o, const Evas_Event_Mouse_Wheel *ev); +EAPI Eina_Bool ewk_frame_feed_mouse_down(Evas_Object *o, const Evas_Event_Mouse_Down *ev); +EAPI Eina_Bool ewk_frame_feed_mouse_up(Evas_Object *o, const Evas_Event_Mouse_Up *ev); +EAPI Eina_Bool ewk_frame_feed_mouse_move(Evas_Object *o, const Evas_Event_Mouse_Move *ev); +EAPI Eina_Bool ewk_frame_feed_touch_event(Evas_Object* o, Ewk_Touch_Event_Type action, Eina_List* points, int metaState); +EAPI Eina_Bool ewk_frame_feed_key_down(Evas_Object *o, const Evas_Event_Key_Down *ev); +EAPI Eina_Bool ewk_frame_feed_key_up(Evas_Object *o, const Evas_Event_Key_Up *ev); + + +#ifdef __cplusplus +} +#endif +#endif // ewk_frame_h diff --git a/Source/WebKit/efl/ewk/ewk_history.cpp b/Source/WebKit/efl/ewk/ewk_history.cpp new file mode 100644 index 0000000..0a9d349 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_history.cpp @@ -0,0 +1,704 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_history.h" + +#include "BackForwardListImpl.h" +#include "EWebKit.h" +#include "HistoryItem.h" +#include "Image.h" +#include "ewk_private.h" +#include <wtf/text/CString.h> + +#include <Eina.h> +#include <eina_safety_checks.h> + +struct _Ewk_History { + WebCore::BackForwardListImpl *core; +}; + +#define EWK_HISTORY_CORE_GET_OR_RETURN(history, core_, ...) \ + if (!(history)) { \ + CRITICAL("history is NULL."); \ + return __VA_ARGS__; \ + } \ + if (!(history)->core) { \ + CRITICAL("history->core is NULL."); \ + return __VA_ARGS__; \ + } \ + if (!(history)->core->enabled()) { \ + ERR("history->core is disabled!."); \ + return __VA_ARGS__; \ + } \ + WebCore::BackForwardListImpl *core_ = (history)->core + + +struct _Ewk_History_Item { + WebCore::HistoryItem *core; + + const char *title; + const char *alternate_title; + const char *uri; + const char *original_uri; +}; + +#define EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core_, ...) \ + if (!(item)) { \ + CRITICAL("item is NULL."); \ + return __VA_ARGS__; \ + } \ + if (!(item)->core) { \ + CRITICAL("item->core is NULL."); \ + return __VA_ARGS__; \ + } \ + WebCore::HistoryItem *core_ = (item)->core + + +static inline Ewk_History_Item *_ewk_history_item_new(WebCore::HistoryItem *core) +{ + Ewk_History_Item* item; + + if (!core) { + ERR("WebCore::HistoryItem is NULL."); + return 0; + } + + item = (Ewk_History_Item *)calloc(1, sizeof(Ewk_History_Item)); + if (!item) { + CRITICAL("Could not allocate item memory."); + return 0; + } + + core->ref(); + item->core = core; + + return item; +} + +static inline Eina_List *_ewk_history_item_list_get(const WebCore::HistoryItemVector &core_items) +{ + Eina_List* ret = 0; + unsigned int i, size; + + size = core_items.size(); + for (i = 0; i < size; i++) { + Ewk_History_Item* item = _ewk_history_item_new(core_items[i].get()); + if (item) + ret = eina_list_append(ret, item); + } + + return ret; +} + +/** + * Go forward in history one item, if possible. + * + * @param history which history instance to modify. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + */ +Eina_Bool ewk_history_forward(Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE); + if (core->forwardListCount() < 1) + return EINA_FALSE; + core->goForward(); + return EINA_TRUE; +} + +/** + * Go back in history one item, if possible. + * + * @param history which history instance to modify. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + */ +Eina_Bool ewk_history_back(Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE); + if (core->backListCount() < 1) + return EINA_FALSE; + core->goBack(); + return EINA_TRUE; +} + +/** + * Adds the given item to history. + * + * Memory handling: This will not modify or even take references to + * given item (Ewk_History_Item), so you should still handle it with + * ewk_history_item_free(). + * + * @param history which history instance to modify. + * @param item reference to add to history. Unmodified. Must @b not be @c NULL. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + */ +Eina_Bool ewk_history_history_item_add(Ewk_History* history, const Ewk_History_Item* item) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE); + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE); + history_core->addItem(item_core); + return EINA_TRUE; +} + +/** + * Sets the given item as current in history (go to item). + * + * Memory handling: This will not modify or even take references to + * given item (Ewk_History_Item), so you should still handle it with + * ewk_history_item_free(). + * + * @param history which history instance to modify. + * @param item reference to go to history. Unmodified. Must @b not be @c NULL. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure. + */ +Eina_Bool ewk_history_history_item_set(Ewk_History* history, const Ewk_History_Item* item) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE); + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE); + history_core->goToItem(item_core); + return EINA_TRUE; +} + +/** + * Get the first item from back list, if any. + * + * @param history which history instance to query. + * + * @return the @b newly allocated item instance. This memory must be + * released with ewk_history_item_free() after use. + */ +Ewk_History_Item* ewk_history_history_item_back_get(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return _ewk_history_item_new(core->backItem()); +} + +/** + * Get the current item in history, if any. + * + * @param history which history instance to query. + * + * @return the @b newly allocated item instance. This memory must be + * released with ewk_history_item_free() after use. + */ +Ewk_History_Item* ewk_history_history_item_current_get(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return _ewk_history_item_new(core->currentItem()); +} + +/** + * Get the first item from forward list, if any. + * + * @param history which history instance to query. + * + * @return the @b newly allocated item instance. This memory must be + * released with ewk_history_item_free() after use. + */ +Ewk_History_Item* ewk_history_history_item_forward_get(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return _ewk_history_item_new(core->forwardItem()); +} + +/** + * Get item at given position, if any at that index. + * + * @param history which history instance to query. + * @param index position of item to get. + * + * @return the @b newly allocated item instance. This memory must be + * released with ewk_history_item_free() after use. + */ +Ewk_History_Item* ewk_history_history_item_nth_get(const Ewk_History* history, int index) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return _ewk_history_item_new(core->itemAtIndex(index)); +} + +/** + * Queries if given item is in history. + * + * Memory handling: This will not modify or even take references to + * given item (Ewk_History_Item), so you should still handle it with + * ewk_history_item_free(). + * + * @param history which history instance to modify. + * @param item reference to check in history. Must @b not be @c NULL. + * + * @return @c EINA_TRUE if in history, @c EINA_FALSE if not or failure. + */ +Eina_Bool ewk_history_history_item_contains(const Ewk_History* history, const Ewk_History_Item* item) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, history_core, EINA_FALSE); + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, item_core, EINA_FALSE); + return history_core->containsItem(item_core); +} + +/** + * Get the whole forward list. + * + * @param history which history instance to query. + * + * @return a newly allocated list of @b newly allocated item + * instance. This memory of each item must be released with + * ewk_history_item_free() after use. use + * ewk_history_item_list_free() for convenience. + * + * @see ewk_history_item_list_free() + * @see ewk_history_forward_list_get_with_limit() + */ +Eina_List* ewk_history_forward_list_get(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + WebCore::HistoryItemVector items; + int limit = core->forwardListCount(); + core->forwardListWithLimit(limit, items); + return _ewk_history_item_list_get(items); +} + +/** + * Get the forward list within the given limit. + * + * @param history which history instance to query. + * @param limit the maximum number of items to return. + * + * @return a newly allocated list of @b newly allocated item + * instance. This memory of each item must be released with + * ewk_history_item_free() after use. use + * ewk_history_item_list_free() for convenience. + * + * @see ewk_history_item_list_free() + * @see ewk_history_forward_list_length() + * @see ewk_history_forward_list_get() + */ +Eina_List* ewk_history_forward_list_get_with_limit(const Ewk_History* history, int limit) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + WebCore::HistoryItemVector items; + core->forwardListWithLimit(limit, items); + return _ewk_history_item_list_get(items); +} + +/** + * Get the whole size of forward list. + * + * @param history which history instance to query. + * + * @return number of elements in whole list. + * + * @see ewk_history_forward_list_get_with_limit() + */ +int ewk_history_forward_list_length(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return core->forwardListCount(); +} + +/** + * Get the whole back list. + * + * @param history which history instance to query. + * + * @return a newly allocated list of @b newly allocated item + * instance. This memory of each item must be released with + * ewk_history_item_free() after use. use + * ewk_history_item_list_free() for convenience. + * + * @see ewk_history_item_list_free() + * @see ewk_history_back_list_get_with_limit() + */ +Eina_List* ewk_history_back_list_get(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + WebCore::HistoryItemVector items; + int limit = core->backListCount(); + core->backListWithLimit(limit, items); + return _ewk_history_item_list_get(items); +} + +/** + * Get the back list within the given limit. + * + * @param history which history instance to query. + * @param limit the maximum number of items to return. + * + * @return a newly allocated list of @b newly allocated item + * instance. This memory of each item must be released with + * ewk_history_item_free() after use. use + * ewk_history_item_list_free() for convenience. + * + * @see ewk_history_item_list_free() + * @see ewk_history_back_list_length() + * @see ewk_history_back_list_get() + */ +Eina_List* ewk_history_back_list_get_with_limit(const Ewk_History* history, int limit) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + WebCore::HistoryItemVector items; + core->backListWithLimit(limit, items); + return _ewk_history_item_list_get(items); +} + +/** + * Get the whole size of back list. + * + * @param history which history instance to query. + * + * @return number of elements in whole list. + * + * @see ewk_history_back_list_get_with_limit() + */ +int ewk_history_back_list_length(const Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return core->backListCount(); +} + +/** + * Get maximum capacity of given history. + * + * @param history which history instance to query. + * + * @return maximum number of entries this history will hold. + */ +int ewk_history_limit_get(Ewk_History* history) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, 0); + return core->capacity(); +} + +/** + * Set maximum capacity of given history. + * + * @param history which history instance to modify. + * @param limit maximum size to allow. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_history_limit_set(const Ewk_History* history, int limit) +{ + EWK_HISTORY_CORE_GET_OR_RETURN(history, core, EINA_FALSE); + core->setCapacity(limit); + return EINA_TRUE; +} + +/** + * Create a new history item with given URI and title. + * + * @param uri where this resource is located. + * @param title resource title. + * + * @return newly allocated history item or @c NULL on errors. You must + * free this item with ewk_history_item_free(). + */ +Ewk_History_Item* ewk_history_item_new(const char* uri, const char* title) +{ + WTF::String u = WTF::String::fromUTF8(uri); + WTF::String t = WTF::String::fromUTF8(title); + WTF::RefPtr<WebCore::HistoryItem> core = WebCore::HistoryItem::create(u, t, 0); + Ewk_History_Item* item = _ewk_history_item_new(core.release().releaseRef()); + return item; +} + +static inline void _ewk_history_item_free(Ewk_History_Item* item, WebCore::HistoryItem* core) +{ + core->deref(); + free(item); +} + +/** + * Free given history item instance. + * + * @param item what to free. + */ +void ewk_history_item_free(Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core); + _ewk_history_item_free(item, core); +} + +/** + * Free given list and associated history items instances. + * + * @param history_items list of items to free (both list nodes and + * item instances). + */ +void ewk_history_item_list_free(Eina_List* history_items) +{ + void* d; + EINA_LIST_FREE(history_items, d) { + Ewk_History_Item* item = (Ewk_History_Item*)d; + _ewk_history_item_free(item, item->core); + } +} + +/** + * Query title for given history item. + * + * @param item history item to query. + * + * @return the title pointer, that may be @c NULL. This pointer is + * guaranteed to be eina_stringshare, so whenever possible + * save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char* ewk_history_item_title_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + // hide the following optimzation from outside + Ewk_History_Item* i = (Ewk_History_Item*)item; + eina_stringshare_replace(&i->title, core->title().utf8().data()); + return i->title; +} + +/** + * Query alternate title for given history item. + * + * @param item history item to query. + * + * @return the alternate title pointer, that may be @c NULL. This + * pointer is guaranteed to be eina_stringshare, so whenever + * possible save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char* ewk_history_item_title_alternate_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + // hide the following optimzation from outside + Ewk_History_Item* i = (Ewk_History_Item*)item; + eina_stringshare_replace(&i->alternate_title, + core->alternateTitle().utf8().data()); + return i->alternate_title; +} + +/** + * Set alternate title for given history item. + * + * @param item history item to query. + * @param title new alternate title to use for given item. No + * references are kept after this function returns. + */ +void ewk_history_item_title_alternate_set(Ewk_History_Item* item, const char* title) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core); + if (!eina_stringshare_replace(&item->alternate_title, title)) + return; + core->setAlternateTitle(WTF::String::fromUTF8(title)); +} + +/** + * Query URI for given history item. + * + * @param item history item to query. + * + * @return the URI pointer, that may be @c NULL. This pointer is + * guaranteed to be eina_stringshare, so whenever possible + * save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char* ewk_history_item_uri_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + // hide the following optimzation from outside + Ewk_History_Item* i = (Ewk_History_Item*)item; + eina_stringshare_replace(&i->uri, core->urlString().utf8().data()); + return i->uri; +} + +/** + * Query original URI for given history item. + * + * @param item history item to query. + * + * @return the original URI pointer, that may be @c NULL. This pointer + * is guaranteed to be eina_stringshare, so whenever possible + * save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char* ewk_history_item_uri_original_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + // hide the following optimzation from outside + Ewk_History_Item* i = (Ewk_History_Item*)item; + eina_stringshare_replace(&i->original_uri, + core->originalURLString().utf8().data()); + return i->original_uri; +} + +/** + * Query last visited time for given history item. + * + * @param item history item to query. + * + * @return the time in seconds this item was visited. + */ +double ewk_history_item_time_last_visited_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0.0); + return core->lastVisitedTime(); +} + +/** + * Get the icon (aka favicon) associated with this history item. + * + * @note in order to have this working, one must open icon database + * with ewk_settings_icon_database_path_set(). + * + * @param item history item to query. + * + * @return the surface reference or @c NULL on errors. Note that the + * reference may be to a standard fallback icon. + */ +cairo_surface_t* ewk_history_item_icon_surface_get(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + WebCore::Image* icon = core->icon(); + if (!icon) { + ERR("icon is NULL."); + return 0; + } + return icon->nativeImageForCurrentFrame(); +} + +/** + * Add an Evas_Object of type 'image' to given canvas with history item icon. + * + * This is an utility function that creates an Evas_Object of type + * image set to have fill always match object size + * (evas_object_image_filled_add()), saving some code to use it from Evas. + * + * @note in order to have this working, one must open icon database + * with ewk_settings_icon_database_path_set(). + * + * @param item history item to query. + * @param canvas evas instance where to add resulting object. + * + * @return newly allocated Evas_Object instance or @c NULL on + * errors. Delete the object with evas_object_del(). + */ +Evas_Object* ewk_history_item_icon_object_add(const Ewk_History_Item* item, Evas* canvas) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0); + WebCore::Image* icon = core->icon(); + cairo_surface_t* surface; + + if (!icon) { + ERR("icon is NULL."); + return 0; + } + + surface = icon->nativeImageForCurrentFrame(); + return ewk_util_image_from_cairo_surface_add(canvas, surface); +} + +/** + * Query if given item is still in page cache. + * + * @param item history item to query. + * + * @return @c EINA_TRUE if in cache, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_history_item_page_cache_exists(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_FALSE); + return core->isInPageCache(); +} + +/** + * Query number of times item was visited. + * + * @param item history item to query. + * + * @return number of visits. + */ +int ewk_history_item_visit_count(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, 0); + return core->visitCount(); +} + +/** + * Query if last visit to item was failure or not. + * + * @param item history item to query. + * + * @return @c EINA_TRUE if last visit was failure, @c EINA_FALSE if it + * was fine. + */ +Eina_Bool ewk_history_item_visit_last_failed(const Ewk_History_Item* item) +{ + EWK_HISTORY_ITEM_CORE_GET_OR_RETURN(item, core, EINA_TRUE); + return core->lastVisitWasFailure(); +} + + +/* internal methods ****************************************************/ +/** + * @internal + * + * Creates history for given view. Called internally by ewk_view and + * should never be called from outside. + * + * @param core WebCore::BackForwardListImpl instance to use internally. + * + * @return newly allocated history instance or @c NULL on errors. + */ +Ewk_History* ewk_history_new(WebCore::BackForwardListImpl* core) +{ + Ewk_History* history; + EINA_SAFETY_ON_NULL_RETURN_VAL(core, 0); + DBG("core=%p", core); + + history = (Ewk_History*)malloc(sizeof(Ewk_History)); + if (!history) { + CRITICAL("Could not allocate history memory."); + return 0; + } + + core->ref(); + history->core = core; + + return history; +} + +/** + * @internal + * + * Destroys previously allocated history instance. This is called + * automatically by ewk_view and should never be called from outside. + * + * @param history instance to free + */ +void ewk_history_free(Ewk_History* history) +{ + DBG("history=%p", history); + history->core->deref(); + free(history); +} diff --git a/Source/WebKit/efl/ewk/ewk_history.h b/Source/WebKit/efl/ewk/ewk_history.h new file mode 100644 index 0000000..3943d7e --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_history.h @@ -0,0 +1,96 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_history_h +#define ewk_history_h + +#include "ewk_eapi.h" + +#include <Eina.h> +#include <Evas.h> +#include <cairo.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The history (back-forward list) associated with a given ewk_view. + * + * Changing the history affects immediately the view, changing the + * current uri, for example. + * + * When ewk_view is navigated or uris are set, history automatically + * updates. That's why no direct access to history structure is + * allowed. + */ +typedef struct _Ewk_History Ewk_History; + +/** + * Represents one item from Ewk_History. + */ +typedef struct _Ewk_History_Item Ewk_History_Item; + + + +EAPI Eina_Bool ewk_history_forward(Ewk_History *history); +EAPI Eina_Bool ewk_history_back(Ewk_History *history); + +EAPI Eina_Bool ewk_history_history_item_add(Ewk_History *history, const Ewk_History_Item *item); +EAPI Eina_Bool ewk_history_history_item_set(Ewk_History *history, const Ewk_History_Item *item); +EAPI Ewk_History_Item *ewk_history_history_item_back_get(const Ewk_History *history); +EAPI Ewk_History_Item *ewk_history_history_item_current_get(const Ewk_History *history); +EAPI Ewk_History_Item *ewk_history_history_item_forward_get(const Ewk_History *history); +EAPI Ewk_History_Item *ewk_history_history_item_nth_get(const Ewk_History *history, int index); +EAPI Eina_Bool ewk_history_history_item_contains(const Ewk_History *history, const Ewk_History_Item *item); + +EAPI Eina_List *ewk_history_forward_list_get(const Ewk_History *history); +EAPI Eina_List *ewk_history_forward_list_get_with_limit(const Ewk_History *history, int limit); +EAPI int ewk_history_forward_list_length(const Ewk_History *history); + +EAPI Eina_List *ewk_history_back_list_get(const Ewk_History *history); +EAPI Eina_List *ewk_history_back_list_get_with_limit(const Ewk_History *history, int limit); +EAPI int ewk_history_back_list_length(const Ewk_History *history); + +EAPI int ewk_history_limit_get(Ewk_History *history); +EAPI Eina_Bool ewk_history_limit_set(const Ewk_History *history, int limit); + +EAPI Ewk_History_Item *ewk_history_item_new(const char *uri, const char *title); +EAPI void ewk_history_item_free(Ewk_History_Item *item); +EAPI void ewk_history_item_list_free(Eina_List *history_items); + +EAPI const char *ewk_history_item_title_get(const Ewk_History_Item *item); +EAPI const char *ewk_history_item_title_alternate_get(const Ewk_History_Item *item); +EAPI void ewk_history_item_title_alternate_set(Ewk_History_Item *item, const char *title); +EAPI const char *ewk_history_item_uri_get(const Ewk_History_Item *item); +EAPI const char *ewk_history_item_uri_original_get(const Ewk_History_Item *item); +EAPI double ewk_history_item_time_last_visited_get(const Ewk_History_Item *item); + +EAPI cairo_surface_t *ewk_history_item_icon_surface_get(const Ewk_History_Item *item); +EAPI Evas_Object *ewk_history_item_icon_object_add(const Ewk_History_Item *item, Evas *canvas); + +EAPI Eina_Bool ewk_history_item_page_cache_exists(const Ewk_History_Item *item); +EAPI int ewk_history_item_visit_count(const Ewk_History_Item *item); +EAPI Eina_Bool ewk_history_item_visit_last_failed(const Ewk_History_Item *item); + +#ifdef __cplusplus +} +#endif +#endif // ewk_history_h diff --git a/Source/WebKit/efl/ewk/ewk_logging.h b/Source/WebKit/efl/ewk/ewk_logging.h new file mode 100644 index 0000000..045bd9c --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_logging.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_logging_h +#define ewk_logging_h + +extern int _ewk_log_dom; +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_ewk_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_ewk_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_ewk_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_ewk_log_dom, __VA_ARGS__) +#define DBG(...) EINA_LOG_DOM_DBG(_ewk_log_dom, __VA_ARGS__) + +#endif // ewk_logging_h diff --git a/Source/WebKit/efl/ewk/ewk_main.cpp b/Source/WebKit/efl/ewk/ewk_main.cpp new file mode 100644 index 0000000..26dec81 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_main.cpp @@ -0,0 +1,193 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_main.h" + +#include "appcache/ApplicationCacheStorage.h" +#include "EWebKit.h" +#include "Logging.h" +#include "PageCache.h" +#include "PageGroup.h" +#include "ewk_private.h" +#include "ewk_settings.h" +#include "runtime/InitializeThreading.h" +#include "wtf/Threading.h" + +#include <Ecore.h> +#include <Ecore_Evas.h> +#include <Edje.h> +#include <Eina.h> +#include <Evas.h> +#include <stdlib.h> +#include <sys/stat.h> + +#if ENABLE(GLIB_SUPPORT) +#include <glib-object.h> +#include <glib.h> + +#ifdef ENABLE_GTK_PLUGINS_SUPPORT +#include <gtk/gtk.h> +#endif + +#endif + +#ifdef WTF_USE_SOUP +// REMOVE-ME: see todo below +#include "ResourceHandle.h" +#include <libsoup/soup.h> +#endif + +static int _ewk_init_count = 0; +int _ewk_log_dom = -1; + +static Eina_Bool _ewk_init_body(void); + +int ewk_init(void) +{ + if (_ewk_init_count) + return ++_ewk_init_count; + + if (!eina_init()) + goto error_eina; + + _ewk_log_dom = eina_log_domain_register("ewebkit", EINA_COLOR_ORANGE); + if (_ewk_log_dom < 0) { + EINA_LOG_CRIT("could not register log domain 'ewebkit'"); + goto error_log_domain; + } + + if (!evas_init()) { + CRITICAL("could not init evas."); + goto error_evas; + } + + if (!ecore_init()) { + CRITICAL("could not init ecore."); + goto error_ecore; + } + + if (!ecore_evas_init()) { + CRITICAL("could not init ecore_evas."); + goto error_ecore_evas; + } + + if (!edje_init()) { + CRITICAL("could not init edje."); + goto error_edje; + } + + _ewk_init_body(); + + return ++_ewk_init_count; + +error_edje: + ecore_evas_shutdown(); +error_ecore_evas: + ecore_shutdown(); +error_ecore: + evas_shutdown(); +error_evas: + eina_log_domain_unregister(_ewk_log_dom); + _ewk_log_dom = -1; +error_log_domain: + eina_shutdown(); +error_eina: + return 0; +} + +int ewk_shutdown(void) +{ + _ewk_init_count--; + if (_ewk_init_count) + return _ewk_init_count; + + ecore_evas_shutdown(); + ecore_shutdown(); + evas_shutdown(); + eina_log_domain_unregister(_ewk_log_dom); + _ewk_log_dom = -1; + eina_shutdown(); + + return 0; +} + +Eina_Bool _ewk_init_body(void) +{ + +#if ENABLE(GLIB_SUPPORT) + g_type_init(); + + if (!g_thread_supported()) + g_thread_init(0); + +#ifdef ENABLE_GTK_PLUGINS_SUPPORT + gdk_threads_init(); + if (!gtk_init_check(0, 0)) + WRN("Could not initialize GTK support."); +#endif + + if (!ecore_main_loop_glib_integrate()) + WRN("Ecore was not compiled with GLib support, some plugins will not " + "work (ie: Adobe Flash)"); +#endif + + JSC::initializeThreading(); + WTF::initializeMainThread(); + WebCore::InitializeLoggingChannelsIfNecessary(); + + // Page cache capacity (in pages). Comment from Mac port: + // (Research indicates that value / page drops substantially after 3 pages.) + // FIXME: Expose this with an API and/or calculate based on available resources + WebCore::pageCache()->setCapacity(3); + WebCore::PageGroup::setShouldTrackVisitedLinks(true); + + // set default location of web database path and appcache dir + const char* home = getenv("HOME"); + if (!home) // don't forget about the homeless + home = "/tmp"; // this directory must always exist + + // anyway, check it first + struct stat state; + if (stat(home, &state) == -1) { + // Exit now - otherwise you may have some crash later + int errnowas = errno; + CRITICAL("Can't access HOME dir (or /tmp) - no place to save databases: %s", strerror(errnowas)); + return EINA_FALSE; + } + + WTF::String wkdir = WTF::String(home) + "/.webkit"; + ewk_settings_web_database_path_set(wkdir.utf8().data()); + ewk_settings_icon_database_path_set(wkdir.utf8().data()); + + WebCore::cacheStorage().setCacheDirectory(wkdir); + + // TODO: this should move to WebCore, already reported to webkit-gtk folks: +#ifdef WTF_USE_SOUP + if (1) { + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER); + soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER); + } +#endif + + return EINA_TRUE; +} + diff --git a/Source/WebKit/efl/ewk/ewk_main.h b/Source/WebKit/efl/ewk/ewk_main.h new file mode 100644 index 0000000..3730e88 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_main.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_main_h +#define ewk_main_h + +#include "ewk_eapi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EAPI int ewk_init(void); +EAPI int ewk_shutdown(void); + +#ifdef __cplusplus +} +#endif +#endif // ewk_main_h diff --git a/Source/WebKit/efl/ewk/ewk_private.h b/Source/WebKit/efl/ewk/ewk_private.h new file mode 100644 index 0000000..496efdb --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_private.h @@ -0,0 +1,169 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_private_h +#define ewk_private_h + +#include "BackForwardListImpl.h" +#include "EWebKit.h" +#include "Frame.h" +#include "Page.h" +#include "Settings.h" +#include "Widget.h" +#include "ewk_logging.h" +#include "ewk_util.h" + +#include <cairo.h> +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// If defined, ewk will do type checking to ensure objects are of correct type +#define EWK_TYPE_CHECK 1 + +// forward declarations +namespace WebCore { +struct PopupMenuClient; +struct ContextMenu; +struct ContextMenuItem; +} + +void ewk_view_ready(Evas_Object *o); +void ewk_view_input_method_state_set(Evas_Object* o, Eina_Bool active); +void ewk_view_title_set(Evas_Object *o, const char *title); +void ewk_view_uri_changed(Evas_Object *o); +void ewk_view_load_started(Evas_Object *o); +void ewk_view_load_provisional(Evas_Object *o); +void ewk_view_frame_main_load_started(Evas_Object *o); +void ewk_view_frame_main_cleared(Evas_Object *o); +void ewk_view_frame_main_icon_received(Evas_Object *o); +void ewk_view_load_finished(Evas_Object *o, const Ewk_Frame_Load_Error *error); +void ewk_view_load_error(Evas_Object *o, const Ewk_Frame_Load_Error *error); +void ewk_view_load_progress_changed(Evas_Object *o); +void ewk_view_load_show(Evas_Object* o); +void ewk_view_restore_state(Evas_Object *o, Evas_Object *frame); +Evas_Object *ewk_view_window_create(Evas_Object *o, Eina_Bool javascript, const WebCore::WindowFeatures* coreFeatures); +void ewk_view_window_close(Evas_Object *o); + +void ewk_view_mouse_link_hover_in(Evas_Object *o, void *data); +void ewk_view_mouse_link_hover_out(Evas_Object *o); + +void ewk_view_toolbars_visible_set(Evas_Object *o, Eina_Bool visible); +void ewk_view_toolbars_visible_get(Evas_Object *o, Eina_Bool *visible); + +void ewk_view_statusbar_visible_set(Evas_Object *o, Eina_Bool visible); +void ewk_view_statusbar_visible_get(Evas_Object *o, Eina_Bool *visible); +void ewk_view_statusbar_text_set(Evas_Object *o, const char *text); + +void ewk_view_scrollbars_visible_set(Evas_Object *o, Eina_Bool visible); +void ewk_view_scrollbars_visible_get(Evas_Object *o, Eina_Bool *visible); + +void ewk_view_menubar_visible_set(Evas_Object *o, Eina_Bool visible); +void ewk_view_menubar_visible_get(Evas_Object *o, Eina_Bool *visible); + +void ewk_view_tooltip_text_set(Evas_Object *o, const char *text); + +void ewk_view_add_console_message(Evas_Object *o, const char *message, unsigned int lineNumber, const char *sourceID); + +void ewk_view_run_javascript_alert(Evas_Object *o, Evas_Object *frame, const char *message); +Eina_Bool ewk_view_run_javascript_confirm(Evas_Object *o, Evas_Object *frame, const char *message); +Eina_Bool ewk_view_run_javascript_prompt(Evas_Object *o, Evas_Object *frame, const char *message, const char *defaultValue, char **value); +Eina_Bool ewk_view_should_interrupt_javascript(Evas_Object *o); +uint64_t ewk_view_exceeded_database_quota(Evas_Object *o, Evas_Object *frame, const char *databaseName, uint64_t current_size, uint64_t expected_size); + +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); + +void ewk_view_repaint(Evas_Object *o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); +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); +WebCore::Page *ewk_view_core_page_get(const Evas_Object *o); + +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); + +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); + +void ewk_view_popup_new(Evas_Object *o, WebCore::PopupMenuClient* client, int selected, const WebCore::IntRect& rect); +void ewk_view_viewport_attributes_set(Evas_Object *o, const WebCore::ViewportArguments& arguments); + +void ewk_view_download_request(Evas_Object *o, Ewk_Download *download); + +int ewk_view_dpi_get(); + +Ewk_History *ewk_history_new(WebCore::BackForwardListImpl *history); +void ewk_history_free(Ewk_History *history); + +#if ENABLE(CONTEXT_MENUS) + +Ewk_Context_Menu *ewk_context_menu_new(Evas_Object *view, WebCore::ContextMenuController *controller); +Eina_Bool ewk_context_menu_free(Ewk_Context_Menu *o); +void ewk_context_menu_item_append(Ewk_Context_Menu *o, WebCore::ContextMenuItem& core); +Ewk_Context_Menu *ewk_context_menu_custom_get(Ewk_Context_Menu *o); +void ewk_context_menu_show(Ewk_Context_Menu *o); + +#endif + +Ewk_Window_Features *ewk_window_features_new_from_core(const WebCore::WindowFeatures* core); + +Evas_Object *ewk_frame_add(Evas *e); +Eina_Bool ewk_frame_init(Evas_Object *o, Evas_Object *view, WebCore::Frame *frame); +Evas_Object *ewk_frame_child_add(Evas_Object *o, WTF::PassRefPtr<WebCore::Frame> child, const WTF::String& name, const WebCore::KURL& url, const WTF::String& referrer); + +WebCore::Frame *ewk_frame_core_get(const Evas_Object *o); +void ewk_frame_core_gone(Evas_Object *o); + +void ewk_frame_load_started(Evas_Object *o); +void ewk_frame_load_provisional(Evas_Object *o); +void ewk_frame_load_firstlayout_finished(Evas_Object *o); +void ewk_frame_load_firstlayout_nonempty_finished(Evas_Object *o); +void ewk_frame_load_document_finished(Evas_Object *o); +void ewk_frame_load_finished(Evas_Object *o, const char *error_domain, int error_code, Eina_Bool is_cancellation, const char *error_description, const char *failing_url); +void ewk_frame_load_error(Evas_Object *o, const char *error_domain, int error_code, Eina_Bool is_cancellation, const char *error_description, const char *failing_url); +void ewk_frame_load_progress_changed(Evas_Object *o); + +void ewk_frame_request_will_send(Evas_Object *o, Ewk_Frame_Resource_Request *request); +void ewk_frame_request_assign_identifier(Evas_Object *o, const Ewk_Frame_Resource_Request *request); +void ewk_frame_view_state_save(Evas_Object *o, WebCore::HistoryItem* item); + +void ewk_frame_did_perform_first_navigation(Evas_Object *o); + +void ewk_frame_contents_size_changed(Evas_Object *o, Evas_Coord w, Evas_Coord h); +void ewk_frame_title_set(Evas_Object *o, const char *title); + +void ewk_frame_view_create_for_view(Evas_Object *o, Evas_Object *view); +Eina_Bool ewk_frame_uri_changed(Evas_Object *o); +void ewk_frame_force_layout(Evas_Object *o); + +WTF::PassRefPtr<WebCore::Widget> ewk_frame_plugin_create(Evas_Object* o, 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); + +Eina_Bool ewk_view_navigation_policy_decision(Evas_Object* o, Ewk_Frame_Resource_Request* request); + +void ewk_view_contents_size_changed(Evas_Object *o, Evas_Coord w, Evas_Coord h); + +WebCore::FloatRect ewk_view_page_rect_get(Evas_Object *o); + +const char* ewk_settings_default_user_agent_get(); + +#ifdef __cplusplus + +} +#endif +#endif // ewk_private_h diff --git a/Source/WebKit/efl/ewk/ewk_settings.cpp b/Source/WebKit/efl/ewk/ewk_settings.cpp new file mode 100644 index 0000000..20051ea --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_settings.cpp @@ -0,0 +1,305 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_settings.h" + +#include "EWebKit.h" +#if ENABLE(DATABASE) +#include "DatabaseTracker.h" +#endif +#include "IconDatabase.h" +#include "Image.h" +#include "IntSize.h" +#include "KURL.h" +#include "Language.h" +#include "ewk_private.h" + +#include <Eina.h> +#include <eina_safety_checks.h> +#include <errno.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <unistd.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringConcatenate.h> + +#if USE(SOUP) +#include "ResourceHandle.h" +#include <libsoup/soup.h> +#endif + +static const char* _ewk_default_web_database_path = 0; +static const char* _ewk_icon_database_path = 0; +static uint64_t _ewk_default_web_database_quota = 1 * 1024 * 1024; + +static WTF::String _ewk_settings_webkit_platform_get() +{ + WTF::String ua_platform; +#if PLATFORM(X11) + ua_platform = "X11"; +#else + ua_platform = "Unknown"; +#endif + return ua_platform; +} + +static WTF::String _ewk_settings_webkit_os_version_get() +{ + WTF::String ua_os_version; + struct utsname name; + + if (uname(&name) != -1) + ua_os_version = WTF::String(name.sysname) + " " + WTF::String(name.machine); + else + ua_os_version = "Unknown"; + + return ua_os_version; +} + +/** + * Returns the default quota for Web Database databases. By default + * this value is 1MB. + * + * @return the current default database quota in bytes + **/ +uint64_t ewk_settings_web_database_default_quota_get() +{ + return _ewk_default_web_database_quota; +} + +/** + * Sets the current path to the directory WebKit will write Web + * Database databases. + * + * @path: the new database directory path + * + */ +void ewk_settings_web_database_path_set(const char *path) +{ +#if ENABLE(DATABASE) + WTF::String corePath = WTF::String::fromUTF8(path); + WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(corePath); + if (!_ewk_default_web_database_path) + _ewk_default_web_database_path = eina_stringshare_add(corePath.utf8().data()); + else + eina_stringshare_replace(&_ewk_default_web_database_path, corePath.utf8().data()); + +#endif +} + +/** + * Return directory path where web database is stored. + * + * @return database path or NULL if none or web database is not supported. + * This is guaranteed to be eina_stringshare, so whenever possible + * save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char *ewk_settings_web_database_path_get() +{ +#if ENABLE(DATABASE) + return _ewk_default_web_database_path; +#else + return 0; +#endif +} + +/** + * Sets directory where to store icon database, opening database. + * + * @param directory where to store icon database, must be + * write-able. If @c NULL is given, then database is closed. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on errors. + */ +Eina_Bool ewk_settings_icon_database_path_set(const char *directory) +{ + WebCore::iconDatabase()->delayDatabaseCleanup(); + + if (directory) { + struct stat st; + + if (stat(directory, &st)) { + ERR("could not stat(%s): %s", directory, strerror(errno)); + return EINA_FALSE; + } + + if (!S_ISDIR(st.st_mode)) { + ERR("not a directory: %s", directory); + return EINA_FALSE; + } + + if (access(directory, R_OK | W_OK)) { + ERR("could not access directory '%s' for read and write: %s", + directory, strerror(errno)); + return EINA_FALSE; + } + + WebCore::iconDatabase()->setEnabled(true); + WebCore::iconDatabase()->open(WTF::String::fromUTF8(directory)); + if (!_ewk_icon_database_path) + _ewk_icon_database_path = eina_stringshare_add(directory); + else + eina_stringshare_replace(&_ewk_icon_database_path, directory); + } else { + WebCore::iconDatabase()->setEnabled(false); + WebCore::iconDatabase()->close(); + if (_ewk_icon_database_path) { + eina_stringshare_del(_ewk_icon_database_path); + _ewk_icon_database_path = 0; + } + } + return EINA_TRUE; +} + +/** + * Return directory path where icon database is stored. + * + * @return database path or @c NULL if none is set or database is closed. + * This is guaranteed to be eina_stringshare, so whenever possible + * save yourself some cpu cycles and use + * eina_stringshare_ref() instead of eina_stringshare_add() or + * strdup(). + */ +const char* ewk_settings_icon_database_path_get(void) +{ + if (!WebCore::iconDatabase()->isEnabled()) + return 0; + if (!WebCore::iconDatabase()->isOpen()) + return 0; + + return _ewk_icon_database_path; +} + +/** + * Remove all known icons from database. + * + * Database must be opened with ewk_settings_icon_database_path_set() + * in order to work. + * + * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise, like + * closed database. + */ +Eina_Bool ewk_settings_icon_database_clear(void) +{ + if (!WebCore::iconDatabase()->isEnabled()) + return EINA_FALSE; + if (!WebCore::iconDatabase()->isOpen()) + return EINA_FALSE; + + WebCore::iconDatabase()->removeAllIcons(); + return EINA_TRUE; +} + +/** + * Query icon for given URL, returning associated cairo surface. + * + * @note in order to have this working, one must open icon database + * with ewk_settings_icon_database_path_set(). + * + * @param url which url to query icon. + * + * @return cairo surface if any, or NULL on failure. + */ +cairo_surface_t* ewk_settings_icon_database_icon_surface_get(const char *url) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(url, 0); + + WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(url)); + WebCore::Image *icon = WebCore::iconDatabase()->iconForPageURL(kurl.string(), WebCore::IntSize(16, 16)); + + if (!icon) { + ERR("no icon for url %s", url); + return 0; + } + + return icon->nativeImageForCurrentFrame(); +} + +/** + * Create Evas_Object of type image representing the given URL. + * + * This is an utility function that creates an Evas_Object of type + * image set to have fill always match object size + * (evas_object_image_filled_add()), saving some code to use it from Evas. + * + * @note in order to have this working, one must open icon database + * with ewk_settings_icon_database_path_set(). + * + * @param url which url to query icon. + * @param canvas evas instance where to add resulting object. + * + * @return newly allocated Evas_Object instance or @c NULL on + * errors. Delete the object with evas_object_del(). + */ +Evas_Object* ewk_settings_icon_database_icon_object_add(const char* url, Evas* canvas) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(url, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0); + + WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(url)); + WebCore::Image* icon = WebCore::iconDatabase()->iconForPageURL(kurl.string(), WebCore::IntSize(16, 16)); + cairo_surface_t* surface; + + if (!icon) { + ERR("no icon for url %s", url); + return 0; + } + + surface = icon->nativeImageForCurrentFrame(); + return ewk_util_image_from_cairo_surface_add(canvas, surface); +} + +/** + * Sets the given proxy URI to network backend. + * + * @param proxy URI. + */ +void ewk_settings_proxy_uri_set(const char* proxy) +{ +#if USE(SOUP) + SoupURI* uri = soup_uri_new(proxy); + EINA_SAFETY_ON_NULL_RETURN(uri); + + SoupSession* session = WebCore::ResourceHandle::defaultSession(); + g_object_set(session, SOUP_SESSION_PROXY_URI, uri, NULL); + soup_uri_free(uri); +#elif USE(CURL) + EINA_SAFETY_ON_TRUE_RETURN(1); +#endif +} + +/** +* @internal +* Gets the default user agent string. +* +* @return A pointer to an eina_stringshare containing the user agent string. +*/ +const char* ewk_settings_default_user_agent_get() +{ + WTF::String ua_version = makeString(String::number(WEBKIT_USER_AGENT_MAJOR_VERSION), '.', String::number(WEBKIT_USER_AGENT_MINOR_VERSION), '+'); + WTF::String static_ua = makeString("Mozilla/5.0 (", _ewk_settings_webkit_platform_get(), "; U; ", _ewk_settings_webkit_os_version_get(), "; ", WebCore::defaultLanguage(), ") AppleWebKit/", ua_version) + makeString(" (KHTML, like Gecko) Version/5.0 Safari/", ua_version); + + return eina_stringshare_add(static_ua.utf8().data()); +} diff --git a/Source/WebKit/efl/ewk/ewk_settings.h b/Source/WebKit/efl/ewk/ewk_settings.h new file mode 100644 index 0000000..3c1668f --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_settings.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_settings_h +#define ewk_settings_h + +#include "ewk_eapi.h" + +#include <Eina.h> +#include <Evas.h> +#include <cairo.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * + * General purpose settings, not tied to any view object. + */ + +EAPI uint64_t ewk_settings_web_database_default_quota_get(); +EAPI void ewk_settings_web_database_path_set(const char *path); +EAPI const char *ewk_settings_web_database_path_get(); + +EAPI Eina_Bool ewk_settings_icon_database_path_set(const char *path); +EAPI const char *ewk_settings_icon_database_path_get(void); +EAPI Eina_Bool ewk_settings_icon_database_clear(void); + +EAPI cairo_surface_t *ewk_settings_icon_database_icon_surface_get(const char *url); +EAPI Evas_Object *ewk_settings_icon_database_icon_object_add(const char *url, Evas *canvas); + +EAPI void ewk_settings_proxy_uri_set(const char* proxy); + +#ifdef __cplusplus +} +#endif +#endif // ewk_settings_h diff --git a/Source/WebKit/efl/ewk/ewk_tiled_backing_store.c b/Source/WebKit/efl/ewk/ewk_tiled_backing_store.c new file mode 100644 index 0000000..4fbd905 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_backing_store.c @@ -0,0 +1,2026 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_tiled_backing_store.h" + +#define _GNU_SOURCE +#include "ewk_tiled_private.h" +#include <Ecore.h> +#include <Eina.h> +#include <errno.h> +#include <math.h> +#include <stdio.h> // XXX REMOVE ME LATER +#include <stdlib.h> +#include <string.h> + +#define IDX(col, row, rowspan) (col + (row * rowspan)) + +#if !defined(MIN) +# define MIN(a, b) ((a < b) ? a : b) +#endif + +#if !defined(MAX) +# define MAX(a, b) ((a > b) ? a : b) +#endif + +typedef enum _Ewk_Tiled_Backing_Store_Pre_Render_Priority Ewk_Tiled_Backing_Store_Pre_Render_Priority; +typedef struct _Ewk_Tiled_Backing_Store_Data Ewk_Tiled_Backing_Store_Data; +typedef struct _Ewk_Tiled_Backing_Store_Item Ewk_Tiled_Backing_Store_Item; +typedef struct _Ewk_Tiled_Backing_Store_Pre_Render_Request Ewk_Tiled_Backing_Store_Pre_Render_Request; + +enum _Ewk_Tiled_Backing_Store_Pre_Render_Priority { + PRE_RENDER_PRIORITY_LOW = 0, /**< Append the request to the list */ + PRE_RENDER_PRIORITY_HIGH /**< Prepend the request to the list */ +}; + +struct _Ewk_Tiled_Backing_Store_Item { + EINA_INLIST; + Ewk_Tile *tile; + struct { + Evas_Coord x, y, w, h; + } geometry; + struct { + Eina_List *process; + unsigned long row, col; + float zoom; + } update; + Eina_Bool smooth_scale; +}; + +struct _Ewk_Tiled_Backing_Store_Pre_Render_Request { + EINA_INLIST; + unsigned long col, row; + float zoom; +}; + +struct _Ewk_Tiled_Backing_Store_Data { + Evas_Object_Smart_Clipped_Data base; + Evas_Object *self; + Evas_Object *contents_clipper; + struct { + Eina_Inlist **items; + Evas_Coord x, y, w, h; + long cols, rows; + struct { + Evas_Coord w, h; + float zoom; + Eina_Bool zoom_weak_smooth_scale:1; + } tile; + struct { + struct { + Evas_Coord x, y; + } cur, old, base, zoom_center; + } offset; + } view; + Evas_Colorspace cspace; + struct { + Ewk_Tile_Matrix *matrix; + struct { + unsigned long col, row; + } base; + struct { + unsigned long cols, rows; + } cur, old; + Evas_Coord width, height; + } model; + struct { + Eina_Bool (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *area); + void *data; + Eina_List *queue; + Eina_Bool process_entire_queue; + Eina_Inlist *pre_render_requests; + Ecore_Idler *idler; + Eina_Bool disabled; + Eina_Bool suspend:1; + } render; + struct { + void *(*pre_cb)(void *data, Evas_Object *o); + void *pre_data; + void *(*post_cb)(void *data, void *pre_data, Evas_Object *o); + void *post_data; + } process; + struct { + Eina_Bool any:1; + Eina_Bool pos:1; + Eina_Bool size:1; + Eina_Bool model:1; + Eina_Bool offset:1; + } changed; +#ifdef DEBUG_MEM_LEAKS + Ecore_Event_Handler *sig_usr; +#endif +}; + +static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL; +int _ewk_tiled_log_dom = -1; + +#define PRIV_DATA_GET_OR_RETURN(obj, ptr, ...) \ + Ewk_Tiled_Backing_Store_Data *ptr = evas_object_smart_data_get(obj); \ + if (!ptr) { \ + CRITICAL("no private data in obj=%p", obj); \ + return __VA_ARGS__; \ + } + +static inline void _ewk_tiled_backing_store_item_request_del(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it); +static inline void _ewk_tiled_backing_store_item_request_add(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it, int m_col, int m_row, float zoom); +static void _ewk_tiled_backing_store_fill_renderers(Ewk_Tiled_Backing_Store_Data *priv); +static inline void _ewk_tiled_backing_store_view_dbg(const Ewk_Tiled_Backing_Store_Data *priv); +static inline void _ewk_tiled_backing_store_changed(Ewk_Tiled_Backing_Store_Data *priv); + +static inline void _ewk_tiled_backing_store_updates_process(Ewk_Tiled_Backing_Store_Data *priv) +{ + void *data = NULL; + + /* Do not process updates. Note that we still want to get updates requests + * in the queue in order to not miss any updates after the render is + * resumed. + */ + if (priv->render.suspend || !evas_object_visible_get(priv->self)) + return; + + if (priv->process.pre_cb) + data = priv->process.pre_cb(priv->process.pre_data, priv->self); + + ewk_tile_matrix_updates_process(priv->model.matrix); + + if (priv->process.post_cb) + priv->process.post_cb(priv->process.post_data, data, priv->self); +} + +static int _ewk_tiled_backing_store_flush(void *data) +{ + Ewk_Tiled_Backing_Store_Data *priv = data; + Ewk_Tile_Unused_Cache *tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + + if (tuc) { + DBG("flush unused tile cache."); + ewk_tile_unused_cache_auto_flush(tuc); + } else + ERR("no cache?!"); + + return 0; +} + +static Ewk_Tile *_ewk_tiled_backing_store_tile_new(Ewk_Tiled_Backing_Store_Data *priv, unsigned long col, unsigned long row, float zoom) +{ + Ewk_Tile *t; + Evas *evas = evas_object_evas_get(priv->self); + if (!evas) { + CRITICAL("evas_object_evas_get failed!"); + return NULL; + } + + t = ewk_tile_matrix_tile_new + (priv->model.matrix, evas, col, row, zoom); + + if (!t) { + CRITICAL("ewk_tile_matrix_tile_new failed!"); + return NULL; + } + + return t; +} + +static void _ewk_tiled_backing_store_item_move(Ewk_Tiled_Backing_Store_Item *it, Evas_Coord x, Evas_Coord y) +{ + it->geometry.x = x; + it->geometry.y = y; + + if (it->tile) + evas_object_move(it->tile->image, x, y); +} + +static void _ewk_tiled_backing_store_item_resize(Ewk_Tiled_Backing_Store_Item *it, Evas_Coord w, Evas_Coord h) +{ + it->geometry.w = w; + it->geometry.h = h; + + if (it->tile) { + evas_object_resize(it->tile->image, w, h); + evas_object_image_fill_set(it->tile->image, 0, 0, w, h); + } +} + +static void _ewk_tiled_backing_store_tile_associate(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tile *t, Ewk_Tiled_Backing_Store_Item *it) +{ + if (it->tile) + CRITICAL("it->tile=%p, but it should be NULL!", it->tile); + it->tile = t; + evas_object_move(it->tile->image, it->geometry.x, it->geometry.y); + evas_object_resize(it->tile->image, it->geometry.w, it->geometry.h); + evas_object_image_fill_set + (it->tile->image, 0, 0, it->geometry.w, it->geometry.h); + evas_object_image_smooth_scale_set(it->tile->image, it->smooth_scale); + + if (!ewk_tile_visible_get(t)) + evas_object_smart_member_add(t->image, priv->self); + + ewk_tile_show(t); +} + +static void _ewk_tiled_backing_store_tile_dissociate(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it, double last_used) +{ + Ewk_Tile_Unused_Cache *tuc; + ewk_tile_hide(it->tile); + if (!ewk_tile_visible_get(it->tile)) + evas_object_smart_member_del(it->tile->image); + ewk_tile_matrix_tile_put(priv->model.matrix, it->tile, last_used); + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_auto_flush(tuc); + + it->tile = NULL; +} + +static void _ewk_tiled_backing_store_tile_dissociate_all(Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist *it; + Ewk_Tiled_Backing_Store_Item *item; + int i; + double last_used = ecore_loop_time_get(); + + for (i = 0; i < priv->view.rows; i++) { + it = priv->view.items[i]; + EINA_INLIST_FOREACH(it, item) + if (item->tile) + _ewk_tiled_backing_store_tile_dissociate(priv, item, last_used); + } +} + +static inline Eina_Bool _ewk_tiled_backing_store_pre_render_request_add(Ewk_Tiled_Backing_Store_Data *priv, unsigned long col, unsigned long row, float zoom, Ewk_Tiled_Backing_Store_Pre_Render_Priority priority) +{ + Ewk_Tiled_Backing_Store_Pre_Render_Request *r; + + MALLOC_OR_OOM_RET(r, sizeof(*r), EINA_FALSE); + + if (priority == PRE_RENDER_PRIORITY_HIGH) + priv->render.pre_render_requests = eina_inlist_prepend + (priv->render.pre_render_requests, EINA_INLIST_GET(r)); + else + priv->render.pre_render_requests = eina_inlist_append + (priv->render.pre_render_requests, EINA_INLIST_GET(r)); + + r->col = col; + r->row = row; + r->zoom = zoom; + + return EINA_TRUE; +} + +static inline void _ewk_tiled_backing_store_pre_render_request_del(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Pre_Render_Request *r) +{ + priv->render.pre_render_requests = eina_inlist_remove + (priv->render.pre_render_requests, EINA_INLIST_GET(r)); + free(r); +} + +static inline Ewk_Tiled_Backing_Store_Pre_Render_Request *_ewk_tiled_backing_store_pre_render_request_first(const Ewk_Tiled_Backing_Store_Data *priv) +{ + return EINA_INLIST_CONTAINER_GET( + priv->render.pre_render_requests, + Ewk_Tiled_Backing_Store_Pre_Render_Request); +} + +static void _ewk_tiled_backing_store_pre_render_request_flush(Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist **pl = &priv->render.pre_render_requests; + while (*pl) { + Ewk_Tiled_Backing_Store_Pre_Render_Request *r; + r = _ewk_tiled_backing_store_pre_render_request_first(priv); + *pl = eina_inlist_remove(*pl, *pl); + free(r); + } +} + +static void _ewk_tiled_backing_store_pre_render_request_clear(Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist **pl = &priv->render.pre_render_requests; + Eina_Inlist *iter = *pl, *tmp; + while (iter) { + Ewk_Tiled_Backing_Store_Pre_Render_Request *r = + EINA_INLIST_CONTAINER_GET( + iter, Ewk_Tiled_Backing_Store_Pre_Render_Request); + tmp = iter->next; + *pl = eina_inlist_remove(*pl, iter); + iter = tmp; + free(r); + } +} + +/* assumes priv->process.pre_cb was called if required! */ +static void _ewk_tiled_backing_store_pre_render_request_process_single(Ewk_Tiled_Backing_Store_Data *priv) +{ + Ewk_Tiled_Backing_Store_Pre_Render_Request *req; + Eina_Rectangle area; + Ewk_Tile_Matrix *tm = priv->model.matrix; + Ewk_Tile *t; + Ewk_Tile_Unused_Cache *tuc; + unsigned long col, row; + float zoom; + double last_used = ecore_loop_time_get(); + + req = _ewk_tiled_backing_store_pre_render_request_first(priv); + if (!req) + return; + + col = req->col; + row = req->row; + zoom = req->zoom; + + if (ewk_tile_matrix_tile_exact_exists(tm, col, row, zoom)) { + DBG("no pre-render required for tile %lu,%lu @ %f.", col, row, zoom); + goto end; + } + + t = _ewk_tiled_backing_store_tile_new(priv, col, row, zoom); + if (!t) + goto end; + + area.x = 0; + area.y = 0; + area.w = priv->view.tile.w; + area.h = priv->view.tile.h; + + priv->render.cb(priv->render.data, t, &area); + evas_object_image_data_update_add( + t->image, + area.x, area.y, area.w, area.h); + ewk_tile_matrix_tile_updates_clear(tm, t); + + ewk_tile_matrix_tile_put(tm, t, last_used); + +end: + _ewk_tiled_backing_store_pre_render_request_del(priv, req); + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_auto_flush(tuc); +} + +static Eina_Bool _ewk_tiled_backing_store_item_process_idler_cb(void *data) +{ + Ewk_Tiled_Backing_Store_Data *priv = data; + Ewk_Tiled_Backing_Store_Item *it = NULL; + + while (priv->render.queue) { + it = priv->render.queue->data; + if (it->tile->zoom == priv->view.tile.zoom) { + _ewk_tiled_backing_store_item_request_del(priv, it); + it = NULL; + } else { + unsigned long row, col; + float zoom; + Ewk_Tile *t; + if (it->tile) { + double last_used = ecore_loop_time_get(); + _ewk_tiled_backing_store_tile_dissociate(priv, it, last_used); + } + + row = it->update.row; + col = it->update.col; + zoom = it->update.zoom; + t = _ewk_tiled_backing_store_tile_new(priv, col, row, zoom); + if (!t) { + priv->render.idler = NULL; + return EINA_FALSE; + } + + _ewk_tiled_backing_store_tile_associate(priv, t, it); + it->update.process = NULL; + priv->render.queue = eina_list_remove_list(priv->render.queue, + priv->render.queue); + if (!priv->render.process_entire_queue) + break; + } + } + + if (priv->process.pre_cb) + data = priv->process.pre_cb(priv->process.pre_data, priv->self); + + ewk_tile_matrix_updates_process(priv->model.matrix); + + if (!it) + _ewk_tiled_backing_store_pre_render_request_process_single(priv); + + if (priv->process.post_cb) + priv->process.post_cb(priv->process.post_data, data, priv->self); + + if (!priv->render.queue && !priv->render.pre_render_requests) { + priv->render.idler = NULL; + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static inline void _ewk_tiled_backing_store_item_process_idler_stop(Ewk_Tiled_Backing_Store_Data *priv) +{ + if (!priv->render.idler) + return; + + ecore_idler_del(priv->render.idler); + priv->render.idler = NULL; +} + +static inline void _ewk_tiled_backing_store_item_process_idler_start(Ewk_Tiled_Backing_Store_Data *priv) +{ + if (priv->render.idler) + return; + priv->render.idler = ecore_idler_add( + _ewk_tiled_backing_store_item_process_idler_cb, priv); +} + +static inline void _ewk_tiled_backing_store_item_request_del(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it) +{ + priv->render.queue = eina_list_remove_list(priv->render.queue, + it->update.process); + it->update.process = NULL; +} + +static inline void _ewk_tiled_backing_store_item_request_add(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it, int m_col, int m_row, float zoom) +{ + if (it->update.process) + return; + + it->update.col = m_col; + it->update.row = m_row; + it->update.zoom = zoom; + + priv->render.queue = eina_list_append(priv->render.queue, it); + it->update.process = eina_list_last(priv->render.queue); + + if (!priv->render.suspend) + _ewk_tiled_backing_store_item_process_idler_start(priv); +} + +static Eina_Bool _ewk_tiled_backing_store_disable_render(Ewk_Tiled_Backing_Store_Data *priv) +{ + if (priv->render.suspend) + return EINA_TRUE; + + priv->render.suspend = EINA_TRUE; + _ewk_tiled_backing_store_item_process_idler_stop(priv); + return EINA_TRUE; +} + +static Eina_Bool _ewk_tiled_backing_store_enable_render(Ewk_Tiled_Backing_Store_Data *priv) +{ + if (!priv->render.suspend) + return EINA_TRUE; + + priv->render.suspend = EINA_FALSE; + + _ewk_tiled_backing_store_fill_renderers(priv); + _ewk_tiled_backing_store_item_process_idler_start(priv); + + return EINA_TRUE; +} + +static inline Eina_Bool _ewk_tiled_backing_store_item_fill(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it, long col, int row) +{ + long m_col = priv->model.base.col + col; + long m_row = priv->model.base.row + row; + double last_used = ecore_loop_time_get(); + + if (m_col < 0 || m_row < 0 + || (unsigned long)(m_col) >= priv->model.cur.cols + || (unsigned long)(m_row) >= priv->model.cur.rows) { + + if (it->tile) { + _ewk_tiled_backing_store_tile_dissociate(priv, it, last_used); + if (it->update.process) + _ewk_tiled_backing_store_item_request_del(priv, it); + } + } else { + Ewk_Tile *t; + const float zoom = priv->view.tile.zoom; + + if (it->update.process) { + if (it->update.row == (unsigned long)(m_row) + && it->update.col == (unsigned long)(m_col) + && it->update.zoom == zoom) + return EINA_TRUE; + + _ewk_tiled_backing_store_item_request_del(priv, it); + } + + if (it->tile) { + Ewk_Tile *old = it->tile; + if (old->row != (unsigned long)(m_row) + || old->col != (unsigned long)(m_col) + || old->zoom != zoom) { + _ewk_tiled_backing_store_tile_dissociate(priv, it, + last_used); + if (it->update.process) + _ewk_tiled_backing_store_item_request_del(priv, it); + } else if (old->row == (unsigned long)(m_row) + && old->col == (unsigned long)(m_col) + && old->zoom == zoom) + goto end; + } + + t = ewk_tile_matrix_tile_exact_get + (priv->model.matrix, m_col, m_row, zoom); + if (!t) { + /* NOTE: it never returns NULL if it->tile was set! */ + if (it->tile) { + CRITICAL("it->tile=%p, but it should be NULL!", it->tile); + _ewk_tiled_backing_store_tile_dissociate(priv, it, + last_used); + } + + /* Do not add new requests to the render queue */ + if (!priv->render.suspend) { + t = _ewk_tiled_backing_store_tile_new(priv, m_col, m_row, zoom); + if (!t) + return EINA_FALSE; + _ewk_tiled_backing_store_tile_associate(priv, t, it); + } + } else if (t != it->tile) { + if (!it->update.process) { + if (it->tile) + _ewk_tiled_backing_store_tile_dissociate(priv, + it, last_used); + _ewk_tiled_backing_store_tile_associate(priv, t, it); + } + } + + end: + + return EINA_TRUE; + } + + return EINA_TRUE; +} + +static Ewk_Tiled_Backing_Store_Item *_ewk_tiled_backing_store_item_add(Ewk_Tiled_Backing_Store_Data *priv, long col, int row) +{ + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord x, y, tw, th; + + DBG("o=%p", priv->self); + + MALLOC_OR_OOM_RET(it, sizeof(*it), NULL); + + tw = priv->view.tile.w; + th = priv->view.tile.h; + x = priv->view.offset.base.x + priv->view.x + tw *col; + y = priv->view.offset.base.y + priv->view.y + th *row; + + it->tile = NULL; + it->update.process = NULL; + it->smooth_scale = priv->view.tile.zoom_weak_smooth_scale; + _ewk_tiled_backing_store_item_move(it, x, y); + _ewk_tiled_backing_store_item_resize(it, tw, th); + if (!_ewk_tiled_backing_store_item_fill(priv, it, col, row)) { + free(it); + return NULL; + } + + return it; +} + +static void _ewk_tiled_backing_store_item_del(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tiled_Backing_Store_Item *it) +{ + if (it->tile) { + double last_used = ecore_loop_time_get(); + _ewk_tiled_backing_store_tile_dissociate(priv, it, last_used); + } + if (it->update.process) + _ewk_tiled_backing_store_item_request_del(priv, it); + free(it); +} + +static void _ewk_tiled_backing_store_item_smooth_scale_set(Ewk_Tiled_Backing_Store_Item *it, Eina_Bool smooth_scale) +{ + if (it->smooth_scale == smooth_scale) + return; + + if (it->tile) + evas_object_image_smooth_scale_set(it->tile->image, smooth_scale); +} + +static inline void _ewk_tiled_backing_store_changed(Ewk_Tiled_Backing_Store_Data *priv) +{ + if (priv->changed.any) + return; + evas_object_smart_changed(priv->self); + priv->changed.any = EINA_TRUE; +} + +static void _ewk_tiled_backing_store_view_cols_end_del(Ewk_Tiled_Backing_Store_Data *priv, Eina_Inlist **p_row, unsigned int count) +{ + Eina_Inlist *n; + unsigned int i; + + if (!count) + return; + + n = (*p_row)->last; + + for (i = 0; i < count; i++) { + Ewk_Tiled_Backing_Store_Item *it; + it = EINA_INLIST_CONTAINER_GET(n, Ewk_Tiled_Backing_Store_Item); + n = n->prev; + *p_row = eina_inlist_remove(*p_row, EINA_INLIST_GET(it)); + _ewk_tiled_backing_store_item_del(priv, it); + } +} + +static Eina_Bool _ewk_tiled_backing_store_view_cols_end_add(Ewk_Tiled_Backing_Store_Data *priv, Eina_Inlist **p_row, unsigned int base_col, unsigned int count) +{ + unsigned int i, r = p_row - priv->view.items; + + for (i = 0; i < count; i++, base_col++) { + Ewk_Tiled_Backing_Store_Item *it; + + it = _ewk_tiled_backing_store_item_add(priv, base_col, r); + if (!it) { + CRITICAL("failed to add column %u of %u in row %u.", i, count, r); + _ewk_tiled_backing_store_view_cols_end_del(priv, p_row, i); + return EINA_FALSE; + } + + *p_row = eina_inlist_append(*p_row, EINA_INLIST_GET(it)); + } + return EINA_TRUE; +} + +static void _ewk_tiled_backing_store_view_row_del(Ewk_Tiled_Backing_Store_Data *priv, Eina_Inlist *row) +{ + while (row) { + Ewk_Tiled_Backing_Store_Item *it; + it = EINA_INLIST_CONTAINER_GET(row, Ewk_Tiled_Backing_Store_Item); + row = row->next; + _ewk_tiled_backing_store_item_del(priv, it); + } +} + +static void _ewk_tiled_backing_store_view_rows_range_del(Ewk_Tiled_Backing_Store_Data *priv, Eina_Inlist **start, Eina_Inlist **end) +{ + for (; start < end; start++) { + _ewk_tiled_backing_store_view_row_del(priv, *start); + *start = NULL; + } +} + +static void _ewk_tiled_backing_store_view_rows_all_del(Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist **start; + Eina_Inlist **end; + + start = priv->view.items; + end = priv->view.items + priv->view.rows; + _ewk_tiled_backing_store_view_rows_range_del(priv, start, end); + + free(priv->view.items); + priv->view.items = NULL; + priv->view.cols = 0; + priv->view.rows = 0; +} + +static void _ewk_tiled_backing_store_render(void *data, Ewk_Tile *t, const Eina_Rectangle *area) +{ + Ewk_Tiled_Backing_Store_Data *priv = data; + + INF("TODO %p (visible? %d) [%lu,%lu] %d,%d + %dx%d", + t, t->visible, t->col, t->row, area->x, area->y, area->w, area->h); + + if (!t->visible) + return; + + if (priv->view.tile.w != t->w || priv->view.tile.h != t->h) + return; // todo: remove me later, don't even flag as dirty! + + EINA_SAFETY_ON_NULL_RETURN(priv->render.cb); + if (!priv->render.cb(priv->render.data, t, area)) + return; + + evas_object_image_data_update_add(t->image, area->x, area->y, area->w, area->h); +} + +static inline void _ewk_tiled_backing_store_model_matrix_create(Ewk_Tiled_Backing_Store_Data *priv, Ewk_Tile_Unused_Cache *tuc) +{ + if (priv->model.matrix) { + _ewk_tiled_backing_store_view_rows_all_del(priv); + + priv->changed.offset = EINA_FALSE; + priv->changed.size = EINA_TRUE; + + ewk_tile_matrix_free(priv->model.matrix); + } + + priv->model.matrix = ewk_tile_matrix_new + (tuc, priv->model.cur.cols, priv->model.cur.rows, priv->cspace, + _ewk_tiled_backing_store_render, priv); +} + +static void _ewk_tiled_backing_store_smart_member_del(Evas_Object *o, Evas_Object *member) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + if (!priv->contents_clipper) + return; + evas_object_clip_unset(member); + if (!evas_object_clipees_get(priv->contents_clipper)) + evas_object_hide(priv->contents_clipper); +} + +static void _ewk_tiled_backing_store_smart_member_add(Evas_Object *o, Evas_Object *member) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + if (!priv->contents_clipper) + return; + evas_object_clip_set(member, priv->contents_clipper); + if (evas_object_visible_get(o)) + evas_object_show(priv->contents_clipper); +} + +#ifdef DEBUG_MEM_LEAKS +static void _ewk_tiled_backing_store_mem_dbg(Ewk_Tiled_Backing_Store_Data *priv) +{ + static int run = 0; + + run++; + + printf("\n--- BEGIN DEBUG TILED BACKING STORE MEMORY [%d] --\n" + "t=%0.2f, obj=%p, priv=%p, view.items=%p, matrix=%p\n", + run, ecore_loop_time_get(), + priv->self, priv, priv->view.items, priv->model.matrix); + + ewk_tile_matrix_dbg(priv->model.matrix); + ewk_tile_accounting_dbg(); + + printf("--- END DEBUG TILED BACKING STORE MEMORY [%d] --\n\n", run); +} + +static Eina_Bool _ewk_tiled_backing_store_sig_usr(void *data, int type, void *event) +{ + Ecore_Event_Signal_User *sig = (Ecore_Event_Signal_User*)event; + Ewk_Tiled_Backing_Store_Data *priv = (Ewk_Tiled_Backing_Store_Data*)data; + + if (sig->number == 2) { + Ewk_Tile_Unused_Cache *tuc; + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_auto_flush(tuc); + } + + _ewk_tiled_backing_store_view_dbg(priv); + _ewk_tiled_backing_store_mem_dbg(priv); + return EINA_TRUE; +} +#endif + +static void _ewk_tiled_backing_store_smart_add(Evas_Object *o) +{ + Ewk_Tiled_Backing_Store_Data *priv; + + DBG("o=%p", o); + + CALLOC_OR_OOM_RET(priv, sizeof(*priv)); + + priv->self = o; + priv->view.tile.zoom = 1.0; + priv->view.tile.w = TILE_W; + priv->view.tile.h = TILE_H; + priv->view.offset.cur.x = 0; + priv->view.offset.cur.y = 0; + priv->view.offset.old.x = 0; + priv->view.offset.old.y = 0; + priv->view.offset.base.x = 0; + priv->view.offset.base.y = 0; + + priv->model.base.col = 0; + priv->model.base.row = 0; + priv->model.cur.cols = 1; + priv->model.cur.rows = 1; + priv->model.old.cols = 0; + priv->model.old.rows = 0; + priv->model.width = 0; + priv->model.height = 0; + priv->render.process_entire_queue = EINA_TRUE; + priv->render.suspend = EINA_FALSE; + priv->cspace = EVAS_COLORSPACE_ARGB8888; // TODO: detect it. + + evas_object_smart_data_set(o, priv); + _parent_sc.add(o); + + priv->contents_clipper = evas_object_rectangle_add( + evas_object_evas_get(o)); + evas_object_move(priv->contents_clipper, 0, 0); + evas_object_resize(priv->contents_clipper, + priv->model.width, priv->model.height); + evas_object_color_set(priv->contents_clipper, 255, 255, 255, 255); + evas_object_show(priv->contents_clipper); + evas_object_smart_member_add(priv->contents_clipper, o); + + _ewk_tiled_backing_store_model_matrix_create(priv, NULL); + evas_object_move(priv->base.clipper, 0, 0); + evas_object_resize(priv->base.clipper, 0, 0); + evas_object_clip_set(priv->contents_clipper, priv->base.clipper); + +#ifdef DEBUG_MEM_LEAKS + priv->sig_usr = ecore_event_handler_add + (ECORE_EVENT_SIGNAL_USER, _ewk_tiled_backing_store_sig_usr, priv); +#endif +} + +static void _ewk_tiled_backing_store_smart_del(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + DBG("o=%p", o); + Ewk_Tile_Unused_Cache *tuc; + + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_unlock_area(tuc); + + _ewk_tiled_backing_store_flush(priv); + + _ewk_tiled_backing_store_pre_render_request_flush(priv); + _ewk_tiled_backing_store_item_process_idler_stop(priv); + _ewk_tiled_backing_store_view_rows_all_del(priv); + +#ifdef DEBUG_MEM_LEAKS + _ewk_tiled_backing_store_mem_dbg(priv); + if (priv->sig_usr) + priv->sig_usr = ecore_event_handler_del(priv->sig_usr); +#endif + + ewk_tile_matrix_free(priv->model.matrix); + evas_object_smart_member_del(priv->contents_clipper); + evas_object_del(priv->contents_clipper); + + _parent_sc.del(o); + +#ifdef DEBUG_MEM_LEAKS + printf("\nIMPORTANT: TILED BACKING STORE DELETED (may be real leaks)\n"); + ewk_tile_accounting_dbg(); +#endif +} + +static void _ewk_tiled_backing_store_smart_move(Evas_Object *o, Evas_Coord x, Evas_Coord y) +{ + DBG("o=%p, new pos: %dx%d", o, x, y); + + PRIV_DATA_GET_OR_RETURN(o, priv); + + if (priv->changed.pos) + return; + + if (priv->view.x == x && priv->view.y == y) + return; + + priv->changed.pos = EINA_TRUE; + _ewk_tiled_backing_store_changed(priv); +} + +static void _ewk_tiled_backing_store_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h) +{ + DBG("o=%p, new size: %dx%d", o, w, h); + + PRIV_DATA_GET_OR_RETURN(o, priv); + + if (priv->changed.size) + return; + + if (priv->view.w == w && priv->view.h == h) + return; + + priv->changed.size = EINA_TRUE; + _ewk_tiled_backing_store_changed(priv); +} + +static void _ewk_tiled_backing_store_recalc_renderers(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord w, Evas_Coord h, Evas_Coord tw, Evas_Coord th) +{ + long cols, rows, old_rows, old_cols; + INF("o=%p, new size: %dx%d", priv->self, w, h); + + cols = 1 + (int)ceil((float)w / (float)tw); + rows = 1 + (int)ceil((float)h / (float)th); + + INF("o=%p new grid size cols: %ld, rows: %ld, was %ld, %ld", + priv->self, cols, rows, priv->view.cols, priv->view.rows); + + if (priv->view.cols == cols && priv->view.rows == rows) + return; + + old_cols = priv->view.cols; + old_rows = priv->view.rows; + + if (rows < old_rows) { + Eina_Inlist **start, **end; + start = priv->view.items + rows; + end = priv->view.items + old_rows; + _ewk_tiled_backing_store_view_rows_range_del(priv, start, end); + } + REALLOC_OR_OOM_RET(priv->view.items, sizeof(Eina_Inlist*) * (int)rows); + priv->view.rows = rows; + priv->view.cols = cols; + if (rows > old_rows) { + Eina_Inlist **start, **end; + start = priv->view.items + old_rows; + end = priv->view.items + rows; + for (; start < end; start++) { + Eina_Bool r; + *start = NULL; + r = _ewk_tiled_backing_store_view_cols_end_add + (priv, start, 0, cols); + if (!r) { + CRITICAL("failed to allocate %ld columns", cols); + _ewk_tiled_backing_store_view_rows_range_del + (priv, priv->view.items + old_rows, start); + priv->view.rows = old_rows; + return; + } + } + } + + if (cols != old_cols) { + Eina_Inlist **start, **end; + int todo = cols - old_cols; + start = priv->view.items; + end = start + MIN(old_rows, rows); + if (todo > 0) { + for (; start < end; start++) { + Eina_Bool r; + r = _ewk_tiled_backing_store_view_cols_end_add + (priv, start, old_cols, todo); + if (!r) { + CRITICAL("failed to allocate %d columns!", todo); + + for (start--; start >= priv->view.items; start--) + _ewk_tiled_backing_store_view_cols_end_del(priv, start, todo); + if (rows > old_rows) { + start = priv->view.items + old_rows; + end = priv->view.items + rows; + for (; start < end; start++) + _ewk_tiled_backing_store_view_cols_end_del(priv, start, todo); + } + return; + } + } + } else if (todo < 0) { + todo = -todo; + for (; start < end; start++) + _ewk_tiled_backing_store_view_cols_end_del(priv, start, todo); + } + } + + _ewk_tiled_backing_store_fill_renderers(priv); +} + +static void _ewk_tiled_backing_store_smart_calculate_size(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord w, Evas_Coord h) +{ + evas_object_resize(priv->base.clipper, w, h); + + priv->view.w = w; + priv->view.h = h; + + _ewk_tiled_backing_store_recalc_renderers( + priv, w, h, priv->view.tile.w, priv->view.tile.h); +} + +// TODO: remove me later. +static inline void _ewk_tiled_backing_store_view_dbg(const Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist **start, **end; + printf("tiles=%2ld,%2ld model=%2ld,%2ld [%dx%d] base=%+3ld,%+4ld offset=%+4d,%+4d old=%+4d,%+4d base=%+3d,%+3d\n", + priv->view.cols, priv->view.rows, + priv->model.cur.cols, priv->model.cur.rows, + priv->model.width, priv->model.height, + priv->model.base.col, priv->model.base.row, + priv->view.offset.cur.x, priv->view.offset.cur.y, + priv->view.offset.old.x, priv->view.offset.old.y, + priv->view.offset.base.x, priv->view.offset.base.y); + + start = priv->view.items; + end = priv->view.items + priv->view.rows; + for (; start < end; start++) { + const Ewk_Tiled_Backing_Store_Item *it; + + EINA_INLIST_FOREACH(*start, it) { + printf(" %+4d,%+4d ", it->geometry.x, it->geometry.y); + + if (!it->tile) + printf(" ;"); + else + printf("%8p %lu,%lu;", it->tile, it->tile->col, it->tile->row); + } + printf("\n"); + } + printf("---\n"); +} + +/** + * @internal + * Move top row down as last. + * + * The final result is visually the same, but logically the top that + * went out of screen is now at bottom and filled with new model items. + * + * This is worth just when @a count is smaller than @c + * priv->view.rows, after that one is refilling the whole matrix so it + * is better to trigger full refill. + * + * @param count the number of times to repeat the process. + */ +static void _ewk_tiled_backing_store_view_wrap_up(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y, unsigned int count) +{ + unsigned int last_row = priv->view.rows - 1; + Evas_Coord tw = priv->view.tile.w; + Evas_Coord th = priv->view.tile.h; + Evas_Coord off_y = priv->view.offset.base.y + count * th; + Evas_Coord oy = y + (last_row - count + 1) * th + off_y; + Eina_Inlist **itr_start, **itr_end; + + itr_start = priv->view.items; + itr_end = itr_start + last_row; + + for (; count > 0; count--) { + Eina_Inlist **itr; + Eina_Inlist *tmp = *itr_start; + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord ox = x + priv->view.offset.base.x; + int c = 0; + + for (itr = itr_start; itr < itr_end; itr++) + *itr = *(itr + 1); + *itr = tmp; + + priv->model.base.row++; + EINA_INLIST_FOREACH(tmp, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + ox += tw; + _ewk_tiled_backing_store_item_fill(priv, it, c, last_row); + c++; + } + oy += th; + } + priv->view.offset.base.y = off_y; +} + +/** + * @internal + * Move bottom row up as first. + * + * The final result is visually the same, but logically the bottom that + * went out of screen is now at top and filled with new model items. + * + * This is worth just when @a count is smaller than @c + * priv->view.rows, after that one is refilling the whole matrix so it + * is better to trigger full refill. + * + * @param count the number of times to repeat the process. + */ +static void _ewk_tiled_backing_store_view_wrap_down(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y, unsigned int count) +{ + Evas_Coord tw = priv->view.tile.w; + Evas_Coord th = priv->view.tile.h; + Evas_Coord off_y = priv->view.offset.base.y - count * th; + Evas_Coord oy = y + off_y + (count - 1) * th; + Eina_Inlist **itr_start, **itr_end; + + itr_start = priv->view.items + priv->view.rows - 1; + itr_end = priv->view.items; + + for (; count > 0; count--) { + Eina_Inlist **itr; + Eina_Inlist *tmp = *itr_start; + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord ox = x + priv->view.offset.base.x; + int c = 0; + + for (itr = itr_start; itr > itr_end; itr--) + *itr = *(itr - 1); + *itr = tmp; + + priv->model.base.row--; + EINA_INLIST_FOREACH(tmp, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + ox += tw; + _ewk_tiled_backing_store_item_fill(priv, it, c, 0); + c++; + } + oy -= th; + } + priv->view.offset.base.y = off_y; +} + +/** + * @internal + * Move left-most (first) column right as last (right-most). + * + * The final result is visually the same, but logically the first col that + * went out of screen is now at last and filled with new model items. + * + * This is worth just when @a count is smaller than @c + * priv->view.cols, after that one is refilling the whole matrix so it + * is better to trigger full refill. + * + * @param count the number of times to repeat the process. + */ +static void _ewk_tiled_backing_store_view_wrap_left(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y, unsigned int count) +{ + unsigned int r, last_col = priv->view.cols - 1; + Evas_Coord tw = priv->view.tile.w; + Evas_Coord th = priv->view.tile.h; + Evas_Coord off_x = priv->view.offset.base.x + count * tw; + Evas_Coord oy = y + priv->view.offset.base.y; + Eina_Inlist **itr; + Eina_Inlist **itr_end; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + r = 0; + + priv->model.base.col += count; + + for (; itr < itr_end; itr++, r++) { + Evas_Coord ox = x + (last_col - count + 1) * tw + off_x; + unsigned int i, c = last_col - count + 1; + + for (i = 0; i < count; i++, c++, ox += tw) { + Ewk_Tiled_Backing_Store_Item *it; + it = EINA_INLIST_CONTAINER_GET(*itr, Ewk_Tiled_Backing_Store_Item); + *itr = eina_inlist_demote(*itr, *itr); + + _ewk_tiled_backing_store_item_move(it, ox, oy); + _ewk_tiled_backing_store_item_fill(priv, it, c, r); + } + oy += th; + } + + priv->view.offset.base.x = off_x; +} + +/** + * @internal + * Move right-most (last) column left as first (left-most). + * + * The final result is visually the same, but logically the last col that + * went out of screen is now at first and filled with new model items. + * + * This is worth just when @a count is smaller than @c + * priv->view.cols, after that one is refilling the whole matrix so it + * is better to trigger full refill. + * + * @param count the number of times to repeat the process. + */ +static void _ewk_tiled_backing_store_view_wrap_right(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y, unsigned int count) +{ + unsigned int r; + Evas_Coord tw = priv->view.tile.w; + Evas_Coord th = priv->view.tile.h; + Evas_Coord off_x = priv->view.offset.base.x - count * tw; + Evas_Coord oy = y + priv->view.offset.base.y; + Eina_Inlist **itr, **itr_end; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + r = 0; + + priv->model.base.col -= count; + + for (; itr < itr_end; itr++, r++) { + Evas_Coord ox = x + (count - 1) * tw + off_x; + unsigned int i, c = count - 1; + + for (i = 0; i < count; i++, c--, ox -= tw) { + Ewk_Tiled_Backing_Store_Item *it; + it = EINA_INLIST_CONTAINER_GET((*itr)->last, Ewk_Tiled_Backing_Store_Item); + *itr = eina_inlist_promote(*itr, (*itr)->last); + + _ewk_tiled_backing_store_item_move(it, ox, oy); + _ewk_tiled_backing_store_item_fill(priv, it, c, r); + } + oy += th; + } + + priv->view.offset.base.x = off_x; +} + +static void _ewk_tiled_backing_store_view_refill(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y, int step_x, int step_y) +{ + Eina_Inlist **itr, **itr_end; + Evas_Coord base_ox, oy, tw, th; + unsigned int r; + + evas_object_move(priv->base.clipper, x, y); + + tw = priv->view.tile.w; + th = priv->view.tile.h; + + base_ox = x + priv->view.offset.base.x; + oy = y + priv->view.offset.base.y; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + r = 0; + + priv->model.base.col -= step_x; + priv->model.base.row -= step_y; + + for (; itr < itr_end; itr++, r++) { + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord ox = base_ox; + unsigned int c = 0; + EINA_INLIST_FOREACH(*itr, it) { + _ewk_tiled_backing_store_item_fill(priv, it, c, r); + _ewk_tiled_backing_store_item_move(it, ox, oy); + c++; + ox += tw; + } + oy += th; + } +} + +static void _ewk_tiled_backing_store_view_pos_apply(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y) +{ + Eina_Inlist **itr, **itr_end; + Evas_Coord base_ox, oy, tw, th; + + evas_object_move(priv->base.clipper, x, y); + + tw = priv->view.tile.w; + th = priv->view.tile.h; + + base_ox = x + priv->view.offset.base.x; + oy = y + priv->view.offset.base.y; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + for (; itr < itr_end; itr++) { + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord ox = base_ox; + EINA_INLIST_FOREACH(*itr, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + ox += tw; + } + oy += th; + } +} + +static void _ewk_tiled_backing_store_smart_calculate_offset_force(Ewk_Tiled_Backing_Store_Data *priv) +{ + Evas_Coord dx = priv->view.offset.cur.x - priv->view.offset.old.x; + Evas_Coord dy = priv->view.offset.cur.y - priv->view.offset.old.y; + Evas_Coord tw, th; + int step_y, step_x; + + INF("o=%p, offset: %+4d, %+4d (%+4d, %+4d)", + priv->self, dx, dy, priv->view.offset.cur.x, priv->view.offset.cur.y); + + tw = priv->view.tile.w; + th = priv->view.tile.h; + + long new_col = -priv->view.offset.cur.x / tw; + step_x = priv->model.base.col - new_col; + long new_row = -priv->view.offset.cur.y / th; + step_y = priv->model.base.row - new_row; + + priv->view.offset.old.x = priv->view.offset.cur.x; + priv->view.offset.old.y = priv->view.offset.cur.y; + evas_object_move( + priv->contents_clipper, + priv->view.offset.cur.x + priv->view.x, + priv->view.offset.cur.y + priv->view.y); + + priv->view.offset.base.x += dx - step_x * tw; + priv->view.offset.base.y += dy - step_y * th; + + _ewk_tiled_backing_store_view_refill + (priv, priv->view.x, priv->view.y, step_x, step_y); +} + +static void _ewk_tiled_backing_store_smart_calculate_offset(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y) +{ + Evas_Coord dx = priv->view.offset.cur.x - priv->view.offset.old.x; + Evas_Coord dy = priv->view.offset.cur.y - priv->view.offset.old.y; + Evas_Coord tw, th; + int step_y, step_x; + + INF("o=%p, offset: %+4d, %+4d (%+4d, %+4d)", + priv->self, dx, dy, priv->view.offset.cur.x, priv->view.offset.cur.y); + + if (!dx && !dy) + return; + + tw = priv->view.tile.w; + th = priv->view.tile.h; + + long new_col = -priv->view.offset.cur.x / tw; + step_x = priv->model.base.col - new_col; + long new_row = -priv->view.offset.cur.y / th; + step_y = priv->model.base.row - new_row; + + priv->view.offset.old.x = priv->view.offset.cur.x; + priv->view.offset.old.y = priv->view.offset.cur.y; + evas_object_move( + priv->contents_clipper, + priv->view.offset.cur.x + priv->view.x, + priv->view.offset.cur.y + priv->view.y); + + if ((step_x < 0 && step_x <= -priv->view.cols) + || (step_x > 0 && step_x >= priv->view.cols) + || (step_y < 0 && step_y <= -priv->view.rows) + || (step_y > 0 && step_y >= priv->view.rows)) { + + priv->view.offset.base.x += dx - step_x * tw; + priv->view.offset.base.y += dy - step_y * th; + + _ewk_tiled_backing_store_view_refill + (priv, priv->view.x, priv->view.y, step_x, step_y); + return; + } + + priv->view.offset.base.x += dx; + priv->view.offset.base.y += dy; + + if (step_y < 0) + _ewk_tiled_backing_store_view_wrap_up(priv, x, y, -step_y); + else if (step_y > 0) + _ewk_tiled_backing_store_view_wrap_down(priv, x, y, step_y); + + if (step_x < 0) + _ewk_tiled_backing_store_view_wrap_left(priv, x, y, -step_x); + else if (step_x > 0) + _ewk_tiled_backing_store_view_wrap_right(priv, x, y, step_x); + + _ewk_tiled_backing_store_view_pos_apply(priv, x, y); +} + +static void _ewk_tiled_backing_store_smart_calculate_pos(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y) +{ + _ewk_tiled_backing_store_view_pos_apply(priv, x, y); + priv->view.x = x; + priv->view.y = y; + evas_object_move( + priv->contents_clipper, + priv->view.offset.cur.x + priv->view.x, + priv->view.offset.cur.y + priv->view.y); +} + +static void _ewk_tiled_backing_store_fill_renderers(Ewk_Tiled_Backing_Store_Data *priv) +{ + Eina_Inlist *it; + Ewk_Tiled_Backing_Store_Item *item; + int i, j; + + for (i = 0; i < priv->view.rows; i++) { + it = priv->view.items[i]; + j = 0; + EINA_INLIST_FOREACH(it, item) + _ewk_tiled_backing_store_item_fill(priv, item, j++, i); + } +} + +static void _ewk_tiled_backing_store_smart_calculate(Evas_Object *o) +{ + Evas_Coord x, y, w, h; + + evas_object_geometry_get(o, &x, &y, &w, &h); + DBG("o=%p at %d,%d + %dx%d", o, x, y, w, h); + + PRIV_DATA_GET_OR_RETURN(o, priv); + + priv->changed.any = EINA_FALSE; + + ewk_tile_matrix_freeze(priv->model.matrix); + + if (!priv->render.suspend && priv->changed.model) { + unsigned long cols, rows; + + cols = priv->model.width / priv->view.tile.w + 1; + rows = priv->model.height / priv->view.tile.h + 1; + + priv->model.old.cols = priv->model.cur.cols; + priv->model.old.rows = priv->model.cur.rows; + priv->model.cur.cols = cols; + priv->model.cur.rows = rows; + if (priv->model.old.cols > cols) + cols = priv->model.old.cols; + if (priv->model.old.rows > rows) + rows = priv->model.old.rows; + ewk_tile_matrix_resize(priv->model.matrix, cols, rows); + } + + if (priv->changed.pos && (priv->view.x != x || priv->view.y != y)) { + _ewk_tiled_backing_store_smart_calculate_pos(priv, x, y); + priv->changed.pos = EINA_FALSE; + } else if (priv->changed.offset) { + _ewk_tiled_backing_store_smart_calculate_offset(priv, x, y); + priv->changed.offset = EINA_FALSE; + } + + if (priv->changed.size) { + _ewk_tiled_backing_store_smart_calculate_size(priv, w, h); + priv->changed.size = EINA_FALSE; + } + + if (!priv->render.suspend && priv->changed.model) { + Eina_Rectangle rect; + rect.x = 0; + rect.y = 0; + rect.w = priv->model.width; + rect.h = priv->model.height; + _ewk_tiled_backing_store_fill_renderers(priv); + ewk_tile_matrix_resize(priv->model.matrix, + priv->model.cur.cols, + priv->model.cur.rows); + priv->changed.model = EINA_FALSE; + evas_object_resize(priv->contents_clipper, + priv->model.width, priv->model.height); + _ewk_tiled_backing_store_smart_calculate_offset_force(priv); + + /* Make sure we do not miss any important repaint by + * repainting the whole viewport */ + const Eina_Rectangle r = + { 0, 0, priv->model.width, priv->model.height }; + ewk_tile_matrix_update(priv->model.matrix, &r, + priv->view.tile.zoom); + } + + ewk_tile_matrix_thaw(priv->model.matrix); + + _ewk_tiled_backing_store_updates_process(priv); + + if (priv->view.offset.base.x > 0 + || priv->view.offset.base.x <= - priv->view.tile.w + || priv->view.offset.base.y > 0 + || priv->view.offset.base.y <= - priv->view.tile.h) + ERR("incorrect base offset %+4d,%+4d, tile=%dx%d, cur=%+4d,%+4d\n", + priv->view.offset.base.x, priv->view.offset.base.y, + priv->view.tile.w, priv->view.tile.h, + priv->view.offset.cur.x, priv->view.offset.cur.y); + +} + +Evas_Object *ewk_tiled_backing_store_add(Evas *e) +{ + static Evas_Smart *smart = NULL; + + if (_ewk_tiled_log_dom < 0) + _ewk_tiled_log_dom = eina_log_domain_register("Ewk_Tiled_Backing_Store", NULL); + + if (!smart) { + static Evas_Smart_Class sc = + EVAS_SMART_CLASS_INIT_NAME_VERSION("Ewk_Tiled_Backing_Store"); + + evas_object_smart_clipped_smart_set(&sc); + _parent_sc = sc; + + sc.add = _ewk_tiled_backing_store_smart_add; + sc.del = _ewk_tiled_backing_store_smart_del; + sc.resize = _ewk_tiled_backing_store_smart_resize; + sc.move = _ewk_tiled_backing_store_smart_move; + sc.calculate = _ewk_tiled_backing_store_smart_calculate; + sc.member_add = _ewk_tiled_backing_store_smart_member_add; + sc.member_del = _ewk_tiled_backing_store_smart_member_del; + + smart = evas_smart_class_new(&sc); + } + + return evas_object_smart_add(e, smart); +} + +void ewk_tiled_backing_store_render_cb_set(Evas_Object *o, Eina_Bool (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *area), const void *data) +{ + EINA_SAFETY_ON_NULL_RETURN(cb); + PRIV_DATA_GET_OR_RETURN(o, priv); + priv->render.cb = cb; + priv->render.data = (void*)data; +} + +Ewk_Tile_Unused_Cache *ewk_tiled_backing_store_tile_unused_cache_get(const Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, NULL); + return ewk_tile_matrix_unused_cache_get(priv->model.matrix); +} + +void ewk_tiled_backing_store_tile_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *tuc) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + + if (ewk_tile_matrix_unused_cache_get(priv->model.matrix) == tuc) + return; + + _ewk_tiled_backing_store_model_matrix_create(priv, tuc); +} + +static Eina_Bool _ewk_tiled_backing_store_scroll_full_offset_set_internal(Ewk_Tiled_Backing_Store_Data *priv, Evas_Coord x, Evas_Coord y) +{ + /* TODO: check offset go out of bounds, clamp */ + if (priv->render.disabled) + return EINA_FALSE; + + priv->view.offset.cur.x = x; + priv->view.offset.cur.y = y; + + priv->changed.offset = EINA_TRUE; + _ewk_tiled_backing_store_changed(priv); + + return EINA_TRUE; +} + +Eina_Bool ewk_tiled_backing_store_scroll_full_offset_set(Evas_Object *o, Evas_Coord x, Evas_Coord y) +{ + DBG("o=%p, x=%d, y=%d", o, x, y); + + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + if (x == priv->view.offset.cur.x && y == priv->view.offset.cur.y) + return EINA_TRUE; + + return _ewk_tiled_backing_store_scroll_full_offset_set_internal(priv, x, y); +} + +Eina_Bool ewk_tiled_backing_store_scroll_full_offset_add(Evas_Object *o, Evas_Coord dx, Evas_Coord dy) +{ + DBG("o=%p, dx=%d, dy=%d", o, dx, dy); + + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + if (!dx && !dy) + return EINA_TRUE; + + return _ewk_tiled_backing_store_scroll_full_offset_set_internal + (priv, priv->view.offset.cur.x + dx, priv->view.offset.cur.y + dy); +} + +static Eina_Bool _ewk_tiled_backing_store_zoom_set_internal(Ewk_Tiled_Backing_Store_Data *priv, float *zoom, Evas_Coord cx, Evas_Coord cy, Evas_Coord *offx, Evas_Coord *offy) +{ + *offx = priv->view.offset.cur.x; + *offy = priv->view.offset.cur.y; + + if (fabsf(priv->view.tile.zoom - *zoom) < ZOOM_STEP_MIN) { + DBG("ignored as zoom difference is < %f: %f", + (double)ZOOM_STEP_MIN, fabsf(priv->view.tile.zoom - *zoom)); + return EINA_TRUE; + } + + _ewk_tiled_backing_store_pre_render_request_flush(priv); + Evas_Coord tw, th; + tw = TILE_SIZE_AT_ZOOM(TILE_W, *zoom); + tw = (tw >> 1) << 1; + *zoom = TILE_W_ZOOM_AT_SIZE(tw); + /* WARNING: assume reverse zoom is the same for both axis */ + th = TILE_SIZE_AT_ZOOM(TILE_H, *zoom); + + float scale = *zoom / priv->view.tile.zoom; + + priv->view.tile.zoom = *zoom; + // todo: check cx [0, w]... + priv->view.offset.zoom_center.x = cx; + priv->view.offset.zoom_center.y = cy; + + priv->view.tile.w = tw; + priv->view.tile.h = th; + + if (!priv->view.w || !priv->view.h) { + priv->view.offset.base.x = 0; + priv->view.offset.base.y = 0; + return EINA_TRUE; + } + Eina_Inlist **itr, **itr_end; + Ewk_Tiled_Backing_Store_Item *it; + + Evas_Coord new_x = cx + (priv->view.offset.cur.x - cx) * scale; + Evas_Coord new_y = cy + (priv->view.offset.cur.y - cy) * scale; + Evas_Coord bx = cx + (priv->view.offset.base.x - cx) * scale; + Evas_Coord by = cy + (priv->view.offset.base.y - cy) * scale; + + Evas_Coord model_width = priv->model.width * scale; + Evas_Coord model_height = priv->model.height * scale; + + if (model_width < priv->view.w || new_x >= 0) + new_x = 0; + else if (-new_x + priv->view.w >= model_width) + new_x = -model_width + priv->view.w; + + if (model_height < priv->view.h || new_y >= 0) + new_y = 0; + else if (-new_y + priv->view.h >= model_height) + new_y = -model_height + priv->view.h; + + bx = new_x % tw; + priv->model.base.col = - new_x / tw; + by = new_y % th; + priv->model.base.row = - new_y / th; + + priv->changed.size = EINA_TRUE; + _ewk_tiled_backing_store_changed(priv); + + priv->view.offset.cur.x = new_x; + priv->view.offset.cur.y = new_y; + priv->view.offset.base.x = bx; + priv->view.offset.base.y = by; + + priv->view.offset.old.x = priv->view.offset.cur.x; + priv->view.offset.old.y = priv->view.offset.cur.y; + *offx = priv->view.offset.cur.x; + *offy = priv->view.offset.cur.y; + + evas_object_move( + priv->contents_clipper, + new_x + priv->view.x, + new_y + priv->view.y); + + _ewk_tiled_backing_store_fill_renderers(priv); + + Evas_Coord oy = priv->view.offset.base.y + priv->view.y; + Evas_Coord base_ox = priv->view.x + priv->view.offset.base.x; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + + for (; itr < itr_end; itr++) { + Evas_Coord ox = base_ox; + Eina_Inlist *lst = *itr; + + EINA_INLIST_FOREACH(lst, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + _ewk_tiled_backing_store_item_resize(it, tw, th); + ox += tw; + } + oy += th; + } + + return EINA_TRUE; +} + +Eina_Bool ewk_tiled_backing_store_zoom_set(Evas_Object *o, float *zoom, Evas_Coord cx, Evas_Coord cy, Evas_Coord *offx, Evas_Coord *offy) +{ + DBG("o=%p, zoom=%f", o, (double)*zoom); + + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + + return _ewk_tiled_backing_store_zoom_set_internal(priv, zoom, cx, cy, offx, offy); +} + +Eina_Bool ewk_tiled_backing_store_zoom_weak_set(Evas_Object *o, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + DBG("o=%p, zoom=%f", o, (double)zoom); + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + if (!priv->view.w || !priv->view.h) + return EINA_FALSE; + Eina_Inlist **itr, **itr_end; + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord tw, th; + Eina_Bool recalc = EINA_FALSE; + + tw = TILE_SIZE_AT_ZOOM(TILE_W, zoom); + zoom = TILE_W_ZOOM_AT_SIZE(tw); + /* WARNING: assume reverse zoom is the same for both axis */ + th = TILE_SIZE_AT_ZOOM(TILE_H, zoom); + + float scale = zoom / priv->view.tile.zoom; + + Evas_Coord model_width = priv->model.width * scale; + Evas_Coord model_height = priv->model.height * scale; + + evas_object_resize(priv->contents_clipper, + model_width, model_height); + + int vrows = ceil((float)priv->view.h / (float)th) + 1; + int vcols = ceil((float)priv->view.w / (float)tw) + 1; + Evas_Coord new_x = cx + (priv->view.offset.cur.x - cx) * scale; + Evas_Coord new_y = cy + (priv->view.offset.cur.y - cy) * scale; + Evas_Coord bx = new_x % tw; + Evas_Coord by = new_y % th; + unsigned long base_row = -new_y / th; + unsigned long base_col = -new_x / tw; + + if (base_row != priv->model.base.row || base_col != priv->model.base.col) { + priv->model.base.row = base_row; + priv->model.base.col = base_col; + recalc = EINA_TRUE; + } + + if (vrows > priv->view.rows || vcols > priv->view.cols) + recalc = EINA_TRUE; + + if (recalc) { + Evas_Coord w, h; + evas_object_geometry_get(o, NULL, NULL, &w, &h); + _ewk_tiled_backing_store_recalc_renderers(priv, w, h, tw, th); + _ewk_tiled_backing_store_fill_renderers(priv); + _ewk_tiled_backing_store_updates_process(priv); + } + + Evas_Coord base_ox = bx + priv->view.x; + Evas_Coord oy = by + priv->view.y; + + evas_object_move(priv->contents_clipper, + new_x + priv->view.x, + new_y + priv->view.y); + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + + for (; itr < itr_end; itr++) { + Evas_Coord ox = base_ox; + Eina_Inlist *lst = *itr; + + EINA_INLIST_FOREACH(lst, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + _ewk_tiled_backing_store_item_resize(it, tw, th); + ox += tw; + } + oy += th; + } + + return EINA_TRUE; +} + +void ewk_tiled_backing_store_fix_offsets(Evas_Object *o, Evas_Coord w, Evas_Coord h) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + Eina_Inlist **itr, **itr_end; + Ewk_Tiled_Backing_Store_Item *it; + Evas_Coord new_x = priv->view.offset.cur.x; + Evas_Coord new_y = priv->view.offset.cur.y; + Evas_Coord bx = priv->view.offset.base.x; + Evas_Coord by = priv->view.offset.base.y; + Evas_Coord tw = priv->view.tile.w; + Evas_Coord th = priv->view.tile.h; + + if (-new_x > w) { + new_x = -w; + bx = new_x % tw; + priv->model.base.col = -new_x / tw; + } + + if (-new_y > h) { + new_y = -h; + by = new_y % th; + priv->model.base.row = -new_y / th; + } + + if (bx >= 0 || bx <= -2 * priv->view.tile.w) { + bx = new_x % tw; + priv->model.base.col = -new_x / tw; + } + + if (by >= 0 || by <= -2 * priv->view.tile.h) { + by = new_y % th; + priv->model.base.row = -new_y / th; + } + + priv->view.offset.cur.x = new_x; + priv->view.offset.cur.y = new_y; + priv->view.offset.old.x = new_x; + priv->view.offset.old.y = new_y; + priv->view.offset.base.x = bx; + priv->view.offset.base.y = by; + evas_object_move(priv->contents_clipper, + new_x + priv->view.x, + new_y + priv->view.y); + + Evas_Coord oy = priv->view.offset.base.y + priv->view.y; + Evas_Coord base_ox = priv->view.x + priv->view.offset.base.x; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + + for (; itr < itr_end; itr++) { + Evas_Coord ox = base_ox; + Eina_Inlist *lst = *itr; + + EINA_INLIST_FOREACH(lst, it) { + _ewk_tiled_backing_store_item_move(it, ox, oy); + _ewk_tiled_backing_store_item_resize(it, tw, th); + ox += tw; + } + oy += th; + } +} + +void ewk_tiled_backing_store_zoom_weak_smooth_scale_set(Evas_Object *o, Eina_Bool smooth_scale) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + Eina_Inlist **itr, **itr_end; + + itr = priv->view.items; + itr_end = itr + priv->view.rows; + priv->view.tile.zoom_weak_smooth_scale = smooth_scale; + + for (; itr< itr_end; itr++) { + Ewk_Tiled_Backing_Store_Item *it; + EINA_INLIST_FOREACH(*itr, it) + if (it->tile) + _ewk_tiled_backing_store_item_smooth_scale_set + (it, smooth_scale); + } +} + +Eina_Bool ewk_tiled_backing_store_update(Evas_Object *o, const Eina_Rectangle *update) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + + if (priv->render.disabled) + return EINA_FALSE; + + return ewk_tile_matrix_update(priv->model.matrix, update, + priv->view.tile.zoom); +} + +void ewk_tiled_backing_store_updates_process_pre_set(Evas_Object *o, void *(*cb)(void *data, Evas_Object *o), const void *data) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + priv->process.pre_cb = cb; + priv->process.pre_data = (void*)data; +} + +void ewk_tiled_backing_store_updates_process_post_set(Evas_Object *o, void *(*cb)(void *data, void *pre_data, Evas_Object *o), const void *data) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + priv->process.post_cb = cb; + priv->process.post_data = (void*)data; +} + +void ewk_tiled_backing_store_updates_process(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + _ewk_tiled_backing_store_updates_process(priv); +} + +void ewk_tiled_backing_store_updates_clear(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + + ewk_tile_matrix_updates_clear(priv->model.matrix); +} + +void ewk_tiled_backing_store_contents_resize(Evas_Object *o, Evas_Coord width, Evas_Coord height) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + + if (width == priv->model.width && height == priv->model.height) + return; + + priv->model.width = width; + priv->model.height = height; + priv->changed.model = EINA_TRUE; + + DBG("width,height=%d, %d", width, height); + _ewk_tiled_backing_store_changed(priv); +} + +void ewk_tiled_backing_store_disabled_update_set(Evas_Object *o, Eina_Bool value) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + + if (value != priv->render.disabled) + priv->render.disabled = value; +} + +void ewk_tiled_backing_store_flush(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + Ewk_Tile_Unused_Cache *tuc = NULL; + + priv->view.offset.cur.x = 0; + priv->view.offset.cur.y = 0; + priv->view.offset.old.x = 0; + priv->view.offset.old.y = 0; + priv->view.offset.base.x = 0; + priv->view.offset.base.y = 0; + priv->model.base.col = 0; + priv->model.base.row = 0; + priv->changed.size = EINA_TRUE; + +#ifdef DEBUG_MEM_LEAKS + printf("\nFLUSHED BACKING STORE, STATUS BEFORE DELETING TILE MATRIX:\n"); + _ewk_tiled_backing_store_mem_dbg(priv); +#endif + + _ewk_tiled_backing_store_pre_render_request_flush(priv); + _ewk_tiled_backing_store_tile_dissociate_all(priv); + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_clear(tuc); + +#ifdef DEBUG_MEM_LEAKS + printf("\nFLUSHED BACKING STORE, STATUS AFTER RECREATING TILE MATRIX:\n"); + _ewk_tiled_backing_store_mem_dbg(priv); +#endif +} + +Eina_Bool ewk_tiled_backing_store_pre_render_region(Evas_Object *o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + Eina_Tile_Grid_Slicer slicer; + const Eina_Tile_Grid_Info *info; + Evas_Coord tw, th; + Ewk_Tile_Unused_Cache *tuc; + + tw = TILE_SIZE_AT_ZOOM(TILE_W, zoom); + tw = (tw >> 1) << 1; + zoom = TILE_W_ZOOM_AT_SIZE(tw); + /* WARNING: assume reverse zoom is the same for both axis */ + th = TILE_SIZE_AT_ZOOM(TILE_H, zoom); + + if (!eina_tile_grid_slicer_setup(&slicer, x, y, w, h, tw, th)) { + ERR("could not setup grid slicer for %d,%d+%dx%d tile=%dx%d", + x, y, w, h, tw, th); + return EINA_FALSE; + } + + while (eina_tile_grid_slicer_next(&slicer, &info)) { + const unsigned long c = info->col; + const unsigned long r = info->row; + if (!_ewk_tiled_backing_store_pre_render_request_add(priv, c, r, zoom, PRE_RENDER_PRIORITY_LOW)) + break; + } + + _ewk_tiled_backing_store_item_process_idler_start(priv); + + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_lock_area(tuc, x, y, w, h, zoom); + return EINA_TRUE; +} + +Eina_Bool ewk_tiled_backing_store_pre_render_relative_radius(Evas_Object *o, unsigned int n, float zoom) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + unsigned long start_row, end_row, start_col, end_col, i, j, w, h; + Ewk_Tile_Unused_Cache *tuc; + + INF("priv->model.base.row =%ld, n=%u priv->view.rows=%lu", + priv->model.base.row, n, priv->view.rows); + start_row = (long)priv->model.base.row - n; + start_col = (long)priv->model.base.col - n; + end_row = MIN(priv->model.cur.rows - 1, + priv->model.base.row + priv->view.rows + n - 1); + end_col = MIN(priv->model.cur.cols - 1, + priv->model.base.col + priv->view.cols + n - 1); + + INF("start_row=%lu, end_row=%lu, start_col=%lu, end_col=%lu", + start_row, end_row, start_col, end_col); + + for (i = start_row; i <= end_row; i++) + for (j = start_col; j <= end_col; j++) + if (!_ewk_tiled_backing_store_pre_render_request_add(priv, j, i, zoom, PRE_RENDER_PRIORITY_LOW)) + goto start_processing; + +start_processing: + _ewk_tiled_backing_store_item_process_idler_start(priv); + + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + h = (end_row - start_row + 1) * TILE_SIZE_AT_ZOOM(TILE_H, zoom); + w = (end_col - start_col + 1) * TILE_SIZE_AT_ZOOM(TILE_W, zoom); + ewk_tile_unused_cache_lock_area(tuc, + start_col * TILE_SIZE_AT_ZOOM(TILE_W, zoom), + start_row * TILE_SIZE_AT_ZOOM(TILE_H, zoom), w, h, zoom); + + return EINA_TRUE; +} + +void ewk_tiled_backing_store_pre_render_cancel(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + Ewk_Tile_Unused_Cache *tuc; + + _ewk_tiled_backing_store_pre_render_request_clear(priv); + + tuc = ewk_tile_matrix_unused_cache_get(priv->model.matrix); + ewk_tile_unused_cache_unlock_area(tuc); +} + +Eina_Bool ewk_tiled_backing_store_disable_render(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + return _ewk_tiled_backing_store_disable_render(priv); +} + +Eina_Bool ewk_tiled_backing_store_enable_render(Evas_Object *o) +{ + PRIV_DATA_GET_OR_RETURN(o, priv, EINA_FALSE); + _ewk_tiled_backing_store_changed(priv); + return _ewk_tiled_backing_store_enable_render(priv); +} + +/** + * Set the process_entire_queue flag of the renderer idler. + * + * + * @param o the tiled backing store object + * @param value EINA_TRUE if we want to process all the request of our queue. EINA_FALSE otherwise. + */ +void ewk_tiled_backing_store_process_entire_queue_set(Evas_Object *o, Eina_Bool value) +{ + PRIV_DATA_GET_OR_RETURN(o, priv); + if (priv->render.process_entire_queue != value) + priv->render.process_entire_queue = value; +} diff --git a/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h b/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h new file mode 100644 index 0000000..4af58c8 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_backing_store.h @@ -0,0 +1,131 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_tiled_backing_store_h +#define ewk_tiled_backing_store_h + +#include "EWebKit.h" + +/* Enable accounting of render time in tile statistics */ +// #define TILE_STATS_ACCOUNT_RENDER_TIME + + +/* If define ewk will do more accounting to check for memory leaks + * try "kill -USR1 $PID" to get instantaneous debug + * try "kill -USR2 $PID" to get instantaneous debug and force flush of cache + */ +#define DEBUG_MEM_LEAKS 1 + +#define TILE_W (256) +#define TILE_H (256) + +#define ZOOM_STEP_MIN (0.01) + +#define TILE_SIZE_AT_ZOOM(SIZE, ZOOM) ((int)roundf((SIZE) * (ZOOM))) +#define TILE_W_ZOOM_AT_SIZE(SIZE) ((float)SIZE / (float)TILE_W) +#define TILE_H_ZOOM_AT_SIZE(SIZE) ((float)SIZE / (float)TILE_H) + +#ifdef __cplusplus +extern "C" { +#endif + +#include <Evas.h> +#include <cairo.h> + +typedef struct _Ewk_Tile Ewk_Tile; +typedef struct _Ewk_Tile_Stats Ewk_Tile_Stats; +typedef struct _Ewk_Tile_Matrix Ewk_Tile_Matrix; + +struct _Ewk_Tile_Stats { + double last_used; /**< time of last use */ +#ifdef TILE_STATS_ACCOUNT_RENDER_TIME + double render_time; /**< amount of time this tile took to render */ +#endif + unsigned int area; /**< cache for (w * h) */ + unsigned int misses; /**< number of times it became dirty but not + * repainted at all since it was not visible. + */ + Eina_Bool full_update:1; /**< tile requires full size update */ +}; + +struct _Ewk_Tile { + EINA_INLIST; /**< sibling tiles at same (i, j) but other zoom */ + Eina_Tiler *updates; /**< updated/dirty areas */ + Ewk_Tile_Stats stats; /**< tile usage statistics */ + unsigned long col, row; /**< tile tile position */ + Evas_Coord x, y; /**< tile coordinate position */ + + /* TODO: does it worth to keep those or create on demand? */ + cairo_surface_t *surface; + cairo_t *cairo; + + /** Never ever change those after tile is created (respect const!) */ + const Evas_Coord w, h; /**< tile size (see TILE_SIZE_AT_ZOOM()) */ + const Evas_Colorspace cspace; /**< colorspace */ + const float zoom; /**< zoom level contents were rendered at */ + const size_t bytes; /**< bytes used in pixels. keep + * before pixels to guarantee + * alignement! + */ + int visible; /**< visibility counter of this tile */ + Evas_Object *image; /**< Evas Image, the tile to be rendered */ + uint8_t *pixels; +}; + +#include "ewk_tiled_matrix.h" +#include "ewk_tiled_model.h" + +/* view */ +EAPI Evas_Object *ewk_tiled_backing_store_add(Evas *e); + +EAPI void ewk_tiled_backing_store_render_cb_set(Evas_Object *o, Eina_Bool (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *area), const void *data); + +EAPI Eina_Bool ewk_tiled_backing_store_scroll_full_offset_set(Evas_Object *o, Evas_Coord x, Evas_Coord y); +EAPI Eina_Bool ewk_tiled_backing_store_scroll_full_offset_add(Evas_Object *o, Evas_Coord dx, Evas_Coord dy); +EAPI Eina_Bool ewk_tiled_backing_store_scroll_inner_offset_add(Evas_Object *o, Evas_Coord dx, Evas_Coord dy, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); + +EAPI Eina_Bool ewk_tiled_backing_store_zoom_set(Evas_Object *o, float *zoom, Evas_Coord cx, Evas_Coord cy, Evas_Coord *offx, Evas_Coord *offy); +EAPI Eina_Bool ewk_tiled_backing_store_zoom_weak_set(Evas_Object *o, float zoom, Evas_Coord cx, Evas_Coord cy); +EAPI void ewk_tiled_backing_store_fix_offsets(Evas_Object *o, Evas_Coord w, Evas_Coord h); +EAPI void ewk_tiled_backing_store_zoom_weak_smooth_scale_set(Evas_Object *o, Eina_Bool smooth_scale); +EAPI Eina_Bool ewk_tiled_backing_store_update(Evas_Object *o, const Eina_Rectangle *update); +EAPI void ewk_tiled_backing_store_updates_process_pre_set(Evas_Object *o, void *(*cb)(void *data, Evas_Object *o), const void *data); +EAPI void ewk_tiled_backing_store_updates_process_post_set(Evas_Object *o, void *(*cb)(void *data, void *pre_data, Evas_Object *o), const void *data); +EAPI void ewk_tiled_backing_store_process_entire_queue_set(Evas_Object *o, Eina_Bool value); +EAPI void ewk_tiled_backing_store_updates_process(Evas_Object *o); +EAPI void ewk_tiled_backing_store_updates_clear(Evas_Object *o); +EAPI void ewk_tiled_backing_store_contents_resize(Evas_Object *o, Evas_Coord width, Evas_Coord height); +EAPI void ewk_tiled_backing_store_disabled_update_set(Evas_Object *o, Eina_Bool value); +EAPI void ewk_tiled_backing_store_flush(Evas_Object *o); +EAPI void ewk_tiled_backing_store_enable_scale_set(Evas_Object *o, Eina_Bool value); + +EAPI Ewk_Tile_Unused_Cache *ewk_tiled_backing_store_tile_unused_cache_get(const Evas_Object *o); +EAPI void ewk_tiled_backing_store_tile_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *tuc); + +EAPI Eina_Bool ewk_tiled_backing_store_pre_render_region(Evas_Object *o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom); +EAPI Eina_Bool ewk_tiled_backing_store_pre_render_relative_radius(Evas_Object *o, unsigned int n, float zoom); +EAPI void ewk_tiled_backing_store_pre_render_cancel(Evas_Object *o); + +EAPI Eina_Bool ewk_tiled_backing_store_disable_render(Evas_Object *o); +EAPI Eina_Bool ewk_tiled_backing_store_enable_render(Evas_Object *o); +#ifdef __cplusplus +} +#endif +#endif // ewk_tiled_backing_store_h diff --git a/Source/WebKit/efl/ewk/ewk_tiled_matrix.c b/Source/WebKit/efl/ewk/ewk_tiled_matrix.c new file mode 100644 index 0000000..130a48a --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_matrix.c @@ -0,0 +1,771 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_tiled_matrix.h" + +#define _GNU_SOURCE +#include "ewk_tiled_backing_store.h" +#include "ewk_tiled_private.h" +#include <Eina.h> +#include <errno.h> +#include <inttypes.h> +#include <math.h> +#include <stdio.h> // XXX remove me later +#include <stdlib.h> +#include <string.h> + +static const Evas_Coord TILE_MATRIX_BASE_TILE_SIZE = 256; + +struct _Ewk_Tile_Matrix { + Eina_Matrixsparse *matrix; + Ewk_Tile_Unused_Cache *tuc; + Evas_Colorspace cspace; + struct { + void (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *update); + void *data; + } render; + unsigned int frozen; + Eina_List *updates; +#ifdef DEBUG_MEM_LEAKS + struct { + struct { + uint64_t allocated, freed; + } tiles, bytes; + } stats; +#endif +}; + +#ifdef DEBUG_MEM_LEAKS +static uint64_t tiles_leaked = 0; +static uint64_t bytes_leaked = 0; +#endif + +/* called when matrixsparse is resized or freed */ +static void _ewk_tile_matrix_cell_free(void *user_data, void *cell_data) +{ + Ewk_Tile_Matrix *tm = user_data; + Eina_Inlist *l = cell_data; + + if (!l) + return; + + ewk_tile_unused_cache_freeze(tm->tuc); + + while (l) { + Ewk_Tile *t = (Ewk_Tile *)l; + l = l->next; + + if (t->updates || t->stats.full_update) + tm->updates = eina_list_remove(tm->updates, t); + + if (t->visible) + ERR("freeing cell that is visible, leaking tile %p", t); + else { + if (!ewk_tile_unused_cache_tile_get(tm->tuc, t)) + ERR("tile %p was not in cache %p? leaking...", t, tm->tuc); + else { + DBG("tile cell does not exist anymore, free it %p", t); + +#ifdef DEBUG_MEM_LEAKS + tm->stats.bytes.freed += t->bytes; + tm->stats.tiles.freed++; +#endif + + ewk_tile_free(t); + } + } + } + + ewk_tile_unused_cache_thaw(tm->tuc); +} + +/* called when cache of unused tile is flushed */ +static void _ewk_tile_matrix_tile_free(void *data, Ewk_Tile *t) +{ + Ewk_Tile_Matrix *tm = data; + Eina_Matrixsparse_Cell *cell; + Eina_Inlist *l, *old; + + if (!eina_matrixsparse_cell_idx_get(tm->matrix, t->row, t->col, &cell)) { + ERR("removing tile %p that was not in the matrix? Leaking...", t); + return; + } + + if (t->updates || t->stats.full_update) + tm->updates = eina_list_remove(tm->updates, t); + + old = eina_matrixsparse_cell_data_get(cell); + l = eina_inlist_remove(old, EINA_INLIST_GET(t)); + if (!l) { + /* set to null to avoid double free */ + eina_matrixsparse_cell_data_replace(cell, NULL, NULL); + eina_matrixsparse_cell_clear(cell); + } else if (old != l) + eina_matrixsparse_cell_data_replace(cell, l, NULL); + + if (EINA_UNLIKELY(!!t->visible)) { + ERR("cache of unused tiles requesting deletion of used tile %p? " + "Leaking...", t); + return; + } + +#ifdef DEBUG_MEM_LEAKS + tm->stats.bytes.freed += t->bytes; + tm->stats.tiles.freed++; +#endif + + ewk_tile_free(t); +} + +/** + * Creates a new matrix of tiles. + * + * The tile matrix is responsible for keeping tiles around and + * providing fast access to them. One can use it to retrieve new or + * existing tiles and give them back, allowing them to be + * freed/replaced by the cache. + * + * @param tuc cache of unused tiles or @c NULL to create one + * automatically. + * @param cols number of columns in the matrix. + * @param rows number of rows in the matrix. + * @param cspace the color space used to create tiles in this matrix. + * @param render_cb function used to render given tile update. + * @param data context to give back to @a render_cb. + * + * @return newly allocated instance on success, @c NULL on failure. + */ +Ewk_Tile_Matrix *ewk_tile_matrix_new(Ewk_Tile_Unused_Cache *tuc, unsigned long cols, unsigned long rows, Evas_Colorspace cspace, void (*render_cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *update), const void *data) +{ + Ewk_Tile_Matrix *tm; + + CALLOC_OR_OOM_RET(tm, sizeof(Ewk_Tile_Matrix), NULL); + + tm->matrix = eina_matrixsparse_new(rows, cols, _ewk_tile_matrix_cell_free, tm); + if (!tm->matrix) { + ERR("could not create sparse matrix."); + free(tm); + return NULL; + } + + if (tuc) + tm->tuc = ewk_tile_unused_cache_ref(tuc); + else { + tm->tuc = ewk_tile_unused_cache_new(40960000); + if (!tm->tuc) { + ERR("no cache of unused tile!"); + eina_matrixsparse_free(tm->matrix); + free(tm); + return NULL; + } + } + + tm->cspace = cspace; + tm->render.cb = render_cb; + tm->render.data = (void *)data; + + return tm; +} + +/** + * Destroys tiles matrix, releasing its resources. + * + * The cache instance is unreferenced, possibly freeing it. + */ +void ewk_tile_matrix_free(Ewk_Tile_Matrix *tm) +{ +#ifdef DEBUG_MEM_LEAKS + uint64_t tiles, bytes; +#endif + + EINA_SAFETY_ON_NULL_RETURN(tm); + ewk_tile_unused_cache_freeze(tm->tuc); + + eina_matrixsparse_free(tm->matrix); + + ewk_tile_unused_cache_thaw(tm->tuc); + ewk_tile_unused_cache_unref(tm->tuc); + +#ifdef DEBUG_MEM_LEAKS + tiles = tm->stats.tiles.allocated - tm->stats.tiles.freed; + bytes = tm->stats.bytes.allocated - tm->stats.bytes.freed; + + tiles_leaked += tiles; + bytes_leaked += bytes; + + if (tiles || bytes) + ERR("tiled matrix leaked: tiles[+%"PRIu64",-%"PRIu64":%"PRIu64"] " + "bytes[+%"PRIu64",-%"PRIu64":%"PRIu64"]", + tm->stats.tiles.allocated, tm->stats.tiles.freed, tiles, + tm->stats.bytes.allocated, tm->stats.bytes.freed, bytes); + else if (tiles_leaked || bytes_leaked) + WRN("tiled matrix had no leaks: tiles[+%"PRIu64",-%"PRIu64"] " + "bytes[+%"PRIu64",-%"PRIu64"], but some other leaked " + "%"PRIu64" tiles (%"PRIu64" bytes)", + tm->stats.tiles.allocated, tm->stats.tiles.freed, + tm->stats.bytes.allocated, tm->stats.bytes.freed, + tiles_leaked, bytes_leaked); + else + INF("tiled matrix had no leaks: tiles[+%"PRIu64",-%"PRIu64"] " + "bytes[+%"PRIu64",-%"PRIu64"]", + tm->stats.tiles.allocated, tm->stats.tiles.freed, + tm->stats.bytes.allocated, tm->stats.bytes.freed); +#endif + + free(tm); +} + +/** + * Resize matrix to given number of rows and columns. + */ +void ewk_tile_matrix_resize(Ewk_Tile_Matrix *tm, unsigned long cols, unsigned long rows) +{ + EINA_SAFETY_ON_NULL_RETURN(tm); + eina_matrixsparse_size_set(tm->matrix, rows, cols); +} + +/** + * Get the cache of unused tiles in use by given matrix. + * + * No reference is taken to the cache. + */ +Ewk_Tile_Unused_Cache *ewk_tile_matrix_unused_cache_get(const Ewk_Tile_Matrix *tm) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, NULL); + return tm->tuc; +} + +/** + * Get the exact tile for the given position and zoom. + * + * If the tile was unused then it's removed from the cache. + * + * After usage, please give it back using + * ewk_tile_matrix_tile_put(). If you just want to check if it exists, + * then use ewk_tile_matrix_tile_exact_exists(). + * + * @param tm the tile matrix to get tile from. + * @param col the column number. + * @param row the row number. + * @param zoom the exact zoom to use. + * + * @return The tile instance or @c NULL if none is found. If the tile + * was in the unused cache it will be @b removed (thus + * considered used) and one should give it back with + * ewk_tile_matrix_tile_put() afterwards. + * + * @see ewk_tile_matrix_tile_nearest_get() + * @see ewk_tile_matrix_tile_exact_get() + */ +Ewk_Tile *ewk_tile_matrix_tile_exact_get(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom) +{ + Ewk_Tile *t, *item, *item_found = NULL; + Eina_Inlist *inl; + + t = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + if (!t) + return NULL; + + if (t->zoom == zoom) + goto end; + + EINA_INLIST_FOREACH(EINA_INLIST_GET(t), item) { + if (item->zoom != zoom) + continue; + item_found = item; + break; + } + + if (!item_found) + return NULL; + + inl = eina_inlist_promote(EINA_INLIST_GET(t), EINA_INLIST_GET(item_found)); + eina_matrixsparse_data_idx_replace(tm->matrix, row, col, inl, NULL); + + end: + if (!t->visible) { + if (!ewk_tile_unused_cache_tile_get(tm->tuc, t)) + WRN("Ewk_Tile was unused but not in cache? bug!"); + } + + return t; +} + +/** + * Checks if tile of given zoom exists in matrix. + * + * @param tm the tile matrix to check tile existence. + * @param col the column number. + * @param row the row number. + * @param zoom the exact zoom to query. + * + * @return @c EINA_TRUE if found, @c EINA_FALSE otherwise. + * + * @see ewk_tile_matrix_tile_exact_get() + */ +Eina_Bool ewk_tile_matrix_tile_exact_exists(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom) +{ + Ewk_Tile *t, *item; + + t = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + if (!t) + return EINA_FALSE; + + EINA_INLIST_FOREACH(EINA_INLIST_GET(t), item) { + if (item->zoom == zoom) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/** + * Get the nearest tile for given position and zoom. + * + * The nearest tile is the one at the given position but with the + * closest zoom, this being the division of the tile zoom by the + * desired zoom, the closest to 1.0 gets it. + * + * If the tile was unused then it's removed from the cache. + * + * After usage, please give it back using ewk_tile_matrix_tile_put(). + * + * @param tm the tile matrix to get tile from. + * @param col the column number. + * @param row the row number. + * @param zoom the exact zoom to use. + * + * @return The tile instance or @c NULL if none is found. If the tile + * was in the unused cache it will be @b removed (thus + * considered used) and one should give it back with + * ewk_tile_matrix_tile_put() afterwards. + */ +Ewk_Tile *ewk_tile_matrix_tile_nearest_get(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom) +{ + Ewk_Tile *t, *item, *item_found = NULL; + Eina_Inlist *inl; + float zoom_found = 0; + + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(zoom > 0.0, NULL); + + t = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + if (!t) + return NULL; + + if (t->zoom == zoom) { + item_found = t; + goto end; + } + + EINA_INLIST_FOREACH(EINA_INLIST_GET(t), item) { + float cur_zoom = item->zoom; + + if (cur_zoom == zoom) { + item_found = item; + break; + } + + if (cur_zoom > zoom) + cur_zoom = zoom / cur_zoom; + else + cur_zoom = cur_zoom / zoom; + + if (cur_zoom > zoom_found) { + item_found = item; + zoom_found = cur_zoom; + } + } + + if (!item_found) + return NULL; + + inl = eina_inlist_promote(EINA_INLIST_GET(t), EINA_INLIST_GET(item_found)); + eina_matrixsparse_data_idx_replace(tm->matrix, row, col, inl, NULL); + + end: + if (!item_found->visible) { + if (!ewk_tile_unused_cache_tile_get(tm->tuc, item_found)) + WRN("Ewk_Tile was unused but not in cache? bug!"); + } + + return item_found; +} + +/** + * Create a new tile at given position and zoom level in the matrix. + * + * The newly created tile is considered in use and not put into cache + * of unused tiles. After it is used one should call + * ewk_tile_matrix_tile_put() to give it back to matrix. + * + * @param tm the tile matrix to create tile on. + * @param col the column number. + * @param row the row number. + * @param zoom the level to create tile, used to determine tile size. + */ +Ewk_Tile *ewk_tile_matrix_tile_new(Ewk_Tile_Matrix *tm, Evas *evas, unsigned long col, unsigned int row, float zoom) +{ + Evas_Coord s; + Eina_Inlist *old; + Ewk_Tile *t; + + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, NULL); + EINA_SAFETY_ON_FALSE_RETURN_VAL(zoom > 0.0, NULL); + + s = TILE_SIZE_AT_ZOOM(TILE_MATRIX_BASE_TILE_SIZE, zoom); + zoom = (float)s / (float)TILE_MATRIX_BASE_TILE_SIZE; + + t = ewk_tile_new(evas, s, s, zoom, tm->cspace); + if (!t) { + ERR("could not create tile %dx%d at %f, cspace=%d", + s, s, (double)zoom, tm->cspace); + return NULL; + } + + old = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + old = eina_inlist_prepend(old, EINA_INLIST_GET(t)); + if (!eina_matrixsparse_data_idx_replace(tm->matrix, row, col, t, NULL)) { + ERR("could not set matrix cell, row/col outside matrix dimensions!"); + ewk_tile_free(t); + return NULL; + } + + t->col = col; + t->row = row; + t->x = col * s; + t->y = row * s; + + cairo_translate(t->cairo, -t->x, -t->y); + + t->stats.full_update = EINA_TRUE; + tm->updates = eina_list_append(tm->updates, t); + +#ifdef DEBUG_MEM_LEAKS + tm->stats.bytes.allocated += t->bytes; + tm->stats.tiles.allocated++; +#endif + + return t; +} + +/** + * Gives back the tile to the tile matrix. + * + * This will report the tile is no longer in use by the one that got + * it with ewk_tile_matrix_tile_nearest_get() or + * ewk_tile_matrix_tile_exact_get(). + * + * Any previous reference to tile should be released + * (ewk_tile_hide()) before calling this function, so it will + * be known if it is not visibile anymore and thus can be put into the + * unused cache. + * + * @param tm the tile matrix to return tile to. + * @param t the tile instance to return, must @b not be @c NULL. + * @param last_used time in which tile was last used. + * + * @return #EINA_TRUE on success or #EINA_FALSE on failure. + */ +Eina_Bool ewk_tile_matrix_tile_put(Ewk_Tile_Matrix *tm, Ewk_Tile *t, double last_used) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(t, EINA_FALSE); + + if (t->visible) + return EINA_TRUE; + + t->stats.last_used = last_used; + return ewk_tile_unused_cache_tile_put(tm->tuc, t, _ewk_tile_matrix_tile_free, tm); +} + +Eina_Bool ewk_tile_matrix_tile_update(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, const Eina_Rectangle *update) +{ + Ewk_Tile *l, *t; + Eina_Rectangle new_update; + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(update, EINA_FALSE); + + memcpy(&new_update, update, sizeof(new_update)); + // check update is valid, otherwise return EINA_FALSE + if (update->x < 0 || update->y < 0 || update->w <= 0 || update->h <= 0) { + ERR("invalid update region."); + return EINA_FALSE; + } + + if (update->x + update->w - 1 >= TILE_MATRIX_BASE_TILE_SIZE) + new_update.w = TILE_MATRIX_BASE_TILE_SIZE - update->x; + if (update->y + update->h - 1 >= TILE_MATRIX_BASE_TILE_SIZE) + new_update.h = TILE_MATRIX_BASE_TILE_SIZE - update->y; + + l = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + + if (!l) + return EINA_TRUE; + + EINA_INLIST_FOREACH(EINA_INLIST_GET(l), t) { + if (!t->updates && !t->stats.full_update) + tm->updates = eina_list_append(tm->updates, t); + new_update.x = roundf(t->zoom * new_update.x); + new_update.y = roundf(t->zoom * new_update.y); + new_update.w = roundf(t->zoom * new_update.w); + new_update.h = roundf(t->zoom * new_update.h); + ewk_tile_update_area(t, &new_update); + } + + return EINA_TRUE; +} + +Eina_Bool ewk_tile_matrix_tile_update_full(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row) +{ + Ewk_Tile *l, *t; + Eina_Matrixsparse_Cell *cell; + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, EINA_FALSE); + + if (!eina_matrixsparse_cell_idx_get(tm->matrix, row, col, &cell)) + return EINA_FALSE; + + if (!cell) + return EINA_TRUE; + + l = eina_matrixsparse_cell_data_get(cell); + if (!l) { + CRITICAL("matrix cell with no tile!"); + return EINA_TRUE; + } + + EINA_INLIST_FOREACH(EINA_INLIST_GET(l), t) { + if (!t->updates && !t->stats.full_update) + tm->updates = eina_list_append(tm->updates, t); + ewk_tile_update_full(t); + } + + return EINA_TRUE; +} + +void ewk_tile_matrix_tile_updates_clear(Ewk_Tile_Matrix *tm, Ewk_Tile *t) +{ + EINA_SAFETY_ON_NULL_RETURN(tm); + if (!t->updates && !t->stats.full_update) + return; + ewk_tile_updates_clear(t); + tm->updates = eina_list_remove(tm->updates, t); +} + +static Eina_Bool _ewk_tile_matrix_slicer_setup(Ewk_Tile_Matrix *tm, const Eina_Rectangle *area, float zoom, Eina_Tile_Grid_Slicer *slicer) +{ + unsigned long rows, cols; + Evas_Coord x, y, w, h, tw, th; + + if (area->w <= 0 || area->h <= 0) { + WRN("invalid area region: %d,%d+%dx%d.", + area->x, area->y, area->w, area->h); + return EINA_FALSE; + } + + x = area->x; + y = area->y; + w = area->w; + h = area->h; + + tw = TILE_SIZE_AT_ZOOM(TILE_W, zoom); + th = TILE_SIZE_AT_ZOOM(TILE_H, zoom); + + // cropping area region to fit matrix + eina_matrixsparse_size_get(tm->matrix, &rows, &cols); + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + + if (y + h - 1 > (long)(rows * th)) + h = rows * th - y; + if (x + w - 1 > (long)(cols * tw)) + w = cols * tw - x; + + return eina_tile_grid_slicer_setup(slicer, x, y, w, h, tw, th); +} + + +Eina_Bool ewk_tile_matrix_update(Ewk_Tile_Matrix *tm, const Eina_Rectangle *update, float zoom) +{ + const Eina_Tile_Grid_Info *info; + Eina_Tile_Grid_Slicer slicer; + EINA_SAFETY_ON_NULL_RETURN_VAL(tm, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(update, EINA_FALSE); + + if (update->w < 1 || update->h < 1) { + DBG("Why we get updates with empty areas? %d,%d+%dx%d at zoom %f", + update->x, update->y, update->w, update->h, zoom); + return EINA_TRUE; + } + + if (!_ewk_tile_matrix_slicer_setup(tm, update, zoom, &slicer)) { + ERR("Could not setup slicer for update %d,%d+%dx%d at zoom %f", + update->x, update->y, update->w, update->h, zoom); + return EINA_FALSE; + } + + while (eina_tile_grid_slicer_next(&slicer, &info)) { + unsigned long col, row; + Ewk_Tile *l, *t; + col = info->col; + row = info->row; + + l = eina_matrixsparse_data_idx_get(tm->matrix, row, col); + if (!l) + continue; + + EINA_INLIST_FOREACH(EINA_INLIST_GET(l), t) { + if (!t->updates && !t->stats.full_update) + tm->updates = eina_list_append(tm->updates, t); + if (info->full) + ewk_tile_update_full(t); + else { + if (t->zoom != zoom) + ewk_tile_update_full(t); + else + ewk_tile_update_area(t, &info->rect); + } + } + } + + + return EINA_TRUE; +} + +void ewk_tile_matrix_updates_process(Ewk_Tile_Matrix *tm) +{ + Eina_List *l, *l_next; + Ewk_Tile *t; + EINA_SAFETY_ON_NULL_RETURN(tm); + + // process updates, unflag tiles + EINA_LIST_FOREACH_SAFE(tm->updates, l, l_next, t) { + ewk_tile_updates_process(t, tm->render.cb, tm->render.data); + if (t->visible) { + ewk_tile_updates_clear(t); + tm->updates = eina_list_remove_list(tm->updates, l); + } + } +} + +void ewk_tile_matrix_updates_clear(Ewk_Tile_Matrix *tm) +{ + Ewk_Tile *t; + EINA_SAFETY_ON_NULL_RETURN(tm); + + EINA_LIST_FREE(tm->updates, t) + ewk_tile_updates_clear(t); + tm->updates = NULL; +} + +// remove me later! +void ewk_tile_matrix_dbg(const Ewk_Tile_Matrix *tm) +{ + Eina_Iterator *it = eina_matrixsparse_iterator_complete_new(tm->matrix); + Eina_Matrixsparse_Cell *cell; + Eina_Bool last_empty = EINA_FALSE; + +#ifdef DEBUG_MEM_LEAKS + printf("Ewk_Tile Matrix: tiles[+%"PRIu64",-%"PRIu64":%"PRIu64"] " + "bytes[+%"PRIu64",-%"PRIu64":%"PRIu64"]\n", + tm->stats.tiles.allocated, tm->stats.tiles.freed, + tm->stats.tiles.allocated - tm->stats.tiles.freed, + tm->stats.bytes.allocated, tm->stats.bytes.freed, + tm->stats.bytes.allocated - tm->stats.bytes.freed); +#else + printf("Ewk_Tile Matrix:\n"); +#endif + + EINA_ITERATOR_FOREACH(it, cell) { + unsigned long row, col; + Eina_Inlist *l; + eina_matrixsparse_cell_position_get(cell, &row, &col); + l = eina_matrixsparse_cell_data_get(cell); + + if (!l) { + if (!last_empty) { + last_empty = EINA_TRUE; + printf("Empty:"); + } + printf(" [%lu,%lu]", col, row); + } else { + if (last_empty) { + last_empty = EINA_FALSE; + printf("\n"); + } + Ewk_Tile *t; + + printf("%3lu,%3lu %10p:", col, row, l); + EINA_INLIST_FOREACH(l, t) + printf(" [%3lu,%3lu + %dx%d @ %0.3f]%c", + t->col, t->row, t->w, t->h, t->zoom, + t->visible ? '*': ' '); + printf("\n"); + } + } + if (last_empty) + printf("\n"); + eina_iterator_free(it); + + ewk_tile_unused_cache_dbg(tm->tuc); +} + +/** + * Freeze matrix to not do maintenance tasks. + * + * Maintenance tasks optimize usage, but maybe we know we should hold + * on them until we do the last operation, in this case we freeze + * while operating and then thaw when we're done. + * + * @see ewk_tile_matrix_thaw() + */ +void ewk_tile_matrix_freeze(Ewk_Tile_Matrix *tm) +{ + EINA_SAFETY_ON_NULL_RETURN(tm); + if (!tm->frozen) + ewk_tile_unused_cache_freeze(tm->tuc); + tm->frozen++; +} + +/** + * Unfreezes maintenance tasks. + * + * If this is the last counterpart of freeze, then maintenance tasks + * will run immediately. + */ +void ewk_tile_matrix_thaw(Ewk_Tile_Matrix *tm) +{ + EINA_SAFETY_ON_NULL_RETURN(tm); + if (!tm->frozen) { + ERR("thawing more than freezing!"); + return; + } + + tm->frozen--; + if (!tm->frozen) + ewk_tile_unused_cache_thaw(tm->tuc); +} diff --git a/Source/WebKit/efl/ewk/ewk_tiled_matrix.h b/Source/WebKit/efl/ewk/ewk_tiled_matrix.h new file mode 100644 index 0000000..07b8612 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_matrix.h @@ -0,0 +1,60 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_tiled_matrix_h +#define ewk_tiled_matrix_h + +#include "ewk_eapi.h" +#include "ewk_tiled_backing_store.h" + +#include <Evas.h> + +/* matrix of tiles */ +EAPI Ewk_Tile_Matrix *ewk_tile_matrix_new(Ewk_Tile_Unused_Cache *tuc, unsigned long cols, unsigned long rows, Evas_Colorspace cspace, void (*render_cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *update), const void *data); +EAPI void ewk_tile_matrix_free(Ewk_Tile_Matrix *tm); + +EAPI void ewk_tile_matrix_resize(Ewk_Tile_Matrix *tm, unsigned long cols, unsigned long rows); + +EAPI Ewk_Tile_Unused_Cache *ewk_tile_matrix_unused_cache_get(const Ewk_Tile_Matrix *tm); + +EAPI Ewk_Tile *ewk_tile_matrix_tile_exact_get(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom); +EAPI Eina_Bool ewk_tile_matrix_tile_exact_exists(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom); +EAPI Ewk_Tile *ewk_tile_matrix_tile_nearest_get(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, float zoom); +EAPI Ewk_Tile *ewk_tile_matrix_tile_new(Ewk_Tile_Matrix *tm, Evas *evas, unsigned long col, unsigned int row, float zoom); +EAPI Eina_Bool ewk_tile_matrix_tile_put(Ewk_Tile_Matrix *tm, Ewk_Tile *t, double last_used); + +EAPI Eina_Bool ewk_tile_matrix_tile_update(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row, const Eina_Rectangle *update); +EAPI Eina_Bool ewk_tile_matrix_tile_update_full(Ewk_Tile_Matrix *tm, unsigned long col, unsigned int row); +EAPI void ewk_tile_matrix_tile_updates_clear(Ewk_Tile_Matrix *tm, Ewk_Tile *t); + +EAPI Eina_Bool ewk_tile_matrix_update(Ewk_Tile_Matrix *tm, const Eina_Rectangle *update, float zoom); +EAPI void ewk_tile_matrix_updates_process(Ewk_Tile_Matrix *tm); +EAPI void ewk_tile_matrix_updates_clear(Ewk_Tile_Matrix *tm); +EAPI void ewk_tile_matrix_freeze(Ewk_Tile_Matrix *tm); +EAPI void ewk_tile_matrix_thaw(Ewk_Tile_Matrix *tm); + +// remove me! + void ewk_tile_matrix_dbg(const Ewk_Tile_Matrix *tm); + void ewk_tile_unused_cache_dbg(const Ewk_Tile_Unused_Cache *tuc); + void ewk_tile_accounting_dbg(void); + + +#endif // ewk_tiled_matrix_h + diff --git a/Source/WebKit/efl/ewk/ewk_tiled_model.c b/Source/WebKit/efl/ewk/ewk_tiled_model.c new file mode 100644 index 0000000..4b81a15 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_model.c @@ -0,0 +1,905 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_tiled_model.h" + +#define _GNU_SOURCE +#include "ewk_tiled_backing_store.h" +#include "ewk_tiled_private.h" +#include <Eina.h> +#include <eina_safety_checks.h> +#include <errno.h> +#include <inttypes.h> +#include <stdio.h> // XXX REMOVE ME LATER +#include <stdlib.h> +#include <string.h> + +#ifdef TILE_STATS_ACCOUNT_RENDER_TIME +#include <sys/time.h> +#endif + +#ifndef CAIRO_FORMAT_RGB16_565 +#define CAIRO_FORMAT_RGB16_565 4 +#endif + +#define IDX(col, row, rowspan) (col + (row * rowspan)) +#define MIN(a, b) ((a < b) ? a : b) +#define MAX(a, b) ((a > b) ? a : b) + +#ifdef DEBUG_MEM_LEAKS +static uint64_t tiles_allocated = 0; +static uint64_t tiles_freed = 0; +static uint64_t bytes_allocated = 0; +static uint64_t bytes_freed = 0; + +struct tile_account { + Evas_Coord size; + struct { + uint64_t allocated; + uint64_t freed; + } tiles, bytes; +}; + +static size_t accounting_len = 0; +static struct tile_account *accounting = NULL; + +static inline struct tile_account *_ewk_tile_account_get(const Ewk_Tile *t) +{ + struct tile_account *acc; + size_t i; + + for (i = 0; i < accounting_len; i++) { + if (accounting[i].size == t->w) + return accounting + i; + } + + i = (accounting_len + 1) * sizeof(struct tile_account); + REALLOC_OR_OOM_RET(accounting, i, NULL); + + acc = accounting + accounting_len; + acc->size = t->w; + acc->tiles.allocated = 0; + acc->tiles.freed = 0; + acc->bytes.allocated = 0; + acc->bytes.freed = 0; + + accounting_len++; + + return acc; +} + +static inline void _ewk_tile_account_allocated(const Ewk_Tile *t) +{ + struct tile_account *acc = _ewk_tile_account_get(t); + if (!acc) + return; + acc->bytes.allocated += t->bytes; + acc->tiles.allocated++; + + bytes_allocated += t->bytes; + tiles_allocated++; +} + +static inline void _ewk_tile_account_freed(const Ewk_Tile *t) +{ + struct tile_account *acc = _ewk_tile_account_get(t); + if (!acc) + return; + + acc->bytes.freed += t->bytes; + acc->tiles.freed++; + + bytes_freed += t->bytes; + tiles_freed++; +} + +void ewk_tile_accounting_dbg(void) +{ + struct tile_account *acc; + struct tile_account *acc_end; + + printf("TILE BALANCE: tiles[+%"PRIu64",-%"PRIu64":%"PRIu64"] " + "bytes[+%"PRIu64",-%"PRIu64":%"PRIu64"]\n", + tiles_allocated, tiles_freed, tiles_allocated - tiles_freed, + bytes_allocated, bytes_freed, bytes_allocated - bytes_freed); + + if (!accounting_len) + return; + + acc = accounting; + acc_end = acc + accounting_len; + printf("BEGIN: TILE BALANCE DETAILS (TO THIS MOMENT!):\n"); + for (; acc < acc_end; acc++) { + uint64_t tiles, bytes; + + tiles = acc->tiles.allocated - acc->tiles.freed; + bytes = acc->bytes.allocated - acc->bytes.freed; + + printf(" %4d: tiles[+%4"PRIu64",-%4"PRIu64":%4"PRIu64"] " + "bytes[+%8"PRIu64",-%8"PRIu64":%8"PRIu64"]%s\n", + acc->size, + acc->tiles.allocated, acc->tiles.freed, tiles, + acc->bytes.allocated, acc->bytes.freed, bytes, + (bytes || tiles) ? " POSSIBLE LEAK" : ""); + } + printf("END: TILE BALANCE DETAILS (TO THIS MOMENT!):\n"); +} +#else + +static inline void _ewk_tile_account_allocated(const Ewk_Tile *t) { } +static inline void _ewk_tile_account_freed(const Ewk_Tile *t) { } + +void ewk_tile_accounting_dbg(void) +{ + printf("compile webkit with DEBUG_MEM_LEAKS defined!\n"); +} +#endif + +static inline void _ewk_tile_paint_rgb888(Ewk_Tile *t, uint8_t r, uint8_t g, uint8_t b) +{ + uint32_t *dst32, *dst32_end, c1; + uint64_t *dst64, *dst64_end, c2; + + c1 = 0xff000000 | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b; + c2 = ((uint64_t)c1 << 32) | c1; + + dst64 = (uint64_t *)t->pixels; + dst64_end = dst64 + ((t->bytes / 8) & ~7); + for (; dst64 < dst64_end; dst64 += 8) { + /* TODO: ARM add pld or NEON instructions */ + dst64[0] = c2; + dst64[1] = c2; + dst64[2] = c2; + dst64[3] = c2; + dst64[4] = c2; + dst64[5] = c2; + dst64[6] = c2; + dst64[7] = c2; + } + + dst32 = (uint32_t *)dst64_end; + dst32_end = (uint32_t *)(t->pixels + t->bytes); + for (; dst32 < dst32_end; dst32++) + *dst32 = c1; +} + +static inline void _ewk_tile_paint_rgb565(Ewk_Tile *t, uint8_t r, uint8_t g, uint8_t b) +{ + uint16_t *dst16, *dst16_end, c1; + uint64_t *dst64, *dst64_end, c2; + + c1 = ((((r >> 3) & 0x1f) << 11) | + (((g >> 2) & 0x3f) << 5) | + ((b >> 3) & 0x1f)); + + c2 = (((uint64_t)c1 << 48) | ((uint64_t)c1 << 32) | + ((uint64_t)c1 << 16) | c1); + + dst64 = (uint64_t *)t->pixels; + dst64_end = dst64 + ((t->bytes / 8) & ~7); + for (; dst64 < dst64_end; dst64 += 8) { + /* TODO: ARM add pld or NEON instructions */ + dst64[0] = c2; + dst64[1] = c2; + dst64[2] = c2; + dst64[3] = c2; + dst64[4] = c2; + dst64[5] = c2; + dst64[6] = c2; + dst64[7] = c2; + } + + dst16 = (uint16_t *)dst16_end; + dst16_end = (uint16_t *)(t->pixels + t->bytes); + for (; dst16 < dst16_end; dst16++) + *dst16 = c1; +} + +static inline void _ewk_tile_paint(Ewk_Tile *t, uint8_t r, uint8_t g, uint8_t b) +{ + if (t->cspace == EVAS_COLORSPACE_ARGB8888) + _ewk_tile_paint_rgb888(t, r, g, b); + else if (t->cspace == EVAS_COLORSPACE_RGB565_A5P) + _ewk_tile_paint_rgb565(t, r, g, b); + else + ERR("unknown color space: %d", t->cspace); +} + +/** + * Create a new tile of given size, zoom level and colorspace. + * + * After created these properties are immutable as they're the basic + * characteristic of the tile and any change will lead to invalid + * memory access. + * + * Other members are of free-access and no getters/setters are + * provided in orderr to avoid expensive operations on those, however + * some are better manipulated with provided functions, such as + * ewk_tile_show() and ewk_tile_hide() to change + * @c visible or ewk_tile_update_full(), ewk_tile_update_area(), + * ewk_tile_updates_clear() to change @c stats.misses, + * @c stats.full_update and @c updates. + */ +Ewk_Tile *ewk_tile_new(Evas *evas, Evas_Coord w, Evas_Coord h, float zoom, Evas_Colorspace cspace) +{ + Eina_Inlist *l; + Evas_Coord *ec; + Evas_Colorspace *ecs; + float *f; + size_t *s; + Ewk_Tile *t; + unsigned int area; + size_t bytes; + cairo_format_t format; + cairo_status_t status; + int stride; + + area = w * h; + + if (cspace == EVAS_COLORSPACE_ARGB8888) { + bytes = area * 4; + stride = w * 4; + format = CAIRO_FORMAT_RGB24; + } else if (cspace == EVAS_COLORSPACE_RGB565_A5P) { + bytes = area * 2; + stride = w * 2; + format = CAIRO_FORMAT_RGB16_565; + } else { + ERR("unknown color space: %d", cspace); + return NULL; + } + + DBG("size: %dx%d (%d), zoom: %f, cspace=%d", + w, h, area, (double)zoom, cspace); + + MALLOC_OR_OOM_RET(t, sizeof(Ewk_Tile), NULL); + t->image = evas_object_image_add(evas); + + l = EINA_INLIST_GET(t); + l->prev = NULL; + l->next = NULL; + + t->visible = 0; + t->updates = NULL; + + memset(&t->stats, 0, sizeof(Ewk_Tile_Stats)); + t->stats.area = area; + + /* ugly, but let's avoid at all costs having users to modify those */ + ec = (Evas_Coord *)&t->w; + *ec = w; + + ec = (Evas_Coord *)&t->h; + *ec = h; + + ecs = (Evas_Colorspace *)&t->cspace; + *ecs = cspace; + + f = (float *)&t->zoom; + *f = zoom; + + s = (size_t *)&t->bytes; + *s = bytes; + + evas_object_image_size_set(t->image, t->w, t->h); + evas_object_image_colorspace_set(t->image, t->cspace); + t->pixels = evas_object_image_data_get(t->image, EINA_TRUE); + t->surface = cairo_image_surface_create_for_data + (t->pixels, format, w, h, stride); + status = cairo_surface_status(t->surface); + if (status != CAIRO_STATUS_SUCCESS) { + ERR("failed to create cairo surface: %s", + cairo_status_to_string(status)); + free(t); + return NULL; + } + + t->cairo = cairo_create(t->surface); + status = cairo_status(t->cairo); + if (status != CAIRO_STATUS_SUCCESS) { + ERR("failed to create cairo: %s", cairo_status_to_string(status)); + cairo_surface_destroy(t->surface); + evas_object_del(t->image); + free(t); + return NULL; + } + + _ewk_tile_account_allocated(t); + + return t; +} + +/** + * Free tile memory. + */ +void ewk_tile_free(Ewk_Tile *t) +{ + _ewk_tile_account_freed(t); + + if (t->updates) + eina_tiler_free(t->updates); + + cairo_surface_destroy(t->surface); + cairo_destroy(t->cairo); + evas_object_del(t->image); + free(t); +} + +/** + * Make the tile visible, incrementing its counter. + */ +void ewk_tile_show(Ewk_Tile *t) +{ + t->visible++; + evas_object_show(t->image); +} + +/** + * Decrement the visibility counter, making it invisible if necessary. + */ +void ewk_tile_hide(Ewk_Tile *t) +{ + t->visible--; + if (!t->visible) + evas_object_hide(t->image); +} + +/** + * Returns EINA_TRUE if the tile is visible, EINA_FALSE otherwise. + */ +Eina_Bool ewk_tile_visible_get(Ewk_Tile *t) +{ + return !!t->visible; +} + +/** + * Mark whole tile as dirty and requiring update. + */ +void ewk_tile_update_full(Ewk_Tile *t) +{ + /* TODO: list of tiles pending updates? */ + t->stats.misses++; + + if (!t->stats.full_update) { + t->stats.full_update = EINA_TRUE; + if (t->updates) { + eina_tiler_free(t->updates); + t->updates = NULL; + } + } +} + +/** + * Mark the specific subarea as dirty and requiring update. + */ +void ewk_tile_update_area(Ewk_Tile *t, const Eina_Rectangle *r) +{ + /* TODO: list of tiles pending updates? */ + t->stats.misses++; + + if (t->stats.full_update) + return; + + if (!r->x && !r->y && r->w == t->w && r->h == t->h) { + t->stats.full_update = EINA_TRUE; + if (t->updates) { + eina_tiler_free(t->updates); + t->updates = NULL; + } + return; + } + + if (!t->updates) { + t->updates = eina_tiler_new(t->w, t->h); + if (!t->updates) { + CRITICAL("could not create eina_tiler %dx%d.", t->w, t->h); + return; + } + } + + eina_tiler_rect_add(t->updates, r); +} + +/** + * For each updated region, call the given function. + * + * This will not change the tile statistics or clear the processed + * updates, use ewk_tile_updates_clear() for that. + */ +void ewk_tile_updates_process(Ewk_Tile *t, void (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *update), const void *data) +{ + if (t->stats.full_update) { + Eina_Rectangle r; + r.x = 0; + r.y = 0; + r.w = t->w; + r.h = t->h; +#ifdef TILE_STATS_ACCOUNT_RENDER_TIME + struct timeval timev; + double render_start; + gettimeofday(&timev, NULL); + render_start = (double)timev.tv_sec + + (((double)timev.tv_usec) / 1000000); +#endif + cb((void *)data, t, &r); +#ifdef TILE_STATS_ACCOUNT_RENDER_TIME + gettimeofday(&timev, NULL); + t->stats.render_time = (double)timev.tv_sec + + (((double)timev.tv_usec) / 1000000) - render_start; +#endif + } else if (t->updates) { + Eina_Iterator *itr = eina_tiler_iterator_new(t->updates); + Eina_Rectangle *r; + if (!itr) { + CRITICAL("could not create tiler iterator!"); + return; + } + EINA_ITERATOR_FOREACH(itr, r) + cb((void *)data, t, r); + eina_iterator_free(itr); + } +} + +/** + * Clear all updates in region, if any. + * + * This will change the tile statistics, specially zero stat.misses + * and unset stats.full_update. If t->updates existed, then it will be + * destroyed. + * + * This function is usually called after ewk_tile_updates_process() is + * called. + */ +void ewk_tile_updates_clear(Ewk_Tile *t) +{ + /* TODO: remove from list of pending updates? */ + t->stats.misses = 0; + + if (t->stats.full_update) + t->stats.full_update = 0; + else if (t->updates) { + eina_tiler_free(t->updates); + t->updates = NULL; + } +} + +typedef struct _Ewk_Tile_Unused_Cache_Entry Ewk_Tile_Unused_Cache_Entry; +struct _Ewk_Tile_Unused_Cache_Entry { + Ewk_Tile *tile; + int weight; + struct { + void (*cb)(void *data, Ewk_Tile *t); + void *data; + } tile_free; +}; + +struct _Ewk_Tile_Unused_Cache { + struct { + Eina_List *list; + size_t count; + size_t allocated; + } entries; + struct { + size_t max; /**< watermark (in bytes) to start freeing tiles */ + size_t used; /**< in bytes, maybe more than max. */ + } memory; + struct { + Evas_Coord x, y, w, h; + float zoom; + Eina_Bool locked; + } locked; + int references; + unsigned int frozen; + Eina_Bool dirty:1; +}; + +static const size_t TILE_UNUSED_CACHE_ALLOCATE_INITIAL = 128; +static const size_t TILE_UNUSED_CACHE_ALLOCATE_STEP = 16; +static const size_t TILE_UNUSED_CACHE_MAX_FREE = 32; + +/** + * Cache of unused tiles (those that are not visible). + * + * The cache of unused tiles. + * + * @param max cache size in bytes. + * + * @return newly allocated cache of unused tiles, use + * ewk_tile_unused_cache_free() to release resources. If not + * possible to allocate memory, @c NULL is returned. + */ +Ewk_Tile_Unused_Cache *ewk_tile_unused_cache_new(size_t max) +{ + Ewk_Tile_Unused_Cache *tuc; + + CALLOC_OR_OOM_RET(tuc, sizeof(Ewk_Tile_Unused_Cache), NULL); + + DBG("tuc=%p", tuc); + tuc->memory.max = max; + tuc->references = 1; + return tuc; +} + +void ewk_tile_unused_cache_lock_area(Ewk_Tile_Unused_Cache *tuc, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + + tuc->locked.locked = EINA_TRUE; + tuc->locked.x = x; + tuc->locked.y = y; + tuc->locked.w = w; + tuc->locked.h = h; + tuc->locked.zoom = zoom; +} + +void ewk_tile_unused_cache_unlock_area(Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + + tuc->locked.locked = EINA_FALSE; +} + +/** + * Free cache of unused tiles. + * + * Those tiles that are still visible will remain live. The unused + * tiles will be freed. + * + * @see ewk_tile_unused_cache_unref() + */ +void ewk_tile_unused_cache_free(Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + + DBG("tuc=%p, " + "entries=(count:%zd, allocated:%zd), " + "memory=(max:%zd, used:%zd)", + tuc, tuc->entries.count, tuc->entries.allocated, + tuc->memory.max, tuc->memory.used); + + ewk_tile_unused_cache_clear(tuc); + free(tuc); +} + +/** + * Clear cache of unused tiles. + * + * Any tiles that are in the cache are freed. The only tiles that are + * kept are those that aren't in the cache (i.e. that are visible). + */ +void ewk_tile_unused_cache_clear(Ewk_Tile_Unused_Cache *tuc) +{ + Ewk_Tile_Unused_Cache_Entry *itr; + EINA_SAFETY_ON_NULL_RETURN(tuc); + + if (!tuc->entries.count) + return; + + EINA_LIST_FREE(tuc->entries.list, itr) { + itr->tile_free.cb(itr->tile_free.data, itr->tile); + free(itr); + } + + tuc->memory.used = 0; + tuc->entries.count = 0; + tuc->dirty = EINA_FALSE; +} + +/** + * Hold reference to cache. + * + * @return same pointer as taken. + * + * @see ewk_tile_unused_cache_unref() + */ +Ewk_Tile_Unused_Cache *ewk_tile_unused_cache_ref(Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tuc, NULL); + tuc->references++; + return tuc; +} + +/** + * Release cache reference, freeing it if it drops to zero. + * + * @see ewk_tile_unused_cache_ref() + * @see ewk_tile_unused_cache_free() + */ +void ewk_tile_unused_cache_unref(Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + tuc->references--; + if (!tuc->references) + ewk_tile_unused_cache_free(tuc); +} + +/** + * Change cache capacity, in bytes. + * + * This will not flush cache, use ewk_tile_unused_cache_flush() or + * ewk_tile_unused_cache_auto_flush() to do so. + */ +void ewk_tile_unused_cache_max_set(Ewk_Tile_Unused_Cache *tuc, size_t max) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + tuc->memory.max = max; +} + +/** + * Retrieve maximum cache capacity, in bytes. + */ +size_t ewk_tile_unused_cache_max_get(const Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tuc, 0); + return tuc->memory.max; +} + +/** + * Retrieve the used cache capacity, in bytes. + */ +size_t ewk_tile_unused_cache_used_get(const Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(tuc, 0); + return tuc->memory.used; +} + +/** + * Flush given amount of bytes from cache. + * + * After calling this function, near @a bytes are freed from cache. It + * may be less if cache did not contain that amount of bytes (ie: an + * empty cache has nothing to free!) or more if the cache just + * contained objects that were larger than the requested amount (this + * is usually the case). + * + * @param tuc cache of unused tiles. + * @param bytes amount to free. + * + * @return amount really freed. + * + * @see ewk_tile_unused_cache_used_get() + */ +size_t ewk_tile_unused_cache_flush(Ewk_Tile_Unused_Cache *tuc, size_t bytes) +{ + Ewk_Tile_Unused_Cache_Entry *itr; + Eina_List *l, *l_next; + EINA_SAFETY_ON_NULL_RETURN_VAL(tuc, 0); + size_t done; + unsigned int count; + + if (!tuc->entries.count) + return 0; + if (bytes < 1) + return 0; + + /* + * NOTE: the cache is a FIFO queue currently. + * Don't need to sort any more. + */ + + if (tuc->dirty) + tuc->dirty = EINA_FALSE; + + done = 0; + count = 0; + EINA_LIST_FOREACH_SAFE(tuc->entries.list, l, l_next, itr) { + Ewk_Tile *t = itr->tile; + if (done > bytes) + break; + if (tuc->locked.locked + && t->x + t->w > tuc->locked.x + && t->y + t->h > tuc->locked.y + && t->x < tuc->locked.x + tuc->locked.w + && t->y < tuc->locked.y + tuc->locked.h + && t->zoom == tuc->locked.zoom) { + continue; + } + done += sizeof(Ewk_Tile) + itr->tile->bytes; + itr->tile_free.cb(itr->tile_free.data, itr->tile); + tuc->entries.list = eina_list_remove_list(tuc->entries.list, l); + free(itr); + count++; + } + + tuc->memory.used -= done; + tuc->entries.count -= count; + + return done; +} + +/** + * Flush enough bytes to make cache usage lower than maximum. + * + * Just like ewk_tile_unused_cache_flush(), but this will make the cache + * free enough tiles to respect maximum cache size as defined with + * ewk_tile_unused_cache_max_set(). + * + * This function is usually called when system becomes idle. This way + * we keep memory low but do not impact performance when + * creating/deleting tiles. + */ +void ewk_tile_unused_cache_auto_flush(Ewk_Tile_Unused_Cache *tuc) +{ + EINA_SAFETY_ON_NULL_RETURN(tuc); + if (tuc->memory.used <= tuc->memory.max) + return; + ewk_tile_unused_cache_flush(tuc, tuc->memory.used - tuc->memory.max); + if (tuc->memory.used > tuc->memory.max) + CRITICAL("Cache still using too much memory: %zd KB; max: %zd KB", + tuc->memory.used, tuc->memory.max); +} + +/** + * Flag cache as dirty. + * + * If cache is dirty then next flush operations will have to recompute + * weight and sort again to find the best tiles to expire. + * + * One must call this function when tile properties that may change + * likeness of tile to be flushed change, like Tile::stats. + */ +void ewk_tile_unused_cache_dirty(Ewk_Tile_Unused_Cache *tuc) +{ + tuc->dirty = EINA_TRUE; +} + +/** + * Freeze cache to not do maintenance tasks. + * + * Maintenance tasks optimize cache usage, but maybe we know we should + * hold on them until we do the last operation, in this case we freeze + * while operating and then thaw when we're done. + * + * @see ewk_tile_unused_cache_thaw() + */ +void ewk_tile_unused_cache_freeze(Ewk_Tile_Unused_Cache *tuc) +{ + tuc->frozen++; +} + +/** + * Unfreezes maintenance tasks. + * + * If this is the last counterpart of freeze, then maintenance tasks + * will run immediately. + */ +void ewk_tile_unused_cache_thaw(Ewk_Tile_Unused_Cache *tuc) +{ + if (!tuc->frozen) { + ERR("thawing more than freezing!"); + return; + } + + tuc->frozen--; +} + +/** + * Get tile from cache of unused tiles, removing it from the cache. + * + * If the tile is used, then it's not in cache of unused tiles, so it + * is removed from the cache and may be given back with + * ewk_tile_unused_cache_tile_put(). + * + * @param tuc cache of unused tiles + * @param t the tile to be removed from Ewk_Tile_Unused_Cache. + * + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. + */ +Eina_Bool ewk_tile_unused_cache_tile_get(Ewk_Tile_Unused_Cache *tuc, Ewk_Tile *t) +{ + Ewk_Tile_Unused_Cache_Entry *entry; + Eina_List *e, *l; + + e = NULL; + EINA_LIST_FOREACH(tuc->entries.list, l, entry) + { + if (entry->tile == t) { + e = l; + break; + } + } + if (!e) { + ERR("tile %p not found in cache %p", t, tuc); + return EINA_FALSE; + } + + tuc->entries.count--; + tuc->memory.used -= sizeof(Ewk_Tile) + t->bytes; + tuc->entries.list = eina_list_remove_list(tuc->entries.list, e); + free(entry); + // TODO assume dirty for now, but may it's not, + // if the item was at the beginning of the queue + tuc->dirty = EINA_TRUE; + + return EINA_TRUE; +} + +/** + * Put tile into cache of unused tiles, adding it to the cache. + * + * This should be called when @c t->visible is @c 0 and no objects are + * using the tile anymore, making it available to be expired and have + * its memory replaced. + * + * Note that tiles are not automatically deleted if cache is full, + * instead the cache will have more bytes used than maximum and one + * can call ewk_tile_unused_cache_auto_flush() to free them. This is done + * because usually we want a lazy operation for better performance. + * + * @param tuc cache of unused tiles + * @param t tile to be added to cache. + * @param tile_free_cb function used to free tiles. + * @param data context to give back to @a tile_free_cb as first argument. + * + * @return #EINA_TRUE on success, #EINA_FALSE otherwise. If @c t->visible + * is not #EINA_FALSE, then it will return #EINA_FALSE. + * + * @see ewk_tile_unused_cache_auto_flush() + */ +Eina_Bool ewk_tile_unused_cache_tile_put(Ewk_Tile_Unused_Cache *tuc, Ewk_Tile *t, void (*tile_free_cb)(void *data, Ewk_Tile *t), const void *data) +{ + Ewk_Tile_Unused_Cache_Entry *e; + + if (t->visible) { + ERR("tile=%p is not unused (visible=%d)", t, t->visible); + return EINA_FALSE; + } + + MALLOC_OR_OOM_RET(e, sizeof(Ewk_Tile_Unused_Cache_Entry), EINA_FALSE); + tuc->entries.list = eina_list_append(tuc->entries.list, e); + if (eina_error_get()) { + ERR("List allocation failed"); + return EINA_FALSE; + } + + e->tile = t; + e->weight = 0; /* calculated just before sort */ + e->tile_free.cb = tile_free_cb; + e->tile_free.data = (void *)data; + + tuc->entries.count++; + tuc->memory.used += sizeof(Ewk_Tile) + t->bytes; + tuc->dirty = EINA_TRUE; + + return EINA_TRUE; +} + +void ewk_tile_unused_cache_dbg(const Ewk_Tile_Unused_Cache *tuc) +{ + Ewk_Tile_Unused_Cache_Entry *itr; + Eina_List *l; + int count = 0; + printf("Cache of unused tiles: entries: %zu/%zu, memory: %zu/%zu\n", + tuc->entries.count, tuc->entries.allocated, + tuc->memory.used, tuc->memory.max); + + EINA_LIST_FOREACH(tuc->entries.list, l, itr) { + const Ewk_Tile *t = itr->tile; + printf(" [%3lu,%3lu + %dx%d @ %0.3f]%c", + t->col, t->row, t->w, t->h, t->zoom, + t->visible ? '*': ' '); + + if (!(count % 4)) + printf("\n"); + } + + printf("\n"); +} diff --git a/Source/WebKit/efl/ewk/ewk_tiled_model.h b/Source/WebKit/efl/ewk/ewk_tiled_model.h new file mode 100644 index 0000000..a546cee --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_model.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_tiled_model_h +#define ewk_tiled_model_h + +#include "ewk_eapi.h" +#include "ewk_tiled_backing_store.h" + +#include <Evas.h> + +/* model */ +EAPI Ewk_Tile *ewk_tile_new(Evas *evas, Evas_Coord w, Evas_Coord h, float zoom, Evas_Colorspace cspace); +EAPI void ewk_tile_free(Ewk_Tile *t); +EAPI void ewk_tile_unused_cache_clear(Ewk_Tile_Unused_Cache *tuc); +EAPI void ewk_tile_show(Ewk_Tile *t); +EAPI void ewk_tile_hide(Ewk_Tile *t); +Eina_Bool ewk_tile_visible_get(Ewk_Tile *t); +EAPI void ewk_tile_update_full(Ewk_Tile *t); +EAPI void ewk_tile_update_area(Ewk_Tile *t, const Eina_Rectangle *r); +EAPI void ewk_tile_updates_process(Ewk_Tile *t, void (*cb)(void *data, Ewk_Tile *t, const Eina_Rectangle *update), const void *data); +EAPI void ewk_tile_updates_clear(Ewk_Tile *t); + +/* cache of unused tiles */ +EAPI Ewk_Tile_Unused_Cache *ewk_tile_unused_cache_new(size_t max); +EAPI void ewk_tile_unused_cache_lock_area(Ewk_Tile_Unused_Cache *tuc, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom); +EAPI void ewk_tile_unused_cache_unlock_area(Ewk_Tile_Unused_Cache *tuc); +EAPI void ewk_tile_unused_cache_free(Ewk_Tile_Unused_Cache *tuc); +EAPI Ewk_Tile_Unused_Cache *ewk_tile_unused_cache_ref(Ewk_Tile_Unused_Cache *tuc); +EAPI void ewk_tile_unused_cache_unref(Ewk_Tile_Unused_Cache *tuc); + +EAPI void ewk_tile_unused_cache_dirty(Ewk_Tile_Unused_Cache *tuc); + +EAPI void ewk_tile_unused_cache_freeze(Ewk_Tile_Unused_Cache *tuc); +EAPI void ewk_tile_unused_cache_thaw(Ewk_Tile_Unused_Cache *tuc); + +EAPI Eina_Bool ewk_tile_unused_cache_tile_get(Ewk_Tile_Unused_Cache *tuc, Ewk_Tile *t); +EAPI Eina_Bool ewk_tile_unused_cache_tile_put(Ewk_Tile_Unused_Cache *tuc, Ewk_Tile *t, void (*tile_free_cb)(void *data, Ewk_Tile *t), const void *data); + +#endif // ewk_tiled_model_h + diff --git a/Source/WebKit/efl/ewk/ewk_tiled_private.h b/Source/WebKit/efl/ewk/ewk_tiled_private.h new file mode 100644 index 0000000..ce65f43 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_tiled_private.h @@ -0,0 +1,62 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_tiled_private_h +#define ewk_tiled_private_h + +/* logging */ +extern int _ewk_tiled_log_dom; + +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_ewk_tiled_log_dom, __VA_ARGS__) +#define ERR(...) EINA_LOG_DOM_ERR(_ewk_tiled_log_dom, __VA_ARGS__) +#define WRN(...) EINA_LOG_DOM_WARN(_ewk_tiled_log_dom, __VA_ARGS__) +#define INF(...) EINA_LOG_DOM_INFO(_ewk_tiled_log_dom, __VA_ARGS__) +#define DBG(...) EINA_LOG_DOM_DBG(_ewk_tiled_log_dom, __VA_ARGS__) +#define OOM(op, size) CRITICAL("could not %s %zd bytes: %s", op, size, strerror(errno)) +#define MALLOC_OR_OOM_RET(ptr, size, ...) \ + do { \ + ptr = malloc(size); \ + if (!ptr && (size) > 0) { \ + OOM("malloc", (size)); \ + return __VA_ARGS__; \ + } \ + } while (0) + +#define CALLOC_OR_OOM_RET(ptr, size, ...) \ + do { \ + ptr = calloc(1, size); \ + if (!ptr && (size) > 0) { \ + OOM("calloc", (size)); \ + return __VA_ARGS__; \ + } \ + } while (0) + +#define REALLOC_OR_OOM_RET(ptr, size, ...) \ + do { \ + void *__tmp_ptr; \ + __tmp_ptr = realloc(ptr, size); \ + if (!__tmp_ptr && (size) > 0) { \ + OOM("realloc", (size)); \ + return __VA_ARGS__; \ + } \ + ptr = __tmp_ptr; \ + } while (0) + +#endif // ewk_tiled_private_h diff --git a/Source/WebKit/efl/ewk/ewk_util.cpp b/Source/WebKit/efl/ewk/ewk_util.cpp new file mode 100644 index 0000000..6830f76 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_util.cpp @@ -0,0 +1,98 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_util.h" + +#include "ewk_private.h" +#include <eina_safety_checks.h> + +Evas_Object* ewk_util_image_from_cairo_surface_add(Evas* canvas, cairo_surface_t* surface) +{ + cairo_status_t status; + cairo_surface_type_t type; + cairo_format_t format; + int w, h, stride; + Evas_Object* image; + const void* src; + void* dst; + + EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface, 0); + + status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) { + ERR("cairo surface is invalid: %s", cairo_status_to_string(status)); + return 0; + } + + type = cairo_surface_get_type(surface); + if (type != CAIRO_SURFACE_TYPE_IMAGE) { + ERR("unknown surface type %d, required %d (CAIRO_SURFACE_TYPE_IMAGE).", + type, CAIRO_SURFACE_TYPE_IMAGE); + return 0; + } + + format = cairo_image_surface_get_format(surface); + if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24) { + ERR("unknown surface format %d, expected %d or %d.", + format, CAIRO_FORMAT_ARGB32, CAIRO_FORMAT_RGB24); + return 0; + } + + w = cairo_image_surface_get_width(surface); + h = cairo_image_surface_get_height(surface); + stride = cairo_image_surface_get_stride(surface); + if (w <= 0 || h <= 0 || stride <= 0) { + ERR("invalid image size %dx%d, stride=%d", w, h, stride); + return 0; + } + + src = cairo_image_surface_get_data(surface); + if (!src) { + ERR("could not get source data."); + return 0; + } + + image = evas_object_image_filled_add(canvas); + if (!image) { + ERR("could not add image to canvas."); + return 0; + } + + evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888); + evas_object_image_size_set(image, w, h); + evas_object_image_alpha_set(image, format == CAIRO_FORMAT_ARGB32); + + if (evas_object_image_stride_get(image) != stride) { + ERR("evas' stride %d diverges from cairo's %d.", + evas_object_image_stride_get(image), stride); + evas_object_del(image); + return 0; + } + + dst = evas_object_image_data_get(image, EINA_TRUE); + memcpy(dst, src, h * stride); + evas_object_image_data_set(image, dst); + + evas_object_resize(image, w, h); // helpful but not really required + + return image; +} diff --git a/Source/WebKit/efl/ewk/ewk_util.h b/Source/WebKit/efl/ewk/ewk_util.h new file mode 100644 index 0000000..d9c8f9c --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_util.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_util_h +#define ewk_util_h + +#include <Evas.h> +#include <cairo.h> + +Evas_Object* ewk_util_image_from_cairo_surface_add(Evas* canvas, cairo_surface_t* surface); + +#endif // ewk_util_h diff --git a/Source/WebKit/efl/ewk/ewk_view.cpp b/Source/WebKit/efl/ewk/ewk_view.cpp new file mode 100644 index 0000000..ce09f64 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_view.cpp @@ -0,0 +1,4519 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#define __STDC_FORMAT_MACROS +#include "config.h" +#include "ewk_view.h" + +#include "BackForwardListImpl.h" +#include "Chrome.h" +#include "ChromeClientEfl.h" +#include "ContextMenuController.h" +#include "DocumentLoader.h" +#include "DragClientEfl.h" +#include "EWebKit.h" +#include "EditorClientEfl.h" +#include "EventHandler.h" +#include "FocusController.h" +#include "FrameLoaderClientEfl.h" +#include "FrameView.h" +#include "GraphicsContext.h" +#include "HTMLElement.h" +#include "HTMLInputElement.h" +#include "HTMLNames.h" +#include "InspectorClientEfl.h" +#include "IntSize.h" +#include "PlatformMouseEvent.h" +#include "PopupMenuClient.h" +#include "ProgressTracker.h" +#include "appcache/ApplicationCacheStorage.h" +#include "ewk_private.h" + +#include <Ecore.h> +#include <Eina.h> +#include <Evas.h> +#include <eina_safety_checks.h> +#include <inttypes.h> +#include <sys/time.h> + +#ifdef HAVE_ECORE_X +#include <Ecore_X.h> +#endif + +#define ZOOM_MIN (0.05) +#define ZOOM_MAX (4.0) + +#define DEVICE_PIXEL_RATIO (1.0) + +static const char EWK_VIEW_TYPE_STR[] = "EWK_View"; + +static const size_t EWK_VIEW_REPAINTS_SIZE_INITIAL = 32; +static const size_t EWK_VIEW_REPAINTS_SIZE_STEP = 8; +static const size_t EWK_VIEW_REPAINTS_SIZE_MAX_FREE = 64; + +static const size_t EWK_VIEW_SCROLLS_SIZE_INITIAL = 8; +static const size_t EWK_VIEW_SCROLLS_SIZE_STEP = 2; +static const size_t EWK_VIEW_SCROLLS_SIZE_MAX_FREE = 32; + +struct _Ewk_View_Private_Data { + WebCore::Page* page; + WebCore::Settings* page_settings; + WebCore::Frame* main_frame; + WebCore::ViewportArguments viewport_arguments; + Ewk_History* history; + struct { + Ewk_Menu menu; + WebCore::PopupMenuClient* menu_client; + } popup; + struct { + Eina_Rectangle* array; + size_t count; + size_t allocated; + } repaints; + struct { + Ewk_Scroll_Request* array; + size_t count; + size_t allocated; + } scrolls; + unsigned int imh; /**< input method hints */ + struct { + Eina_Bool view_cleared:1; + } flags; + struct { + const char* user_agent; + const char* user_stylesheet; + const char* encoding_default; + const char* encoding_custom; + const char* cache_directory; + const char* theme; + const char* local_storage_database_path; + int font_minimum_size; + int font_minimum_logical_size; + int font_default_size; + int font_monospace_size; + const char* font_standard; + const char* font_cursive; + const char* font_monospace; + const char* font_fantasy; + const char* font_serif; + const char* font_sans_serif; + Eina_Bool auto_load_images:1; + Eina_Bool auto_shrink_images:1; + Eina_Bool enable_auto_resize_window:1; + Eina_Bool enable_scripts:1; + Eina_Bool enable_plugins:1; + Eina_Bool enable_frame_flattening:1; + Eina_Bool encoding_detector:1; + Eina_Bool scripts_window_open:1; + Eina_Bool resizable_textareas:1; + Eina_Bool private_browsing:1; + Eina_Bool caret_browsing:1; + Eina_Bool spatial_navigation:1; + Eina_Bool local_storage:1; + Eina_Bool offline_app_cache: 1; + Eina_Bool page_cache: 1; + struct { + float min_scale; + float max_scale; + Eina_Bool user_scalable:1; + } zoom_range; + float device_pixel_ratio; + } settings; + struct { + struct { + double start; + double end; + double duration; + } time; + struct { + float start; + float end; + float range; + } zoom; + struct { + Evas_Coord x, y; + } center; + Ecore_Animator* animator; + } animated_zoom; + struct { + Evas_Coord w, h; + Eina_Bool use:1; + } fixed_layout; +}; + +#ifndef EWK_TYPE_CHECK +#define EWK_VIEW_TYPE_CHECK(o, ...) do { } while (0) +#else +#define EWK_VIEW_TYPE_CHECK(o, ...) \ + do { \ + const char* _tmp_otype = evas_object_type_get(o); \ + const Evas_Smart* _tmp_s = evas_object_smart_smart_get(o); \ + if (EINA_UNLIKELY(!_tmp_s)) { \ + EINA_LOG_CRIT \ + ("%p (%s) is not a smart object!", o, \ + _tmp_otype ? _tmp_otype : "(null)"); \ + return __VA_ARGS__; \ + } \ + const Evas_Smart_Class* _tmp_sc = evas_smart_class_get(_tmp_s); \ + if (EINA_UNLIKELY(!_tmp_sc)) { \ + EINA_LOG_CRIT \ + ("%p (%s) is not a smart object!", o, \ + _tmp_otype ? _tmp_otype : "(null)"); \ + return __VA_ARGS__; \ + } \ + if (EINA_UNLIKELY(_tmp_sc->data != EWK_VIEW_TYPE_STR)) { \ + EINA_LOG_CRIT \ + ("%p (%s) is not of an ewk_view (need %p, got %p)!", \ + o, _tmp_otype ? _tmp_otype : "(null)", \ + EWK_VIEW_TYPE_STR, _tmp_sc->data); \ + return __VA_ARGS__; \ + } \ + } while (0) +#endif + +#define EWK_VIEW_SD_GET(o, ptr) \ + Ewk_View_Smart_Data* ptr = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o) + +#define EWK_VIEW_SD_GET_OR_RETURN(o, ptr, ...) \ + EWK_VIEW_TYPE_CHECK(o, __VA_ARGS__); \ + EWK_VIEW_SD_GET(o, ptr); \ + if (!ptr) { \ + CRITICAL("no smart data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return __VA_ARGS__; \ + } + +#define EWK_VIEW_PRIV_GET(sd, ptr) \ + Ewk_View_Private_Data* ptr = sd->_priv + +#define EWK_VIEW_PRIV_GET_OR_RETURN(sd, ptr, ...) \ + EWK_VIEW_PRIV_GET(sd, ptr); \ + if (!ptr) { \ + CRITICAL("no private data for object %p (%s)", \ + sd->self, evas_object_type_get(sd->self)); \ + return __VA_ARGS__; \ + } + +static void _ewk_view_smart_changed(Ewk_View_Smart_Data* sd) +{ + if (sd->changed.any) + return; + sd->changed.any = EINA_TRUE; + evas_object_smart_changed(sd->self); +} + +static Eina_Bool _ewk_view_repaints_resize(Ewk_View_Private_Data* priv, size_t size) +{ + void* tmp = realloc(priv->repaints.array, size * sizeof(Eina_Rectangle)); + if (!tmp) { + CRITICAL("could not realloc repaints array to %zu elements.", size); + return EINA_FALSE; + } + priv->repaints.allocated = size; + priv->repaints.array = (Eina_Rectangle*)tmp; + return EINA_TRUE; +} + +static void _ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + Eina_Rectangle* r; + + // fprintf(stderr, ">>> repaint requested: %d,%d+%dx%d\n", x, y, w, h); + if (priv->repaints.allocated == priv->repaints.count) { + size_t size; + if (!priv->repaints.allocated) + size = EWK_VIEW_REPAINTS_SIZE_INITIAL; + else + size = priv->repaints.allocated + EWK_VIEW_REPAINTS_SIZE_STEP; + if (!_ewk_view_repaints_resize(priv, size)) + return; + } + + r = priv->repaints.array + priv->repaints.count; + priv->repaints.count++; + + r->x = x; + r->y = y; + r->w = w; + r->h = h; + + DBG("add repaint %d,%d+%dx%d", x, y, w, h); +} + +static void _ewk_view_repaints_flush(Ewk_View_Private_Data* priv) +{ + priv->repaints.count = 0; + if (priv->repaints.allocated <= EWK_VIEW_REPAINTS_SIZE_MAX_FREE) + return; + _ewk_view_repaints_resize(priv, EWK_VIEW_REPAINTS_SIZE_MAX_FREE); +} + +static Eina_Bool _ewk_view_scrolls_resize(Ewk_View_Private_Data* priv, size_t size) +{ + void* tmp = realloc(priv->scrolls.array, size * sizeof(Ewk_Scroll_Request)); + if (!tmp) { + CRITICAL("could not realloc scrolls array to %zu elements.", size); + return EINA_FALSE; + } + priv->scrolls.allocated = size; + priv->scrolls.array = (Ewk_Scroll_Request*)tmp; + return EINA_TRUE; +} + +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) +{ + Ewk_Scroll_Request* r; + Ewk_Scroll_Request* r_end; + Evas_Coord x2 = x + w, y2 = y + h; + + r = priv->scrolls.array; + r_end = r + priv->scrolls.count; + for (; r < r_end; r++) { + if (r->x == x && r->y == y && r->w == w && r->h == h) { + DBG("region already scrolled %d,%d+%dx%d %+03d,%+03d add " + "%+03d,%+03d", + r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy); + r->dx += dx; + r->dy += dy; + return; + } + if ((x <= r->x && x2 >= r->x2) && (y <= r->y && y2 >= r->y2)) { + DBG("old viewport (%d,%d+%dx%d %+03d,%+03d) was scrolled itself, " + "add %+03d,%+03d", + r->x, r->y, r->w, r->h, r->dx, r->dy, dx, dy); + r->x += dx; + r->y += dy; + } + } + + if (priv->scrolls.allocated == priv->scrolls.count) { + size_t size; + if (!priv->scrolls.allocated) + size = EWK_VIEW_SCROLLS_SIZE_INITIAL; + else + size = priv->scrolls.allocated + EWK_VIEW_SCROLLS_SIZE_STEP; + if (!_ewk_view_scrolls_resize(priv, size)) + return; + } + + r = priv->scrolls.array + priv->scrolls.count; + priv->scrolls.count++; + + r->x = x; + r->y = y; + r->w = w; + r->h = h; + r->x2 = x2; + r->y2 = y2; + r->dx = dx; + r->dy = dy; + r->main_scroll = main_scroll; + DBG("add scroll in region: %d,%d+%dx%d %+03d,%+03d", x, y, w, h, dx, dy); + + Eina_Rectangle* pr; + Eina_Rectangle* pr_end; + size_t count; + pr = priv->repaints.array; + count = priv->repaints.count; + pr_end = pr + count; + for (; pr < pr_end; pr++) { + pr->x += dx; + pr->y += dy; + } +} + +static void _ewk_view_scrolls_flush(Ewk_View_Private_Data* priv) +{ + priv->scrolls.count = 0; + if (priv->scrolls.allocated <= EWK_VIEW_SCROLLS_SIZE_MAX_FREE) + return; + _ewk_view_scrolls_resize(priv, EWK_VIEW_SCROLLS_SIZE_MAX_FREE); +} + +// Default Event Handling ////////////////////////////////////////////// +static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* sd) +{ + EWK_VIEW_PRIV_GET(sd, priv); + WebCore::FocusController* fc = priv->page->focusController(); + DBG("o=%p, fc=%p", sd->self, fc); + EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE); + + fc->setActive(true); + fc->setFocused(true); + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* sd) +{ + EWK_VIEW_PRIV_GET(sd, priv); + WebCore::FocusController* fc = priv->page->focusController(); + DBG("o=%p, fc=%p", sd->self, fc); + EINA_SAFETY_ON_NULL_RETURN_VAL(fc, EINA_FALSE); + + fc->setActive(false); + fc->setFocused(false); + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Wheel* ev) +{ + return ewk_frame_feed_mouse_wheel(sd->main_frame, ev); +} + +static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Down* ev) +{ + return ewk_frame_feed_mouse_down(sd->main_frame, ev); +} + +static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Up* ev) +{ + return ewk_frame_feed_mouse_up(sd->main_frame, ev); +} + +static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* sd, const Evas_Event_Mouse_Move* ev) +{ + return ewk_frame_feed_mouse_move(sd->main_frame, ev); +} + +static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Down* ev) +{ + Evas_Object* frame = ewk_view_frame_focused_get(sd->self); + + if (!frame) + frame = sd->main_frame; + + return ewk_frame_feed_key_down(frame, ev); +} + +static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* sd, const Evas_Event_Key_Up* ev) +{ + Evas_Object* frame = ewk_view_frame_focused_get(sd->self); + + if (!frame) + frame = sd->main_frame; + + return ewk_frame_feed_key_up(frame, ev); +} + +static void _ewk_view_smart_add_console_message(Ewk_View_Smart_Data* sd, const char* message, unsigned int lineNumber, const char* sourceID) +{ + INF("console message: %s @%d: %s\n", sourceID, lineNumber, message); +} + +static void _ewk_view_smart_run_javascript_alert(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message) +{ + INF("javascript alert: %s\n", message); +} + +static Eina_Bool _ewk_view_smart_run_javascript_confirm(Ewk_View_Smart_Data* sd, Evas_Object* frame, const char* message) +{ + INF("javascript confirm: %s", message); + INF("javascript confirm (HARD CODED)? YES"); + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_smart_should_interrupt_javascript(Ewk_View_Smart_Data* sd) +{ + INF("should interrupt javascript?\n" + "\t(HARD CODED) NO"); + return EINA_FALSE; +} + +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) +{ + *value = strdup("test"); + Eina_Bool ret = EINA_TRUE; + INF("javascript prompt:\n" + "\t message: %s\n" + "\tdefault value: %s\n" + "\tgiving answer: %s\n" + "\t button: %s", message, defaultValue, *value, ret?"ok":"cancel"); + + return ret; +} + +// Event Handling ////////////////////////////////////////////////////// +static void _ewk_view_on_focus_in(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_in); + sd->api->focus_in(sd); +} + +static void _ewk_view_on_focus_out(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->focus_out); + sd->api->focus_out(sd); +} + +static void _ewk_view_on_mouse_wheel(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Mouse_Wheel* ev = (Evas_Event_Mouse_Wheel*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_wheel); + sd->api->mouse_wheel(sd, ev); +} + +static void _ewk_view_on_mouse_down(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Mouse_Down* ev = (Evas_Event_Mouse_Down*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_down); + sd->api->mouse_down(sd, ev); +} + +static void _ewk_view_on_mouse_up(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Mouse_Up* ev = (Evas_Event_Mouse_Up*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_up); + sd->api->mouse_up(sd, ev); +} + +static void _ewk_view_on_mouse_move(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Mouse_Move* ev = (Evas_Event_Mouse_Move*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->mouse_move); + sd->api->mouse_move(sd, ev); +} + +static void _ewk_view_on_key_down(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Key_Down* ev = (Evas_Event_Key_Down*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->key_down); + sd->api->key_down(sd, ev); +} + +static void _ewk_view_on_key_up(void* data, Evas* e, Evas_Object* o, void* event_info) +{ + Evas_Event_Key_Up* ev = (Evas_Event_Key_Up*)event_info; + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->key_up); + sd->api->key_up(sd, ev); +} + +static WTF::PassRefPtr<WebCore::Frame> _ewk_view_core_frame_new(Ewk_View_Smart_Data* sd, Ewk_View_Private_Data* priv, WebCore::HTMLFrameOwnerElement* owner) +{ + WebCore::FrameLoaderClientEfl* flc = new WebCore::FrameLoaderClientEfl(sd->self); + if (!flc) { + CRITICAL("Could not create frame loader client."); + return 0; + } + flc->setCustomUserAgent(WTF::String::fromUTF8(priv->settings.user_agent)); + + return WebCore::Frame::create(priv->page, owner, flc); +} + +static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL; + +static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* sd) +{ + Ewk_View_Private_Data* priv = + (Ewk_View_Private_Data*)calloc(1, sizeof(Ewk_View_Private_Data)); + WTF::AtomicString s; + WebCore::KURL url; + + if (!priv) { + CRITICAL("could not allocate Ewk_View_Private_Data"); + return 0; + } + + WebCore::Page::PageClients pageClients; + pageClients.chromeClient = static_cast<WebCore::ChromeClient*>(new WebCore::ChromeClientEfl(sd->self)); + pageClients.editorClient = static_cast<WebCore::EditorClient*>(new WebCore::EditorClientEfl(sd->self)); + pageClients.dragClient = static_cast<WebCore::DragClient*>(new WebCore::DragClientEfl); + pageClients.inspectorClient = static_cast<WebCore::InspectorClient*>(new WebCore::InspectorClientEfl); + priv->page = new WebCore::Page(pageClients); + if (!priv->page) { + CRITICAL("Could not create WebKit Page"); + goto error_page; + } + + priv->page_settings = priv->page->settings(); + if (!priv->page_settings) { + CRITICAL("Could not get page settings."); + goto error_settings; + } + + priv->page_settings->setLoadsImagesAutomatically(true); + priv->page_settings->setDefaultFixedFontSize(12); + priv->page_settings->setDefaultFontSize(16); + priv->page_settings->setSerifFontFamily("serif"); + priv->page_settings->setFixedFontFamily("monotype"); + priv->page_settings->setSansSerifFontFamily("sans"); + priv->page_settings->setStandardFontFamily("sans"); + priv->page_settings->setJavaScriptEnabled(true); + priv->page_settings->setPluginsEnabled(true); + priv->page_settings->setLocalStorageEnabled(true); + priv->page_settings->setOfflineWebApplicationCacheEnabled(true); + priv->page_settings->setUsesPageCache(true); + priv->page_settings->setUsesEncodingDetector(true); + + url = priv->page_settings->userStyleSheetLocation(); + priv->settings.user_stylesheet = eina_stringshare_add(url.prettyURL().utf8().data()); + + priv->settings.encoding_default = eina_stringshare_add + (priv->page_settings->defaultTextEncodingName().utf8().data()); + priv->settings.encoding_custom = 0; + + priv->settings.cache_directory = eina_stringshare_add + (WebCore::cacheStorage().cacheDirectory().utf8().data()); + + s = priv->page_settings->localStorageDatabasePath(); + priv->settings.local_storage_database_path = eina_stringshare_add(s.string().utf8().data()); + + priv->settings.font_minimum_size = priv->page_settings->minimumFontSize(); + priv->settings.font_minimum_logical_size = priv->page_settings->minimumLogicalFontSize(); + priv->settings.font_default_size = priv->page_settings->defaultFontSize(); + priv->settings.font_monospace_size = priv->page_settings->defaultFixedFontSize(); + + s = priv->page_settings->standardFontFamily(); + priv->settings.font_standard = eina_stringshare_add(s.string().utf8().data()); + s = priv->page_settings->cursiveFontFamily(); + priv->settings.font_cursive = eina_stringshare_add(s.string().utf8().data()); + s = priv->page_settings->fixedFontFamily(); + priv->settings.font_monospace = eina_stringshare_add(s.string().utf8().data()); + s = priv->page_settings->fantasyFontFamily(); + priv->settings.font_fantasy = eina_stringshare_add(s.string().utf8().data()); + s = priv->page_settings->serifFontFamily(); + priv->settings.font_serif = eina_stringshare_add(s.string().utf8().data()); + s = priv->page_settings->sansSerifFontFamily(); + priv->settings.font_sans_serif = eina_stringshare_add(s.string().utf8().data()); + + priv->settings.auto_load_images = priv->page_settings->loadsImagesAutomatically(); + priv->settings.auto_shrink_images = priv->page_settings->shrinksStandaloneImagesToFit(); + priv->settings.enable_auto_resize_window = EINA_TRUE; + priv->settings.enable_scripts = priv->page_settings->isJavaScriptEnabled(); + priv->settings.enable_plugins = priv->page_settings->arePluginsEnabled(); + priv->settings.enable_frame_flattening = priv->page_settings->frameFlatteningEnabled(); + priv->settings.scripts_window_open = priv->page_settings->allowScriptsToCloseWindows(); + priv->settings.resizable_textareas = priv->page_settings->textAreasAreResizable(); + priv->settings.private_browsing = priv->page_settings->privateBrowsingEnabled(); + priv->settings.caret_browsing = priv->page_settings->caretBrowsingEnabled(); + priv->settings.local_storage = priv->page_settings->localStorageEnabled(); + priv->settings.offline_app_cache = true; // XXX no function to read setting; this keeps the original setting + priv->settings.page_cache = priv->page_settings->usesPageCache(); + priv->settings.encoding_detector = priv->page_settings->usesEncodingDetector(); + + priv->settings.user_agent = ewk_settings_default_user_agent_get(); + + // Since there's no scale separated from zooming in webkit-efl, this functionality of + // viewport meta tag is implemented using zoom. When scale zoom is supported by webkit-efl, + // this functionality will be modified by the scale zoom patch. + priv->settings.zoom_range.min_scale = ZOOM_MIN; + priv->settings.zoom_range.max_scale = ZOOM_MAX; + priv->settings.zoom_range.user_scalable = EINA_TRUE; + priv->settings.device_pixel_ratio = DEVICE_PIXEL_RATIO; + + priv->main_frame = _ewk_view_core_frame_new(sd, priv, 0).get(); + if (!priv->main_frame) { + CRITICAL("Could not create main frame."); + goto error_main_frame; + } + + priv->history = ewk_history_new(static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())); + if (!priv->history) { + CRITICAL("Could not create history instance for view."); + goto error_history; + } + + return priv; + +error_history: + // delete priv->main_frame; /* do not delete priv->main_frame */ +error_main_frame: +error_settings: + delete priv->page; +error_page: + free(priv); + return 0; +} + +static void _ewk_view_priv_del(Ewk_View_Private_Data* priv) +{ + if (!priv) + return; + + /* do not delete priv->main_frame */ + + free(priv->repaints.array); + free(priv->scrolls.array); + + eina_stringshare_del(priv->settings.user_agent); + eina_stringshare_del(priv->settings.user_stylesheet); + eina_stringshare_del(priv->settings.encoding_default); + eina_stringshare_del(priv->settings.encoding_custom); + eina_stringshare_del(priv->settings.cache_directory); + eina_stringshare_del(priv->settings.font_standard); + eina_stringshare_del(priv->settings.font_cursive); + eina_stringshare_del(priv->settings.font_monospace); + eina_stringshare_del(priv->settings.font_fantasy); + eina_stringshare_del(priv->settings.font_serif); + eina_stringshare_del(priv->settings.font_sans_serif); + eina_stringshare_del(priv->settings.local_storage_database_path); + + if (priv->animated_zoom.animator) + ecore_animator_del(priv->animated_zoom.animator); + + ewk_history_free(priv->history); + + delete priv->page; + free(priv); +} + +static void _ewk_view_smart_add(Evas_Object* o) +{ + const Evas_Smart* smart = evas_object_smart_smart_get(o); + const Evas_Smart_Class* sc = evas_smart_class_get(smart); + const Ewk_View_Smart_Class* api = (const Ewk_View_Smart_Class*)sc; + EINA_SAFETY_ON_NULL_RETURN(api->backing_store_add); + EWK_VIEW_SD_GET(o, sd); + + if (!sd) { + sd = (Ewk_View_Smart_Data*)calloc(1, sizeof(Ewk_View_Smart_Data)); + if (!sd) + CRITICAL("could not allocate Ewk_View_Smart_Data"); + else + evas_object_smart_data_set(o, sd); + } + + sd->bg_color.r = 255; + sd->bg_color.g = 255; + sd->bg_color.b = 255; + sd->bg_color.a = 255; + + sd->self = o; + sd->_priv = _ewk_view_priv_new(sd); + sd->api = api; + + _parent_sc.add(o); + + if (!sd->_priv) + return; + + EWK_VIEW_PRIV_GET(sd, priv); + + sd->backing_store = api->backing_store_add(sd); + if (!sd->backing_store) { + ERR("Could not create backing store object."); + return; + } + + evas_object_smart_member_add(sd->backing_store, o); + evas_object_show(sd->backing_store); + evas_object_pass_events_set(sd->backing_store, EINA_TRUE); + + sd->events_rect = evas_object_rectangle_add(sd->base.evas); + evas_object_color_set(sd->events_rect, 0, 0, 0, 0); + evas_object_smart_member_add(sd->events_rect, o); + evas_object_show(sd->events_rect); + + sd->main_frame = ewk_frame_add(sd->base.evas); + if (!sd->main_frame) { + ERR("Could not create main frame object."); + return; + } + + if (!ewk_frame_init(sd->main_frame, o, priv->main_frame)) { + ERR("Could not initialize main frme object."); + evas_object_del(sd->main_frame); + sd->main_frame = 0; + + delete priv->main_frame; + priv->main_frame = 0; + return; + } + + evas_object_name_set(sd->main_frame, "EWK_Frame:main"); + evas_object_smart_member_add(sd->main_frame, o); + evas_object_show(sd->main_frame); + +#define CONNECT(s, c) evas_object_event_callback_add(o, s, c, sd) + CONNECT(EVAS_CALLBACK_FOCUS_IN, _ewk_view_on_focus_in); + CONNECT(EVAS_CALLBACK_FOCUS_OUT, _ewk_view_on_focus_out); + CONNECT(EVAS_CALLBACK_MOUSE_WHEEL, _ewk_view_on_mouse_wheel); + CONNECT(EVAS_CALLBACK_MOUSE_DOWN, _ewk_view_on_mouse_down); + CONNECT(EVAS_CALLBACK_MOUSE_UP, _ewk_view_on_mouse_up); + CONNECT(EVAS_CALLBACK_MOUSE_MOVE, _ewk_view_on_mouse_move); + CONNECT(EVAS_CALLBACK_KEY_DOWN, _ewk_view_on_key_down); + CONNECT(EVAS_CALLBACK_KEY_UP, _ewk_view_on_key_up); +#undef CONNECT +} + +static void _ewk_view_smart_del(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + Ewk_View_Private_Data* priv = sd ? sd->_priv : 0; + + ewk_view_stop(o); + _parent_sc.del(o); + _ewk_view_priv_del(priv); +} + +static void _ewk_view_smart_resize(Evas_Object* o, Evas_Coord w, Evas_Coord h) +{ + EWK_VIEW_SD_GET(o, sd); + + // these should be queued and processed in calculate as well! + evas_object_resize(sd->backing_store, w, h); + + sd->changed.size = EINA_TRUE; + _ewk_view_smart_changed(sd); +} + +static void _ewk_view_smart_move(Evas_Object* o, Evas_Coord x, Evas_Coord y) +{ + EWK_VIEW_SD_GET(o, sd); + sd->changed.position = EINA_TRUE; + _ewk_view_smart_changed(sd); +} + +static void _ewk_view_smart_calculate(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + EINA_SAFETY_ON_NULL_RETURN(sd->api->contents_resize); + EINA_SAFETY_ON_NULL_RETURN(sd->api->scrolls_process); + EINA_SAFETY_ON_NULL_RETURN(sd->api->repaints_process); + Evas_Coord x, y, w, h; + + sd->changed.any = EINA_FALSE; + + if (!sd->main_frame || !priv->main_frame) + return; + + evas_object_geometry_get(o, &x, &y, &w, &h); + + DBG("o=%p geo=[%d, %d + %dx%d], changed: size=%hhu, " + "scrolls=%zu, repaints=%zu", + o, x, y, w, h, sd->changed.size, + priv->scrolls.count, priv->repaints.count); + + if (sd->changed.size && ((w != sd->view.w) || (h != sd->view.h))) { + WebCore::FrameView* view = priv->main_frame->view(); + if (view) { + view->resize(w, h); + view->forceLayout(); + view->adjustViewSize(); + } + evas_object_resize(sd->main_frame, w, h); + evas_object_resize(sd->events_rect, w, h); + sd->changed.frame_rect = EINA_TRUE; + sd->view.w = w; + sd->view.h = h; + + // This callback is a good place e.g. to change fixed layout size (ewk_view_fixed_layout_size_set). + evas_object_smart_callback_call(o, "view,resized", 0); + } + sd->changed.size = EINA_FALSE; + + if (sd->changed.position && ((x != sd->view.x) || (y != sd->view.y))) { + evas_object_move(sd->main_frame, x, y); + evas_object_move(sd->backing_store, x, y); + evas_object_move(sd->events_rect, x, y); + sd->changed.frame_rect = EINA_TRUE; + sd->view.x = x; + sd->view.y = y; + } + sd->changed.position = EINA_FALSE; + + ewk_view_layout_if_needed_recursive(sd->_priv); + + if (!sd->api->scrolls_process(sd)) + ERR("failed to process scrolls."); + _ewk_view_scrolls_flush(priv); + + if (!sd->api->repaints_process(sd)) + ERR("failed to process repaints."); + _ewk_view_repaints_flush(priv); + + if (sd->changed.frame_rect) { + WebCore::FrameView* view = priv->main_frame->view(); + view->frameRectsChanged(); /* force tree to get position from root */ + sd->changed.frame_rect = EINA_FALSE; + } +} + +static void _ewk_view_smart_show(Evas_Object *o) +{ + EWK_VIEW_SD_GET(o, sd); + + if (evas_object_clipees_get(sd->base.clipper)) + evas_object_show(sd->base.clipper); + evas_object_show(sd->backing_store); +} + +static void _ewk_view_smart_hide(Evas_Object *o) +{ + EWK_VIEW_SD_GET(o, sd); + + evas_object_hide(sd->base.clipper); + evas_object_hide(sd->backing_store); +} + +static Eina_Bool _ewk_view_smart_contents_resize(Ewk_View_Smart_Data* sd, int w, int h) +{ + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_smart_zoom_set(Ewk_View_Smart_Data* sd, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + double px, py; + Evas_Coord x, y, w, h; + Eina_Bool ret; + + ewk_frame_scroll_size_get(sd->main_frame, &w, &h); + ewk_frame_scroll_pos_get(sd->main_frame, &x, &y); + + if (w + sd->view.w > 0) + px = (double)(x + cx) / (w + sd->view.w); + else + px = 0.0; + + if (h + sd->view.h > 0) + py = (double)(y + cy) / (h + sd->view.h); + else + py = 0.0; + + ret = ewk_frame_zoom_set(sd->main_frame, zoom); + + ewk_frame_scroll_size_get(sd->main_frame, &w, &h); + x = (w + sd->view.w) * px - cx; + y = (h + sd->view.h) * py - cy; + ewk_frame_scroll_set(sd->main_frame, x, y); + return ret; +} + +static void _ewk_view_smart_flush(Ewk_View_Smart_Data* sd) +{ + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + _ewk_view_repaints_flush(priv); + _ewk_view_scrolls_flush(priv); +} + +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) +{ + WRN("not supported by engine. sd=%p area=%d,%d+%dx%d, zoom=%f", + sd, x, y, w, h, zoom); + return EINA_FALSE; +} + +static Eina_Bool _ewk_view_smart_pre_render_relative_radius(Ewk_View_Smart_Data* sd, unsigned int n, float zoom) +{ + WRN("not supported by engine. sd=%p, n=%u zoom=%f", + sd, n, zoom); + return EINA_FALSE; +} + +static void _ewk_view_smart_pre_render_cancel(Ewk_View_Smart_Data* sd) +{ + WRN("not supported by engine. sd=%p", sd); +} + +static void _ewk_view_zoom_animated_mark_stop(Ewk_View_Smart_Data* sd) +{ + sd->animated_zoom.zoom.start = 0.0; + sd->animated_zoom.zoom.end = 0.0; + sd->animated_zoom.zoom.current = 0.0; +} + +static void _ewk_view_zoom_animated_finish(Ewk_View_Smart_Data* sd) +{ + EWK_VIEW_PRIV_GET(sd, priv); + ecore_animator_del(priv->animated_zoom.animator); + priv->animated_zoom.animator = 0; + _ewk_view_zoom_animated_mark_stop(sd); + evas_object_smart_callback_call(sd->self, "zoom,animated,end", 0); +} + +static float _ewk_view_zoom_animated_current(Ewk_View_Private_Data* priv) +{ + double now = ecore_loop_time_get(); + double delta = now - priv->animated_zoom.time.start; + + if (delta > priv->animated_zoom.time.duration) + delta = priv->animated_zoom.time.duration; + if (delta < 0.0) // time went back, clock adjusted? + delta = 0.0; + + delta /= priv->animated_zoom.time.duration; + + return ((priv->animated_zoom.zoom.range * delta) + + priv->animated_zoom.zoom.start); +} + +static Eina_Bool _ewk_view_zoom_animator_cb(void* data) +{ + Ewk_View_Smart_Data* sd = (Ewk_View_Smart_Data*)data; + Evas_Coord cx, cy; + EWK_VIEW_PRIV_GET(sd, priv); + double now = ecore_loop_time_get(); + + cx = priv->animated_zoom.center.x; + cy = priv->animated_zoom.center.y; + + // TODO: progressively center (cx, cy) -> (view.x + view.h/2, view.y + view.h/2) + if (cx >= sd->view.w) + cx = sd->view.w - 1; + if (cy >= sd->view.h) + cy = sd->view.h - 1; + + if ((now >= priv->animated_zoom.time.end) + || (now < priv->animated_zoom.time.start)) { + _ewk_view_zoom_animated_finish(sd); + ewk_view_zoom_set(sd->self, priv->animated_zoom.zoom.end, cx, cy); + sd->api->sc.calculate(sd->self); + return EINA_FALSE; + } + + sd->animated_zoom.zoom.current = _ewk_view_zoom_animated_current(priv); + sd->api->zoom_weak_set(sd, sd->animated_zoom.zoom.current, cx, cy); + return EINA_TRUE; +} + +static void _ewk_view_zoom_animation_start(Ewk_View_Smart_Data* sd) +{ + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + if (priv->animated_zoom.animator) + return; + priv->animated_zoom.animator = ecore_animator_add + (_ewk_view_zoom_animator_cb, sd); +} + +static WebCore::ViewportAttributes _ewk_view_viewport_attributes_compute(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + int desktop_width = 980; + int device_dpi = 160; + + int available_width = (int) priv->page->chrome()->client()->pageRect().width(); + int available_height = (int) priv->page->chrome()->client()->pageRect().height(); + + int device_width = (int) priv->page->chrome()->client()->windowRect().width(); + int device_height = (int) priv->page->chrome()->client()->windowRect().height(); + + WebCore::IntSize available_size = WebCore::IntSize(available_width, available_height); + WebCore::ViewportAttributes attributes = WebCore::computeViewportAttributes(priv->viewport_arguments, desktop_width, device_width, device_height, device_dpi, available_size); + + return attributes; +} + +static Eina_Bool _ewk_view_smart_disable_render(Ewk_View_Smart_Data *sd) +{ + WRN("not supported by engine. sd=%p", sd); + return EINA_FALSE; +} + +static Eina_Bool _ewk_view_smart_enable_render(Ewk_View_Smart_Data *sd) +{ + WRN("not supported by engine. sd=%p", sd); + return EINA_FALSE; +} + +/** + * Sets the smart class api without any backing store, enabling view + * to be inherited. + * + * @param api class definition to be set, all members with the + * exception of Evas_Smart_Class->data may be overridden. Must + * @b not be @c 0. + * + * @note Evas_Smart_Class->data is used to implement type checking and + * is not supposed to be changed/overridden. If you need extra + * data for your smart class to work, just extend + * Ewk_View_Smart_Class instead. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably + * version mismatch). + * + * @see ewk_view_single_smart_set() + * @see ewk_view_tiled_smart_set() + */ +Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class* api) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(api, EINA_FALSE); + + if (api->version != EWK_VIEW_SMART_CLASS_VERSION) { + EINA_LOG_CRIT + ("Ewk_View_Smart_Class %p is version %lu while %lu was expected.", + api, api->version, EWK_VIEW_SMART_CLASS_VERSION); + return EINA_FALSE; + } + + if (EINA_UNLIKELY(!_parent_sc.add)) + evas_object_smart_clipped_smart_set(&_parent_sc); + + evas_object_smart_clipped_smart_set(&api->sc); + api->sc.add = _ewk_view_smart_add; + api->sc.del = _ewk_view_smart_del; + api->sc.resize = _ewk_view_smart_resize; + api->sc.move = _ewk_view_smart_move; + api->sc.calculate = _ewk_view_smart_calculate; + api->sc.show = _ewk_view_smart_show; + api->sc.hide = _ewk_view_smart_hide; + api->sc.data = EWK_VIEW_TYPE_STR; /* used by type checking */ + + api->contents_resize = _ewk_view_smart_contents_resize; + api->zoom_set = _ewk_view_smart_zoom_set; + api->flush = _ewk_view_smart_flush; + api->pre_render_region = _ewk_view_smart_pre_render_region; + api->pre_render_relative_radius = _ewk_view_smart_pre_render_relative_radius; + api->pre_render_cancel = _ewk_view_smart_pre_render_cancel; + api->disable_render = _ewk_view_smart_disable_render; + api->enable_render = _ewk_view_smart_enable_render; + + api->focus_in = _ewk_view_smart_focus_in; + api->focus_out = _ewk_view_smart_focus_out; + api->mouse_wheel = _ewk_view_smart_mouse_wheel; + api->mouse_down = _ewk_view_smart_mouse_down; + api->mouse_up = _ewk_view_smart_mouse_up; + api->mouse_move = _ewk_view_smart_mouse_move; + api->key_down = _ewk_view_smart_key_down; + api->key_up = _ewk_view_smart_key_up; + + api->add_console_message = _ewk_view_smart_add_console_message; + api->run_javascript_alert = _ewk_view_smart_run_javascript_alert; + api->run_javascript_confirm = _ewk_view_smart_run_javascript_confirm; + api->run_javascript_prompt = _ewk_view_smart_run_javascript_prompt; + api->should_interrupt_javascript = _ewk_view_smart_should_interrupt_javascript; + + return EINA_TRUE; +} + +/** + * Set a fixed layout size to be used, dissociating it from viewport size. + * + * Setting a width different than zero enables fixed layout on that + * size. It's automatically scaled based on zoom, but will not change + * if viewport changes. + * + * Setting both @a w and @a h to zero will disable fixed layout. + * + * @param o view object to change fixed layout. + * @param w fixed width to use. This size will be automatically scaled + * based on zoom level. + * @param h fixed height to use. This size will be automatically scaled + * based on zoom level. + */ +void ewk_view_fixed_layout_size_set(Evas_Object* o, Evas_Coord w, Evas_Coord h) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + + WebCore::FrameView* view = sd->_priv->main_frame->view(); + if (w <= 0 && h <= 0) { + if (!priv->fixed_layout.use) + return; + priv->fixed_layout.w = 0; + priv->fixed_layout.h = 0; + priv->fixed_layout.use = EINA_FALSE; + } else { + if (priv->fixed_layout.use + && priv->fixed_layout.w == w && priv->fixed_layout.h == h) + return; + priv->fixed_layout.w = w; + priv->fixed_layout.h = h; + priv->fixed_layout.use = EINA_TRUE; + + if (view) + view->setFixedLayoutSize(WebCore::IntSize(w, h)); + } + + if (!view) + return; + view->setUseFixedLayout(priv->fixed_layout.use); + view->forceLayout(); +} + +/** + * Get fixed layout size in use. + * + * @param o view object to query fixed layout size. + * @param w where to return width. Returns 0 on error or if no fixed + * layout in use. + * @param h where to return height. Returns 0 on error or if no fixed + * layout in use. + */ +void ewk_view_fixed_layout_size_get(Evas_Object* o, Evas_Coord* w, Evas_Coord* h) +{ + if (w) + *w = 0; + if (h) + *h = 0; + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + if (priv->fixed_layout.use) { + if (w) + *w = priv->fixed_layout.w; + if (h) + *h = priv->fixed_layout.h; + } +} + +/** + * Set the theme path to be used by this view. + * + * This also sets the theme on the main frame. As frames inherit theme + * from their parent, this will have all frames with unset theme to + * use this one. + * + * @param o view object to change theme. + * @param path theme path, may be @c 0 to reset to default. + */ +void ewk_view_theme_set(Evas_Object* o, const char* path) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + if (!eina_stringshare_replace(&priv->settings.theme, path)) + return; + ewk_frame_theme_set(sd->main_frame, path); +} + +/** + * Gets the theme set on this frame. + * + * This returns the value set by ewk_view_theme_set(). + * + * @param o view object to get theme path. + * + * @return theme path, may be @c 0 if not set. + */ +const char* ewk_view_theme_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.theme; +} + +/** + * Get the object that represents the main frame. + * + * @param o view object to get main frame. + * + * @return ewk_frame object or @c 0 if none yet. + */ +Evas_Object* ewk_view_frame_main_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + return sd->main_frame; +} + +/** + * Get the currently focused frame object. + * + * @param o view object to get focused frame. + * + * @return ewk_frame object or @c 0 if none yet. + */ +Evas_Object* ewk_view_frame_focused_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + + WebCore::Frame* core = priv->page->focusController()->focusedFrame(); + if (!core) + return 0; + + WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(core->loader()->client()); + if (!client) + return 0; + return client->webFrame(); +} + +/** + * Ask main frame to load the given URI. + * + * @param o view object to load uri. + * @param uri uniform resource identifier to load. + * + * @return @c EINA_TRUE on successful request, @c EINA_FALSE on failure. + * Note that it means the request was done, not that it was + * satisfied. + */ +Eina_Bool ewk_view_uri_set(Evas_Object* o, const char* uri) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_uri_set(sd->main_frame, uri); +} + +/** + * Get the current uri loaded by main frame. + * + * @param o view object to get current uri. + * + * @return current uri reference or @c 0. It's internal, don't change. + */ +const char* ewk_view_uri_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + return ewk_frame_uri_get(sd->main_frame); +} + +/** + * Get the current title of main frame. + * + * @param o view object to get current title. + * + * @return current title reference or @c 0. It's internal, don't change. + */ +const char* ewk_view_title_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + return ewk_frame_title_get(sd->main_frame); +} + +/** + * Gets if main frame is editable. + * + * @param o view object to get editable state. + * + * @return @c EINA_TRUE if editable, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_editable_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_editable_get(sd->main_frame); +} + +/** + * Set background color and transparency + * + * Just as in Evas, colors are pre-multiplied, so 50% red is + * (128, 0, 0, 128) and not (255, 0, 0, 128)! + * + * @warning Watch out performance issues with transparency! Object + * will be handled as transparent image by evas even if the + * webpage specifies a background color. That mean you'll pay + * a price even if it's not really transparent, thus + * scrolling/panning and zooming will be likely slower than + * if transparency is off. + * + * @param o view object to change. + * @param r red component. + * @param g green component. + * @param b blue component. + * @param a transparency. + */ +void ewk_view_bg_color_set(Evas_Object* o, int r, int g, int b, int a) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->bg_color_set); + + if (a < 0) { + WRN("Alpha less than zero (%d).", a); + a = 0; + } else if (a > 255) { + WRN("Alpha is larger than 255 (%d).", a); + a = 255; + } + +#define CHECK_PREMUL_COLOR(c, a) \ + if (c < 0) { \ + WRN("Color component "#c" is less than zero (%d).", c); \ + c = 0; \ + } else if (c > a) { \ + WRN("Color component "#c" is greater than alpha (%d, alpha=%d).", \ + c, a); \ + c = a; \ + } + CHECK_PREMUL_COLOR(r, a); + CHECK_PREMUL_COLOR(g, a); + CHECK_PREMUL_COLOR(b, a); +#undef CHECK_PREMUL_COLOR + + sd->bg_color.r = r; + sd->bg_color.g = g; + sd->bg_color.b = b; + sd->bg_color.a = a; + + sd->api->bg_color_set(sd, r, g, b, a); + + WebCore::FrameView* view = sd->_priv->main_frame->view(); + if (view) { + WebCore::Color color; + + if (!a) + color = WebCore::Color(0, 0, 0, 0); + else if (a == 255) + color = WebCore::Color(r, g, b, a); + else + color = WebCore::Color(r * 255 / a, g * 255 / a, b * 255 / a, a); + + view->updateBackgroundRecursively(color, !a); + } +} + +/** + * Query if view object background color. + * + * Just as in Evas, colors are pre-multiplied, so 50% red is + * (128, 0, 0, 128) and not (255, 0, 0, 128)! + * + * @param o view object to query. + * @param r where to return red color component. + * @param g where to return green color component. + * @param b where to return blue color component. + * @param a where to return alpha value. + */ +void ewk_view_bg_color_get(const Evas_Object* o, int* r, int* g, int* b, int* a) +{ + if (r) + *r = 0; + if (g) + *g = 0; + if (b) + *b = 0; + if (a) + *a = 0; + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + if (r) + *r = sd->bg_color.r; + if (g) + *g = sd->bg_color.g; + if (b) + *b = sd->bg_color.b; + if (a) + *a = sd->bg_color.a; +} + +/** + * Search the given text string in document. + * + * @param o view object where to search text. + * @param string reference string to search. + * @param case_sensitive if search should be case sensitive or not. + * @param forward if search is from cursor and on or backwards. + * @param wrap if search should wrap at end. + * + * @return @c EINA_TRUE if found, @c EINA_FALSE if not or failure. + */ +Eina_Bool ewk_view_text_search(const Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(string, EINA_FALSE); + WTF::TextCaseSensitivity sensitive; + WebCore::FindDirection direction; + + if (case_sensitive) + sensitive = WTF::TextCaseSensitive; + else + sensitive = WTF::TextCaseInsensitive; + + if (forward) + direction = WebCore::FindDirectionForward; + else + direction = WebCore::FindDirectionBackward; + + return priv->page->findString(WTF::String::fromUTF8(string), sensitive, direction, wrap); +} + +/** + * Mark matches the given text string in document. + * + * @param o view object where to search text. + * @param string reference string to match. + * @param case_sensitive if match should be case sensitive or not. + * @param highlight if matches should be highlighted. + * @param limit maximum amount of matches, or zero to unlimited. + * + * @return number of matches. + */ +unsigned int ewk_view_text_matches_mark(Evas_Object* o, const char* string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(string, 0); + WTF::TextCaseSensitivity sensitive; + + if (case_sensitive) + sensitive = WTF::TextCaseSensitive; + else + sensitive = WTF::TextCaseInsensitive; + + return priv->page->markAllMatchesForText(WTF::String::fromUTF8(string), sensitive, highlight, limit); +} + +/** + * Reverses the effect of ewk_view_text_matches_mark() + * + * @param o view object where to search text. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE for failure. + */ +Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + priv->page->unmarkAllTextMatches(); + return EINA_TRUE; +} + +/** + * Set if should highlight matches marked with ewk_view_text_matches_mark(). + * + * @param o view object where to set if matches are highlighted or not. + * @param highlight if @c EINA_TRUE, matches will be highlighted. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE for failure. + */ +Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object* o, Eina_Bool highlight) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_text_matches_highlight_set(sd->main_frame, highlight); +} + +/** + * Get if should highlight matches marked with ewk_view_text_matches_mark(). + * + * @param o view object to query if matches are highlighted or not. + * + * @return @c EINA_TRUE if they are highlighted, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_text_matches_highlight_get(sd->main_frame); +} + +/** + * Sets if main frame is editable. + * + * @param o view object to set editable state. + * @param editable new state. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_editable_set(Evas_Object* o, Eina_Bool editable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_editable_set(sd->main_frame, editable); +} + +/** + * Get the copy of the selection text. + * + * @param o view object to get selection text. + * + * @return newly allocated string or @c 0 if nothing is selected or failure. + */ +char* ewk_view_selection_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + WTF::CString s = priv->page->focusController()->focusedOrMainFrame()->editor()->selectedText().utf8(); + if (s.isNull()) + return 0; + return strdup(s.data()); +} + +static Eina_Bool _ewk_view_editor_command(Ewk_View_Private_Data* priv, const char* command) +{ + return priv->page->focusController()->focusedOrMainFrame()->editor()->command(WTF::String::fromUTF8(command)).execute(); +} + +/** + * Unselects whatever was selected. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_none(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "Unselect"); +} + +/** + * Selects everything. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_all(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "SelectAll"); +} + +/** + * Selects the current paragrah. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_paragraph(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "SelectParagraph"); +} + +/** + * Selects the current sentence. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_sentence(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "SelectSentence"); +} + +/** + * Selects the current line. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_line(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "SelectLine"); +} + +/** + * Selects the current word. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_select_word(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return _ewk_view_editor_command(priv, "SelectWord"); +} + +#if ENABLE(CONTEXT_MENUS) + +/** + * Forwards a request of new Context Menu to WebCore. + * + * @param o View. + * @param ev Event data. + * + * @return @c EINA_TRUE if operation was executed, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_context_menu_forward_event(Evas_Object* o, const Evas_Event_Mouse_Down* ev) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + Eina_Bool mouse_press_handled = EINA_FALSE; + + priv->page->contextMenuController()->clearContextMenu(); + WebCore::Frame* main_frame = priv->page->mainFrame(); + Evas_Coord x, y; + evas_object_geometry_get(sd->self, &x, &y, 0, 0); + + WebCore::PlatformMouseEvent event(ev, WebCore::IntPoint(x, y)); + + if (main_frame->view()) { + mouse_press_handled = + main_frame->eventHandler()->handleMousePressEvent(event); + } + + if (main_frame->eventHandler()->sendContextMenuEvent(event)) + return EINA_FALSE; + + WebCore::ContextMenu* coreMenu = + priv->page->contextMenuController()->contextMenu(); + if (!coreMenu) { + // WebCore decided not to create a context menu, return true if event + // was handled by handleMouseReleaseEvent + return mouse_press_handled; + } + + return EINA_TRUE; +} + +#endif + +/** + * Get current load progress estimate from 0.0 to 1.0. + * + * @param o view object to get current progress. + * + * @return progres value from 0.0 to 1.0 or -1.0 on error. + */ +double ewk_view_load_progress_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, -1.0); + return priv->page->progress()->estimatedProgress(); +} + +/** + * Ask main frame to stop loading. + * + * @param o view object to stop loading. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_stop() + */ +Eina_Bool ewk_view_stop(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_stop(sd->main_frame); +} + +/** + * Ask main frame to reload current document. + * + * @param o view object to reload. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_reload() + */ +Eina_Bool ewk_view_reload(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_reload(sd->main_frame); +} + +/** + * Ask main frame to fully reload current document, using no caches. + * + * @param o view object to reload. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_reload_full() + */ +Eina_Bool ewk_view_reload_full(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_reload_full(sd->main_frame); +} + +/** + * Ask main frame to navigate back in history. + * + * @param o view object to navigate back. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_back() + */ +Eina_Bool ewk_view_back(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_back(sd->main_frame); +} + +/** + * Ask main frame to navigate forward in history. + * + * @param o view object to navigate forward. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_forward() + */ +Eina_Bool ewk_view_forward(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_forward(sd->main_frame); +} + +/** + * Navigate back or forward in history. + * + * @param o view object to navigate. + * @param steps if positive navigates that amount forwards, if negative + * does backwards. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_frame_navigate() + */ +Eina_Bool ewk_view_navigate(Evas_Object* o, int steps) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_navigate(sd->main_frame, steps); +} + +/** + * Check if it is possible to navigate backwards one item in history. + * + * @param o view object to check if backward navigation is possible. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + * + * @see ewk_view_navigate_possible() + */ +Eina_Bool ewk_view_back_possible(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_back_possible(sd->main_frame); +} + +/** + * Check if it is possible to navigate forwards one item in history. + * + * @param o view object to check if forward navigation is possible. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + * + * @see ewk_view_navigate_possible() + */ +Eina_Bool ewk_view_forward_possible(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_forward_possible(sd->main_frame); +} + +/** + * Check if it is possible to navigate given @a steps in history. + * + * @param o view object to navigate. + * @param steps if positive navigates that amount forwards, if negative + * does backwards. + * + * @return @c EINA_TRUE if possible, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_navigate_possible(Evas_Object* o, int steps) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_navigate_possible(sd->main_frame, steps); +} + +/** + * Check if navigation history (back-forward lists) is enabled. + * + * @param o view object to check if navigation history is enabled. + * + * @return @c EINA_TRUE if view keeps history, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_history_enable_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled(); +} + +/** + * Sets if navigation history (back-forward lists) is enabled. + * + * @param o view object to set if navigation history is enabled. + * @param enable @c EINA_TRUE if we want to enable navigation history; + * @c EINA_FALSE otherwise. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_history_enable_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->setEnabled(enable); + return EINA_TRUE; +} + +/** + * Gets the history (back-forward list) associated with this view. + * + * @param o view object to get navigation history from. + * + * @return returns the history instance handle associated with this + * view or @c 0 on errors (including when history is not + * enabled with ewk_view_history_enable_set()). This instance + * is unique for this view and thus multiple calls to this + * function with the same view as parameter returns the same + * handle. This handle is alive while view is alive, thus one + * might want to listen for EVAS_CALLBACK_DEL on given view + * (@a o) to know when to stop using returned handle. + * + * @see ewk_view_history_enable_set() + */ +Ewk_History* ewk_view_history_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + if (!static_cast<WebCore::BackForwardListImpl*>(priv->page->backForwardList())->enabled()) { + ERR("asked history, but it's disabled! Returning 0!"); + return 0; + } + return priv->history; +} + +/** + * Get the current zoom level of main frame. + * + * @param o view object to query zoom level. + * + * @return current zoom level in use or -1.0 on error. + */ +float ewk_view_zoom_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, -1.0); + return ewk_frame_zoom_get(sd->main_frame); +} + +/** + * Set the current zoom level of main frame. + * + * @param o view object to set zoom level. + * @param zoom new level to use. + * @param cx x of center coordinate + * @param cy y of center coordinate + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_zoom_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET(sd, priv); + + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_set, EINA_FALSE); + + if (!priv->settings.zoom_range.user_scalable) { + WRN("userScalable is false"); + return EINA_FALSE; + } + + if (zoom < priv->settings.zoom_range.min_scale) { + WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom); + return EINA_FALSE; + } + if (zoom > priv->settings.zoom_range.max_scale) { + WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom); + return EINA_FALSE; + } + + if (cx >= sd->view.w) + cx = sd->view.w - 1; + if (cy >= sd->view.h) + cy = sd->view.h - 1; + if (cx < 0) + cx = 0; + if (cy < 0) + cy = 0; + _ewk_view_zoom_animated_mark_stop(sd); + return sd->api->zoom_set(sd, zoom, cx, cy); +} + +Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return sd->zoom_weak_smooth_scale; +} + +void ewk_view_zoom_weak_smooth_scale_set(Evas_Object* o, Eina_Bool smooth_scale) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + smooth_scale = !!smooth_scale; + if (sd->zoom_weak_smooth_scale == smooth_scale) + return; + sd->zoom_weak_smooth_scale = smooth_scale; + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->zoom_weak_smooth_scale_set); + sd->api->zoom_weak_smooth_scale_set(sd, smooth_scale); +} + +/** + * Set the current zoom level of backing store, centered at given point. + * + * Unlike ewk_view_zoom_set(), this call do not ask WebKit to render + * at new size, but scale what is already rendered, being much faster + * but worse quality. + * + * Often one should use ewk_view_zoom_animated_set(), it will call the + * same machinery internally. + * + * @note this will set variables used by ewk_view_zoom_animated_set() + * so sub-classes will not reset internal state on their + * "calculate" phase. To unset those and enable sub-classes to + * reset their internal state, call + * ewk_view_zoom_animated_mark_stop(). Namely, this call will + * set ewk_view_zoom_animated_mark_start() to actual webkit zoom + * level, ewk_view_zoom_animated_mark_end() and + * ewk_view_zoom_animated_mark_current() to given zoom level. + * + * @param o view object to set weak zoom level. + * @param zoom level to scale backing store. + * @param cx horizontal center offset, relative to object (w/2 is middle). + * @param cy vertical center offset, relative to object (h/2 is middle). + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_zoom_weak_set(Evas_Object* o, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET(sd, priv); + + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE); + + if (!priv->settings.zoom_range.user_scalable) { + WRN("userScalable is false"); + return EINA_FALSE; + } + + if (zoom < priv->settings.zoom_range.min_scale) { + WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom); + return EINA_FALSE; + } + if (zoom > priv->settings.zoom_range.max_scale) { + WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom); + return EINA_FALSE; + } + + if (cx >= sd->view.w) + cx = sd->view.w - 1; + if (cy >= sd->view.h) + cy = sd->view.h - 1; + if (cx < 0) + cx = 0; + if (cy < 0) + cy = 0; + + sd->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame); + sd->animated_zoom.zoom.end = zoom; + sd->animated_zoom.zoom.current = zoom; + return sd->api->zoom_weak_set(sd, zoom, cx, cy); +} + +/** + * Mark internal zoom animation state to given zoom. + * + * This does not modify any actual zoom in WebKit or backing store, + * just set the Ewk_View_Smart_Data->animated_zoom.zoom.start so + * sub-classes will know they should not reset their internal state. + * + * @param o view object to change value. + * @param zoom new start value. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_view_zoom_animated_set() + * @see ewk_view_zoom_weak_set() + * @see ewk_view_zoom_animated_mark_stop() + * @see ewk_view_zoom_animated_mark_end() + * @see ewk_view_zoom_animated_mark_current() + */ +Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object* o, float zoom) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + sd->animated_zoom.zoom.start = zoom; + return EINA_TRUE; +} + +/** + * Mark internal zoom animation state to given zoom. + * + * This does not modify any actual zoom in WebKit or backing store, + * just set the Ewk_View_Smart_Data->animated_zoom.zoom.end so + * sub-classes will know they should not reset their internal state. + * + * @param o view object to change value. + * @param zoom new end value. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_view_zoom_animated_set() + * @see ewk_view_zoom_weak_set() + * @see ewk_view_zoom_animated_mark_stop() + * @see ewk_view_zoom_animated_mark_start() + * @see ewk_view_zoom_animated_mark_current() + */ +Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object* o, float zoom) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + sd->animated_zoom.zoom.end = zoom; + return EINA_TRUE; +} + +/** + * Mark internal zoom animation state to given zoom. + * + * This does not modify any actual zoom in WebKit or backing store, + * just set the Ewk_View_Smart_Data->animated_zoom.zoom.current so + * sub-classes will know they should not reset their internal state. + * + * @param o view object to change value. + * @param zoom new current value. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @see ewk_view_zoom_animated_set() + * @see ewk_view_zoom_weak_set() + * @see ewk_view_zoom_animated_mark_stop() + * @see ewk_view_zoom_animated_mark_start() + * @see ewk_view_zoom_animated_mark_end() + */ +Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object* o, float zoom) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + sd->animated_zoom.zoom.current = zoom; + return EINA_TRUE; +} + +/** + * Unmark internal zoom animation state. + * + * This zero all start, end and current values. + * + * @param o view object to mark as animated is stopped. + * + * @see ewk_view_zoom_animated_mark_start() + * @see ewk_view_zoom_animated_mark_end() + * @see ewk_view_zoom_animated_mark_current() + * @see ewk_view_zoom_weak_set() + */ +Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + _ewk_view_zoom_animated_mark_stop(sd); + return EINA_TRUE; +} + +/** + * Set the current zoom level while animating. + * + * If the view was already animating to another zoom, it will start + * from current point to the next provided zoom (@a zoom parameter) + * and duration (@a duration parameter). + * + * This is the recommended way to do transitions from one level to + * another. However, one may wish to do those from outside, in that + * case use ewk_view_zoom_weak_set() and later control intermediate + * states with ewk_view_zoom_animated_mark_current(), + * ewk_view_zoom_animated_mark_end() and + * ewk_view_zoom_animated_mark_stop(). + * + * @param o view object to animate. + * @param zoom final zoom level to use. + * @param duration time in seconds the animation should take. + * @param cx offset inside object that defines zoom center. 0 is left side. + * @param cy offset inside object that defines zoom center. 0 is top side. + * @return @c EINA_TRUE if animation will be started, @c EINA_FALSE if not + * because zoom is too small/big. + */ +Eina_Bool ewk_view_zoom_animated_set(Evas_Object* o, float zoom, float duration, Evas_Coord cx, Evas_Coord cy) +{ + double now; + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->zoom_weak_set, EINA_FALSE); + + if (!priv->settings.zoom_range.user_scalable) { + WRN("userScalable is false"); + return EINA_FALSE; + } + + if (zoom < priv->settings.zoom_range.min_scale) { + WRN("zoom level is < %f : %f", (double)priv->settings.zoom_range.min_scale, (double)zoom); + return EINA_FALSE; + } + if (zoom > priv->settings.zoom_range.max_scale) { + WRN("zoom level is > %f : %f", (double)priv->settings.zoom_range.max_scale, (double)zoom); + return EINA_FALSE; + } + + if (priv->animated_zoom.animator) + priv->animated_zoom.zoom.start = _ewk_view_zoom_animated_current(priv); + else { + priv->animated_zoom.zoom.start = ewk_frame_zoom_get(sd->main_frame); + _ewk_view_zoom_animation_start(sd); + } + + if (cx < 0) + cx = 0; + if (cy < 0) + cy = 0; + + now = ecore_loop_time_get(); + priv->animated_zoom.time.start = now; + priv->animated_zoom.time.end = now + duration; + priv->animated_zoom.time.duration = duration; + priv->animated_zoom.zoom.end = zoom; + priv->animated_zoom.zoom.range = (priv->animated_zoom.zoom.end - priv->animated_zoom.zoom.start); + priv->animated_zoom.center.x = cx; + priv->animated_zoom.center.y = cy; + sd->animated_zoom.zoom.current = priv->animated_zoom.zoom.start; + sd->animated_zoom.zoom.start = priv->animated_zoom.zoom.start; + sd->animated_zoom.zoom.end = priv->animated_zoom.zoom.end; + + return EINA_TRUE; +} + +/** + * Query if zoom level just applies to text and not other elements. + * + * @param o view to query setting. + * + * @return @c EINA_TRUE if just text are scaled, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_zoom_text_only_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_zoom_text_only_get(sd->main_frame); +} + +/** + * Set if zoom level just applies to text and not other elements. + * + * @param o view to change setting. + * @param setting @c EINA_TRUE if zoom should just be applied to text. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_zoom_text_only_set(Evas_Object* o, Eina_Bool setting) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + return ewk_frame_zoom_text_only_set(sd->main_frame, setting); +} + +/** + * Hint engine to pre-render region. + * + * Engines and backing store might be able to pre-render regions in + * order to speed up zooming or scrolling to that region. Not all + * engines might implement that and they will return @c EINA_FALSE + * in that case. + * + * The given region is a hint. Engines might do bigger or smaller area + * that covers that region. Pre-render might not be immediate, it may + * be postponed to a thread, operated cooperatively in the main loop + * and may be even ignored or cancelled afterwards. + * + * Multiple requests might be queued by engines. One can clear/forget + * about them with ewk_view_pre_render_cancel(). + * + * @param o view to ask pre-render of given region. + * @param x absolute coordinate (0=left) to pre-render at zoom. + * @param y absolute coordinate (0=top) to pre-render at zoom. + * @param w width to pre-render starting from @a x at zoom. + * @param h height to pre-render starting from @a y at zoom. + * @param zoom desired zoom. + * + * @return @c EINA_TRUE if request was accepted, @c EINA_FALSE + * otherwise (errors, pre-render not supported, etc). + * + * @see ewk_view_pre_render_cancel() + */ +Eina_Bool ewk_view_pre_render_region(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_region, EINA_FALSE); + float cur_zoom; + Evas_Coord cw, ch; + + /* When doing animated zoom it's not possible to call pre-render since it + * would screw up parameters that animation is currently using + */ + if (priv->animated_zoom.animator) + return EINA_FALSE; + + cur_zoom = ewk_frame_zoom_get(sd->main_frame); + + if (cur_zoom < 0.00001) + return EINA_FALSE; + if (!ewk_frame_contents_size_get(sd->main_frame, &cw, &ch)) + return EINA_FALSE; + + cw *= zoom / cur_zoom; + ch *= zoom / cur_zoom; + DBG("region %d,%d+%dx%d @ %f contents=%dx%d", x, y, w, h, zoom, cw, ch); + + if (x + w > cw) + w = cw - x; + + if (y + h > ch) + h = ch - y; + + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + + return sd->api->pre_render_region(sd, x, y, w, h, zoom); +} + +/** + * Hint engine to pre-render region, given n extra cols/rows + * + * This is an alternative method to ewk_view_pre_render_region(). It does not + * make sense in all engines and therefore it might not be implemented at all. + * + * It's only useful if engine divide the area being rendered in smaller tiles, + * forming a grid. Then, browser could call this function to pre-render @param n + * rows/cols involving the current viewport. + * + * @param o view to ask pre-render on. + * @param n number of cols/rows that must be part of the region pre-rendered + * + * @see ewk_view_pre_render_region() + */ +Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object* o, unsigned int n) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->pre_render_relative_radius, EINA_FALSE); + float cur_zoom; + + if (priv->animated_zoom.animator) + return EINA_FALSE; + + cur_zoom = ewk_frame_zoom_get(sd->main_frame); + return sd->api->pre_render_relative_radius(sd, n, cur_zoom); +} + +/** + * Get input method hints + * + * @param o View. + * + * @return input method hints + */ +unsigned int ewk_view_imh_get(Evas_Object *o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->imh; +} + +/** + * Cancel (clear) previous pre-render requests. + * + * @param o view to clear pre-render requests. + */ +void ewk_view_pre_render_cancel(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api->pre_render_cancel); + sd->api->pre_render_cancel(sd); +} + +/** + * Enable processing of update requests. + * + * @param o view to enable rendering. + * + * @return @c EINA_TRUE if render was enabled, @c EINA_FALSE + otherwise (errors, rendering suspension not supported). + */ +Eina_Bool ewk_view_enable_render(const Evas_Object *o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->enable_render, EINA_FALSE); + return sd->api->enable_render(sd); +} + +/** + * Disable processing of update requests. + * + * @param o view to disable rendering. + * + * @return @c EINA_TRUE if render was disabled, @c EINA_FALSE + otherwise (errors, rendering suspension not supported). + */ +Eina_Bool ewk_view_disable_render(const Evas_Object *o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api->disable_render, EINA_FALSE); + return sd->api->disable_render(sd); +} + +const char* ewk_view_setting_user_agent_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.user_agent; +} + +Eina_Bool ewk_view_setting_user_agent_set(Evas_Object* o, const char* user_agent) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.user_agent, user_agent)) { + WebCore::FrameLoaderClientEfl* client = static_cast<WebCore::FrameLoaderClientEfl*>(priv->main_frame->loader()->client()); + client->setCustomUserAgent(WTF::String::fromUTF8(user_agent)); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_user_stylesheet_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.user_stylesheet; +} + +Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object* o, const char* uri) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.user_stylesheet, uri)) { + WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(uri)); + priv->page_settings->setUserStyleSheetLocation(kurl); + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.auto_load_images; +} + +Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object* o, Eina_Bool automatic) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + automatic = !!automatic; + if (priv->settings.auto_load_images != automatic) { + priv->page_settings->setLoadsImagesAutomatically(automatic); + priv->settings.auto_load_images = automatic; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.auto_shrink_images; +} + +Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object* o, Eina_Bool automatic) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + automatic = !!automatic; + if (priv->settings.auto_shrink_images != automatic) { + priv->page_settings->setShrinksStandaloneImagesToFit(automatic); + priv->settings.auto_shrink_images = automatic; + } + return EINA_TRUE; +} + +/** + * Gets if view can be resized automatically. + * + * @param o view to check status + * + * @return EINA_TRUE if view can be resized, EINA_FALSE + * otherwise (errors, cannot be resized). + */ +Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.enable_auto_resize_window; +} + +/** + * Sets if view can be resized automatically. + * + * @param o View. + * @param resizable @c EINA_TRUE if we want to resize automatically; + * @c EINA_FALSE otherwise. It defaults to @c EINA_TRUE + * + * @return EINA_TRUE if auto_resize_window status set, EINA_FALSE + * otherwise (errors). + */ +Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object* o, Eina_Bool resizable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + priv->settings.enable_auto_resize_window = resizable; + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.enable_scripts; +} + +Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.enable_scripts != enable) { + priv->page_settings->setJavaScriptEnabled(enable); + priv->settings.enable_scripts = enable; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.enable_plugins; +} + +Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.enable_plugins != enable) { + priv->page_settings->setPluginsEnabled(enable); + priv->settings.enable_plugins = enable; + } + return EINA_TRUE; +} + +/** + * Get status of frame flattening. + * + * @param o view to check status + * + * @return EINA_TRUE if flattening is enabled, EINA_FALSE + * otherwise (errors, flattening disabled). + */ +Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.enable_frame_flattening; +} + +/** + * Set frame flattening. + * + * @param o view to set flattening + * + * @return EINA_TRUE if flattening status set, EINA_FALSE + * otherwise (errors). + */ +Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.enable_frame_flattening != enable) { + priv->page_settings->setFrameFlatteningEnabled(enable); + priv->settings.enable_frame_flattening = enable; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_scripts_window_open_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.scripts_window_open; +} + +Eina_Bool ewk_view_setting_scripts_window_open_set(Evas_Object* o, Eina_Bool allow) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + allow = !!allow; + if (priv->settings.scripts_window_open != allow) { + priv->page_settings->setJavaScriptCanOpenWindowsAutomatically(allow); + priv->settings.scripts_window_open = allow; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.resizable_textareas; +} + +Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.resizable_textareas != enable) { + priv->page_settings->setTextAreasAreResizable(enable); + priv->settings.resizable_textareas = enable; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.private_browsing; +} + +Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.private_browsing != enable) { + priv->page_settings->setPrivateBrowsingEnabled(enable); + priv->settings.private_browsing = enable; + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_offline_app_cache_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.offline_app_cache; +} + +Eina_Bool ewk_view_setting_offline_app_cache_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.offline_app_cache != enable) { + priv->page_settings->setOfflineWebApplicationCacheEnabled(enable); + priv->settings.offline_app_cache = enable; + } + return EINA_TRUE; +} + + +Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.caret_browsing; +} + +Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.caret_browsing != enable) { + priv->page_settings->setCaretBrowsingEnabled(enable); + priv->settings.caret_browsing = enable; + } + return EINA_TRUE; +} + +/** + * Get current encoding of this View. + * + * @param o View. + * + * @return A pointer to an eina_strinshare containing the current custom + * encoding for View object @param o, or @c 0 if it's not set. + */ +const char* ewk_view_setting_encoding_custom_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + Evas_Object* main_frame = ewk_view_frame_main_get(o); + WebCore::Frame* core_frame = ewk_frame_core_get(main_frame); + + WTF::String overrideEncoding = core_frame->loader()->documentLoader()->overrideEncoding(); + + if (overrideEncoding.isEmpty()) + return 0; + + eina_stringshare_replace(&priv->settings.encoding_custom, overrideEncoding.utf8().data()); + return priv->settings.encoding_custom; +} + +/** + * Set encoding of this View and reload page. + * + * @param o View. + * @param encoding The new encoding or @c 0 to restore the default encoding. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + */ +Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object* o, const char *encoding) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + Evas_Object* main_frame = ewk_view_frame_main_get(o); + WebCore::Frame* core_frame = ewk_frame_core_get(main_frame); +DBG("%s", encoding); + eina_stringshare_replace(&priv->settings.encoding_custom, encoding); + core_frame->loader()->reloadWithOverrideEncoding(WTF::String::fromUTF8(encoding)); + + return EINA_TRUE; +} + +const char* ewk_view_setting_encoding_default_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.encoding_default; +} + +Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object* o, const char* encoding) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.encoding_default, encoding)) + priv->page_settings->setDefaultTextEncodingName(WTF::String::fromUTF8(encoding)); + return EINA_TRUE; +} + +/** + * Sets the encoding detector. + * + * @param o view object to set if encoding detector is enabled. + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure + */ +Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.encoding_detector != enable) { + priv->page_settings->setUsesEncodingDetector(enable); + priv->settings.encoding_detector = enable; + } + return EINA_TRUE; +} + +/** + * Gets if the encoding detector is enabled. + * + * @param o view object to get if encoding detector is enabled. + * @return @c EINA_TRUE if encoding detector is enabled, @c EINA_FALSE if not or on errors. + */ +Eina_Bool ewk_view_setting_encoding_detector_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.encoding_detector; +} + +const char* ewk_view_setting_cache_directory_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.cache_directory; +} + +Eina_Bool ewk_view_setting_cache_directory_set(Evas_Object* o, const char* path) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.cache_directory, path)) + WebCore::cacheStorage().setCacheDirectory(WTF::String::fromUTF8(path)); + return EINA_TRUE; +} + +int ewk_view_setting_font_minimum_size_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_minimum_size; +} + +Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object* o, int size) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (priv->settings.font_minimum_size != size) { + priv->page_settings->setMinimumFontSize(size); + priv->settings.font_minimum_size = size; + } + return EINA_TRUE; +} + +int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_minimum_logical_size; +} + +Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object* o, int size) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (priv->settings.font_minimum_logical_size != size) { + priv->page_settings->setMinimumLogicalFontSize(size); + priv->settings.font_minimum_logical_size = size; + } + return EINA_TRUE; +} + +int ewk_view_setting_font_default_size_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_default_size; +} + +Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object* o, int size) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (priv->settings.font_default_size != size) { + priv->page_settings->setDefaultFontSize(size); + priv->settings.font_default_size = size; + } + return EINA_TRUE; +} + +int ewk_view_setting_font_monospace_size_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_monospace_size; +} + +Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object* o, int size) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (priv->settings.font_monospace_size != size) { + priv->page_settings->setDefaultFixedFontSize(size); + priv->settings.font_monospace_size = size; + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_standard_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_standard; +} + +Eina_Bool ewk_view_setting_font_standard_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_standard, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setStandardFontFamily(s); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_cursive_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_cursive; +} + +Eina_Bool ewk_view_setting_font_cursive_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_cursive, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setCursiveFontFamily(s); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_fantasy_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_fantasy; +} + +Eina_Bool ewk_view_setting_font_fantasy_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_fantasy, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setFantasyFontFamily(s); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_monospace_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_monospace; +} + +Eina_Bool ewk_view_setting_font_monospace_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_monospace, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setFixedFontFamily(s); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_serif_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_serif; +} + +Eina_Bool ewk_view_setting_font_serif_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_serif, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setSerifFontFamily(s); + } + return EINA_TRUE; +} + +const char* ewk_view_setting_font_sans_serif_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.font_sans_serif; +} + +Eina_Bool ewk_view_setting_font_sans_serif_set(Evas_Object* o, const char* family) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.font_sans_serif, family)) { + WTF::AtomicString s = WTF::String::fromUTF8(family); + priv->page_settings->setSansSerifFontFamily(s); + } + return EINA_TRUE; +} + +Eina_Bool ewk_view_setting_spatial_navigation_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.spatial_navigation; +} + +Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.spatial_navigation != enable) { + priv->page_settings->setSpatialNavigationEnabled(enable); + priv->settings.spatial_navigation = enable; + } + return EINA_TRUE; +} + +/** + * Gets if the local storage is enabled. + * + * @param o view object to get if local storage is enabled. + * @return @c EINA_TRUE if local storage is enabled, @c EINA_FALSE if not or on errors. + */ +Eina_Bool ewk_view_setting_local_storage_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.local_storage; +} + +/** + * Sets the local storage of HTML5. + * + * @param o view object to set if local storage is enabled. + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure + */ +Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.local_storage != enable) { + priv->page_settings->setLocalStorageEnabled(enable); + priv->settings.local_storage = enable; + } + return EINA_TRUE; +} + +/** + * Gets if the page cache is enabled. + * + * @param o view object to set if page cache is enabled. + * @return @c EINA_TRUE if page cache is enabled, @c EINA_FALSE if not. + */ +Eina_Bool ewk_view_setting_page_cache_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + return priv->settings.page_cache; +} + +/** + * Sets the page cache. + * + * @param o view object to set if page cache is enabled. + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure + */ +Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* o, Eina_Bool enable) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + enable = !!enable; + if (priv->settings.page_cache != enable) { + priv->page_settings->setUsesPageCache(enable); + priv->settings.page_cache = enable; + } + return EINA_TRUE; +} + +/* + * Gets the local storage database path. + * + * @param o view object to get the local storage database path. + * @return the local storage database path. + */ +const char* ewk_view_setting_local_storage_database_path_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->settings.local_storage_database_path; +} + +/** + * Sets the local storage database path. + * + * @param o view object to set the local storage database path. + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure + */ +Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object* o, const char* path) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + if (eina_stringshare_replace(&priv->settings.local_storage_database_path, path)) { + WTF::AtomicString s = WTF::String::fromUTF8(path); + priv->page_settings->setLocalStorageDatabasePath(s); + } + return EINA_TRUE; +} + +/** + * Similar to evas_object_smart_data_get(), but does type checking. + * + * @param o view object to query internal data. + * @return internal data or @c 0 on errors (ie: incorrect type of @a o). + */ +Ewk_View_Smart_Data* ewk_view_smart_data_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + return sd; +} + +/** + * Gets the internal array of repaint requests. + * + * This array should not be modified anyhow. It should be processed + * immediately as any further ewk_view call might change it, like + * those that add repaints or flush them, so be sure that your code + * does not call any of those while you process the repaints, + * otherwise copy the array. + * + * @param priv private handle pointer of the view to get repaints. + * @param count where to return the number of elements of returned array. + * + * @return reference to array of requested repaints. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +const Eina_Rectangle* ewk_view_repaints_get(const Ewk_View_Private_Data* priv, size_t* count) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0); + if (count) + *count = 0; + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0); + if (count) + *count = priv->repaints.count; + return priv->repaints.array; +} + +/** + * Gets the internal array of scroll requests. + * + * This array should not be modified anyhow. It should be processed + * immediately as any further ewk_view call might change it, like + * those that add scrolls or flush them, so be sure that your code + * does not call any of those while you process the scrolls, + * otherwise copy the array. + * + * @param priv private handle pointer of the view to get scrolls. + * @param count where to return the number of elements of returned array. + * + * @return reference to array of requested scrolls. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +const Ewk_Scroll_Request* ewk_view_scroll_requests_get(const Ewk_View_Private_Data* priv, size_t* count) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(count, 0); + if (count) + *count = 0; + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0); + if (count) + *count = priv->scrolls.count; + return priv->scrolls.array; +} + +/** + * Add a new repaint request to queue. + * + * The repaints are assumed to be relative to current viewport. + * + * @param priv private handle pointer of the view to add repaint request. + * @param x horizontal position relative to current view port (scrolled). + * @param y vertical position relative to current view port (scrolled). + * @param w width of area to be repainted + * @param h height of area to be repainted + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_repaint_add(Ewk_View_Private_Data* priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + EINA_SAFETY_ON_NULL_RETURN(priv); + _ewk_view_repaint_add(priv, x, y, w, h); +} + +/** + * Do layout if required, applied recursively. + * + * @param priv private handle pointer of the view to layout. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data* priv) +{ + EINA_SAFETY_ON_NULL_RETURN(priv); + + WebCore::FrameView* v = priv->main_frame->view(); + if (!v) { + ERR("no main frame view"); + return; + } + v->updateLayoutAndStyleIfNeededRecursive(); +} + +void ewk_view_scrolls_process(Ewk_View_Smart_Data* sd) +{ + EINA_SAFETY_ON_NULL_RETURN(sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + if (!sd->api->scrolls_process(sd)) + ERR("failed to process scrolls."); + _ewk_view_scrolls_flush(priv); +} + +struct _Ewk_View_Paint_Context { + WebCore::GraphicsContext* gc; + WebCore::FrameView* view; + cairo_t* cr; +}; + +/** + * Create a new paint context using the view as source and cairo as output. + * + * @param priv private handle pointer of the view to use as paint source. + * @param cr cairo context to use as paint destination. A new + * reference is taken, so it's safe to call cairo_destroy() + * after this function returns. + * + * @return newly allocated instance or @c 0 on errors. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +Ewk_View_Paint_Context* ewk_view_paint_context_new(Ewk_View_Private_Data* priv, cairo_t* cr) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(cr, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(priv->main_frame, 0); + WebCore::FrameView* view = priv->main_frame->view(); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, 0); + Ewk_View_Paint_Context* ctxt = (Ewk_View_Paint_Context*)malloc(sizeof(*ctxt)); + EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, 0); + + ctxt->gc = new WebCore::GraphicsContext(cr); + if (!ctxt->gc) { + free(ctxt); + return 0; + } + ctxt->view = view; + ctxt->cr = cairo_reference(cr); + return ctxt; +} + +/** + * Destroy previously created paint context. + * + * @param ctxt paint context to destroy. Must @b not be @c 0. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_free(Ewk_View_Paint_Context* ctxt) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + delete ctxt->gc; + cairo_destroy(ctxt->cr); + free(ctxt); +} + +/** + * Save (push to stack) paint context status. + * + * @param ctxt paint context to save. Must @b not be @c 0. + * + * @see ewk_view_paint_context_restore() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_save(Ewk_View_Paint_Context* ctxt) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + cairo_save(ctxt->cr); + ctxt->gc->save(); +} + +/** + * Restore (pop from stack) paint context status. + * + * @param ctxt paint context to restore. Must @b not be @c 0. + * + * @see ewk_view_paint_context_save() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_restore(Ewk_View_Paint_Context* ctxt) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + ctxt->gc->restore(); + cairo_restore(ctxt->cr); +} + +/** + * Clip paint context drawings to given area. + * + * @param ctxt paint context to clip. Must @b not be @c 0. + * @param area clip area to use. + * + * @see ewk_view_paint_context_save() + * @see ewk_view_paint_context_restore() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_clip(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + EINA_SAFETY_ON_NULL_RETURN(area); + ctxt->gc->clip(WebCore::IntRect(area->x, area->y, area->w, area->h)); +} + +/** + * Paint using context using given area. + * + * @param ctxt paint context to paint. Must @b not be @c 0. + * @param area paint area to use. Coordinates are relative to current viewport, + * thus "scrolled". + * + * @note one may use cairo functions on the cairo context to + * translate, scale or any modification that may fit his desires. + * + * @see ewk_view_paint_context_clip() + * @see ewk_view_paint_context_paint_contents() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_paint(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + EINA_SAFETY_ON_NULL_RETURN(area); + + WebCore::IntRect rect(area->x, area->y, area->w, area->h); + + if (ctxt->view->isTransparent()) + ctxt->gc->clearRect(rect); + ctxt->view->paint(ctxt->gc, rect); +} + +/** + * Paint just contents using context using given area. + * + * Unlike ewk_view_paint_context_paint(), this function paint just + * bare contents and ignores any scrolling, scrollbars and extras. It + * will walk the rendering tree and paint contents inside the given + * area to the cairo context specified in @a ctxt. + * + * @param ctxt paint context to paint. Must @b not be @c 0. + * @param area paint area to use. Coordinates are absolute to page. + * + * @note one may use cairo functions on the cairo context to + * translate, scale or any modification that may fit his desires. + * + * @see ewk_view_paint_context_clip() + * @see ewk_view_paint_context_paint() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +void ewk_view_paint_context_paint_contents(Ewk_View_Paint_Context* ctxt, const Eina_Rectangle* area) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + EINA_SAFETY_ON_NULL_RETURN(area); + + WebCore::IntRect rect(area->x, area->y, area->w, area->h); + + if (ctxt->view->isTransparent()) + ctxt->gc->clearRect(rect); + + ctxt->view->paintContents(ctxt->gc, rect); +} + +/** + * Scale the contents by the given factors. + * + * This function applies a scaling transformation using Cairo. + * + * @param ctxt paint context to paint. Must @b not be @c 0. + * @param scale_x scale factor for the X dimension. + * @param scale_y scale factor for the Y dimension. + */ +void ewk_view_paint_context_scale(Ewk_View_Paint_Context* ctxt, float scale_x, float scale_y) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + + ctxt->gc->scale(WebCore::FloatSize(scale_x, scale_y)); +} + +/** + * Performs a translation of the origin coordinates. + * + * This function moves the origin coordinates by @p x and @p y pixels. + * + * @param ctxt paint context to paint. Must @b not be @c 0. + * @param x amount of pixels to translate in the X dimension. + * @param y amount of pixels to translate in the Y dimension. + */ +void ewk_view_paint_context_translate(Ewk_View_Paint_Context* ctxt, float x, float y) +{ + EINA_SAFETY_ON_NULL_RETURN(ctxt); + + ctxt->gc->translate(x, y); +} + +/** + * Paint using given graphics context the given area. + * + * This uses viewport relative area and will also handle scrollbars + * and other extra elements. See ewk_view_paint_contents() for the + * alternative function. + * + * @param priv private handle pointer of view to use as paint source. + * @param cr cairo context to use as paint destination. Its state will + * be saved before operation and restored afterwards. + * @param area viewport relative geometry to paint. + * + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like + * incorrect parameters. + * + * @note this is an easy to use version, but internal structures are + * always created, then graphics context is clipped, then + * painted, restored and destroyed. This might not be optimum, + * so using #Ewk_View_Paint_Context may be a better solutions + * for large number of operations. + * + * @see ewk_view_paint_contents() + * @see ewk_view_paint_context_paint() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +Eina_Bool ewk_view_paint(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE); + WebCore::FrameView* view = priv->main_frame->view(); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + if (view->needsLayout()) + view->forceLayout(); + WebCore::GraphicsContext gc(cr); + WebCore::IntRect rect(area->x, area->y, area->w, area->h); + + cairo_save(cr); + gc.save(); + gc.clip(rect); + if (view->isTransparent()) + gc.clearRect(rect); + view->paint(&gc, rect); + gc.restore(); + cairo_restore(cr); + + return EINA_TRUE; +} + +/** + * Paint just contents using given graphics context the given area. + * + * This uses absolute coordinates for area and will just handle + * contents, no scrollbars or extras. See ewk_view_paint() for the + * alternative solution. + * + * @param priv private handle pointer of view to use as paint source. + * @param cr cairo context to use as paint destination. Its state will + * be saved before operation and restored afterwards. + * @param area absolute geometry to paint. + * + * @return @c EINA_TRUE on success and @c EINA_FALSE on failure, like + * incorrect parameters. + * + * @note this is an easy to use version, but internal structures are + * always created, then graphics context is clipped, then + * painted, restored and destroyed. This might not be optimum, + * so using #Ewk_View_Paint_Context may be a better solutions + * for large number of operations. + * + * @see ewk_view_paint() + * @see ewk_view_paint_context_paint_contents() + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data* priv, cairo_t* cr, const Eina_Rectangle* area) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(cr, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(area, EINA_FALSE); + WebCore::FrameView* view = priv->main_frame->view(); + EINA_SAFETY_ON_NULL_RETURN_VAL(view, EINA_FALSE); + + WebCore::GraphicsContext gc(cr); + WebCore::IntRect rect(area->x, area->y, area->w, area->h); + + cairo_save(cr); + gc.save(); + gc.clip(rect); + if (view->isTransparent()) + gc.clearRect(rect); + view->paintContents(&gc, rect); + gc.restore(); + cairo_restore(cr); + + return EINA_TRUE; +} + + +/* internal methods ****************************************************/ +/** + * @internal + * Reports the view is ready to be displayed as all elements are aready. + * + * Emits signal: "ready" with no parameters. + */ +void ewk_view_ready(Evas_Object* o) +{ + DBG("o=%p", o); + evas_object_smart_callback_call(o, "ready", 0); +} + +/** + * @internal + * Reports the state of input method changed. This is triggered, for example + * when a input field received/lost focus + * + * Emits signal: "inputmethod,changed" with a boolean indicating whether it's + * enabled or not. + */ +void ewk_view_input_method_state_set(Evas_Object* o, Eina_Bool active) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + WebCore::Frame* focusedFrame = priv->page->focusController()->focusedOrMainFrame(); + + if (focusedFrame + && focusedFrame->document() + && focusedFrame->document()->focusedNode() + && focusedFrame->document()->focusedNode()->hasTagName(WebCore::HTMLNames::inputTag)) { + WebCore::HTMLInputElement* inputElement; + + inputElement = static_cast<WebCore::HTMLInputElement*>(focusedFrame->document()->focusedNode()); + if (inputElement) { + priv->imh = 0; + // for password fields, active == false + if (!active) { + active = inputElement->isPasswordField(); + priv->imh = inputElement->isPasswordField() * EWK_IMH_PASSWORD; + } else { + // Set input method hints for "number", "tel", "email", and "url" input elements. + priv->imh |= inputElement->isTelephoneField() * EWK_IMH_TELEPHONE; + priv->imh |= inputElement->isNumberField() * EWK_IMH_NUMBER; + priv->imh |= inputElement->isEmailField() * EWK_IMH_EMAIL; + priv->imh |= inputElement->isURLField() * EWK_IMH_URL; + } + } + } + + evas_object_smart_callback_call(o, "inputmethod,changed", (void*)active); +} + +/** + * @internal + * The view title was changed by the frame loader. + * + * Emits signal: "title,changed" with pointer to new title string. + */ +void ewk_view_title_set(Evas_Object* o, const char* title) +{ + DBG("o=%p, title=%s", o, title ? title : "(null)"); + evas_object_smart_callback_call(o, "title,changed", (void*)title); +} + +/** + * @internal + * Reports that main frame's uri changed. + * + * Emits signal: "uri,changed" with pointer to the new uri string. + */ +void ewk_view_uri_changed(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + const char* uri = ewk_frame_uri_get(sd->main_frame); + DBG("o=%p, uri=%s", o, uri ? uri : "(null)"); + evas_object_smart_callback_call(o, "uri,changed", (void*)uri); +} + +/** + * @internal + * Reports the view started loading something. + * + * @param o View. + * + * Emits signal: "load,started" with no parameters. + */ +void ewk_view_load_started(Evas_Object* o) +{ + DBG("o=%p", o); + evas_object_smart_callback_call(o, "load,started", 0); +} + +/** + * Reports the frame started loading something. + * + * @param o View. + * + * Emits signal: "load,started" on main frame with no parameters. + */ +void ewk_view_frame_main_load_started(Evas_Object* o) +{ + DBG("o=%p", o); + Evas_Object* frame = ewk_view_frame_main_get(o); + evas_object_smart_callback_call(frame, "load,started", 0); +} + +/** + * @internal + * Reports the main frame started provisional load. + * + * @param o View. + * + * Emits signal: "load,provisional" on View with no parameters. + */ +void ewk_view_load_provisional(Evas_Object* o) +{ + DBG("o=%p", o); + evas_object_smart_callback_call(o, "load,provisional", 0); +} + +/** + * @internal + * Reports view can be shown after a new window is created. + * + * @param o Frame. + * + * Emits signal: "load,newwindow,show" on view with no parameters. + */ +void ewk_view_load_show(Evas_Object* o) +{ + DBG("o=%p", o); + evas_object_smart_callback_call(o, "load,newwindow,show", 0); +} + + +/** + * @internal + * Reports the main frame was cleared. + * + * @param o View. + */ +void ewk_view_frame_main_cleared(Evas_Object* o) +{ + DBG("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api->flush); + sd->api->flush(sd); +} + +/** + * @internal + * Reports the main frame received an icon. + * + * @param o View. + * + * Emits signal: "icon,received" with no parameters. + */ +void ewk_view_frame_main_icon_received(Evas_Object* o) +{ + DBG("o=%p", o); + Evas_Object* frame = ewk_view_frame_main_get(o); + evas_object_smart_callback_call(frame, "icon,received", 0); +} + +/** + * @internal + * Reports load finished, optionally with error information. + * + * Emits signal: "load,finished" with pointer to #Ewk_Frame_Load_Error + * if any error, or @c 0 if successful load. + * + * @note there should not be any error stuff here, but trying to be + * compatible with previous WebKit. + */ +void ewk_view_load_finished(Evas_Object* o, const Ewk_Frame_Load_Error* error) +{ + DBG("o=%p, error=%p", o, error); + evas_object_smart_callback_call(o, "load,finished", (void*)error); +} + +/** + * @internal + * Reports load failed with error information. + * + * Emits signal: "load,error" with pointer to Ewk_Frame_Load_Error. + */ +void ewk_view_load_error(Evas_Object* o, const Ewk_Frame_Load_Error* error) +{ + DBG("o=%p, error=%p", o, error); + evas_object_smart_callback_call(o, "load,error", (void*)error); +} + +/** + * @internal + * Reports load progress changed. + * + * Emits signal: "load,progress" with pointer to a double from 0.0 to 1.0. + */ +void ewk_view_load_progress_changed(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + + // Evas_Coord w, h; + double progress = priv->page->progress()->estimatedProgress(); + + DBG("o=%p (p=%0.3f)", o, progress); + + evas_object_smart_callback_call(o, "load,progress", &progress); +} + +/** + * @internal + * Reports view @param o should be restored to default conditions + * + * @param o View. + * @param frame Frame that originated restore. + * + * Emits signal: "restore" with frame. + */ +void ewk_view_restore_state(Evas_Object* o, Evas_Object* frame) +{ + evas_object_smart_callback_call(o, "restore", frame); +} + +/** + * @internal + * Delegates to browser the creation of a new window. If it is not implemented, + * current view is returned, so navigation might continue in same window. If + * browser supports the creation of new windows, a new Ewk_Window_Features is + * created and passed to browser. If it intends to keep the request for opening + * the window later it must increments the Ewk_Winwdow_Features ref count by + * calling ewk_window_features_ref(window_features). Otherwise this struct will + * be freed after returning to this function. + * + * @param o Current view. + * @param javascript @c EINA_TRUE if the new window is originated from javascript, + * @c EINA_FALSE otherwise + * @param window_features Features of the new window being created. If it's @c + * NULL, it will be created a window with default features. + * + * @return New view, in case smart class implements the creation of new windows; + * else, current view @param o. + * + * @see ewk_window_features_ref(). + */ +Evas_Object* ewk_view_window_create(Evas_Object* o, Eina_Bool javascript, const WebCore::WindowFeatures* coreFeatures) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + + if (!sd->api->window_create) + return o; + + Ewk_Window_Features* window_features = ewk_window_features_new_from_core(coreFeatures); + Evas_Object* view = sd->api->window_create(sd, javascript, window_features); + ewk_window_features_unref(window_features); + + return view; +} + +/** + * @internal + * Reports a window should be closed. It's client responsibility to decide if + * the window should in fact be closed. So, if only windows created by javascript + * are allowed to be closed by this call, browser needs to save the javascript + * flag when the window is created. Since a window can close itself (for example + * with a 'self.close()' in Javascript) browser must postpone the deletion to an + * idler. + * + * @param o View to be closed. + */ +void ewk_view_window_close(Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + + ewk_view_stop(o); + if (!sd->api->window_close) + return; + sd->api->window_close(sd); +} + +/** + * @internal + * Reports mouse has moved over a link. + * + * Emits signal: "link,hover,in" + */ +void ewk_view_mouse_link_hover_in(Evas_Object* o, void* data) +{ + evas_object_smart_callback_call(o, "link,hover,in", data); +} + +/** + * @internal + * Reports mouse is not over a link anymore. + * + * Emits signal: "link,hover,out" + */ +void ewk_view_mouse_link_hover_out(Evas_Object* o) +{ + evas_object_smart_callback_call(o, "link,hover,out", 0); +} + +/** + * @internal + * Set toolbar visible. + * + * Emits signal: "toolbars,visible,set" with a pointer to a boolean. + */ +void ewk_view_toolbars_visible_set(Evas_Object* o, Eina_Bool visible) +{ + DBG("o=%p (visible=%d)", o, !!visible); + evas_object_smart_callback_call(o, "toolbars,visible,set", &visible); +} + +/** + * @internal + * Get toolbar visibility. + * + * @param o View. + * @param visible boolean pointer in which to save the result. It defaults + * to @c FALSE, i.e. if browser does no listen to emitted signal, it means + * there are no toolbars and therefore they are not visible. + * + * Emits signal: "toolbars,visible,get" with a pointer to a boolean. + */ +void ewk_view_toolbars_visible_get(Evas_Object* o, Eina_Bool* visible) +{ + DBG("%s, o=%p", __func__, o); + *visible = EINA_FALSE; + evas_object_smart_callback_call(o, "toolbars,visible,get", visible); +} + +/** + * @internal + * Set statusbar visible. + * + * @param o View. + * @param visible @c TRUE if statusbar are visible, @c FALSE otherwise. + * + * Emits signal: "statusbar,visible,set" with a pointer to a boolean. + */ +void ewk_view_statusbar_visible_set(Evas_Object* o, Eina_Bool visible) +{ + DBG("o=%p (visible=%d)", o, !!visible); + evas_object_smart_callback_call(o, "statusbar,visible,set", &visible); +} + +/** + * @internal + * Get statusbar visibility. + * + * @param o View. + * @param visible boolean pointer in which to save the result. It defaults + * to @c FALSE, i.e. if browser does no listen to emitted signal, it means + * there is no statusbar and therefore it is not visible. + * + * Emits signal: "statusbar,visible,get" with a pointer to a boolean. + */ +void ewk_view_statusbar_visible_get(Evas_Object* o, Eina_Bool* visible) +{ + DBG("%s, o=%p", __func__, o); + *visible = EINA_FALSE; + evas_object_smart_callback_call(o, "statusbar,visible,get", visible); +} + +/** + * @internal + * Set text of statusbar + * + * @param o View. + * @param text New text to put on statusbar. + * + * Emits signal: "statusbar,text,set" with a string. + */ +void ewk_view_statusbar_text_set(Evas_Object* o, const char* text) +{ + DBG("o=%p (text=%s)", o, text); + INF("status bar text set: %s", text); + evas_object_smart_callback_call(o, "statusbar,text,set", (void *)text); +} + +/** + * @internal + * Set scrollbars visible. + * + * @param o View. + * @param visible @c TRUE if scrollbars are visible, @c FALSE otherwise. + * + * Emits signal: "scrollbars,visible,set" with a pointer to a boolean. + */ +void ewk_view_scrollbars_visible_set(Evas_Object* o, Eina_Bool visible) +{ + DBG("o=%p (visible=%d)", o, !!visible); + evas_object_smart_callback_call(o, "scrollbars,visible,set", &visible); +} + +/** + * @internal + * Get scrollbars visibility. + * + * @param o View. + * @param visible boolean pointer in which to save the result. It defaults + * to @c FALSE, i.e. if browser does no listen to emitted signal, it means + * there are no scrollbars and therefore they are not visible. + * + * Emits signal: "scrollbars,visible,get" with a pointer to a boolean. + */ +void ewk_view_scrollbars_visible_get(Evas_Object* o, Eina_Bool* visible) +{ + DBG("%s, o=%p", __func__, o); + *visible = EINA_FALSE; + evas_object_smart_callback_call(o, "scrollbars,visible,get", visible); +} + +/** + * @internal + * Set menubar visible. + * + * @param o View. + * @param visible @c TRUE if menubar is visible, @c FALSE otherwise. + * + * Emits signal: "menubar,visible,set" with a pointer to a boolean. + */ +void ewk_view_menubar_visible_set(Evas_Object* o, Eina_Bool visible) +{ + DBG("o=%p (visible=%d)", o, !!visible); + evas_object_smart_callback_call(o, "menubar,visible,set", &visible); +} + +/** + * @internal + * Get menubar visibility. + * + * @param o View. + * @param visible boolean pointer in which to save the result. It defaults + * to @c FALSE, i.e. if browser does no listen to emitted signal, it means + * there is no menubar and therefore it is not visible. + * + * Emits signal: "menubar,visible,get" with a pointer to a boolean. + */ +void ewk_view_menubar_visible_get(Evas_Object* o, Eina_Bool* visible) +{ + DBG("%s, o=%p", __func__, o); + *visible = EINA_FALSE; + evas_object_smart_callback_call(o, "menubar,visible,get", visible); +} + +/** + * @internal + * Set tooltip text and display if it is currently hidden. + * + * @param o View. + * @param text Text to set tooltip to. + * + * Emits signal: "tooltip,text,set" with a string. If tooltip must be actually + * removed, text will be 0 or '\0' + */ +void ewk_view_tooltip_text_set(Evas_Object* o, const char* text) +{ + DBG("o=%p text=%s", o, text); + evas_object_smart_callback_call(o, "tooltip,text,set", (void *)text); +} + +/** + * @internal + * + * @param o View. + * @param message String to show on console. + * @param lineNumber Line number. + * @sourceID Source id. + * + */ +void ewk_view_add_console_message(Evas_Object* o, const char* message, unsigned int lineNumber, const char* sourceID) +{ + DBG("o=%p message=%s lineNumber=%u sourceID=%s", o, message, lineNumber, sourceID); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->add_console_message); + sd->api->add_console_message(sd, message, lineNumber, sourceID); +} + +void ewk_view_run_javascript_alert(Evas_Object* o, Evas_Object* frame, const char* message) +{ + DBG("o=%p frame=%p message=%s", o, frame, message); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api); + + if (!sd->api->run_javascript_alert) + return; + + sd->api->run_javascript_alert(sd, frame, message); +} + +Eina_Bool ewk_view_run_javascript_confirm(Evas_Object* o, Evas_Object* frame, const char* message) +{ + DBG("o=%p frame=%p message=%s", o, frame, message); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + + if (!sd->api->run_javascript_confirm) + return EINA_FALSE; + + return sd->api->run_javascript_confirm(sd, frame, message); +} + +Eina_Bool ewk_view_run_javascript_prompt(Evas_Object* o, Evas_Object* frame, const char* message, const char* defaultValue, char** value) +{ + DBG("o=%p frame=%p message=%s", o, frame, message); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + + if (!sd->api->run_javascript_prompt) + return EINA_FALSE; + + return sd->api->run_javascript_prompt(sd, frame, message, defaultValue, value); +} + +/** + * @internal + * Delegates to client to decide whether a script must be stopped because it's + * running for too long. If client does not implement it, it goes to default + * implementation, which logs and returns EINA_FALSE. Client may remove log by + * setting this function 0, which will just return EINA_FALSE. + * + * @param o View. + * + * @return @c EINA_TRUE if script should be stopped; @c EINA_FALSE otherwise + */ +Eina_Bool ewk_view_should_interrupt_javascript(Evas_Object* o) +{ + DBG("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + + if (!sd->api->should_interrupt_javascript) + return EINA_FALSE; + + return sd->api->should_interrupt_javascript(sd); +} + +/** + * @internal + * This is called whenever the web site shown in @param frame is asking to store data + * to the database @param databaseName and the quota allocated to that web site + * is exceeded. Browser may use this to increase the size of quota before the + * originating operationa fails. + * + * @param o View. + * @param frame The frame whose web page exceeded its database quota. + * @param databaseName Database name. + * @param current_size Current size of this database + * @param expected_size The expected size of this database in order to fulfill + * site's requirement. + */ +uint64_t ewk_view_exceeded_database_quota(Evas_Object* o, Evas_Object* frame, const char* databaseName, uint64_t current_size, uint64_t expected_size) +{ + DBG("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, 0); + if (!sd->api->exceeded_database_quota) + return 0; + + INF("current_size=%"PRIu64" expected_size=%"PRIu64, current_size, expected_size); + return sd->api->exceeded_database_quota(sd, frame, databaseName, current_size, expected_size); +} + +/** + * @internal + * Open panel to choose a file. + * + * @param o View. + * @param frame Frame in which operation is required. + * @param allows_multiple_files @c EINA_TRUE when more than one file may be + * selected, @c EINA_FALSE otherwise + * @suggested_filenames List of suggested files to select. It's advisable to + * just ignore this value, since it's a source of security flaw. + * @selected_filenames List of files selected. + * + * @return @EINA_FALSE if user canceled file selection; @EINA_TRUE if confirmed. + */ +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) +{ + DBG("o=%p frame=%p allows_multiple_files=%d", o, frame, allows_multiple_files); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_FALSE); + Eina_Bool confirm; + + if (!sd->api->run_open_panel) + return EINA_FALSE; + + *selected_filenames = 0; + + confirm = sd->api->run_open_panel(sd, frame, allows_multiple_files, suggested_filenames, selected_filenames); + if (!confirm && *selected_filenames) + ERR("Canceled file selection, but selected filenames != 0. Free names before return."); + return confirm; +} + +void ewk_view_repaint(Evas_Object* o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + DBG("o=%p, region=%d,%d + %dx%d", o, x, y, w, h); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + + if (!priv->main_frame->contentRenderer()) { + ERR("no main frame content renderer."); + return; + } + + _ewk_view_repaint_add(priv, x, y, w, h); + _ewk_view_smart_changed(sd); +} + +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) +{ + DBG("o=%p, delta: %d,%d, scroll: %d,%d+%dx%d, clip: %d,%d+%dx%d", + o, dx, dy, sx, sy, sw, sh, cx, cy, cw, ch); + + if ((sx != cx) || (sy != cy) || (sw != cw) || (sh != ch)) + WRN("scroll region and clip are different! %d,%d+%dx%d and %d,%d+%dx%d", + sx, sy, sw, sh, cx, cy, cw, ch); + + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + EINA_SAFETY_ON_TRUE_RETURN(!dx && !dy); + + _ewk_view_scroll_add(priv, dx, dy, sx, sy, sw, sh, main_frame); + + _ewk_view_smart_changed(sd); +} + +WebCore::Page* ewk_view_core_page_get(const Evas_Object* o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + return priv->page; +} + +/** + * Creates a new frame for given url and owner element. + * + * Emits "frame,created" with the new frame object on success. + */ +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) +{ + DBG("o=%p, frame=%p, name=%s, ownerElement=%p, url=%s, referrer=%s", + o, frame, name.utf8().data(), ownerElement, + url.prettyURL().utf8().data(), referrer.utf8().data()); + + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, 0); + + WTF::RefPtr<WebCore::Frame> cf = _ewk_view_core_frame_new + (sd, priv, ownerElement); + if (!cf) { + ERR("Could not create child core frame '%s'", name.utf8().data()); + return 0; + } + + if (!ewk_frame_child_add(frame, cf, name, url, referrer)) { + ERR("Could not create child frame object '%s'", name.utf8().data()); + return 0; + } + + // The creation of the frame may have removed itself already. + if (!cf->page() || !cf->tree() || !cf->tree()->parent()) + return 0; + + sd->changed.frame_rect = EINA_TRUE; + _ewk_view_smart_changed(sd); + + evas_object_smart_callback_call(o, "frame,created", frame); + return cf.release(); +} + +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) +{ + DBG("o=%p, frame=%p, size=%dx%d, element=%p, url=%s, mimeType=%s", + o, frame, pluginSize.width(), pluginSize.height(), element, + url.prettyURL().utf8().data(), mimeType.utf8().data()); + + EWK_VIEW_SD_GET_OR_RETURN(o, sd, 0); + sd->changed.frame_rect = EINA_TRUE; + _ewk_view_smart_changed(sd); + + return ewk_frame_plugin_create + (frame, pluginSize, element, url, paramNames, paramValues, + mimeType, loadManually); +} + + +/** + * @internal + * + * Creates a new popup with options when a select widget was clicked. + * + * @param client PopupMenuClient instance that allows communication with webkit. + * @param selected Selected item. + * @param rect Menu's position. + * + * Emits: "popup,create" with a list of Ewk_Menu containing each item's data + */ +void ewk_view_popup_new(Evas_Object* o, WebCore::PopupMenuClient* client, int selected, const WebCore::IntRect& rect) +{ + INF("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + + if (priv->popup.menu_client) + ewk_view_popup_destroy(o); + + priv->popup.menu_client = client; + + // populate items + const int size = client->listSize(); + for (int i = 0; i < size; ++i) { + Ewk_Menu_Item* item = (Ewk_Menu_Item*) malloc(sizeof(*item)); + if (client->itemIsSeparator(i)) + item->type = EWK_MENU_SEPARATOR; + else if (client->itemIsLabel(i)) + item->type = EWK_MENU_GROUP; + else + item->type = EWK_MENU_OPTION; + item->text = eina_stringshare_add(client->itemText(i).utf8().data()); + + priv->popup.menu.items = eina_list_append(priv->popup.menu.items, item); + } + + priv->popup.menu.x = rect.x(); + priv->popup.menu.y = rect.y(); + priv->popup.menu.width = rect.width(); + priv->popup.menu.height = rect.height(); + evas_object_smart_callback_call(o, "popup,create", &priv->popup.menu); +} + +/** + * Destroy a previously created menu. + * + * Before destroying, it informs client that menu's data is ready to be + * destroyed by sending a "popup,willdelete" with a list of menu items. Then it + * removes any reference to menu inside webkit. It's safe to call this + * function either from inside webkit or from browser. + * + * @param o View. + * + * @returns EINA_TRUE in case menu was successfully destroyed or EINA_TRUE in + * case there wasn't any menu to be destroyed. + */ +Eina_Bool ewk_view_popup_destroy(Evas_Object* o) +{ + INF("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_FALSE); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv, EINA_FALSE); + + if (!priv->popup.menu_client) + return EINA_FALSE; + + evas_object_smart_callback_call(o, "popup,willdelete", &priv->popup.menu); + + void* itemv; + EINA_LIST_FREE(priv->popup.menu.items, itemv) { + Ewk_Menu_Item* item = (Ewk_Menu_Item*)itemv; + eina_stringshare_del(item->text); + free(item); + } + priv->popup.menu_client->popupDidHide(); + priv->popup.menu_client = 0; + + return EINA_TRUE; +} + +/** + * Changes currently selected item. + * + * Changes the option selected in select widget. This is called by browser + * whenever user has chosen a different item. Most likely after calling this, a + * call to ewk_view_popup_destroy might be made in order to close the popup. + * + * @param o View. + * @index Index of selected item. + * + */ +void ewk_view_popup_selected_set(Evas_Object* o, int index) +{ + INF("o=%p", o); + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + EINA_SAFETY_ON_NULL_RETURN(priv->popup.menu_client); + + priv->popup.menu_client->valueChanged(index); +} + +/** + * @internal + * Request a download to user. + * + * @param o View. + * @oaram download Ewk_Download struct to be sent. + * + * Emits: "download,request" with an Ewk_Download containing the details of the + * requested download. The download per se must be handled outside of webkit. + */ +void ewk_view_download_request(Evas_Object* o, Ewk_Download* download) +{ + DBG("view=%p", o); + evas_object_smart_callback_call(o, "download,request", download); +} + +/** + * @internal + * Reports the viewport has changed. + * + * @param arguments viewport argument. + * + * Emits signal: "viewport,changed" with no parameters. + */ +void ewk_view_viewport_attributes_set(Evas_Object *o, const WebCore::ViewportArguments& arguments) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + priv->viewport_arguments = arguments; + evas_object_smart_callback_call(o, "viewport,changed", 0); +} + +/** + * Gets attributes of viewport meta tag. + * + * @param o view. + * @param w width. + * @param h height. + * @param init_scale initial Scale value. + * @param max_scale maximum Scale value. + * @param min_scale minimum Scale value. + * @param device_pixel_ratio value. + * @param user_scalable user Scalable value. + */ +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) +{ + WebCore::ViewportAttributes attributes = _ewk_view_viewport_attributes_compute(o); + + if (w) + *w = attributes.layoutSize.width(); + if (h) + *h = attributes.layoutSize.height(); + if (init_scale) + *init_scale = attributes.initialScale; + if (max_scale) + *max_scale = attributes.maximumScale; + if (min_scale) + *min_scale = attributes.minimumScale; + if (device_pixel_ratio) + *device_pixel_ratio = attributes.devicePixelRatio; + if (user_scalable) + *user_scalable = attributes.userScalable; +} + +/** + * Sets the zoom range. + * + * @param o view. + * @param min_scale minimum value of zoom range. + * @param max_scale maximum value of zoom range. + * + * @return @c EINA_TRUE if zoom range is changed, @c EINA_FALSE if not or failure. + */ +Eina_Bool ewk_view_zoom_range_set(Evas_Object* o, float min_scale, float max_scale) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + if (max_scale < min_scale) { + WRN("min_scale is larger than max_scale"); + return EINA_FALSE; + } + + priv->settings.zoom_range.min_scale = min_scale; + priv->settings.zoom_range.max_scale = max_scale; + + return EINA_TRUE; +} + +/** + * Gets the minimum value of zoom range. + * + * @param o view. + * + * @return minimum value of zoom range. + */ +float ewk_view_zoom_range_min_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + return priv->settings.zoom_range.min_scale; +} + +/** + * Gets the maximum value of zoom range. + * + * @param o view. + * + * @return maximum value of zoom range. + */ +float ewk_view_zoom_range_max_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + return priv->settings.zoom_range.max_scale; +} + +/** + * Sets if zoom is enabled. + * + * @param o view. + * @param user_scalable boolean pointer in which to enable zoom. It defaults + * to @c EINA_TRUE. + */ +void ewk_view_user_scalable_set(Evas_Object* o, Eina_Bool user_scalable) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + priv->settings.zoom_range.user_scalable = user_scalable; +} + +/** + * Gets if zoom is enabled. + * + * @param o view. + * @param user_scalable where to return the current user scalable value. + * + * @return @c EINA_TRUE if zoom is enabled, @c EINA_FALSE if not. + */ +Eina_Bool ewk_view_user_scalable_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + return priv->settings.zoom_range.user_scalable; +} + +/** + * Gets device pixel ratio value. + * + * @param o view. + * @param user_scalable where to return the current user scalable value. + * + * @return @c EINA_TRUE if zoom is enabled, @c EINA_FALSE if not. + */ +float ewk_view_device_pixel_ratio_get(Evas_Object* o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + return priv->settings.device_pixel_ratio; +} + +void ewk_view_did_first_visually_nonempty_layout(Evas_Object *o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + if (!priv->flags.view_cleared) { + ewk_view_frame_main_cleared(o); + ewk_view_enable_render(o); + priv->flags.view_cleared = EINA_TRUE; + } +} + +/** + * @internal + * Dispatch finished loading. + * + * @param o view. + */ +void ewk_view_dispatch_did_finish_loading(Evas_Object *o) +{ + /* If we reach this point and rendering is still disabled, WebCore will not + * trigger the didFirstVisuallyNonEmptyLayout signal anymore. So, we + * forcefully re-enable the rendering. + */ + ewk_view_did_first_visually_nonempty_layout(o); +} + +void ewk_view_transition_to_commited_for_newpage(Evas_Object *o) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EWK_VIEW_PRIV_GET_OR_RETURN(sd, priv); + + ewk_view_disable_render(o); + priv->flags.view_cleared = EINA_FALSE; +} + + +/** + * @internal + * Reports a requeset will be loaded. It's client responsibility to decide if + * request would be used. If @return is true, loader will try to load. Else, + * Loader ignore action of request. + * + * @param o View to load + * @param request Request which contain url to navigate + */ +Eina_Bool ewk_view_navigation_policy_decision(Evas_Object* o, Ewk_Frame_Resource_Request* request) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd, EINA_TRUE); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd->api, EINA_TRUE); + + if (!sd->api->navigation_policy_decision) + return EINA_TRUE; + + return sd->api->navigation_policy_decision(sd, request); +} + +/** + * @internal + * Reports that the contents have resized. The ewk_view calls contents_resize, + * which can be reimplemented as needed. + * + * @param o view. + * @param w new content width. + * @param h new content height. + */ +void ewk_view_contents_size_changed(Evas_Object *o, int w, int h) +{ + EWK_VIEW_SD_GET_OR_RETURN(o, sd); + EINA_SAFETY_ON_NULL_RETURN(sd->api); + EINA_SAFETY_ON_NULL_RETURN(sd->api->contents_resize); + + if (!sd->api->contents_resize(sd, w, h)) + ERR("failed to resize contents to %dx%d", w, h); +} + +/** + * @internal + * Gets page size from frameview. + * + * @param o view. + * + * @return page size. + */ +WebCore::FloatRect ewk_view_page_rect_get(Evas_Object *o) +{ + EWK_VIEW_SD_GET(o, sd); + EWK_VIEW_PRIV_GET(sd, priv); + + WebCore::Frame* main_frame = priv->page->mainFrame(); + return main_frame->view()->frameRect(); +} + +/** + * @internal + * Gets dpi value. + * + * @return device's dpi value. + */ +int ewk_view_dpi_get() +{ +#ifdef HAVE_ECORE_X + return ecore_x_dpi_get(); +#else + return 160; +#endif +} diff --git a/Source/WebKit/efl/ewk/ewk_view.h b/Source/WebKit/efl/ewk/ewk_view.h new file mode 100644 index 0000000..e487f5e --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_view.h @@ -0,0 +1,542 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_view_h +#define ewk_view_h + +#include "ewk_frame.h" +#include "ewk_history.h" +#include "ewk_window_features.h" + +#include <Evas.h> +#include <cairo.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief WebKit main smart object. + * + * This object is the high level access to WebKit-EFL browser + * component. It is responsible for managing the main frame and other + * critical resources. + * + * Every ewk_view has at least one frame, called "main frame" and + * retrieved with ewk_view_frame_main_get(). Direct frame access is + * often discouraged, it is recommended to use ewk_view functions + * instead. + * + * The following signals (see evas_object_smart_callback_add()) are emitted: + * + * - "ready", void: page is fully loaded. + * - "title,changed", const char*: title of the main frame changed. + * - "uri,changed", const char*: uri of the main frame changed. + * - "load,started", void: frame started loading. + * - "load,progress", double*: load progress changed (overall value + * from 0.0 to 1.0, connect to individual frames for fine grained). + * - "load,finished", const Ewk_Frame_Load_Error*: reports load + * finished and as argument @c NULL if successfully or pointer to + * structure defining the error. + * - "load,provisional", void: view started provisional load. + * - "load,error", const Ewk_Frame_Load_Error*: reports load failed + * and as argument a pointer to structure defining the error. + * - "frame,created", Evas_Object*: when frames are created, they are + * emitted in this signal. + * - "zoom,animated,end", void: requested animated zoom is finished. + * - "menubar,visible,set", Eina_Bool: set menubar visibility. + * - "menubar,visible,get", Eina_Bool *: expects a @c EINA_TRUE if menubar is + * visible; otherwise, @c EINA_FALSE. + * - "menubar,visible,set", Eina_Bool: set menubar visibility. + * - "menubar,visible,get", Eina_Bool *: expects a @c EINA_TRUE if menubar is + * visible; @c EINA_FALSE, otherwise. + * - "scrollbars,visible,set", Eina_Bool: set scrollbars visibility. + * - "scrollbars,visible,get", Eina_Bool *: expects a @c EINA_TRUE if scrollbars + * are visible; @c EINA_FALSE, otherwise. + * - "statusbar,visible,set", Eina_Bool: set statusbar visibility. + * - "statusbar,visible,get", Eina_Bool *: expects a @c EINA_TRUE if statusbar is + * visible; @c EINA_FALSE, otherwise. + * - "toolbar,visible,set", Eina_Bool: set toolbar visibility. + * - "toolbar,visible,get", Eina_Bool *: expects a @c EINA_TRUE if toolbar + * is visible; @c EINA_FALSE, otherwise. + * - "link,hover,in", const char *link[2]: reports mouse is over a link and as + * argument gives the url in link[0] and link's title in link[1]. + * - "link,hover,out", const char *link[2]: reports mouse moved out from a link + * and as argument gives the url in link[0] and link's title in link[1]. + * - "popup,create", Ewk_Menu: reports that a new menu was created. + * - "popup,willdeleted", Ewk_Menu: reports that a previously created menu is + * about to be deleted. + * - "download,request", Ewk_Download: reports a download is being requested + * and as arguments gives its details. + * - "icon,received", void: main frame received an icon. + * - "viewport,changed", void: Report that viewport has changed. + * - "inputmethods,changed" with a boolean indicating whether it's enabled or not. + * - "view,resized", void: view object's size has changed. + */ + +typedef struct _Ewk_View_Smart_Data Ewk_View_Smart_Data; + +/** + * Ewk view's class, to be overridden by sub-classes. + */ +typedef struct _Ewk_View_Smart_Class Ewk_View_Smart_Class; +struct _Ewk_View_Smart_Class { + Evas_Smart_Class sc; /**< all but 'data' is free to be changed. */ + unsigned long version; + + Evas_Object *(*window_create)(Ewk_View_Smart_Data *sd, Eina_Bool javascript, const Ewk_Window_Features *window_features); /**< creates a new window, requested by webkit */ + void (*window_close)(Ewk_View_Smart_Data *sd); /**< creates a new window, requested by webkit */ + // hooks to allow different backing stores + Evas_Object *(*backing_store_add)(Ewk_View_Smart_Data *sd); /**< must be defined */ + Eina_Bool (*scrolls_process)(Ewk_View_Smart_Data *sd); /**< must be defined */ + Eina_Bool (*repaints_process)(Ewk_View_Smart_Data *sd); /**< must be defined */ + Eina_Bool (*contents_resize)(Ewk_View_Smart_Data *sd, int w, int h); + Eina_Bool (*zoom_set)(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy); + Eina_Bool (*zoom_weak_set)(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy); + void (*zoom_weak_smooth_scale_set)(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale); + void (*bg_color_set)(Ewk_View_Smart_Data *sd, unsigned char r, unsigned char g, unsigned char b, unsigned char a); + void (*flush)(Ewk_View_Smart_Data *sd); + Eina_Bool (*pre_render_region)(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom); + Eina_Bool (*pre_render_relative_radius)(Ewk_View_Smart_Data *sd, unsigned int n, float zoom); + void (*pre_render_cancel)(Ewk_View_Smart_Data *sd); + Eina_Bool (*disable_render)(Ewk_View_Smart_Data *sd); + Eina_Bool (*enable_render)(Ewk_View_Smart_Data *sd); + + // event handling: + // - returns true if handled + // - if overridden, have to call parent method if desired + Eina_Bool (*focus_in)(Ewk_View_Smart_Data *sd); + Eina_Bool (*focus_out)(Ewk_View_Smart_Data *sd); + Eina_Bool (*mouse_wheel)(Ewk_View_Smart_Data *sd, const Evas_Event_Mouse_Wheel *ev); + Eina_Bool (*mouse_down)(Ewk_View_Smart_Data *sd, const Evas_Event_Mouse_Down *ev); + Eina_Bool (*mouse_up)(Ewk_View_Smart_Data *sd, const Evas_Event_Mouse_Up *ev); + Eina_Bool (*mouse_move)(Ewk_View_Smart_Data *sd, const Evas_Event_Mouse_Move *ev); + Eina_Bool (*key_down)(Ewk_View_Smart_Data *sd, const Evas_Event_Key_Down *ev); + Eina_Bool (*key_up)(Ewk_View_Smart_Data *sd, const Evas_Event_Key_Up *ev); + + void (*add_console_message)(Ewk_View_Smart_Data *sd, const char *message, unsigned int lineNumber, const char *sourceID); + void (*run_javascript_alert)(Ewk_View_Smart_Data *sd, Evas_Object *frame, const char *message); + Eina_Bool (*run_javascript_confirm)(Ewk_View_Smart_Data *sd, Evas_Object *frame, const char *message); + Eina_Bool (*run_javascript_prompt)(Ewk_View_Smart_Data *sd, Evas_Object *frame, const char *message, const char *defaultValue, char **value); + Eina_Bool (*should_interrupt_javascript)(Ewk_View_Smart_Data *sd); + uint64_t (*exceeded_database_quota)(Ewk_View_Smart_Data *sd, Evas_Object *frame, const char *databaseName, uint64_t current_size, uint64_t expected_size); + + Eina_Bool (*run_open_panel)(Ewk_View_Smart_Data *sd, Evas_Object *frame, Eina_Bool allows_multiple_files, const Eina_List *suggested_filenames, Eina_List **selected_filenames); + + Eina_Bool (*navigation_policy_decision)(Ewk_View_Smart_Data *sd, Ewk_Frame_Resource_Request *request); +}; + +#define EWK_VIEW_SMART_CLASS_VERSION 1UL /** the version you have to put into the version field in the Ewk_View_Smart_Class structure */ + +/** + * Initializer for whole Ewk_View_Smart_Class structure. + * + * @param smart_class_init initializer to use for the "base" field + * (Evas_Smart_Class). + * + * @see EWK_VIEW_SMART_CLASS_INIT_NULL + * @see EWK_VIEW_SMART_CLASS_INIT_VERSION + * @see EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION + */ +#define EWK_VIEW_SMART_CLASS_INIT(smart_class_init) {smart_class_init, EWK_VIEW_SMART_CLASS_VERSION, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/** + * Initializer to zero a whole Ewk_View_Smart_Class structure. + * + * @see EWK_VIEW_SMART_CLASS_INIT_VERSION + * @see EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION + * @see EWK_VIEW_SMART_CLASS_INIT + */ +#define EWK_VIEW_SMART_CLASS_INIT_NULL EWK_VIEW_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NULL) + +/** + * Initializer to zero a whole Ewk_View_Smart_Class structure and set version. + * + * Similar to EWK_VIEW_SMART_CLASS_INIT_NULL, but will set version field of + * Evas_Smart_Class (base field) to latest EVAS_SMART_CLASS_VERSION + * + * @see EWK_VIEW_SMART_CLASS_INIT_NULL + * @see EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION + * @see EWK_VIEW_SMART_CLASS_INIT + */ +#define EWK_VIEW_SMART_CLASS_INIT_VERSION EWK_VIEW_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_VERSION) + +/** + * Initializer to zero a whole Ewk_View_Smart_Class structure and set + * name and version. + * + * Similar to EWK_VIEW_SMART_CLASS_INIT_NULL, but will set version field of + * Evas_Smart_Class (base field) to latest EVAS_SMART_CLASS_VERSION and name + * to the specific value. + * + * It will keep a reference to name field as a "const char *", that is, + * name must be available while the structure is used (hint: static or global!) + * and will not be modified. + * + * @see EWK_VIEW_SMART_CLASS_INIT_NULL + * @see EWK_VIEW_SMART_CLASS_INIT_VERSION + * @see EWK_VIEW_SMART_CLASS_INIT + */ +#define EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION(name) EWK_VIEW_SMART_CLASS_INIT(EVAS_SMART_CLASS_INIT_NAME_VERSION(name)) + +enum _Ewk_Imh { + EWK_IMH_TELEPHONE = (1 << 0), + EWK_IMH_NUMBER = (1 << 1), + EWK_IMH_EMAIL = (1 << 2), + EWK_IMH_URL = (1 << 3), + EWK_IMH_PASSWORD = (1 << 4) +}; +typedef enum _Ewk_Imh Ewk_Imh; + +/** + * @internal + * + * private data that is used internally by EFL WebKit and should never + * be modified from outside. + */ +typedef struct _Ewk_View_Private_Data Ewk_View_Private_Data; + +enum _Ewk_Menu_Item_Type { + EWK_MENU_SEPARATOR, + EWK_MENU_GROUP, + EWK_MENU_OPTION +}; +typedef enum _Ewk_Menu_Item_Type Ewk_Menu_Item_Type; + + +/** + * Structure do contain data of each menu item + */ +typedef struct _Ewk_Menu_Item Ewk_Menu_Item; +struct _Ewk_Menu_Item { + const char *text; /**< Item's text */ + Ewk_Menu_Item_Type type; /** Item's type */ +}; + +/** + * Structure to contain Popup menu data. + */ +typedef struct _Ewk_Menu Ewk_Menu; +struct _Ewk_Menu { + Eina_List* items; + int x; + int y; + int width; + int height; +}; + +/** + * Structure to contain Download data + */ +typedef struct _Ewk_Download Ewk_Download; +struct _Ewk_Download { + const char* url; + /* to be extended */ +}; + +/** + * Scroll request that should be processed by subclass implementations. + */ +typedef struct _Ewk_Scroll_Request Ewk_Scroll_Request; +struct _Ewk_Scroll_Request { + Evas_Coord dx, dy; + Evas_Coord x, y, w, h, x2, y2; + Eina_Bool main_scroll; +}; + +/** + * Structure to contain internal View data, it is to be considered + * private by users, but may be extended or changed by sub-classes + * (that's why it's in public header file). + */ +struct _Ewk_View_Smart_Data { + Evas_Object_Smart_Clipped_Data base; + const Ewk_View_Smart_Class *api; /**< reference to casted class instance */ + Evas_Object *self; /**< reference to owner object */ + Evas_Object *main_frame; /**< reference to main frame object */ + Evas_Object *backing_store; /**< reference to backing store */ + Evas_Object *events_rect; /**< rectangle that should receive mouse events */ + Ewk_View_Private_Data *_priv; /**< should never be accessed, c++ stuff */ + struct { + Evas_Coord x, y, w, h; /**< last used viewport */ + } view; + struct { + struct { + float start; + float end; + float current; /**< if > 0.0, then doing animated zoom. */ + } zoom; + } animated_zoom; + struct { + unsigned char r, g, b, a; + } bg_color; + Eina_Bool zoom_weak_smooth_scale:1; + struct { /**< what changed since last smart_calculate */ + Eina_Bool any:1; + Eina_Bool size:1; + Eina_Bool position:1; + Eina_Bool frame_rect:1; + } changed; +}; + +/** + * Cache (pool) that contains unused tiles for ewk_view_tiled. + * + * This cache will maintain unused tiles and flush them when the total + * memory exceeds the set amount when + * ewk_tile_unused_cache_auto_flush() or explicitly set value when + * ewk_tile_unused_cache_flush() is called. + * + * The tile may be shared among different ewk_view_tiled instances to + * group maximum unused memory resident in the system. + */ +typedef struct _Ewk_Tile_Unused_Cache Ewk_Tile_Unused_Cache; +EAPI void ewk_tile_unused_cache_max_set(Ewk_Tile_Unused_Cache *tuc, size_t max); +EAPI size_t ewk_tile_unused_cache_max_get(const Ewk_Tile_Unused_Cache *tuc); +EAPI size_t ewk_tile_unused_cache_used_get(const Ewk_Tile_Unused_Cache *tuc); +EAPI size_t ewk_tile_unused_cache_flush(Ewk_Tile_Unused_Cache *tuc, size_t bytes); +EAPI void ewk_tile_unused_cache_auto_flush(Ewk_Tile_Unused_Cache *tuc); + +EAPI Eina_Bool ewk_view_base_smart_set(Ewk_View_Smart_Class *api); +EAPI Eina_Bool ewk_view_single_smart_set(Ewk_View_Smart_Class *api); +EAPI Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class *api); + +EAPI Evas_Object *ewk_view_single_add(Evas *e); +EAPI Evas_Object *ewk_view_tiled_add(Evas *e); + +EAPI Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o); +EAPI void ewk_view_tiled_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *cache); + +// FIXME: this function should be removed later, when we find the best flag to use. +EAPI void ewk_view_tiled_process_entire_queue_set(Evas_Object *o, Eina_Bool flag); + +EAPI void ewk_view_fixed_layout_size_set(Evas_Object *o, Evas_Coord w, Evas_Coord h); +EAPI void ewk_view_fixed_layout_size_get(Evas_Object *o, Evas_Coord *w, Evas_Coord *h); + +EAPI void ewk_view_theme_set(Evas_Object *o, const char *path); +EAPI const char *ewk_view_theme_get(Evas_Object *o); + +EAPI Evas_Object *ewk_view_frame_main_get(const Evas_Object *o); +EAPI Evas_Object *ewk_view_frame_focused_get(const Evas_Object *o); + +EAPI Eina_Bool ewk_view_uri_set(Evas_Object *o, const char *uri); +EAPI const char *ewk_view_uri_get(const Evas_Object *o); +EAPI const char *ewk_view_title_get(const Evas_Object *o); + +EAPI Eina_Bool ewk_view_editable_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_editable_set(Evas_Object *o, Eina_Bool editable); + +EAPI void ewk_view_bg_color_set(Evas_Object *o, int r, int g, int b, int a); +EAPI void ewk_view_bg_color_get(const Evas_Object *o, int *r, int *g, int *b, int *a); + +EAPI char *ewk_view_selection_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_select_none(Evas_Object *o); +EAPI Eina_Bool ewk_view_select_all(Evas_Object *o); +EAPI Eina_Bool ewk_view_select_paragraph(Evas_Object *o); +EAPI Eina_Bool ewk_view_select_sentence(Evas_Object *o); +EAPI Eina_Bool ewk_view_select_line(Evas_Object *o); +EAPI Eina_Bool ewk_view_select_word(Evas_Object *o); + +EAPI Eina_Bool ewk_view_context_menu_forward_event(Evas_Object *o, const Evas_Event_Mouse_Down *ev); + +EAPI void ewk_view_popup_selected_set(Evas_Object *o, int index); +EAPI Eina_Bool ewk_view_popup_destroy(Evas_Object *o); + +EAPI Eina_Bool ewk_view_text_search(const Evas_Object *o, const char *string, Eina_Bool case_sensitive, Eina_Bool forward, Eina_Bool wrap); + +EAPI unsigned int ewk_view_text_matches_mark(Evas_Object *o, const char *string, Eina_Bool case_sensitive, Eina_Bool highlight, unsigned int limit); +EAPI Eina_Bool ewk_view_text_matches_unmark_all(Evas_Object *o); +EAPI Eina_Bool ewk_view_text_matches_highlight_set(Evas_Object *o, Eina_Bool highlight); +EAPI Eina_Bool ewk_view_text_matches_highlight_get(const Evas_Object *o); + +EAPI double ewk_view_load_progress_get(const Evas_Object *o); + +EAPI Eina_Bool ewk_view_stop(Evas_Object *o); +EAPI Eina_Bool ewk_view_reload(Evas_Object *o); +EAPI Eina_Bool ewk_view_reload_full(Evas_Object *o); + +EAPI Eina_Bool ewk_view_back(Evas_Object *o); +EAPI Eina_Bool ewk_view_forward(Evas_Object *o); +EAPI Eina_Bool ewk_view_navigate(Evas_Object *o, int steps); + +EAPI Eina_Bool ewk_view_back_possible(Evas_Object *o); +EAPI Eina_Bool ewk_view_forward_possible(Evas_Object *o); +EAPI Eina_Bool ewk_view_navigate_possible(Evas_Object *o, int steps); + +EAPI Eina_Bool ewk_view_history_enable_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_history_enable_set(Evas_Object *o, Eina_Bool enable); +EAPI Ewk_History *ewk_view_history_get(const Evas_Object *o); + +EAPI float ewk_view_zoom_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_zoom_set(Evas_Object *o, float zoom, Evas_Coord cx, Evas_Coord cy); + +EAPI Eina_Bool ewk_view_zoom_weak_smooth_scale_get(const Evas_Object *o); +EAPI void ewk_view_zoom_weak_smooth_scale_set(Evas_Object *o, Eina_Bool smooth_scale); + +EAPI Eina_Bool ewk_view_zoom_weak_set(Evas_Object *o, float zoom, Evas_Coord cx, Evas_Coord cy); +EAPI Eina_Bool ewk_view_zoom_animated_mark_start(Evas_Object *o, float zoom); +EAPI Eina_Bool ewk_view_zoom_animated_mark_end(Evas_Object *o, float zoom); +EAPI Eina_Bool ewk_view_zoom_animated_mark_current(Evas_Object *o, float zoom); +EAPI Eina_Bool ewk_view_zoom_animated_mark_stop(Evas_Object *o); + +EAPI Eina_Bool ewk_view_zoom_animated_set(Evas_Object *o, float zoom, float duration, Evas_Coord cx, Evas_Coord cy); +EAPI Eina_Bool ewk_view_zoom_text_only_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_zoom_text_only_set(Evas_Object *o, Eina_Bool setting); + +EAPI Eina_Bool ewk_view_pre_render_region(Evas_Object *o, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom); +EAPI Eina_Bool ewk_view_pre_render_relative_radius(Evas_Object *o, unsigned int n); +EAPI void ewk_view_pre_render_cancel(Evas_Object *o); +EAPI Eina_Bool ewk_view_enable_render(const Evas_Object *o); +EAPI Eina_Bool ewk_view_disable_render(const Evas_Object *o); + +EAPI unsigned int ewk_view_imh_get(Evas_Object *o); + +/* settings */ +EAPI const char *ewk_view_setting_user_agent_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_user_agent_set(Evas_Object *o, const char *user_agent); + +EAPI Eina_Bool ewk_view_setting_auto_load_images_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_auto_load_images_set(Evas_Object *o, Eina_Bool automatic); + +EAPI Eina_Bool ewk_view_setting_auto_shrink_images_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_auto_shrink_images_set(Evas_Object *o, Eina_Bool automatic); + +EAPI Eina_Bool ewk_view_setting_enable_auto_resize_window_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_enable_auto_resize_window_set(Evas_Object *o, Eina_Bool resizable); +EAPI Eina_Bool ewk_view_setting_enable_scripts_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_enable_scripts_set(Evas_Object *o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_enable_plugins_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_enable_plugins_set(Evas_Object *o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_enable_frame_flattening_get(const Evas_Object* o); +EAPI Eina_Bool ewk_view_setting_enable_frame_flattening_set(Evas_Object* o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_scripts_window_open_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_scripts_window_open_set(Evas_Object *o, Eina_Bool allow); + +EAPI Eina_Bool ewk_view_setting_resizable_textareas_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_resizable_textareas_set(Evas_Object *o, Eina_Bool enable); + +EAPI const char *ewk_view_setting_user_stylesheet_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_user_stylesheet_set(Evas_Object *o, const char *uri); + +EAPI Eina_Bool ewk_view_setting_private_browsing_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_private_browsing_set(Evas_Object *o, Eina_Bool enable); +EAPI Eina_Bool ewk_view_setting_offline_app_cache_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_offline_app_cache_set(Evas_Object *o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_caret_browsing_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_caret_browsing_set(Evas_Object *o, Eina_Bool enable); + +EAPI const char *ewk_view_setting_encoding_custom_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_encoding_custom_set(Evas_Object *o, const char *encoding); +EAPI const char *ewk_view_setting_encoding_default_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_encoding_default_set(Evas_Object *o, const char *encoding); +EAPI const char *ewk_view_setting_cache_directory_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_cache_directory_set(Evas_Object *o, const char *path); + +EAPI int ewk_view_setting_font_minimum_size_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_minimum_size_set(Evas_Object *o, int size); +EAPI int ewk_view_setting_font_minimum_logical_size_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_minimum_logical_size_set(Evas_Object *o, int size); +EAPI int ewk_view_setting_font_default_size_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_default_size_set(Evas_Object *o, int size); +EAPI int ewk_view_setting_font_monospace_size_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_monospace_size_set(Evas_Object *o, int size); + +EAPI const char *ewk_view_setting_font_standard_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_standard_set(Evas_Object *o, const char *family); + +EAPI const char *ewk_view_setting_font_cursive_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_cursive_set(Evas_Object *o, const char *family); + +EAPI const char *ewk_view_setting_font_monospace_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_monospace_set(Evas_Object *o, const char *family); + +EAPI const char *ewk_view_setting_font_fantasy_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_fantasy_set(Evas_Object *o, const char *family); + +EAPI const char *ewk_view_setting_font_serif_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_serif_set(Evas_Object *o, const char *family); + +EAPI const char *ewk_view_setting_font_sans_serif_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_font_sans_serif_set(Evas_Object *o, const char *family); + +EAPI Eina_Bool ewk_view_setting_spatial_navigation_get(Evas_Object* o); +EAPI Eina_Bool ewk_view_setting_spatial_navigation_set(Evas_Object* o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_local_storage_get(Evas_Object* o); +EAPI Eina_Bool ewk_view_setting_local_storage_set(Evas_Object* o, Eina_Bool enable); +EAPI const char *ewk_view_setting_local_storage_database_path_get(const Evas_Object *o); +EAPI Eina_Bool ewk_view_setting_local_storage_database_path_set(Evas_Object *o, const char *path); + +EAPI Eina_Bool ewk_view_setting_page_cache_get(Evas_Object* o); +EAPI Eina_Bool ewk_view_setting_page_cache_set(Evas_Object* o, Eina_Bool enable); + +EAPI Eina_Bool ewk_view_setting_encoding_detector_get(Evas_Object* o); +EAPI Eina_Bool ewk_view_setting_encoding_detector_set(Evas_Object* o, Eina_Bool enable); + +/* to be used by subclass implementations */ +EAPI Ewk_View_Smart_Data *ewk_view_smart_data_get(const Evas_Object *o); + +EAPI const Eina_Rectangle *ewk_view_repaints_get(const Ewk_View_Private_Data *priv, size_t *count); +EAPI const Ewk_Scroll_Request *ewk_view_scroll_requests_get(const Ewk_View_Private_Data *priv, size_t *count); + +EAPI void ewk_view_repaint_add(Ewk_View_Private_Data *priv, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); + +EAPI void ewk_view_layout_if_needed_recursive(Ewk_View_Private_Data *priv); + +EAPI void ewk_view_scrolls_process(Ewk_View_Smart_Data *sd); + +/** + * Structure that keeps paint context. + * + * @note this is not for general use but just for subclasses that want + * to define their own backing store. + */ +typedef struct _Ewk_View_Paint_Context Ewk_View_Paint_Context; + +EAPI Ewk_View_Paint_Context *ewk_view_paint_context_new(Ewk_View_Private_Data *priv, cairo_t *cr); +EAPI void ewk_view_paint_context_free(Ewk_View_Paint_Context *ctxt); + +EAPI void ewk_view_paint_context_save(Ewk_View_Paint_Context *ctxt); +EAPI void ewk_view_paint_context_restore(Ewk_View_Paint_Context *ctxt); +EAPI void ewk_view_paint_context_clip(Ewk_View_Paint_Context *ctxt, const Eina_Rectangle *area); +EAPI void ewk_view_paint_context_paint(Ewk_View_Paint_Context *ctxt, const Eina_Rectangle *area); +EAPI void ewk_view_paint_context_paint_contents(Ewk_View_Paint_Context *ctxt, const Eina_Rectangle *area); +EAPI void ewk_view_paint_context_scale(Ewk_View_Paint_Context *ctxt, float scale_x, float scale_y); +EAPI void ewk_view_paint_context_translate(Ewk_View_Paint_Context *ctxt, float x, float y); + +EAPI Eina_Bool ewk_view_paint(Ewk_View_Private_Data *priv, cairo_t *cr, const Eina_Rectangle *area); +EAPI Eina_Bool ewk_view_paint_contents(Ewk_View_Private_Data *priv, cairo_t *cr, const Eina_Rectangle *area); + +EAPI 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); +EAPI Eina_Bool ewk_view_zoom_range_set(Evas_Object* o, float min_scale, float max_scale); +EAPI float ewk_view_zoom_range_min_get(Evas_Object* o); +EAPI float ewk_view_zoom_range_max_get(Evas_Object* o); +EAPI void ewk_view_user_scalable_set(Evas_Object* o, Eina_Bool user_scalable); +EAPI Eina_Bool ewk_view_user_scalable_get(Evas_Object* o); +EAPI float ewk_view_device_pixel_ratio_get(Evas_Object* o); + +#ifdef __cplusplus +} +#endif +#endif // ewk_view_h diff --git a/Source/WebKit/efl/ewk/ewk_view_single.c b/Source/WebKit/efl/ewk/ewk_view_single.c new file mode 100644 index 0000000..6d965d0 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_view_single.c @@ -0,0 +1,599 @@ +/* + Copyright (C) 2009-2010 ProFUSION embedded systems + Copyright (C) 2009-2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_view.h" + +#include "ewk_frame.h" +#include "ewk_logging.h" + +#include <Evas.h> +#include <eina_safety_checks.h> +#include <string.h> + +static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL; + +static void _ewk_view_single_on_del(void *data, Evas *e, Evas_Object *o, void *event_info) +{ + Evas_Object *clip = (Evas_Object*)data; + evas_object_del(clip); +} + +static void _ewk_view_single_smart_add(Evas_Object *o) +{ + Ewk_View_Smart_Data *sd; + + _parent_sc.sc.add(o); + + sd = (Ewk_View_Smart_Data *)evas_object_smart_data_get(o); + + Evas_Object *clip = evas_object_rectangle_add(sd->base.evas); + evas_object_clip_set(sd->backing_store, clip); + evas_object_smart_member_add(clip, o); + evas_object_show(clip); + + evas_object_event_callback_add + (sd->backing_store, EVAS_CALLBACK_DEL, _ewk_view_single_on_del, clip); +} + +static Evas_Object *_ewk_view_single_smart_backing_store_add(Ewk_View_Smart_Data *sd) +{ + Evas_Object *bs = evas_object_image_add(sd->base.evas); + evas_object_image_alpha_set(bs, EINA_FALSE); + evas_object_image_smooth_scale_set(bs, sd->zoom_weak_smooth_scale); + + return bs; +} + +static void _ewk_view_single_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h) +{ + Ewk_View_Smart_Data *sd = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o); + _parent_sc.sc.resize(o, w, h); + + // these should be queued and processed in calculate as well! + evas_object_image_size_set(sd->backing_store, w, h); + if (sd->animated_zoom.zoom.current < 0.00001) { + Evas_Object *clip = evas_object_clip_get(sd->backing_store); + Evas_Coord x, y, cw, ch; + evas_object_image_fill_set(sd->backing_store, 0, 0, w, h); + evas_object_geometry_get(sd->backing_store, &x, &y, 0, 0); + evas_object_move(clip, x, y); + ewk_frame_contents_size_get(sd->main_frame, &cw, &ch); + if (w > cw) + w = cw; + if (h > ch) + h = ch; + evas_object_resize(clip, w, h); + } +} + +static inline void _ewk_view_4b_move_region_up(uint32_t *image, size_t rows, size_t x, size_t y, size_t w, size_t h, size_t rowsize) +{ + uint32_t *src; + uint32_t *dst; + + dst = image + x + y * rowsize; + src = dst + rows * rowsize; + h -= rows; + + for (; h > 0; h--, dst += rowsize, src += rowsize) + memcpy(dst, src, w * 4); +} + +static inline void _ewk_view_4b_move_region_down(uint32_t *image, size_t rows, size_t x, size_t y, size_t w, size_t h, size_t rowsize) +{ + uint32_t *src; + uint32_t *dst; + + h -= rows; + src = image + x + (y + h - 1) * rowsize; + dst = src + rows * rowsize; + + for (; h > 0; h--, dst -= rowsize, src -= rowsize) + memcpy(dst, src, w * 4); +} + +static inline void _ewk_view_4b_move_line_left(uint32_t *dst, const uint32_t *src, size_t count) +{ + uint32_t *dst_end = dst + count; + /* no memcpy() as it does not allow overlapping regions */ + /* no memmove() as it will copy to a temporary buffer */ + /* TODO: loop unrolling, copying up to quad-words would help */ + for (; dst < dst_end; dst++, src++) + *dst = *src; +} + +static inline void _ewk_view_4b_move_line_right(uint32_t *dst, uint32_t *src, size_t count) +{ + uint32_t *dst_end = dst - count; + /* no memcpy() as it does not allow overlapping regions */ + /* no memmove() as it will copy to a temporary buffer */ + /* TODO: loop unrolling, copying up to quad-words would help */ + for (; dst > dst_end; dst--, src--) + *dst = *src; +} + +static inline void _ewk_view_4b_move_region_left(uint32_t *image, size_t cols, size_t x, size_t y, size_t w, size_t h, size_t rowsize) +{ + uint32_t *src; + uint32_t *dst; + + dst = image + x + y * rowsize; + src = dst + cols; + w -= cols; + + for (; h > 0; h--, dst += rowsize, src += rowsize) + _ewk_view_4b_move_line_left(dst, src, w); +} + +static inline void _ewk_view_4b_move_region_right(uint32_t *image, size_t cols, size_t x, size_t y, size_t w, size_t h, size_t rowsize) +{ + uint32_t *src; + uint32_t *dst; + + w -= cols; + src = image + (x + w - 1) + y * rowsize; + dst = src + cols; + + for (; h > 0; h--, dst += rowsize, src += rowsize) + _ewk_view_4b_move_line_right(dst, src, w); +} + +/* catch-all function, not as optimized as the others, but does the work. */ +static inline void _ewk_view_4b_move_region(uint32_t *image, int dx, int dy, size_t x, size_t y, size_t w, size_t h, size_t rowsize) +{ + uint32_t *src; + uint32_t *dst; + + if (dy < 0) { + h += dy; + dst = image + x + y * rowsize; + src = dst - dy * rowsize; + if (dx <= 0) { + w += dx; + src -= dx; + for (; h > 0; h--, dst += rowsize, src += rowsize) + _ewk_view_4b_move_line_left(dst, src, w); + } else { + w -= dx; + src += w - 1; + dst += w + dx -1; + for (; h > 0; h--, dst += rowsize, src += rowsize) + _ewk_view_4b_move_line_right(dst, src, w); + } + } else { + h -= dy; + src = image + x + (y + h - 1) * rowsize; + dst = src + dy * rowsize; + if (dx <= 0) { + w += dx; + src -= dx; + for (; h > 0; h--, dst -= rowsize, src -= rowsize) + _ewk_view_4b_move_line_left(dst, src, w); + } else { + w -= dx; + src += w - 1; + dst += w + dx - 1; + for (; h > 0; h--, dst -= rowsize, src -= rowsize) + _ewk_view_4b_move_line_right(dst, src, w); + } + } +} + +static inline void _ewk_view_single_scroll_process_single(Ewk_View_Smart_Data *sd, void *pixels, Evas_Coord ow, Evas_Coord oh, const Ewk_Scroll_Request *sr) +{ + Evas_Coord sx, sy, sw, sh; + + DBG("%d,%d + %d,%d %+03d,%+03d, store: %p %dx%d", + sr->x, sr->y, sr->w, sr->h, sr->dx, sr->dy, pixels, ow, oh); + + sx = sr->x; + sy = sr->y; + sw = sr->w; + sh = sr->h; + + if (abs(sr->dx) >= sw || abs(sr->dy) >= sh) { + /* doubt webkit would be so stupid... */ + DBG("full page scroll %+03d,%+03d. convert to repaint %d,%d + %dx%d", + sr->dx, sr->dy, sx, sy, sw, sh); + ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh); + return; + } + + if (sx < 0) { + sw += sx; + sx = 0; + } + if (sy < 0) { + sh += sy; + sy = 0; + } + + if (sx + sw > ow) + sw = ow - sx; + if (sy + sh > oh) + sh = oh - sy; + + if (sw < 0) + sw = 0; + if (sh < 0) + sh = 0; + + EINA_SAFETY_ON_TRUE_RETURN(!sw || !sh); + if (!sr->dx) { + if (sr->dy < 0) { + DBG("scroll up: %+03d,%+03d update=%d,%d+%dx%d, " + "repaint=%d,%d+%dx%d", + sr->dx, sr->dy, sx, sy, sw, sh + sr->dy, + sx, sy + sh + sr->dy, sw, -sr->dy); + + _ewk_view_4b_move_region_up + ((uint32_t*)pixels, -sr->dy, sx, sy, sw, sh, ow); + evas_object_image_data_update_add + (sd->backing_store, sx, sy, sw, sh + sr->dy); + + ewk_view_repaint_add(sd->_priv, sx, sy + sh + sr->dy, sw, -sr->dy); + } else if (sr->dy > 0) { + DBG("scroll down: %+03d,%+03d update=%d,%d+%dx%d, " + "repaint=%d,%d+%dx%d", + sr->dx, sr->dy, sx, sy + sr->dy, sw, sh - sr->dy, + sx, sy, sw, sr->dy); + + _ewk_view_4b_move_region_down + ((uint32_t*)pixels, sr->dy, sx, sy, sw, sh, ow); + evas_object_image_data_update_add + (sd->backing_store, sx, sy + sr->dy, sw, sh - sr->dy); + + ewk_view_repaint_add(sd->_priv, sx, sy, sw, sr->dy); + } + } else if (!sr->dy) { + if (sr->dx < 0) { + DBG("scroll left: %+03d,%+03d update=%d,%d+%dx%d, " + "repaint=%d,%d+%dx%d", + sr->dx, sr->dy, sx, sy, sw + sr->dx, sh, + sx + sw + sr->dx, sy, -sr->dx, sh); + + _ewk_view_4b_move_region_left + ((uint32_t*)pixels, -sr->dx, sx, sy, sw, sh, ow); + evas_object_image_data_update_add + (sd->backing_store, sx, sy, sw + sr->dx, sh); + + ewk_view_repaint_add(sd->_priv, sx + sw + sr->dx, sy, -sr->dx, sh); + } else if (sr->dx > 0) { + DBG("scroll up: %+03d,%+03d update=%d,%d+%dx%d, " + "repaint=%d,%d+%dx%d", + sr->dx, sr->dy, sx + sr->dx, sy, sw - sr->dx, sh, + sx, sy, sr->dx, sh); + + _ewk_view_4b_move_region_right + ((uint32_t*)pixels, sr->dx, sx, sy, sw, sh, ow); + evas_object_image_data_update_add + (sd->backing_store, sx + sr->dx, sy, sw - sr->dx, sh); + + ewk_view_repaint_add(sd->_priv, sx, sy, sr->dx, sh); + } + } else { + Evas_Coord mx, my, mw, mh, ax, ay, aw, ah, bx, by, bw, bh; + + if (sr->dx < 0) { + mx = sx; + mw = sw + sr->dx; + ax = mx + mw; + aw = -sr->dx; + } else { + ax = sx; + aw = sr->dx; + mx = ax + aw; + mw = sw - sr->dx; + } + + if (sr->dy < 0) { + my = sy; + mh = sh + sr->dy; + by = my + mh; + bh = -sr->dy; + } else { + by = sy; + bh = sr->dy; + my = by + bh; + mh = sh - sr->dy; + } + + ay = my; + ah = mh; + bx = sx; + bw = sw; + + DBG("scroll diagonal: %+03d,%+03d update=%d,%d+%dx%d, " + "repaints: h=%d,%d+%dx%d v=%d,%d+%dx%d", + sr->dx, sr->dy, mx, my, mw, mh, ax, ay, aw, ah, bx, by, bw, bh); + + _ewk_view_4b_move_region + ((uint32_t*)pixels, sr->dx, sr->dy, sx, sy, sw, sh, ow); + + evas_object_image_data_update_add(sd->backing_store, mx, my, mw, mh); + ewk_view_repaint_add(sd->_priv, ax, ay, aw, ah); + ewk_view_repaint_add(sd->_priv, bx, by, bw, bh); + } +} + +static Eina_Bool _ewk_view_single_smart_scrolls_process(Ewk_View_Smart_Data *sd) +{ + const Ewk_Scroll_Request *sr; + const Ewk_Scroll_Request *sr_end; + Evas_Coord ow, oh; + size_t count; + void *pixels = evas_object_image_data_get(sd->backing_store, 1); + evas_object_image_size_get(sd->backing_store, &ow, &oh); + + sr = ewk_view_scroll_requests_get(sd->_priv, &count); + sr_end = sr + count; + for (; sr < sr_end; sr++) + _ewk_view_single_scroll_process_single(sd, pixels, ow, oh, sr); + + evas_object_image_data_set(sd->backing_store, pixels); + + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_single_smart_repaints_process(Ewk_View_Smart_Data *sd) +{ + Ewk_View_Paint_Context *ctxt; + Evas_Coord ow, oh; + void *pixels; + Eina_Rectangle *r; + const Eina_Rectangle *pr; + const Eina_Rectangle *pr_end; + Eina_Tiler *tiler; + Eina_Iterator *itr; + cairo_status_t status; + cairo_surface_t *surface; + cairo_format_t format; + cairo_t *cairo; + size_t count; + Eina_Bool ret = EINA_TRUE; + + if (sd->animated_zoom.zoom.current < 0.00001) { + Evas_Object *clip = evas_object_clip_get(sd->backing_store); + Evas_Coord w, h, cw, ch; + // reset effects of zoom_weak_set() + evas_object_image_fill_set + (sd->backing_store, 0, 0, sd->view.w, sd->view.h); + evas_object_move(clip, sd->view.x, sd->view.y); + + w = sd->view.w; + h = sd->view.h; + + ewk_frame_contents_size_get(sd->main_frame, &cw, &ch); + if (w > cw) + w = cw; + if (h > ch) + h = ch; + evas_object_resize(clip, w, h); + } + + pixels = evas_object_image_data_get(sd->backing_store, 1); + evas_object_image_size_get(sd->backing_store, &ow, &oh); + + if (sd->bg_color.a < 255) + format = CAIRO_FORMAT_ARGB32; + else + format = CAIRO_FORMAT_RGB24; + + surface = cairo_image_surface_create_for_data + ((unsigned char*)pixels, format, ow, oh, ow * 4); + status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) { + ERR("could not create surface from data %dx%d: %s", + ow, oh, cairo_status_to_string(status)); + ret = EINA_FALSE; + goto error_cairo_surface; + } + cairo = cairo_create(surface); + status = cairo_status(cairo); + if (status != CAIRO_STATUS_SUCCESS) { + ERR("could not create cairo from surface %dx%d: %s", + ow, oh, cairo_status_to_string(status)); + ret = EINA_FALSE; + goto error_cairo; + } + + ctxt = ewk_view_paint_context_new(sd->_priv, cairo); + if (!ctxt) { + ERR("could not create paint context"); + ret = EINA_FALSE; + goto error_paint_context; + } + + tiler = eina_tiler_new(ow, oh); + if (!tiler) { + ERR("could not create tiler %dx%d", ow, oh); + ret = EINA_FALSE; + goto error_tiler; + } + + pr = ewk_view_repaints_get(sd->_priv, &count); + pr_end = pr + count; + for (; pr < pr_end; pr++) + eina_tiler_rect_add(tiler, pr); + + itr = eina_tiler_iterator_new(tiler); + if (!itr) { + ERR("could not get iterator for tiler"); + ret = EINA_FALSE; + goto error_iterator; + } + + int sx, sy; + ewk_frame_scroll_pos_get(sd->main_frame, &sx, &sy); + + EINA_ITERATOR_FOREACH(itr, r) { + Eina_Rectangle scrolled_rect = { + r->x + sx, r->y + sy, + r->w, r->h + }; + + ewk_view_paint_context_save(ctxt); + + if ((sx) || (sy)) + ewk_view_paint_context_translate(ctxt, -sx, -sy); + + ewk_view_paint_context_clip(ctxt, &scrolled_rect); + ewk_view_paint_context_paint_contents(ctxt, &scrolled_rect); + + ewk_view_paint_context_restore(ctxt); + evas_object_image_data_update_add + (sd->backing_store, r->x, r->y, r->w, r->h); + } + eina_iterator_free(itr); + +error_iterator: + eina_tiler_free(tiler); +error_tiler: + ewk_view_paint_context_free(ctxt); +error_paint_context: + cairo_destroy(cairo); +error_cairo: + cairo_surface_destroy(surface); +error_cairo_surface: + evas_object_image_data_set(sd->backing_store, pixels); /* dec refcount */ + + return ret; +} + +static Eina_Bool _ewk_view_single_smart_zoom_weak_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + // TODO: review + float scale = zoom / sd->animated_zoom.zoom.start; + Evas_Coord w = sd->view.w * scale; + Evas_Coord h = sd->view.h * scale; + Evas_Coord dx, dy, cw, ch; + Evas_Object *clip = evas_object_clip_get(sd->backing_store); + + ewk_frame_contents_size_get(sd->main_frame, &cw, &ch); + if (sd->view.w > 0 && sd->view.h > 0) { + dx = (w * (sd->view.w - cx)) / sd->view.w; + dy = (h * (sd->view.h - cy)) / sd->view.h; + } else { + dx = 0; + dy = 0; + } + + evas_object_image_fill_set(sd->backing_store, cx + dx, cy + dy, w, h); + + if (sd->view.w > 0 && sd->view.h > 0) { + dx = ((sd->view.w - w) * cx) / sd->view.w; + dy = ((sd->view.h - h) * cy) / sd->view.h; + } else { + dx = 0; + dy = 0; + } + evas_object_move(clip, sd->view.x + dx, sd->view.y + dy); + + if (cw < sd->view.w) + w = cw * scale; + if (ch < sd->view.h) + h = ch * scale; + evas_object_resize(clip, w, h); + return EINA_TRUE; +} + +static void _ewk_view_single_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale) +{ + evas_object_image_smooth_scale_set(sd->backing_store, smooth_scale); +} + +static void _ewk_view_single_smart_bg_color_set(Ewk_View_Smart_Data *sd, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + evas_object_image_alpha_set(sd->backing_store, a < 255); +} + +/** + * Sets the smart class api using single backing store, enabling view + * to be inherited. + * + * @param api class definition to be set, all members with the + * exception of Evas_Smart_Class->data may be overridden. Must + * @b not be @c NULL. + * + * @note Evas_Smart_Class->data is used to implement type checking and + * is not supposed to be changed/overridden. If you need extra + * data for your smart class to work, just extend + * Ewk_View_Smart_Class instead. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably + * version mismatch). + * + * @see ewk_view_base_smart_set() + */ +Eina_Bool ewk_view_single_smart_set(Ewk_View_Smart_Class *api) +{ + if (!ewk_view_base_smart_set(api)) + return EINA_FALSE; + + if (EINA_UNLIKELY(!_parent_sc.sc.add)) + ewk_view_base_smart_set(&_parent_sc); + + api->sc.add = _ewk_view_single_smart_add; + api->sc.resize = _ewk_view_single_smart_resize; + + api->backing_store_add = _ewk_view_single_smart_backing_store_add; + api->scrolls_process = _ewk_view_single_smart_scrolls_process; + api->repaints_process = _ewk_view_single_smart_repaints_process; + api->zoom_weak_set = _ewk_view_single_smart_zoom_weak_set; + api->zoom_weak_smooth_scale_set = _ewk_view_single_smart_zoom_weak_smooth_scale_set; + api->bg_color_set = _ewk_view_single_smart_bg_color_set; + + return EINA_TRUE; +} + +static inline Evas_Smart *_ewk_view_single_smart_class_new(void) +{ + static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("Ewk_View_Single"); + static Evas_Smart *smart = 0; + + if (EINA_UNLIKELY(!smart)) { + ewk_view_single_smart_set(&api); + smart = evas_smart_class_new(&api.sc); + } + + return smart; +} + +/** + * Creates a new EFL WebKit View object. + * + * View objects are the recommended way to deal with EFL WebKit as it + * abstracts the complex pieces of the process. + * + * Each view is composed by a set of frames. The set has at least one + * frame, called 'main_frame'. See ewk_view_frame_main_get() and + * ewk_view_frame_focused_get(). + * + * @param e canvas where to create the view object. + * + * @return view object or @c NULL if errors. + * + * @see ewk_view_uri_set() + */ +Evas_Object *ewk_view_single_add(Evas *e) +{ + return evas_object_smart_add(e, _ewk_view_single_smart_class_new()); +} diff --git a/Source/WebKit/efl/ewk/ewk_view_tiled.c b/Source/WebKit/efl/ewk/ewk_view_tiled.c new file mode 100644 index 0000000..d380e8e --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_view_tiled.c @@ -0,0 +1,346 @@ +/* + Copyright (C) 2009-2010 Samsung Electronics + Copyright (C) 2009-2010 ProFUSION embedded systems + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_view.h" + +#include "ewk_logging.h" + +#include <Evas.h> +#include <eina_safety_checks.h> +#include <ewk_tiled_backing_store.h> + +static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL; + +static Eina_Bool _ewk_view_tiled_render_cb(void *data, Ewk_Tile *t, const Eina_Rectangle *area) +{ + Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data; + Eina_Rectangle r = {area->x + t->x, area->y + t->y, area->w, area->h}; + + return ewk_view_paint_contents(priv, t->cairo, &r); +} + +static void *_ewk_view_tiled_updates_process_pre(void *data, Evas_Object *o) +{ + Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data; + ewk_view_layout_if_needed_recursive(priv); + return 0; +} + +static Evas_Object *_ewk_view_tiled_smart_backing_store_add(Ewk_View_Smart_Data *sd) +{ + Evas_Object *bs = ewk_tiled_backing_store_add(sd->base.evas); + ewk_tiled_backing_store_render_cb_set + (bs, _ewk_view_tiled_render_cb, sd->_priv); + ewk_tiled_backing_store_updates_process_pre_set + (bs, _ewk_view_tiled_updates_process_pre, sd->_priv); + return bs; +} + +static void +_ewk_view_tiled_contents_size_changed_cb(void *data, Evas_Object *o, void *event_info) +{ + Evas_Coord *size = (Evas_Coord*)event_info; + Ewk_View_Smart_Data *sd = (Ewk_View_Smart_Data*)data; + + ewk_tiled_backing_store_contents_resize + (sd->backing_store, size[0], size[1]); +} + +static void _ewk_view_tiled_smart_add(Evas_Object *o) +{ + Ewk_View_Smart_Data *sd; + + _parent_sc.sc.add(o); + + sd = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o); + evas_object_smart_callback_add( + sd->main_frame, "contents,size,changed", + _ewk_view_tiled_contents_size_changed_cb, sd); + ewk_frame_paint_full_set(sd->main_frame, EINA_TRUE); +} + +static Eina_Bool _ewk_view_tiled_smart_scrolls_process(Ewk_View_Smart_Data *sd) +{ + const Ewk_Scroll_Request *sr; + const Ewk_Scroll_Request *sr_end; + size_t count; + Evas_Coord vw, vh; + + ewk_frame_contents_size_get(sd->main_frame, &vw, &vh); + + sr = ewk_view_scroll_requests_get(sd->_priv, &count); + sr_end = sr + count; + for (; sr < sr_end; sr++) { + if (sr->main_scroll) + ewk_tiled_backing_store_scroll_full_offset_add + (sd->backing_store, sr->dx, sr->dy); + else { + Evas_Coord sx, sy, sw, sh; + + sx = sr->x; + sy = sr->y; + sw = sr->w; + sh = sr->h; + + if (abs(sr->dx) >= sw || abs(sr->dy) >= sh) { + /* doubt webkit would be so stupid... */ + DBG("full page scroll %+03d,%+03d. convert to repaint %d,%d + %dx%d", + sr->dx, sr->dy, sx, sy, sw, sh); + ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh); + continue; + } + + if (sx + sw > vw) + sw = vw - sx; + if (sy + sh > vh) + sh = vh - sy; + + if (sw < 0) + sw = 0; + if (sh < 0) + sh = 0; + + if (!sw || !sh) + continue; + + sx -= abs(sr->dx); + sy -= abs(sr->dy); + sw += abs(sr->dx); + sh += abs(sr->dy); + ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh); + INF("using repaint for inner frame scolling!"); + } + } + + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_tiled_smart_repaints_process(Ewk_View_Smart_Data *sd) +{ + const Eina_Rectangle *pr, *pr_end; + size_t count; + int sx, sy; + + ewk_frame_scroll_pos_get(sd->main_frame, &sx, &sy); + + pr = ewk_view_repaints_get(sd->_priv, &count); + pr_end = pr + count; + for (; pr < pr_end; pr++) { + Eina_Rectangle r; + r.x = pr->x + sx; + r.y = pr->y + sy; + r.w = pr->w; + r.h = pr->h; + ewk_tiled_backing_store_update(sd->backing_store, &r); + } + ewk_tiled_backing_store_updates_process(sd->backing_store); + + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_tiled_smart_contents_resize(Ewk_View_Smart_Data *sd, int w, int h) +{ + ewk_tiled_backing_store_contents_resize(sd->backing_store, w, h); + return EINA_TRUE; +} + +static Eina_Bool _ewk_view_tiled_smart_zoom_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + Evas_Coord x, y, w, h; + Eina_Bool r; + r = ewk_tiled_backing_store_zoom_set(sd->backing_store, + &zoom, cx, cy, &x, &y); + if (!r) + return r; + ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_TRUE); + r = _parent_sc.zoom_set(sd, zoom, cx, cy); + ewk_frame_scroll_set(sd->main_frame, -x, -y); + ewk_frame_scroll_size_get(sd->main_frame, &w, &h); + ewk_tiled_backing_store_fix_offsets(sd->backing_store, w, h); + ewk_view_scrolls_process(sd); + evas_object_smart_calculate(sd->backing_store); + evas_object_smart_calculate(sd->self); + ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_FALSE); + return r; +} + +static Eina_Bool _ewk_view_tiled_smart_zoom_weak_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy) +{ + return ewk_tiled_backing_store_zoom_weak_set(sd->backing_store, zoom, cx, cy); +} + +static void _ewk_view_tiled_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale) +{ + ewk_tiled_backing_store_zoom_weak_smooth_scale_set(sd->backing_store, smooth_scale); +} + +static void _ewk_view_tiled_smart_flush(Ewk_View_Smart_Data *sd) +{ + ewk_tiled_backing_store_flush(sd->backing_store); + _parent_sc.flush(sd); +} + +static Eina_Bool _ewk_view_tiled_smart_pre_render_region(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom) +{ + return ewk_tiled_backing_store_pre_render_region + (sd->backing_store, x, y, w, h, zoom); +} + +static Eina_Bool _ewk_view_tiled_smart_pre_render_relative_radius(Ewk_View_Smart_Data *sd, unsigned int n, float zoom) +{ + return ewk_tiled_backing_store_pre_render_relative_radius + (sd->backing_store, n, zoom); +} + +static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data *sd) +{ + ewk_tiled_backing_store_pre_render_cancel(sd->backing_store); +} + +static Eina_Bool _ewk_view_tiled_smart_disable_render(Ewk_View_Smart_Data *sd) +{ + return ewk_tiled_backing_store_disable_render(sd->backing_store); +} + +static Eina_Bool _ewk_view_tiled_smart_enable_render(Ewk_View_Smart_Data *sd) +{ + return ewk_tiled_backing_store_enable_render(sd->backing_store); +} + +/** + * Sets the smart class api using tiled backing store, enabling view + * to be inherited. + * + * @param api class definition to be set, all members with the + * exception of Evas_Smart_Class->data may be overridden. Must + * @b not be @c NULL. + * + * @note Evas_Smart_Class->data is used to implement type checking and + * is not supposed to be changed/overridden. If you need extra + * data for your smart class to work, just extend + * Ewk_View_Smart_Class instead. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably + * version mismatch). + * + * @see ewk_view_base_smart_set() + */ +Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class *api) +{ + if (!ewk_view_base_smart_set(api)) + return EINA_FALSE; + + if (EINA_UNLIKELY(!_parent_sc.sc.add)) + ewk_view_base_smart_set(&_parent_sc); + + api->sc.add = _ewk_view_tiled_smart_add; + + api->backing_store_add = _ewk_view_tiled_smart_backing_store_add; + api->scrolls_process = _ewk_view_tiled_smart_scrolls_process; + api->repaints_process = _ewk_view_tiled_smart_repaints_process; + api->contents_resize = _ewk_view_tiled_smart_contents_resize; + api->zoom_set = _ewk_view_tiled_smart_zoom_set; + api->zoom_weak_set = _ewk_view_tiled_smart_zoom_weak_set; + api->zoom_weak_smooth_scale_set = _ewk_view_tiled_smart_zoom_weak_smooth_scale_set; + api->flush = _ewk_view_tiled_smart_flush; + api->pre_render_region = _ewk_view_tiled_smart_pre_render_region; + api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius; + api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel; + api->disable_render = _ewk_view_tiled_smart_disable_render; + api->enable_render = _ewk_view_tiled_smart_enable_render; + return EINA_TRUE; +} + +static inline Evas_Smart *_ewk_view_tiled_smart_class_new(void) +{ + static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Tiled"); + static Evas_Smart *smart = 0; + + if (EINA_UNLIKELY(!smart)) { + ewk_view_tiled_smart_set(&api); + smart = evas_smart_class_new(&api.sc); + } + + return smart; +} + +/** + * Creates a new EFL WebKit View object using tiled backing store. + * + * View objects are the recommended way to deal with EFL WebKit as it + * abstracts the complex pieces of the process. + * + * This object is almost the same as the one returned by the ewk_view_add() + * function, but it uses the tiled backing store instead of the default + * backing store. + * + * @param e canvas where to create the view object. + * + * @return view object or @c NULL if errors. + * + * @see ewk_view_uri_set() + */ +Evas_Object *ewk_view_tiled_add(Evas *e) +{ + return evas_object_smart_add(e, _ewk_view_tiled_smart_class_new()); +} + +/** + * Get the cache of unused tiles used by this view. + * + * @param o view object to get cache. + * @return instance of "cache of unused tiles" or @c NULL on errors. + */ +Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o) +{ + Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o); + EINA_SAFETY_ON_NULL_RETURN_VAL(sd, 0); + return ewk_tiled_backing_store_tile_unused_cache_get(sd->backing_store); +} + +/** + * Set the cache of unused tiles used by this view. + * + * @param o view object to get cache. + * @param cache instance of "cache of unused tiles". This can be used + * to share a single cache amongst different views. The tiles + * from one view will not be used by the other! This is just to + * limit the group with amount of unused memory. + * If @c NULL is provided, then a new cache is created. + */ +void ewk_view_tiled_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *cache) +{ + Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o); + EINA_SAFETY_ON_NULL_RETURN(sd); + ewk_tiled_backing_store_tile_unused_cache_set(sd->backing_store, cache); +} + +/** + * Set the function with the same name of the tiled backing store. + * @param o the tiled backing store object. + * @param flag value of the tiled backing store flag to set. + */ +void ewk_view_tiled_process_entire_queue_set(Evas_Object *o, Eina_Bool flag) +{ + Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o); + EINA_SAFETY_ON_NULL_RETURN(sd); + ewk_tiled_backing_store_process_entire_queue_set(sd->backing_store, flag); +} diff --git a/Source/WebKit/efl/ewk/ewk_window_features.cpp b/Source/WebKit/efl/ewk/ewk_window_features.cpp new file mode 100644 index 0000000..3855e89 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_window_features.cpp @@ -0,0 +1,156 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "ewk_window_features.h" + +#include "WindowFeatures.h" +#include "ewk_private.h" + +#include <Eina.h> + +struct _Ewk_Window_Features { + unsigned int __ref; + WebCore::WindowFeatures* core; +}; + +/** + * Decrease the ref count of an Ewk_Window_Features, possibly freeing it. + * + * When its ref count reaches 0, @param window_features is freed. + * + * @param window_features The window's features. + */ +EAPI void ewk_window_features_unref(Ewk_Window_Features* window_features) +{ + EINA_SAFETY_ON_NULL_RETURN(window_features); + EINA_SAFETY_ON_FALSE_RETURN(window_features->__ref > 0); + + if (--window_features->__ref) + return; + + delete window_features->core; + window_features->core = 0; + free(window_features); +} + +/** + * Increase the ref count of an Ewk_Window_Features + * + * @param window_features The window's features. + */ +EAPI void ewk_window_features_ref(Ewk_Window_Features* window_features) +{ + EINA_SAFETY_ON_NULL_RETURN(window_features); + window_features->__ref++; +} + +/** + * Get boolean properties + * + * @param window_features A window_features. + * @param toolbar_visible pointer to store if toolbar is visible. + * @param statusbar_visible pointer to store if statusbar is visible. + * @param scrollbars_visible pointer to store if scrollbars is visible. + * @param menubar_visible pointer to store if menubar is visible. + * @param locationbar_visible pointer to store if locationbar is visible. + * @param fullscreen pointer to store if fullscreen is enabled. + */ +EAPI void ewk_window_features_bool_property_get(Ewk_Window_Features* window_features, Eina_Bool* toolbar_visible, Eina_Bool* statusbar_visible, Eina_Bool* scrollbars_visible, Eina_Bool* menubar_visible, Eina_Bool* locationbar_visible, Eina_Bool* fullscreen) +{ + EINA_SAFETY_ON_NULL_RETURN(window_features); + EINA_SAFETY_ON_NULL_RETURN(window_features->core); + + if (toolbar_visible) + *toolbar_visible = window_features->core->toolBarVisible; + + if (statusbar_visible) + *statusbar_visible = window_features->core->statusBarVisible; + + if (scrollbars_visible) + *scrollbars_visible = window_features->core->scrollbarsVisible; + + if (menubar_visible) + *menubar_visible = window_features->core->menuBarVisible; + + if (locationbar_visible) + *locationbar_visible = window_features->core->locationBarVisible; + + if (fullscreen) + *fullscreen = window_features->core->fullscreen; +} + +/** + * Get int properties + * + * Properties are returned in the respective pointers. Passing NULL to any of + * these pointers will make that property to not be returned. Make sure to check + * if the value returned is less than 0 before using it, since in that case it + * means that property was not set in @param winwdow_features. + * + * @param window_features A window_features. + * @param x pointer to store x position or -1 if it's not set in window_features. + * @param y pointer to store y position or-1 if it's not set in window_features. + * @param w pointer to store width or-1 if it's not set in window_features. + * @param h pointer to store height or-1 if it's not set in window_features. + */ +EAPI void ewk_window_features_int_property_get(Ewk_Window_Features* window_features, int* x, int* y, int* w, int* h) +{ + EINA_SAFETY_ON_NULL_RETURN(window_features); + EINA_SAFETY_ON_NULL_RETURN(window_features->core); + + if (x) + *x = window_features->core->xSet ? static_cast<int>(window_features->core->x) : -1; + + if (y) + *y = window_features->core->ySet ? static_cast<int>(window_features->core->y) : -1; + + if (w) + *w = window_features->core->widthSet ? static_cast<int>(window_features->core->width) : -1; + + if (h) + *h = window_features->core->heightSet ? static_cast<int>(window_features->core->height) : -1; +} + +/* internal methods ****************************************************/ + +/** + * @internal + * Create a new Ewk_Window_Features from a WebCore::WindowFeatures if @param + * core is not NULL or a new one with default features. + * + * A new WebCore::WindowFeatures is allocated copying @param core features and + * it is embedded inside an Ewk_Window_Features whose ref count is initialized. + * + * @returns a new allocated Ewk_Window_Features + */ +Ewk_Window_Features* ewk_window_features_new_from_core(const WebCore::WindowFeatures* core) +{ + Ewk_Window_Features* window_features = static_cast<Ewk_Window_Features*>(malloc(sizeof(*window_features))); + + if (core) + window_features->core = new WebCore::WindowFeatures(*core); + else + window_features->core = new WebCore::WindowFeatures(); + + window_features->__ref = 1; + + return window_features; +} diff --git a/Source/WebKit/efl/ewk/ewk_window_features.h b/Source/WebKit/efl/ewk/ewk_window_features.h new file mode 100644 index 0000000..b579dc4 --- /dev/null +++ b/Source/WebKit/efl/ewk/ewk_window_features.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2010 ProFUSION embedded systems + Copyright (C) 2010 Samsung Electronics + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef ewk_window_features_h +#define ewk_window_features_h + +#include "ewk_eapi.h" + +#include <Eina.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _Ewk_Window_Features Ewk_Window_Features; + +EAPI void ewk_window_features_unref(Ewk_Window_Features* window_features); +EAPI void ewk_window_features_ref(Ewk_Window_Features* window_features); + +EAPI void ewk_window_features_bool_property_get(Ewk_Window_Features* window_features, Eina_Bool* toolbar_visible, Eina_Bool* statusbar_visible, Eina_Bool* scrollbars_visible, Eina_Bool* menubar_visible, Eina_Bool* locationbar_visible, Eina_Bool* fullscreen); +EAPI void ewk_window_features_int_property_get(Ewk_Window_Features* window_features, int* x, int* y, int* w, int* h); + +#ifdef __cplusplus +} +#endif +#endif // ewk_window_features_h |