[Tizen] Introduce Evas-plugin 10/202410/5 accepted/tizen/unified/20190410.061755 submit/tizen/20190409.081337
authorSinJae Lee <sinjae4b.lee@samsung.com>
Thu, 9 Nov 2017 07:34:04 +0000 (16:34 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Tue, 9 Apr 2019 06:43:51 +0000 (06:43 +0000)
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.

Originally the code was made for Tizen 4.0.

What is diffrent from the original
* Disable 4.0 features (Adaptor, IMFManager)
* Version up: Ecore Wayland -> Ecore Wayland2

To-do when the multi-window refactoring is done
* 4.0 features will be replaced
* Support multiple Evas-plugin
* Consider being an independent rpm (Need to check dependency issue)

Change-Id: Iec8a83e401219f529c5fed033542e9cb2e88527a
Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
18 files changed:
build/tizen/configure.ac
build/tizen/dali-extension.pc.in
build/tizen/evas-plugin/Makefile.am [new file with mode: 0755]
build/tizen/evas-plugin/configure.ac [new file with mode: 0755]
dali-extension/dali-extension.h [new file with mode: 0644]
dali-extension/devel-api/evas-plugin/evas-plugin.cpp [new file with mode: 0755]
dali-extension/devel-api/evas-plugin/evas-plugin.h [new file with mode: 0644]
dali-extension/devel-api/evas-plugin/file.list [new file with mode: 0644]
dali-extension/internal/evas-plugin/ecore-wl-event-handler.cpp [new file with mode: 0644]
dali-extension/internal/evas-plugin/ecore-wl-event-handler.h [new file with mode: 0644]
dali-extension/internal/evas-plugin/evas-event-handler.cpp [new file with mode: 0644]
dali-extension/internal/evas-plugin/evas-event-handler.h [new file with mode: 0644]
dali-extension/internal/evas-plugin/evas-plugin-event-interface.h [new file with mode: 0644]
dali-extension/internal/evas-plugin/evas-plugin-impl.cpp [new file with mode: 0755]
dali-extension/internal/evas-plugin/evas-plugin-impl.h [new file with mode: 0755]
dali-extension/internal/evas-plugin/evas-plugin-visibility-interface.h [new file with mode: 0644]
dali-extension/internal/evas-plugin/file.list [new file with mode: 0644]
packaging/dali-extension.spec

index fbca1d5..b614a40 100755 (executable)
@@ -23,6 +23,7 @@ AC_CONFIG_SUBDIRS(image-loader)
 AC_CONFIG_SUBDIRS(vector-animation-renderer)
 AC_CONFIG_SUBDIRS(color-controller)
 AC_CONFIG_SUBDIRS(web-engine-lwe)
+AC_CONFIG_SUBDIRS(evas-plugin)
 
 AC_CONFIG_FILES([
 Makefile
index 5f2a55a..8e7122e 100644 (file)
@@ -6,6 +6,6 @@ includedir=@INC_DIR@
 Name: DALi extension
 Description: The DALi extension Libaray
 Version: @VERSION@
-Requires: dali-toolkit
+Requires: dali-adaptor dali-toolkit
 Libs: -L${libdir} -ldali-extension
 Cflags: -I${includedir}/dali-extension
diff --git a/build/tizen/evas-plugin/Makefile.am b/build/tizen/evas-plugin/Makefile.am
new file mode 100755 (executable)
index 0000000..5073ba6
--- /dev/null
@@ -0,0 +1,61 @@
+#
+# Copyright (c) 2015 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 evas plugin
+
+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_public_src_files) \
+                       $(evas_plugin_internal_src_files)
+
+libdali_extension_la_DEPENDENCIES =
+
+libdali_extension_la_CXXFLAGS = \
+                       $(DLOG_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_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_public_header_files)
diff --git a/build/tizen/evas-plugin/configure.ac b/build/tizen/evas-plugin/configure.ac
new file mode 100755 (executable)
index 0000000..06b5c12
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/dali-extension/dali-extension.h b/dali-extension/dali-extension.h
new file mode 100644 (file)
index 0000000..762dd96
--- /dev/null
@@ -0,0 +1,23 @@
+#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__
diff --git a/dali-extension/devel-api/evas-plugin/evas-plugin.cpp b/dali-extension/devel-api/evas-plugin/evas-plugin.cpp
new file mode 100755 (executable)
index 0000000..e409419
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-plugin.h"
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+EvasPlugin EvasPlugin::New(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+{
+  Internal::EvasPluginPtr internal = Internal::EvasPlugin::New(parentEvasObject, width, height, transparent);
+  return EvasPlugin(internal.Get());
+}
+
+EvasPlugin::EvasPlugin()
+{
+}
+
+EvasPlugin::EvasPlugin(const EvasPlugin& evasPlugin)
+: BaseHandle(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)
+: BaseHandle(evasPlugin)
+{
+}
+
+}  // namespace Extension
+
+}  // namespace Dali
diff --git a/dali-extension/devel-api/evas-plugin/evas-plugin.h b/dali-extension/devel-api/evas-plugin/evas-plugin.h
new file mode 100644 (file)
index 0000000..1d496c9
--- /dev/null
@@ -0,0 +1,336 @@
+#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/object/base-handle.h>
+#include <dali/public-api/signals/dali-signal.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 means 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 and EFL applications should follow the example below:
+ *
+ * @code
+ * #include <app.h>
+ * #include <app_extension.h>
+ * #include <Elementary.h>
+ *
+ * #include <dali/dali.h>
+ * #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.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 = 480;
+ * const int EVAS_PLUGIN_HEIGHT = 800;
+ * }
+ *
+ * class DaliApplication : public ConnectionTracker
+ * {
+ * public:
+ *   DaliApplication(EvasPlugin evasPlugin)
+ *   : mEvasPlugin(evasPlugin)
+ *   {
+ *     mEvasPlugin.InitSignal().Connect(this, &DaliApplication::OnInitialize);
+ *     mEvasPlugin.Run();
+ *   }
+ *
+ *   ~DaliApplication()
+ *   {
+ *     mEvasPlugin.Stop();
+ *   }
+ *
+ *   void OnInitialize(EvasPlugin& evasPlugin)
+ *   {
+ *     Stage stage = Stage::GetCurrent();
+ *
+ *     TextLabel textLabel = TextLabel::New( "Hello World" );
+ *     textLabel.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ *     textLabel.SetName( "helloWorldLabel" );
+ *     stage.Add( textLabel );
+ *   }
+ *
+ * private:
+ *   EvasPlugin mEvasPlugin;
+ * };
+ *
+ * struct app_data
+ * {
+ *   Evas_Object* elm_win;
+ *   DaliApplication* daliApplication;
+ * };
+ *
+ * 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->daliApplication = new DaliApplication(evasPlugin);
+ *
+ *   return true;
+ * }
+ *
+ * static void app_terminate(void *data)
+ * {
+ *   struct app_data* ad = (struct app_data*)data;
+ *
+ *   delete ad->daliApplication;
+ *   ad->daliApplication = 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 BaseHandle
+{
+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] transparent Whether the Evas object is transparent or not
+   */
+  static EvasPlugin New(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+  /**
+   * @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 adaptor 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__
diff --git a/dali-extension/devel-api/evas-plugin/file.list b/dali-extension/devel-api/evas-plugin/file.list
new file mode 100644 (file)
index 0000000..6f1cafe
--- /dev/null
@@ -0,0 +1,5 @@
+evas_plugin_public_header_files = \
+   $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.h
+
+evas_plugin_public_src_files = \
+   $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.cpp
diff --git a/dali-extension/internal/evas-plugin/ecore-wl-event-handler.cpp b/dali-extension/internal/evas-plugin/ecore-wl-event-handler.cpp
new file mode 100644 (file)
index 0000000..8f01016
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "ecore-wl-event-handler.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const int ECORE_WL_EVENT_COUNT = 4;
+
+//const char* CLIPBOARD_ATOM = "CBHM_MSG";
+//const char* CLIPBOARD_SET_OWNER_MESSAGE = "SET_OWNER";
+
+}
+
+struct EcoreWlEventHandler::Impl
+{
+  Impl(EcoreWlEventHandler* eventHandler, Ecore_Wl2_Window* window)
+  : mEventHandler(eventHandler)
+  , mWindow(window)
+  , mEcoreEventHandlers(ECORE_WL_EVENT_COUNT)
+  {
+#if 0
+    // Register Client message events - accessibility etc
+    mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreWlEventClientMessage, eventHandler));
+
+    // Register Selection events - clipboard selection, Drag & Drop selection etc
+    mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, EcoreWlEventSelectionClear, eventHandler));
+    mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, EcoreWlEventSelectionNotify, eventHandler));
+#endif
+    // Register Window visibility change events
+    mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, EcoreWlEventWindowVisibilityChange, eventHandler));
+
+  }
+
+  ~Impl()
+  {
+    for(std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandlers.begin(), endIter = mEcoreEventHandlers.end(); iter != endIter; ++iter)
+    {
+      ecore_event_handler_del(*iter);
+    }
+  }
+
+  static Eina_Bool EcoreWlEventClientMessage(void* data, int type, void* event)
+  {
+#if 0
+    Ecore_X_Event_Client_Message* eventClientMessage = static_cast<Ecore_X_Event_Client_Message*>(event);
+    EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+    if (eventClientMessage->win == eventHandler->mImpl->mWindow)
+    {
+      if (eventClientMessage->message_type == ecore_x_atom_get(CLIPBOARD_ATOM))
+      {
+        if (!strcmp(eventClientMessage->data.b, CLIPBOARD_SET_OWNER_MESSAGE))
+        {
+          // Claim the ownership of the SECONDARY selection
+          ecore_x_selection_secondary_set(eventClientMessage->win, "", 1);
+
+          // Show the clipboard window
+          Clipboard::Get().ShowClipboard();
+        }
+      }
+    }
+#endif
+
+    return ECORE_CALLBACK_PASS_ON;
+  }
+
+  static Eina_Bool EcoreWlEventSelectionClear(void* data, int type, void* event)
+  {
+#if 0
+    Ecore_X_Event_Selection_Clear* eventSelectionClear = static_cast<Ecore_X_Event_Selection_Clear*>(event);
+    EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+    if (eventSelectionClear->win == eventHandler->mImpl->mWindow)
+    {
+      if (eventSelectionClear->selection == ECORE_X_SELECTION_SECONDARY)
+      {
+        // Request to get the content from Ecore
+        ecore_x_selection_secondary_request(eventSelectionClear->win, ECORE_X_SELECTION_TARGET_TEXT);
+      }
+    }
+#endif
+
+    return ECORE_CALLBACK_PASS_ON;
+  }
+
+  static Eina_Bool EcoreWlEventSelectionNotify(void* data, int type, void* event)
+  {
+#if 0
+    Ecore_X_Event_Selection_Notify* eventSelectionNotify = static_cast<Ecore_X_Event_Selection_Notify*>(event);
+    EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+    if (eventSelectionNotify->win == eventHandler->mImpl->mWindow)
+    {
+      Ecore_X_Selection_Data* selectionData = static_cast<Ecore_X_Selection_Data*>(eventSelectionNotify->data);
+      if (selectionData->data)
+      {
+        if (eventSelectionNotify->selection == ECORE_X_SELECTION_SECONDARY)
+        {
+          std::string content(reinterpret_cast<char*>(selectionData->data), selectionData->length);
+
+          ClipboardEventNotifier clipboardEventNotifier = ClipboardEventNotifier::Get();
+          clipboardEventNotifier.SetContent(content);
+          clipboardEventNotifier.EmitContentSelectedSignal();
+
+          // Claim the ownership of the SECONDARY selection
+          ecore_x_selection_secondary_set(eventSelectionNotify->win, "", 1);
+
+          DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreWlEventSelectionNotify: Content(%d):\n" , selectionData->length );
+          DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
+          DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
+          DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
+        }
+      }
+    }
+#endif
+
+    return ECORE_CALLBACK_PASS_ON;
+  }
+
+  static Eina_Bool EcoreWlEventWindowVisibilityChange(void* data, int type, void* event)
+  {
+    Ecore_Wl2_Event_Window_Visibility_Change* eventWindowVisibilityChange = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+
+    EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+    // 0 is visible and 1 is invisible
+    eventHandler->SendEcoreWlVisibility(!eventWindowVisibilityChange->fully_obscured);
+
+    return ECORE_CALLBACK_PASS_ON;
+  }
+
+  EcoreWlEventHandler* mEventHandler;
+  Ecore_Wl2_Window* mWindow;
+  std::vector<Ecore_Event_Handler*> mEcoreEventHandlers;
+};
+
+EcoreWlEventHandler::EcoreWlEventHandler(Ecore_Wl2_Window* window,
+                                         EvasPluginVisibilityInterface& evasPluginVisibilityInterface)
+: mEvasPluginVisibilityInterface(evasPluginVisibilityInterface)
+, mImpl(NULL)
+{
+  mImpl = new Impl(this, window);
+}
+
+EcoreWlEventHandler::~EcoreWlEventHandler()
+{
+  delete mImpl;
+  mImpl = NULL;
+}
+
+void EcoreWlEventHandler::SendEcoreWlVisibility(bool visibility)
+{
+  mEvasPluginVisibilityInterface.OnEcoreWlVisibility(visibility);
+}
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
diff --git a/dali-extension/internal/evas-plugin/ecore-wl-event-handler.h b/dali-extension/internal/evas-plugin/ecore-wl-event-handler.h
new file mode 100644 (file)
index 0000000..0f55c6c
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef __DALI_EXTENSION_INTERNAL_ECORE_X_EVENT_HANDLER__
+#define __DALI_EXTENSION_INTERNAL_ECORE_X_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 <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Wl2.h>
+#include <vector>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include "evas-plugin-visibility-interface.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginVisibilityInterface;
+
+class EcoreWlEventHandler
+{
+public:
+  /**
+   * @brief Constructor
+   *
+   * @param[in] window is id of ecore wayland window.
+   * @param[in] evasPluginVisibilityInterface Used to send ecore wayland event to evas plugin
+   */
+  EcoreWlEventHandler(Ecore_Wl2_Window* window, EvasPluginVisibilityInterface& evasPluginVisibilityInterface);
+
+  /**
+   * @brief Destructor
+   */
+  ~EcoreWlEventHandler();
+
+  /**
+   * @brief Send the ecore wayland visibility.
+   *
+   * @param[in] visibility True is that ecore wayland window is show up and false is not
+   */
+  void SendEcoreWlVisibility(bool visibility);
+
+private:
+  EvasPluginVisibilityInterface& mEvasPluginVisibilityInterface;
+
+  struct Impl;
+  Impl* mImpl;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif
diff --git a/dali-extension/internal/evas-plugin/evas-event-handler.cpp b/dali-extension/internal/evas-plugin/evas-event-handler.cpp
new file mode 100644 (file)
index 0000000..f07a5e0
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-event-handler.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+/**
+ * Copied from x server
+ * @brief Retrieve the current milliseconds.
+ *
+ * @return the current milliseconds.
+ */
+static 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);
+}
+
+namespace
+{
+
+const int TOUCH_DEVICE_ID = 0;
+
+const char* EVAS_OBJECT_FOCUSED_EVENT_NAME = "focused";
+const char* EVAS_OBJECT_UNFOCUSED_EVENT_NAME = "unfocused";
+
+/**
+ * @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;
+}
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+/**
+ * @brief Evas_Modifier enums in Ecore_Input.h do not match Ecore_Event_Modifier in Ecore_Input.h.
+ *        This function converts from Evas_Modifier to Ecore_Event_Modifier enums.
+ *
+ * @param[in] evasModifier the Evas_Modifier input.
+ * @return the Ecore_Event_Modifier output.
+ */
+unsigned int EvasModifierToEcoreModifier(Evas_Modifier* evasModifier)
+{
+   unsigned int modifier = 0;  // If no other matches returns NONE.
+
+   if (evas_key_modifier_is_set(evasModifier, "Shift"))
+   {
+     modifier |= ECORE_EVENT_MODIFIER_SHIFT;
+   }
+
+   if (evas_key_modifier_is_set(evasModifier, "Alt"))
+   {
+     modifier |= ECORE_EVENT_MODIFIER_ALT;
+   }
+
+   if (evas_key_modifier_is_set(evasModifier, "AltGr"))
+   {
+     modifier |= ECORE_EVENT_MODIFIER_ALTGR;
+   }
+
+   if (evas_key_modifier_is_set(evasModifier, "Control"))
+   {
+     modifier |= ECORE_EVENT_MODIFIER_CTRL;
+   }
+
+   if (evas_key_modifier_is_set(evasModifier, "Win") ||
+       evas_key_modifier_is_set(evasModifier, "Super") ||
+       evas_key_modifier_is_set(evasModifier, "Hyper"))
+   {
+     modifier |= ECORE_EVENT_MODIFIER_WIN;
+   }
+
+   return modifier;
+}
+#endif
+
+
+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();
+}
+
+} // namespace
+
+EvasEventHandler::EvasEventHandler(Evas_Object* imageEvasObject,
+                                   Evas_Object* elmAccessEvasObject,
+                                   Evas_Object* elmFocusEvasObject,
+                                   EvasPluginEventInterface& evasPluginEventInterface)
+: mEvasPluginEventInterface(evasPluginEventInterface)
+, mEvas(evas_object_evas_get(imageEvasObject))
+, mImageEvasObject(imageEvasObject)
+, mElmAccessEvasObject(elmAccessEvasObject)
+, mElmFocusEvasObject(elmFocusEvasObject)
+{
+  // Register the evas event callbacks
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_DOWN,  OnEvasObjectMouseDown,      &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_UP,    OnEvasObjectMouseUp,        &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_MOVE,  OnEvasObjectMouseMove,      &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel,     &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_DOWN,  OnEvasObjectMultiTouchDown, &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_UP,    OnEvasObjectMultiTouchUp,   &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_MOVE,  OnEvasObjectMultiTouchMove, &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_KEY_DOWN,    OnEvasObjectKeyDown,        &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_KEY_UP,      OnEvasObjectKeyUp,          &evasPluginEventInterface);
+
+  // Register the evas geometry callbacks
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOVE,   OnEvasObjectMove,   &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_RESIZE, OnEvasObjectResize, &evasPluginEventInterface);
+
+  // Register the evas focus callbacks
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_FOCUS_IN,  OnEvasObjectFocusIn,  &evasPluginEventInterface);
+  evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut, &evasPluginEventInterface);
+
+  evas_event_callback_add(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN,  OnEvasFocusIn,  &evasPluginEventInterface);
+  evas_event_callback_add(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut, &evasPluginEventInterface);
+
+  // Register the evas render callbacks
+  evas_event_callback_add(mEvas, 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(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT,      OnElmAccessActionHighlight,      &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_UNHIGHLIGHT,    OnElmAccessActionUnhighlight,    &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, OnElmAccessActionHighlightNext,  &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, OnElmAccessActionHighlightPrev, &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_ACTIVATE,       OnElmAccessActionActivate,       &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_UP,             OnElmAccessActionUp,             &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_DOWN,           OnElmAccessActionDown,           &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_SCROLL,         OnElmAccessActionScroll,         &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_BACK,           OnElmAccessActionBack,           &evasPluginEventInterface);
+  elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_READ,           OnElmAccessActionRead,           &evasPluginEventInterface);
+
+  // Register the elm focus callbacks
+  evas_object_smart_callback_add(mElmFocusEvasObject, EVAS_OBJECT_FOCUSED_EVENT_NAME,   OnEvasObjectSmartFocused,   this);
+  evas_object_smart_callback_add(mElmFocusEvasObject, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused, this);
+}
+
+EvasEventHandler::~EvasEventHandler()
+{
+  // Unregister the evas event callbacks.
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_DOWN,  OnEvasObjectMouseDown);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_UP,    OnEvasObjectMouseUp);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_MOVE,  OnEvasObjectMouseMove);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_DOWN,  OnEvasObjectMultiTouchDown);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_UP,    OnEvasObjectMultiTouchUp);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_MOVE,  OnEvasObjectMultiTouchMove);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_KEY_DOWN,    OnEvasObjectKeyDown);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_KEY_UP,      OnEvasObjectKeyUp);
+
+  // Unregister the evas geometry callbacks.
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOVE,   OnEvasObjectMove);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_RESIZE, OnEvasObjectResize);
+
+  // Unregister the evas focus callbacks
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_FOCUS_IN,  OnEvasObjectFocusIn);
+  evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut);
+
+  evas_event_callback_del(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN,  OnEvasFocusIn);
+  evas_event_callback_del(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut);
+
+  // Register the evas render callbacks
+  evas_event_callback_del(mEvas, EVAS_CALLBACK_RENDER_POST, OnEvasRenderPost);
+
+  // Unregister the elm focus callbacks
+  evas_object_smart_callback_del(mElmFocusEvasObject, EVAS_OBJECT_FOCUSED_EVENT_NAME,   OnEvasObjectSmartFocused);
+  evas_object_smart_callback_del(mElmFocusEvasObject, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Event callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::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();
+  }
+
+  WheelEvent wheelEvent(WheelEvent::MOUSE_WHEEL, direction, modifiers, point, z, timeStamp);
+
+  EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+  pEvasPlugin->OnEvasObjectWheelEvent(wheelEvent);
+}
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::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);
+
+  TouchPoint touchPoint = 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(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectKeyDown(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+  Evas_Event_Key_Down* eventKeyDown = static_cast<Evas_Event_Key_Down*>(event);
+  bool eventHandled = false;
+
+  // If a device key then skip ecore_imf_context_filter_event.
+  if (!KeyLookup::IsDeviceButton(eventKeyDown->keyname))
+  {
+    ImfManager imfManager = ImfManager::Get();
+    if(imfManager)
+    {
+      Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+      if (imfContext)
+      {
+        // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
+        Ecore_IMF_Event_Key_Down imfEventKeyDown;
+        ecore_imf_evas_event_key_down_wrap(eventKeyDown, &imfEventKeyDown);
+
+        eventHandled = ecore_imf_context_filter_event(imfContext, ECORE_IMF_EVENT_KEY_DOWN, reinterpret_cast<Ecore_IMF_Event*>(&imfEventKeyDown));
+
+        if (!eventHandled)
+        {
+          // Menu, home, back button must skip ecore_imf_context_filter_event.
+          static const char* escapeKeyName = KeyLookup::GetKeyName(DALI_KEY_ESCAPE);
+          static const char* returnKeyName = KeyLookup::GetKeyName(static_cast<Dali::KEY>(DALI_EXTENSION_INTERNAL_KEY_RETURN));
+          static const char* kpEnterKeyName = KeyLookup::GetKeyName(static_cast<Dali::KEY>(DALI_EXTENSION_INTERNAL_KEY_KP_ENTER));
+          if ((escapeKeyName && !strcmp(eventKeyDown->keyname, escapeKeyName)) ||
+              (returnKeyName && !strcmp(eventKeyDown->keyname, returnKeyName)) ||
+              (kpEnterKeyName && !strcmp(eventKeyDown->keyname, kpEnterKeyName)))
+          {
+            ecore_imf_context_reset(imfContext);
+          }
+        }
+      }
+    }
+  }
+
+  // If the event wasn't handled then we should send a key event.
+  if (!eventHandled)
+  {
+    std::string keyName = eventKeyDown->keyname;
+    std::string keyString = (eventKeyDown->string != NULL) ? eventKeyDown->string : "";
+    int keyCode = KeyLookup::GetDaliKeyCode(eventKeyDown->keyname);
+    int modifier = EvasModifierToEcoreModifier(eventKeyDown->modifiers);
+    unsigned long timeStamp = eventKeyDown->timestamp;
+    if (timeStamp < 1)
+    {
+      timeStamp = GetCurrentMilliSeconds();
+    }
+
+    KeyEvent keyEvent(keyName, keyString, keyCode, modifier, timeStamp, KeyEvent::Down);
+
+    EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+    pEvasPlugin->OnEvasObjectKeyEvent(keyEvent);
+  }
+#endif
+}
+
+void EvasEventHandler::OnEvasObjectKeyUp(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+  Evas_Event_Key_Up* eventKeyUp = static_cast<Evas_Event_Key_Up*>(event);
+  bool eventHandled = false;
+
+  // Menu, home, back button must skip ecore_imf_context_filter_event.
+  static const char* menuKeyName = KeyLookup::GetKeyName(DALI_KEY_MENU);
+  static const char* homeKeyName = KeyLookup::GetKeyName(DALI_KEY_HOME);
+  static const char* backKeyName = KeyLookup::GetKeyName(DALI_KEY_BACK);
+  if ((menuKeyName && !strcmp(eventKeyUp->keyname, menuKeyName)) &&
+      (homeKeyName && !strcmp(eventKeyUp->keyname, homeKeyName)) &&
+      (backKeyName && !strcmp(eventKeyUp->keyname, backKeyName)))
+  {
+    ImfManager imfManager = ImfManager::Get();
+    if(imfManager)
+    {
+      Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+
+      if (imfContext)
+      {
+        Ecore_IMF_Event_Key_Up imfEventKeyUp;
+        ecore_imf_evas_event_key_up_wrap(eventKeyUp, &imfEventKeyUp);
+
+        eventHandled = ecore_imf_context_filter_event(imfContext, ECORE_IMF_EVENT_KEY_UP, reinterpret_cast<Ecore_IMF_Event*>(&imfEventKeyUp));
+      }
+    }
+  }
+
+  if (!eventHandled)
+  {
+    std::string keyName = eventKeyUp->keyname;
+    std::string keyString = (eventKeyUp->string != NULL) ? eventKeyUp->string : "";
+    int keyCode = KeyLookup::GetDaliKeyCode(eventKeyUp->keyname);
+    int modifier = EvasModifierToEcoreModifier(eventKeyUp->modifiers);
+    unsigned long timeStamp = eventKeyUp->timestamp;
+    if (timeStamp < 1)
+    {
+      timeStamp = GetCurrentMilliSeconds();
+    }
+
+    KeyEvent keyEvent(keyName, keyString, keyCode, modifier, timeStamp, KeyEvent::Up);
+
+    EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+    pEvasPlugin->OnEvasObjectKeyEvent(keyEvent);
+  }
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Geometry callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::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 EvasEventHandler::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 EvasEventHandler::OnEvasObjectFocusIn(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+  EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+  pEvasPlugin->OnEvasObjectFocusIn();
+}
+
+void EvasEventHandler::OnEvasObjectFocusOut(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+  EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+  pEvasPlugin->OnEvasObjectFocusOut();
+}
+
+void EvasEventHandler::OnEvasFocusIn(void *data, Evas* evas, void* event)
+{
+}
+
+void EvasEventHandler::OnEvasFocusOut(void *data, Evas* evas, void* event)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Render callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasRenderPost(void *data, Evas* evas, void* event)
+{
+  EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+  pEvasPlugin->OnEvasPostRender();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Access callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionHighlight(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionUnhighlight(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionHighlightNext(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionHighlightPrev(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionActivate(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionScroll(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionUp(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionDown(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionBack(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::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->OnElmAccessActionRead(daliActionInfo);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectSmartFocused(void *data, Evas_Object* evasObject, void* event)
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>(data);
+  EvasPluginEventInterface& evasPlugin = eventHandler->GetEvasPluginInterface();
+
+  if (eventHandler->mElmFocusEvasObject == 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
+        KeyEvent fakeKeyEvent("", "", 0, 0, 100, KeyEvent::Down);
+
+        evasPlugin.OnEvasObjectKeyEvent(fakeKeyEvent);
+      }
+    }
+
+    evas_object_focus_set(eventHandler->mImageEvasObject, EINA_TRUE);
+  }
+}
+
+void EvasEventHandler::OnEvasObjectSmartUnfocused(void *data, Evas_Object* evasObject, void* event)
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>(data);
+  if (eventHandler->mElmFocusEvasObject == evasObject)
+  {
+    evas_object_focus_set(eventHandler->mImageEvasObject, EINA_FALSE);
+  }
+}
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
diff --git a/dali-extension/internal/evas-plugin/evas-event-handler.h b/dali-extension/internal/evas-plugin/evas-event-handler.h
new file mode 100644 (file)
index 0000000..15711f0
--- /dev/null
@@ -0,0 +1,230 @@
+#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 <dali/public-api/events/touch-point.h>
+#include <dali/public-api/events/wheel-event.h>
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/math/rect.h>
+// #include <dali/integration-api/adaptors/input-method-context.h>
+
+#include <string>
+
+// INTERNAL INCLUDES
+#include "evas-plugin-event-interface.h"
+
+
+
+namespace Dali
+{
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginEventInterface;
+
+class EvasEventHandler
+{
+public:
+  /**
+   * @brief Constructor
+   *
+   * @param[in] imageEvasObject is stream showing the pixmap which is drawn by dali
+   *
+   *
+   * @param[in] evasPluginEventInterface Used to send event to evas plugin
+   */
+  EvasEventHandler(Evas_Object* imageEvasObject,
+                   Evas_Object* elmAccessEvasObject,
+                   Evas_Object* elmFocusEvasObject,
+                   EvasPluginEventInterface& evasPluginEventInterface);
+
+  /**
+   * Destructor.
+   */
+  ~EvasEventHandler();
+
+public:
+
+  EvasPluginEventInterface& GetEvasPluginInterface() { return mEvasPluginEventInterface; }
+
+private:
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // 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);
+
+private:
+  EvasPluginEventInterface& mEvasPluginEventInterface;
+
+  Evas* mEvas;
+  Evas_Object* mImageEvasObject;
+  Evas_Object* mElmAccessEvasObject;
+  Evas_Object* mElmFocusEvasObject;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif
diff --git a/dali-extension/internal/evas-plugin/evas-plugin-event-interface.h b/dali-extension/internal/evas-plugin/evas-plugin-event-interface.h
new file mode 100644 (file)
index 0000000..e8b2d15
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_EVENT_INTERFACE_H__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_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.
+ *
+ */
+
+namespace Dali
+{
+
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+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 Handle evas object event
+   *
+   * @param[in] touchPoint is the information of touch
+   * @param[in] timeStamp is that touch is occured
+   */
+  virtual void OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp) = 0;
+
+  /**
+   * @brief Handle evas object event
+   *
+   * @param[in] wheelEvent is the information of wheel
+   */
+  virtual void OnEvasObjectWheelEvent(WheelEvent& wheelEvent) = 0;
+
+  /**
+   * @brief Handle evas object event
+   *
+   * @param[in] keyEvent is the information of key
+   */
+  virtual void OnEvasObjectKeyEvent(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;
+
+  virtual bool OnElmAccessActionHighlight(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionUnhighlight(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionHighlightNext(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionHighlightPrev(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionActivate(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionScroll(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionUp(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionDown(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionBack(AccessActionInfo& accessActionInfo) = 0;
+
+  virtual bool OnElmAccessActionRead(AccessActionInfo& accessActionInfo) = 0;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif
diff --git a/dali-extension/internal/evas-plugin/evas-plugin-impl.cpp b/dali-extension/internal/evas-plugin/evas-plugin-impl.cpp
new file mode 100755 (executable)
index 0000000..f3666e9
--- /dev/null
@@ -0,0 +1,649 @@
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-plugin-impl.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";
+}
+
+struct EvasPlugin::Impl
+{
+  Impl(EvasPlugin* evasPlugin, Evas_Object* parentEvasObject, int width, int height, bool transparent)
+  : mEvasPlugin(evasPlugin)
+  , mEcoreEvas(NULL)
+  , mImageEvasObject(NULL)
+  , mAccessEvasObject(NULL)
+  , mDaliEvasObject(NULL)
+  {
+    Evas* evas = evas_object_evas_get(parentEvasObject);
+    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
+    mAccessEvasObject = elm_access_object_register(mImageEvasObject, parentEvasObject);
+
+    // Create a button and set style as "focus", if does not want to show the focus, then "transparent"
+    mDaliEvasObject = elm_button_add(parentEvasObject);
+
+    // Don't need to show the focus boundary here
+    elm_object_style_set(mDaliEvasObject, ELM_OBJECT_STYLE);
+
+    // Set the image evas object to focus object, but event should not be propagated
+    elm_object_part_content_set(mDaliEvasObject, 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(mDaliEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(mDaliEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+    evas_object_move(mDaliEvasObject, 0, 0);
+    evas_object_resize(mDaliEvasObject, width, height);
+    evas_object_show(mDaliEvasObject);
+  }
+
+  ~Impl()
+  {
+    // Delete the elm focus evas object
+    evas_object_del(mDaliEvasObject);
+    mDaliEvasObject = NULL;
+
+    // Unregister elm_access_object
+    elm_access_object_unregister(mImageEvasObject);
+    mAccessEvasObject = NULL;
+
+    // Delete the image evas object
+    evas_object_del(mImageEvasObject);
+    mImageEvasObject = NULL;
+  }
+
+  Ecore_Wl2_Window* GetNativeWindow()
+  {
+    return ecore_evas_wayland2_window_get( mEcoreEvas );
+  }
+
+  PositionSize GetGeometry()
+  {
+    PositionSize geometry;
+    evas_object_geometry_get(mImageEvasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height);
+    return geometry;
+  }
+
+  void SetFocus()
+  {
+    evas_object_focus_set(mImageEvasObject, EINA_TRUE);
+  }
+
+  void BindTBMSurface( tbm_surface_h surface )
+  {
+#ifdef ENABLE_TTRACE
+    traceBegin( TTRACE_TAG_GRAPHICS, "EvasNativeSurfaceSet[%d]", pixmap );
+#endif
+
+    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 );
+
+#ifdef ENABLE_TTRACE
+    traceEnd( TTRACE_TAG_GRAPHICS );
+#endif
+  }
+
+  void RequestRender()
+  {
+    evas_object_image_pixels_dirty_set( mImageEvasObject, EINA_TRUE );
+    ecore_evas_manual_render( mEcoreEvas );
+  }
+
+  EvasPlugin* mEvasPlugin;
+  Ecore_Evas* mEcoreEvas;
+  Evas_Object* mImageEvasObject;
+  Evas_Object* mAccessEvasObject;
+  Evas_Object* mDaliEvasObject;
+};
+
+EvasPluginPtr EvasPlugin::New(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+{
+  EvasPluginPtr evasPlugin = new EvasPlugin(parentEvasObject, width, height, transparent);
+  return evasPlugin;
+}
+
+EvasPlugin::EvasPlugin(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+: mState(READY)
+, mTBMRenderSurface(NULL)
+, mAdaptor(NULL)
+, mRenderNotification(NULL)
+, mEvasEventHandler(NULL)
+, mEcoreWlEventHandler(NULL)
+, mIsFocus(false)
+, mTransparent(transparent)
+, mImpl(NULL)
+{
+  DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the evas plugin." );
+
+  mImpl = new Impl(this, parentEvasObject, width, height, transparent);
+
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+  // Create the singleton service
+  mSingletonService = SingletonService::New();
+
+  // Create the pixmap render surface
+  mTBMRenderSurface = CreateNativeSurface( PositionSize( 0, 0, width, height ), transparent );
+
+  // Initialize dali
+  Any nativeWindow = mImpl->GetNativeWindow();
+  mAdaptor = &Adaptor::New(nativeWindow, *mTBMRenderSurface, Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
+#endif
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+  ImfManager imfManager = ImfManager::Get();
+  if(imfManager)
+  {
+    imfManager.ActivatedSignal().Connect(this, &EvasPlugin::OnImfActivated);
+  }
+#endif
+
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+  TriggerEventFactory triggerEventFactory;
+  mRenderNotification = triggerEventFactory.CreateTriggerEvent(MakeCallback(this, &EvasPlugin::OnPostRender),
+                                                               TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
+
+  mTBMRenderSurface->SetRenderNotification(mRenderNotification);
+#endif
+}
+
+EvasPlugin::~EvasPlugin()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+  mAdaptor->Stop();
+
+  if (mEcoreWlEventHandler)
+  {
+    delete mEcoreWlEventHandler;
+    mEcoreWlEventHandler = NULL;
+  }
+
+  if (mEvasEventHandler)
+  {
+    delete mEvasEventHandler;
+    mEvasEventHandler = NULL;
+  }
+
+  delete mRenderNotification;
+  mRenderNotification = NULL;
+
+  delete mAdaptor;
+  mAdaptor = NULL;
+
+  delete mTBMRenderSurface;
+  mTBMRenderSurface = NULL;
+
+  mSingletonService.UnregisterAll();
+
+  delete mImpl;
+  mImpl = NULL;
+#endif
+}
+
+void EvasPlugin::Run()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+  if(READY == mState)
+  {
+    if (!mEvasEventHandler)
+    {
+      mEvasEventHandler = new Extension::Internal::EvasEventHandler(mImpl->mImageEvasObject, mImpl->mAccessEvasObject, mImpl->mDaliEvasObject, *this);
+    }
+
+    // Start the adaptor
+    mAdaptor->Start();
+
+    mInitSignal.Emit();
+
+    mAdaptor->NotifySceneCreated();
+
+    mState = RUNNING;
+  }
+#endif
+}
+
+void EvasPlugin::Pause()
+{
+  if(mState == RUNNING)
+  {
+    mState = SUSPENDED;
+
+    mAdaptor->Pause();
+
+    mPauseSignal.Emit();
+  }
+}
+
+void EvasPlugin::Resume()
+{
+  if(mState == SUSPENDED)
+  {
+    mAdaptor->Resume();
+
+    mResumeSignal.Emit();
+
+    mState = RUNNING;
+  }
+}
+
+void EvasPlugin::Stop()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+  if(mState != STOPPED)
+  {
+    // Stop the adaptor
+    mAdaptor->Stop();
+    mState = STOPPED;
+
+    mTerminateSignal.Emit();
+  }
+#endif
+}
+
+Evas_Object* EvasPlugin::GetAccessEvasObject()
+{
+  return mImpl->mAccessEvasObject;
+}
+
+Evas_Object* EvasPlugin::GetDaliEvasObject()
+{
+  return mImpl->mDaliEvasObject;
+}
+
+void EvasPlugin::ResizeSurface()
+{
+#if 0
+  // Remember old surface
+  NativeRenderSurface* oldSurface = mTBMRenderSurface;
+  TriggerEventInterface* oldTriggerEvent = mRenderNotification;
+
+  PositionSize geometry = mImpl->GetGeometry();
+
+  mAdaptor->SurfaceSizeChanged( geometry );
+
+  // emit resized signal to application
+  mResizeSignal.Emit();
+
+  mTBMRenderSurface = CreateNativeSurface( PositionSize( 0, 0, geometry.width, geometry.height ), NATIVE_SURFACE_NAME, mTransparent );
+  mTBMRenderSurface->SetRenderNotification( mRenderNotification );
+
+  // Ask the replace the surface inside dali
+  Any nativeWindow = mImpl->GetNativeWindow();
+
+  mAdaptor->ReplaceSurface( nativeWindow, *mTBMRenderSurface ); // this method is synchronous => guarantee until rendering next frame
+
+  TriggerEventFactory triggerEventFactory;
+  mRenderNotification = triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &EvasPlugin::OnPostRender ),
+                                                                TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
+
+  mTBMRenderSurface->SetRenderNotification( mRenderNotification );
+  delete oldTriggerEvent;
+
+  // Bind offscreen surface to the evas object
+  mTBMRenderSurface->WaitUntilSurfaceReplaced();
+  mImpl->BindTBMSurface( AnyCast<tbm_surface_h>( mTBMRenderSurface->GetDrawable() ) );
+  mAdaptor->ReleaseSurfaceLock();
+
+  // It's now safe to delete the old surface
+  delete oldSurface;
+#endif
+}
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+void EvasPlugin::OnImfActivated(ImfManager& imfManager)
+{
+  mImpl->SetFocus();
+}
+#endif
+
+void EvasPlugin::OnPostRender()
+{
+  // Bind offscreen surface to the evas object
+  mImpl->BindTBMSurface(AnyCast<tbm_surface_h>(mTBMRenderSurface->GetDrawable()));
+  mAdaptor->ReleaseSurfaceLock();
+
+  mImpl->RequestRender();
+}
+
+void EvasPlugin::OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp)
+{
+  mAdaptor->FeedTouchPoint(touchPoint, timeStamp);
+}
+
+void EvasPlugin::OnEvasObjectWheelEvent(WheelEvent& wheelEvent)
+{
+  mAdaptor->FeedWheelEvent( wheelEvent );
+}
+
+void EvasPlugin::OnEvasObjectKeyEvent(KeyEvent& keyEvent)
+{
+  mAdaptor->FeedKeyEvent( keyEvent );
+}
+
+void EvasPlugin::OnEvasObjectMove(const Rect<int>& geometry)
+{
+}
+
+void EvasPlugin::OnEvasObjectResize(const Rect<int>& geometry)
+{
+  if (geometry.width <= 1 || geometry.height <= 1)
+  {
+    // skip meaningless resize signal
+    return;
+  }
+
+  Vector2 size = Stage::GetCurrent().GetSize();
+  if(size.width == geometry.width && size.height == geometry.height)
+  {
+    // skip meaningless resize signal
+    return;
+  }
+
+  ResizeSurface();
+}
+
+void EvasPlugin::OnEvasObjectFocusIn()
+{
+  if(!mIsFocus)
+  {
+    if (!mEcoreWlEventHandler)
+    {
+      mEcoreWlEventHandler = new Extension::Internal::EcoreWlEventHandler(mImpl->GetNativeWindow(), *this);
+    }
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+    ImfManager imfManager = ImfManager::Get();
+    if(imfManager)
+    {
+      // TODO : Move to Impl
+      Ecore_Wl_Window* window = mImpl->GetNativeWindow();
+      Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+      ecore_imf_context_client_window_set( imfContext, reinterpret_cast<void*>( window ) );
+
+      if(imfManager.RestoreAfterFocusLost())
+      {
+        imfManager.Activate();
+      }
+    }
+#endif
+
+    mFocusedSignal.Emit();
+
+    mIsFocus = true;
+  }
+}
+
+void EvasPlugin::OnEvasObjectFocusOut()
+{
+  if(mIsFocus)
+  {
+    mIsFocus = false;
+
+    if (mEcoreWlEventHandler)
+    {
+      delete mEcoreWlEventHandler;
+      mEcoreWlEventHandler = NULL;
+    }
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+    ImfManager imfManager = ImfManager::Get();
+    if(imfManager && imfManager.RestoreAfterFocusLost())
+    {
+      imfManager.Deactivate();
+    }
+#endif
+
+    Clipboard::Get().HideClipboard();
+
+    mUnFocusedSignal.Emit();
+  }
+}
+
+void EvasPlugin::OnEvasPostRender()
+{
+}
+
+bool EvasPlugin::OnElmAccessActionHighlight(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionUnhighlight(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionHighlightNext(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionHighlightPrev(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionActivate(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionUp(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionDown(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionScroll(AccessActionInfo& accessActionInfo)
+{
+  bool ret = false;
+
+  Evas_Coord rel_x, rel_y;
+  Evas_Coord obj_x,  obj_y, obj_w, obj_h;
+  Evas_Object* eo = this->GetAccessEvasObject();
+
+  if(eo)
+  {
+    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;
+
+    ret = this->OnElmAccessibilityActionEvent(accessActionInfo, rel_x, rel_y);
+  }
+
+  return ret;
+}
+
+bool EvasPlugin::OnElmAccessActionBack(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionRead(AccessActionInfo& accessActionInfo)
+{
+  return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+void EvasPlugin::OnEcoreWlVisibility(bool visibility)
+{
+  if (!visibility)
+  {
+    mAdaptor->ReleaseSurfaceLock();
+  }
+}
+
+bool EvasPlugin::OnElmAccessibilityActionEvent(AccessActionInfo& accessActionInfo, int x, int y)
+{
+  bool ret = false;
+
+  if( NULL == mAdaptor)
+  {
+    return ret;
+  }
+
+  Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
+  if( accessibilityAdaptor )
+  {
+    int touchType = accessActionInfo.mouseType;
+    int touchX = x >= 0 ? x : accessActionInfo.x;
+    int touchY = y >= 0 ? y : accessActionInfo.y;
+
+    switch(accessActionInfo.actionBy)
+    {
+      case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
+      case Dali::Extension::Internal::ACCESS_ACTION_READ:
+      {
+        ret = accessibilityAdaptor.HandleActionReadEvent((unsigned int)x, (unsigned int)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:
+      {
+        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.
+        TouchPoint point( 0, state, (float)touchX, (float)touchY );
+        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__);
+  }
+
+  DALI_LOG_INFO(gEvasPluginLogFilter, Debug::General, "[%s:%d] [action : %d] focus manager returns %s\n", __FUNCTION__, __LINE__, (int)(actionType), ret?"TRUE":"FALSE");
+
+  return ret;
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
diff --git a/dali-extension/internal/evas-plugin/evas-plugin-impl.h b/dali-extension/internal/evas-plugin/evas-plugin-impl.h
new file mode 100755 (executable)
index 0000000..15239fd
--- /dev/null
@@ -0,0 +1,393 @@
+#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 <Elementary.h>
+#include <Ecore_IMF_Evas.h>
+#include <tbm_surface.h>
+
+#include <dali/public-api/dali-core.h>
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/signals/connection-tracker.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+
+#include <dali/devel-api/adaptor-framework/singleton-service.h>
+#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/debug.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>
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+#include <dali/integration-api/adaptors/imf-manager-impl.h>
+#endif
+
+#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
+
+
+#ifdef ENABLE_TTRACE
+#include <ttrace.h>
+#endif
+
+
+// INTERNAL INCLUDES
+#include "evas-event-handler.h"
+#include "ecore-wl-event-handler.h"
+#include "evas-plugin-event-interface.h"
+#include "evas-plugin-visibility-interface.h"
+
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+class TriggerEventInterface;
+class NativeRenderSurface;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+typedef Rect<int> PositionSize;
+
+class EvasPlugin;
+typedef IntrusivePtr<EvasPlugin> EvasPluginPtr;
+
+/**
+ * Implementation of the EvasPlugin class.
+ */
+class EvasPlugin : public BaseObject,
+                   public ConnectionTracker,
+                   public Extension::Internal::EvasPluginEventInterface,
+                   public Extension::Internal::EvasPluginVisibilityInterface
+{
+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] transparent Whether the evas object is transparent or not
+   */
+  static EvasPluginPtr New(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+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();
+
+  /**
+   * @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;
+  }
+
+private:
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectTouchEvent
+   */
+  virtual void OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectWheelEvent
+   */
+  virtual void OnEvasObjectWheelEvent(WheelEvent& wheelEvent);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectKeyEvent
+   */
+  virtual void OnEvasObjectKeyEvent(KeyEvent& keyEvent);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectMove
+   */
+  virtual void OnEvasObjectMove(const Rect<int>& geometry);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectResize
+   */
+  virtual void OnEvasObjectResize(const Rect<int>& geometry);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusIn
+   */
+  virtual void OnEvasObjectFocusIn();
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusOut
+   */
+  virtual void OnEvasObjectFocusOut();
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasRenderPost
+   */
+  virtual void OnEvasPostRender();
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlight
+   */
+  virtual bool OnElmAccessActionHighlight(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionUnhighlight
+   */
+  virtual bool OnElmAccessActionUnhighlight(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlightNext
+   */
+  virtual bool OnElmAccessActionHighlightNext(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlightPrev
+   */
+  virtual bool OnElmAccessActionHighlightPrev(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionActivate
+   */
+  virtual bool OnElmAccessActionActivate(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionUp
+   */
+  virtual bool OnElmAccessActionUp(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionDown
+   */
+  virtual bool OnElmAccessActionDown(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionScroll
+   */
+  virtual bool OnElmAccessActionScroll(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface:OnElmAccessActionBack:
+   */
+  virtual bool OnElmAccessActionBack(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionRead
+   */
+  virtual bool OnElmAccessActionRead(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasPluginVisibilityInterface::OnElmEcoreWlVisibility
+   */
+  virtual void OnEcoreWlVisibility(bool visibility);
+
+  /**
+   * Resize the surface
+   * To resize, create new surface with evas object's size and replace with it.
+   */
+  void ResizeSurface();
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+  /**
+   * For ImfActivated signal
+   * When the imf is activated, it will handle the focus
+   * @param[in] imfManager imfManager instance
+   */
+  void OnImfActivated(ImfManager& imfManager);
+#endif
+
+  /**
+   * This function is called after drawing by dali.
+   */
+  void OnPostRender();
+
+  /**
+   * Called when the accessibility action event dispatched from elm_access.
+   * @param[in] actionType elm accessibility action type structure
+   * @param[in] x x position for action, it could be unnecessary
+   * @param[in] y y position for action, it could be unnecessary
+   * @return True if the event was handled
+   */
+  bool OnElmAccessibilityActionEvent(AccessActionInfo& actionInfo, int x = -1, int y = -1);
+
+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] transparent Whether the evas object is transparent or not
+   */
+  EvasPlugin(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+  /**
+   * Destructor
+   */
+  virtual ~EvasPlugin();
+
+  // Undefined
+  EvasPlugin(const EvasPlugin&);
+  EvasPlugin& operator=(EvasPlugin&);
+
+private:
+  enum State
+  {
+    READY,
+    RUNNING,
+    SUSPENDED,
+    STOPPED,
+  };
+
+  State mState;
+  NativeRenderSurface* mTBMRenderSurface;
+  Adaptor* mAdaptor;
+  TriggerEventInterface* mRenderNotification;
+  Extension::Internal::EvasEventHandler* mEvasEventHandler;
+  Extension::Internal::EcoreWlEventHandler* mEcoreWlEventHandler;
+
+  bool mIsFocus:1;        ///< Flag
+  bool mTransparent:1;    ///< Whether
+
+  SingletonService mSingletonService;
+
+  // Signals
+  EvasPluginSignalType mInitSignal;
+  EvasPluginSignalType mTerminateSignal;
+  EvasPluginSignalType mPauseSignal;
+  EvasPluginSignalType mResumeSignal;
+  EvasPluginSignalType mResizeSignal;
+  EvasPluginSignalType mFocusedSignal;
+  EvasPluginSignalType mUnFocusedSignal;
+
+  struct Impl;
+  Impl* mImpl;
+};
+
+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__
diff --git a/dali-extension/internal/evas-plugin/evas-plugin-visibility-interface.h b/dali-extension/internal/evas-plugin/evas-plugin-visibility-interface.h
new file mode 100644 (file)
index 0000000..124906b
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_VISIBILITY_INTERFACE__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_VISIBILITY_INTERFACE__
+
+/*
+ * 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.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginVisibilityInterface
+{
+public:
+  /**
+   * @brief Process the ecore wayland visibility.
+   *
+   * @param[in] visibility True is that ecore wayland window is show up and false is not
+   */
+  virtual void OnEcoreWlVisibility(bool visibility) = 0;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+#endif
diff --git a/dali-extension/internal/evas-plugin/file.list b/dali-extension/internal/evas-plugin/file.list
new file mode 100644 (file)
index 0000000..defd2a2
--- /dev/null
@@ -0,0 +1,11 @@
+evas_plugin_internal_header_files = \
+   $(extension_src_dir)/internal/evas-plugin/ecore-wl-event-handler.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-event-handler.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-event-interface.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-visibility-interface.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.h
+
+evas_plugin_internal_src_files = \
+   $(extension_src_dir)/internal/evas-plugin/ecore-wl-event-handler.cpp \
+   $(extension_src_dir)/internal/evas-plugin/evas-event-handler.cpp \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.cpp
index a387320..9793eee 100755 (executable)
@@ -23,6 +23,13 @@ BuildRequires:  pkgconfig(dali-adaptor)
 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
 
@@ -274,11 +281,12 @@ exit 0
 %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