summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/UIProcess/API/efl/ewk_view.cpp')
-rw-r--r--Source/WebKit2/UIProcess/API/efl/ewk_view.cpp468
1 files changed, 468 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
new file mode 100644
index 000000000..c5bca11b4
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp
@@ -0,0 +1,468 @@
+/*
+ Copyright (C) 2011 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 "NativeWebKeyboardEvent.h"
+#include "NativeWebMouseEvent.h"
+#include "NativeWebWheelEvent.h"
+#include "PageClientImpl.h"
+#include "WKAPICast.h"
+
+using namespace WebKit;
+using namespace WebCore;
+
+static const char EWK_VIEW_TYPE_STR[] = "EWK2_View";
+
+struct _Ewk_View_Private_Data {
+ OwnPtr<PageClientImpl> pageClient;
+};
+
+#define EWK_VIEW_TYPE_CHECK(ewkView, result) \
+ bool result = true; \
+ do { \
+ const char* _tmp_otype = evas_object_type_get(ewkView); \
+ const Evas_Smart* _tmp_s = evas_object_smart_smart_get(ewkView); \
+ if (EINA_UNLIKELY(!_tmp_s)) { \
+ EINA_LOG_CRIT \
+ ("%p (%s) is not a smart object!", \
+ ewkView, _tmp_otype ? _tmp_otype : "(null)"); \
+ result = false; \
+ } \
+ 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!", \
+ ewkView, _tmp_otype ? _tmp_otype : "(null)"); \
+ result = false; \
+ } \
+ 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)!", \
+ ewkView, _tmp_otype ? _tmp_otype : "(null)", \
+ EWK_VIEW_TYPE_STR, _tmp_sc->data); \
+ result = false; \
+ } \
+ } while (0)
+
+#define EWK_VIEW_SD_GET(ewkView, smartData) \
+ EWK_VIEW_TYPE_CHECK(ewkView, _tmp_result); \
+ Ewk_View_Smart_Data* smartData = 0; \
+ if (_tmp_result) \
+ smartData = (Ewk_View_Smart_Data*)evas_object_smart_data_get(ewkView);
+
+#define EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, ...) \
+ EWK_VIEW_SD_GET(ewkView, smartData); \
+ if (!smartData) { \
+ EINA_LOG_CRIT("no smart data for object %p (%s)", \
+ ewkView, evas_object_type_get(ewkView)); \
+ return __VA_ARGS__; \
+ }
+
+#define EWK_VIEW_PRIV_GET(smartData, priv) \
+ Ewk_View_Private_Data* priv = smartData->priv
+
+#define EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, ...) \
+ if (!smartData) { \
+ EINA_LOG_CRIT("smart data is null"); \
+ return __VA_ARGS__; \
+ } \
+ EWK_VIEW_PRIV_GET(smartData, priv); \
+ if (!priv) { \
+ EINA_LOG_CRIT("no private data for object %p (%s)", \
+ smartData->self, evas_object_type_get(smartData->self)); \
+ return __VA_ARGS__; \
+ }
+
+static void _ewk_view_smart_changed(Ewk_View_Smart_Data* smartData)
+{
+ if (smartData->changed.any)
+ return;
+ smartData->changed.any = true;
+ evas_object_smart_changed(smartData->self);
+}
+
+// Default Event Handling.
+static Eina_Bool _ewk_view_smart_focus_in(Ewk_View_Smart_Data* smartData)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ priv->pageClient->page()->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_focus_out(Ewk_View_Smart_Data* smartData)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ priv->pageClient->page()->viewStateDidChange(WebPageProxy::ViewWindowIsActive);
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_mouse_wheel(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Wheel* wheelEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ Evas_Point position = {smartData->view.x, smartData->view.y};
+ priv->pageClient->page()->handleWheelEvent(NativeWebWheelEvent(wheelEvent, &position));
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_mouse_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Down* downEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ Evas_Point position = {smartData->view.x, smartData->view.y};
+ priv->pageClient->page()->handleMouseEvent(NativeWebMouseEvent(downEvent, &position));
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_mouse_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Up* upEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ Evas_Point position = {smartData->view.x, smartData->view.y};
+ priv->pageClient->page()->handleMouseEvent(NativeWebMouseEvent(upEvent, &position));
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_mouse_move(Ewk_View_Smart_Data* smartData, const Evas_Event_Mouse_Move* moveEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ Evas_Point position = {smartData->view.x, smartData->view.y};
+ priv->pageClient->page()->handleMouseEvent(NativeWebMouseEvent(moveEvent, &position));
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_key_down(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Down* downEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ priv->pageClient->page()->handleKeyboardEvent(NativeWebKeyboardEvent(downEvent));
+ return true;
+}
+
+static Eina_Bool _ewk_view_smart_key_up(Ewk_View_Smart_Data* smartData, const Evas_Event_Key_Up* upEvent)
+{
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, false)
+
+ priv->pageClient->page()->handleKeyboardEvent(NativeWebKeyboardEvent(upEvent));
+ return true;
+}
+
+// Event Handling.
+static void _ewk_view_on_focus_in(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_in);
+ smartData->api->focus_in(smartData);
+}
+
+static void _ewk_view_on_focus_out(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->focus_out);
+ smartData->api->focus_out(smartData);
+}
+
+static void _ewk_view_on_mouse_wheel(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Mouse_Wheel* wheelEvent = static_cast<Evas_Event_Mouse_Wheel*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_wheel);
+ smartData->api->mouse_wheel(smartData, wheelEvent);
+}
+
+static void _ewk_view_on_mouse_down(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Mouse_Down* downEvent = static_cast<Evas_Event_Mouse_Down*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_down);
+ smartData->api->mouse_down(smartData, downEvent);
+}
+
+static void _ewk_view_on_mouse_up(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Mouse_Up* upEvent = static_cast<Evas_Event_Mouse_Up*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_up);
+ smartData->api->mouse_up(smartData, upEvent);
+}
+
+static void _ewk_view_on_mouse_move(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Mouse_Move* moveEvent = static_cast<Evas_Event_Mouse_Move*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->mouse_move);
+ smartData->api->mouse_move(smartData, moveEvent);
+}
+
+static void _ewk_view_on_key_down(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Key_Down* downEvent = static_cast<Evas_Event_Key_Down*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_down);
+ smartData->api->key_down(smartData, downEvent);
+}
+
+static void _ewk_view_on_key_up(void* data, Evas* canvas, Evas_Object* ewkView, void* eventInfo)
+{
+ Evas_Event_Key_Up* upEvent = static_cast<Evas_Event_Key_Up*>(eventInfo);
+ Ewk_View_Smart_Data* smartData = static_cast<Ewk_View_Smart_Data*>(data);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api);
+ EINA_SAFETY_ON_NULL_RETURN(smartData->api->key_up);
+ smartData->api->key_up(smartData, upEvent);
+}
+
+static Evas_Smart_Class g_parentSmartClass = EVAS_SMART_CLASS_INIT_NULL;
+
+static Ewk_View_Private_Data* _ewk_view_priv_new(Ewk_View_Smart_Data* smartData)
+{
+ Ewk_View_Private_Data* priv =
+ static_cast<Ewk_View_Private_Data*>(calloc(1, sizeof(Ewk_View_Private_Data)));
+ if (!priv) {
+ EINA_LOG_CRIT("could not allocate Ewk_View_Private_Data");
+ return 0;
+ }
+
+ return priv;
+}
+
+static void _ewk_view_priv_del(Ewk_View_Private_Data* priv)
+{
+ if (!priv)
+ return;
+
+ priv->pageClient = nullptr;
+ free(priv);
+}
+
+static void _ewk_view_smart_add(Evas_Object* ewkView)
+{
+ const Evas_Smart* smart = evas_object_smart_smart_get(ewkView);
+ const Evas_Smart_Class* smartClass = evas_smart_class_get(smart);
+ const Ewk_View_Smart_Class* api = reinterpret_cast<const Ewk_View_Smart_Class*>(smartClass);
+ EWK_VIEW_SD_GET(ewkView, smartData);
+
+ if (!smartData) {
+ smartData = static_cast<Ewk_View_Smart_Data*>(calloc(1, sizeof(Ewk_View_Smart_Data)));
+ if (!smartData) {
+ EINA_LOG_CRIT("could not allocate Ewk_View_Smart_Data");
+ return;
+ }
+ evas_object_smart_data_set(ewkView, smartData);
+ }
+
+ smartData->self = ewkView;
+ smartData->priv = _ewk_view_priv_new(smartData);
+ smartData->api = api;
+
+ if (!smartData->priv) {
+ EINA_LOG_CRIT("could not allocate _Ewk_View_Private_Data");
+ evas_object_smart_data_set(ewkView, 0);
+ free(smartData);
+ return;
+ }
+
+ g_parentSmartClass.add(ewkView);
+
+ // Create evas_object_image to draw web contents.
+ smartData->image = evas_object_image_add(smartData->base.evas);
+ evas_object_image_alpha_set(smartData->image, false);
+ evas_object_image_filled_set(smartData->image, true);
+ evas_object_smart_member_add(smartData->image, ewkView);
+ evas_object_show(smartData->image);
+
+#define CONNECT(s, c) evas_object_event_callback_add(ewkView, s, c, smartData)
+ 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* ewkView)
+{
+ EWK_VIEW_SD_GET(ewkView, smartData);
+ if (smartData && smartData->priv)
+ _ewk_view_priv_del(smartData->priv);
+
+ g_parentSmartClass.del(ewkView);
+}
+
+static void _ewk_view_smart_resize(Evas_Object* ewkView, Evas_Coord width, Evas_Coord height)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
+
+ evas_object_resize(smartData->image, width, height);
+ evas_object_image_size_set(smartData->image, width, height);
+ evas_object_image_fill_set(smartData->image, 0, 0, width, height);
+
+ smartData->changed.size = true;
+ _ewk_view_smart_changed(smartData);
+}
+
+static void _ewk_view_smart_move(Evas_Object* ewkView, Evas_Coord x, Evas_Coord y)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
+
+ smartData->changed.position = true;
+ _ewk_view_smart_changed(smartData);
+}
+
+static void _ewk_view_smart_calculate(Evas_Object* ewkView)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
+ Evas_Coord x, y, width, height;
+
+ smartData->changed.any = false;
+
+ evas_object_geometry_get(ewkView, &x, &y, &width, &height);
+ Evas_Object* clip = evas_object_clip_get(smartData->image);
+
+ if (smartData->changed.size) {
+ if (priv->pageClient->page()->drawingArea())
+ priv->pageClient->page()->drawingArea()->setSize(IntSize(width, height), IntSize());
+ smartData->view.w = width;
+ smartData->view.h = height;
+ evas_object_resize(clip, width, height);
+ smartData->changed.size = false;
+ }
+
+ if (smartData->changed.position) {
+ evas_object_move(smartData->image, x, y);
+ evas_object_move(clip, x, y);
+ smartData->view.x = x;
+ smartData->view.y = y;
+ smartData->changed.position = false;
+ }
+}
+
+static void _ewk_view_smart_show(Evas_Object* ewkView)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
+
+ if (evas_object_clipees_get(smartData->base.clipper))
+ evas_object_show(smartData->base.clipper);
+ evas_object_show(smartData->image);
+}
+
+static void _ewk_view_smart_hide(Evas_Object* ewkView)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
+
+ evas_object_hide(smartData->base.clipper);
+ evas_object_hide(smartData->image);
+}
+
+Eina_Bool ewk_view_smart_class_init(Ewk_View_Smart_Class* api)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(api, 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 false;
+ }
+
+ if (EINA_UNLIKELY(!g_parentSmartClass.add))
+ evas_object_smart_clipped_smart_set(&g_parentSmartClass);
+
+ evas_object_smart_clipped_smart_set(&api->sc);
+
+ // Set Evas_Smart_Class functions.
+ api->sc.add = _ewk_view_smart_add;
+ api->sc.del = _ewk_view_smart_del;
+ api->sc.move = _ewk_view_smart_move;
+ api->sc.resize = _ewk_view_smart_resize;
+ api->sc.show = _ewk_view_smart_show;
+ api->sc.hide = _ewk_view_smart_hide;
+ api->sc.calculate = _ewk_view_smart_calculate;
+ api->sc.data = EWK_VIEW_TYPE_STR; // It is used by type checking.
+
+ // Set Ewk_View_Smart_Class functions.
+ 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;
+
+ return true;
+}
+
+static inline Evas_Smart* _ewk_view_smart_class_new(void)
+{
+ static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("Ewk_View");
+ static Evas_Smart* smart = 0;
+
+ if (EINA_UNLIKELY(!smart)) {
+ ewk_view_smart_class_init(&api);
+ smart = evas_smart_class_new(&api.sc);
+ }
+
+ return smart;
+}
+
+Evas_Object* ewk_view_add(Evas* canvas, WKContextRef contextRef, WKPageGroupRef pageGroupRef)
+{
+ Evas_Object* ewkView = evas_object_smart_add(canvas, _ewk_view_smart_class_new());
+ if (!ewkView)
+ return 0;
+
+ EWK_VIEW_SD_GET(ewkView, smartData);
+ if (!smartData) {
+ evas_object_del(ewkView);
+ return 0;
+ }
+
+ EWK_VIEW_PRIV_GET(smartData, priv);
+ if (!priv) {
+ evas_object_del(ewkView);
+ return 0;
+ }
+
+ priv->pageClient = PageClientImpl::create(toImpl(contextRef), toImpl(pageGroupRef), smartData->image);
+
+ return ewkView;
+}
+
+WKPageRef ewk_view_page_get(Evas_Object* ewkView)
+{
+ EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
+ EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
+
+ return toAPI(priv->pageClient->page());
+}