Evas-plugin is used by EFL applications that wish to use Dali.
It provides a means for initializing the resources required by the Dali::Core.
Change-Id: I2b4428615e42771f94ee1df3c818386e77349c6f
Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
AC_CONFIG_SUBDIRS(web-engine-chromium)
AC_CONFIG_SUBDIRS(web-engine-lwe)
fi
+AC_CONFIG_SUBDIRS(dali-extension)
devincludepath=${includedir}
AC_SUBST(devincludepath)
Name: DALi extension
Description: The DALi extension Libaray
Version: @DALI_EXTENSION_VERSION@
-Requires: dali-toolkit
+Requires: dali-adaptor dali-toolkit
Libs: -L${libdir} -ldali-extension
Cflags: -I${includedir}/dali-extension
--- /dev/null
+#
+# Copyright (c) 2019 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build the Dali extension library
+
+extension_src_dir = ../../../dali-extension
+
+# evas-plugin
+include ../../../dali-extension/devel-api/evas-plugin/file.list
+include ../../../dali-extension/internal/evas-plugin/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-extension.la
+
+# Todo Evas plugin separation
+libdali_extension_la_SOURCES = \
+ $(evas_plugin_devel_src_files) \
+ $(evas_plugin_internal_src_files)
+
+libdali_extension_la_DEPENDENCIES =
+
+libdali_extension_la_CXXFLAGS = \
+ $(DLOG_CFLAGS) \
+ $(DALI_CFLAGS) \
+ $(DALI_EXTENSION_CFLAGS) \
+ $(DALI_ADAPTOR_INTEGRATION_CFLAGS) \
+ $(ELEMENTARY_CFLAGS) \
+ $(EVAS_CFLAGS) \
+ $(WAYLAND_CFLAGS) \
+ -DEFL_BETA_API_SUPPORT \
+ -I../../../ \
+ -Werror -Wall
+
+libdali_extension_la_LIBADD = \
+ $(DLOG_LIBS) \
+ $(DALI_LIBS) \
+ $(DALI_ADAPTOR_INTEGRATION_LIBS) \
+ $(ELEMENTARY_LIBS) \
+ $(EVAS_LIBS) \
+ $(WAYLAND_LIBS)
+
+libdali_extension_la_LDFLAGS = \
+ -rdynamic
+
+#install headers
+dali_extensiondir = $(devincludepath)/dali-extension
+dali_extension_HEADERS = ../../../dali-extension/dali-extension.h
+
+dali_extension_evasplugindir = $(devincludepath)/dali-extension/devel-api/evas-plugin
+dali_extension_evasplugin_HEADERS = $(evas_plugin_devel_header_files)
--- /dev/null
+4_define([dali_version],[0.1.0])
+AC_INIT([dali], [dali_version])
+AM_INIT_AUTOMAKE([-Wall foreign])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+LT_INIT
+
+DALI_EXTENSION_VERSION=dali_version
+AC_SUBST(DALI_EXTENSION_VERSION)
+
+# For evas-plugin
+PKG_CHECK_MODULES(DALI_ADAPTOR_INTEGRATION, dali-adaptor-integration)
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
+PKG_CHECK_MODULES(EVAS, evas)
+PKG_CHECK_MODULES(WAYLAND, [ecore-wl2])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
--- /dev/null
+#ifndef __DALI_EXTENSION_H__
+#define __DALI_EXTENSION_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+#endif // __DALI_EXTENSION_H__
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+// CLASS HEADER
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+EvasPlugin EvasPlugin::New( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent )
+{
+ IntrusivePtr< Internal::EvasPlugin > impl = Internal::EvasPlugin::New( parentEvasObject, width, height, isTranslucent );
+
+ // When Initialize(), EvasPlugin creates Adaptor which needs BaseHandle of Internal::EvasPlugin.
+ // In that process, EvasPlugin can be deleted when destroying BaseHandle
+ // so it is needed to count reference before calling Initialize()
+ EvasPlugin evasPlugin = EvasPlugin( impl.Get() );
+
+ impl->Initialize();
+
+ return evasPlugin;
+}
+
+EvasPlugin::EvasPlugin()
+{
+}
+
+EvasPlugin::EvasPlugin( const EvasPlugin& evasPlugin )
+: SceneHolder( evasPlugin )
+{
+}
+
+EvasPlugin& EvasPlugin::operator=( const EvasPlugin& evasPlugin )
+{
+ if( *this != evasPlugin )
+ {
+ BaseHandle::operator=( evasPlugin );
+ }
+ return *this;
+}
+
+EvasPlugin::~EvasPlugin()
+{
+}
+
+void EvasPlugin::Run()
+{
+ Internal::GetImplementation( *this ).Run();
+}
+
+void EvasPlugin::Pause()
+{
+ Internal::GetImplementation( *this ).Pause();
+}
+
+void EvasPlugin::Resume()
+{
+ Internal::GetImplementation( *this ).Resume();
+}
+
+void EvasPlugin::Stop()
+{
+ Internal::GetImplementation( *this ).Stop();
+}
+
+Evas_Object* EvasPlugin::GetAccessEvasObject()
+{
+ return Internal::GetImplementation( *this ).GetAccessEvasObject();
+}
+
+Evas_Object* EvasPlugin::GetDaliEvasObject()
+{
+ return Internal::GetImplementation( *this ).GetDaliEvasObject();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::InitSignal()
+{
+ return Internal::GetImplementation( *this ).InitSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::TerminateSignal()
+{
+ return Internal::GetImplementation( *this ).TerminateSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::PauseSignal()
+{
+ return Internal::GetImplementation( *this ).PauseSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::ResumeSignal()
+{
+ return Internal::GetImplementation( *this ).ResumeSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::ResizeSignal()
+{
+ return Internal::GetImplementation( *this ).ResizeSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::FocusedSignal()
+{
+ return Internal::GetImplementation( *this ).FocusedSignal();
+}
+
+EvasPlugin::EvasPluginSignalType& EvasPlugin::UnFocusedSignal()
+{
+ return Internal::GetImplementation( *this ).UnFocusedSignal();
+}
+
+EvasPlugin::EvasPlugin( Internal::EvasPlugin* evasPlugin )
+: SceneHolder( evasPlugin )
+{
+}
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_EVAS_PLUGIN_H__
+#define __DALI_EXTENSION_EVAS_PLUGIN_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @addtogroup CAPI_DALI_EXTENSION_FRAMEWORK_MODULE
+ * @{
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+
+#include <dali/public-api/signals/dali-signal.h>
+#include <dali/integration-api/adaptors/scene-holder.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+class EvasPlugin;
+}
+
+/**
+ * @brief Application class used by EFL applications that wish to use Dali
+ *
+ * An EvasPlugin class object should be created by EFL applications
+ * that wish to use Dali. It provides a mean for initializing the
+ * resources required by the Dali::Core.
+ *
+ * The EvasPlugin class emits several signals which the user can
+ * connect to. The user should not create any Dali objects in the main
+ * function and instead should connect to the Init signal of the
+ * EvasPlugin and create the Dali objects in the connected callback.
+ *
+ * Tizen EFL applications should follow the example below:
+ *
+ * @code
+ *
+ * #include <app.h>
+ * #include <Elementary.h>
+ * #include <dali/dali.h>
+ * #include <dali-toolkit/dali-toolkit.h>
+ * #include <dali-extension/dali-extension.h>
+ *
+ * using namespace Dali;
+ * using namespace Dali::Toolkit;
+ * using namespace Dali::Extension;
+ *
+ * namespace
+ * {
+ * const char* const APPLICATION_TITLE = "EvasPluginExample";
+ * const int EVAS_PLUGIN_WIDTH = 360;
+ * const int EVAS_PLUGIN_HEIGHT = 360;
+ * }
+ *
+ * class EvasPluginExample : public ConnectionTracker
+ * {
+ * public:
+ * EvasPluginExample(EvasPlugin evasPlugin)
+ * : mEvasPlugin(evasPlugin)
+ * {
+ * mEvasPlugin.InitSignal().Connect(this, &EvasPluginExample::OnInitialize);
+ * mEvasPlugin.Run();
+ * }
+ *
+ * ~EvasPluginExample()
+ * {
+ * mEvasPlugin.Stop();
+ * }
+ *
+ * void OnInitialize()
+ * {
+ * Stage stage = Stage::GetCurrent();
+ * stage.SetBackgroundColor( Color::WHITE );
+ *
+ * TextLabel textLabel = TextLabel::New( "Hello World" );
+ * textLabel.SetParentOrigin( ParentOrigin::CENTER );
+ * textLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ * textLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER );
+ * textLabel.SetProperty( TextLabel::Property::POINT_SIZE, 40 );
+ * textLabel.SetName( "helloWorldLabel" );
+ * stage.Add( textLabel );
+ *
+ * Animation anim = Animation::New( 3.f );
+ * anim.SetLooping( true );
+ * anim.AnimateBy( Property(textLabel, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
+ * anim.Play();
+ * }
+ *
+ * private:
+ * EvasPlugin mEvasPlugin;
+ * };
+ *
+ * struct app_data
+ * {
+ * Evas_Object* elm_win;
+ * EvasPluginExample* evasPluginExample;
+ * };
+ *
+ * static void win_del(void *data, Evas_Object * obj, void *event_info)
+ * {
+ * }
+ *
+ * static bool app_create(void *data)
+ * {
+ * struct app_data* ad = (struct app_data*)data;
+ *
+ * // Sets the GL backend for rendering
+ * elm_config_accel_preference_set("3d");
+ *
+ * // Creates the elm window
+ * ad->elm_win = elm_win_add(NULL, APPLICATION_TITLE, ELM_WIN_BASIC);
+ *
+ * DALI_ASSERT_ALWAYS(ad->elm_win != NULL && "Fail to create elm window.");
+ *
+ * elm_win_title_set(ad->elm_win, APPLICATION_TITLE);
+ * elm_win_rotation_with_resize_set(ad->elm_win, 0);
+ * evas_object_smart_callback_add(ad->elm_win, "delete,request", win_del, ad->elm_win);
+ * evas_object_show(ad->elm_win);
+ *
+ * // Adds the background
+ * Evas_Object* bg = elm_bg_add(ad->elm_win);
+ * elm_bg_color_set(bg, 255, 255, 255);
+ * evas_object_size_hint_weight_set(bg, 0,0);
+ * elm_win_resize_object_add(ad->elm_win, bg);
+ * evas_object_show(bg);
+ *
+ * // Creates an Evas plugin
+ * EvasPlugin evasPlugin = EvasPlugin::New(ad->elm_win, EVAS_PLUGIN_WIDTH, EVAS_PLUGIN_HEIGHT, true);
+ *
+ * // Creates a Dali application
+ * ad->evasPluginExample = new EvasPluginExample(evasPlugin);
+ *
+ * return true;
+ * }
+ *
+ * static void app_terminate(void *data)
+ * {
+ * struct app_data* ad = (struct app_data*)data;
+ *
+ * delete ad->evasPluginExample;
+ * ad->evasPluginExample = NULL;
+ * }
+ *
+ * static void app_pause(void *data)
+ * {
+ * }
+ *
+ * static void app_resume(void *data)
+ * {
+ * }
+ *
+ * static void app_control(app_control_h service, void *data)
+ * {
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ * // Initializes the Tizen application framework
+ * ui_app_lifecycle_callback_s event_callback;
+ *
+ * event_callback.create = app_create;
+ * event_callback.terminate = app_terminate;
+ * event_callback.pause = app_pause;
+ * event_callback.resume = app_resume;
+ * event_callback.app_control = app_control;
+ *
+ * struct app_data ad;
+ * memset(&ad, 0x0, sizeof(ad));
+ *
+ * // Runs the Tizen application framework
+ * return ui_app_main(argc, argv, &event_callback, &ad);
+ * }
+ *
+ * @endcode
+ */
+class DALI_IMPORT_API EvasPlugin : public Dali::Integration::SceneHolder
+{
+public:
+
+ typedef Signal<void (void)> EvasPluginSignalType;
+
+public:
+
+ /**
+ * @brief This is the constructor for Tizen EFL applications
+ *
+ * @param[in] parentEvasObject Parent of the new Evas object
+ * @param[in] width The initial width of the Dali view port
+ * @param[in] height The initial height of the Dali view port
+ * @param[in] isTranslucent Whether the Evas object is translucent or not
+ */
+ static EvasPlugin New( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent );
+
+ /**
+ * @brief Constructs an empty handle
+ */
+ EvasPlugin();
+
+ /**
+ * @brief Copy constructor
+ */
+ EvasPlugin( const EvasPlugin& evasPlugin );
+
+ /**
+ * @brief Assignment operator
+ */
+ EvasPlugin& operator=( const EvasPlugin& evasPlugin );
+
+ /**
+ * @brief Destructor
+ */
+ ~EvasPlugin();
+
+public:
+
+ /**
+ * @brief Runs the Evas plugin (rendering, event handling, etc)
+ */
+ void Run();
+
+ /**
+ * @brief Pauses the Evas plugin
+ */
+ void Pause();
+
+ /**
+ * @brief Resumes the Evas plugin
+ */
+ void Resume();
+
+ /**
+ * @brief Stops the Evas plugin
+ */
+ void Stop();
+
+ /**
+ * @brief This returns the Evas_Object* which is created internally
+ *
+ * Applications should append this access object to custom focus chain for accessibility
+ *
+ * e.g., elm_object_focus_custom_chain_append(layout, dali_access_object, NULL);
+ *
+ * @return Evas_Object* Elm access object which Dali image Evas object is registered
+ */
+ Evas_Object* GetAccessEvasObject();
+
+ /**
+ * @brief This returns the Evas_Object* which is created internally
+ *
+ * @return Evas_Object* Evas object which is rendered by Dali
+ */
+ Evas_Object* GetDaliEvasObject();
+
+public: // Signals
+
+ /**
+ * @brief Signal to notify the client when the application is ready to be initialized
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& InitSignal();
+
+ /**
+ * @brief Signal to notify the user when the application is about to be terminated
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& TerminateSignal();
+
+ /**
+ * @brief Signal to notify the client when the EvasPlugin is about to be paused
+ *
+ * The user should connect to this signal if the user needs to perform any special
+ * activities when the application is about to be paused.
+ * @return The signal
+ */
+ EvasPluginSignalType& PauseSignal();
+
+ /**
+ * @brief Signal to notify the client when the adpator has resumed
+ *
+ * The user should connect to this signal if the user needs to perform any special
+ * activities when the application has resumed.
+ * @return The signal
+ */
+ EvasPluginSignalType& ResumeSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object is resized
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& ResizeSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object gets the keyboard focus
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& FocusedSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object loses the keyboard focus
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& UnFocusedSignal();
+
+public: // Not intended for application developers
+ /**
+ * @brief Internal constructor
+ */
+ explicit DALI_INTERNAL EvasPlugin( Internal::EvasPlugin* evasPlugin );
+
+};
+
+/**
+ * @}
+ */
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // __DALI_EXTENSION_EVAS_PLUGIN_H__
--- /dev/null
+evas_plugin_devel_header_files = \
+ $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.h
+
+evas_plugin_devel_src_files = \
+ $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.cpp
--- /dev/null
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/key-devel.h>
+#include <dali/public-api/events/device.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-event-interface.h>
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-event-handler.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const int TOUCH_DEVICE_ID = 0;
+
+const char* EVAS_OBJECT_FOCUSED_EVENT_NAME = "focused";
+const char* EVAS_OBJECT_UNFOCUSED_EVENT_NAME = "unfocused";
+
+/**
+ * Copied from x server
+ * @brief Retrieve the current milliseconds.
+ *
+ * @return the current milliseconds.
+ */
+unsigned int GetCurrentMilliSeconds( void )
+{
+ struct timeval tv;
+
+ struct timespec tp;
+ static clockid_t clockid;
+
+ if( !clockid )
+ {
+#ifdef CLOCK_MONOTONIC_COARSE
+ if( clock_getres( CLOCK_MONOTONIC_COARSE, &tp ) == 0 && ( tp.tv_nsec / 1000 ) <= 1000 && clock_gettime( CLOCK_MONOTONIC_COARSE, &tp ) == 0 )
+ {
+ clockid = CLOCK_MONOTONIC_COARSE;
+ }
+ else
+#endif
+ if( clock_gettime( CLOCK_MONOTONIC, &tp ) == 0 )
+ {
+ clockid = CLOCK_MONOTONIC;
+ }
+ else
+ {
+ clockid = ~0L;
+ }
+ }
+ if( clockid != ~0L && clock_gettime( clockid, &tp ) == 0 )
+ {
+ return ( tp.tv_sec * 1000 ) + ( tp.tv_nsec / 1000000L );
+ }
+
+ gettimeofday( &tv, NULL );
+ return ( tv.tv_sec * 1000 ) + ( tv.tv_usec / 1000 );
+}
+
+/**
+ * @brief Retrieve the dali screen touch point.
+ *
+ * @param[in] canvasX is the x of canvas position
+ * @param[in] canvasY is the y of canvas position
+ * @param[in] evasObject is rendered by dali
+ * @param[out] screenX is the x of local position of evasObject
+ * @param[out] screenY is the y of local position of evasObject
+ */
+void GetScreenPosition( Evas_Coord canvasX, Evas_Coord canvasY, Evas_Object* evasObject, Evas_Coord &screenX, Evas_Coord &screenY )
+{
+ Evas_Coord objX = 0, objY = 0, objW = 0, objH = 0;
+ evas_object_geometry_get( evasObject, &objX, &objY, &objW, &objH );
+
+ screenX = canvasX - objX;
+ screenY = canvasY - objY;
+}
+
+void ConvertActionInfo( Elm_Access_Action_Info* elmActionInfo, Dali::Extension::Internal::AccessActionInfo& daliActionInfo )
+{
+ daliActionInfo.x = elmActionInfo->x;
+ daliActionInfo.y = elmActionInfo->y;
+ daliActionInfo.mouseType = elmActionInfo->mouse_type;
+
+ switch( elmActionInfo->action_type )
+ {
+ case ELM_ACCESS_ACTION_HIGHLIGHT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_READ:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_READ;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_PREV;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_NEXT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_ACTIVATE:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_ACTIVATE;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_UNHIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_SCROLL:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_SCROLL;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UP:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_UP;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_DOWN:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_DOWN;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_BACK:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_BACK;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ switch( elmActionInfo->action_by )
+ {
+ case ELM_ACCESS_ACTION_HIGHLIGHT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_READ:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_READ;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_PREV;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_NEXT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_ACTIVATE:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_ACTIVATE;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_UNHIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_SCROLL:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_SCROLL;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UP:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_UP;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_DOWN:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_DOWN;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_BACK:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_BACK;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ daliActionInfo.highlightCycle = elmActionInfo->highlight_cycle;
+ daliActionInfo.timeStamp = GetCurrentMilliSeconds();
+}
+
+template<typename Type>
+void FillIntegrationKeyEvent( Type keyEvent, Integration::KeyEvent& result )
+{
+ // KeyName
+ if( keyEvent->keyname )
+ {
+ result.keyName = keyEvent->keyname;
+ }
+
+ // LogicalKey
+ if( keyEvent->key )
+ {
+ result.logicalKey = keyEvent->key;
+ }
+
+ // KeyString
+ if( keyEvent->string )
+ {
+ result.keyString = keyEvent->string;
+ }
+
+ // KeyCode
+ if( !strncmp( keyEvent->keyname, "Keycode-", 8 ) )
+ {
+ result.keyCode = atoi( keyEvent->keyname + 8 );
+ }
+ else
+ {
+ int keycode = Dali::DevelKey::GetDaliKeyCode( keyEvent->keyname );
+ result.keyCode = ( keycode == Dali::DALI_KEY_INVALID ) ? 0 : keycode;
+ }
+
+ // Modifier
+ result.keyModifier = 0;
+ if( evas_key_modifier_is_set( keyEvent->modifiers, "Shift" ) )
+ {
+ result.keyModifier |= ECORE_EVENT_MODIFIER_SHIFT;
+ }
+ if( evas_key_modifier_is_set( keyEvent->modifiers, "Alt" ) )
+ {
+ result.keyModifier |= ECORE_EVENT_MODIFIER_ALT;
+ }
+ if( evas_key_modifier_is_set( keyEvent->modifiers, "AltGr" ) )
+ {
+ result.keyModifier |= ECORE_EVENT_MODIFIER_ALTGR;
+ }
+ if( evas_key_modifier_is_set( keyEvent->modifiers, "Control" ) )
+ {
+ result.keyModifier |= ECORE_EVENT_MODIFIER_CTRL;
+ }
+ if( evas_key_modifier_is_set( keyEvent->modifiers, "Win" ) ||
+ evas_key_modifier_is_set( keyEvent->modifiers, "Super" ) ||
+ evas_key_modifier_is_set( keyEvent->modifiers, "Hyper" ) )
+ {
+ result.keyModifier |= ECORE_EVENT_MODIFIER_WIN;
+ }
+
+ // Time
+ result.time = keyEvent->timestamp;
+
+ // Compose
+ if( keyEvent->compose )
+ {
+ result.compose = keyEvent->compose;
+ }
+
+ // DeviceName
+ const char* ecoreDeviceName = ecore_device_name_get( keyEvent->dev );
+ if( ecoreDeviceName )
+ {
+ result.deviceName = ecoreDeviceName;
+ }
+
+ // DeviceClass
+ Ecore_Device_Class ecoreDeviceClass = ecore_device_class_get( keyEvent->dev );
+ switch( ecoreDeviceClass )
+ {
+ case ECORE_DEVICE_CLASS_SEAT:
+ {
+ result.deviceClass = Device::Class::USER;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_KEYBOARD:
+ {
+ result.deviceClass = Device::Class::KEYBOARD;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_MOUSE:
+ {
+ result.deviceClass = Device::Class::MOUSE;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_TOUCH:
+ {
+ result.deviceClass = Device::Class::TOUCH;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_PEN:
+ {
+ result.deviceClass = Device::Class::PEN;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_POINTER:
+ {
+ result.deviceClass = Device::Class::POINTER;
+ break;
+ }
+ case ECORE_DEVICE_CLASS_GAMEPAD:
+ {
+ result.deviceClass = Device::Class::GAMEPAD;
+ break;
+ }
+ default:
+ {
+ result.deviceClass = Device::Class::NONE;
+ break;
+ }
+ }
+
+ // DeviceSubClass
+ Ecore_Device_Subclass ecoreDeviceSubclass = ecore_device_subclass_get( keyEvent->dev );
+
+ switch( ecoreDeviceSubclass )
+ {
+ case ECORE_DEVICE_SUBCLASS_FINGER:
+ {
+ result.deviceSubclass = Device::Subclass::FINGER;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_FINGERNAIL:
+ {
+ result.deviceSubclass = Device::Subclass::FINGERNAIL;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_KNUCKLE:
+ {
+ result.deviceSubclass = Device::Subclass::KNUCKLE;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_PALM:
+ {
+ result.deviceSubclass = Device::Subclass::PALM;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_HAND_SIZE:
+ {
+ result.deviceSubclass = Device::Subclass::HAND_SIDE;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_HAND_FLAT:
+ {
+ result.deviceSubclass = Device::Subclass::HAND_FLAT;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_PEN_TIP:
+ {
+ result.deviceSubclass = Device::Subclass::PEN_TIP;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_TRACKPAD:
+ {
+ result.deviceSubclass = Device::Subclass::TRACKPAD;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_TRACKPOINT:
+ {
+ result.deviceSubclass = Device::Subclass::TRACKPOINT;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_TRACKBALL:
+ {
+ result.deviceSubclass = Device::Subclass::TRACKBALL;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_REMOCON:
+ {
+ result.deviceSubclass = Device::Subclass::REMOCON;
+ break;
+ }
+ case ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD:
+ {
+ result.deviceSubclass = Device::Subclass::VIRTUAL_KEYBOARD;
+ break;
+ }
+ default:
+ {
+ result.deviceSubclass = Device::Subclass::NONE;
+ break;
+ }
+ }
+}
+
+} // anonymous namespace
+
+EvasPluginEventHandler::EvasPluginEventHandler( EvasPluginEventInterface& evasPluginEventInterface )
+: mEvasPluginEventInterface( evasPluginEventInterface )
+{
+ EvasWrapper* evasWrapper = mEvasPluginEventInterface.GetEvasWrapper();
+ Evas_Object* renderTarget = evasWrapper->GetRenderTarget();
+ Evas_Object* accessibilityTarget = evasWrapper->GetAccessibilityTarget();
+ Evas_Object* focusTarget = evasWrapper->GetFocusTarget();
+ Evas* renderTargetAsEvas = evas_object_evas_get( renderTarget );
+
+ // Register the evas event callbacks
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_DOWN, OnEvasObjectMouseDown, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_UP, OnEvasObjectMouseUp, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_MOVE, OnEvasObjectMouseMove, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_DOWN, OnEvasObjectMultiTouchDown, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_UP, OnEvasObjectMultiTouchUp, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_MOVE, OnEvasObjectMultiTouchMove, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_KEY_DOWN, OnEvasObjectKeyDown, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_KEY_UP, OnEvasObjectKeyUp, &evasPluginEventInterface );
+
+ // Register the evas geometry callbacks
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOVE, OnEvasObjectMove, &evasPluginEventInterface );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_RESIZE, OnEvasObjectResize, &evasPluginEventInterface );
+
+ // Register the evas focus callbacks
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_FOCUS_IN, OnEvasObjectFocusIn, this );
+ evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut, this );
+
+ evas_event_callback_add( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, OnEvasFocusIn, &evasPluginEventInterface );
+ evas_event_callback_add( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut, &evasPluginEventInterface );
+
+ // Register the evas render callbacks
+ evas_event_callback_add( renderTargetAsEvas, EVAS_CALLBACK_RENDER_POST, OnEvasRenderPost, &evasPluginEventInterface );
+
+ // Register the elm access action callbacks and these callbacks are disconnected when mElmAccessEvasObject is unregistred
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT, OnElmAccessActionHighlight, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_UNHIGHLIGHT, OnElmAccessActionUnhighlight, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, OnElmAccessActionHighlightNext, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, OnElmAccessActionHighlightPrev, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_ACTIVATE, OnElmAccessActionActivate, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_UP, OnElmAccessActionUp, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_DOWN, OnElmAccessActionDown, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_SCROLL, OnElmAccessActionScroll, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_BACK, OnElmAccessActionBack, &evasPluginEventInterface );
+ elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_READ, OnElmAccessActionRead, &evasPluginEventInterface );
+
+ // Register the elm focus callbacks
+ evas_object_smart_callback_add( focusTarget, EVAS_OBJECT_FOCUSED_EVENT_NAME, OnEvasObjectSmartFocused, this );
+ evas_object_smart_callback_add( focusTarget, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused, this );
+}
+
+EvasPluginEventHandler::~EvasPluginEventHandler()
+{
+ EvasWrapper* evasWrapper = mEvasPluginEventInterface.GetEvasWrapper();
+ Evas_Object* renderTarget = evasWrapper->GetRenderTarget();
+ Evas_Object* focusTarget = evasWrapper->GetFocusTarget();
+ Evas* renderTargetAsEvas = evas_object_evas_get( renderTarget );
+
+ // Unregister the evas event callbacks.
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_DOWN, OnEvasObjectMouseDown );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_UP, OnEvasObjectMouseUp );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_MOVE, OnEvasObjectMouseMove );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_DOWN, OnEvasObjectMultiTouchDown );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_UP, OnEvasObjectMultiTouchUp );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_MOVE, OnEvasObjectMultiTouchMove );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_KEY_DOWN, OnEvasObjectKeyDown );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_KEY_UP, OnEvasObjectKeyUp );
+
+ // Unregister the evas geometry callbacks.
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOVE, OnEvasObjectMove );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_RESIZE, OnEvasObjectResize );
+
+ // Unregister the evas focus callbacks
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_FOCUS_IN, OnEvasObjectFocusIn );
+ evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut );
+
+ evas_event_callback_del( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, OnEvasFocusIn );
+ evas_event_callback_del( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut );
+
+ // Register the evas render callbacks
+ evas_event_callback_del( renderTargetAsEvas, EVAS_CALLBACK_RENDER_POST, OnEvasRenderPost );
+
+ // Unregister the elm focus callbacks
+ evas_object_smart_callback_del( focusTarget, EVAS_OBJECT_FOCUSED_EVENT_NAME, OnEvasObjectSmartFocused );
+ evas_object_smart_callback_del( focusTarget, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused );
+}
+
+void EvasPluginEventHandler::EnableEcoreWl2Events()
+{
+ if( !mEcoreEventHandlers.size() )
+ {
+ // Register Window visibility change events
+ mEcoreEventHandlers.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, OnEcoreWl2EventWindowVisibilityChange, &mEvasPluginEventInterface ) );
+ }
+}
+
+void EvasPluginEventHandler::DisableEcoreWl2Events()
+{
+ if( mEcoreEventHandlers.size() )
+ {
+ // Unregister Window events
+ for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandlers.begin(), endIter = mEcoreEventHandlers.end(); iter != endIter; ++iter )
+ {
+ ecore_event_handler_del( *iter );
+ }
+ mEcoreEventHandlers.clear();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Event callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasPluginEventHandler::OnEvasObjectMouseDown( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Mouse_Down* eventMouseDown = static_cast<Evas_Event_Mouse_Down*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMouseDown->canvas.x, eventMouseDown->canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Down, screenX, screenY ) );
+ unsigned long timeStamp = eventMouseDown->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMouseUp( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Mouse_Up* eventMouseUp = static_cast<Evas_Event_Mouse_Up*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMouseUp->canvas.x, eventMouseUp->canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Up, screenX, screenY ) );
+ unsigned long timeStamp = eventMouseUp->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMouseMove( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Mouse_Move* eventMouseMove = static_cast<Evas_Event_Mouse_Move*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMouseMove->cur.canvas.x, eventMouseMove->cur.canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Motion, screenX, screenY ) );
+ unsigned long timeStamp = eventMouseMove->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMouseWheel( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Mouse_Wheel* eventMouseWheel = static_cast<Evas_Event_Mouse_Wheel*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMouseWheel->canvas.x, eventMouseWheel->canvas.y, evasObject, screenX, screenY );
+
+ int direction = eventMouseWheel->direction;
+ unsigned int modifiers = -1; // TODO: Need to check evas modifier
+ Vector2 point = Vector2( screenX, screenY );
+ int z = eventMouseWheel->z;
+ unsigned int timeStamp = eventMouseWheel->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ Dali::Integration::WheelEvent wheelEvent( Dali::Integration::WheelEvent::MOUSE_WHEEL, direction, modifiers, point, z, timeStamp );
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectWheelEvent( wheelEvent );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMultiTouchDown( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Multi_Down* eventMultiDown = static_cast<Evas_Event_Multi_Down*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMultiDown->canvas.x, eventMultiDown->canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( eventMultiDown->device, TouchPoint::Down, screenX, screenY ) );
+ unsigned long timeStamp = eventMultiDown->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMultiTouchUp( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Multi_Up* eventMultiUp = static_cast<Evas_Event_Multi_Up*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMultiUp->canvas.x, eventMultiUp->canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( eventMultiUp->device, TouchPoint::Up, screenX, screenY ) );
+ unsigned long timeStamp = eventMultiUp->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectMultiTouchMove( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Multi_Move* eventMultiMove = static_cast<Evas_Event_Multi_Move*>( event );
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition( eventMultiMove->cur.canvas.x, eventMultiMove->cur.canvas.y, evasObject, screenX, screenY );
+
+ Dali::Integration::Point point( TouchPoint( eventMultiMove->device, TouchPoint::Motion, screenX, screenY ) );
+ unsigned long timeStamp = eventMultiMove->timestamp;
+ if( timeStamp < 1 )
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasPluginEventHandler::OnEvasObjectKeyDown( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Key_Down* keyEvent = static_cast<Evas_Event_Key_Down*>( event );
+
+ // Create KeyEvent
+ Integration::KeyEvent integKeyEvent;
+
+ integKeyEvent.state = Integration::KeyEvent::Down;
+
+ FillIntegrationKeyEvent( keyEvent, integKeyEvent );
+
+ // Feed to EvasPlugin
+ ( static_cast<EvasPluginEventInterface*>( data ) )->OnEvasObjectKeyEvent( integKeyEvent );
+}
+
+void EvasPluginEventHandler::OnEvasObjectKeyUp( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Evas_Event_Key_Up* keyEvent = static_cast<Evas_Event_Key_Up*>( event );
+
+ // Create KeyEvent
+ Integration::KeyEvent integKeyEvent;
+
+ integKeyEvent.state = Integration::KeyEvent::Up;
+
+ FillIntegrationKeyEvent( keyEvent, integKeyEvent );
+
+ // Feed to EvasPlugin
+ ( static_cast<EvasPluginEventInterface*>( data ) )->OnEvasObjectKeyEvent( integKeyEvent );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Geometry callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasPluginEventHandler::OnEvasObjectMove( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Rect<int> geometry;
+ evas_object_geometry_get( evasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height );
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectMove( geometry );
+}
+
+void EvasPluginEventHandler::OnEvasObjectResize( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ Rect<int> geometry;
+ evas_object_geometry_get( evasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height );
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasObjectResize( geometry );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasPluginEventHandler::OnEvasObjectFocusIn( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ EvasPluginEventHandler* eventHandler = static_cast<EvasPluginEventHandler*>( data );
+
+ eventHandler->EnableEcoreWl2Events();
+ eventHandler->GetEvasPluginInterface().OnEvasObjectFocusIn();
+}
+
+void EvasPluginEventHandler::OnEvasObjectFocusOut( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+ EvasPluginEventHandler* eventHandler = static_cast<EvasPluginEventHandler*>( data );
+
+ eventHandler->DisableEcoreWl2Events();
+ eventHandler->GetEvasPluginInterface().OnEvasObjectFocusOut();
+}
+
+void EvasPluginEventHandler::OnEvasFocusIn( void *data, Evas* evas, void* event )
+{
+}
+
+void EvasPluginEventHandler::OnEvasFocusOut( void *data, Evas* evas, void* event )
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Render callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasPluginEventHandler::OnEvasRenderPost( void *data, Evas* evas, void* event )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ pEvasPlugin->OnEvasPostRender();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Access callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionHighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionUnhighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionHighlightNext( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionHighlightPrev( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionActivate( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionScroll( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionUp( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionDown( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionBack( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasPluginEventHandler::OnElmAccessActionRead( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo( actionInfo, daliActionInfo );
+
+ return pEvasPlugin->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasPluginEventHandler::OnEvasObjectSmartFocused( void *data, Evas_Object* evasObject, void* event )
+{
+ EvasPluginEventHandler* eventHandler = static_cast<EvasPluginEventHandler*>( data );
+ EvasPluginEventInterface& evasPlugin = eventHandler->GetEvasPluginInterface();
+
+ if( eventHandler->mEvasPluginEventInterface.GetEvasWrapper()->GetFocusTarget() == evasObject )
+ {
+ Evas_Object* topWidget = elm_object_top_widget_get( evasObject );
+
+ if( !strcmp( "elm_win", elm_object_widget_type_get( topWidget ) ) )
+ {
+ if( elm_win_focus_highlight_enabled_get( topWidget ) == EINA_TRUE )
+ {
+ // To allow that KeyboardFocusManager can handle the keyboard focus
+ Dali::Integration::KeyEvent fakeKeyEvent( Dali::KeyEvent( "", "", 0, 0, 100, KeyEvent::Down ) );
+
+ evasPlugin.OnEvasObjectKeyEvent( fakeKeyEvent );
+ }
+ }
+
+ evas_object_focus_set( eventHandler->mEvasPluginEventInterface.GetEvasWrapper()->GetRenderTarget(), EINA_TRUE );
+ }
+}
+
+void EvasPluginEventHandler::OnEvasObjectSmartUnfocused( void *data, Evas_Object* evasObject, void* event )
+{
+ EvasPluginEventHandler* eventHandler = static_cast<EvasPluginEventHandler*>( data );
+ if( eventHandler->mEvasPluginEventInterface.GetEvasWrapper()->GetFocusTarget() == evasObject )
+ {
+ evas_object_focus_set( eventHandler->mEvasPluginEventInterface.GetEvasWrapper()->GetRenderTarget(), EINA_FALSE );
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Ecore Wl2 callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasPluginEventHandler::OnEcoreWl2EventWindowVisibilityChange( void* data, int type, void* event )
+{
+ Ecore_Wl2_Event_Window_Visibility_Change* eventWindowVisibilityChange = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>( event );
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>( data );
+
+ // 0 is visible and 1 is invisible
+ pEvasPlugin->OnEcoreWl2VisibilityChange( !eventWindowVisibilityChange->fully_obscured );
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER__
+#define __DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER__
+
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+#include <Elementary.h>
+#include <Ecore_Wl2.h>
+#include <Ecore_Input.h>
+#include <Ecore_IMF.h>
+#include <Ecore_IMF_Evas.h>
+
+#include <string>
+#include <vector>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginEventInterface;
+
+class EvasPluginEventHandler
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param[in] evasPluginEventInterface Used to send event to evas plugin
+ */
+ EvasPluginEventHandler( EvasPluginEventInterface& evasPluginEventInterface );
+
+ /**
+ * Destructor.
+ */
+ ~EvasPluginEventHandler();
+
+public:
+
+ EvasPluginEventInterface& GetEvasPluginInterface()
+ {
+ return mEvasPluginEventInterface;
+ }
+
+private:
+
+ void EnableEcoreWl2Events();
+
+ void DisableEcoreWl2Events();
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Event callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when the mouse down is received
+ */
+ static void OnEvasObjectMouseDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the mouse up is received
+ */
+ static void OnEvasObjectMouseUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the mouse move is received
+ */
+ static void OnEvasObjectMouseMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the mouse wheel is received
+ */
+ static void OnEvasObjectMouseWheel( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the multi-touch down is received
+ */
+ static void OnEvasObjectMultiTouchDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the multi-touch up is received
+ */
+ static void OnEvasObjectMultiTouchUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when the multi-touch move is received
+ */
+ static void OnEvasObjectMultiTouchMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when key down is received
+ */
+ static void OnEvasObjectKeyDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when key up is received
+ */
+ static void OnEvasObjectKeyUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Geometry callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when move is received
+ */
+ static void OnEvasObjectMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when resize is received
+ */
+ static void OnEvasObjectResize( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Focus callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when evas object focus in is received
+ */
+ static void OnEvasObjectFocusIn( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when evas object focus out is received
+ */
+ static void OnEvasObjectFocusOut( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+ /**
+ * @brief Called when evas focus in is received
+ */
+ static void OnEvasFocusIn( void *data, Evas* evas, void* event );
+
+ /**
+ * @brief Called when evas focus out is received
+ */
+ static void OnEvasFocusOut( void *data, Evas* evas, void* event );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Render callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when evas render post
+ */
+ static void OnEvasRenderPost( void *data, Evas* evas, void* event );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Elm Access callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ static Eina_Bool OnElmAccessActionHighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionUnhighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionHighlightNext( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionHighlightPrev( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionActivate( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionScroll( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionUp( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionDown( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionBack( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ static Eina_Bool OnElmAccessActionRead( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Elm Focus callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ static void OnEvasObjectSmartFocused( void* data, Evas_Object* evasObject, void* event );
+
+ static void OnEvasObjectSmartUnfocused( void* data, Evas_Object* evasObject, void* event );
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Ecore Wl2 callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ static Eina_Bool OnEcoreWl2EventWindowVisibilityChange( void* data, int type, void* event );
+
+private:
+
+ EvasPluginEventInterface& mEvasPluginEventInterface;
+ std::vector<Ecore_Event_Handler*> mEcoreEventHandlers;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_EVENT_INTERFACE_H__
+#define __DALI_EXTENSION_INTERNAL_EVAS_EVENT_INTERFACE_H__
+
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/events/point.h>
+#include <dali/integration-api/events/wheel-event-integ.h>
+#include <dali/integration-api/events/key-event-integ.h>
+
+namespace Dali
+{
+
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasWrapper;
+
+enum AccessActionType
+{
+ ACCESS_ACTION_FIRST = -1,
+
+ ACCESS_ACTION_HIGHLIGHT, /* highlight an object */
+
+ ACCESS_ACTION_UNHIGHLIGHT, /* unhighlight an object */
+
+ ACCESS_ACTION_HIGHLIGHT_NEXT, /* set highlight to next object */
+
+ ACCESS_ACTION_HIGHLIGHT_PREV, /* set highlight to previous object */
+
+ ACCESS_ACTION_ACTIVATE, /* activate a highlight object */
+
+ ACCESS_ACTION_SCROLL, /* scroll if one of highlight object parents is scrollable */
+
+ ACCESS_ACTION_UP, /* change value up of highlight object */
+
+ ACCESS_ACTION_DOWN, /* change value down of highlight object */
+
+ ACCESS_ACTION_BACK, /* go back to a previous view (ex: pop naviframe item) */
+
+ ACCESS_ACTION_READ, /* highlight an object */
+
+ ACCESS_ACTION_LAST
+};
+
+struct AccessActionInfo
+{
+ int x;
+ int y;
+ unsigned int mouseType; /* 0: mouse down
+ 1: mouse move
+ 2: mouse up */
+ AccessActionType actionType;
+ AccessActionType actionBy;
+ bool highlightCycle : 1;
+ unsigned int timeStamp;
+};
+
+class EvasPluginEventInterface
+{
+public:
+ /**
+ * @brief Gets an EvasWrapper instance to connect events
+ *
+ * @return The EvasWrapper instance
+ */
+ virtual EvasWrapper* GetEvasWrapper() const = 0;
+
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] touchPoint is the information of touch
+ * @param[in] timeStamp is that touch is occured
+ */
+ virtual void OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp ) = 0;
+
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] wheelEvent is the information of wheel
+ */
+ virtual void OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent ) = 0;
+
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] keyEvent is the information of key
+ */
+ virtual void OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent ) = 0;
+
+ /**
+ * @brief Handle evas object geometry
+ *
+ * @param geometry is the move information of evas object
+ */
+ virtual void OnEvasObjectMove( const Rect<int>& geometry ) = 0;
+
+ /**
+ * @brief Handle evas object geometry
+ *
+ * @param geometry is the resize information of evas object
+ */
+ virtual void OnEvasObjectResize( const Rect<int>& geometry ) = 0;
+
+ /**
+ * @brief Handle evas object focus in
+ */
+ virtual void OnEvasObjectFocusIn() = 0;
+
+ /**
+ * @brief Handle evas object focus out
+ */
+ virtual void OnEvasObjectFocusOut() = 0;
+
+ /**
+ * @brief Handle evas object render post
+ */
+ virtual void OnEvasPostRender() = 0;
+
+ /**
+ * @brief Called when the accessibility action event dispatched from elm_access.
+ * @param[in] accessActionInfo elm accessibility action information structure
+ * @return True if the event was handled
+ */
+ virtual bool OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo ) = 0;
+
+ /**
+ * @brief Process the ecore wayland visibility.
+ *
+ * @param[in] visibility True is that ecore wayland window is show up and false is not
+ */
+ virtual void OnEcoreWl2VisibilityChange( bool visibility ) = 0;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard.h>
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/integration-api/adaptors/native-render-surface.h>
+#include <dali/integration-api/adaptors/native-render-surface-factory.h>
+#include <dali/integration-api/adaptors/trigger-event-factory.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+#include <dali-extension/internal/evas-plugin/evas-event-handler.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+// Initialize static members
+
+Adaptor* EvasPlugin::mAdaptor = nullptr;
+
+uint32_t EvasPlugin::mEvasPluginCount = 0;
+
+SingletonService EvasPlugin::mSingletonService = SingletonService();
+
+
+IntrusivePtr< EvasPlugin > EvasPlugin::New( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent )
+{
+ IntrusivePtr< EvasPlugin > evasPlugin = new EvasPlugin( parentEvasObject, width, height, isTranslucent );
+ return evasPlugin;
+}
+
+EvasPlugin::EvasPlugin( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent )
+: mEvasWrapper( new EvasWrapper( parentEvasObject, width, height, isTranslucent ) ),
+ mRenderNotification(),
+ mEvasPluginEventHandler(),
+ mState( READY ),
+ mIsFocus( false ),
+ mIsTranslucent( isTranslucent )
+{
+ DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the evas plugin." );
+
+ // Increase plugin count.
+ mEvasPluginCount++;
+
+ // Create surface
+ mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( PositionSize( 0, 0, width, height ), isTranslucent ) );
+}
+
+void EvasPlugin::Initialize()
+{
+ NativeRenderSurface* surface = static_cast<NativeRenderSurface*>( mSurface.get() );
+
+ Dali::Integration::SceneHolder sceneHolderHandler = Dali::Extension::EvasPlugin( this );
+
+ if( !mAdaptor )
+ {
+ // Create the singleton service
+ mSingletonService = SingletonService::New();
+
+ // Create an adaptor or add new scene holder to the adaptor
+ mAdaptor = &Adaptor::New( sceneHolderHandler, *surface, Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS );
+ }
+ else
+ {
+ mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
+ }
+
+ // Connect callback to be notified when the surface is rendered
+ TriggerEventFactory triggerEventFactory;
+
+ mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &EvasPlugin::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
+
+ surface->SetRenderNotification( mRenderNotification.get() );
+}
+
+EvasPlugin::~EvasPlugin()
+{
+ mEvasPluginCount--;
+
+ if( !mEvasPluginCount )
+ {
+ delete mAdaptor;
+
+ mSingletonService.UnregisterAll();
+ }
+}
+
+void EvasPlugin::Run()
+{
+ if( READY == mState )
+ {
+ if( !mEvasPluginEventHandler )
+ {
+ mEvasPluginEventHandler = std::unique_ptr< EvasPluginEventHandler >( new EvasPluginEventHandler( *this ) );
+ }
+
+ // Start the adaptor
+ mAdaptor->Start();
+
+ mInitSignal.Emit();
+
+ mAdaptor->NotifySceneCreated();
+
+ mState = RUNNING;
+ }
+}
+
+void EvasPlugin::Pause()
+{
+ if( mState == RUNNING )
+ {
+ mState = SUSPENDED;
+
+ Hide();
+
+ mPauseSignal.Emit();
+ }
+}
+
+void EvasPlugin::Resume()
+{
+ if( mState == SUSPENDED )
+ {
+ Show();
+
+ mResumeSignal.Emit();
+
+ mState = RUNNING;
+ }
+}
+
+void EvasPlugin::Stop()
+{
+ if( mState != STOPPED )
+ {
+ // Stop the adaptor
+ mAdaptor->Stop();
+ mState = STOPPED;
+
+ mTerminateSignal.Emit();
+ }
+}
+
+Dali::Any EvasPlugin::GetNativeHandle() const
+{
+ return mEvasWrapper->GetNativeWindow();
+}
+
+NativeRenderSurface* EvasPlugin::GetNativeRenderSurface() const
+{
+ return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
+}
+
+Evas_Object* EvasPlugin::GetAccessEvasObject()
+{
+ return mEvasWrapper->GetAccessibilityTarget();
+}
+
+Evas_Object* EvasPlugin::GetDaliEvasObject()
+{
+ return mEvasWrapper->GetFocusTarget();
+}
+
+void EvasPlugin::ResizeSurface( int width, int height )
+{
+ if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
+ {
+ return;
+ }
+
+ PositionSize currentSize = mSurface->GetPositionSize();
+ if( currentSize.width == width && currentSize.height == height )
+ {
+ return;
+ }
+
+ mSurface->MoveResize( PositionSize( 0, 0, width, height ) );
+
+ SurfaceResized();
+
+ Adaptor::SurfaceSize newSize( width, height );
+
+ // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
+ mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
+
+ mResizeSignal.Emit();
+
+ mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
+}
+
+void EvasPlugin::OnPostRender()
+{
+ // Bind offscreen surface to the evas object
+ NativeRenderSurface* surface = GetNativeRenderSurface();
+
+ DALI_ASSERT_DEBUG( surface && "Surface is null in EvasPlugin" );
+
+ tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
+
+ if( !tbmSurface )
+ {
+ return;
+ }
+
+ mEvasWrapper->BindTBMSurface( tbmSurface );
+
+ mEvasWrapper->RequestRender();
+
+ surface->ReleaseLock();
+}
+
+EvasWrapper* EvasPlugin::GetEvasWrapper() const
+{
+ return mEvasWrapper.get();
+}
+
+void EvasPlugin::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
+{
+ FeedTouchPoint( touchPoint, timeStamp );
+}
+
+void EvasPlugin::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
+{
+ FeedWheelEvent( wheelEvent );
+}
+
+void EvasPlugin::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
+{
+ FeedKeyEvent( keyEvent );
+}
+
+void EvasPlugin::OnEvasObjectMove( const Rect<int>& geometry )
+{
+}
+
+void EvasPlugin::OnEvasObjectResize( const Rect<int>& geometry )
+{
+ ResizeSurface( geometry.width, geometry.height );
+}
+
+void EvasPlugin::OnEvasObjectFocusIn()
+{
+ if( !mIsFocus )
+ {
+ mFocusedSignal.Emit();
+
+ mIsFocus = true;
+ }
+}
+
+void EvasPlugin::OnEvasObjectFocusOut()
+{
+ if( mIsFocus )
+ {
+ mIsFocus = false;
+
+ Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
+ Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
+ if( currentFocused )
+ {
+ focusManager.RemoveFocus( currentFocused );
+ }
+
+ Clipboard::Get().HideClipboard();
+
+ mUnFocusedSignal.Emit();
+ }
+}
+
+void EvasPlugin::OnEvasPostRender()
+{
+}
+
+bool EvasPlugin::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
+{
+ bool ret = false;
+
+ if( mAdaptor == nullptr )
+ {
+ return ret;
+ }
+
+ Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
+ if( accessibilityAdaptor )
+ {
+ switch( accessActionInfo.actionBy )
+ {
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
+ case Dali::Extension::Internal::ACCESS_ACTION_READ:
+ {
+ ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
+ ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
+ if(!ret)
+ {
+ // when focus moving was failed, clear the focus
+ accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
+ ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
+ if(!ret)
+ {
+ // when focus moving was failed, clear the focus
+ accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
+ {
+ ret = accessibilityAdaptor.HandleActionActivateEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ ret = accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
+ {
+ Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
+
+ if( eo )
+ {
+ int touchType = accessActionInfo.mouseType;
+
+ TouchPoint::State state( TouchPoint::Down );
+
+ if( touchType == 0 )
+ {
+ state = TouchPoint::Down; // mouse down
+ }
+ else if( touchType == 1 )
+ {
+ state = TouchPoint::Motion; // mouse move
+ }
+ else if( touchType == 2 )
+ {
+ state = TouchPoint::Up; // mouse up
+ }
+ else
+ {
+ state = TouchPoint::Interrupted; // error
+ }
+
+ // Send touch event to accessibility manager.
+ Evas_Coord rel_x, rel_y, obj_x, obj_y, obj_w, obj_h;
+
+ evas_object_geometry_get( eo, &obj_x, &obj_y, &obj_w, &obj_h );
+
+ rel_x = accessActionInfo.x - obj_x;
+ rel_y = accessActionInfo.y - obj_y;
+
+ TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
+
+ ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
+ }
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_UP:
+ {
+ ret = accessibilityAdaptor.HandleActionUpEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
+ {
+ ret = accessibilityAdaptor.HandleActionDownEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_BACK:
+ default:
+ {
+ DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
+ }
+
+ break;
+ }
+ }
+ else
+ {
+ DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
+ }
+
+ return ret;
+}
+
+void EvasPlugin::OnEcoreWl2VisibilityChange( bool visibility )
+{
+ DALI_LOG_RELEASE_INFO( "EvasPlugin::OnEcoreWl2VisibilityChange( %s )", visibility ? "T" : "F" );
+
+ if( visibility )
+ {
+ Show();
+ }
+ else
+ {
+ Hide();
+
+ mAdaptor->ReleaseSurfaceLock();
+ }
+}
+
+void EvasPlugin::Show()
+{
+ if( !mVisible )
+ {
+ mVisible = true;
+
+ mAdaptor->OnWindowShown();
+ }
+}
+
+void EvasPlugin::Hide()
+{
+ if( mVisible )
+ {
+ mVisible = false;
+
+ mAdaptor->OnWindowHidden();
+ }
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <Ecore_IMF_Evas.h>
+
+#include <dali/devel-api/adaptor-framework/singleton-service.h>
+#include <dali/integration-api/adaptors/scene-holder-impl.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/signals/connection-tracker.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-event-interface.h>
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+class Adaptor;
+class NativeRenderSurface;
+class TriggerEventInterface;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginEventHandler;
+class EvasWrapper;
+
+/**
+ * Implementation of the EvasPlugin class.
+ */
+class EvasPlugin : public Dali::Internal::Adaptor::SceneHolder,
+ public ConnectionTracker,
+ public Extension::Internal::EvasPluginEventInterface
+{
+public:
+
+ typedef Dali::Extension::EvasPlugin::EvasPluginSignalType EvasPluginSignalType;
+
+ /**
+ * @brief Create a new evas plugin
+ * @param[in] parentEvasObject A pointer of the parent evas object
+ * @param[in] width The width of Dali view port
+ * @param[in] height The height of Dali view port
+ * @param[in] isTranslucent Whether the evas object is translucent or not
+ */
+ static IntrusivePtr<EvasPlugin> New( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent );
+
+public:
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Start()
+ */
+ void Run();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Pause()
+ */
+ void Pause();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Resume()
+ */
+ void Resume();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Stop()
+ */
+ void Stop();
+
+ /**
+ * @brief Gets the native handle.
+ * @note When users call this function, it wraps the actual type used by the underlying system.
+ * @return The native handle or an empty handle
+ */
+ Dali::Any GetNativeHandle() const override;
+
+ /**
+ * @brief Get the native render surface
+ * @return The render surface
+ */
+ NativeRenderSurface* GetNativeRenderSurface() const;
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::GetAccessEvasObject()
+ */
+ Evas_Object* GetAccessEvasObject();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::GetDaliEvasObject()
+ */
+ Evas_Object* GetDaliEvasObject();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::InitSignal()
+ */
+ EvasPluginSignalType& InitSignal()
+ {
+ return mInitSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::TerminateSignal()
+ */
+ EvasPluginSignalType& TerminateSignal()
+ {
+ return mTerminateSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::PauseSignal()
+ */
+ EvasPluginSignalType& PauseSignal()
+ {
+ return mPauseSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::ResumeSignal()
+ */
+ EvasPluginSignalType& ResumeSignal()
+ {
+ return mResumeSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::ResizeSignal()
+ */
+ EvasPluginSignalType& ResizeSignal()
+ {
+ return mResizeSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::FocusedSignal()
+ */
+ EvasPluginSignalType& FocusedSignal()
+ {
+ return mFocusedSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::UnFocusedSignal()
+ */
+ EvasPluginSignalType& UnFocusedSignal()
+ {
+ return mUnFocusedSignal;
+ }
+
+ /*
+ * @bried Initialize EvasPlugin
+ */
+ void Initialize();
+
+private:
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::GetEvasWrapper
+ */
+ EvasWrapper* GetEvasWrapper() const override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectTouchEvent
+ */
+ void OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectWheelEvent
+ */
+ void OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectKeyEvent
+ */
+ void OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectMove
+ */
+ void OnEvasObjectMove( const Rect<int>& geometry ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectResize
+ */
+ void OnEvasObjectResize( const Rect<int>& geometry ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusIn
+ */
+ void OnEvasObjectFocusIn() override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusOut
+ */
+ void OnEvasObjectFocusOut() override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasRenderPost
+ */
+ void OnEvasPostRender() override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessibilityActionEvent
+ */
+ bool OnElmAccessibilityActionEvent( AccessActionInfo& actionInfo ) override;
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEcoreWl2VisibilityChange
+ */
+ void OnEcoreWl2VisibilityChange( bool visibility ) override;
+
+ /**
+ * @brief Resize the surface
+ * @param[in] width The width value
+ * @param[in] height The height value
+ */
+ void ResizeSurface( int width, int height );
+
+ /**
+ * This function is called after drawing by dali.
+ */
+ void OnPostRender();
+
+ /**
+ * @brief Shows the EvasPlugin if it is hidden.
+ */
+ void Show();
+
+ /**
+ * @brief Hides the EvasPlugin if it is showing.
+ */
+ void Hide();
+
+private:
+ /**
+ * Private constructor
+ * @param[in] parentEvasObject A pointer of the parent evas object
+ * @param[in] width The width of Dali view port
+ * @param[in] height The height of Dali view port
+ * @param[in] isTranslucent Whether the evas object is translucent or not
+ */
+ EvasPlugin( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent );
+
+ /**
+ * Destructor
+ */
+ virtual ~EvasPlugin();
+
+ // Undefined
+ EvasPlugin( const EvasPlugin& );
+ EvasPlugin& operator=( EvasPlugin& );
+
+private:
+
+ enum State
+ {
+ READY,
+ RUNNING,
+ SUSPENDED,
+ STOPPED,
+ };
+
+ static Adaptor* mAdaptor;
+ static uint32_t mEvasPluginCount;
+ static SingletonService mSingletonService;
+
+ std::unique_ptr< EvasWrapper > mEvasWrapper;
+ std::unique_ptr< TriggerEventInterface > mRenderNotification;
+ std::unique_ptr< EvasPluginEventHandler > mEvasPluginEventHandler;
+
+ EvasPluginSignalType mInitSignal;
+ EvasPluginSignalType mTerminateSignal;
+ EvasPluginSignalType mPauseSignal;
+ EvasPluginSignalType mResumeSignal;
+ EvasPluginSignalType mResizeSignal;
+ EvasPluginSignalType mFocusedSignal;
+ EvasPluginSignalType mUnFocusedSignal;
+
+ State mState;
+ bool mIsFocus;
+ bool mIsTranslucent;
+};
+
+inline EvasPlugin& GetImplementation( Extension::EvasPlugin& evasPlugin )
+{
+ DALI_ASSERT_ALWAYS( evasPlugin && "evasPluing handle is empty" );
+
+ BaseObject& handle = evasPlugin.GetBaseObject();
+
+ return static_cast<EvasPlugin&>( handle );
+}
+
+inline const EvasPlugin& GetImplementation( const Extension::EvasPlugin& evasPlugin )
+{
+ DALI_ASSERT_ALWAYS( evasPlugin && "evasPlugin handle is empty" );
+
+ const BaseObject& handle = evasPlugin.GetBaseObject();
+
+ return static_cast<const EvasPlugin&>( handle );
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
--- /dev/null
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/rect.h>
+#include <Elementary.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const char* IMAGE_EVAS_OBJECT_NAME = "dali-evas-plugin";
+const char* ELM_OBJECT_STYLE = "transparent";
+const char* ELM_OBJECT_CONTAINER_PART_NAME = "elm.swallow.content";
+
+} // unnamed namespace
+
+EvasWrapper::EvasWrapper( Evas_Object* pluginParent, int width, int height, bool transparent )
+: mEcoreEvas( nullptr ),
+ mImageEvasObject( nullptr ),
+ mAccessibilityEvasObject( nullptr ),
+ mFocusEvasObject( nullptr )
+{
+ Evas* evas = evas_object_evas_get( pluginParent );
+ mEcoreEvas = ecore_evas_ecore_evas_get( evas );
+
+ // Create the image evas object
+ mImageEvasObject = evas_object_image_filled_add( evas );
+ evas_object_name_set( mImageEvasObject, IMAGE_EVAS_OBJECT_NAME );
+ evas_object_image_content_hint_set( mImageEvasObject, EVAS_IMAGE_CONTENT_HINT_DYNAMIC );
+ evas_object_image_alpha_set( mImageEvasObject, transparent ? EINA_TRUE : EINA_FALSE );
+ evas_object_image_size_set( mImageEvasObject, width, height );
+ evas_object_size_hint_weight_set( mImageEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND );
+ evas_object_size_hint_align_set( mImageEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL );
+
+ // Register the elm access to image evas object
+ mAccessibilityEvasObject = elm_access_object_register( mImageEvasObject, pluginParent );
+
+ // Create a button and set style as "focus", if does not want to show the focus, then "transparent"
+ mFocusEvasObject = elm_button_add( pluginParent );
+
+ // Don't need to show the focus boundary here
+ elm_object_style_set( mFocusEvasObject, ELM_OBJECT_STYLE );
+
+ // Set the image evas object to focus object, but event should not be propagated
+ elm_object_part_content_set( mFocusEvasObject, ELM_OBJECT_CONTAINER_PART_NAME, mImageEvasObject );
+ evas_object_propagate_events_set( mImageEvasObject, EINA_FALSE );
+
+ // Set the evas object you want to make focusable as the content of the swallow part
+ evas_object_size_hint_weight_set( mFocusEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND );
+ evas_object_size_hint_align_set( mFocusEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL );
+
+ evas_object_move( mFocusEvasObject, 0, 0 );
+ evas_object_resize( mFocusEvasObject, width, height );
+ evas_object_show( mFocusEvasObject );
+}
+
+EvasWrapper::~EvasWrapper()
+{
+ // Delete the elm focus evas object
+ evas_object_del( mFocusEvasObject );
+ mFocusEvasObject = NULL;
+
+ // Unregister elm_access_object
+ elm_access_object_unregister( mAccessibilityEvasObject );
+ mAccessibilityEvasObject = NULL;
+
+ // Delete the image evas object
+ evas_object_del( mImageEvasObject );
+ mImageEvasObject = NULL;
+}
+
+Ecore_Wl2_Window* EvasWrapper::GetNativeWindow() const
+{
+ return ecore_evas_wayland2_window_get( mEcoreEvas );
+}
+
+PositionSize EvasWrapper::GetGeometry() const
+{
+ PositionSize geometry;
+ evas_object_geometry_get( mImageEvasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height );
+ return geometry;
+}
+
+Evas_Object* EvasWrapper::GetRenderTarget() const
+{
+ return mImageEvasObject;
+}
+
+Evas_Object* EvasWrapper::GetAccessibilityTarget() const
+{
+ return mAccessibilityEvasObject;
+}
+
+Evas_Object* EvasWrapper::GetFocusTarget() const
+{
+ return mFocusEvasObject;
+}
+
+void EvasWrapper::SetFocus()
+{
+ evas_object_focus_set( mImageEvasObject, EINA_TRUE );
+}
+
+void EvasWrapper::BindTBMSurface( tbm_surface_h surface )
+{
+ Evas_Native_Surface nativeSurface;
+ nativeSurface.type = EVAS_NATIVE_SURFACE_TBM;
+ nativeSurface.version = EVAS_NATIVE_SURFACE_VERSION;
+ nativeSurface.data.tbm.buffer = surface;
+ nativeSurface.data.tbm.rot = 0;
+ nativeSurface.data.tbm.ratio = 0;
+ nativeSurface.data.tbm.flip = 0;
+
+ evas_object_image_native_surface_set( mImageEvasObject, &nativeSurface );
+}
+
+void EvasWrapper::RequestRender()
+{
+ evas_object_image_pixels_dirty_set( mImageEvasObject, EINA_TRUE );
+ ecore_evas_manual_render( mEcoreEvas );
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_WRAPPER__
+#define __DALI_EXTENSION_INTERNAL_EVAS_WRAPPER__
+
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Wl2.h>
+#include <tbm_surface.h>
+
+#include <dali/public-api/math/rect.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+typedef Rect<int> PositionSize;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+/**
+ * EvasWrapper is a class which holds a parent evas object for the EvasPlugin.
+ * This creates essential evas ebjects (RenderTarget, AccessibiltyTarget, FocusTarget) to connect evas to Dali properly,
+ * and also provides evas rendering interfaces.
+ */
+class EvasWrapper
+{
+
+public:
+
+ /**
+ * @brief Constructor
+ * @param[in] pluginParent An parent evas object of a evas plugin
+ * @param[in] width The initial width of the Dali view port
+ * @param[in] height The initial height of the Dali view port
+ * @param[in] transparent Whether the Evas object is transparent or not
+ */
+ EvasWrapper( Evas_Object* pluginParent, int width, int height, bool transparent );
+
+ /**
+ * @brief Destructor
+ */
+ ~EvasWrapper();
+
+ /**
+ * @brief Gets current native window object
+ * @return The ecore window object
+ */
+ Ecore_Wl2_Window* GetNativeWindow() const;
+
+ /**
+ * @brief Gets the geometry information
+ * @return The geometry information
+ */
+ PositionSize GetGeometry() const;
+
+ /**
+ * @brief Gets the rendering target evas object
+ * @return The rendering target object
+ */
+ Evas_Object* GetRenderTarget() const;
+
+ /**
+ * @brief Gets the accessibility target evas object
+ * @return The accessibility target object
+ */
+ Evas_Object* GetAccessibilityTarget() const;
+
+ /**
+ * @brief Gets the focus target evas object
+ * @return The focus target object
+ */
+ Evas_Object* GetFocusTarget() const;
+
+ /**
+ * @brief Sets focus
+ */
+ void SetFocus();
+
+ /**
+ * @brief Bind a tbm surface
+ */
+ void BindTBMSurface( tbm_surface_h surface );
+
+ /**
+ * @brief Request rendering
+ */
+ void RequestRender();
+
+private:
+
+ Ecore_Evas* mEcoreEvas;
+ Evas_Object* mImageEvasObject;
+ Evas_Object* mAccessibilityEvasObject;
+ Evas_Object* mFocusEvasObject;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // __DALI_EXTENSION_INTERNAL_EVAS_WRAPPER__
--- /dev/null
+evas_plugin_internal_header_files = \
+ $(extension_src_dir)/internal/evas-plugin/evas-event-handler.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-event-interface.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-wrapper.h
+
+evas_plugin_internal_src_files = \
+ $(extension_src_dir)/internal/evas-plugin/evas-event-handler.cpp \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.cpp \
+ $(extension_src_dir)/internal/evas-plugin/evas-wrapper.cpp
BuildRequires: pkgconfig(dali-toolkit)
BuildRequires: pkgconfig(dlog)
+# For evas-plugin
+BuildRequires: pkgconfig(dali-adaptor-integration)
+BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(ecore-wl2)
+
%description
dali-extension
%manifest dali-extension.manifest
%defattr(-,root,root,-)
%{_sysconfdir}/profile.d/dali.sh
+%{_libdir}/libdali-extension.so*
%license LICENSE
%files devel
%defattr(-,root,root,-)
-%{_includedir}/%{name}/
+%{_includedir}/%{name}/*
%{_libdir}/pkgconfig/*.pc
%files key-extension