Initial copy from dali-extension repository 36/231536/1
authorHeeyong Song <heeyong.song@samsung.com>
Wed, 22 Apr 2020 08:15:03 +0000 (17:15 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Wed, 22 Apr 2020 08:15:03 +0000 (17:15 +0900)
Change-Id: I67a10cde5fa89d17119cc344a124e210de7648b5

69 files changed:
LICENSE [new file with mode: 0644]
build/tizen/Makefile.am [new file with mode: 0644]
build/tizen/color-controller/Makefile.am [new file with mode: 0755]
build/tizen/color-controller/configure.ac [new file with mode: 0755]
build/tizen/configure.ac [new file with mode: 0755]
build/tizen/dali-extension.pc.in [new file with mode: 0644]
build/tizen/dali-extension/Makefile.am [new file with mode: 0755]
build/tizen/dali-extension/configure.ac [new file with mode: 0755]
build/tizen/image-loader/Makefile.am [new file with mode: 0755]
build/tizen/image-loader/configure.ac [new file with mode: 0755]
build/tizen/key/Makefile.am [new file with mode: 0644]
build/tizen/key/configure.ac [new file with mode: 0644]
build/tizen/vector-animation-renderer/Makefile.am [new file with mode: 0644]
build/tizen/vector-animation-renderer/configure.ac [new file with mode: 0644]
build/tizen/video-player/Makefile.am [new file with mode: 0644]
build/tizen/video-player/configure.ac [new file with mode: 0644]
build/tizen/web-engine-chromium/Makefile.am [new file with mode: 0644]
build/tizen/web-engine-chromium/configure.ac [new file with mode: 0644]
build/tizen/web-engine-lwe/Makefile.am [new file with mode: 0644]
build/tizen/web-engine-lwe/configure.ac [new file with mode: 0644]
dali-extension.manifest [new file with mode: 0644]
dali-extension/color-controller/file.list [new file with mode: 0644]
dali-extension/color-controller/tizen-color-controller.cpp [new file with mode: 0644]
dali-extension/color-controller/tizen-color-controller.h [new file with mode: 0644]
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/devel-api/evas-plugin/scene.cpp [new file with mode: 0644]
dali-extension/devel-api/evas-plugin/scene.h [new file with mode: 0644]
dali-extension/image-loader/README [new file with mode: 0755]
dali-extension/image-loader/file.list [new file with mode: 0755]
dali-extension/image-loader/loader-dummy.cpp [new file with mode: 0755]
dali-extension/image-loader/loader-dummy.h [new file with mode: 0755]
dali-extension/image-loader/tizen-image-loader.cpp [new file with mode: 0755]
dali-extension/image-loader/tizen-image-loader.h [new file with mode: 0755]
dali-extension/integration-api/file.list [new file with mode: 0644]
dali-extension/integration-api/key-extension.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-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-wrapper.cpp [new file with mode: 0644]
dali-extension/internal/evas-plugin/evas-wrapper.h [new file with mode: 0644]
dali-extension/internal/evas-plugin/file.list [new file with mode: 0644]
dali-extension/internal/evas-plugin/scene-impl.cpp [new file with mode: 0644]
dali-extension/internal/evas-plugin/scene-impl.h [new file with mode: 0644]
dali-extension/key/file.list [new file with mode: 0644]
dali-extension/key/key-extension.cpp [new file with mode: 0644]
dali-extension/vector-animation-renderer/file.list [new file with mode: 0644]
dali-extension/vector-animation-renderer/tizen-vector-animation-event-handler.h [new file with mode: 0755]
dali-extension/vector-animation-renderer/tizen-vector-animation-manager.cpp [new file with mode: 0755]
dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h [new file with mode: 0755]
dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.cpp [new file with mode: 0755]
dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.h [new file with mode: 0755]
dali-extension/video-player/ecore-wl/tizen-video-player-ecore-wl.cpp [new file with mode: 0755]
dali-extension/video-player/ecore-wl/tizen-video-player.h [new file with mode: 0755]
dali-extension/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp [new file with mode: 0755]
dali-extension/video-player/ecore-wl2/tizen-video-player.h [new file with mode: 0755]
dali-extension/video-player/file.list [new file with mode: 0644]
dali-extension/web-engine-chromium/file.list [new file with mode: 0644]
dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp [new file with mode: 0644]
dali-extension/web-engine-chromium/tizen-web-engine-chromium.h [new file with mode: 0644]
dali-extension/web-engine-lwe/file.list [new file with mode: 0644]
dali-extension/web-engine-lwe/tizen-web-engine-lwe.cpp [new file with mode: 0644]
dali-extension/web-engine-lwe/tizen-web-engine-lwe.h [new file with mode: 0644]
packaging/dali-extension.spec [new file with mode: 0755]
scripts/dali.sh [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..dc0510e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,70 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this License; and
+You must cause any modified files to carry prominent notices stating that You changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+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.
\ No newline at end of file
diff --git a/build/tizen/Makefile.am b/build/tizen/Makefile.am
new file mode 100644 (file)
index 0000000..587ad5a
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+
+SUBDIRS = ${subdirs}
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = dali-extension.pc
diff --git a/build/tizen/color-controller/Makefile.am b/build/tizen/color-controller/Makefile.am
new file mode 100755 (executable)
index 0000000..ef606d5
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2018 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 color controller
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/color-controller/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-color-controller-plugin.la
+
+libdali_color_controller_plugin_la_includes =
+
+libdali_color_controller_plugin_la_SOURCES = \
+                     $(color_controller_plugin_src_files)
+
+libdali_color_controller_plugin_la_DEPENDENCIES =
+
+libdali_color_controller_plugin_la_CXXFLAGS = \
+                      $(DLOG_CFLAGS) \
+                      $(DALI_CFLAGS) \
+                      -I../../../dali-extension/color-controller \
+                      -Werror -Wall
+
+libdali_color_controller_plugin_la_LIBADD = \
+                      $(DLOG_LIBS) \
+                      $(DALI_LIBS)
+
+libdali_color_controller_plugin_la_LDFLAGS = \
+                      -rdynamic
\ No newline at end of file
diff --git a/build/tizen/color-controller/configure.ac b/build/tizen/color-controller/configure.ac
new file mode 100755 (executable)
index 0000000..c4df6b7
--- /dev/null
@@ -0,0 +1,26 @@
+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)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/configure.ac b/build/tizen/configure.ac
new file mode 100755 (executable)
index 0000000..99b1911
--- /dev/null
@@ -0,0 +1,45 @@
+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)
+
+AC_ARG_WITH([tizen_55_or_greater],
+            [AC_HELP_STRING([--with-tizen-55-or-greater],
+                            [Use this conditional when Tizen version is 5.5 or greater])],
+            [with_tizen_55_or_greater=yes],
+            [with_tizen_55_or_greater=no])
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+
+AC_CONFIG_SUBDIRS(key)
+AC_CONFIG_SUBDIRS(video-player)
+AC_CONFIG_SUBDIRS(image-loader)
+AC_CONFIG_SUBDIRS(color-controller)
+
+if test "x$with_tizen_55_or_greater" = "xyes"; then
+  AC_CONFIG_SUBDIRS(vector-animation-renderer)
+  AC_CONFIG_SUBDIRS(web-engine-chromium)
+  AC_CONFIG_SUBDIRS(web-engine-lwe)
+fi
+AC_CONFIG_SUBDIRS(dali-extension)
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+dali-extension.pc
+])
+
+AC_OUTPUT
diff --git a/build/tizen/dali-extension.pc.in b/build/tizen/dali-extension.pc.in
new file mode 100644 (file)
index 0000000..08373bf
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@devincludepath@
+
+Name: DALi extension
+Description: The DALi extension Libaray
+Version: @DALI_EXTENSION_VERSION@
+Requires: dali-adaptor dali-toolkit
+Libs: -L${libdir} -ldali-extension
+Cflags: -I${includedir}/dali-extension
diff --git a/build/tizen/dali-extension/Makefile.am b/build/tizen/dali-extension/Makefile.am
new file mode 100755 (executable)
index 0000000..11f781c
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2019 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build the Dali extension library
+
+extension_src_dir = ../../../dali-extension
+
+# evas-plugin
+include ../../../dali-extension/devel-api/evas-plugin/file.list
+include ../../../dali-extension/internal/evas-plugin/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-extension.la
+
+# Todo Evas plugin separation
+libdali_extension_la_SOURCES = \
+            $(evas_plugin_devel_src_files) \
+            $(evas_plugin_internal_src_files)
+
+libdali_extension_la_DEPENDENCIES =
+
+libdali_extension_la_CXXFLAGS = \
+            $(DLOG_CFLAGS) \
+            $(DALI_CFLAGS) \
+            $(DALI_EXTENSION_CFLAGS) \
+            $(DALI_ADAPTOR_INTEGRATION_CFLAGS) \
+            $(ELEMENTARY_CFLAGS) \
+            $(EVAS_CFLAGS) \
+            $(WAYLAND_CFLAGS) \
+            -DEFL_BETA_API_SUPPORT \
+            -I../../../ \
+            -Werror -Wall
+
+libdali_extension_la_LIBADD = \
+            $(DLOG_LIBS) \
+            $(DALI_LIBS) \
+            $(DALI_ADAPTOR_INTEGRATION_LIBS) \
+            $(ELEMENTARY_LIBS) \
+            $(EVAS_LIBS) \
+            $(WAYLAND_LIBS)
+
+libdali_extension_la_LDFLAGS = \
+            -rdynamic
+
+#install headers
+dali_extensiondir = $(devincludepath)/dali-extension
+dali_extension_HEADERS = ../../../dali-extension/dali-extension.h
+
+dali_extension_evasplugindir = $(devincludepath)/dali-extension/devel-api/evas-plugin
+dali_extension_evasplugin_HEADERS = $(evas_plugin_devel_header_files)
diff --git a/build/tizen/dali-extension/configure.ac b/build/tizen/dali-extension/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/build/tizen/image-loader/Makefile.am b/build/tizen/image-loader/Makefile.am
new file mode 100755 (executable)
index 0000000..1d35ced
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2018 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 image loader plugin
+
+if USE_IMAGELOADER_EXTENSION
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/image-loader/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-image-loader-plugin.la
+
+libdali_image_loader_plugin_la_includes =
+
+libdali_image_loader_plugin_la_SOURCES = \
+                     $(image_loader_plugin_src_files)
+
+libdali_image_loader_plugin_la_DEPENDENCIES =
+
+libdali_image_loader_plugin_la_CXXFLAGS = \
+                      $(DLOG_CFLAGS) \
+                      $(DALI_CFLAGS) \
+                      -Werror -Wall
+
+libdali_image_loader_plugin_la_CXXFLAGS+= \
+                      -I../../../dali-extension/image-loader
+
+libdali_image_loader_plugin_la_LIBADD = \
+                      $(DLOG_LIBS) \
+                      $(DALI_LIBS)
+
+libdali_image_loader_plugin_la_LDFLAGS = \
+                      -rdynamic
+endif
diff --git a/build/tizen/image-loader/configure.ac b/build/tizen/image-loader/configure.ac
new file mode 100755 (executable)
index 0000000..71ccb5b
--- /dev/null
@@ -0,0 +1,34 @@
+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)
+
+AC_ARG_ENABLE([imageloader-extension],
+              [AC_HELP_STRING([--enable-imageloader-extension],
+              [enables the image loader extension of all the symbols in the library])],
+              [enable_imageloader_extension=yes],
+              [enable_imageloader_extension=no])
+
+AM_CONDITIONAL([USE_IMAGELOADER_EXTENSION], [test x$enable_imageloader_extension = xyes])
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/key/Makefile.am b/build/tizen/key/Makefile.am
new file mode 100644 (file)
index 0000000..a479f43
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# 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 feedback plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/key/file.list
+include ../../../dali-extension/integration-api/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-key-extension.la
+
+# key extension
+libdali_key_extension_la_SOURCES = \
+                       $(key_extension_src_files)
+
+libdali_key_extension_la_DEPENDENCIES =
+
+libdali_key_extension_la_CXXFLAGS = \
+                       -I../../../dali-extension/ \
+                       -I../../../dali-extension/integration-api \
+                       $(DLOG_CFLAGS) \
+                       $(DALI_CFLAGS) \
+                       -Werror -Wall
+
+libdali_key_extension_la_LIBADD = \
+                       $(DLOG_LIBS)
+
+libdali_key_extension_la_LDFLAGS = \
+                       -rdynamic
+
+libdali_key_extensiondir = $(devincludepath)/dali-extension/integration-api
+libdali_key_extension_HEADERS = $(key_extension_header_files)
diff --git a/build/tizen/key/configure.ac b/build/tizen/key/configure.ac
new file mode 100644 (file)
index 0000000..4fac011
--- /dev/null
@@ -0,0 +1,32 @@
+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)
+
+AC_ARG_ENABLE([keyextension],
+              [AC_HELP_STRING([--enable-keyextension],
+              [enables the key extension of all the symbols in the library])],
+              [enable_keyextension=yes],
+              [enable_keyextension=no])
+
+AM_CONDITIONAL([USE_KEY_EXTENSION], [test x$enable_keyextension = xyes])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/vector-animation-renderer/Makefile.am b/build/tizen/vector-animation-renderer/Makefile.am
new file mode 100644 (file)
index 0000000..3260bb5
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2018 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 vector animation renderer plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/vector-animation-renderer/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-vector-animation-renderer-plugin.la
+
+libdali_vector_animation_renderer_plugin_la_SOURCES = \
+                     $(vector_animation_renderer_plugin_src_files)
+
+libdali_vector_animation_renderer_plugin_la_DEPENDENCIES =
+
+libdali_vector_animation_renderer_plugin_la_CXXFLAGS = \
+                      -I../../../ \
+                      $(DALI_CFLAGS) \
+                      $(RLOTTIE_CFLAGS) \
+                      -Werror -Wall
+
+libdali_vector_animation_renderer_plugin_la_LIBADD = \
+                      $(DALI_LIBS) \
+                      $(RLOTTIE_LIBS)
+
+libdali_vector_animation_renderer_plugin_la_LDFLAGS = \
+                      -rdynamic
+
diff --git a/build/tizen/vector-animation-renderer/configure.ac b/build/tizen/vector-animation-renderer/configure.ac
new file mode 100644 (file)
index 0000000..33ab430
--- /dev/null
@@ -0,0 +1,27 @@
+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)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+PKG_CHECK_MODULES(RLOTTIE, rlottie)
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/video-player/Makefile.am b/build/tizen/video-player/Makefile.am
new file mode 100644 (file)
index 0000000..3f56766
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# 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 feedback plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/video-player/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-video-player-plugin.la
+
+# Todo Video player plugin separation
+if ECOREWL2
+libdali_video_player_plugin_la_SOURCES = \
+                     $(video_player_ecore_wl2_plugin_src_files)
+else
+libdali_video_player_plugin_la_SOURCES = \
+                     $(video_player_ecore_wl_plugin_src_files)
+endif
+
+libdali_video_player_plugin_la_DEPENDENCIES =
+
+libdali_video_player_plugin_la_CXXFLAGS = \
+                      $(DLOG_CFLAGS) \
+                      $(DALI_CFLAGS) \
+                      $(CAPI_MEDIA_PLAYER_CFLAGS) \
+                      $(CAPI_SYSTEM_INFO_CFLAGS) \
+                      -Werror -Wall
+
+if ECOREWL2
+libdali_video_player_plugin_la_CXXFLAGS+= $(ECORE_WL2_CFLAGS) \
+                      -I../../../dali-extension/video-player/ecore-wl2
+else
+libdali_video_player_plugin_la_CXXFLAGS+= $(ECORE_WAYLAND_CFLAGS) \
+                      -I../../../dali-extension/video-player/ecore-wl
+endif
+
+libdali_video_player_plugin_la_LIBADD = \
+                      $(DLOG_LIBS) \
+                      $(DALI_LIBS) \
+                      $(CAPI_MEDIA_PLAYER_LIBS) \
+                      $(CAPI_SYSTEM_INFO_LIBS)
+
+if ECOREWL2
+libdali_video_player_plugin_la_LIBADD+= $(ECORE_WL2_LIBS)
+else
+libdali_video_player_plugin_la_LIBADD+= $(ECORE_WAYLAND_LIBS)
+endif
+
+libdali_video_player_plugin_la_LDFLAGS = \
+                      -rdynamic
+
diff --git a/build/tizen/video-player/configure.ac b/build/tizen/video-player/configure.ac
new file mode 100644 (file)
index 0000000..43bcc09
--- /dev/null
@@ -0,0 +1,41 @@
+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)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+PKG_CHECK_MODULES(CAPI_MEDIA_PLAYER, capi-media-player)
+PKG_CHECK_MODULES(CAPI_SYSTEM_INFO, capi-system-info)
+
+AC_ARG_ENABLE([ecore-wl2],
+              [AC_HELP_STRING([--enable-ecore-wl2], [build with ecorewl2 on tizen])],
+              [enable_ecore_wl2=yes],
+              [enable_ecore_wl2=no])
+
+AM_CONDITIONAL([ECOREWL2], [test x$enable_ecore_wl2 = xyes])
+
+if test x$enable_ecore_wl2 = xyes; then
+  PKG_CHECK_MODULES(ECORE_WL2, ecore-wl2)
+else
+  PKG_CHECK_MODULES(ECORE_WAYLAND, ecore-wayland)
+fi
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/web-engine-chromium/Makefile.am b/build/tizen/web-engine-chromium/Makefile.am
new file mode 100644 (file)
index 0000000..f503a0a
--- /dev/null
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2018 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 web engine chromium plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/web-engine-chromium/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-web-engine-chromium-plugin.la
+
+libdali_web_engine_chromium_plugin_la_SOURCES = \
+                     $(web_engine_chromium_plugin_src_files)
+
+libdali_web_engine_chromium_plugin_la_DEPENDENCIES =
+
+libdali_web_engine_chromium_plugin_la_CXXFLAGS = \
+                      $(DALI_CFLAGS) \
+                      $(WEB_ENGINE_CHROMIUM_CFLAGS) \
+                      $(ELEMENTARY_CFLAGS) \
+                      -I../../../dali-extension/web-engine-chromium \
+                      -Werror -Wall
+
+libdali_web_engine_chromium_plugin_la_LIBADD = \
+                      $(DLOG_LIBS) \
+                      $(DALI_LIBS) \
+                      $(WEB_ENGINE_CHROMIUM_LIBS)
+
+libdali_web_engine_chromium_plugin_la_LDFLAGS = \
+                      -rdynamic
+
diff --git a/build/tizen/web-engine-chromium/configure.ac b/build/tizen/web-engine-chromium/configure.ac
new file mode 100644 (file)
index 0000000..92069f5
--- /dev/null
@@ -0,0 +1,29 @@
+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)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+PKG_CHECK_MODULES(WAYLAND, libtbm)
+PKG_CHECK_MODULES(WEB_ENGINE_CHROMIUM, chromium-efl)
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/build/tizen/web-engine-lwe/Makefile.am b/build/tizen/web-engine-lwe/Makefile.am
new file mode 100644 (file)
index 0000000..37729e8
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2018 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 web engine lwe plugin
+
+extension_src_dir = ../../../dali-extension
+
+include ../../../dali-extension/web-engine-lwe/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-web-engine-lwe-plugin.la
+
+libdali_web_engine_lwe_plugin_la_SOURCES = \
+                     $(web_engine_lwe_plugin_src_files)
+
+libdali_web_engine_lwe_plugin_la_DEPENDENCIES =
+
+libdali_web_engine_lwe_plugin_la_CXXFLAGS = \
+                      $(DALI_CFLAGS) \
+                      $(WEB_ENGINE_LWE_CFLAGS) \
+                      -Werror -Wall
+
+libdali_web_engine_lwe_plugin_la_LIBADD = \
+                      $(DALI_LIBS) \
+                      $(WEB_ENGINE_LWE_LIBS)
+
+libdali_web_engine_lwe_plugin_la_LDFLAGS = \
+                      -rdynamic
+
diff --git a/build/tizen/web-engine-lwe/configure.ac b/build/tizen/web-engine-lwe/configure.ac
new file mode 100644 (file)
index 0000000..bbd0d47
--- /dev/null
@@ -0,0 +1,28 @@
+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)
+
+PKG_CHECK_MODULES([DALI], [dali-core dali-adaptor dali-toolkit])
+PKG_CHECK_MODULES(WAYLAND, libtbm)
+PKG_CHECK_MODULES([WEB_ENGINE_LWE], [lightweight-web-engine-dali-plugin])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
diff --git a/dali-extension.manifest b/dali-extension.manifest
new file mode 100644 (file)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
diff --git a/dali-extension/color-controller/file.list b/dali-extension/color-controller/file.list
new file mode 100644 (file)
index 0000000..864428d
--- /dev/null
@@ -0,0 +1,2 @@
+color_controller_plugin_src_files = \
+   $(extension_src_dir)/color-controller/tizen-color-controller.cpp
\ No newline at end of file
diff --git a/dali-extension/color-controller/tizen-color-controller.cpp b/dali-extension/color-controller/tizen-color-controller.cpp
new file mode 100644 (file)
index 0000000..6431f1c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 "tizen-color-controller.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/constants.h>
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::ColorControllerPlugin* CreateColorControllerPlugin( void )
+{
+  return new Dali::Plugin::TizenColorController;
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+TizenColorController::TizenColorController()
+{
+}
+
+TizenColorController::~TizenColorController()
+{
+}
+
+bool TizenColorController::RetrieveColor( const std::string& colorCode, Vector4& colorValue ) const
+{
+  colorValue = Color::WHITE;
+  return true;
+}
+
+bool TizenColorController::RetrieveColor( const std::string& colorCode , Vector4& textColor, Vector4& textOutlineColor, Vector4& textShadowColor ) const
+{
+  textColor = Color::WHITE;
+  textOutlineColor = Color::WHITE;
+  textShadowColor = Color::WHITE;
+  return true;
+}
+
+} // namespace Plugin
+
+} // namespace Dali;
\ No newline at end of file
diff --git a/dali-extension/color-controller/tizen-color-controller.h b/dali-extension/color-controller/tizen-color-controller.h
new file mode 100644 (file)
index 0000000..e777290
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef DALI_TIZEN_COLOR_CONTROLLER_PLUGIN_H
+#define DALI_TIZEN_COLOR_CONTROLLER_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 <string>
+#include <dali/public-api/math/vector4.h>
+#include <dali/devel-api/adaptor-framework/color-controller-plugin.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+class TizenColorController : public Dali::ColorControllerPlugin
+{
+
+public:
+
+  /**
+   * @brief TizenColorController constructor.
+   */
+  TizenColorController();
+
+  /**
+   * @brief TizenColorController destructor.
+   */
+  virtual ~TizenColorController();
+
+public:
+  /**
+   * @copydoc Dali::ColorControllerPlugin::RetrieveColor(const std::string&, Vector4&)
+   */
+  virtual bool RetrieveColor( const std::string& colorCode, Vector4& colorValue ) const;
+
+  /**
+   * @copydoc Dali::ColorControllerPlugin::RetrieveColor(const std::string&, Vector4&, Vector4&, Vector4&)
+   */
+  virtual bool RetrieveColor( const std::string& colorCode , Vector4& textColor, Vector4& textOutlineColor, Vector4& textShadowColor ) const;
+};
+
+}
+}
+#endif // DALI_TIZEN_COLOR_CONTROLLER_PLUGIN_H
diff --git a/dali-extension/dali-extension.h b/dali-extension/dali-extension.h
new file mode 100644 (file)
index 0000000..3d634aa
--- /dev/null
@@ -0,0 +1,24 @@
+#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>
+#include <dali-extension/devel-api/evas-plugin/scene.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..18d4414
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+// CLASS HEADER
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+EvasPlugin EvasPlugin::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+{
+  IntrusivePtr< Internal::EvasPlugin > impl = Internal::EvasPlugin::New( parentEvasObject, width, height, isTranslucent );
+
+  EvasPlugin evasPlugin = EvasPlugin( impl.Get() );
+
+  return evasPlugin;
+}
+
+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();
+}
+
+Scene EvasPlugin::GetDefaultScene()
+{
+  return Internal::GetImplementation( *this ).GetDefaultScene();
+}
+
+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..177f479
--- /dev/null
@@ -0,0 +1,370 @@
+#ifndef DALI_EXTENSION_EVAS_PLUGIN_H
+#define DALI_EXTENSION_EVAS_PLUGIN_H
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @addtogroup CAPI_DALI_EXTENSION_FRAMEWORK_MODULE
+ * @{
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+
+#include <dali/public-api/signals/dali-signal.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+class Scene;
+
+namespace Internal
+{
+class EvasPlugin;
+}
+
+/**
+ * @brief Application class used by EFL applications that wish to use Dali
+ *
+ * An EvasPlugin class object should be created by EFL applications
+ * that wish to use Dali. It provides a mean for initializing the
+ * resources required by the Dali::Core.
+ *
+ * The EvasPlugin class emits several signals which the user can
+ * connect to.  The user should not create any Dali objects in the main
+ * function and instead should connect to the Init signal of the
+ * EvasPlugin and create the Dali objects in the connected callback.
+ *
+ * Tizen EFL applications should follow the example below:
+ *
+ * @code
+ *
+ * #include <app.h>
+ * #include <Elementary.h>
+ * #include <dali/dali.h>
+ * #include <dali-toolkit/dali-toolkit.h>
+ * #include <dali-extension/dali-extension.h>
+ *
+ * using namespace Dali;
+ * using namespace Dali::Toolkit;
+ * using namespace Dali::Extension;
+ *
+ * namespace
+ * {
+ * const char* const APPLICATION_TITLE = "EvasPluginExample";
+ * const uint16_t EVAS_PLUGIN_WIDTH = 360;
+ * const uint16_t EVAS_PLUGIN_HEIGHT = 360;
+ * }
+ *
+ * class EvasPluginExample : public ConnectionTracker
+ * {
+ * public:
+ *   EvasPluginExample(EvasPlugin evasPlugin)
+ *   : mEvasPlugin(evasPlugin)
+ *   {
+ *     mEvasPlugin.InitSignal().Connect(this, &EvasPluginExample::OnInitialize);
+ *     mEvasPlugin.Run();
+ *   }
+ *
+ *   ~EvasPluginExample()
+ *   {
+ *     mEvasPlugin.Stop();
+ *   }
+ *
+ *   void OnInitialize()
+ *   {
+ *     Scene scene = mEvasPlugin.GetDefaultScene();
+ *     scene.SetBackgroundColor( Color::WHITE );
+ *
+ *     TextLabel textLabel = TextLabel::New( "Hello World" );
+ *     textLabel.SetParentOrigin( ParentOrigin::CENTER );
+ *     textLabel.SetAnchorPoint( AnchorPoint::CENTER );
+ *     textLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER );
+ *     textLabel.SetProperty( TextLabel::Property::POINT_SIZE, 40 );
+ *     textLabel.SetName( "helloWorldLabel" );
+ *     scene.Add( textLabel );
+ *
+ *     Animation anim = Animation::New( 3.f );
+ *     anim.SetLooping( true );
+ *     anim.AnimateBy( Property(textLabel, Actor::Property::ORIENTATION), Quaternion(Degree(0.f), Degree(360.f), Degree(0.f)) );
+ *     anim.Play();
+ *   }
+ *
+ * private:
+ *   EvasPlugin mEvasPlugin;
+ * };
+ *
+ * struct app_data
+ * {
+ *   Evas_Object* elm_win;
+ *   EvasPluginExample* evasPluginExample;
+ * };
+ *
+ * static void win_del(void *data, Evas_Object * obj, void *event_info)
+ * {
+ * }
+ *
+ * static bool app_create(void *data)
+ * {
+ *   struct app_data* ad = (struct app_data*)data;
+ *
+ *   // Sets the GL backend for rendering
+ *   elm_config_accel_preference_set("3d");
+ *
+ *   // Creates the elm window
+ *   ad->elm_win = elm_win_add(NULL, APPLICATION_TITLE, ELM_WIN_BASIC);
+ *
+ *   DALI_ASSERT_ALWAYS(ad->elm_win != NULL && "Fail to create elm window.");
+ *
+ *   elm_win_title_set(ad->elm_win, APPLICATION_TITLE);
+ *   elm_win_rotation_with_resize_set(ad->elm_win, 0);
+ *   evas_object_smart_callback_add(ad->elm_win, "delete,request", win_del, ad->elm_win);
+ *   evas_object_show(ad->elm_win);
+ *
+ *   // Adds the background
+ *   Evas_Object* bg = elm_bg_add(ad->elm_win);
+ *   elm_bg_color_set(bg, 255, 255, 255);
+ *   evas_object_size_hint_weight_set(bg, 0,0);
+ *   elm_win_resize_object_add(ad->elm_win, bg);
+ *   evas_object_show(bg);
+ *
+ *   // Creates an Evas plugin
+ *   EvasPlugin evasPlugin = EvasPlugin::New(ad->elm_win, EVAS_PLUGIN_WIDTH, EVAS_PLUGIN_HEIGHT, true);
+ *
+ *   // Creates a Dali application
+ *   ad->evasPluginExample = new EvasPluginExample(evasPlugin);
+ *
+ *   return true;
+ * }
+ *
+ * static void app_terminate(void *data)
+ * {
+ *   struct app_data* ad = (struct app_data*)data;
+ *
+ *   delete ad->evasPluginExample;
+ *   ad->evasPluginExample = NULL;
+ * }
+ *
+ * static void app_pause(void *data)
+ * {
+ * }
+ *
+ * static void app_resume(void *data)
+ * {
+ * }
+ *
+ * static void app_control(app_control_h service, void *data)
+ * {
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ *   // Initializes the Tizen application framework
+ *   ui_app_lifecycle_callback_s event_callback;
+ *
+ *   event_callback.create = app_create;
+ *   event_callback.terminate = app_terminate;
+ *   event_callback.pause = app_pause;
+ *   event_callback.resume = app_resume;
+ *   event_callback.app_control = app_control;
+ *
+ *   struct app_data ad;
+ *   memset(&ad, 0x0, sizeof(ad));
+ *
+ *   // Runs the Tizen application framework
+ *   return ui_app_main(argc, argv, &event_callback, &ad);
+ * }
+ *
+ * @endcode
+ */
+class DALI_IMPORT_API EvasPlugin : public Dali::BaseHandle
+{
+public:
+
+  typedef Signal<void (void)> EvasPluginSignalType;
+
+public:
+
+  /**
+   * @brief This is the constructor of EvasPlugin for Tizen EFL applications
+   *
+   * @param[in] parentEvasObject Parent Evas object of the default scene
+   * @param[in] width The initial width of the default scene
+   * @param[in] height The initial height of the default scene
+   * @param[in] isTranslucent Whether the Evas object is translucent or not
+   */
+  static EvasPlugin New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+  /**
+   * @brief Constructs an empty handle
+   */
+  EvasPlugin();
+
+  /**
+   * @brief Copy constructor
+   */
+  EvasPlugin( const EvasPlugin& evasPlugin );
+
+  /**
+   * @brief Assignment operator
+   */
+  EvasPlugin& operator=( const EvasPlugin& evasPlugin );
+
+  /**
+   * @brief Destructor
+   */
+  ~EvasPlugin();
+
+public:
+
+  /**
+   * @brief Runs the Evas plugin (rendering, event handling, etc)
+   */
+  void Run();
+
+  /**
+   * @note DEPRECATED. Instead, hide corresponding Evas object.
+   * @brief Pauses the Evas plugin
+   */
+  void Pause();
+
+  /**
+   * @note DEPRECATED. Instead, show corresponding Evas object.
+   * @brief Resumes the Evas plugin
+   */
+  void Resume();
+
+  /**
+   * @brief Stops the Evas plugin
+   */
+  void Stop();
+
+
+  /**
+   * @brief Get the default Scene handle
+   * @return The default Scene
+   */
+  Scene GetDefaultScene();
+
+  /**
+   * @note DEPRECATED. This is same as evasPlugin.GetDefaultScene().GetAccessEvasObject()
+   *
+   * @brief This returns the Evas_Object* for accessibility 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();
+
+  /**
+   * @note DEPRECATED. This is same as evasPlugin.GetDefaultScene().GetDaliEvasObject()
+   *
+   * @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
+   *
+   * @note EvasPlugin::Run() should be called 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();
+
+  /**
+   * @note DEPRECATED
+   * @brief Signal to notify the client when the EvasPlugin is about to be paused
+   *
+   * The user should connect to this signal if the user needs to perform any special
+   * activities when the application is about to be paused.
+   * @return The signal
+   */
+  EvasPluginSignalType& PauseSignal();
+
+  /**
+   * @note DEPRECATED
+   * @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();
+
+  /**
+   * @note DEPRECATED. Use Scene::ResizedSignal()
+   *
+   * @brief Signal to notify the client when the Evas object is resized
+   *
+   * @return The signal
+   */
+  EvasPluginSignalType& ResizeSignal();
+
+  /**
+   * @note DEPRECATED. Use Scene::FocusChangedSignal()
+   *
+   * @brief Signal to notify the client when the Evas object gets the keyboard focus
+   *
+   * @return The signal
+   */
+  EvasPluginSignalType& FocusedSignal();
+
+  /**
+   * @note DEPRECATED. Use Scene::FocusChangedSignal()
+   *
+   * @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..24958c9
--- /dev/null
@@ -0,0 +1,7 @@
+evas_plugin_devel_header_files = \
+   $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.h \
+   $(extension_src_dir)/devel-api/evas-plugin/scene.h
+
+evas_plugin_devel_src_files = \
+   $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.cpp \
+   $(extension_src_dir)/devel-api/evas-plugin/scene.cpp
diff --git a/dali-extension/devel-api/evas-plugin/scene.cpp b/dali-extension/devel-api/evas-plugin/scene.cpp
new file mode 100644 (file)
index 0000000..364a49d
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2020 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.
+ *
+ */
+
+// EXTENRAL INCLUDES
+#include <dali/public-api/actors/layer.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+#include <dali-extension/internal/evas-plugin/scene-impl.h>
+
+// CLASS HEADER
+#include <dali-extension/devel-api/evas-plugin/scene.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+Scene Scene::New( EvasPlugin evasPlugin, Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+{
+  IntrusivePtr< Internal::Scene > impl = Internal::Scene::New( parentEvasObject, width, height, isTranslucent );
+
+  Scene scene = Scene( impl.Get() );
+
+  impl->Initialize( &Internal::GetImplementation( evasPlugin ), false );
+
+  return scene;
+}
+
+Scene::Scene()
+{
+}
+
+Scene::Scene( const Scene& scene )
+: BaseHandle( scene )
+{
+}
+
+Scene& Scene::operator=( const Scene& scene )
+{
+  if( *this != scene )
+  {
+    BaseHandle::operator=( scene );
+  }
+  return *this;
+}
+
+Scene::~Scene()
+{
+}
+
+void Scene::Add( Actor actor )
+{
+  Internal::GetImplementation( *this ).Add( actor );
+}
+
+void Scene::Remove( Actor actor )
+{
+  Internal::GetImplementation( *this ).Remove( actor );
+}
+
+void Scene::SetBackgroundColor( const Vector4& color )
+{
+  Internal::GetImplementation( *this ).SetBackgroundColor( color );
+}
+
+Vector4 Scene::GetBackgroundColor() const
+{
+  return Internal::GetImplementation( *this ).GetBackgroundColor();
+}
+
+Layer Scene::GetRootLayer() const
+{
+  return Internal::GetImplementation( *this ).GetRootLayer();
+}
+
+uint32_t Scene::GetLayerCount() const
+{
+  return Internal::GetImplementation( *this ).GetLayerCount();
+}
+
+Layer Scene::GetLayer( uint32_t depth ) const
+{
+  return Internal::GetImplementation( *this ).GetLayer( depth );
+}
+
+Scene::SceneSize Scene::GetSize() const
+{
+  return Internal::GetImplementation( *this ).GetSize();
+}
+
+Evas_Object* Scene::GetAccessEvasObject()
+{
+  return Internal::GetImplementation( *this ).GetAccessEvasObject();
+}
+
+Evas_Object* Scene::GetDaliEvasObject()
+{
+  return Internal::GetImplementation( *this ).GetDaliEvasObject();
+}
+
+Scene::ResizedSignalType& Scene::ResizedSignal()
+{
+  return Internal::GetImplementation( *this ).ResizedSignal();
+}
+
+Scene::VisibilityChangedSignalType& Scene::VisibilityChangedSignal()
+{
+  return Internal::GetImplementation( *this ).VisibilityChangedSignal();
+}
+
+Scene::FocusChangedSignalType& Scene::FocusChangedSignal()
+{
+  return Internal::GetImplementation( *this ).FocusChangedSignal();
+}
+
+Scene::Scene( Internal::Scene* scene )
+: BaseHandle( scene )
+{
+}
+
+}  // namespace Extension
+
+}  // namespace Dali
diff --git a/dali-extension/devel-api/evas-plugin/scene.h b/dali-extension/devel-api/evas-plugin/scene.h
new file mode 100644 (file)
index 0000000..fb57d1b
--- /dev/null
@@ -0,0 +1,240 @@
+#ifndef DALI_EXTENSION_SCENE_H
+#define DALI_EXTENSION_SCENE_H
+
+/*
+ * Copyright (c) 2020 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/actors/actor.h>
+#include <dali/public-api/math/uint-16-pair.h>
+#include <dali/public-api/signals/dali-signal.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+
+class Layer;
+
+namespace Extension
+{
+
+namespace Internal
+{
+class Scene;
+}
+
+/**
+ * @brief Like EvasPlugin is an Application class used by EFL applications,
+ * the Scene corresponds to the Window class.
+ *
+ * |  DALi         | EFL with DALi     |
+ * |---------------|-------------------|
+ * |  Application  | EvasPlugin        |
+ * |  Window       | Scene             |
+ *
+ * When the EvasPlugin is created, a Scene is generated by default, it is called "default scene".
+ * You can get it by calling EvasPlugin::GetDefaultScene().
+ *
+ * Also, the EvasPlugin can have multiple scenes.
+ * You can create a new Scene by calling Scene::New(...);
+ */
+class DALI_IMPORT_API Scene : public Dali::BaseHandle
+{
+public:
+
+  typedef Uint16Pair SceneSize;
+
+  typedef Signal<void (Scene, bool)> VisibilityChangedSignalType;
+
+  typedef Signal<void (Scene, bool)> FocusChangedSignalType;
+
+  typedef Signal<void (Scene, uint16_t, uint16_t)> ResizedSignalType;
+
+public:
+
+  /**
+   * @brief Creates an initialized handle to a new Scene
+   * @note You should hold the returned handle. If you missed the handle, the scene will be released
+   *
+   * @param[in] evasPlugin The EvasPlugin handle
+   * @param[in] parentEvasObject Parent Evas object of the new scene
+   * @param[in] width The initial width of the scene
+   * @param[in] height The initial height of the scene
+   * @param[in] isTranslucent Whether the Evas object is translucent or not
+   */
+  static Scene New( EvasPlugin evasPlugin, Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+  /**
+   * @brief Constructs an empty handle
+   */
+  Scene();
+
+  /**
+   * @brief Copy constructor
+   */
+  Scene( const Scene& scene );
+
+  /**
+   * @brief Assignment operator
+   */
+  Scene& operator=( const Scene& scene );
+
+  /**
+   * @brief Destructor
+   */
+  ~Scene();
+
+public:
+  /**
+   * @brief Adds a child Actor to the Scene.
+   *
+   * The child will be referenced.
+   *
+   * @param[in] actor The child
+   * @pre The actor has been initialized.
+   * @pre The actor does not have a parent.
+   */
+  void Add( Actor actor );
+
+  /**
+   * @brief Removes a child Actor from the Scene.
+   *
+   * The child will be unreferenced.
+   *
+   * @param[in] actor The child
+   * @pre The actor has been added to the Scene.
+   */
+  void Remove( Actor actor );
+
+  /**
+   * @brief Sets the background color of the Scene.
+   *
+   * @param[in] color The new background color
+   */
+  void SetBackgroundColor( const Vector4& color );
+
+  /**
+   * @brief Gets the background color of the Scene.
+   *
+   * @return The background color
+   */
+  Vector4 GetBackgroundColor() const;
+
+  /**
+   * @brief Returns the root Layer of the Scene.
+   *
+   * @return The root layer
+   */
+  Layer GetRootLayer() const;
+
+  /**
+   * @brief Queries the number of on-scene layers.
+   *
+   * Note that a default layer is always provided (count >= 1).
+   *
+   * @return The number of layers
+   */
+  uint32_t GetLayerCount() const;
+
+  /**
+   * @brief Retrieves the layer at a specified depth in the Scene.
+   *
+   * @SINCE_1_4.19
+   * @param[in] depth The depth
+   * @return The layer found at the given depth
+   * @pre Depth is less than layer count; see GetLayerCount().
+   */
+  Layer GetLayer( uint32_t depth ) const;
+
+  /**
+   * @brief Returns the size of the Scene in pixels as a Vector.
+   *
+   * The x component will be the width of the Scene in pixels.
+   * The y component will be the height of the Scene in pixels.
+   *
+   * @return The size of the Scene as a Vector
+   */
+  SceneSize GetSize() const;
+
+  /**
+   * @brief This returns the Evas_Object* for accessibility 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 Evas object's visibility is changed
+   *
+   * @return The signal
+   */
+  VisibilityChangedSignalType& VisibilityChangedSignal();
+
+  /**
+   * @brief Signal to notify the client when the Evas object is resized
+   *
+   * @return The signal
+   */
+  ResizedSignalType& ResizedSignal();
+
+  /**
+   * @brief Signal to notify the client when the Evas object gets/loses the keyboard focus
+   *
+   * @return The signal
+   */
+  FocusChangedSignalType& FocusChangedSignal();
+
+public: // Not intended for application developers
+
+  /**
+   * @brief Internal constructor
+   */
+  explicit DALI_INTERNAL Scene( Internal::Scene* scene );
+
+};
+
+/**
+ * @}
+ */
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif // DALI_EXTENSION_SCENE_H
diff --git a/dali-extension/image-loader/README b/dali-extension/image-loader/README
new file mode 100755 (executable)
index 0000000..c29e199
--- /dev/null
@@ -0,0 +1,53 @@
+## Implement
+
+You can implement a new type of image loader plugin.
+implement LoadBitmapFromImage and LoadImageHeader in the loader-dummy.cpp file.
+
+ bool LoadImageHeader( const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height )
+ {
+  bool success = false;
+  /* Loads the header of a image file and fills in the width and height appropriately. */
+
+  return success;
+ }
+
+ bool LoadBitmapFromImage( const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
+ {
+   bool success = false;
+   /* Loads the bitmap from an image file.  This function checks the header first */
+
+   return success;
+ }
+
+And register your new image loader in tizen-image-loader.cpp
+ 1) add type of new file formats
+   enum FileFormats
+  {
+    // Unknown file format
+    FORMAT_UNKNOWN = -1,
+
+    // formats that use magic bytes
+    FORMAT_DUMMY = 0,
+    FORMAT_TOTAL_COUNT
+  };
+
+ 2) add function of new image loader
+  const Dali::ImageLoader::BitmapLoader BITMAP_LOADER_LOOKUP_TABLE[FORMAT_TOTAL_COUNT] =
+  {
+    { 0x0,                0x0,                LoadBitmapFromImage,  LoadImageHeader,  Dali::Integration::Bitmap::BITMAP_2D_PACKED_PIXELS },
+  };
+
+ 3) add file extensions and formats
+   const FormatExtension FORMAT_EXTENSIONS[] =
+  {
+    { ".dummy",  FORMAT_DUMMY  }
+  };
+
+## Build
+To use the new Image Loader plugin, You must change the use_image_loader value to 1.
+ packaging/dali-extension.spec
+ # Use Image Loader Plugin
+ %define use_image_loader 1
+
+ When you build the dali-extension, dali-extension-image-loader-plugin.armv7l.rpm file is created.
+
diff --git a/dali-extension/image-loader/file.list b/dali-extension/image-loader/file.list
new file mode 100755 (executable)
index 0000000..6b458d3
--- /dev/null
@@ -0,0 +1,3 @@
+image_loader_plugin_src_files = \
+   $(extension_src_dir)/image-loader/tizen-image-loader.cpp \
+   $(extension_src_dir)/image-loader/loader-dummy.cpp
diff --git a/dali-extension/image-loader/loader-dummy.cpp b/dali-extension/image-loader/loader-dummy.cpp
new file mode 100755 (executable)
index 0000000..f39c0a7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 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.
+ *
+ */
+
+// HEADER
+#include "loader-dummy.h"
+
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/images/image.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Plugin
+{
+
+/**
+ * This code is a dummy code. You can implement it here.
+ */
+
+bool LoadImageHeader( const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height )
+{
+  bool success = false;
+  /* Loads the header of a image file and fills in the width and height appropriately. */
+
+  return success;
+}
+
+
+bool LoadBitmapFromImage( const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap )
+{
+  bool success = false;
+  /* Loads the bitmap from an image file.  This function checks the header first */
+
+  return success;
+}
+
+}
+}
diff --git a/dali-extension/image-loader/loader-dummy.h b/dali-extension/image-loader/loader-dummy.h
new file mode 100755 (executable)
index 0000000..5d2257f
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef DALI_TIZEN_EXTENSION_LOADER_DUMMY_H
+#define DALI_TIZEN_EXTENSION_LOADER_DUMMY_H
+
+/*
+ * Copyright (c) 2018 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 <cstdio>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/images/pixel.h>
+#include <dali/devel-api/adaptor-framework/image-loader-input.h>
+
+namespace Dali
+{
+namespace Devel
+{
+class PixelBuffer;
+}
+
+namespace Plugin
+{
+
+class ResourceLoadingClient;
+
+/**
+ * Loads the bitmap from an image file.  This function checks the header first
+ * and if it is not a image file, then it returns straight away.
+ * @param[in]  input  Information about the input image (including file pointer)
+ * @param[out] bitmap The bitmap class where the decoded image will be stored
+ * @return  true if file decoded successfully, false otherwise
+ */
+bool LoadBitmapFromImage( const Dali::ImageLoader::Input& input, Dali::Devel::PixelBuffer& bitmap );
+
+/**
+ * Loads the header of a image file and fills in the width and height appropriately.
+ * @param[in]   fp      Pointer to the Image file
+ * @param[in]  attributes  Describes the dimensions, pixel format and other details for loading the image data
+ * @param[out]  width   Is set with the width of the image
+ * @param[out]  height  Is set with the height of the image
+ * @return true if the file's header was read successully, false otherwise
+ */
+bool LoadImageHeader( const Dali::ImageLoader::Input& input, unsigned int& width, unsigned int& height );
+
+} // namespace Plugin
+
+} // namespace Dali
+#endif // DALI_TIZEN_EXTENSION_LOADER_DUMMY_H
diff --git a/dali-extension/image-loader/tizen-image-loader.cpp b/dali-extension/image-loader/tizen-image-loader.cpp
new file mode 100755 (executable)
index 0000000..34bf24b
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2018 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 <tizen-image-loader.h>
+#include <dali/integration-api/debug.h>
+#include <dali/integration-api/bitmap.h>
+#include "loader-dummy.h"
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::ImageLoaderPlugin* CreateImageLoaderPlugin(void)
+{
+  return new Dali::Plugin::TizenImageLoader;
+}
+
+extern "C" DALI_EXPORT_API void DestroyImageLoaderPlugin( Dali::ImageLoaderPlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+namespace Plugin
+{
+namespace
+{
+  /**
+   * Enum for file formats, has to be in sync with BITMAP_LOADER_LOOKUP_TABLE
+   */
+  enum FileFormats
+  {
+    // Unknown file format
+    FORMAT_UNKNOWN = -1,
+
+    // formats that use magic bytes
+    FORMAT_DUMMY = 0,
+    FORMAT_TOTAL_COUNT
+  };
+
+  /**
+   * A lookup table containing all the bitmap loaders with the appropriate information.
+   * Has to be in sync with enum FileFormats
+   */
+  const Dali::ImageLoader::BitmapLoader BITMAP_LOADER_LOOKUP_TABLE[FORMAT_TOTAL_COUNT] =
+  {
+    { 0x0,                0x0,                LoadBitmapFromImage,  LoadImageHeader,  Dali::Integration::Bitmap::BITMAP_2D_PACKED_PIXELS },
+  };
+
+
+  struct FormatExtension
+  {
+    const std::string extension;
+    FileFormats format;
+  };
+
+  const FormatExtension FORMAT_EXTENSIONS[] =
+  {
+    { ".dummy",  FORMAT_DUMMY  }
+  };
+
+  const unsigned int FORMAT_EXTENSIONS_COUNT = sizeof(FORMAT_EXTENSIONS) / sizeof(FormatExtension);
+
+
+  FileFormats GetFormatHint( const std::string& filename )
+  {
+    FileFormats format = FORMAT_UNKNOWN;
+
+    for ( unsigned int i = 0; i < FORMAT_EXTENSIONS_COUNT; ++i )
+    {
+      unsigned int length = FORMAT_EXTENSIONS[i].extension.size();
+      if ( ( filename.size() > length ) &&
+           ( 0 == filename.compare( filename.size() - length, length, FORMAT_EXTENSIONS[i].extension ) ) )
+      {
+        format = FORMAT_EXTENSIONS[i].format;
+        break;
+      }
+    }
+    return format;
+  }
+
+}
+
+TizenImageLoader::TizenImageLoader()
+{
+}
+
+TizenImageLoader::~TizenImageLoader()
+{
+}
+
+const Dali::ImageLoader::BitmapLoader* TizenImageLoader::BitmapLoaderLookup( const std::string& filename ) const
+{
+  const Dali::ImageLoader::BitmapLoader *lookupPtr = BITMAP_LOADER_LOOKUP_TABLE;
+  FileFormats format =  GetFormatHint( filename );
+  if ( format != FORMAT_UNKNOWN )
+  {
+    lookupPtr = BITMAP_LOADER_LOOKUP_TABLE + format;
+    return lookupPtr;
+  }
+  else
+  {
+    return NULL;
+  }
+}
+
+} // namespace Plugin
+
+} // namespace Dali
+
diff --git a/dali-extension/image-loader/tizen-image-loader.h b/dali-extension/image-loader/tizen-image-loader.h
new file mode 100755 (executable)
index 0000000..7066edb
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef DALI_TIZEN_IMAGE_LOADER_PLUGIN_H
+#define DALI_TIZEN_IMAGE_LOADER_PLUGIN_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/image-loader-plugin.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * image loading plugin for image loader.
+ */
+class TizenImageLoader : public Dali::ImageLoaderPlugin
+{
+
+public: // Construction & Destruction
+
+  /**
+   * Constructor
+   */
+  TizenImageLoader();
+
+  /**
+   * Destructor
+   */
+  virtual ~TizenImageLoader();
+
+public: // ImageLoaderPlugin overrides
+
+  /**
+   * @copydoc Dali::Plugin::TizenImageLoader::BitmapLoaderLookup()
+   */
+  virtual const Dali::ImageLoader::BitmapLoader* BitmapLoaderLookup( const std::string& filename ) const;
+
+};
+
+}  // namespace Plugin
+
+}  // namespace Dali
+
+#endif // DALI_TIZEN_IMAGE_LOADER_PLUGIN_H
diff --git a/dali-extension/integration-api/file.list b/dali-extension/integration-api/file.list
new file mode 100644 (file)
index 0000000..2b6c6af
--- /dev/null
@@ -0,0 +1,2 @@
+key_extension_header_files = \
+   $(extension_src_dir)/integration-api/key-extension.h
diff --git a/dali-extension/integration-api/key-extension.h b/dali-extension/integration-api/key-extension.h
new file mode 100644 (file)
index 0000000..3c04e09
--- /dev/null
@@ -0,0 +1,85 @@
+#ifndef __DALI_KEY_EXTENSION_H__
+#define __DALI_KEY_EXTENSION_H__
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/devel-api/adaptor-framework/key-extension-plugin.h>
+
+namespace Dali
+{
+
+/**
+ * @brief Enumeration for mapping keyboard and mouse button event keycodes to extension codes.
+ * @SINCE_1_2.43
+ */
+enum EXTENSION_KEY
+{
+};
+
+/**
+ * @brief Checks if a key event is for a specific extension DALI KEY.
+ *
+ * @SINCE_1_2.43
+ * @param keyEvent reference to a keyEvent structure
+ * @param daliKey Dali extension key enum
+ * @return true if the key is matched, @c false if not
+ */
+DALI_IMPORT_API bool IsExtensionKey( const Dali::KeyEvent& keyEvent, Dali::EXTENSION_KEY daliKey);
+
+namespace Plugin
+{
+class KeyExtension : public Dali::KeyExtensionPlugin
+{
+
+public:
+
+  /**
+   * @brief KeyExtension constructor.
+   * @SINCE_1_2.43
+   */
+  KeyExtension();
+
+  /**
+   * @brief KeyExtension destructor.
+   * @SINCE_1_2.43
+   */
+  virtual ~KeyExtension();
+
+  /**
+   * @brief Get extension key lookup table.
+   *
+   * @SINCE_1_2.43
+   * @return Pointer of extension Key lookup table.
+   */
+  virtual Dali::KeyExtensionPlugin::KeyLookup* GetKeyLookupTable();
+
+  /**
+   * @brief Get count of extension key lookup table.
+   *
+   * @SINCE_1_2.43
+   * @return count of extension Key lookup table.
+   */
+  virtual std::size_t GetKeyLookupTableCount();
+};
+
+}
+}
+#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..517cbd5
--- /dev/null
@@ -0,0 +1,939 @@
+/*
+ * Copyright ( c ) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/key-devel.h>
+#include <dali/public-api/events/device.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-event-interface.h>
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-event-handler.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const int TOUCH_DEVICE_ID = 0;
+
+const char* EVAS_OBJECT_FOCUSED_EVENT_NAME = "focused";
+const char* EVAS_OBJECT_UNFOCUSED_EVENT_NAME = "unfocused";
+
+/**
+ * Copied from x server
+ * @brief Retrieve the current milliseconds.
+ *
+ * @return the current milliseconds.
+ */
+unsigned int GetCurrentMilliSeconds( void )
+{
+  struct timeval tv;
+
+  struct timespec tp;
+  static clockid_t clockid;
+
+  if( !clockid )
+  {
+#ifdef CLOCK_MONOTONIC_COARSE
+    if( clock_getres( CLOCK_MONOTONIC_COARSE, &tp ) == 0 && ( tp.tv_nsec / 1000 ) <= 1000 && clock_gettime( CLOCK_MONOTONIC_COARSE, &tp ) == 0 )
+    {
+      clockid = CLOCK_MONOTONIC_COARSE;
+    }
+    else
+#endif
+    if( clock_gettime( CLOCK_MONOTONIC, &tp ) == 0 )
+    {
+      clockid = CLOCK_MONOTONIC;
+    }
+    else
+    {
+      clockid = ~0L;
+    }
+  }
+  if( clockid != ~0L && clock_gettime( clockid, &tp ) == 0 )
+  {
+    return ( tp.tv_sec * 1000 ) + ( tp.tv_nsec / 1000000L );
+  }
+
+  gettimeofday( &tv, NULL );
+  return ( tv.tv_sec * 1000 ) + ( tv.tv_usec / 1000 );
+}
+
+/**
+ * @brief Retrieve the dali screen touch point.
+ *
+ * @param[in] canvasX is the x of canvas position
+ * @param[in] canvasY is the y of canvas position
+ * @param[in] evasObject is rendered by dali
+ * @param[out] screenX is the x of local position of evasObject
+ * @param[out] screenY is the y of local position of evasObject
+ */
+void GetScreenPosition( Evas_Coord canvasX, Evas_Coord canvasY, Evas_Object* evasObject, Evas_Coord &screenX, Evas_Coord &screenY )
+{
+  Evas_Coord objX = 0, objY = 0, objW = 0, objH = 0;
+  evas_object_geometry_get( evasObject, &objX, &objY, &objW, &objH );
+
+  screenX = canvasX - objX;
+  screenY = canvasY - objY;
+}
+
+void ConvertActionInfo( Elm_Access_Action_Info* elmActionInfo, Dali::Extension::Internal::AccessActionInfo&  daliActionInfo )
+{
+  daliActionInfo.x = elmActionInfo->x;
+  daliActionInfo.y = elmActionInfo->y;
+  daliActionInfo.mouseType = elmActionInfo->mouse_type;
+
+  switch( elmActionInfo->action_type )
+  {
+    case ELM_ACCESS_ACTION_HIGHLIGHT:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_READ:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_READ;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_PREV;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_NEXT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_ACTIVATE:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_ACTIVATE;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_UNHIGHLIGHT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_SCROLL:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_SCROLL;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_UP:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_UP;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_DOWN:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_DOWN;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_BACK:
+    {
+      daliActionInfo.actionType = ACCESS_ACTION_BACK;
+    }
+    break;
+
+    default:
+
+    break;
+  }
+
+  switch( elmActionInfo->action_by )
+  {
+    case ELM_ACCESS_ACTION_HIGHLIGHT:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_READ:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_READ;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_PREV;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_NEXT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_ACTIVATE:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_ACTIVATE;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_UNHIGHLIGHT;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_SCROLL:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_SCROLL;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_UP:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_UP;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_DOWN:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_DOWN;
+    }
+    break;
+
+    case ELM_ACCESS_ACTION_BACK:
+    {
+      daliActionInfo.actionBy = ACCESS_ACTION_BACK;
+    }
+    break;
+
+    default:
+
+    break;
+  }
+
+  daliActionInfo.highlightCycle = elmActionInfo->highlight_cycle;
+  daliActionInfo.timeStamp = GetCurrentMilliSeconds();
+}
+
+template<typename Type>
+void FillIntegrationKeyEvent( Type keyEvent, Integration::KeyEvent& result )
+{
+  // KeyName
+  if( keyEvent->keyname )
+  {
+    result.keyName = keyEvent->keyname;
+  }
+
+  // LogicalKey
+  if( keyEvent->key )
+  {
+    result.logicalKey = keyEvent->key;
+  }
+
+  // KeyString
+  if( keyEvent->string )
+  {
+    result.keyString = keyEvent->string;
+  }
+
+  // KeyCode
+  if( keyEvent->keyname && !strncmp( keyEvent->keyname, "Keycode-", 8 ) )
+  {
+    result.keyCode = atoi( keyEvent->keyname + 8 );
+  }
+  else
+  {
+    int keycode = Dali::DevelKey::GetDaliKeyCode( keyEvent->keyname );
+    result.keyCode = ( keycode == Dali::DALI_KEY_INVALID ) ? 0 : keycode;
+  }
+
+  // Modifier
+  result.keyModifier = 0;
+  if( evas_key_modifier_is_set( keyEvent->modifiers, "Shift" ) )
+  {
+    result.keyModifier |= ECORE_EVENT_MODIFIER_SHIFT;
+  }
+  if( evas_key_modifier_is_set( keyEvent->modifiers, "Alt" ) )
+  {
+    result.keyModifier |= ECORE_EVENT_MODIFIER_ALT;
+  }
+  if( evas_key_modifier_is_set( keyEvent->modifiers, "AltGr" ) )
+  {
+    result.keyModifier |= ECORE_EVENT_MODIFIER_ALTGR;
+  }
+  if( evas_key_modifier_is_set( keyEvent->modifiers, "Control" ) )
+  {
+    result.keyModifier |= ECORE_EVENT_MODIFIER_CTRL;
+  }
+  if( evas_key_modifier_is_set( keyEvent->modifiers, "Win" ) ||
+      evas_key_modifier_is_set( keyEvent->modifiers, "Super" ) ||
+      evas_key_modifier_is_set( keyEvent->modifiers, "Hyper" ) )
+  {
+    result.keyModifier |= ECORE_EVENT_MODIFIER_WIN;
+  }
+
+  // Time
+  result.time = keyEvent->timestamp;
+
+  // Compose
+  if( keyEvent->compose )
+  {
+    result.compose = keyEvent->compose;
+  }
+
+  // DeviceName
+  const char* ecoreDeviceName = ecore_device_name_get( keyEvent->dev );
+  if( ecoreDeviceName )
+  {
+    result.deviceName = ecoreDeviceName;
+  }
+
+  // DeviceClass
+  Ecore_Device_Class ecoreDeviceClass = ecore_device_class_get( keyEvent->dev );
+  switch( ecoreDeviceClass )
+  {
+    case ECORE_DEVICE_CLASS_SEAT:
+    {
+      result.deviceClass = Device::Class::USER;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_KEYBOARD:
+    {
+      result.deviceClass = Device::Class::KEYBOARD;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_MOUSE:
+    {
+      result.deviceClass = Device::Class::MOUSE;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_TOUCH:
+    {
+      result.deviceClass = Device::Class::TOUCH;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_PEN:
+    {
+      result.deviceClass = Device::Class::PEN;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_POINTER:
+    {
+      result.deviceClass = Device::Class::POINTER;
+      break;
+    }
+    case ECORE_DEVICE_CLASS_GAMEPAD:
+    {
+      result.deviceClass = Device::Class::GAMEPAD;
+      break;
+    }
+    default:
+    {
+      result.deviceClass = Device::Class::NONE;
+      break;
+    }
+  }
+
+  // DeviceSubClass
+  Ecore_Device_Subclass ecoreDeviceSubclass = ecore_device_subclass_get( keyEvent->dev );
+
+  switch( ecoreDeviceSubclass )
+  {
+    case ECORE_DEVICE_SUBCLASS_FINGER:
+    {
+      result.deviceSubclass = Device::Subclass::FINGER;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_FINGERNAIL:
+    {
+      result.deviceSubclass = Device::Subclass::FINGERNAIL;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_KNUCKLE:
+    {
+      result.deviceSubclass = Device::Subclass::KNUCKLE;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_PALM:
+    {
+      result.deviceSubclass = Device::Subclass::PALM;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_HAND_SIZE:
+    {
+      result.deviceSubclass = Device::Subclass::HAND_SIDE;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_HAND_FLAT:
+    {
+      result.deviceSubclass = Device::Subclass::HAND_FLAT;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_PEN_TIP:
+    {
+      result.deviceSubclass = Device::Subclass::PEN_TIP;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_TRACKPAD:
+    {
+      result.deviceSubclass = Device::Subclass::TRACKPAD;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_TRACKPOINT:
+    {
+      result.deviceSubclass = Device::Subclass::TRACKPOINT;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_TRACKBALL:
+    {
+      result.deviceSubclass = Device::Subclass::TRACKBALL;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_REMOCON:
+    {
+      result.deviceSubclass = Device::Subclass::REMOCON;
+      break;
+    }
+    case ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD:
+    {
+      result.deviceSubclass = Device::Subclass::VIRTUAL_KEYBOARD;
+      break;
+    }
+    default:
+    {
+      result.deviceSubclass = Device::Subclass::NONE;
+      break;
+    }
+  }
+}
+
+} // anonymous namespace
+
+EvasEventHandler::EvasEventHandler( EvasEventInterface& evasEventInterface )
+: mEvasEventInterface( evasEventInterface )
+{
+  EvasWrapper* evasWrapper = mEvasEventInterface.GetEvasWrapper();
+  Evas_Object* renderTarget = evasWrapper->GetRenderTarget();
+  Evas_Object* accessibilityTarget = evasWrapper->GetAccessibilityTarget();
+  Evas_Object* focusTarget = evasWrapper->GetFocusTarget();
+  Evas* renderTargetAsEvas = evas_object_evas_get( renderTarget );
+
+  // Register the evas event callbacks
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_DOWN,  OnEvasObjectMouseDown,      &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_UP,    OnEvasObjectMouseUp,        &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_MOVE,  OnEvasObjectMouseMove,      &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel,     &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_DOWN,  OnEvasObjectMultiTouchDown, &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_UP,    OnEvasObjectMultiTouchUp,   &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MULTI_MOVE,  OnEvasObjectMultiTouchMove, &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_KEY_DOWN,    OnEvasObjectKeyDown,        &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_KEY_UP,      OnEvasObjectKeyUp,          &evasEventInterface );
+
+  // Register the evas geometry callbacks
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_MOVE,   OnEvasObjectMove,   &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_RESIZE, OnEvasObjectResize, &evasEventInterface );
+
+  // Register the evas visibility callbacks
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_SHOW, OnEvasObjectShow, &evasEventInterface );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_HIDE, OnEvasObjectHide, &evasEventInterface );
+
+  // Register the evas focus callbacks
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_FOCUS_IN,  OnEvasObjectFocusIn,  this );
+  evas_object_event_callback_add( renderTarget, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut, this );
+
+  evas_event_callback_add( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN,  OnEvasFocusIn,  &evasEventInterface );
+  evas_event_callback_add( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut, &evasEventInterface );
+
+  // Register the elm access action callbacks and these callbacks are disconnected when mElmAccessEvasObject is unregistred
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT,      OnElmAccessActionHighlight,      &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_UNHIGHLIGHT,    OnElmAccessActionUnhighlight,    &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, OnElmAccessActionHighlightNext,  &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, OnElmAccessActionHighlightPrev,  &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_ACTIVATE,       OnElmAccessActionActivate,       &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_UP,             OnElmAccessActionUp,             &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_DOWN,           OnElmAccessActionDown,           &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_SCROLL,         OnElmAccessActionScroll,         &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_BACK,           OnElmAccessActionBack,           &evasEventInterface );
+  elm_access_action_cb_set( accessibilityTarget, ELM_ACCESS_ACTION_READ,           OnElmAccessActionRead,           &evasEventInterface );
+
+  // Register the elm focus callbacks
+  evas_object_smart_callback_add( focusTarget, EVAS_OBJECT_FOCUSED_EVENT_NAME,   OnEvasObjectSmartFocused,   this );
+  evas_object_smart_callback_add( focusTarget, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused, this );
+
+  EnableEcoreWl2Events();
+}
+
+EvasEventHandler::~EvasEventHandler()
+{
+  EvasWrapper* evasWrapper = mEvasEventInterface.GetEvasWrapper();
+  Evas_Object* renderTarget = evasWrapper->GetRenderTarget();
+  Evas_Object* focusTarget = evasWrapper->GetFocusTarget();
+  Evas* renderTargetAsEvas = evas_object_evas_get( renderTarget );
+
+  // Unregister the evas event callbacks.
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_DOWN,  OnEvasObjectMouseDown );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_UP,    OnEvasObjectMouseUp );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_MOVE,  OnEvasObjectMouseMove );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_DOWN,  OnEvasObjectMultiTouchDown );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_UP,    OnEvasObjectMultiTouchUp );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MULTI_MOVE,  OnEvasObjectMultiTouchMove );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_KEY_DOWN,    OnEvasObjectKeyDown );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_KEY_UP,      OnEvasObjectKeyUp );
+
+  // Unregister the evas geometry callbacks.
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_MOVE,   OnEvasObjectMove );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_RESIZE, OnEvasObjectResize );
+
+  // Unregister the evas visibility callbacks
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_SHOW, OnEvasObjectShow );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_HIDE, OnEvasObjectHide );
+
+  // Unregister the evas focus callbacks
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_FOCUS_IN,  OnEvasObjectFocusIn );
+  evas_object_event_callback_del( renderTarget, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut );
+
+  evas_event_callback_del( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN,  OnEvasFocusIn );
+  evas_event_callback_del( renderTargetAsEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut );
+
+  // Unregister the elm focus callbacks
+  evas_object_smart_callback_del( focusTarget, EVAS_OBJECT_FOCUSED_EVENT_NAME,   OnEvasObjectSmartFocused );
+  evas_object_smart_callback_del( focusTarget, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused );
+
+  DisableEcoreWl2Events();
+}
+
+void EvasEventHandler::EnableEcoreWl2Events()
+{
+  if( !mEcoreEventHandlers.size() )
+  {
+    // Register Window visibility change events
+    mEcoreEventHandlers.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, OnEcoreWl2EventWindowVisibilityChange, &mEvasEventInterface ) );
+  }
+}
+
+void EvasEventHandler::DisableEcoreWl2Events()
+{
+  if( mEcoreEventHandlers.size() )
+  {
+    // Unregister Window events
+    for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandlers.begin(), endIter = mEcoreEventHandlers.end(); iter != endIter; ++iter )
+    {
+      ecore_event_handler_del( *iter );
+    }
+    mEcoreEventHandlers.clear();
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Event callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void 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 );
+
+  Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Down, screenX, screenY ) );
+  unsigned long timeStamp = eventMouseDown->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, 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 );
+
+  Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Up, screenX, screenY ) );
+  unsigned long timeStamp = eventMouseUp->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, 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 );
+
+  Dali::Integration::Point point( TouchPoint( TOUCH_DEVICE_ID, TouchPoint::Motion, screenX, screenY ) );
+  unsigned long timeStamp = eventMouseMove->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, 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();
+  }
+
+  Dali::Integration::WheelEvent wheelEvent( Dali::Integration::WheelEvent::MOUSE_WHEEL, direction, modifiers, point, z, timeStamp );
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->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 );
+
+  Dali::Integration::Point point( TouchPoint( eventMultiDown->device, TouchPoint::Down, screenX, screenY ) );
+  unsigned long timeStamp = eventMultiDown->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, 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 );
+
+  Dali::Integration::Point point( TouchPoint( eventMultiUp->device, TouchPoint::Up, screenX, screenY ) );
+  unsigned long timeStamp = eventMultiUp->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, 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 );
+
+  Dali::Integration::Point point( TouchPoint( eventMultiMove->device, TouchPoint::Motion, screenX, screenY ) );
+  unsigned long timeStamp = eventMultiMove->timestamp;
+  if( timeStamp < 1 )
+  {
+    timeStamp = GetCurrentMilliSeconds();
+  }
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectTouchEvent( point, timeStamp );
+}
+
+void EvasEventHandler::OnEvasObjectKeyDown( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  Evas_Event_Key_Down* keyEvent = static_cast<Evas_Event_Key_Down*>( event );
+
+  // Create KeyEvent
+  Integration::KeyEvent integKeyEvent;
+
+  integKeyEvent.state = Integration::KeyEvent::Down;
+
+  FillIntegrationKeyEvent( keyEvent, integKeyEvent );
+
+  // Feed to EvasPlugin
+  ( static_cast<EvasEventInterface*>( data ) )->OnEvasObjectKeyEvent( integKeyEvent );
+}
+
+void EvasEventHandler::OnEvasObjectKeyUp( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  Evas_Event_Key_Up* keyEvent = static_cast<Evas_Event_Key_Up*>( event );
+
+  // Create KeyEvent
+  Integration::KeyEvent integKeyEvent;
+
+  integKeyEvent.state = Integration::KeyEvent::Up;
+
+  FillIntegrationKeyEvent( keyEvent, integKeyEvent );
+
+  // Feed to EvasPlugin
+  ( static_cast<EvasEventInterface*>( data ) )->OnEvasObjectKeyEvent( integKeyEvent );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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 );
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->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 );
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectResize( geometry );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Visibility callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectShow( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectVisiblityChanged( true );
+}
+
+void EvasEventHandler::OnEvasObjectHide( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  eventInterface->OnEvasObjectVisiblityChanged( false );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectFocusIn( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>( data );
+
+  eventHandler->GetEvasEventInterface().OnEvasObjectFocusIn();
+}
+
+void EvasEventHandler::OnEvasObjectFocusOut( void *data, Evas* evas, Evas_Object* evasObject, void* event )
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>( data );
+
+  eventHandler->GetEvasEventInterface().OnEvasObjectFocusOut();
+}
+
+void EvasEventHandler::OnEvasFocusIn( void *data, Evas* evas, void* event )
+{
+}
+
+void EvasEventHandler::OnEvasFocusOut( void *data, Evas* evas, void* event )
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Access callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionUnhighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlightNext( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlightPrev( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionActivate( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionScroll( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionUp( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionDown( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionBack( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionRead( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo )
+{
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+  Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+  ConvertActionInfo( actionInfo, daliActionInfo );
+
+  return eventInterface->OnElmAccessibilityActionEvent( daliActionInfo );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectSmartFocused( void *data, Evas_Object* evasObject, void* event )
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>( data );
+  EvasEventInterface& evasPlugin = eventHandler->GetEvasEventInterface();
+
+  if( eventHandler->mEvasEventInterface.GetEvasWrapper()->GetFocusTarget() == evasObject )
+  {
+    Evas_Object* topWidget = elm_object_top_widget_get( evasObject );
+
+    if( !strcmp( "elm_win", elm_object_widget_type_get( topWidget ) ) )
+    {
+      if( elm_win_focus_highlight_enabled_get( topWidget ) == EINA_TRUE )
+      {
+        // To allow that KeyboardFocusManager can handle the keyboard focus
+        Dali::Integration::KeyEvent fakeKeyEvent( Dali::KeyEvent( "", "", 0, 0, 100, KeyEvent::Down ) );
+
+        evasPlugin.OnEvasObjectKeyEvent( fakeKeyEvent );
+      }
+    }
+
+    evas_object_focus_set( eventHandler->mEvasEventInterface.GetEvasWrapper()->GetRenderTarget(), EINA_TRUE );
+  }
+}
+
+void EvasEventHandler::OnEvasObjectSmartUnfocused( void *data, Evas_Object* evasObject, void* event )
+{
+  EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>( data );
+  if( eventHandler->mEvasEventInterface.GetEvasWrapper()->GetFocusTarget() == evasObject )
+  {
+    evas_object_focus_set( eventHandler->mEvasEventInterface.GetEvasWrapper()->GetRenderTarget(), EINA_FALSE );
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Ecore Wl2 callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasEventHandler::OnEcoreWl2EventWindowVisibilityChange( void* data, int type, void* event )
+{
+  Ecore_Wl2_Event_Window_Visibility_Change* eventWindowVisibilityChange = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>( event );
+
+  EvasEventInterface* eventInterface = static_cast<EvasEventInterface*>( data );
+
+  // 0 is visible and 1 is invisible
+  eventInterface->OnEcoreWl2VisibilityChange( !eventWindowVisibilityChange->fully_obscured );
+
+  return ECORE_CALLBACK_PASS_ON;
+}
+
+}  // 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..f77c30b
--- /dev/null
@@ -0,0 +1,224 @@
+#ifndef DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER
+#define DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER
+
+/*
+ * Copyright ( c ) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+#include <Elementary.h>
+#include <Ecore_Wl2.h>
+#include <Ecore_Input.h>
+#include <Ecore_IMF.h>
+#include <Ecore_IMF_Evas.h>
+
+#include <string>
+#include <vector>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasEventInterface;
+
+class EvasEventHandler
+{
+public:
+  /**
+   * @brief Constructor
+   *
+   * @param[in] evasEventInterface Used to send event to evas plugin
+   */
+  EvasEventHandler( EvasEventInterface& evasEventInterface );
+
+  /**
+   * Destructor.
+   */
+  ~EvasEventHandler();
+
+public:
+
+  EvasEventInterface& GetEvasEventInterface()
+  {
+    return mEvasEventInterface;
+  }
+
+private:
+
+  void EnableEcoreWl2Events();
+
+  void DisableEcoreWl2Events();
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Event callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Called when the mouse down is received
+   */
+  static void OnEvasObjectMouseDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the mouse up is received
+   */
+  static void OnEvasObjectMouseUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the mouse move is received
+   */
+  static void OnEvasObjectMouseMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the mouse wheel is received
+   */
+  static void OnEvasObjectMouseWheel( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the multi-touch down is received
+   */
+  static void OnEvasObjectMultiTouchDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the multi-touch up is received
+   */
+  static void OnEvasObjectMultiTouchUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when the multi-touch move is received
+   */
+  static void OnEvasObjectMultiTouchMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when key down is received
+   */
+  static void OnEvasObjectKeyDown( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when key up is received
+   */
+  static void OnEvasObjectKeyUp( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Geometry callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Called when move is received
+   */
+  static void OnEvasObjectMove( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when resize is received
+   */
+  static void OnEvasObjectResize( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Visibility callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Called when show is received
+   */
+  static void OnEvasObjectShow( void *data, Evas* evas, Evas_Object* evasObject, void* event );
+
+  /**
+   * @brief Called when hide is received
+   */
+  static void OnEvasObjectHide( 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 );
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Elm Access callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static Eina_Bool OnElmAccessActionHighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionUnhighlight( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionHighlightNext( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionHighlightPrev( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionActivate( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionScroll( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionUp( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionDown( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionBack( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  static Eina_Bool OnElmAccessActionRead( void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info );
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Elm Focus callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static void OnEvasObjectSmartFocused( void* data, Evas_Object* evasObject, void* event );
+
+  static void OnEvasObjectSmartUnfocused( void* data, Evas_Object* evasObject, void* event );
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+  // Ecore Wl2 callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+  static Eina_Bool OnEcoreWl2EventWindowVisibilityChange( void* data, int type, void* event );
+
+private:
+
+  EvasEventInterface&               mEvasEventInterface;
+  std::vector<Ecore_Event_Handler*> mEcoreEventHandlers;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif
diff --git a/dali-extension/internal/evas-plugin/evas-event-interface.h b/dali-extension/internal/evas-plugin/evas-event-interface.h
new file mode 100644 (file)
index 0000000..d940186
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef DALI_EXTENSION_INTERNAL_EVAS_EVENT_INTERFACE_H
+#define DALI_EXTENSION_INTERNAL_EVAS_EVENT_INTERFACE_H
+
+/*
+ * Copyright ( c ) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/events/point.h>
+#include <dali/integration-api/events/wheel-event-integ.h>
+#include <dali/integration-api/events/key-event-integ.h>
+
+namespace Dali
+{
+
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasWrapper;
+
+enum AccessActionType
+{
+   ACCESS_ACTION_FIRST = -1,
+
+   ACCESS_ACTION_HIGHLIGHT,      /* highlight an object */
+
+   ACCESS_ACTION_UNHIGHLIGHT,    /* unhighlight an object */
+
+   ACCESS_ACTION_HIGHLIGHT_NEXT, /* set highlight to next object */
+
+   ACCESS_ACTION_HIGHLIGHT_PREV, /* set highlight to previous object */
+
+   ACCESS_ACTION_ACTIVATE,       /* activate a highlight object */
+
+   ACCESS_ACTION_SCROLL,         /* scroll if one of highlight object parents is scrollable */
+
+   ACCESS_ACTION_UP,             /* change value up of highlight object */
+
+   ACCESS_ACTION_DOWN,           /* change value down of highlight object */
+
+   ACCESS_ACTION_BACK,           /* go back to a previous view (ex: pop naviframe item) */
+
+   ACCESS_ACTION_READ,           /* highlight an object */
+
+   ACCESS_ACTION_LAST
+};
+
+struct AccessActionInfo
+{
+   int              x;
+   int              y;
+   unsigned int     mouseType; /* 0: mouse down
+                                  1: mouse move
+                                  2: mouse up   */
+   AccessActionType actionType;
+   AccessActionType actionBy;
+   bool             highlightCycle : 1;
+   unsigned int     timeStamp;
+};
+
+class EvasEventInterface
+{
+public:
+   /**
+   * @brief Gets an EvasWrapper instance to connect events
+   *
+   * @return The EvasWrapper instance
+   */
+  virtual EvasWrapper* GetEvasWrapper() const = 0;
+
+  /**
+   * @brief Handle evas object event
+   *
+   * @param[in] touchPoint is the information of touch
+   * @param[in] timeStamp is that touch is occured
+   */
+  virtual void OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp ) = 0;
+
+  /**
+   * @brief Handle evas object event
+   *
+   * @param[in] wheelEvent is the information of wheel
+   */
+  virtual void OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent ) = 0;
+
+  /**
+   * @brief Handle evas object event
+   *
+   * @param[in] keyEvent is the information of key
+   */
+  virtual void OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent ) = 0;
+
+  /**
+   * @brief Handle evas object geometry
+   *
+   * @param geometry is the move information of evas object
+   */
+  virtual void OnEvasObjectMove( const Rect<int>& geometry ) = 0;
+
+  /**
+   * @brief Handle evas object geometry
+   *
+   * @param geometry is the resize information of evas object
+   */
+  virtual void OnEvasObjectResize( const Rect<int>& geometry ) = 0;
+
+  /**
+   * @brief Handle evas object visibility
+   *
+   * @param visible is the visibility information of evas object
+   */
+  virtual void OnEvasObjectVisiblityChanged( bool visible ) = 0;
+
+  /**
+   * @brief Handle evas object focus in
+   */
+  virtual void OnEvasObjectFocusIn() = 0;
+
+  /**
+   * @brief Handle evas object focus out
+   */
+  virtual void OnEvasObjectFocusOut() = 0;
+
+   /**
+   * @brief Called when the accessibility action event dispatched from elm_access.
+   * @param[in] accessActionInfo elm accessibility action information structure
+   * @return True if the event was handled
+   */
+  virtual bool OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo ) = 0;
+
+  /**
+   * @brief Process the ecore wayland visibility.
+   *
+   * @param[in] visible True is that ecore wayland window is show up and false is not
+   */
+  virtual void OnEcoreWl2VisibilityChange( bool visible ) = 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..91ee2f5
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/adaptor-framework/native-render-surface.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/scene-impl.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+IntrusivePtr< EvasPlugin > EvasPlugin::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+{
+  IntrusivePtr< EvasPlugin > evasPlugin = new EvasPlugin( parentEvasObject, width, height, isTranslucent );
+  return evasPlugin;
+}
+
+EvasPlugin::EvasPlugin( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+: mState( READY )
+{
+  DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the EvasPlugin." );
+
+  // Generate a default scene
+  IntrusivePtr< Internal::Scene > scenePtr = Internal::Scene::New( parentEvasObject, width, height, isTranslucent );
+
+  mDefaultScene = Extension::Scene( scenePtr.Get() );
+
+  // Generate DALi adaptor
+  NativeRenderSurface* surface = static_cast<NativeRenderSurface*>( scenePtr->GetSurface() );
+
+  mAdaptor = &Adaptor::New( Dali::Integration::SceneHolder( scenePtr.Get() ), *surface, Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS );
+
+  // Initialize default scene
+  scenePtr->Initialize( this, true );
+
+  scenePtr->ResizedSignal().Connect( this, &EvasPlugin::OnDefaultSceneResized );
+
+  scenePtr->FocusChangedSignal().Connect( this, &EvasPlugin::OnDefaultSceneFocusChanged );
+}
+
+EvasPlugin::~EvasPlugin()
+{
+  delete mAdaptor;
+  mAdaptor = nullptr;
+}
+
+Adaptor* EvasPlugin::GetAdaptor()
+{
+  return mAdaptor;
+}
+
+void EvasPlugin::Run()
+{
+  if( READY == mState )
+  {
+    // Start the adaptor
+    mAdaptor->Start();
+
+    mState = RUNNING;
+
+    mPreInitSignal.Emit();
+
+    mInitSignal.Emit();
+
+    mAdaptor->NotifySceneCreated();
+  }
+}
+
+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()
+{
+  if( mState != STOPPED )
+  {
+    // Stop the adaptor
+    mAdaptor->Stop();
+    mState = STOPPED;
+
+    mTerminateSignal.Emit();
+  }
+}
+
+Extension::Scene EvasPlugin::GetDefaultScene()
+{
+  return mDefaultScene;
+}
+
+Evas_Object* EvasPlugin::GetAccessEvasObject()
+{
+  return mDefaultScene.GetAccessEvasObject();
+}
+
+Evas_Object* EvasPlugin::GetDaliEvasObject()
+{
+  return mDefaultScene.GetDaliEvasObject();
+}
+
+void EvasPlugin::OnDefaultSceneResized( Extension::Scene defaultScene, uint16_t width, uint16_t height )
+{
+  mResizeSignal.Emit();
+}
+
+void EvasPlugin::OnDefaultSceneFocusChanged( Extension::Scene defaultScene, bool focused )
+{
+  if( focused )
+  {
+    mFocusedSignal.Emit();
+  }
+  else
+  {
+    mUnFocusedSignal.Emit();
+  }
+}
+
+} // 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..7cc0f31
--- /dev/null
@@ -0,0 +1,262 @@
+#ifndef DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H
+#define DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <Ecore_IMF_Evas.h>
+
+#include <dali/integration-api/adaptor-framework/scene-holder-impl.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/signals/connection-tracker.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+#include <dali-extension/devel-api/evas-plugin/scene.h>
+
+namespace Dali
+{
+class Adaptor;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+/**
+ * Implementation of the EvasPlugin class.
+ */
+class EvasPlugin : public BaseObject,
+                   public ConnectionTracker
+{
+public:
+
+  typedef Dali::Extension::EvasPlugin::EvasPluginSignalType EvasPluginSignalType;
+
+  /**
+   * @brief Create a new evas plugin
+   * @param[in] parentEvasObject A pointer of the parent evas object
+   * @param[in] width The width of Dali view port
+   * @param[in] height The height of Dali view port
+   * @param[in] isTranslucent Whether the evas object is translucent or not
+   */
+  static IntrusivePtr<EvasPlugin> New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+public:
+
+  /**
+   * @copydoc Dali::Extension::EvasPlugin::Start()
+   */
+  void Run();
+
+  /**
+   * @copydoc Dali::Extension::EvasPlugin::Pause()
+   */
+  void Pause();
+
+  /**
+   * @copydoc Dali::Extension::EvasPlugin::Resume()
+   */
+  void Resume();
+
+  /**
+   * @copydoc Dali::Extension::EvasPlugin::Stop()
+   */
+  void Stop();
+
+  /**
+   * @copydoc Dali::Extension::EvasPlugin::GetDefaultScene()
+   */
+  Extension::Scene GetDefaultScene();
+
+  /**
+   * @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;
+  }
+
+public:
+  /**
+   * All methods here are for the internal use
+   */
+
+  enum State
+  {
+    READY,
+    RUNNING,
+    SUSPENDED,
+    STOPPED,
+  };
+
+  /**
+   * @brief This is for internal use to get notified before InitSignal() emits
+   */
+  EvasPluginSignalType& PreInitSignal()
+  {
+    return mPreInitSignal;
+  }
+
+  /**
+   * @brief Get EvasPlugin's current state
+   *
+   * @return The state
+   */
+  const State GetState() const
+  {
+    return mState;
+  }
+
+  /*
+   * @bried Get currently working Adaptor. It can be null.
+   */
+  Adaptor* GetAdaptor();
+
+private:
+  /**
+   * Private constructor
+   * @param[in] parentEvasObject A pointer of the parent evas object
+   * @param[in] width The width of Dali view port
+   * @param[in] height The height of Dali view port
+   * @param[in] isTranslucent Whether the evas object is translucent or not
+   */
+  EvasPlugin( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+  /**
+   * Destructor
+   */
+  virtual ~EvasPlugin();
+
+  // Undefined
+  EvasPlugin( const EvasPlugin& );
+  EvasPlugin& operator=( EvasPlugin& );
+
+  /**
+   * This callback is for supporting legacy API EvasPlugin::ResizeSignal
+   */
+  void OnDefaultSceneResized( Extension::Scene defaultScene, uint16_t width, uint16_t height );
+
+  /**
+   * This callback is for supporting legacy API EvasPlugin::FocusedSignal, EvasPlugin::UnFocusedSignal
+   */
+  void OnDefaultSceneFocusChanged( Extension::Scene defaultScene, bool focused );
+
+private:
+
+  Adaptor*                                  mAdaptor;
+  Extension::Scene                          mDefaultScene;
+
+  EvasPluginSignalType                      mPreInitSignal;
+  EvasPluginSignalType                      mInitSignal;
+  EvasPluginSignalType                      mTerminateSignal;
+  EvasPluginSignalType                      mPauseSignal;
+  EvasPluginSignalType                      mResumeSignal;
+  EvasPluginSignalType                      mResizeSignal;    // Connect to DefaultScene.ResizedSignal
+  EvasPluginSignalType                      mFocusedSignal;   // Connect to DefaultScene.FocusChangedSignal
+  EvasPluginSignalType                      mUnFocusedSignal; // Connect to DefaultScene.FocusChangedSignal
+
+  State                                     mState;
+};
+
+inline EvasPlugin& GetImplementation( Extension::EvasPlugin& evasPlugin )
+{
+  DALI_ASSERT_ALWAYS( evasPlugin && "EvasPlugin 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-wrapper.cpp b/dali-extension/internal/evas-plugin/evas-wrapper.cpp
new file mode 100644 (file)
index 0000000..7ab1d94
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/rect.h>
+#include <Elementary.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const char* IMAGE_EVAS_OBJECT_NAME = "dali-evas-plugin";
+const char* ELM_OBJECT_STYLE = "transparent";
+const char* ELM_OBJECT_CONTAINER_PART_NAME = "elm.swallow.content";
+
+} // unnamed namespace
+
+EvasWrapper::EvasWrapper( Evas_Object* pluginParent, uint16_t width, uint16_t height, bool transparent )
+: mEcoreEvas( nullptr ),
+  mImageEvasObject( nullptr ),
+  mAccessibilityEvasObject( nullptr ),
+  mFocusEvasObject( nullptr )
+{
+  int intWidth = static_cast<int>( width );
+  int intHeight = static_cast<int>( height );
+
+  Evas* evas = evas_object_evas_get( pluginParent );
+  mEcoreEvas = ecore_evas_ecore_evas_get( evas );
+
+  // Create the image evas object
+  mImageEvasObject = evas_object_image_filled_add( evas );
+  evas_object_name_set( mImageEvasObject, IMAGE_EVAS_OBJECT_NAME );
+  evas_object_image_alpha_set( mImageEvasObject, transparent ? EINA_TRUE : EINA_FALSE );
+  evas_object_image_size_set( mImageEvasObject, intWidth, intHeight );
+  evas_object_size_hint_weight_set( mImageEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND );
+  evas_object_size_hint_align_set( mImageEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL );
+
+  // Register the elm access to image evas object
+  mAccessibilityEvasObject = elm_access_object_register( mImageEvasObject, pluginParent );
+
+  // Create a button and set style as "focus", if does not want to show the focus, then "transparent"
+  mFocusEvasObject = elm_button_add( pluginParent );
+
+  // Don't need to show the focus boundary here
+  elm_object_style_set( mFocusEvasObject, ELM_OBJECT_STYLE );
+
+  // Set the image evas object to focus object, but event should not be propagated
+  elm_object_part_content_set( mFocusEvasObject, ELM_OBJECT_CONTAINER_PART_NAME, mImageEvasObject );
+  evas_object_propagate_events_set( mImageEvasObject, EINA_FALSE );
+
+  // Set the evas object you want to make focusable as the content of the swallow part
+  evas_object_size_hint_weight_set( mFocusEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND );
+  evas_object_size_hint_align_set( mFocusEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL );
+
+  evas_object_move( mFocusEvasObject, 0, 0 );
+  evas_object_resize( mFocusEvasObject, intWidth, intHeight );
+  evas_object_show( mFocusEvasObject );
+}
+
+EvasWrapper::~EvasWrapper()
+{
+  // Delete the elm focus evas object
+  evas_object_del( mFocusEvasObject );
+  mFocusEvasObject = NULL;
+
+  // Unregister elm_access_object
+  elm_access_object_unregister( mAccessibilityEvasObject );
+  mAccessibilityEvasObject = NULL;
+
+  // Delete the image evas object
+  evas_object_del( mImageEvasObject );
+  mImageEvasObject = NULL;
+}
+
+Ecore_Wl2_Window* EvasWrapper::GetNativeWindow() const
+{
+  return ecore_evas_wayland2_window_get( mEcoreEvas );
+}
+
+PositionSize EvasWrapper::GetGeometry() const
+{
+  PositionSize geometry;
+  evas_object_geometry_get( mImageEvasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height );
+  return geometry;
+}
+
+Evas_Object* EvasWrapper::GetRenderTarget() const
+{
+  return mImageEvasObject;
+}
+
+Evas_Object* EvasWrapper::GetAccessibilityTarget() const
+{
+  return mAccessibilityEvasObject;
+}
+
+Evas_Object* EvasWrapper::GetFocusTarget() const
+{
+  return mFocusEvasObject;
+}
+
+void EvasWrapper::SetFocus()
+{
+  evas_object_focus_set( mImageEvasObject, EINA_TRUE );
+}
+
+void EvasWrapper::BindTBMSurface( tbm_surface_h surface )
+{
+  Evas_Native_Surface nativeSurface;
+  nativeSurface.type = EVAS_NATIVE_SURFACE_TBM;
+  nativeSurface.version = EVAS_NATIVE_SURFACE_VERSION;
+  nativeSurface.data.tbm.buffer = surface;
+  nativeSurface.data.tbm.rot = 0;
+  nativeSurface.data.tbm.ratio = 0;
+  nativeSurface.data.tbm.flip = 0;
+
+  evas_object_image_native_surface_set( mImageEvasObject, &nativeSurface );
+}
+
+void EvasWrapper::RequestRender()
+{
+  evas_object_image_pixels_dirty_set( mImageEvasObject, EINA_TRUE );
+  ecore_evas_manual_render( mEcoreEvas );
+}
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
\ No newline at end of file
diff --git a/dali-extension/internal/evas-plugin/evas-wrapper.h b/dali-extension/internal/evas-plugin/evas-wrapper.h
new file mode 100644 (file)
index 0000000..a853772
--- /dev/null
@@ -0,0 +1,125 @@
+#ifndef DALI_EXTENSION_INTERNAL_EVAS_WRAPPER
+#define DALI_EXTENSION_INTERNAL_EVAS_WRAPPER
+
+/*
+ * Copyright ( c ) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" );
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Wl2.h>
+#include <tbm_surface.h>
+
+#include <dali/public-api/math/rect.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+
+typedef Rect<int> PositionSize;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+/**
+ * EvasWrapper is a class which holds a parent evas object for the EvasPlugin.
+ * This creates essential evas ebjects (RenderTarget, AccessibiltyTarget, FocusTarget) to connect evas to Dali properly,
+ * and also provides evas rendering interfaces.
+ */
+class EvasWrapper
+{
+
+public:
+
+  /**
+   * @brief Constructor
+   * @param[in] pluginParent An parent evas object of a evas plugin
+   * @param[in] width The initial width of the Dali view port
+   * @param[in] height The initial height of the Dali view port
+   * @param[in] transparent Whether the Evas object is transparent or not
+   */
+  EvasWrapper( Evas_Object* pluginParent, uint16_t width, uint16_t height, bool transparent );
+
+  /**
+   * @brief Destructor
+   */
+  ~EvasWrapper();
+
+  /**
+   * @brief Gets current native window object
+   * @return The ecore window object
+   */
+  Ecore_Wl2_Window* GetNativeWindow() const;
+
+  /**
+   * @brief Gets the geometry information
+   * @return The geometry information
+   */
+  PositionSize GetGeometry() const;
+
+  /**
+   * @brief Gets the rendering target evas object
+   * @return The rendering target object
+   */
+  Evas_Object* GetRenderTarget() const;
+
+  /**
+   * @brief Gets the accessibility target evas object
+   * @return The accessibility target object
+   */
+  Evas_Object* GetAccessibilityTarget() const;
+
+  /**
+   * @brief Gets the focus target evas object
+   * @return The focus target object
+   */
+  Evas_Object* GetFocusTarget() const;
+
+  /**
+   * @brief Sets focus
+   */
+  void SetFocus();
+
+  /**
+   * @brief Bind a tbm surface
+   */
+  void BindTBMSurface( tbm_surface_h surface );
+
+  /**
+   * @brief Request rendering
+   */
+  void RequestRender();
+
+private:
+
+  Ecore_Evas*  mEcoreEvas;
+  Evas_Object* mImageEvasObject;
+  Evas_Object* mAccessibilityEvasObject;
+  Evas_Object* mFocusEvasObject;
+};
+
+}  // namespace Internal
+
+}  // namespace Extension
+
+}  // namespace Dali
+
+#endif // DALI_EXTENSION_INTERNAL_EVAS_WRAPPER
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..1330896
--- /dev/null
@@ -0,0 +1,12 @@
+evas_plugin_internal_header_files = \
+   $(extension_src_dir)/internal/evas-plugin/evas-event-handler.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-event-interface.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.h \
+   $(extension_src_dir)/internal/evas-plugin/evas-wrapper.h \
+   $(extension_src_dir)/internal/evas-plugin/scene-impl.h
+
+evas_plugin_internal_src_files = \
+   $(extension_src_dir)/internal/evas-plugin/evas-event-handler.cpp \
+   $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.cpp \
+   $(extension_src_dir)/internal/evas-plugin/evas-wrapper.cpp \
+   $(extension_src_dir)/internal/evas-plugin/scene-impl.cpp
diff --git a/dali-extension/internal/evas-plugin/scene-impl.cpp b/dali-extension/internal/evas-plugin/scene-impl.cpp
new file mode 100644 (file)
index 0000000..9c6f340
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard.h>
+#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/adaptor-framework/native-render-surface.h>
+#include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
+#include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
+#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-event-handler.h>
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+#include <dali-extension/internal/evas-plugin/evas-wrapper.h>
+
+// CLASS HEADER
+#include <dali-extension/internal/evas-plugin/scene-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+IntrusivePtr< Scene > Scene::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+{
+  IntrusivePtr< Scene > scene = new Scene( parentEvasObject, width, height, isTranslucent );
+  return scene;
+}
+
+Scene::Scene( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
+: mAdaptor( nullptr ),
+  mEvasWrapper( new EvasWrapper( parentEvasObject, width, height, isTranslucent ) ),
+  mEvasEventHandler(),
+  mRenderNotification(),
+  mIsFocus( false ),
+  mIsTranslucent( isTranslucent )
+{
+  DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the scene" );
+
+  // Create surface
+  mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( PositionSize( 0, 0, static_cast<int>( width ), static_cast<int>( height ) ), isTranslucent ) );
+}
+
+void Scene::Initialize( EvasPlugin* evasPlugin, bool isDefaultScene )
+{
+  mAdaptor = evasPlugin->GetAdaptor();
+
+  DALI_ASSERT_ALWAYS( mAdaptor && "Scene can not be created when the Adaptor is null" );
+
+  if( isDefaultScene )
+  {
+    Initialize();
+    return;
+  }
+
+  if( evasPlugin->GetState() != EvasPlugin::RUNNING )
+  {
+    evasPlugin->PreInitSignal().Connect( this, &Scene::OnPreInitEvasPlugin );
+
+    return;
+  }
+
+  Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
+  mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
+
+  Initialize();
+}
+
+void Scene::Initialize()
+{
+  // Connect callback to be notified when the surface is rendered
+  TriggerEventFactory triggerEventFactory;
+
+  mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Scene::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
+
+  NativeRenderSurface* surface = GetNativeRenderSurface();
+
+  if( !surface )
+  {
+    return;
+  }
+
+  surface->SetRenderNotification( mRenderNotification.get() );
+
+  if( !mEvasEventHandler )
+  {
+    mEvasEventHandler = std::unique_ptr< EvasEventHandler >( new EvasEventHandler( *this ) );
+  }
+}
+
+void Scene::OnPreInitEvasPlugin()
+{
+  Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
+  mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
+
+  Initialize();
+}
+
+Scene::~Scene()
+{
+  NativeRenderSurface* surface = GetNativeRenderSurface();
+
+  if( surface )
+  {
+    // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
+    surface->SetRenderNotification( nullptr );
+  }
+}
+
+uint32_t Scene::GetLayerCount() const
+{
+  return mScene.GetLayerCount();
+}
+
+Layer Scene::GetLayer( uint32_t depth ) const
+{
+  return mScene.GetLayer( depth );
+}
+
+Scene::SceneSize Scene::GetSize() const
+{
+  Size size = mScene.GetSize();
+
+  return Scene::SceneSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
+}
+
+Dali::Any Scene::GetNativeHandle() const
+{
+  return mEvasWrapper->GetNativeWindow();
+}
+
+NativeRenderSurface* Scene::GetNativeRenderSurface() const
+{
+  return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
+}
+
+Evas_Object* Scene::GetAccessEvasObject()
+{
+  return mEvasWrapper->GetAccessibilityTarget();
+}
+
+Evas_Object* Scene::GetDaliEvasObject()
+{
+  return mEvasWrapper->GetFocusTarget();
+}
+
+void Scene::ResizeSurface( uint16_t width, uint16_t height )
+{
+  if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
+  {
+    return;
+  }
+
+  int intWidth = static_cast<int>( width );
+  int intHeight = static_cast<int>( height );
+
+  PositionSize currentSize = mSurface->GetPositionSize();
+  if( currentSize.width == intWidth && currentSize.height == intHeight )
+  {
+    return;
+  }
+
+  mSurface->MoveResize( PositionSize( 0, 0, intWidth, intHeight ) );
+
+  SurfaceResized();
+
+  Adaptor::SurfaceSize newSize( width, height );
+
+  // When surface size is updated, inform adaptor of resizing and emit ResizedSignal
+  mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
+
+  mResizedSignal.Emit( Extension::Scene( this ), width, height );
+
+  mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
+}
+
+void Scene::OnPostRender()
+{
+  // Bind offscreen surface to the evas object
+  NativeRenderSurface* surface = GetNativeRenderSurface();
+
+  if( !surface )
+  {
+    return;
+  }
+
+  tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
+
+  if( !tbmSurface )
+  {
+    return;
+  }
+
+  mEvasWrapper->BindTBMSurface( tbmSurface );
+
+  mEvasWrapper->RequestRender();
+
+  surface->ReleaseLock();
+}
+
+EvasWrapper* Scene::GetEvasWrapper() const
+{
+  return mEvasWrapper.get();
+}
+
+void Scene::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
+{
+  FeedTouchPoint( touchPoint, timeStamp );
+}
+
+void Scene::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
+{
+  FeedWheelEvent( wheelEvent );
+}
+
+void Scene::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
+{
+  FeedKeyEvent( keyEvent );
+}
+
+void Scene::OnEvasObjectMove( const Rect<int>& geometry )
+{
+}
+
+void Scene::OnEvasObjectResize( const Rect<int>& geometry )
+{
+  ResizeSurface( static_cast<uint16_t>( geometry.width ), static_cast<uint16_t>( geometry.height ) );
+}
+
+void Scene::OnEvasObjectVisiblityChanged( bool visible )
+{
+  if( mVisible == visible )
+  {
+    return;
+  }
+  DALI_LOG_RELEASE_INFO( "Scene::OnEvasObjectVisiblityChanged( %s )", visible ? "T" : "F" );
+
+  SetVisibility( visible );
+}
+
+void Scene::OnEvasObjectFocusIn()
+{
+  if( !mIsFocus )
+  {
+    mFocusChangedSignal.Emit( Extension::Scene( this ), true );
+
+    mIsFocus = true;
+  }
+}
+
+void Scene::OnEvasObjectFocusOut()
+{
+  if( mIsFocus )
+  {
+    mIsFocus = false;
+
+    Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
+    Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
+    if( currentFocused )
+    {
+      focusManager.RemoveFocus( currentFocused );
+    }
+
+    Clipboard::Get().HideClipboard();
+
+    mFocusChangedSignal.Emit( Extension::Scene( this ), false );
+  }
+}
+
+bool Scene::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
+{
+  bool ret = false;
+
+  if( mAdaptor == nullptr )
+  {
+    return ret;
+  }
+
+  Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
+  if( accessibilityAdaptor )
+  {
+    switch( accessActionInfo.actionBy )
+    {
+      case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
+      case Dali::Extension::Internal::ACCESS_ACTION_READ:
+      {
+        ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
+      {
+        // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
+        ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
+        if(!ret)
+        {
+          // when focus moving was failed, clear the focus
+          accessibilityAdaptor.HandleActionClearFocusEvent();
+        }
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
+      {
+        // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
+        ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
+        if(!ret)
+        {
+          // when focus moving was failed, clear the focus
+          accessibilityAdaptor.HandleActionClearFocusEvent();
+        }
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
+      {
+        ret = accessibilityAdaptor.HandleActionActivateEvent();
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
+      {
+        ret = accessibilityAdaptor.HandleActionClearFocusEvent();
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
+      {
+        Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
+
+        if( eo )
+        {
+          int touchType = accessActionInfo.mouseType;
+
+          TouchPoint::State state( TouchPoint::Down );
+
+          if( touchType == 0 )
+          {
+            state = TouchPoint::Down; // mouse down
+          }
+          else if( touchType == 1 )
+          {
+            state = TouchPoint::Motion; // mouse move
+          }
+          else if( touchType == 2 )
+          {
+            state = TouchPoint::Up; // mouse up
+          }
+          else
+          {
+            state = TouchPoint::Interrupted; // error
+          }
+
+          // Send touch event to accessibility manager.
+          Evas_Coord rel_x, rel_y, obj_x,  obj_y, obj_w, obj_h;
+
+          evas_object_geometry_get( eo, &obj_x,  &obj_y, &obj_w, &obj_h );
+
+          rel_x = accessActionInfo.x - obj_x;
+          rel_y = accessActionInfo.y - obj_y;
+
+          TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
+
+          ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
+        }
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_UP:
+      {
+        ret = accessibilityAdaptor.HandleActionUpEvent();
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
+      {
+        ret = accessibilityAdaptor.HandleActionDownEvent();
+      }
+      break;
+
+      case Dali::Extension::Internal::ACCESS_ACTION_BACK:
+      default:
+      {
+        DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
+      }
+
+      break;
+    }
+  }
+  else
+  {
+    DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
+  }
+
+  return ret;
+}
+
+void Scene::OnEcoreWl2VisibilityChange( bool visible )
+{
+  DALI_LOG_RELEASE_INFO( "Scene::OnEcoreWl2VisibilityChange( %s )", visible ? "T" : "F" );
+
+  SetVisibility( visible );
+}
+
+void Scene::SetVisibility( bool visible )
+{
+  if( mVisible == visible )
+  {
+    return;
+  }
+
+  mVisible = visible;
+
+  if( !mAdaptor )
+  {
+    return;
+  }
+
+  if( mVisible )
+  {
+    mAdaptor->OnWindowShown();
+  }
+  else
+  {
+    mAdaptor->OnWindowHidden();
+
+    mSurface->ReleaseLock();
+  }
+
+  mVisibilityChangedSignal.Emit( Extension::Scene( this ), mVisible );
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
diff --git a/dali-extension/internal/evas-plugin/scene-impl.h b/dali-extension/internal/evas-plugin/scene-impl.h
new file mode 100644 (file)
index 0000000..c31b70e
--- /dev/null
@@ -0,0 +1,294 @@
+#ifndef DALI_EXTENSION_INTERNAL_SCENE_IMPL_H
+#define DALI_EXTENSION_INTERNAL_SCENE_IMPL_H
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+#include <Ecore_IMF_Evas.h>
+
+#include <dali/integration-api/adaptor-framework/scene-holder-impl.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/signals/connection-tracker.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-event-interface.h>
+#include <dali-extension/devel-api/evas-plugin/scene.h>
+
+namespace Dali
+{
+class Adaptor;
+class Layer;
+class NativeRenderSurface;
+class TriggerEventInterface;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasEventHandler;
+class EvasWrapper;
+
+/**
+ * Implementation of the Scene class.
+ */
+class Scene : public Dali::Internal::Adaptor::SceneHolder,
+              public ConnectionTracker,
+              public Extension::Internal::EvasEventInterface
+{
+public:
+  typedef Dali::Extension::Scene::SceneSize SceneSize;
+
+  typedef Dali::Extension::Scene::VisibilityChangedSignalType VisibilityChangedSignalType;
+
+  typedef Dali::Extension::Scene::FocusChangedSignalType FocusChangedSignalType;
+
+  typedef Dali::Extension::Scene::ResizedSignalType ResizedSignalType;
+
+  /**
+   * @brief Create a new scene
+   *
+   * @param[in] parentEvasObject Parent Evas object of the new scene
+   * @param[in] width The initial width of the scene
+   * @param[in] height The initial height of the scene
+   * @param[in] isTranslucent Whether the Evas object is translucent or not
+   */
+  static IntrusivePtr<Scene> New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+public:
+
+  /**
+   * @copydoc Dali::Extension::Scene::GetLayerCount
+   */
+  uint32_t GetLayerCount() const;
+
+  /**
+   * @copydoc Dali::Extension::Scene::GetLayer
+   */
+  Layer GetLayer( uint32_t depth ) const;
+
+  /**
+   * @copydoc Dali::Extension::Scene::GetSize
+   */
+  SceneSize GetSize() const;
+
+  /**
+   * @brief Gets the native handle.
+   * @note When users call this function, it wraps the actual type used by the underlying system.
+   * @return The native handle or an empty handle
+   */
+  Dali::Any GetNativeHandle() const override;
+
+  /**
+   * @copydoc Dali::Extension::Scene::GetAccessEvasObject
+   */
+  Evas_Object* GetAccessEvasObject();
+
+  /**
+   * @copydoc Dali::Extension::Scene::GetDaliEvasObject
+   */
+  Evas_Object* GetDaliEvasObject();
+
+  /**
+   * @copydoc Dali::Extension::Scene::VisibilityChangedSignal
+   */
+  VisibilityChangedSignalType& VisibilityChangedSignal()
+  {
+    return mVisibilityChangedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Extension::Scene::ResizedSignal
+   */
+  ResizedSignalType& ResizedSignal()
+  {
+    return mResizedSignal;
+  }
+
+  /**
+   * @copydoc Dali::Extension::Scene::FocusChangedSignal
+   */
+  FocusChangedSignalType& FocusChangedSignal()
+  {
+    return mFocusChangedSignal;
+  }
+
+  /*
+   * @brief Initialize the Scene
+   * @param[in] evasPlugin The EvasPlugin instance to be used to intialize the new scene
+   * @param[in] isDefaultScene Whether the Scene is a default one or not
+   */
+  void Initialize( EvasPlugin* evasPlugin, bool isDefaultScene );
+
+private:
+
+  /**
+   * @brief Resize the surface
+   * @param[in] width The width value
+   * @param[in] height The height value
+   */
+  void ResizeSurface( uint16_t width, uint16_t height );
+
+  /**
+   * This function is called after drawing by dali.
+   */
+  void OnPostRender();
+
+  /**
+   * @brief Set visibility of the Scene
+   * @param[in] visible The visibility
+   */
+  void SetVisibility( bool visible );
+
+  /**
+   * @brief Get the native render surface
+   * @return The render surface
+   */
+  NativeRenderSurface* GetNativeRenderSurface() const;
+
+private:
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::GetEvasWrapper
+   */
+  EvasWrapper* GetEvasWrapper() const override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectTouchEvent
+   */
+  void OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectWheelEvent
+   */
+  void OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectKeyEvent
+   */
+  void OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectMove
+   */
+  void OnEvasObjectMove( const Rect<int>& geometry ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectResize
+   */
+  void OnEvasObjectResize( const Rect<int>& geometry ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectVisiblityChanged
+   */
+  void OnEvasObjectVisiblityChanged( bool visible ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectFocusIn
+   */
+  void OnEvasObjectFocusIn() override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEvasObjectFocusOut
+   */
+  void OnEvasObjectFocusOut() override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnElmAccessibilityActionEvent
+   */
+  bool OnElmAccessibilityActionEvent( AccessActionInfo& actionInfo ) override;
+
+  /**
+   * @copydoc Dali::Extension::Internal::EvasEventInterface::OnEcoreWl2VisibilityChange
+   */
+  void OnEcoreWl2VisibilityChange( bool visible ) override;
+
+private:
+
+  /**
+   * Private constructor
+   *
+   * @param[in] parentEvasObject Parent Evas object of the new scene
+   * @param[in] width The initial width of the scene
+   * @param[in] height The initial height of the scene
+   * @param[in] isTranslucent Whether the Evas object is translucent or not
+   */
+  Scene( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent );
+
+  /**
+   * Destructor
+   */
+  virtual ~Scene();
+
+  // Undefined
+  Scene( const Scene& );
+  Scene& operator=( Scene& );
+
+  /**
+   * This is for initialization of this Scene in case it is created before adaptor is running.
+   */
+  void OnPreInitEvasPlugin();
+
+  /*
+   * @brief Initialize the Scene (for internal use)
+   */
+  void Initialize();
+
+private:
+
+  Adaptor*                                  mAdaptor;
+
+  std::unique_ptr< EvasWrapper >            mEvasWrapper;
+  std::unique_ptr< EvasEventHandler >       mEvasEventHandler;
+  std::unique_ptr< TriggerEventInterface >  mRenderNotification;
+
+  ResizedSignalType                         mResizedSignal;
+  VisibilityChangedSignalType               mVisibilityChangedSignal;
+  FocusChangedSignalType                    mFocusChangedSignal;
+
+  bool                                      mIsFocus;
+  bool                                      mIsTranslucent;
+};
+
+inline Scene& GetImplementation( Extension::Scene& scene )
+{
+  DALI_ASSERT_ALWAYS( scene && "Extension::Scene handle is empty" );
+
+  BaseObject& handle = scene.GetBaseObject();
+
+  return static_cast<Scene&>( handle );
+}
+
+inline const Scene& GetImplementation( const Extension::Scene& scene )
+{
+  DALI_ASSERT_ALWAYS( scene && "Extension::Scene handle is empty" );
+
+  const BaseObject& handle = scene.GetBaseObject();
+
+  return static_cast<const Scene&>( handle );
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // DALI_EXTENSION_INTERNAL_SCENE_IMPL_H
diff --git a/dali-extension/key/file.list b/dali-extension/key/file.list
new file mode 100644 (file)
index 0000000..1122fa8
--- /dev/null
@@ -0,0 +1,2 @@
+key_extension_src_files = \
+   $(extension_src_dir)/key/key-extension.cpp
diff --git a/dali-extension/key/key-extension.cpp b/dali-extension/key/key-extension.cpp
new file mode 100644 (file)
index 0000000..fbf64a2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 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 <integration-api/key-extension.h>
+
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::KeyExtensionPlugin* CreateKeyExtensionPlugin( void )
+{
+  return new Dali::Plugin::KeyExtension;
+}
+
+extern "C" DALI_EXPORT_API void DestroyKeyExtensionPlugin( Dali::KeyExtensionPlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+
+KeyExtensionPlugin::KeyLookup mKeyLookupTable[]=
+{
+  // more than one key name can be assigned to a single key code
+};
+
+bool IsExtensionKey( const Dali::KeyEvent& keyEvent, Dali::EXTENSION_KEY daliKey)
+{
+  int key = -200000;
+
+  for( size_t i = 0 ; i < sizeof(mKeyLookupTable) / sizeof(KeyExtensionPlugin::KeyLookup) ; i++ )
+  {
+    if( !keyEvent.keyPressedName.compare( mKeyLookupTable[i].keyName ) )
+    {
+      key = mKeyLookupTable[i].daliKeyCode;
+      break;
+    }
+  }
+
+  return daliKey == key;
+}
+
+namespace Plugin
+{
+
+KeyExtension::KeyExtension()
+{
+}
+
+KeyExtension::~KeyExtension()
+{
+}
+
+Dali::KeyExtensionPlugin::KeyLookup* KeyExtension::GetKeyLookupTable()
+{
+  return mKeyLookupTable;
+}
+
+std::size_t KeyExtension::GetKeyLookupTableCount()
+{
+  return sizeof(mKeyLookupTable) / sizeof(KeyExtensionPlugin::KeyLookup);
+}
+
+}
+}
diff --git a/dali-extension/vector-animation-renderer/file.list b/dali-extension/vector-animation-renderer/file.list
new file mode 100644 (file)
index 0000000..ac36d00
--- /dev/null
@@ -0,0 +1,4 @@
+vector_animation_renderer_plugin_src_files = \
+   $(extension_src_dir)/vector-animation-renderer/tizen-vector-animation-renderer.cpp \
+   $(extension_src_dir)/vector-animation-renderer/tizen-vector-animation-manager.cpp
+
diff --git a/dali-extension/vector-animation-renderer/tizen-vector-animation-event-handler.h b/dali-extension/vector-animation-renderer/tizen-vector-animation-event-handler.h
new file mode 100755 (executable)
index 0000000..869d2fd
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_TIZEN_VECTOR_ANIMATION_EVENT_HANDLER_H
+#define DALI_TIZEN_VECTOR_ANIMATION_EVENT_HANDLER_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
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Tizen vector animation event handler
+ */
+class TizenVectorAnimationEventHandler
+{
+public:
+
+  /**
+   * @brief Notify events
+   */
+  virtual void NotifyEvent() = 0;
+
+protected:
+
+  /**
+   * constructor
+   */
+  TizenVectorAnimationEventHandler()
+  {
+  }
+
+  /**
+   * virtual destructor
+   */
+  virtual ~TizenVectorAnimationEventHandler()
+  {
+  }
+
+  // Undefined copy constructor.
+  TizenVectorAnimationEventHandler( const TizenVectorAnimationEventHandler& ) = delete;
+
+  // Undefined assignment operator.
+  TizenVectorAnimationEventHandler& operator=( const TizenVectorAnimationEventHandler& ) = delete;
+};
+
+} // namespace Plugin
+
+} // namespace Dali;
+
+#endif // DALI_TIZEN_VECTOR_ANIMATION_EVENT_HANDLER_H
diff --git a/dali-extension/vector-animation-renderer/tizen-vector-animation-manager.cpp b/dali-extension/vector-animation-renderer/tizen-vector-animation-manager.cpp
new file mode 100755 (executable)
index 0000000..37371ae
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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 <dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+TizenVectorAnimationManager& TizenVectorAnimationManager::Get()
+{
+  static TizenVectorAnimationManager animationManager;
+  return animationManager;
+}
+
+TizenVectorAnimationManager::TizenVectorAnimationManager()
+: mEventHandlers(),
+  mTriggeredHandlers(),
+  mMutex(),
+  mEventTrigger()
+{
+}
+
+TizenVectorAnimationManager::~TizenVectorAnimationManager()
+{
+  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationManager::~TizenVectorAnimationManager: this = %p\n", this );
+}
+
+void TizenVectorAnimationManager::AddEventHandler( TizenVectorAnimationEventHandler& handler )
+{
+  if( mEventHandlers.end() == std::find( mEventHandlers.begin(), mEventHandlers.end(), &handler ) )
+  {
+    if( mEventHandlers.empty() )
+    {
+      Adaptor::Get().RegisterProcessor( *this );
+    }
+
+    if( !mEventTrigger )
+    {
+      mEventTrigger = std::unique_ptr< EventThreadCallback >( new EventThreadCallback( MakeCallback( this, &TizenVectorAnimationManager::OnEventTriggered ) ) );
+    }
+
+    mEventHandlers.push_back( &handler );
+  }
+}
+
+void TizenVectorAnimationManager::RemoveEventHandler( TizenVectorAnimationEventHandler& handler )
+{
+  auto iter = std::find( mEventHandlers.begin(), mEventHandlers.end(), &handler );
+  if( iter != mEventHandlers.end() )
+  {
+    mEventHandlers.erase( iter );
+
+    if( mEventHandlers.empty() )
+    {
+      if( Adaptor::IsAvailable() )
+      {
+        Adaptor::Get().UnregisterProcessor( *this );
+      }
+
+      mEventTrigger.release();
+    }
+  }
+
+  {
+    Dali::Mutex::ScopedLock lock( mMutex );
+
+    auto triggeredHandler = std::find( mTriggeredHandlers.begin(), mTriggeredHandlers.end(), &handler );
+    if( triggeredHandler != mTriggeredHandlers.end() )
+    {
+      mTriggeredHandlers.erase( triggeredHandler );
+    }
+  }
+}
+
+void TizenVectorAnimationManager::TriggerEvent( TizenVectorAnimationEventHandler& handler )
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( mTriggeredHandlers.end() == std::find( mTriggeredHandlers.begin(), mTriggeredHandlers.end(), &handler ) )
+  {
+    mTriggeredHandlers.push_back( &handler );
+
+    mEventTrigger->Trigger();
+  }
+}
+
+void TizenVectorAnimationManager::Process()
+{
+  OnEventTriggered();
+}
+
+// This function is called in the main thread.
+void TizenVectorAnimationManager::OnEventTriggered()
+{
+  std::vector< TizenVectorAnimationEventHandler* > handlers;
+
+  {
+    Dali::Mutex::ScopedLock lock( mMutex );
+
+    // Copy the list to the local variable and clear
+    handlers = mTriggeredHandlers;
+    mTriggeredHandlers.clear();
+  }
+
+  for( auto&& iter : handlers )
+  {
+    iter->NotifyEvent();
+  }
+}
+
+} // namespace Plugin
+
+} // namespace Dali;
diff --git a/dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h b/dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h
new file mode 100755 (executable)
index 0000000..aa6d63f
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef DALI_TIZEN_VECTOR_ANIMATION_MANAGER_H
+#define DALI_TIZEN_VECTOR_ANIMATION_MANAGER_H
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
+#include <dali/integration-api/processor-interface.h>
+#include <memory>
+
+// INTERNAL INCLUDES
+#include <dali-extension/vector-animation-renderer/tizen-vector-animation-event-handler.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Tizen vector animation manager
+ */
+class TizenVectorAnimationManager : public Integration::Processor
+{
+public:
+
+  /**
+   * @brief Create or retrieve TizenVectorAnimationManager singleton.
+   *
+   * @return A reference to the TizenVectorAnimationManager.
+   */
+  static TizenVectorAnimationManager& Get();
+
+  /**
+   * @brief Add the event handler.
+   *
+   * @param handler The event handler to add.
+   */
+  void AddEventHandler( TizenVectorAnimationEventHandler& handler );
+
+  /**
+   * @brief Remove the event handler.
+   *
+   * @param handler The event handler to remove.
+   */
+  void RemoveEventHandler( TizenVectorAnimationEventHandler& handler );
+
+  /**
+   * @brief Trigger the event.
+   */
+  void TriggerEvent( TizenVectorAnimationEventHandler& handler );
+
+protected: // Implementation of Processor
+
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process() override;
+
+private:
+
+  /**
+   * @brief Event callback to process events.
+   */
+  void OnEventTriggered();
+
+private:
+
+  /**
+   * @brief Constructor.
+   */
+  TizenVectorAnimationManager();
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~TizenVectorAnimationManager();
+
+  // Undefined
+  TizenVectorAnimationManager( const TizenVectorAnimationManager& ) = delete;
+
+  // Undefined
+  TizenVectorAnimationManager& operator=( const TizenVectorAnimationManager& ) = delete;
+
+private:
+
+  std::vector< TizenVectorAnimationEventHandler* > mEventHandlers;
+  std::vector< TizenVectorAnimationEventHandler* > mTriggeredHandlers;
+  Dali::Mutex                                      mMutex;
+  std::unique_ptr< EventThreadCallback >           mEventTrigger;
+};
+
+} // namespace Plugin
+
+} // namespace Dali;
+
+#endif // DALI_TIZEN_VECTOR_ANIMATION_MANAGER_H
diff --git a/dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.cpp b/dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.cpp
new file mode 100755 (executable)
index 0000000..ae5dfb4
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ * 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 <dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/property-array.h>
+#include <dali/integration-api/debug.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/devel-api/images/native-image-interface-extension.h>
+#include <cstring> // for strlen()
+#include <tbm_surface_internal.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h>
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::VectorAnimationRendererPlugin* CreateVectorAnimationRendererPlugin( void )
+{
+  return new Dali::Plugin::TizenVectorAnimationRenderer;
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+namespace
+{
+
+const char* const DEFAULT_SAMPLER_TYPENAME( "sampler2D" );
+const char* const PIXEL_AREA_UNIFORM_NAME( "pixelArea" );
+
+const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
+
+} // unnamed namespace
+
+TizenVectorAnimationRenderer::TizenVectorAnimationRenderer()
+: mUrl(),
+  mBuffers(),
+  mMutex(),
+  mRenderer(),
+  mTexture(),
+  mRenderedTexture(),
+  mTargetSurface(),
+  mVectorRenderer(),
+  mUploadCompletedSignal(),
+  mTbmQueue( NULL ),
+  mTotalFrameNumber( 0 ),
+  mWidth( 0 ),
+  mHeight( 0 ),
+  mDefaultWidth( 0 ),
+  mDefaultHeight( 0 ),
+  mFrameRate( 60.0f ),
+  mResourceReady( false ),
+  mShaderChanged( false ),
+  mResourceReadyTriggered( false )
+{
+}
+
+TizenVectorAnimationRenderer::~TizenVectorAnimationRenderer()
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  ResetBuffers();
+}
+
+bool TizenVectorAnimationRenderer::Initialize( const std::string& url )
+{
+  mUrl = url;
+
+  mVectorRenderer = rlottie::Animation::loadFromFile( mUrl );
+  if( !mVectorRenderer )
+  {
+    DALI_LOG_ERROR( "Failed to load a Lottie file [%s]\n", mUrl.c_str() );
+    return false;
+  }
+
+  mTotalFrameNumber = mVectorRenderer->totalFrame();
+  mFrameRate = static_cast< float >( mVectorRenderer->frameRate() );
+
+  size_t w, h;
+  mVectorRenderer->size( w, h );
+  mDefaultWidth = static_cast< uint32_t >( w );
+  mDefaultHeight = static_cast< uint32_t >( h );
+
+  TizenVectorAnimationManager::Get().AddEventHandler( *this );
+
+  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Initialize: file [%s] [%p]\n", url.c_str(), this );
+
+  return true;
+}
+
+void TizenVectorAnimationRenderer::Finalize()
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  TizenVectorAnimationManager::Get().RemoveEventHandler( *this );
+
+  mRenderer.Reset();
+  mTexture.Reset();
+  mRenderedTexture.Reset();
+  mVectorRenderer.reset();
+
+  mTargetSurface = nullptr;
+  mTbmQueue = NULL;
+}
+
+void TizenVectorAnimationRenderer::SetRenderer( Renderer renderer )
+{
+  mRenderer = renderer;
+  mShaderChanged = false;
+
+  if( mTargetSurface )
+  {
+    Dali::Mutex::ScopedLock lock( mMutex );
+
+    if( mResourceReady && mRenderedTexture )
+    {
+      TextureSet textureSet = renderer.GetTextures();
+
+      textureSet.SetTexture( 0, mRenderedTexture );
+
+      mUploadCompletedSignal.Emit();
+    }
+
+    SetShader();
+  }
+
+  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetRenderer [%p]\n", this );
+}
+
+void TizenVectorAnimationRenderer::SetSize( uint32_t width, uint32_t height )
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( mWidth == width && mHeight == height )
+  {
+    DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetSize: Same size (%d, %d) [%p]\n", mWidth, mHeight, this );
+    return;
+  }
+
+  mTargetSurface = NativeImageSourceQueue::New( width, height, NativeImageSourceQueue::COLOR_DEPTH_DEFAULT );
+
+  mTexture = Texture::New( *mTargetSurface );
+
+  if( mRenderer )
+  {
+    SetShader();
+  }
+
+  mTbmQueue = AnyCast< tbm_surface_queue_h >( mTargetSurface->GetNativeImageSourceQueue() );
+
+  mWidth = width;
+  mHeight = height;
+
+  mResourceReady = false;
+
+  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetSize: width = %d, height = %d [%p]\n", mWidth, mHeight, this );
+}
+
+bool TizenVectorAnimationRenderer::Render( uint32_t frameNumber )
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( !mTbmQueue || !mVectorRenderer )
+  {
+    return false;
+  }
+
+  if( tbm_surface_queue_can_dequeue( mTbmQueue, 0 ) )
+  {
+    tbm_surface_h tbmSurface;
+
+    if( tbm_surface_queue_dequeue( mTbmQueue, &tbmSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Failed to dequeue a tbm_surface [%p]\n", this );
+      return false;
+    }
+
+    tbm_surface_info_s info;
+    tbm_surface_map( tbmSurface, TBM_OPTION_WRITE, &info );
+
+    rlottie::Surface surface;
+    bool existing = false;
+
+    if( !mResourceReady )
+    {
+      // Need to reset buffer list
+      ResetBuffers();
+    }
+    else
+    {
+      for( auto&& iter : mBuffers )
+      {
+        if( iter.first == tbmSurface )
+        {
+          // Find the buffer in the existing list
+          existing = true;
+          surface = iter.second;
+          break;
+        }
+      }
+    }
+
+    if( !existing )
+    {
+      tbm_surface_internal_ref( tbmSurface );
+
+      unsigned char* buffer = info.planes[0].ptr;
+
+      // Create Surface object
+      surface = rlottie::Surface( reinterpret_cast< uint32_t* >( buffer ), mWidth, mHeight, static_cast< size_t >( info.planes[0].stride ) );
+
+      // Push the buffer
+      mBuffers.push_back( SurfacePair( tbmSurface, surface ) );
+    }
+
+    // Render the frame
+    mVectorRenderer->renderSync( frameNumber, surface );
+
+    tbm_surface_unmap( tbmSurface );
+
+    tbm_surface_queue_enqueue( mTbmQueue, tbmSurface );
+
+    if( !mResourceReady )
+    {
+      mRenderedTexture = mTexture;
+      mResourceReady = true;
+      mResourceReadyTriggered = true;
+
+      TizenVectorAnimationManager::Get().TriggerEvent( *this );
+
+      DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Render: Resource ready [current = %d] [%p]\n", frameNumber, this );
+    }
+
+    return true;
+  }
+
+  return false;
+}
+
+uint32_t TizenVectorAnimationRenderer::GetTotalFrameNumber() const
+{
+  return mTotalFrameNumber;
+}
+
+float TizenVectorAnimationRenderer::GetFrameRate() const
+{
+  return mFrameRate;
+}
+
+void TizenVectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
+{
+  width = mDefaultWidth;
+  height = mDefaultHeight;
+
+  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::GetDefaultSize: width = %d, height = %d [%p]\n", width, height, this );
+}
+
+void TizenVectorAnimationRenderer::GetLayerInfo( Property::Map& map ) const
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( mVectorRenderer )
+  {
+    auto layerInfo = mVectorRenderer->layers();
+
+    for( auto&& iter : layerInfo )
+    {
+      Property::Array frames;
+      frames.PushBack( std::get< 1 >( iter ) );
+      frames.PushBack( std::get< 2 >( iter ) );
+      map.Add( std::get< 0 >( iter ), frames );
+    }
+  }
+}
+
+bool TizenVectorAnimationRenderer::GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( mVectorRenderer )
+  {
+    auto markerList = mVectorRenderer->markers();
+    for( auto&& iter : markerList )
+    {
+      if( std::get< 0 >( iter ).compare( marker ) == 0 )
+      {
+        startFrame = static_cast< uint32_t >( std::get< 1 >( iter ) );
+        endFrame = static_cast< uint32_t >( std::get< 2 >( iter ) );
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+VectorAnimationRendererPlugin::UploadCompletedSignalType& TizenVectorAnimationRenderer::UploadCompletedSignal()
+{
+  return mUploadCompletedSignal;
+}
+
+void TizenVectorAnimationRenderer::NotifyEvent()
+{
+  Dali::Mutex::ScopedLock lock( mMutex );
+
+  if( mResourceReadyTriggered )
+  {
+    DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::NotifyEvent: Set Texture [%p]\n", this );
+
+    // Set texture
+    if( mRenderer && mRenderedTexture )
+    {
+      TextureSet textureSet = mRenderer.GetTextures();
+      textureSet.SetTexture( 0, mRenderedTexture );
+    }
+
+    mResourceReadyTriggered = false;
+
+    mUploadCompletedSignal.Emit();
+  }
+}
+
+void TizenVectorAnimationRenderer::SetShader()
+{
+  if( mShaderChanged )
+  {
+    return;
+  }
+
+  NativeImageInterface::Extension* extension = static_cast< NativeImageInterface* >( mTargetSurface.Get() )->GetExtension();
+  if( extension )
+  {
+    Shader shader = mRenderer.GetShader();
+
+    std::string fragmentShader;
+    std::string vertexShader;
+
+    // Get custom fragment shader prefix
+    const char* fragmentPreFix = extension->GetCustomFragmentPreFix();
+    if( fragmentPreFix )
+    {
+      fragmentShader = fragmentPreFix;
+      fragmentShader += "\n";
+    }
+
+    // Get the current fragment shader source
+    Property::Value program = shader.GetProperty( Shader::Property::PROGRAM );
+    Property::Map* map = program.GetMap();
+    if( map )
+    {
+      Property::Value* fragment = map->Find( "fragment" );
+      if( fragment )
+      {
+        fragmentShader += fragment->Get< std::string >();
+      }
+
+      Property::Value* vertex = map->Find( "vertex" );
+      if( vertex )
+      {
+        vertexShader = vertex->Get< std::string >();
+      }
+    }
+
+    // Get custom sampler type name
+    const char* customSamplerTypename = extension->GetCustomSamplerTypename();
+    if( customSamplerTypename )
+    {
+      size_t position = fragmentShader.find( DEFAULT_SAMPLER_TYPENAME );
+      if( position != std::string::npos )
+      {
+        fragmentShader.replace( position, strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
+      }
+    }
+
+    // Set the modified shader again
+    Shader newShader = Shader::New( vertexShader, fragmentShader );
+    newShader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+
+    mRenderer.SetShader( newShader );
+
+    mShaderChanged = true;
+  }
+}
+
+void TizenVectorAnimationRenderer::ResetBuffers()
+{
+  for( auto&& iter : mBuffers )
+  {
+    tbm_surface_internal_unref( iter.first );
+  }
+  mBuffers.clear();
+}
+
+} // namespace Plugin
+
+} // namespace Dali;
diff --git a/dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.h b/dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.h
new file mode 100755 (executable)
index 0000000..e3283a2
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef DALI_TIZEN_VECTOR_ANIMATION_RENDERER_PLUGIN_H
+#define DALI_TIZEN_VECTOR_ANIMATION_RENDERER_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 <dali/public-api/common/vector-wrapper.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
+#include <dali/devel-api/adaptor-framework/vector-animation-renderer-plugin.h>
+#include <memory>
+#include <rlottie.h>
+#include <tbm_surface.h>
+#include <tbm_surface_queue.h>
+
+// INTERNAL INCLUDES
+#include <dali-extension/vector-animation-renderer/tizen-vector-animation-event-handler.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the Tizen vector animation renderer class which has Tizen platform dependency.
+ */
+class TizenVectorAnimationRenderer : public Dali::VectorAnimationRendererPlugin, public TizenVectorAnimationEventHandler
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  TizenVectorAnimationRenderer();
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~TizenVectorAnimationRenderer();
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::Initialize()
+   */
+  bool Initialize( const std::string& url ) override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::Finalize()
+   */
+  void Finalize() override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::SetRenderer()
+   */
+  void SetRenderer( Renderer renderer ) override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::SetSize()
+   */
+  void SetSize( uint32_t width, uint32_t height ) override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::Render()
+   */
+  bool Render( uint32_t frameNumber ) override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::GetTotalFrameNumber()
+   */
+  uint32_t GetTotalFrameNumber() const override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::GetFrameRate()
+   */
+  float GetFrameRate() const override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::GetDefaultSize()
+   */
+  void GetDefaultSize( uint32_t& width, uint32_t& height ) const override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::GetLayerInfo()
+   */
+  void GetLayerInfo( Property::Map& map ) const override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::GetMarkerInfo()
+   */
+  bool GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const override;
+
+  /**
+   * @copydoc Dali::VectorAnimationRendererPlugin::UploadCompletedSignal()
+   */
+  UploadCompletedSignalType& UploadCompletedSignal() override;
+
+protected: // Implementation of TizenVectorAnimationEventHandler
+
+  /**
+   * @copydoc Dali::Plugin::TizenVectorAnimationEventHandler::NotifyEvent()
+   */
+  void NotifyEvent() override;
+
+private:
+
+  /**
+   * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
+   */
+  void SetShader();
+
+  /**
+   * @brief Reset buffer list.
+   */
+  void ResetBuffers();
+
+private:
+
+  using SurfacePair = std::pair< tbm_surface_h, rlottie::Surface >;
+
+  std::string                            mUrl;                   ///< The content file path
+  std::vector< SurfacePair >             mBuffers;               ///< EGL Image vector
+  mutable Dali::Mutex                    mMutex;                 ///< Mutex
+  Dali::Renderer                         mRenderer;              ///< Renderer
+  Dali::Texture                          mTexture;               ///< Texture
+  Dali::Texture                          mRenderedTexture;       ///< Rendered Texture
+  NativeImageSourceQueuePtr              mTargetSurface;         ///< The target surface
+  std::unique_ptr< rlottie::Animation >  mVectorRenderer;        ///< The vector animation renderer
+  UploadCompletedSignalType              mUploadCompletedSignal; ///< Upload completed signal
+  tbm_surface_queue_h                    mTbmQueue;              ///< Tbm surface queue handle
+  uint32_t                               mTotalFrameNumber;      ///< The total frame number
+  uint32_t                               mWidth;                 ///< The width of the surface
+  uint32_t                               mHeight;                ///< The height of the surface
+  uint32_t                               mDefaultWidth;          ///< The width of the surface
+  uint32_t                               mDefaultHeight;         ///< The height of the surface
+  float                                  mFrameRate;             ///< The frame rate of the content
+  bool                                   mResourceReady;         ///< Whether the resource is ready
+  bool                                   mShaderChanged;         ///< Whether the shader is changed to support native image
+  bool                                   mResourceReadyTriggered;///< Whether the resource ready is triggered
+};
+
+} // namespace Plugin
+
+} // namespace Dali;
+
+#endif // DALI_TIZEN_VECTOR_ANIMATION_RENDERER_PLUGIN_H
diff --git a/dali-extension/video-player/ecore-wl/tizen-video-player-ecore-wl.cpp b/dali-extension/video-player/ecore-wl/tizen-video-player-ecore-wl.cpp
new file mode 100755 (executable)
index 0000000..7e65731
--- /dev/null
@@ -0,0 +1,914 @@
+/*
+ * Copyright (c) 2016 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 <tizen-video-player.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/integration-api/debug.h>
+#include <system_info.h>
+
+// INTERNAL INCLUDES
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
+{
+  return new Dali::Plugin::TizenVideoPlayer;
+}
+
+extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+namespace
+{
+
+const int TIMER_INTERVAL( 20 );
+
+static void MediaPacketVideoDecodedCb( media_packet_h packet, void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  player->PushPacket( packet );
+}
+
+static void EmitPlaybackFinishedSignal( void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  if( !player->mFinishedSignal.Empty() )
+  {
+    DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
+    player->mFinishedSignal.Emit();
+  }
+
+  player->Stop();
+}
+
+// ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
+// We should check whether this callback is needed in platform.
+static void PlayerSeekCompletedCb( void* data )
+{
+}
+
+void LogPlayerError( int error )
+{
+  if( error != PLAYER_ERROR_NONE )
+  {
+    switch( error )
+    {
+      case PLAYER_ERROR_OUT_OF_MEMORY:
+      {
+        DALI_LOG_ERROR( "Player error: Out of memory\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_PARAMETER:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
+        return;
+      }
+      case PLAYER_ERROR_NO_SUCH_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: No such file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_OPERATION:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid operation\n" );
+        return;
+      }
+      case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: No space on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_SEEK_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Seek failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_STATE:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid state\n" );
+        return;
+      }
+      case PLAYER_ERROR_NOT_SUPPORTED_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_URI:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid uri\n" );
+        return;
+      }
+      case PLAYER_ERROR_SOUND_POLICY:
+      {
+        DALI_LOG_ERROR( "Player error: Sound policy\n" );
+        return;
+      }
+      case PLAYER_ERROR_CONNECTION_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Connection failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Video capture failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_EXPIRED:
+      {
+        DALI_LOG_ERROR( "Player error: DRM expired\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NO_LICENSE:
+      {
+        DALI_LOG_ERROR( "Player error: No license\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_FUTURE_USE:
+      {
+        DALI_LOG_ERROR( "Player error: License for future use\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NOT_PERMITTED:
+      {
+        DALI_LOG_ERROR( "Player error: Format not permitted\n" );
+        return;
+      }
+      case PLAYER_ERROR_RESOURCE_LIMIT:
+      {
+        DALI_LOG_ERROR( "Player error: Resource limit\n" );
+        return;
+      }
+      case PLAYER_ERROR_PERMISSION_DENIED:
+      {
+        DALI_LOG_ERROR( "Player error: Permission denied\n" );
+        return;
+      }
+      case PLAYER_ERROR_SERVICE_DISCONNECTED:
+      {
+        DALI_LOG_ERROR( "Player error: Service disconnected\n" );
+        return;
+      }
+      case PLAYER_ERROR_BUFFER_SPACE:
+      {
+        DALI_LOG_ERROR( "Player error: Buffer space\n" );
+        return;
+      }
+      case PLAYER_ERROR_NOT_SUPPORTED_VIDEO_CODEC:
+      {
+        DALI_LOG_ERROR( "Player error: The target should not support the codec type\n" );
+        return;
+      }
+      default :
+      {
+        DALI_LOG_ERROR( "Player error: Unknown error code ( %d ) \n", error );
+        return;
+      }
+    }
+  }
+}
+
+} // unnamed namespace
+
+TizenVideoPlayer::TizenVideoPlayer()
+: mUrl(),
+  mPlayer( NULL ),
+  mPlayerState( PLAYER_STATE_NONE ),
+  mTbmSurface( NULL ),
+  mPacket( NULL ),
+  mNativeImageSourcePtr( NULL ),
+  mTimer(),
+  mBackgroundColor( Dali::Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ),
+  mTargetType( NativeImage ),
+  mPacketMutex(),
+  mPacketVector(),
+  mEcoreWlWindow( NULL ),
+  mAlphaBitChanged( false ),
+  mStreamInfo( NULL ),
+  mStreamType( SOUND_STREAM_TYPE_MEDIA ),
+  mCodecType( PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT )
+{
+}
+
+TizenVideoPlayer::~TizenVideoPlayer()
+{
+  DestroyPlayer();
+}
+
+void TizenVideoPlayer::GetPlayerState( player_state_e* state ) const
+{
+  if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
+    *state = PLAYER_STATE_NONE;
+  }
+}
+
+void TizenVideoPlayer::SetUrl( const std::string& url )
+{
+  if( mUrl != url )
+  {
+    int error = PLAYER_ERROR_NONE;
+
+    mUrl = url;
+
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
+    {
+
+      if( mNativeImageSourcePtr )
+      {
+        error = player_unset_media_packet_video_frame_decoded_cb( mPlayer );
+        LogPlayerError( error );
+      }
+
+      Stop();
+
+      error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+
+      if( mNativeImageSourcePtr )
+      {
+        error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
+        LogPlayerError( error );
+      }
+      else
+      {
+        int width, height;
+        ecore_wl_screen_size_get( &width, &height );
+        error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+        LogPlayerError( error );
+      }
+
+      GetPlayerState( &mPlayerState );
+      LogPlayerError( error );
+    }
+
+    if( mPlayerState == PLAYER_STATE_IDLE )
+    {
+      error = player_set_uri( mPlayer, mUrl.c_str() );
+      LogPlayerError( error );
+
+      error = player_prepare( mPlayer );
+      LogPlayerError( error );
+    }
+  }
+}
+
+std::string TizenVideoPlayer::GetUrl()
+{
+  return mUrl;
+}
+
+void TizenVideoPlayer::SetRenderingTarget( Any target )
+{
+  DestroyPlayer();
+
+  mNativeImageSourcePtr = NULL;
+  mEcoreWlWindow = NULL;
+
+  if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
+  {
+    mTargetType = TizenVideoPlayer::NativeImage;
+
+    Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
+
+    InitializeTextureStreamMode( nativeImageSourcePtr );
+  }
+  else if( target.GetType() == typeid( Ecore_Wl_Window* ) )
+  {
+    mTargetType = TizenVideoPlayer::WindowSurface;
+
+    Ecore_Wl_Window* nativeWindow = Dali::AnyCast< Ecore_Wl_Window* >( target );
+    InitializeUnderlayMode( nativeWindow );
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Video rendering target is unknown\n" );
+  }
+}
+
+void TizenVideoPlayer::SetLooping( bool looping )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_set_looping( mPlayer, looping );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsLooping()
+{
+  GetPlayerState( &mPlayerState );
+
+  bool looping = false;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_is_looping( mPlayer, &looping );
+    LogPlayerError( error );
+  }
+
+  return looping;
+}
+
+void TizenVideoPlayer::Play()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Start();
+    }
+
+    int error = player_start( mPlayer );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Pause()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING )
+  {
+    int error = player_pause( mPlayer );
+    LogPlayerError( error );
+
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Stop();
+      DestroyPackets();
+    }
+  }
+}
+
+void TizenVideoPlayer::Stop()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    int error = player_stop( mPlayer );
+    LogPlayerError( error );
+  }
+
+  if( mNativeImageSourcePtr != NULL && mTimer )
+  {
+    mTimer.Stop();
+    DestroyPackets();
+  }
+}
+
+void TizenVideoPlayer::SetMute( bool muted )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_set_mute( mPlayer, muted );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsMuted()
+{
+  GetPlayerState( &mPlayerState );
+  bool muted = false;
+
+   if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_is_muted( mPlayer, &muted );
+    LogPlayerError( error );
+  }
+
+  return muted;
+}
+
+void TizenVideoPlayer::SetVolume( float left, float right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_set_volume( mPlayer, left, right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::GetVolume( float& left, float& right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_get_volume( mPlayer, &left, &right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::SetPlayPosition( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_prepare( mPlayer );
+    LogPlayerError( error );
+
+    GetPlayerState( &mPlayerState ); // Check the status again.
+  }
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+int TizenVideoPlayer::GetPlayPosition()
+{
+  int error;
+  int millisecond = 0;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_get_play_position( mPlayer, &millisecond );
+    LogPlayerError( error );
+  }
+
+  return millisecond;
+}
+
+void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
+    return;
+  }
+
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
+    LogPlayerError( error );
+  }
+}
+
+Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
+    return Dali::VideoPlayerPlugin::ROTATION_NONE;
+  }
+
+  int error;
+  player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_get_display_rotation( mPlayer, &rotation );
+    LogPlayerError( error );
+  }
+  return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
+}
+
+Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
+{
+  return mFinishedSignal;
+}
+
+void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
+{
+  int error;
+
+  mNativeImageSourcePtr = nativeImageSourcePtr;
+
+  if( mAlphaBitChanged )
+  {
+    ecore_wl_window_alpha_set( mEcoreWlWindow, false );
+    mAlphaBitChanged = false;
+  }
+
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
+    LogPlayerError( error );
+
+    error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_sound_stream_info( mPlayer, mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
+    LogPlayerError( error );
+
+    error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
+    LogPlayerError( error );
+
+    error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+    LogPlayerError( error );
+
+    error = player_set_display_visible( mPlayer, true );
+    LogPlayerError( error );
+
+    mTimer = Dali::Timer::New( TIMER_INTERVAL );
+    mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
+  }
+}
+
+void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow )
+{
+  int error;
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+  mEcoreWlWindow = ecoreWlWindow;
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_sound_stream_info( mPlayer, mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
+    LogPlayerError( error );
+
+    error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
+    LogPlayerError( error );
+
+    error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+    LogPlayerError( error );
+
+    int width, height;
+    ecore_wl_screen_size_get( &width, &height );
+    ecore_wl_window_alpha_set( mEcoreWlWindow, false );
+
+    error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+    LogPlayerError( error );
+
+    error = player_set_display_visible( mPlayer, true );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::Update()
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+
+  int error;
+
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    if( error != MEDIA_PACKET_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    }
+    mPacket = NULL;
+  }
+
+  if( !mPacketVector.Empty() )
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[0] );
+    mPacketVector.Remove( mPacketVector.Begin() );
+  }
+
+  if( mPacket == NULL )
+  {
+    return true;
+  }
+
+  error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
+  if( error != MEDIA_PACKET_ERROR_NONE )
+  {
+    media_packet_destroy( mPacket );
+    mPacket = NULL;
+    DALI_LOG_ERROR( " error: %d\n", error );
+    return true;
+  }
+
+  Any source( mTbmSurface );
+  mNativeImageSourcePtr->SetSource( source );
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+
+  return true;
+}
+
+void TizenVideoPlayer::DestroyPackets()
+{
+  int error;
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+
+  for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[i] );
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+  mPacketVector.Clear();
+}
+
+void TizenVideoPlayer::PushPacket( media_packet_h packet )
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+  mPacketVector.PushBack( packet );
+}
+
+void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
+    return;
+  }
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+
+  )
+  {
+    area.x = ( area.x < 0 ) ? 0: area.x;
+    area.y = ( area.y < 0 ) ? 0: area.y;
+    int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Forward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition + millisecond;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Backward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition - millisecond;
+    nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsVideoTextureSupported()
+{
+  bool featureFlag = true;
+  int error = SYSTEM_INFO_ERROR_NONE;
+
+  error = system_info_get_platform_bool( "tizen.org/feature/multimedia.raw_video", &featureFlag );
+
+  if( error != SYSTEM_INFO_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "Plugin can't check platform feature\n" );
+    return false;
+  }
+
+  return featureFlag;
+}
+
+void TizenVideoPlayer::DestroyPlayer()
+{
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_IDLE )
+    {
+      Stop();
+      error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+    }
+
+    error = player_destroy( mPlayer );
+    LogPlayerError( error );
+
+    error = sound_manager_destroy_stream_information(mStreamInfo);
+    LogPlayerError( error );
+
+    mPlayerState = PLAYER_STATE_NONE;
+    mPlayer = NULL;
+    mUrl = "";
+  }
+}
+
+void TizenVideoPlayer::SetCodecType( Dali::VideoPlayerPlugin::CodecType type )
+{
+  int error;
+  switch( type )
+  {
+    case Dali::VideoPlayerPlugin::CodecType::DEFAULT :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT;
+      break;
+    }
+    case Dali::VideoPlayerPlugin::CodecType::HW :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_HW;
+      break;
+    }
+    case Dali::VideoPlayerPlugin::CodecType::SW :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_SW;
+      break;
+    }
+  }
+
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState == PLAYER_STATE_IDLE )
+    {
+      error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+      LogPlayerError( error );
+    }
+  }
+}
+
+Dali::VideoPlayerPlugin::CodecType TizenVideoPlayer::GetCodecType() const
+{
+  Dali::VideoPlayerPlugin::CodecType type = Dali::VideoPlayerPlugin::CodecType::DEFAULT;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    player_video_codec_type_ex_e codecType = PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT;
+    int error = player_get_video_codec_type_ex( mPlayer, &codecType );
+    if( error != PLAYER_ERROR_NONE )
+    {
+      LogPlayerError( error );
+      return type;
+    }
+
+    switch( codecType )
+    {
+      case PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::DEFAULT;
+        break;
+      }
+      case PLAYER_VIDEO_CODEC_TYPE_EX_HW :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::HW;
+        break;
+      }
+      case PLAYER_VIDEO_CODEC_TYPE_EX_SW :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::SW;
+        break;
+      }
+    }
+  }
+  return type;
+}
+
+void TizenVideoPlayer::SetDisplayMode( Dali::VideoPlayerPlugin::DisplayMode::Type mode )
+{
+  int error;
+  error = player_set_display_mode( mPlayer, static_cast< player_display_mode_e >( mode ) );
+  LogPlayerError( error );
+}
+
+Dali::VideoPlayerPlugin::DisplayMode::Type TizenVideoPlayer::GetDisplayMode() const
+{
+  player_display_mode_e mode;
+  player_get_display_mode( mPlayer, &mode );
+  return static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode );
+}
+
+Any TizenVideoPlayer::GetMediaPlayer()
+{
+   return Any( ( void* ) mPlayer );
+}
+
+
+} // namespace Plugin
+} // namespace Dali;
diff --git a/dali-extension/video-player/ecore-wl/tizen-video-player.h b/dali-extension/video-player/ecore-wl/tizen-video-player.h
new file mode 100755 (executable)
index 0000000..e50c464
--- /dev/null
@@ -0,0 +1,269 @@
+#ifndef __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+#define __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
+#include <dali/devel-api/adaptor-framework/video-player-plugin.h>
+#include <player.h>
+#include <string>
+
+#ifndef HAVE_WAYLAND
+#define HAVE_WAYLAND
+#endif
+#include <player_internal.h>
+#include <Ecore_Wayland.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the Tizen video player class which has Tizen platform dependency.
+ * @SINCE_1_1.38
+ */
+class TizenVideoPlayer : public Dali::VideoPlayerPlugin, public Dali::ConnectionTracker
+{
+public:
+
+  /**
+   * @brief Video rendering target type
+   * @SINCE_1_1.38
+   */
+  enum RenderingTargetType
+  {
+    WindowSurface, ///< HW underlay
+    NativeImage ///< texture stream
+  };
+
+  /**
+   * @brief Constructor.
+   * @SINCE_1_1.38
+   */
+  TizenVideoPlayer();
+
+  /**
+   * @brief Destructor.
+   * @SINCE_1_1.38
+   */
+  virtual ~TizenVideoPlayer();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetUrl()
+   */
+  virtual void SetUrl( const std::string& url );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetUrl()
+   */
+  virtual std::string GetUrl();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetLooping()
+   */
+  virtual void SetLooping(bool looping);
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsLooping()
+   */
+  virtual bool IsLooping();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Play()
+   */
+  virtual void Play();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Pause()
+   */
+  virtual void Pause();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Stop()
+   */
+  virtual void Stop();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetMute()
+   */
+  virtual void SetMute( bool mute );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsMute()
+   */
+  virtual bool IsMuted();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetVolume()
+   */
+  virtual void SetVolume( float left, float right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetVolume()
+   */
+  virtual void GetVolume( float& left, float& right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetRenderingTarget()
+   */
+  void SetRenderingTarget( Any target );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetPlayPosition()
+   */
+  virtual void SetPlayPosition( int millisecond );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetPlayPosition()
+   */
+  virtual int GetPlayPosition();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayArea()
+   */
+  virtual void SetDisplayArea( DisplayArea area );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayRotation()
+   */
+  virtual void SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetDisplayRotation()
+   */
+  virtual Dali::VideoPlayerPlugin::DisplayRotation GetDisplayRotation();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::FinishedSignal()
+   */
+  virtual Dali::VideoPlayerPlugin::VideoPlayerSignalType& FinishedSignal();
+
+  /**
+   * @brief Push media packet with video frame image
+   */
+  void PushPacket( media_packet_h packet );
+
+  /**
+   * @brief Dali::VideoPlayer::Forward()
+   */
+  void Forward( int millisecond );
+
+  /**
+   * @brief Dali::VideoPlayer::Backward()
+   */
+  void Backward( int millisecond );
+
+  /**
+   * @brief Dali::VideoPlayer::IsVideoTextureSupported()
+   */
+  bool IsVideoTextureSupported();
+
+  /**
+   * @brief Dali::VideoPlayer::SetCodecType()
+   */
+  void SetCodecType( Dali::VideoPlayerPlugin::CodecType type );
+
+  /**
+   * @brief Dali::VideoPlayer::GetCodecType()
+   */
+  Dali::VideoPlayerPlugin::CodecType GetCodecType() const;
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayMode()
+   */
+  void SetDisplayMode(  Dali::VideoPlayerPlugin::DisplayMode::Type mode );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetDisplayMode()
+   */
+  Dali::VideoPlayerPlugin::DisplayMode::Type GetDisplayMode() const;
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetMediaPlayer()
+   */
+  Any GetMediaPlayer();
+
+private:
+
+  /**
+   * @brief Updates video frame image by timer if rendering targe is native image source
+   */
+  bool Update();
+
+  /**
+   * @brief Gets current player state
+   */
+  void GetPlayerState( player_state_e* state ) const;
+
+  /**
+   * @brief Destroy all packests, which this plugin stores
+   */
+  void DestroyPackets();
+
+  /**
+   * @brief Initializes player for video rendering using native image source
+   */
+  void InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr );
+
+  /**
+   * @brief Initializes player for video rendering using wayland window surface
+   */
+  void InitializeUnderlayMode( Ecore_Wl_Window* ecoreWlWindow );
+
+  /**
+   * @brief Destroys player handle
+   */
+  void DestroyPlayer();
+
+private:
+
+  std::string mUrl; ///< The video file path
+  player_h mPlayer; ///< Tizen player handle
+  player_state_e mPlayerState; ///< Tizen player state
+  tbm_surface_h mTbmSurface; ///< tbm surface handle
+  media_packet_h mPacket; ///< Media packet handle with tbm surface of current video frame image
+  Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< native image source for video rendering
+  Dali::Timer mTimer; ///< Timer for texture streaming rendering
+  Dali::Vector4 mBackgroundColor; ///< Current background color, which texturestream mode needs.
+  RenderingTargetType mTargetType; ///< Current rendering target type
+
+  Dali::Mutex mPacketMutex;
+  Dali::Vector< media_packet_h > mPacketVector; ///< Container for media packet handle from Tizen player callback
+
+  Ecore_Wl_Window* mEcoreWlWindow;
+
+  bool mAlphaBitChanged; ///< True if underlay rendering initialization changes window alpha
+
+  sound_stream_info_h mStreamInfo;
+  sound_stream_type_e mStreamType;
+
+  player_video_codec_type_ex_e mCodecType;
+public:
+
+  Dali::VideoPlayerPlugin::VideoPlayerSignalType mFinishedSignal;
+};
+
+} // namespace Plugin
+} // namespace Dali;
+
+#endif
diff --git a/dali-extension/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp b/dali-extension/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp
new file mode 100755 (executable)
index 0000000..ffcba37
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ * Copyright (c) 2016 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 <tizen-video-player.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/integration-api/debug.h>
+#include <system_info.h>
+
+// INTERNAL INCLUDES
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::VideoPlayerPlugin* CreateVideoPlayerPlugin( void )
+{
+  return new Dali::Plugin::TizenVideoPlayer;
+}
+
+extern "C" DALI_EXPORT_API void DestroyVideoPlayerPlugin( Dali::VideoPlayerPlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+namespace
+{
+
+const int TIMER_INTERVAL( 20 );
+
+static void MediaPacketVideoDecodedCb( media_packet_h packet, void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  player->PushPacket( packet );
+}
+
+static void EmitPlaybackFinishedSignal( void* user_data )
+{
+  TizenVideoPlayer* player = static_cast< TizenVideoPlayer* >( user_data );
+
+  if( player == NULL )
+  {
+    DALI_LOG_ERROR( "Decoded callback got Null pointer as user_data.\n" );
+    return;
+  }
+
+  if( !player->mFinishedSignal.Empty() )
+  {
+    DALI_LOG_ERROR( "EmitPlaybackFinishedSignal.3\n" );
+    player->mFinishedSignal.Emit();
+  }
+
+  player->Stop();
+}
+
+// ToDo: VD player_set_play_position() doesn't work when callback pointer is NULL.
+// We should check whether this callback is needed in platform.
+static void PlayerSeekCompletedCb( void* data )
+{
+}
+
+void LogPlayerError( int error )
+{
+  if( error != PLAYER_ERROR_NONE )
+  {
+    switch( error )
+    {
+      case PLAYER_ERROR_OUT_OF_MEMORY:
+      {
+        DALI_LOG_ERROR( "Player error: Out of memory\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_PARAMETER:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid parameter\n" );
+        return;
+      }
+      case PLAYER_ERROR_NO_SUCH_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: No such file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_OPERATION:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid operation\n" );
+        return;
+      }
+      case PLAYER_ERROR_FILE_NO_SPACE_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: No space on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_FEATURE_NOT_SUPPORTED_ON_DEVICE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported feature on device\n" );
+        return;
+      }
+      case PLAYER_ERROR_SEEK_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Seek failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_STATE:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid state\n" );
+        return;
+      }
+      case PLAYER_ERROR_NOT_SUPPORTED_FILE:
+      {
+        DALI_LOG_ERROR( "Player error: Not supported file\n" );
+        return;
+      }
+      case PLAYER_ERROR_INVALID_URI:
+      {
+        DALI_LOG_ERROR( "Player error: Invalid uri\n" );
+        return;
+      }
+      case PLAYER_ERROR_SOUND_POLICY:
+      {
+        DALI_LOG_ERROR( "Player error: Sound policy\n" );
+        return;
+      }
+      case PLAYER_ERROR_CONNECTION_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Connection failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_VIDEO_CAPTURE_FAILED:
+      {
+        DALI_LOG_ERROR( "Player error: Video capture failed\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_EXPIRED:
+      {
+        DALI_LOG_ERROR( "Player error: DRM expired\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NO_LICENSE:
+      {
+        DALI_LOG_ERROR( "Player error: No license\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_FUTURE_USE:
+      {
+        DALI_LOG_ERROR( "Player error: License for future use\n" );
+        return;
+      }
+      case PLAYER_ERROR_DRM_NOT_PERMITTED:
+      {
+        DALI_LOG_ERROR( "Player error: Format not permitted\n" );
+        return;
+      }
+      case PLAYER_ERROR_RESOURCE_LIMIT:
+      {
+        DALI_LOG_ERROR( "Player error: Resource limit\n" );
+        return;
+      }
+      case PLAYER_ERROR_PERMISSION_DENIED:
+      {
+        DALI_LOG_ERROR( "Player error: Permission denied\n" );
+        return;
+      }
+      case PLAYER_ERROR_SERVICE_DISCONNECTED:
+      {
+        DALI_LOG_ERROR( "Player error: Service disconnected\n" );
+        return;
+      }
+      case PLAYER_ERROR_BUFFER_SPACE:
+      {
+        DALI_LOG_ERROR( "Player error: Buffer space\n" );
+        return;
+      }
+      case PLAYER_ERROR_NOT_SUPPORTED_VIDEO_CODEC:
+      {
+        DALI_LOG_ERROR( "Player error: The target should not support the codec type\n" );
+        return;
+      }
+      default :
+      {
+        DALI_LOG_ERROR( "Player error: Unknown error code ( %d ) \n", error );
+        return;
+      }
+    }
+  }
+}
+
+} // unnamed namespace
+
+TizenVideoPlayer::TizenVideoPlayer()
+: mUrl(),
+  mPlayer( NULL ),
+  mPlayerState( PLAYER_STATE_NONE ),
+  mTbmSurface( NULL ),
+  mPacket( NULL ),
+  mNativeImageSourcePtr( NULL ),
+  mTimer(),
+  mBackgroundColor( Dali::Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ),
+  mTargetType( NativeImage ),
+  mPacketMutex(),
+  mPacketVector(),
+  mEcoreWlWindow( NULL ),
+  mAlphaBitChanged( false ),
+  mStreamInfo( NULL ),
+  mStreamType( SOUND_STREAM_TYPE_MEDIA ),
+  mCodecType( PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT )
+{
+}
+
+TizenVideoPlayer::~TizenVideoPlayer()
+{
+  DestroyPlayer();
+}
+
+void TizenVideoPlayer::GetPlayerState( player_state_e* state ) const
+{
+  if( mPlayer != NULL && player_get_state( mPlayer, state ) != PLAYER_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "player_get_state error: Invalid parameter\n" );
+    *state = PLAYER_STATE_NONE;
+  }
+}
+
+void TizenVideoPlayer::SetUrl( const std::string& url )
+{
+  if( mUrl != url )
+  {
+    int error = PLAYER_ERROR_NONE;
+
+    mUrl = url;
+
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_NONE && mPlayerState != PLAYER_STATE_IDLE )
+    {
+      if( mNativeImageSourcePtr )
+      {
+        error = player_unset_media_packet_video_frame_decoded_cb( mPlayer );
+        LogPlayerError( error );
+      }
+      Stop();
+
+      error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+
+      if( mNativeImageSourcePtr )
+      {
+        error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
+        LogPlayerError( error );
+      }
+      else
+      {
+        int width, height;
+        Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
+        ecore_wl2_display_screen_size_get( wl2_display, &width, &height );
+
+        error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+        LogPlayerError( error );
+      }
+      GetPlayerState( &mPlayerState );
+      LogPlayerError( error );
+    }
+
+    if( mPlayerState == PLAYER_STATE_IDLE )
+    {
+      error = player_set_uri( mPlayer, mUrl.c_str() );
+      LogPlayerError( error );
+
+      error = player_prepare( mPlayer );
+      LogPlayerError( error );
+    }
+  }
+}
+
+std::string TizenVideoPlayer::GetUrl()
+{
+  return mUrl;
+}
+
+void TizenVideoPlayer::SetRenderingTarget( Any target )
+{
+  DestroyPlayer();
+
+  mNativeImageSourcePtr = NULL;
+  mEcoreWlWindow = NULL;
+
+  if( target.GetType() == typeid( Dali::NativeImageSourcePtr ) )
+  {
+    mTargetType = TizenVideoPlayer::NativeImage;
+
+    Dali::NativeImageSourcePtr nativeImageSourcePtr = AnyCast< Dali::NativeImageSourcePtr >( target );
+
+    InitializeTextureStreamMode( nativeImageSourcePtr );
+  }
+  else if( target.GetType() == typeid( Ecore_Wl2_Window* ) )
+  {
+    mTargetType = TizenVideoPlayer::WindowSurface;
+
+    Ecore_Wl2_Window* nativeWindow = Dali::AnyCast< Ecore_Wl2_Window* >( target );
+    InitializeUnderlayMode( nativeWindow );
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Video rendering target is unknown\n" );
+  }
+}
+
+void TizenVideoPlayer::SetLooping( bool looping )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_set_looping( mPlayer, looping );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsLooping()
+{
+  GetPlayerState( &mPlayerState );
+
+  bool looping = false;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    int error = player_is_looping( mPlayer, &looping );
+    LogPlayerError( error );
+  }
+
+  return looping;
+}
+
+void TizenVideoPlayer::Play()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Start();
+    }
+
+    int error = player_start( mPlayer );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Pause()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING )
+  {
+    int error = player_pause( mPlayer );
+    LogPlayerError( error );
+
+    if( mNativeImageSourcePtr != NULL && mTimer )
+    {
+      mTimer.Stop();
+      DestroyPackets();
+    }
+  }
+}
+
+void TizenVideoPlayer::Stop()
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_PLAYING || mPlayerState == PLAYER_STATE_PAUSED )
+  {
+    int error = player_stop( mPlayer );
+    LogPlayerError( error );
+  }
+
+  if( mNativeImageSourcePtr != NULL && mTimer )
+  {
+    mTimer.Stop();
+    DestroyPackets();
+  }
+}
+
+void TizenVideoPlayer::SetMute( bool muted )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_set_mute( mPlayer, muted );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsMuted()
+{
+  GetPlayerState( &mPlayerState );
+  bool muted = false;
+
+   if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+    )
+  {
+    int error = player_is_muted( mPlayer, &muted );
+    LogPlayerError( error );
+  }
+
+  return muted;
+}
+
+void TizenVideoPlayer::SetVolume( float left, float right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_set_volume( mPlayer, left, right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::GetVolume( float& left, float& right )
+{
+  GetPlayerState( &mPlayerState );
+
+  int error = player_get_volume( mPlayer, &left, &right );
+  LogPlayerError( error );
+}
+
+void TizenVideoPlayer::SetPlayPosition( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_prepare( mPlayer );
+    LogPlayerError( error );
+
+    GetPlayerState( &mPlayerState ); // Check the status again.
+  }
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_set_play_position( mPlayer, millisecond, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+int TizenVideoPlayer::GetPlayPosition()
+{
+  int error;
+  int millisecond = 0;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    error = player_get_play_position( mPlayer, &millisecond );
+    LogPlayerError( error );
+  }
+
+  return millisecond;
+}
+
+void TizenVideoPlayer::SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation )
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayRotation is only for window rendering target.\n" );
+    return;
+  }
+
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_set_display_rotation( mPlayer, static_cast< player_display_rotation_e >( rotation ) );
+    LogPlayerError( error );
+  }
+}
+
+Dali::VideoPlayerPlugin::DisplayRotation TizenVideoPlayer::GetDisplayRotation()
+{
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "GetDisplayRotation is only for window rendering target.\n" );
+    return Dali::VideoPlayerPlugin::ROTATION_NONE;
+  }
+
+  int error;
+  player_display_rotation_e rotation = PLAYER_DISPLAY_ROTATION_NONE;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    error = player_get_display_rotation( mPlayer, &rotation );
+    LogPlayerError( error );
+  }
+  return static_cast< Dali::VideoPlayerPlugin::DisplayRotation >( rotation );
+}
+
+Dali::VideoPlayerPlugin::VideoPlayerSignalType& TizenVideoPlayer::FinishedSignal()
+{
+  return mFinishedSignal;
+}
+
+void TizenVideoPlayer::InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr )
+{
+  int error;
+
+  mNativeImageSourcePtr = nativeImageSourcePtr;
+
+  if( mAlphaBitChanged )
+  {
+    ecore_wl2_window_alpha_set( mEcoreWlWindow, false );
+    mAlphaBitChanged = false;
+  }
+
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = player_set_media_packet_video_frame_decoded_cb( mPlayer, MediaPacketVideoDecodedCb, this );
+    LogPlayerError( error );
+
+    error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_sound_stream_info( mPlayer, mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_FULL_SCREEN );
+    LogPlayerError( error );
+
+    error = player_set_display( mPlayer, PLAYER_DISPLAY_TYPE_NONE, NULL );
+    LogPlayerError( error );
+
+    error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+    LogPlayerError( error );
+
+    error = player_set_display_visible( mPlayer, true );
+    LogPlayerError( error );
+
+    mTimer = Dali::Timer::New( TIMER_INTERVAL );
+    mTimer.TickSignal().Connect( this, &TizenVideoPlayer::Update );
+  }
+}
+
+void TizenVideoPlayer::InitializeUnderlayMode( Ecore_Wl2_Window* ecoreWlWindow )
+{
+  int error;
+  if( mPlayerState == PLAYER_STATE_NONE )
+  {
+    error = player_create( &mPlayer );
+    LogPlayerError( error );
+  }
+
+  GetPlayerState( &mPlayerState );
+  mEcoreWlWindow = ecoreWlWindow;
+
+  if( mPlayerState == PLAYER_STATE_IDLE )
+  {
+    error = player_set_completed_cb( mPlayer, EmitPlaybackFinishedSignal, this );
+    LogPlayerError( error );
+
+    error = sound_manager_create_stream_information( mStreamType, NULL, NULL, &mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_sound_stream_info( mPlayer, mStreamInfo );
+    LogPlayerError( error );
+
+    error = player_set_display_mode( mPlayer, PLAYER_DISPLAY_MODE_DST_ROI );
+    LogPlayerError( error );
+
+    error = player_set_display_roi_area( mPlayer, 0, 0, 1, 1 );
+    LogPlayerError( error );
+
+    error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+    LogPlayerError( error );
+
+    int width, height;
+    Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
+    ecore_wl2_display_screen_size_get( wl2_display, &width, &height );
+    ecore_wl2_window_alpha_set( mEcoreWlWindow, false );
+    error = player_set_ecore_wl_display( mPlayer, PLAYER_DISPLAY_TYPE_OVERLAY, mEcoreWlWindow, 0, 0, width, height );
+    LogPlayerError( error );
+
+    error = player_set_display_visible( mPlayer, true );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::Update()
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+
+  int error;
+
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    if( error != MEDIA_PACKET_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    }
+    mPacket = NULL;
+  }
+
+  if( !mPacketVector.Empty() )
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[0] );
+    mPacketVector.Remove( mPacketVector.Begin() );
+  }
+
+  if( mPacket == NULL )
+  {
+    return true;
+  }
+
+  error = media_packet_get_tbm_surface( mPacket, &mTbmSurface );
+  if( error != MEDIA_PACKET_ERROR_NONE )
+  {
+    media_packet_destroy( mPacket );
+    mPacket = NULL;
+    DALI_LOG_ERROR( " error: %d\n", error );
+    return true;
+  }
+
+  Any source( mTbmSurface );
+  mNativeImageSourcePtr->SetSource( source );
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+
+  return true;
+}
+
+void TizenVideoPlayer::DestroyPackets()
+{
+  int error;
+  if( mPacket != NULL )
+  {
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+
+  for(unsigned int i = 0; i < mPacketVector.Size(); ++i)
+  {
+    mPacket = static_cast< media_packet_h >( mPacketVector[i] );
+    error = media_packet_destroy( mPacket );
+    DALI_LOG_ERROR( "Media packet destroy error: %d\n", error );
+    mPacket = NULL;
+  }
+  mPacketVector.Clear();
+}
+
+void TizenVideoPlayer::PushPacket( media_packet_h packet )
+{
+  Dali::Mutex::ScopedLock lock( mPacketMutex );
+  mPacketVector.PushBack( packet );
+}
+
+void TizenVideoPlayer::SetDisplayArea( DisplayArea area )
+{
+  GetPlayerState( &mPlayerState );
+
+  if( mNativeImageSourcePtr != NULL )
+  {
+    DALI_LOG_ERROR( "SetDisplayArea is only for window surface target.\n" );
+    return;
+  }
+
+  if( mPlayerState == PLAYER_STATE_IDLE ||
+      mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+
+  )
+  {
+    area.x = ( area.x < 0 ) ? 0: area.x;
+    area.y = ( area.y < 0 ) ? 0: area.y;
+    int error = player_set_display_roi_area( mPlayer, area.x, area.y, area.width, area.height );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Forward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition + millisecond;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+void TizenVideoPlayer::Backward( int millisecond )
+{
+  int error;
+
+  GetPlayerState( &mPlayerState );
+
+  if( mPlayerState == PLAYER_STATE_READY ||
+      mPlayerState == PLAYER_STATE_PLAYING ||
+      mPlayerState == PLAYER_STATE_PAUSED
+  )
+  {
+    int currentPosition = 0;
+    int nextPosition = 0;
+
+    error = player_get_play_position( mPlayer, &currentPosition );
+    LogPlayerError( error );
+
+    nextPosition = currentPosition - millisecond;
+    nextPosition = ( nextPosition < 0 )? 0 : nextPosition;
+
+    error = player_set_play_position( mPlayer, nextPosition, false, PlayerSeekCompletedCb, NULL );
+    LogPlayerError( error );
+  }
+}
+
+bool TizenVideoPlayer::IsVideoTextureSupported()
+{
+  bool featureFlag = true;
+  int error = SYSTEM_INFO_ERROR_NONE;
+
+  error = system_info_get_platform_bool( "tizen.org/feature/multimedia.raw_video", &featureFlag );
+
+  if( error != SYSTEM_INFO_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "Plugin can't check platform feature\n" );
+    return false;
+  }
+
+  return featureFlag;
+}
+
+void TizenVideoPlayer::DestroyPlayer()
+{
+  mUrl = "";
+
+  int error;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState != PLAYER_STATE_IDLE )
+    {
+      Stop();
+      error = player_unprepare( mPlayer );
+      LogPlayerError( error );
+    }
+
+    error = player_destroy( mPlayer );
+    LogPlayerError( error );
+
+    error = sound_manager_destroy_stream_information(mStreamInfo);
+    LogPlayerError( error );
+
+    mPlayerState = PLAYER_STATE_NONE;
+    mPlayer = NULL;
+  }
+}
+
+void TizenVideoPlayer::SetCodecType( Dali::VideoPlayerPlugin::CodecType type )
+{
+  int error;
+  switch( type )
+  {
+    case Dali::VideoPlayerPlugin::CodecType::DEFAULT :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT;
+      break;
+    }
+    case Dali::VideoPlayerPlugin::CodecType::HW :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_HW;
+      break;
+    }
+    case Dali::VideoPlayerPlugin::CodecType::SW :
+    {
+      mCodecType = PLAYER_VIDEO_CODEC_TYPE_EX_SW;
+      break;
+    }
+  }
+
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    GetPlayerState( &mPlayerState );
+
+    if( mPlayerState == PLAYER_STATE_IDLE )
+    {
+      error = player_set_video_codec_type_ex( mPlayer, mCodecType );
+      LogPlayerError( error );
+    }
+  }
+}
+
+Dali::VideoPlayerPlugin::CodecType TizenVideoPlayer::GetCodecType() const
+{
+  Dali::VideoPlayerPlugin::CodecType type = Dali::VideoPlayerPlugin::CodecType::DEFAULT;
+  if( mPlayerState != PLAYER_STATE_NONE )
+  {
+    player_video_codec_type_ex_e codecType = PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT;
+    int error = player_get_video_codec_type_ex( mPlayer, &codecType );
+    if( error != PLAYER_ERROR_NONE )
+    {
+      LogPlayerError( error );
+      return type;
+    }
+
+    switch( codecType )
+    {
+      case PLAYER_VIDEO_CODEC_TYPE_EX_DEFAULT :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::DEFAULT;
+        break;
+      }
+      case PLAYER_VIDEO_CODEC_TYPE_EX_HW :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::HW;
+        break;
+      }
+      case PLAYER_VIDEO_CODEC_TYPE_EX_SW :
+      {
+        type = Dali::VideoPlayerPlugin::CodecType::SW;
+        break;
+      }
+    }
+  }
+  return type;
+}
+
+void TizenVideoPlayer::SetDisplayMode( Dali::VideoPlayerPlugin::DisplayMode::Type mode )
+{
+  int error;
+  error = player_set_display_mode( mPlayer, static_cast< player_display_mode_e >( mode ) );
+  LogPlayerError( error );
+}
+
+Dali::VideoPlayerPlugin::DisplayMode::Type TizenVideoPlayer::GetDisplayMode() const
+{
+  player_display_mode_e mode;
+  player_get_display_mode( mPlayer, &mode );
+  return static_cast< Dali::VideoPlayerPlugin::DisplayMode::Type >( mode );
+}
+
+Any TizenVideoPlayer::GetMediaPlayer()
+{
+   return Any( ( void* ) mPlayer );
+}
+
+} // namespace Plugin
+} // namespace Dali;
diff --git a/dali-extension/video-player/ecore-wl2/tizen-video-player.h b/dali-extension/video-player/ecore-wl2/tizen-video-player.h
new file mode 100755 (executable)
index 0000000..04cc00f
--- /dev/null
@@ -0,0 +1,269 @@
+#ifndef __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+#define __DALI_TIZEN_VIDEO_PLAYER_PLUGIN_H__
+
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
+#include <dali/devel-api/adaptor-framework/video-player-plugin.h>
+#include <player.h>
+#include <string>
+
+#ifndef HAVE_WAYLAND
+#define HAVE_WAYLAND
+#endif
+#include <player_internal.h>
+#include <Ecore_Wl2.h>
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the Tizen video player class which has Tizen platform dependency.
+ * @SINCE_1_1.38
+ */
+class TizenVideoPlayer : public Dali::VideoPlayerPlugin, public Dali::ConnectionTracker
+{
+public:
+
+  /**
+   * @brief Video rendering target type
+   * @SINCE_1_1.38
+   */
+  enum RenderingTargetType
+  {
+    WindowSurface, ///< HW underlay
+    NativeImage ///< texture stream
+  };
+
+  /**
+   * @brief Constructor.
+   * @SINCE_1_1.38
+   */
+  TizenVideoPlayer();
+
+  /**
+   * @brief Destructor.
+   * @SINCE_1_1.38
+   */
+  virtual ~TizenVideoPlayer();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetUrl()
+   */
+  virtual void SetUrl( const std::string& url );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetUrl()
+   */
+  virtual std::string GetUrl();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetLooping()
+   */
+  virtual void SetLooping(bool looping);
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsLooping()
+   */
+  virtual bool IsLooping();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Play()
+   */
+  virtual void Play();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Pause()
+   */
+  virtual void Pause();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::Stop()
+   */
+  virtual void Stop();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetMute()
+   */
+  virtual void SetMute( bool mute );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::IsMute()
+   */
+  virtual bool IsMuted();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetVolume()
+   */
+  virtual void SetVolume( float left, float right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetVolume()
+   */
+  virtual void GetVolume( float& left, float& right );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetRenderingTarget()
+   */
+  void SetRenderingTarget( Any target );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetPlayPosition()
+   */
+  virtual void SetPlayPosition( int millisecond );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetPlayPosition()
+   */
+  virtual int GetPlayPosition();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayArea()
+   */
+  virtual void SetDisplayArea( DisplayArea area );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayRotation()
+   */
+  virtual void SetDisplayRotation( Dali::VideoPlayerPlugin::DisplayRotation rotation );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetDisplayRotation()
+   */
+  virtual Dali::VideoPlayerPlugin::DisplayRotation GetDisplayRotation();
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::FinishedSignal()
+   */
+  virtual Dali::VideoPlayerPlugin::VideoPlayerSignalType& FinishedSignal();
+
+  /**
+   * @brief Push media packet with video frame image
+   */
+  void PushPacket( media_packet_h packet );
+
+  /**
+   * @brief Dali::VideoPlayer::Forward()
+   */
+  void Forward( int millisecond );
+
+  /**
+   * @brief Dali::VideoPlayer::Backward()
+   */
+  void Backward( int millisecond );
+
+  /**
+   * @brief Dali::VideoPlayer::IsVideoTextureSupported()
+   */
+  bool IsVideoTextureSupported();
+
+  /**
+   * @brief Dali::VideoPlayer::SetCodecType()
+   */
+  void SetCodecType( Dali::VideoPlayerPlugin::CodecType type );
+
+  /**
+   * @brief Dali::VideoPlayer::GetCodecType()
+   */
+  Dali::VideoPlayerPlugin::CodecType GetCodecType() const;
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::SetDisplayMode()
+   */
+  void SetDisplayMode(  Dali::VideoPlayerPlugin::DisplayMode::Type mode );
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetDisplayMode()
+   */
+  Dali::VideoPlayerPlugin::DisplayMode::Type GetDisplayMode() const;
+
+  /**
+   * @copydoc Dali::VideoPlayerPlugin::GetMediaPlayer()
+   */
+  Any GetMediaPlayer();
+
+private:
+
+  /**
+   * @brief Updates video frame image by timer if rendering targe is native image source
+   */
+  bool Update();
+
+  /**
+   * @brief Gets current player state
+   */
+  void GetPlayerState( player_state_e* state ) const;
+
+  /**
+   * @brief Destroy all packests, which this plugin stores
+   */
+  void DestroyPackets();
+
+  /**
+   * @brief Initializes player for video rendering using native image source
+   */
+  void InitializeTextureStreamMode( Dali::NativeImageSourcePtr nativeImageSourcePtr );
+
+  /**
+   * @brief Initializes player for video rendering using wayland window surface
+   */
+  void InitializeUnderlayMode( Ecore_Wl2_Window* ecoreWlWindow );
+
+  /**
+   * @brief Destroys player handle
+   */
+  void DestroyPlayer();
+
+private:
+
+  std::string mUrl; ///< The video file path
+  player_h mPlayer; ///< Tizen player handle
+  player_state_e mPlayerState; ///< Tizen player state
+  tbm_surface_h mTbmSurface; ///< tbm surface handle
+  media_packet_h mPacket; ///< Media packet handle with tbm surface of current video frame image
+  Dali::NativeImageSourcePtr mNativeImageSourcePtr; ///< native image source for video rendering
+  Dali::Timer mTimer; ///< Timer for texture streaming rendering
+  Dali::Vector4 mBackgroundColor; ///< Current background color, which texturestream mode needs.
+  RenderingTargetType mTargetType; ///< Current rendering target type
+
+  Dali::Mutex mPacketMutex;
+  Dali::Vector< media_packet_h > mPacketVector; ///< Container for media packet handle from Tizen player callback
+
+  Ecore_Wl2_Window* mEcoreWlWindow;
+
+  bool mAlphaBitChanged; ///< True if underlay rendering initialization changes window alpha
+
+  sound_stream_info_h mStreamInfo;
+  sound_stream_type_e mStreamType;
+
+  player_video_codec_type_ex_e mCodecType;
+public:
+
+  Dali::VideoPlayerPlugin::VideoPlayerSignalType mFinishedSignal;
+};
+
+} // namespace Plugin
+} // namespace Dali;
+
+#endif
diff --git a/dali-extension/video-player/file.list b/dali-extension/video-player/file.list
new file mode 100644 (file)
index 0000000..93fd294
--- /dev/null
@@ -0,0 +1,5 @@
+video_player_ecore_wl2_plugin_src_files = \
+   $(extension_src_dir)/video-player/ecore-wl2/tizen-video-player-ecore-wl2.cpp
+
+video_player_ecore_wl_plugin_src_files = \
+   $(extension_src_dir)/video-player/ecore-wl/tizen-video-player-ecore-wl.cpp
diff --git a/dali-extension/web-engine-chromium/file.list b/dali-extension/web-engine-chromium/file.list
new file mode 100644 (file)
index 0000000..fa00bc1
--- /dev/null
@@ -0,0 +1,2 @@
+web_engine_chromium_plugin_src_files = \
+   $(extension_src_dir)/web-engine-chromium/tizen-web-engine-chromium.cpp
diff --git a/dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp b/dali-extension/web-engine-chromium/tizen-web-engine-chromium.cpp
new file mode 100644 (file)
index 0000000..e3fa0d9
--- /dev/null
@@ -0,0 +1,921 @@
+/*
+ * 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 <tizen-web-engine-chromium.h>
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Evas.h>
+#include <Elementary.h>
+
+#include <EWebKit_internal.h>
+#include <EWebKit_product.h>
+
+#include <dali/integration-api/debug.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+
+using namespace Dali;
+
+namespace Dali
+{
+namespace Plugin
+{
+
+class WebViewContainerClientPair {
+public:
+  WebViewContainerClientPair( WebViewContainerClient* client, Evas_Object* webView )
+  {
+    mClient = client;
+    mWebView = webView;
+  }
+
+  WebViewContainerClient* mClient;
+  Evas_Object* mWebView;
+};
+
+class WebEngineManager {
+  //
+  // A class for managing multiple WebViews
+  //
+public:
+  static WebEngineManager& Get()
+  {
+    static WebEngineManager instance;
+
+    return instance;
+  }
+
+  WebEngineManager(WebEngineManager const&) = delete;
+
+  void operator=(WebEngineManager const&) = delete;
+
+  Ecore_Evas* GetWindow()
+  {
+    return mWindow;
+  }
+
+  void AddContainerClient( WebViewContainerClient* client, Evas_Object* webView )
+  {
+    mContainerClients.push_back( WebViewContainerClientPair( client, webView ) );
+  }
+
+  void RemoveContainerClient( Evas_Object* webView )
+  {
+    for( auto it = mContainerClients.begin(); it != mContainerClients.end(); )
+    {
+      if( (*it).mWebView == webView )
+      {
+        mContainerClients.erase( it );
+        break;
+      }
+    }
+  }
+
+  WebViewContainerClient* FindContainerClient( Evas_Object* o )
+  {
+    for( auto& webViewClient :  mContainerClients )
+    {
+      if( webViewClient.mWebView == o )
+      {
+        return webViewClient.mClient;
+      }
+    }
+    return 0;
+  }
+
+private:
+  WebEngineManager()
+  {
+    elm_init( 0, 0 );
+    ewk_init();
+    mWindow = ecore_evas_new( "wayland_egl", 0, 0, 1, 1, 0 );
+  }
+
+  Ecore_Evas* mWindow;
+  std::vector< WebViewContainerClientPair > mContainerClients;
+};
+
+class WebViewContainerForDali
+{
+public:
+  WebViewContainerForDali( WebViewContainerClient& client, int width, int height )
+    : mClient( client ),
+      mWidth( width ),
+      mHeight( height ),
+      mCookieAcceptancePolicy( EWK_COOKIE_ACCEPT_POLICY_NO_THIRD_PARTY )
+  {
+    InitWebView();
+
+    WebEngineManager::Get().AddContainerClient( &mClient, mWebView );
+  }
+
+  ~WebViewContainerForDali()
+  {
+    WebEngineManager::Get().RemoveContainerClient( mWebView );
+
+    evas_object_del( mWebView );
+  }
+
+  void InitWebView()
+  {
+    Ecore_Wl2_Window* win = AnyCast< Ecore_Wl2_Window* >( Adaptor::Get().GetNativeWindowHandle() );
+    Ewk_Context* context = ewk_context_default_get();
+    ewk_context_max_refresh_rate_set( context, 60 );
+    mWebView = ewk_view_add( ecore_evas_get( WebEngineManager::Get().GetWindow() ) );
+    ewk_view_offscreen_rendering_enabled_set( mWebView, true );
+    ewk_view_ime_window_set( mWebView, win );
+
+    evas_object_smart_callback_add( mWebView, "offscreen,frame,rendered",
+                                    &WebViewContainerForDali::OnFrameRendered,
+                                    &mClient );
+    evas_object_smart_callback_add( mWebView, "load,started",
+                                    &WebViewContainerForDali::OnLoadStarted,
+                                    &mClient );
+    evas_object_smart_callback_add( mWebView, "load,finished",
+                                    &WebViewContainerForDali::OnLoadFinished,
+                                    &mClient );
+    evas_object_smart_callback_add( mWebView, "load,error",
+                                    &WebViewContainerForDali::OnLoadError,
+                                    &mClient );
+    evas_object_smart_callback_add( mWebView, "console,message",
+                                    &WebViewContainerForDali::OnConsoleMessage,
+                                    this );
+
+    evas_object_resize( mWebView, mWidth, mHeight );
+    evas_object_show( mWebView );
+  }
+
+  void LoadUrl( const std::string& url )
+  {
+    ewk_view_url_set( mWebView, url.c_str() );
+    ewk_view_focus_set( mWebView, true );
+  }
+
+  void LoadHtml( const std::string& html )
+  {
+    ewk_view_html_string_load( mWebView, html.c_str(), 0, 0 );
+  }
+
+  std::string GetUrl()
+  {
+    return std::string( ewk_view_url_get( mWebView ) );
+  }
+
+  void Reload()
+  {
+    ewk_view_reload( mWebView );
+  }
+
+  void StopLoading()
+  {
+    ewk_view_stop( mWebView );
+  }
+
+  void Suspend()
+  {
+    ewk_view_suspend( mWebView );
+  }
+
+  void Resume()
+  {
+    ewk_view_resume( mWebView );
+  }
+
+  void GoBack()
+  {
+    ewk_view_back( mWebView );
+  }
+
+  void GoForward()
+  {
+    ewk_view_forward( mWebView );
+  }
+
+  bool CanGoBack()
+  {
+    return ewk_view_back_possible( mWebView );
+  }
+
+  bool CanGoForward()
+  {
+    return ewk_view_forward_possible( mWebView );
+  }
+
+  void EvaluateJavaScript( size_t key, const std::string& script )
+  {
+    ewk_view_script_execute( mWebView, script.c_str(), OnEvaluateJavaScript, (void*)key );
+  }
+
+  void AddJavaScriptMessageHandler( const std::string& exposedObjectName )
+  {
+    // |jsFunctionName| is fixed as "postMessage" so we don't use this.
+    ewk_view_javascript_message_handler_add( mWebView, &WebViewContainerForDali::OnJavaScriptMessage, exposedObjectName.c_str() );
+  }
+
+  void ClearHistory()
+  {
+    ewk_view_back_forward_list_clear( mWebView );
+  }
+
+  void ClearCache()
+  {
+    ewk_context_cache_clear( ewk_view_context_get( mWebView ) );
+  }
+
+  void ClearCookies()
+  {
+    ewk_cookie_manager_cookies_clear( ewk_context_cookie_manager_get( ewk_view_context_get( mWebView ) ) );
+  }
+
+  Ewk_Cache_Model GetCacheModel()
+  {
+    return ewk_context_cache_model_get( ewk_view_context_get( mWebView ) );
+  }
+
+  void SetCacheModel( Ewk_Cache_Model cacheModel )
+  {
+    ewk_context_cache_model_set( ewk_view_context_get( mWebView ), cacheModel );
+  }
+
+  Ewk_Cookie_Accept_Policy GetCookieAcceptPolicy()
+  {
+    return mCookieAcceptancePolicy;
+  }
+
+  void SetCookieAcceptPolicy( Ewk_Cookie_Accept_Policy policy )
+  {
+    ewk_cookie_manager_accept_policy_set( ewk_context_cookie_manager_get( ewk_view_context_get( mWebView ) ), policy );
+    mCookieAcceptancePolicy = policy;
+  }
+
+  const std::string& GetUserAgent()
+  {
+    mUserAgent = std::string( ewk_view_user_agent_get( mWebView ) );
+    return mUserAgent;
+  }
+
+  void SetUserAgent( const std::string& userAgent )
+  {
+    ewk_view_user_agent_set( mWebView, userAgent.c_str() );
+  }
+
+  bool IsJavaScriptEnabled()
+  {
+    return ewk_settings_javascript_enabled_get( ewk_view_settings_get( mWebView ) );
+  }
+
+  void EnableJavaScript( bool enabled )
+  {
+    ewk_settings_javascript_enabled_set( ewk_view_settings_get( mWebView ), enabled );
+  }
+
+  bool AreImagesAutomaticallyLoaded()
+  {
+    return ewk_settings_loads_images_automatically_get( ewk_view_settings_get( mWebView ) );
+  }
+
+  void LoadImagesAutomatically( bool automatic )
+  {
+    ewk_settings_loads_images_automatically_set( ewk_view_settings_get( mWebView ), automatic );
+  }
+
+  const std::string& GetDefaultTextEncodingName()
+  {
+    mDefaultTextEncodingName = std::string( ewk_settings_default_text_encoding_name_get( ewk_view_settings_get( mWebView ) ) );
+    return mDefaultTextEncodingName;
+  }
+
+  void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName )
+  {
+    ewk_settings_default_text_encoding_name_set( ewk_view_settings_get( mWebView ), defaultTextEncodingName.c_str() );
+  }
+
+  int GetDefaultFontSize()
+  {
+    return ewk_settings_default_font_size_get( ewk_view_settings_get( mWebView ) );
+  }
+
+  void SetDefaultFontSize( int defaultFontSize )
+  {
+    ewk_settings_default_font_size_set( ewk_view_settings_get( mWebView ), defaultFontSize );
+  }
+
+  void SetSize( int width, int height )
+  {
+    mWidth = width;
+    mHeight = height;
+    evas_object_resize( mWebView, mWidth, mHeight );
+  }
+
+  bool SendTouchEvent( const TouchData& touch )
+  {
+    Ewk_Touch_Event_Type type = EWK_TOUCH_START;
+    Evas_Touch_Point_State state = EVAS_TOUCH_POINT_DOWN;
+    switch ( touch.GetState( 0 ) )
+    {
+      case PointState::DOWN:
+      {
+        type = EWK_TOUCH_START;
+        state = EVAS_TOUCH_POINT_DOWN;
+        break;
+      }
+      case PointState::UP:
+      {
+        type = EWK_TOUCH_END;
+        state = EVAS_TOUCH_POINT_UP;
+        break;
+      }
+      case PointState::MOTION:
+      {
+        type = EWK_TOUCH_MOVE;
+        state = EVAS_TOUCH_POINT_MOVE;
+        break;
+      }
+      case PointState::INTERRUPTED:
+      {
+        type = EWK_TOUCH_CANCEL;
+        state = EVAS_TOUCH_POINT_CANCEL;
+        break;
+      }
+      default:
+      {
+        break;
+      }
+    }
+
+    Eina_List* pointList = 0;
+    Ewk_Touch_Point* point = new Ewk_Touch_Point;
+    point->id = 0;
+    point->x = touch.GetLocalPosition( 0 ).x;
+    point->y = touch.GetLocalPosition( 0 ).y;
+    point->state = state;
+    pointList = eina_list_append( pointList, point );
+
+    ewk_view_feed_touch_event( mWebView, type, pointList, 0 );
+    eina_list_free( pointList );
+    return false;
+  }
+
+  bool SendKeyEvent( const KeyEvent& keyEvent )
+  {
+    void* evasKeyEvent = 0;
+    if( keyEvent.state == KeyEvent::Down )
+    {
+      Evas_Event_Key_Down downEvent;
+      memset( &downEvent, 0, sizeof(Evas_Event_Key_Down) );
+      downEvent.key = keyEvent.keyPressedName.c_str();
+      downEvent.string = keyEvent.keyPressed.c_str();
+      evasKeyEvent = static_cast<void*>(&downEvent);
+      ewk_view_send_key_event( mWebView, evasKeyEvent, true );
+    }
+    else
+    {
+      Evas_Event_Key_Up upEvent;
+      memset(&upEvent, 0, sizeof(Evas_Event_Key_Up));
+      upEvent.key = keyEvent.keyPressedName.c_str();
+      upEvent.string = keyEvent.keyPressed.c_str();
+      evasKeyEvent = static_cast<void*>(&upEvent);
+      ewk_view_send_key_event( mWebView, evasKeyEvent, false );
+     }
+     return false;
+  }
+
+private:
+  static void OnFrameRendered( void* data, Evas_Object*, void* buffer )
+  {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->UpdateImage( static_cast<tbm_surface_h>(buffer) );
+  }
+
+  static void OnLoadStarted( void* data, Evas_Object*, void* )
+  {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->LoadStarted();
+  }
+
+  static void OnLoadFinished( void* data, Evas_Object*, void* )
+  {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    client->LoadFinished();
+  }
+
+  static void OnLoadError( void* data, Evas_Object*, void* rawError )
+  {
+    auto client = static_cast<WebViewContainerClient*>(data);
+    Ewk_Error* error = static_cast< Ewk_Error* >( rawError );
+
+    client->LoadError( ewk_error_url_get( error ), ewk_error_code_get( error ) );
+  }
+
+  static void OnConsoleMessage( void*, Evas_Object*, void* eventInfo )
+  {
+    Ewk_Console_Message* message = (Ewk_Console_Message*)eventInfo;
+    DALI_LOG_RELEASE_INFO( "console message:%s: %d: %d: %s",
+        ewk_console_message_source_get( message ),
+        ewk_console_message_line_get( message ),
+        ewk_console_message_level_get( message ),
+        ewk_console_message_text_get( message ) );
+  }
+
+  static void OnEvaluateJavaScript( Evas_Object* o, const char* result, void* data )
+  {
+    auto client = WebEngineManager::Get().FindContainerClient( o );
+    if( client )
+    {
+      client->RunJavaScriptEvaluationResultHandler( (size_t)data, result );
+    }
+  }
+
+  static void OnJavaScriptMessage( Evas_Object* o, Ewk_Script_Message message )
+  {
+    auto client = WebEngineManager::Get().FindContainerClient( o );
+    if( client )
+    {
+      client->RunJavaScriptMessageHandler( message.name, static_cast<char*>( message.body ) );
+    }
+  }
+
+private:
+  Evas_Object* mWebView;
+  WebViewContainerClient& mClient;
+
+  int mWidth;
+  int mHeight;
+
+  Ewk_Cookie_Accept_Policy mCookieAcceptancePolicy;
+  std::string mUserAgent;
+  std::string mDefaultTextEncodingName;
+};
+
+class TBMSurfaceSourceInitializer
+{
+public:
+  explicit TBMSurfaceSourceInitializer( NativeImageSourcePtr& imageSrc,
+                                        int width, int height )
+  {
+    mSurface = tbm_surface_create( width, height, TBM_FORMAT_ARGB8888 );
+    if( !mSurface )
+    {
+      DALI_LOG_ERROR( "Failed to create tbm surface." );
+    }
+
+    Any tbmSource( mSurface );
+    imageSrc = NativeImageSource::New( tbmSource );
+    Any emptySource( 0 );
+    imageSrc->SetSource( emptySource );
+  }
+
+  ~TBMSurfaceSourceInitializer()
+  {
+    if( mSurface )
+    {
+      if( tbm_surface_destroy( mSurface ) != TBM_SURFACE_ERROR_NONE )
+      {
+        DALI_LOG_ERROR( "Failed to destroy tbm surface." );
+      }
+    }
+  }
+private:
+  tbm_surface_h mSurface;
+};
+
+TizenWebEngineChromium::TizenWebEngineChromium()
+  : mWebViewContainer( 0 )
+  , mJavaScriptEvaluationCount( 0 )
+{
+}
+
+TizenWebEngineChromium::~TizenWebEngineChromium()
+{
+  Destroy();
+}
+
+void TizenWebEngineChromium::Create( int width, int height,
+                                     const std::string& locale,
+                                     const std::string& timezoneID )
+{
+  mWebViewContainer =
+      new WebViewContainerForDali( *this, width, height );
+  TBMSurfaceSourceInitializer initializer( mDaliImageSrc, width, height );
+}
+
+void TizenWebEngineChromium::Destroy()
+{
+  if (mWebViewContainer)
+  {
+    mJavaScriptEvaluationResultHandlers.clear();
+    mJavaScriptMessageHandlers.clear();
+
+    delete mWebViewContainer;
+    mWebViewContainer = 0;
+  }
+}
+
+void TizenWebEngineChromium::LoadUrl( const std::string& path )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->LoadUrl( path );
+  }
+}
+
+NativeImageInterfacePtr TizenWebEngineChromium::GetNativeImageSource()
+{
+  return mDaliImageSrc;
+}
+
+const std::string& TizenWebEngineChromium::GetUrl()
+{
+  if( mWebViewContainer )
+  {
+    mUrl =  mWebViewContainer->GetUrl();
+  }
+  return mUrl;
+}
+
+void TizenWebEngineChromium::LoadHTMLString( const std::string& string )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->LoadHtml( string );
+  }
+}
+
+void TizenWebEngineChromium::Reload()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->Reload();
+  }
+}
+
+void TizenWebEngineChromium::StopLoading()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->StopLoading();
+  }
+}
+
+void TizenWebEngineChromium::Suspend()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->Suspend();
+  }
+}
+
+void TizenWebEngineChromium::Resume()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->Resume();
+  }
+}
+
+bool TizenWebEngineChromium::CanGoForward()
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->CanGoForward();
+  }
+  return false;
+}
+
+void TizenWebEngineChromium::GoForward()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->GoForward();
+  }
+}
+
+bool TizenWebEngineChromium::CanGoBack()
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->CanGoBack();
+  }
+  return false;
+}
+
+void TizenWebEngineChromium::GoBack()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->GoBack();
+  }
+}
+
+void TizenWebEngineChromium::EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler )
+{
+  if( mWebViewContainer )
+  {
+    bool badAlloc = false;
+
+    try
+    {
+      mJavaScriptEvaluationResultHandlers.emplace( mJavaScriptEvaluationCount, resultHandler );
+    }
+    catch( std::bad_alloc &e )
+    {
+      badAlloc = true;
+      DALI_LOG_ERROR( "Too many ongoing JavaScript evaluations." );
+    }
+
+    if( !badAlloc )
+    {
+      mWebViewContainer->EvaluateJavaScript( mJavaScriptEvaluationCount++, script );
+    }
+  }
+}
+
+void TizenWebEngineChromium::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void( const std::string& ) > handler )
+{
+  if( mWebViewContainer )
+  {
+    if( mJavaScriptMessageHandlers.emplace( exposedObjectName, handler ).second )
+    {
+      mWebViewContainer->AddJavaScriptMessageHandler( exposedObjectName );
+    }
+    else
+    {
+      DALI_LOG_ERROR( "Callback for (%s) already exists.", exposedObjectName.c_str() );
+    }
+  }
+}
+
+void TizenWebEngineChromium::ClearHistory()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->ClearHistory();
+  }
+}
+
+void TizenWebEngineChromium::ClearCache()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->ClearCache();
+  }
+}
+
+void TizenWebEngineChromium::ClearCookies()
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->ClearCookies();
+  }
+}
+
+Dali::WebEnginePlugin::CacheModel TizenWebEngineChromium::GetCacheModel() const
+{
+  if( mWebViewContainer )
+  {
+    return static_cast< Dali::WebEnginePlugin::CacheModel >( mWebViewContainer->GetCacheModel() );
+  }
+  return Dali::WebEnginePlugin::CacheModel::DOCUMENT_VIEWER;
+}
+
+void TizenWebEngineChromium::SetCacheModel( Dali::WebEnginePlugin::CacheModel cacheModel )
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->SetCacheModel( static_cast< Ewk_Cache_Model >( cacheModel ) );
+  }
+}
+
+Dali::WebEnginePlugin::CookieAcceptPolicy TizenWebEngineChromium::GetCookieAcceptPolicy() const
+{
+  if( mWebViewContainer )
+  {
+    return static_cast< Dali::WebEnginePlugin::CookieAcceptPolicy >( mWebViewContainer->GetCookieAcceptPolicy() );
+  }
+  return Dali::WebEnginePlugin::CookieAcceptPolicy::NO_THIRD_PARTY;
+}
+
+void TizenWebEngineChromium::SetCookieAcceptPolicy( Dali::WebEnginePlugin::CookieAcceptPolicy policy )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->SetCookieAcceptPolicy( static_cast< Ewk_Cookie_Accept_Policy >( policy ) );
+  }
+}
+
+const std::string kEmpty;
+
+const std::string& TizenWebEngineChromium::GetUserAgent() const
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->GetUserAgent();
+  }
+  return kEmpty;
+}
+
+void TizenWebEngineChromium::SetUserAgent( const std::string& userAgent )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->SetUserAgent( userAgent );
+  }
+}
+
+bool TizenWebEngineChromium::IsJavaScriptEnabled() const
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->IsJavaScriptEnabled();
+  }
+  return false;
+}
+
+void TizenWebEngineChromium::EnableJavaScript( bool enabled )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->EnableJavaScript( enabled );
+  }
+}
+
+bool TizenWebEngineChromium::AreImagesAutomaticallyLoaded() const
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->AreImagesAutomaticallyLoaded();
+  }
+  return false;
+}
+
+void TizenWebEngineChromium::LoadImagesAutomatically( bool automatic )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->LoadImagesAutomatically( automatic );
+  }
+}
+
+const std::string& TizenWebEngineChromium::GetDefaultTextEncodingName() const
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->GetDefaultTextEncodingName();
+  }
+  return kEmpty;
+}
+
+void TizenWebEngineChromium::SetDefaultTextEncodingName( const std::string& defaultTextEncodingName )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->SetDefaultTextEncodingName( defaultTextEncodingName );
+  }
+}
+
+int TizenWebEngineChromium::GetDefaultFontSize() const
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->AreImagesAutomaticallyLoaded();
+  }
+  return 0;
+}
+
+void TizenWebEngineChromium::SetDefaultFontSize( int defaultFontSize )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->SetDefaultFontSize( defaultFontSize );
+  }
+}
+
+void TizenWebEngineChromium::SetSize( int width, int height )
+{
+  if( mWebViewContainer )
+  {
+    mWebViewContainer->SetSize( width, height );
+  }
+}
+
+bool TizenWebEngineChromium::SendTouchEvent( const Dali::TouchData& touch )
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->SendTouchEvent( touch );
+  }
+  return false;
+}
+
+bool TizenWebEngineChromium::SendKeyEvent( const Dali::KeyEvent& event )
+{
+  if( mWebViewContainer )
+  {
+    return mWebViewContainer->SendKeyEvent( event );
+  }
+  return false;
+}
+
+Dali::WebEnginePlugin::WebEnginePageLoadSignalType& TizenWebEngineChromium::PageLoadStartedSignal()
+{
+  return mLoadStartedSignal;
+}
+
+Dali::WebEnginePlugin::WebEnginePageLoadSignalType& TizenWebEngineChromium::PageLoadFinishedSignal()
+{
+  return mLoadFinishedSignal;
+}
+
+Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& TizenWebEngineChromium::PageLoadErrorSignal()
+{
+  return mLoadErrorSignal;
+}
+
+// WebViewContainerClient Interface
+void TizenWebEngineChromium::UpdateImage( tbm_surface_h buffer )
+{
+  if( !buffer )
+  {
+    return;
+  }
+
+  Any source( buffer );
+  mDaliImageSrc->SetSource( source );
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+}
+
+void TizenWebEngineChromium::LoadStarted()
+{
+  DALI_LOG_RELEASE_INFO( "#LoadStarted : %s\n", GetUrl().c_str() );
+  mLoadStartedSignal.Emit( GetUrl() );
+}
+
+void TizenWebEngineChromium::LoadFinished()
+{
+  DALI_LOG_RELEASE_INFO( "#LoadFinished : %s\n", GetUrl().c_str() );
+  mLoadFinishedSignal.Emit( GetUrl() );
+}
+
+void TizenWebEngineChromium::LoadError( const char* url, int errorCode )
+{
+  std::string stdUrl( url );
+  mLoadErrorSignal.Emit( stdUrl, errorCode );
+}
+
+void TizenWebEngineChromium::RunJavaScriptEvaluationResultHandler( size_t key, const char* result )
+{
+  auto handler = mJavaScriptEvaluationResultHandlers.find( key );
+  if( handler == mJavaScriptEvaluationResultHandlers.end() )
+  {
+    return;
+  }
+
+  if( handler->second )
+  {
+    std::string stored( result );
+    handler->second( stored );
+  }
+
+  mJavaScriptEvaluationResultHandlers.erase( handler );
+}
+
+void TizenWebEngineChromium::RunJavaScriptMessageHandler( const std::string& objectName, const std::string& message )
+{
+  auto handler = mJavaScriptMessageHandlers.find( objectName );
+  if( handler == mJavaScriptMessageHandlers.end() )
+  {
+    return;
+  }
+
+  handler->second( message );
+}
+} // namespace Plugin
+} // namespace Dali
+
+
+extern "C" DALI_EXPORT_API Dali::WebEnginePlugin* CreateWebEnginePlugin()
+{
+  return new Dali::Plugin::TizenWebEngineChromium();
+}
+
+extern "C" DALI_EXPORT_API void DestroyWebEnginePlugin( Dali::WebEnginePlugin* plugin )
+{
+  if( plugin )
+  {
+    delete plugin;
+  }
+}
diff --git a/dali-extension/web-engine-chromium/tizen-web-engine-chromium.h b/dali-extension/web-engine-chromium/tizen-web-engine-chromium.h
new file mode 100644 (file)
index 0000000..cf1f53f
--- /dev/null
@@ -0,0 +1,355 @@
+#ifndef DALI_TIZEN_WEB_ENGINE_CHROMIUM_H
+#define DALI_TIZEN_WEB_ENGINE_CHROMIUM_H
+
+/*
+ * Copyright (c) 2018 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 <functional>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali/devel-api/adaptor-framework/web-engine-plugin.h>
+#include <dali/public-api/images/native-image-interface.h>
+
+#include <tbm_surface.h>
+#include <unordered_map>
+
+namespace Dali
+{
+namespace Plugin
+{
+
+class WebViewContainerForDali;
+
+/**
+ * @brief The interface class to represent client of corresponding WebView container (WebViewContainerForDali).
+ */
+class WebViewContainerClient
+{
+
+public:
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when surface is updated.
+   * @param [in] buffer The surface
+   */
+  virtual void UpdateImage( tbm_surface_h buffer ) = 0;
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when page loading is started.
+   */
+  virtual void LoadStarted() = 0;
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when page loading is finished.
+   */
+  virtual void LoadFinished() = 0;
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when an error occurs in page loading.
+   * @param [in] url Failing URL for this error
+   * @param [in] errorCode The error code
+   */
+  virtual void LoadError( const char* url, int errorCode ) = 0;
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when it gets JavaScript evalution result.
+   * @param [in] key An unsigned integer representing the result handler
+   * @param [in] result Result string from JavaScript runtime
+   * @see Dali::Plugin::TizenWebEngineChromium::EvaluateJavaScript
+   */
+  virtual void RunJavaScriptEvaluationResultHandler( size_t key, const char* result ) = 0;
+
+  /**
+   * @brief Callback function to be called by WebViewContainer when a message handler is called from JavaScript runtime.
+   * @param [in] objectName Exposed object name of the message handler
+   * @param [in] message Message from JavaScript runtime
+   * @see Dali::Plugin::TizenWebEngineChromium::AddJavaScriptMessageHandler
+   */
+  virtual void RunJavaScriptMessageHandler( const std::string& objectName, const std::string& message ) = 0;
+};
+
+/**
+ * @brief A class implements WebViewContainerClient and Dali::WebEnginePlugin for tizen chromium.
+ */
+class TizenWebEngineChromium : public Dali::WebEnginePlugin, public WebViewContainerClient
+{
+
+public:
+
+  typedef std::function< void(const std::string&) > JavaScriptCallback;
+
+  /**
+   * @brief Constructor.
+   */
+  TizenWebEngineChromium();
+
+  /**
+   * @brief Destructor.
+   */
+  ~TizenWebEngineChromium() override;
+
+
+  // WebEnginePlugin Interface
+
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Create()
+   */
+  void Create( int width, int height, const std::string& locale, const std::string& timezoneID ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Destroy()
+   */
+  void Destroy() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadUrl()
+   */
+  void LoadUrl( const std::string& url ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetNativeImageSource()
+   */
+  NativeImageInterfacePtr GetNativeImageSource() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetUrl()
+   */
+  const std::string& GetUrl() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadHTMLString()
+   */
+  void LoadHTMLString( const std::string& string ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Reload()
+   */
+  void Reload() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::StopLoading()
+   */
+  void StopLoading() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Suspend()
+   */
+  void Suspend() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Resume()
+   */
+  void Resume() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::CanGoForward()
+   */
+  bool CanGoForward() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GoForward()
+   */
+  void GoForward() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::CanGoBack()
+   */
+  bool CanGoBack() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GoBack()
+   */
+  void GoBack() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::EvaluateJavaScript()
+   */
+  void EvaluateJavaScript( const std::string& script, std::function< void( const std::string& ) > resultHandler ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::AddJavaScriptMessageHandler()
+   */
+  void AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void( const std::string& ) > handler ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearHistory()
+   */
+  void ClearHistory() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearCache()
+   */
+  void ClearCache() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearCookies()
+   */
+  void ClearCookies() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetCacheModel()
+   */
+  Dali::WebEnginePlugin::CacheModel GetCacheModel() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetCacheModel()
+   */
+  void SetCacheModel( Dali::WebEnginePlugin::CacheModel cacheModel ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetCookieAcceptPolicy()
+   */
+  Dali::WebEnginePlugin::CookieAcceptPolicy GetCookieAcceptPolicy() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetCookieAcceptPolicy()
+   */
+  void SetCookieAcceptPolicy( Dali::WebEnginePlugin::CookieAcceptPolicy policy ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetUserAgent()
+   */
+  const std::string& GetUserAgent() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetUserAgent()
+   */
+  void SetUserAgent( const std::string& userAgent ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::IsJavaScriptEnabled()
+   */
+  bool IsJavaScriptEnabled() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::EnableJavaScript()
+   */
+  void EnableJavaScript( bool enabled ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::AreImagesAutomaticallyLoaded()
+   */
+  bool AreImagesAutomaticallyLoaded() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadImagesAutomatically()
+   */
+  void LoadImagesAutomatically( bool automatic ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetDefaultTextEncodingName()
+   */
+  const std::string& GetDefaultTextEncodingName() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetDefaultTextEncodingName()
+   */
+  void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetDefaultFontSize()
+   */
+  int GetDefaultFontSize() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetDefaultFontSize()
+   */
+  void SetDefaultFontSize( int defaultFontSize ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetSize()
+   */
+  void SetSize( int width, int height ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SendTouchEvent()
+   */
+  bool SendTouchEvent( const Dali::TouchData& touch ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SendKeyEvent()
+   */
+  bool SendKeyEvent( const Dali::KeyEvent& event ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadStartedSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadFinishedSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadErrorSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal() override;
+
+
+  // WebViewContainerClient Interface
+
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::UpdateImage()
+   */
+  void UpdateImage( tbm_surface_h buffer ) override;
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::LoadStarted()
+   */
+  void LoadStarted() override;
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::LoadFinished()
+   */
+  void LoadFinished() override;
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::LoadError()
+   */
+  void LoadError( const char* url, int errorCode ) override;
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::RunJavaScriptEvaluationResultHandler()
+   */
+  void RunJavaScriptEvaluationResultHandler( size_t key, const char* result ) override;
+
+  /**
+   * @copydoc Dali::Plugin::WebViewContainerClient::RunJavaScriptMessageHandler()
+   */
+  void RunJavaScriptMessageHandler( const std::string& objectName, const std::string& message ) override;
+
+private:
+
+  WebViewContainerForDali*                                mWebViewContainer;
+  Dali::NativeImageSourcePtr                              mDaliImageSrc;
+  std::string                                             mUrl;
+  size_t                                                  mJavaScriptEvaluationCount;
+
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType      mLoadStartedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType      mLoadFinishedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mLoadErrorSignal;
+
+  std::unordered_map< size_t, JavaScriptCallback >        mJavaScriptEvaluationResultHandlers;
+  std::unordered_map< std::string, JavaScriptCallback >   mJavaScriptMessageHandlers;
+};
+} // namespace Plugin
+} // namespace Dali
+
+#endif
diff --git a/dali-extension/web-engine-lwe/file.list b/dali-extension/web-engine-lwe/file.list
new file mode 100644 (file)
index 0000000..f811624
--- /dev/null
@@ -0,0 +1,2 @@
+web_engine_lwe_plugin_src_files = \
+   $(extension_src_dir)/web-engine-lwe/tizen-web-engine-lwe.cpp
diff --git a/dali-extension/web-engine-lwe/tizen-web-engine-lwe.cpp b/dali-extension/web-engine-lwe/tizen-web-engine-lwe.cpp
new file mode 100644 (file)
index 0000000..91fe722
--- /dev/null
@@ -0,0 +1,808 @@
+/*
+ * Copyright (c) 2018 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 "tizen-web-engine-lwe.h"
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/events/touch-data.h>
+#include <dali/devel-api/adaptor-framework/application-devel.h>
+
+#include <unistd.h>
+#include <pthread.h>
+
+#define DB_NAME_LOCAL_STORAGE "LWE_localStorage.db"
+#define DB_NAME_COOKIES "LWE_Cookies.db"
+#define DB_NAME_CACHE "LWE_Cache.db"
+
+// The plugin factories
+extern "C" DALI_EXPORT_API Dali::WebEnginePlugin* CreateWebEnginePlugin( void )
+{
+  return new Dali::Plugin::TizenWebEngineLWE;
+}
+
+extern "C" DALI_EXPORT_API void DestroyWebEnginePlugin( Dali::WebEnginePlugin* plugin )
+{
+  if( plugin != NULL )
+  {
+    delete plugin;
+  }
+}
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+namespace
+{
+
+LWE::KeyValue KeyStringToKeyValue( const char* DALIKeyString, bool isShiftPressed )
+{
+  LWE::KeyValue keyValue = LWE::KeyValue::UnidentifiedKey;
+  if( strcmp( "Left", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::ArrowLeftKey;
+  }
+  else if( strcmp( "Right", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::ArrowRightKey;
+  }
+  else if( strcmp( "Up", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::ArrowUpKey;
+  }
+  else if( strcmp( "Down", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::ArrowDownKey;
+  }
+  else if( strcmp( "space", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::SpaceKey;
+  }
+  else if( strcmp( "Return", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::EnterKey;
+  }
+  else if( strcmp( "BackSpace", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::BackspaceKey;
+  }
+  else if( strcmp( "Escape", DALIKeyString ) == 0 )
+  {
+    keyValue = LWE::KeyValue::EscapeKey;
+  }
+  else if( strcmp( "minus", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::MinusMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::UnderScoreMarkKey;
+    }
+  }
+  else if( strcmp( "equal", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::PlusMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::EqualitySignKey;
+    }
+  }
+  else if( strcmp( "bracketleft", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::LeftCurlyBracketMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::LeftSquareBracketKey;
+    }
+  }
+  else if( strcmp( "bracketright", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::RightCurlyBracketMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::RightSquareBracketKey;
+    }
+  }
+  else if( strcmp( "semicolon", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::ColonMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::SemiColonMarkKey;
+    }
+  }
+  else if( strcmp( "apostrophe", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::DoubleQuoteMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::SingleQuoteMarkKey;
+    }
+  }
+  else if( strcmp( "comma", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::LessThanMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::CommaMarkKey;
+    }
+  }
+  else if( strcmp( "period", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::GreaterThanSignKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::PeriodKey;
+    }
+  }
+  else if( strcmp( "slash", DALIKeyString ) == 0 )
+  {
+    if( isShiftPressed )
+    {
+      keyValue = LWE::KeyValue::QuestionMarkKey;
+    }
+    else
+    {
+      keyValue = LWE::KeyValue::SlashKey;
+    }
+  }
+  else if( strlen( DALIKeyString ) == 1 )
+  {
+    char ch = DALIKeyString[0];
+    if( ch >= '0' && ch <= '9' )
+    {
+      if( isShiftPressed )
+      {
+        switch( ch )
+        {
+          case '1':
+          {
+            keyValue = LWE::KeyValue::ExclamationMarkKey;
+            break;
+          }
+          case '2':
+          {
+            keyValue = LWE::KeyValue::AtMarkKey;
+            break;
+          }
+          case '3':
+          {
+            keyValue = LWE::KeyValue::SharpMarkKey;
+            break;
+          }
+          case '4':
+          {
+            keyValue = LWE::KeyValue::DollarMarkKey;
+            break;
+          }
+          case '5':
+          {
+            keyValue = LWE::KeyValue::PercentMarkKey;
+            break;
+          }
+          case '6':
+          {
+            keyValue = LWE::KeyValue::CaretMarkKey;
+            break;
+          }
+          case '7':
+          {
+            keyValue = LWE::KeyValue::AmpersandMarkKey;
+            break;
+          }
+          case '8':
+          {
+            keyValue = LWE::KeyValue::AsteriskMarkKey;
+            break;
+          }
+          case '9':
+          {
+            keyValue = LWE::KeyValue::LeftParenthesisMarkKey;
+            break;
+          }
+          case '0':
+          {
+            keyValue = LWE::KeyValue::RightParenthesisMarkKey;
+            break;
+          }
+        }
+      }
+      else
+      {
+        keyValue = ( LWE::KeyValue )( LWE::KeyValue::Digit0Key + ch - '0' );
+      }
+    }
+    else if( ch >= 'a' && ch <= 'z' )
+    {
+      int kv = LWE::KeyValue::LowerAKey + ch - 'a';
+      if( isShiftPressed )
+      {
+        kv -= ( 'z' - 'a' );
+        kv -= 7;
+      }
+      keyValue = (LWE::KeyValue)kv;
+    }
+  }
+  return keyValue;
+}
+
+} // unnamed namespace
+
+class Locker
+{
+public:
+  Locker( pthread_mutex_t& lock )
+    : m_lock( lock )
+  {
+    pthread_mutex_lock( &m_lock );
+  }
+
+  ~Locker()
+  {
+    pthread_mutex_unlock( &m_lock );
+  }
+protected:
+  pthread_mutex_t m_lock;
+};
+
+TizenWebEngineLWE::TizenWebEngineLWE()
+: mUrl( "" ),
+  mOutputWidth( 0 ),
+  mOutputHeight( 0 ),
+  mOutputStride( 0 ),
+  mOutputBuffer ( NULL ),
+  mIsMouseLbuttonDown( false ),
+  mCanGoBack( false ),
+  mCanGoForward( false ),
+  mWebContainer( NULL ),
+#ifdef DALI_USE_TBMSURFACE
+  mTbmSurface( NULL ),
+  mNativeImageSourcePtr( NULL ),
+#else
+  mBufferImage( NULL ),
+#endif
+  mUpdateBufferTrigger( MakeCallback( this, &TizenWebEngineLWE::UpdateBuffer ) )
+{
+  pthread_mutex_init( &mOutputBufferMutex, NULL );
+}
+
+TizenWebEngineLWE::~TizenWebEngineLWE()
+{
+  pthread_mutex_destroy( &mOutputBufferMutex );
+}
+
+void TizenWebEngineLWE::UpdateBuffer()
+{
+  Locker l( mOutputBufferMutex );
+
+#ifdef DALI_USE_TBMSURFACE
+  Dali::Stage::GetCurrent().KeepRendering( 0.0f );
+#else
+  if( mBufferImage )
+  {
+    mBufferImage.Update();
+  }
+#endif
+}
+
+void TizenWebEngineLWE::Create( int width, int height, const std::string& locale, const std::string& timezoneId )
+{
+  mOutputWidth = width;
+  mOutputHeight = height;
+  mOutputStride = width * sizeof( uint32_t );
+  mOutputBuffer = ( uint8_t* )malloc( width * height * sizeof( uint32_t ) );
+
+  mOnRenderedHandler = [this]( LWE::WebContainer* c, const LWE::WebContainer::RenderResult& renderResult )
+  {
+    size_t w = mOutputWidth;
+    size_t h = mOutputHeight;
+    if( renderResult.updatedWidth != w || renderResult.updatedHeight != h )
+    {
+      return;
+    }
+    Locker l(mOutputBufferMutex);
+    uint8_t* dstBuffer;
+    size_t dstStride;
+
+#ifdef DALI_USE_TBMSURFACE
+    tbm_surface_info_s tbmSurfaceInfo;
+    if( tbm_surface_map( mTbmSurface, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &tbmSurfaceInfo ) != TBM_SURFACE_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Fail to map tbm_surface\n" );
+    }
+
+    DALI_ASSERT_ALWAYS( tbmSurfaceInfo.format == TBM_FORMAT_ARGB8888 && "Unsupported TizenWebEngineLWE tbm format" );
+    dstBuffer = tbmSurfaceInfo.planes[0].ptr;
+    dstStride = tbmSurfaceInfo.planes[0].stride;
+#else
+    dstBuffer = mBufferImage.GetBuffer();
+    dstStride = mBufferImage.GetBufferStride();
+#endif
+
+    uint32_t srcStride = renderResult.updatedWidth * sizeof(uint32_t);
+    uint8_t* srcBuffer = static_cast< uint8_t* >( renderResult.updatedBufferAddress );
+
+    if( dstStride == srcStride )
+    {
+      memcpy( dstBuffer, srcBuffer, tbmSurfaceInfo.planes[0].size );
+    }
+    else
+    {
+      for ( auto y = renderResult.updatedY; y < ( renderResult.updatedHeight + renderResult.updatedY ); y++ )
+      {
+        auto start = renderResult.updatedX;
+        memcpy( dstBuffer + ( y * dstStride ) + ( start * 4 ), srcBuffer + ( y * srcStride ) + ( start * 4 ), srcStride );
+      }
+    }
+
+#ifdef DALI_USE_TBMSURFACE
+    if( tbm_surface_unmap( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Fail to unmap tbm_surface\n" );
+    }
+#endif
+    mUpdateBufferTrigger.Trigger();
+  };
+
+  mOnReceivedError = []( LWE::WebContainer* container, LWE::ResourceError error ) {
+  };
+
+  mOnPageStartedHandler = []( LWE::WebContainer* container, const std::string& url ) {
+  };
+
+  mOnPageFinishedHandler = []( LWE::WebContainer* container, const std::string& url ) {
+  };
+
+  mOnLoadResourceHandler = []( LWE::WebContainer* container, const std::string& url ) {
+  };
+
+#ifdef DALI_USE_TBMSURFACE
+  mTbmSurface = tbm_surface_create( width, height, TBM_FORMAT_ARGB8888 );
+  mNativeImageSourcePtr = Dali::NativeImageSource::New( mTbmSurface );
+#else
+  mBufferImage = Dali::BufferImage::New( width, height, Dali::Pixel::BGRA8888 );
+#endif
+
+  if( !LWE::LWE::IsInitialized() )
+  {
+    std::string dataPath = DevelApplication::GetDataPath();
+    LWE::LWE::Initialize( ( dataPath + DB_NAME_LOCAL_STORAGE ).c_str(),
+                          ( dataPath + DB_NAME_COOKIES ).c_str(),
+                          ( dataPath + DB_NAME_CACHE ).c_str() );
+  }
+  mWebContainer = LWE::WebContainer::Create( mOutputWidth, mOutputHeight, 1.0, "", locale.data(), timezoneId.data() );
+
+  mWebContainer->RegisterPreRenderingHandler(
+    [this]() -> LWE::WebContainer::RenderInfo {
+
+        if(mOutputBuffer == NULL) {
+            mOutputBuffer = (uint8_t*)malloc( mOutputWidth * mOutputHeight * sizeof(uint32_t));
+            mOutputStride = mOutputWidth * sizeof(uint32_t);
+        }
+
+        ::LWE::WebContainer::RenderInfo result;
+        result.updatedBufferAddress = mOutputBuffer;
+        result.bufferStride = mOutputStride;
+
+        return result;
+    }
+  );
+
+  mWebContainer->RegisterOnRenderedHandler(
+      [ this ]( LWE::WebContainer* container, const LWE::WebContainer::RenderResult& renderResult )
+      {
+        mOnRenderedHandler( container, renderResult );
+      } );
+  mWebContainer->RegisterOnReceivedErrorHandler(
+      [ this ]( LWE::WebContainer* container, LWE::ResourceError error )
+      {
+        mCanGoBack = container->CanGoBack();
+        mCanGoForward = container->CanGoForward();
+        mOnReceivedError( container, error );
+      });
+  mWebContainer->RegisterOnPageStartedHandler(
+      [ this ]( LWE::WebContainer* container, const std::string& url )
+      {
+        mUrl = url;
+        mCanGoBack = container->CanGoBack();
+        mCanGoForward = container->CanGoForward();
+        mOnPageStartedHandler( container, url );
+      });
+  mWebContainer->RegisterOnPageLoadedHandler(
+      [ this ]( LWE::WebContainer* container, const std::string& url )
+      {
+        mUrl = url;
+        mCanGoBack = container->CanGoBack();
+        mCanGoForward = container->CanGoForward();
+        mOnPageFinishedHandler( container, url );
+      });
+  mWebContainer->RegisterOnLoadResourceHandler(
+      [ this ]( LWE::WebContainer* container, const std::string& url )
+      {
+        mUrl = url;
+        mCanGoBack = container->CanGoBack();
+        mCanGoForward = container->CanGoForward();
+        mOnLoadResourceHandler( container, url );
+      });
+
+}
+
+void TizenWebEngineLWE::Destroy()
+{
+  if( !mWebContainer )
+  {
+    return;
+  }
+
+#ifdef DALI_USE_TBMSURFACE
+  if( mTbmSurface != NULL && tbm_surface_destroy( mTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+  {
+    DALI_LOG_ERROR( "Failed to destroy tbm_surface\n" );
+  }
+#endif
+
+  DestroyInstance();
+  mWebContainer = NULL;
+}
+
+void TizenWebEngineLWE::DestroyInstance()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->Destroy();
+}
+
+Dali::NativeImageInterfacePtr TizenWebEngineLWE::GetNativeImageSource()
+{
+  return mNativeImageSourcePtr;
+}
+
+void TizenWebEngineLWE::LoadUrl( const std::string& url )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->LoadURL( url );
+}
+
+const std::string& TizenWebEngineLWE::GetUrl()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  return mUrl;
+}
+
+void TizenWebEngineLWE::LoadHTMLString( const std::string& str )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->LoadData( str );
+}
+
+void TizenWebEngineLWE::Reload()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->Reload();
+}
+
+void TizenWebEngineLWE::StopLoading()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->StopLoading();
+}
+
+void TizenWebEngineLWE::Suspend()
+{
+  // NOT IMPLEMENTED
+}
+
+void TizenWebEngineLWE::Resume()
+{
+  // NOT IMPLEMENTED
+}
+
+void TizenWebEngineLWE::GoBack()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->GoBack();
+}
+
+void TizenWebEngineLWE::GoForward()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->GoForward();
+}
+
+bool TizenWebEngineLWE::CanGoBack()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  return mCanGoBack;
+}
+
+bool TizenWebEngineLWE::CanGoForward()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  return mCanGoForward;
+}
+
+void TizenWebEngineLWE::EvaluateJavaScript( const std::string& script, std::function< void(const std::string&) > resultHandler )
+{
+  // NOT IMPLEMENTED
+}
+
+void TizenWebEngineLWE::AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->AddJavaScriptInterface( exposedObjectName, "postMessage", [handler]( const std::string& data )->std::string {
+    handler( data );
+    return "";
+  } );
+}
+
+void TizenWebEngineLWE::ClearHistory()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->ClearHistory();
+  mCanGoBack = mWebContainer->CanGoBack();
+}
+
+void TizenWebEngineLWE::ClearCache()
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+  mWebContainer->ClearCache();
+}
+
+void TizenWebEngineLWE::ClearCookies()
+{
+  // NOT IMPLEMENTED
+}
+
+Dali::WebEnginePlugin::CacheModel TizenWebEngineLWE::GetCacheModel() const
+{
+  // NOT IMPLEMENTED
+  return Dali::WebEnginePlugin::CacheModel::DOCUMENT_VIEWER;
+}
+
+void TizenWebEngineLWE::SetCacheModel( Dali::WebEnginePlugin::CacheModel cacheModel )
+{
+  // NOT IMPLEMENTED
+}
+
+Dali::WebEnginePlugin::CookieAcceptPolicy TizenWebEngineLWE::GetCookieAcceptPolicy() const
+{
+  // NOT IMPLEMENTED
+  return Dali::WebEnginePlugin::CookieAcceptPolicy::NO_THIRD_PARTY;
+}
+
+void TizenWebEngineLWE::SetCookieAcceptPolicy( Dali::WebEnginePlugin::CookieAcceptPolicy policy )
+{
+  // NOT IMPLEMENTED
+}
+
+const std::string& TizenWebEngineLWE::GetUserAgent() const
+{
+  // NOT IMPLEMENTED
+  static const std::string kEmpty;
+  return kEmpty;
+}
+
+void TizenWebEngineLWE::SetUserAgent( const std::string& userAgent )
+{
+  // NOT IMPLEMENTED
+}
+
+bool TizenWebEngineLWE::IsJavaScriptEnabled() const
+{
+  // NOT IMPLEMENTED
+  return 0;
+}
+
+void TizenWebEngineLWE::EnableJavaScript( bool enabled )
+{
+  // NOT IMPLEMENTED
+}
+
+bool TizenWebEngineLWE::AreImagesAutomaticallyLoaded() const
+{
+  // NOT IMPLEMENTED
+  return 0;
+}
+
+void TizenWebEngineLWE::LoadImagesAutomatically( bool automatic )
+{
+  // NOT IMPLEMENTED
+}
+
+const std::string& TizenWebEngineLWE::GetDefaultTextEncodingName() const
+{
+  // NOT IMPLEMENTED
+  static const std::string kEmpty;
+  return kEmpty;
+}
+
+void TizenWebEngineLWE::SetDefaultTextEncodingName( const std::string& defaultTextEncodingName )
+{
+  // NOT IMPLEMENTED
+}
+
+int TizenWebEngineLWE::GetDefaultFontSize() const
+{
+  // NOT IMPLEMENTED
+  return 0;
+}
+
+void TizenWebEngineLWE::SetDefaultFontSize( int defaultFontSize )
+{
+  // NOT IMPLEMENTED
+}
+
+void TizenWebEngineLWE::SetSize( int width, int height )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  if( mOutputWidth != ( size_t )width || mOutputHeight != ( size_t )height )
+  {
+    mOutputWidth = width;
+    mOutputHeight = height;
+    mOutputStride = width * sizeof(uint32_t);
+
+#ifdef DALI_USE_TBMSURFACE
+    tbm_surface_h prevTbmSurface = mTbmSurface;
+    mTbmSurface = tbm_surface_create( width, height, TBM_FORMAT_ARGB8888 );
+    Dali::Any source( mTbmSurface );
+    mNativeImageSourcePtr->SetSource( source );
+    if( prevTbmSurface != NULL && tbm_surface_destroy( prevTbmSurface ) != TBM_SURFACE_ERROR_NONE )
+    {
+      DALI_LOG_ERROR( "Failed to destroy tbm_surface\n" );
+    }
+#endif
+
+    auto oldOutputBuffer = mOutputBuffer;
+    mOutputBuffer = ( uint8_t* )malloc( mOutputWidth * mOutputHeight * sizeof( uint32_t ) );
+    mOutputStride = mOutputWidth * sizeof( uint32_t );
+    mWebContainer->ResizeTo( mOutputWidth, mOutputHeight );
+
+    if( oldOutputBuffer ) {
+        free(oldOutputBuffer);
+    }
+  }
+}
+
+void TizenWebEngineLWE::DispatchMouseDownEvent( float x, float y )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchMouseDownEvent( LWE::MouseButtonValue::LeftButton, LWE::MouseButtonsValue::LeftButtonDown, x, y );
+}
+
+void TizenWebEngineLWE::DispatchMouseUpEvent( float x, float y )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchMouseUpEvent( LWE::MouseButtonValue::NoButton, LWE::MouseButtonsValue::NoButtonDown, x, y );
+}
+
+void TizenWebEngineLWE::DispatchMouseMoveEvent( float x, float y, bool isLButtonPressed, bool isRButtonPressed )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchMouseMoveEvent(
+    isLButtonPressed ? LWE::MouseButtonValue::LeftButton
+    : LWE::MouseButtonValue::NoButton,
+    isLButtonPressed ? LWE::MouseButtonsValue::LeftButtonDown
+    : LWE::MouseButtonsValue::NoButtonDown, x, y );
+}
+
+bool TizenWebEngineLWE::SendTouchEvent( const TouchData& touch )
+{
+  size_t pointCount = touch.GetPointCount();
+  if( pointCount == 1 )
+  {
+    // Single touch event
+    Dali::PointState::Type pointState = touch.GetState( 0 );
+    const Dali::Vector2& screen = touch.GetLocalPosition( 0 );
+
+    if( pointState == Dali::PointState::DOWN )
+    {
+      DispatchMouseDownEvent( screen.x, screen.y );
+      mIsMouseLbuttonDown = true;
+    }
+    else if( pointState == Dali::PointState::UP )
+    {
+      DispatchMouseUpEvent( screen.x, screen.y );
+      mIsMouseLbuttonDown = false;
+    }
+    else
+    {
+      DispatchMouseMoveEvent( screen.x, screen.y, mIsMouseLbuttonDown, false );
+    }
+  }
+
+  return false;
+}
+
+void TizenWebEngineLWE::DispatchKeyDownEvent( LWE::KeyValue keyCode )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchKeyDownEvent( keyCode );
+}
+
+void TizenWebEngineLWE::DispatchKeyPressEvent( LWE::KeyValue keyCode )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchKeyPressEvent( keyCode );
+}
+
+void TizenWebEngineLWE::DispatchKeyUpEvent( LWE::KeyValue keyCode )
+{
+  DALI_ASSERT_ALWAYS( mWebContainer );
+
+  mWebContainer->DispatchKeyUpEvent(keyCode);
+}
+
+bool TizenWebEngineLWE::SendKeyEvent( const Dali::KeyEvent& event )
+{
+  LWE::KeyValue keyValue = LWE::KeyValue::UnidentifiedKey;
+  if( 32 < event.keyPressed.c_str()[0] && 127 > event.keyPressed.c_str()[0] )
+  {
+    keyValue = static_cast<LWE::KeyValue>( event.keyPressed.c_str()[0] );
+  }
+  else
+  {
+    keyValue = KeyStringToKeyValue( event.keyPressedName.c_str(), event.keyModifier & 1 );
+  }
+  if( event.state == Dali::KeyEvent::Down )
+  {
+    DispatchKeyDownEvent( keyValue );
+    DispatchKeyPressEvent( keyValue );
+  }
+  else if( event.state == Dali::KeyEvent::Up )
+  {
+    DispatchKeyUpEvent( keyValue );
+  }
+
+  return false;
+}
+
+} // namespace Plugin
+} // namespace Dali
diff --git a/dali-extension/web-engine-lwe/tizen-web-engine-lwe.h b/dali-extension/web-engine-lwe/tizen-web-engine-lwe.h
new file mode 100644 (file)
index 0000000..2168115
--- /dev/null
@@ -0,0 +1,321 @@
+#ifndef DALI_TIZEN_WEB_ENGINE_LWE_H
+#define DALI_TIZEN_WEB_ENGINE_LWE_H
+
+/*
+ * Copyright (c) 2018 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 <string.h>
+#include <vector>
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
+#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/adaptor-framework/native-image-source.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/devel-api/adaptor-framework/web-engine-plugin.h>
+#include <LWEWebView.h>
+#include <list>
+
+#ifndef DALI_USE_TBMSURFACE
+#define DALI_USE_TBMSURFACE
+#endif
+
+#ifdef DALI_USE_TBMSURFACE
+#include <tbm_surface.h>
+#else
+#include <dali/public-api/images/buffer-image.h>
+#endif
+
+namespace Dali
+{
+
+namespace Plugin
+{
+
+/**
+ * @brief Implementation of the Tizen WebEngineLWE class which has Tizen platform dependency.
+ */
+class TizenWebEngineLWE : public Dali::WebEnginePlugin, public Dali::ConnectionTracker
+{
+public:
+
+  /**
+   * @brief Constructor.
+   */
+  TizenWebEngineLWE();
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~TizenWebEngineLWE();
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Create()
+   */
+  void Create( int width, int height, const std::string& locale, const std::string& timezoneId ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Destroy()
+   */
+  void Destroy() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetNativeImageSource()
+   */
+  Dali::NativeImageInterfacePtr GetNativeImageSource() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadUrl()
+   */
+  void LoadUrl( const std::string& url ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetUrl()
+   */
+  const std::string& GetUrl() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadHTMLString()
+   */
+  void LoadHTMLString( const std::string& string ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Reload()
+   */
+  void Reload() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::StopLoading()
+   */
+  void StopLoading() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Suspend()
+   */
+  void Suspend() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::Resume()
+   */
+  void Resume() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GoBack()
+   */
+  void GoBack() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GoForward()
+   */
+  void GoForward() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::CanGoBack()
+   */
+  bool CanGoBack() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::CanGoForward()
+   */
+  bool CanGoForward() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::EvaluateJavaScript()
+   */
+  void EvaluateJavaScript( const std::string& script, std::function< void(const std::string&) > resultHandler ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::AddJavaScriptMessageHandler()
+   */
+  void AddJavaScriptMessageHandler( const std::string& exposedObjectName, std::function< void(const std::string&) > handler ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearHistory()
+   */
+  void ClearHistory() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearCache()
+   */
+  void ClearCache() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::ClearCookies()
+   */
+  void ClearCookies() override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetCacheModel()
+   */
+  Dali::WebEnginePlugin::CacheModel GetCacheModel() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetCacheModel()
+   */
+  void SetCacheModel( Dali::WebEnginePlugin::CacheModel cacheModel ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetCookieAcceptPolicy()
+   */
+  Dali::WebEnginePlugin::CookieAcceptPolicy GetCookieAcceptPolicy() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetCookieAcceptPolicy()
+   */
+  void SetCookieAcceptPolicy( Dali::WebEnginePlugin::CookieAcceptPolicy policy ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetUserAgent()
+   */
+  const std::string& GetUserAgent() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetUserAgent()
+   */
+  void SetUserAgent( const std::string& userAgent ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::IsJavaScriptEnabled()
+   */
+  bool IsJavaScriptEnabled() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::EnableJavaScript()
+   */
+  void EnableJavaScript( bool enabled ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::AreImagesAutomaticallyLoaded()
+   */
+  bool AreImagesAutomaticallyLoaded() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::LoadImagesAutomatically()
+   */
+  void LoadImagesAutomatically( bool automatic ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetDefaultTextEncodingName()
+   */
+  const std::string& GetDefaultTextEncodingName() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetDefaultTextEncodingName()
+   */
+  void SetDefaultTextEncodingName( const std::string& defaultTextEncodingName ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::GetDefaultFontSize()
+   */
+  int GetDefaultFontSize() const override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetDefaultFontSize()
+   */
+  void SetDefaultFontSize( int defaultFontSize ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SetSize()
+   */
+  void SetSize( int width, int height ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SendTouchEvent()
+   */
+  bool SendTouchEvent( const Dali::TouchData& touch ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::SendKeyEvent()
+   */
+  bool SendKeyEvent( const Dali::KeyEvent& event ) override;
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadStartedSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadStartedSignal() override
+  {
+    return mPageLoadStartedSignal;
+  }
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadFinishedSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType& PageLoadFinishedSignal() override
+  {
+    return mPageLoadFinishedSignal;
+  }
+
+  /**
+   * @copydoc Dali::WebEnginePlugin::PageLoadErrorSignal()
+   */
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType& PageLoadErrorSignal() override
+  {
+    return mPageLoadErrorSignal;
+  }
+
+private:
+
+  void UpdateBuffer();
+
+  void DestroyInstance();
+
+  void DispatchMouseDownEvent(float x, float y);
+
+  void DispatchMouseUpEvent(float x, float y);
+
+  void DispatchMouseMoveEvent(float x, float y, bool isLButtonPressed, bool isRButtonPressed);
+
+  void DispatchKeyDownEvent(LWE::KeyValue keyCode);
+
+  void DispatchKeyPressEvent(LWE::KeyValue keyCode);
+
+  void DispatchKeyUpEvent(LWE::KeyValue keyCode);
+
+private:
+
+  std::string                mUrl;
+  size_t                     mOutputWidth;
+  size_t                     mOutputHeight;
+  size_t                     mOutputStride;
+  uint8_t*                   mOutputBuffer;
+  bool                       mIsMouseLbuttonDown;
+  bool                       mCanGoBack;
+  bool                       mCanGoForward;
+  pthread_mutex_t            mOutputBufferMutex;
+  LWE::WebContainer*         mWebContainer;
+#ifdef DALI_USE_TBMSURFACE
+  tbm_surface_h              mTbmSurface;
+  Dali::NativeImageSourcePtr mNativeImageSourcePtr;
+#else
+  Dali::BufferImage          mBufferImage;
+#endif
+
+  std::function<void(LWE::WebContainer*, const LWE::WebContainer::RenderResult&)> mOnRenderedHandler;
+  std::function<void(LWE::WebContainer*, LWE::ResourceError)> mOnReceivedError;
+  std::function<void(LWE::WebContainer*, const std::string&)> mOnPageFinishedHandler;
+  std::function<void(LWE::WebContainer*, const std::string&)> mOnPageStartedHandler;
+  std::function<void(LWE::WebContainer*, const std::string&)> mOnLoadResourceHandler;
+
+  EventThreadCallback                                     mUpdateBufferTrigger;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType      mPageLoadStartedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType      mPageLoadFinishedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType mPageLoadErrorSignal;
+};
+
+} // namespace Plugin
+} // namespace Dali;
+
+#endif
diff --git a/packaging/dali-extension.spec b/packaging/dali-extension.spec
new file mode 100755 (executable)
index 0000000..3bbab53
--- /dev/null
@@ -0,0 +1,379 @@
+# NOTES
+# This spec file is used to build DALi Extensions
+#
+# gbs will try to download the build.conf for the platform automatically from the repo location when
+# performing a gbs build ( use gbs build -v to see it download location) E.g.
+# http://download.tizen.org/snapshots/tizen/tv/tizen-tv/repos/arm-wayland/packages/repodata/xxxx-build.conf.gz
+
+Name:       dali-extension
+Summary:    The DALi Tizen Extensions
+Version:    1.5.8
+Release:    1
+Group:      System/Libraries
+License:    Apache-2.0 and BSD-3-Clause and MIT
+URL:        https://review.tizen.org/git/?p=platform/core/uifw/dali-extensions.git;a=summary
+Source0:    %{name}-%{version}.tar.gz
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+BuildRequires:  pkgconfig
+BuildRequires:  pkgconfig(dali-core)
+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
+
+%if 0%{?tizen_version_major} >= 4
+%define tizen_40_or_greater 1
+%endif
+
+%if 0%{?tizen_version_major} >= 5
+%define tizen_50_or_greater 1
+%endif
+
+%if ( 0%{?tizen_version_major} == 5 && 0%{?tizen_version_minor} >= 5 ) || 0%{?tizen_version_major} >= 6
+%define tizen_55_or_greater 1
+%endif
+
+# # Note
+# %if 0%{?tizen_version_major} >= 6
+# %define tizen_60_or_greater 1
+# %endif
+
+##############################
+# devel
+##############################
+%package devel
+Summary:    Development components for the DALi Extension
+Group:      Development/Building
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Development components for the DALi Tizen Extensions - public headers and package configs
+
+##############################
+# Dali Key Extension
+##############################
+
+%package key-extension
+Summary:    Plugin to support extension keys for Dali
+Group:      System/Libraries
+
+%description key-extension
+Plugin to support extension keys for Dali
+
+##############################
+# Dali VideoPlayer Plugin
+##############################
+
+%package video-player-plugin
+Summary:    Plugin to play a video file for Dali
+Group:      System/Libraries
+BuildRequires: pkgconfig(capi-media-player)
+BuildRequires: pkgconfig(capi-system-info)
+# dali-adaptor uses ecore mainloop
+%if 0%{?tizen_version_major} >= 5
+BuildRequires:  pkgconfig(ecore-wl2)
+%else
+BuildRequires:  pkgconfig(ecore-wayland)
+%endif
+
+%description video-player-plugin
+VideoPlayer plugin to play a video file for Dali
+
+##############################
+# Dali Web Engine chromium Plugin
+##############################
+
+%package web-engine-chromium-plugin
+Summary:    Plugin to support WebView for Dali
+Group:      System/Libraries
+%if 0%{?tizen_55_or_greater}
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(chromium-efl)
+BuildRequires: pkgconfig(elementary)
+%endif
+
+%description web-engine-chromium-plugin
+Web Engine chromium plugin to support WebView for Dali
+
+##############################
+# Dali Image Loader Plugin
+##############################
+
+%package image-loader-plugin
+Summary:    Plugin to image loading for Dali
+Group:      System/Libraries
+
+%description image-loader-plugin
+Image Loader plugin to image loading file for Dali
+
+####################################
+# Vector Animation Renderer Plugin
+####################################
+%package vector-animation-renderer-plugin
+Summary:    Plugin to render a vector animation
+Group:      System/Libraries
+%if 0%{?tizen_55_or_greater}
+BuildRequires:  pkgconfig(rlottie)
+%endif
+
+%description vector-animation-renderer-plugin
+Plugin to render a vector animation
+
+####################################
+# color controller Plugin
+####################################
+
+%package color-controller-plugin
+Summary:    Plugin to load color theme
+Group:      System/Libraries
+
+%description color-controller-plugin
+Plugin to load color theme
+
+##############################
+# Dali Web Engine LWE Plugin
+##############################
+
+%package web-engine-lwe-plugin
+Summary:    Plugin to support WebView for Dali
+Group:      System/Libraries
+%if 0%{?tizen_55_or_greater}
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(lightweight-web-engine)
+%endif
+
+%description web-engine-lwe-plugin
+Web Engine LWE(Light-weight Web Engine) plugin to support WebView for Dali
+
+##############################
+# Preparation
+##############################
+%prep
+%setup -q
+
+#Use TZ_PATH when tizen version is 3.x or greater
+
+%define dali_data_rw_dir         %TZ_SYS_RO_SHARE/dali/
+%define dali_data_ro_dir         %TZ_SYS_RO_SHARE/dali/
+%define dev_include_path %{_includedir}
+
+# Use Image Loader Plugin
+%define use_image_loader 0
+
+##############################
+# Build
+##############################
+%build
+PREFIX+="/usr"
+CXXFLAGS+=" -Wall -g -Os -fPIC -fvisibility-inlines-hidden -fdata-sections -ffunction-sections -DGL_GLEXT_PROTOTYPES"
+LDFLAGS+=" -Wl,--rpath=%{_libdir} -Wl,--as-needed -Wl,--gc-sections -Wl,-Bsymbolic-functions "
+
+%if 0%{?tizen_version_major} >= 5
+CFLAGS+=" -DECORE_WL2 -DEFL_BETA_API_SUPPORT"
+CXXFLAGS+=" -DECORE_WL2 -DEFL_BETA_API_SUPPORT"
+configure_flags="--enable-ecore-wl2"
+%endif
+
+libtoolize --force
+cd %{_builddir}/%{name}-%{version}/build/tizen
+autoreconf --install
+
+%configure --prefix=$PREFIX \
+%if 0%{?tizen_50_or_greater}
+           --with-tizen-50-or-greater \
+%endif
+%if 0%{?tizen_55_or_greater}
+           --with-tizen-55-or-greater \
+%endif
+           --enable-ecore-wl2 \
+           --enable-keyextension
+%if 0%{?use_image_loader}
+%configure \
+           --enable-imageloader-extension
+%endif
+
+make %{?jobs:-j%jobs}
+
+##############################
+# Installation
+##############################
+%install
+rm -rf %{buildroot}
+
+# install dali.sh
+mkdir -p %{buildroot}%{_sysconfdir}/profile.d
+install -m 0644 scripts/dali.sh %{buildroot}%{_sysconfdir}/profile.d
+
+cd build/tizen
+%make_install DALI_DATA_RW_DIR="%{dali_data_rw_dir}" DALI_DATA_RO_DIR="%{dali_data_ro_dir}"
+
+%pre
+exit 0
+
+##############################
+#  Post Install new package
+##############################
+%post
+/sbin/ldconfig
+exit 0
+
+%post key-extension
+/sbin/ldconfig
+exit 0
+
+%post video-player-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%post web-engine-chromium-plugin
+pushd %{_libdir}
+ln -sf libdali-web-engine-chromium-plugin.so libdali-web-engine-plugin.so
+popd
+/sbin/ldconfig
+exit 0
+%endif
+
+%post image-loader-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%post vector-animation-renderer-plugin
+/sbin/ldconfig
+exit 0
+%endif
+
+%post color-controller-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%post web-engine-lwe-plugin
+/sbin/ldconfig
+exit 0
+%endif
+
+##############################
+#   Pre Uninstall old package
+##############################
+%preun
+exit 0
+
+##############################
+#   Post Uninstall old package
+##############################
+%postun
+/sbin/ldconfig
+exit 0
+
+%postun key-extension
+/sbin/ldconfig
+exit 0
+
+%postun video-player-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%postun web-engine-chromium-plugin
+/sbin/ldconfig
+exit 0
+%endif
+
+%postun image-loader-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%postun vector-animation-renderer-plugin
+/sbin/ldconfig
+exit 0
+%endif
+
+%postun color-controller-plugin
+/sbin/ldconfig
+exit 0
+
+%if 0%{?tizen_55_or_greater}
+%postun web-engine-lwe-plugin
+/sbin/ldconfig
+exit 0
+%endif
+
+##############################
+# Files in Binary Packages
+##############################
+
+%files
+%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}/*
+%{_libdir}/pkgconfig/*.pc
+
+%files key-extension
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-key-extension.so*
+%license LICENSE
+
+%files video-player-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-video-player-plugin.so*
+%license LICENSE
+
+%if 0%{?tizen_55_or_greater}
+%files web-engine-chromium-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-web-engine-chromium-plugin.so*
+%license LICENSE
+%endif
+
+%if 0%{?use_image_loader}
+%files image-loader-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-image-loader-plugin.so*
+%license LICENSE
+%endif
+
+%if 0%{?tizen_55_or_greater}
+%files vector-animation-renderer-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-vector-animation-renderer-plugin.so*
+%license LICENSE
+%endif
+
+%files color-controller-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-color-controller-plugin.so*
+%license LICENSE
+
+%if 0%{?tizen_55_or_greater}
+%files web-engine-lwe-plugin
+%manifest dali-extension.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libdali-web-engine-lwe-plugin.so*
+%license LICENSE
+%endif
diff --git a/scripts/dali.sh b/scripts/dali.sh
new file mode 100644 (file)
index 0000000..594cf23
--- /dev/null
@@ -0,0 +1,134 @@
+# This script set environment value for dali
+
+# 1. Introduction
+#  this script is executed when device is booted.
+#  when device is booted, environment values are applied across system wide.
+#  it means every dali applications are affected to this script.
+#  if developer want specific environment value,
+#  please remove '#' from the desired environment value and reboot to apply the changes
+
+# 2. Example
+
+# @ Enable ttrace for checking
+#  This environment value can enable ttrace
+#
+#   DALI_PERFORMANCE_TIMESTAMP_OUTPUT=4
+#
+#  Where timestamped events for update/render/event and custom events are output.
+#  See TimeStampOutput in performance-interface.h for values
+#
+#   0:NO_TIME_STAMP_OUTPUT, 1:OUTPUT_DALI_LOG, 2:OUTPUT_KERNEL_TRACE, 4:OUTPUT_SYSTEM_TRACE, 8:OUTPUT_NETWORK
+
+#export DALI_PERFORMANCE_TIMESTAMP_OUTPUT=4
+
+
+# @ Enable log for checking performance
+#  What performance statistics are logged out to dlog
+#  see StatisticsLogOptions in performance-interface.h for values
+#
+#   0:DISABLED, 1:LOG_EVERYTHING, 2:LOG_UPDATE_RENDER, 4:LOG_EVENT_PROCESS, 8:LOG_CUSTOM_MARKERS
+
+#export DALI_LOG_PERFORMANCE_STAT=1
+
+
+# @ Allow control and monitoring of DALi via the network
+#export DALI_NETWORK_CONTROL=1
+
+# @ environment variable for enabling/disabling fps tracking
+#export DALI_FPS_TRACKING=1
+#export DALI_UPDATE_STATUS_INTERVAL=1
+#export DALI_OBJECT_PROFILER_INTERVAL=1
+
+# @ Set the the graphics status time
+#export DALI_GLES_CALL_TIME=5
+
+# @ Whether or not to accumulate gles call statistics
+#export DALI_GLES_CALL_ACCUMULATE=1
+
+# @ Set dali window status
+#export DALI_WINDOW_WIDTH=400
+#export DALI_WINDOW_HEIGHT=400
+#export DALI_WINDOW_NAME=DALI_ENV_WINDOW
+#export DALI_WINDOW_CLASS_NAME=DALI_ENV_CLASS
+
+# @ Set the rate of render refresh
+#export DALI_REFRESH_RATE=30
+
+# @ Set the number of samples required in multisample buffers
+#export DALI_MULTI_SAMPLING_LEVEL=4
+
+# @ Set the maximum texture size that GL can handle
+#export DALI_MAX_TEXTURE_SIZE=512
+
+# @ Set the mode of indicator visible
+#  IndicatorVisibleMode
+#  {
+#    INVISIBLE = 0, ///< Hide indicator
+#    VISIBLE = 1, ///< Show indicator
+#    AUTO = 2 ///< Hide in default, will show when necessary
+#  };
+#export DALI_INDICATOR_VISIBLE_MODE=1
+
+# @ Set the number of frames
+#  The number of frames that are going to be rendered into the Frame Buffer Object
+#  but the last one which is going to be rendered into the Frame Buffer.
+#export DALI_RENDER_TO_FBO=2
+
+# @ Disable depth buffer
+#export DALI_DISABLE_DEPTH_BUFFER=1
+
+# @ Disable stencil buffer
+#export DALI_DISABLE_STENCIL_BUFFER=1
+
+# @ Set the configuration of Pan-Gesture
+# @ Prediction Modes 1 & 2:
+
+# @ prediction mode for pan gestures
+#export DALI_PAN_PREDICTION_MODE=1
+#export DALI_PAN_PREDICTION_AMOUNT=1
+#export DALI_PAN_SMOOTHING_MODE=1
+
+# @ Prediction Mode 1:
+#export DALI_PAN_MAX_PREDICTION_AMOUNT=1
+#export DALI_PAN_MIN_PREDICTION_AMOUNT=1
+#export DALI_PAN_PREDICTION_AMOUNT_ADJUSTMENT=1
+#export DALI_PAN_SMOOTHING_AMOUNT=1
+
+# @ Prediction Mode 2 :
+#export DALI_PAN_USE_ACTUAL_TIMES=1
+#export DALI_PAN_INTERPOLATION_TIME_RANGE=1
+#export DALI_PAN_SCALAR_ONLY_PREDICTION_ENABLED=1
+#export DALI_PAN_TWO_POINT_PREDICTION_ENABLED=1
+#export DALI_PAN_TWO_POINT_PAST_INTERPOLATE_TIME=1
+#export DALI_PAN_TWO_POINT_VELOCITY_BIAS=1
+#export DALI_PAN_TWO_POINT_ACCELERATION_BIAS=1
+#export DALI_PAN_MULTITAP_SMOOTHING_RANGE=1
+
+# @ Pan-Gesture miscellaneous :
+#export DALI_LOG_PAN_GESTURE=1
+#export DALI_PAN_MINIMUM_DISTANCE=1
+#export DALI_PAN_MINIMUM_EVENTS=1
+
+
+# @ Enable filter for checking detail log
+#  If you enable filter, you can check detail log.
+#  but for use it, you need to build dali pkg using debug option
+#
+#   gbs build -A armv7l --include-al --define "%enable_debug 1"
+#
+#  After build and install dali pkg using debug option, you can enable the filter you want.
+#  Most filters set 0 level, so you need to set 1~3 level using environment value.
+#
+#   enum LogLevel
+#   {
+#   NoLogging   = 0,
+#   Concise     = 1,
+#   General     = 2,
+#   Verbose     = 3
+#   };
+
+#export LOG_KEYBOARD_FOCUS_MANAGER=3
+#export LOG_TEXT_RENDERING=3
+#export LOG_WINDOW=3
+
+