diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/UIProcess/API/efl/ewk_view.cpp | |
download | qtwebkit-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.cpp | 468 |
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()); +} |