AC_CONFIG_SUBDIRS(web-engine-chromium)
AC_CONFIG_SUBDIRS(web-engine-lwe)
fi
+AC_CONFIG_SUBDIRS(evas-plugin)
devincludepath=${includedir}
AC_SUBST(devincludepath)
Name: DALi extension
Description: The DALi extension Libaray
Version: @DALI_EXTENSION_VERSION@
-Requires: dali-toolkit
+Requires: dali-adaptor dali-toolkit
Libs: -L${libdir} -ldali-extension
Cflags: -I${includedir}/dali-extension
--- /dev/null
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Build the Dali evas plugin
+
+extension_src_dir = ../../../dali-extension
+
+# evas-plugin
+include ../../../dali-extension/devel-api/evas-plugin/file.list
+include ../../../dali-extension/internal/evas-plugin/file.list
+
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libdali-extension.la
+
+# Todo Evas plugin separation
+libdali_extension_la_SOURCES = \
+ $(evas_plugin_public_src_files) \
+ $(evas_plugin_internal_src_files)
+
+libdali_extension_la_DEPENDENCIES =
+
+libdali_extension_la_CXXFLAGS = \
+ $(DLOG_CFLAGS) \
+ $(DALI_ADAPTOR_INTEGRATION_CFLAGS) \
+ $(ELEMENTARY_CFLAGS) \
+ $(EVAS_CFLAGS) \
+ $(WAYLAND_CFLAGS) \
+ -DEFL_BETA_API_SUPPORT \
+ -I../../../ \
+ -Werror -Wall
+
+libdali_extension_la_LIBADD = \
+ $(DLOG_LIBS) \
+ $(DALI_ADAPTOR_INTEGRATION_LIBS) \
+ $(ELEMENTARY_LIBS) \
+ $(EVAS_LIBS) \
+ $(WAYLAND_LIBS)
+
+libdali_extension_la_LDFLAGS = \
+ -rdynamic
+
+#install headers
+dali_extensiondir = $(devincludepath)/dali-extension
+dali_extension_HEADERS = ../../../dali-extension/dali-extension.h
+
+dali_extension_evasplugindir = $(devincludepath)/dali-extension/devel-api/evas-plugin
+dali_extension_evasplugin_HEADERS = $(evas_plugin_public_header_files)
--- /dev/null
+4_define([dali_version],[0.1.0])
+AC_INIT([dali], [dali_version])
+AM_INIT_AUTOMAKE([-Wall foreign])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CXX
+AC_PROG_LIBTOOL
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+LT_INIT
+
+DALI_EXTENSION_VERSION=dali_version
+AC_SUBST(DALI_EXTENSION_VERSION)
+
+# For evas-plugin
+PKG_CHECK_MODULES(DALI_ADAPTOR_INTEGRATION, dali-adaptor-integration)
+PKG_CHECK_MODULES(ELEMENTARY, elementary)
+PKG_CHECK_MODULES(EVAS, evas)
+PKG_CHECK_MODULES(WAYLAND, [ecore-wl2])
+
+devincludepath=${includedir}
+AC_SUBST(devincludepath)
+
+AC_CONFIG_FILES([
+Makefile
+])
+
+AC_OUTPUT
--- /dev/null
+#ifndef __DALI_EXTENSION_H__
+#define __DALI_EXTENSION_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+#endif // __DALI_EXTENSION_H__
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-plugin.h"
+
+// INTERNAL INCLUDES
+#include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+EvasPlugin EvasPlugin::New(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+{
+ Internal::EvasPluginPtr internal = Internal::EvasPlugin::New(parentEvasObject, width, height, transparent);
+ return EvasPlugin(internal.Get());
+}
+
+EvasPlugin::EvasPlugin()
+{
+}
+
+EvasPlugin::EvasPlugin(const EvasPlugin& evasPlugin)
+: BaseHandle(evasPlugin)
+{
+}
+
+EvasPlugin& EvasPlugin::operator=(const EvasPlugin& evasPlugin)
+{
+ if (*this != evasPlugin)
+ {
+ BaseHandle::operator=(evasPlugin);
+ }
+ return *this;
+}
+
+EvasPlugin::~EvasPlugin()
+{
+}
+
+void EvasPlugin::Run()
+{
+ Internal::GetImplementation(*this).Run();
+}
+
+void EvasPlugin::Pause()
+{
+ Internal::GetImplementation(*this).Pause();
+}
+
+void EvasPlugin::Resume()
+{
+ Internal::GetImplementation(*this).Resume();
+}
+
+void EvasPlugin::Stop()
+{
+ Internal::GetImplementation(*this).Stop();
+}
+
+Evas_Object* EvasPlugin::GetDaliAccessEvasObject()
+{
+ return Internal::GetImplementation(*this).GetDaliAccessEvasObject();
+}
+
+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
--- /dev/null
+#ifndef __DALI_EXTENSION_EVAS_PLUGIN_H__
+#define __DALI_EXTENSION_EVAS_PLUGIN_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * @addtogroup CAPI_DALI_EXTENSION_FRAMEWORK_MODULE
+ * @{
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/signals/dali-signal.h>
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+class EvasPlugin;
+}
+
+/**
+ * @brief Application class used by EFL applications that wish to use Dali
+ *
+ * An EvasPlugin class object should be created by EFL applications
+ * that wish to use Dali. It provides a means for initializing the
+ * resources required by the Dali::Core.
+ *
+ * The EvasPlugin class emits several signals which the user can
+ * connect to. The user should not create any Dali objects in the main
+ * function and instead should connect to the Init signal of the
+ * EvasPlugin and create the Dali objects in the connected callback.
+ *
+ * Tizen and EFL applications should follow the example below:
+ *
+ * @code
+ * #include <app.h>
+ * #include <app_extension.h>
+ * #include <Elementary.h>
+ *
+ * #include <dali/dali.h>
+ * #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
+ * #include <dali-extension/dali-extension.h>
+ *
+ * using namespace Dali;
+ * using namespace Dali::Toolkit;
+ * using namespace Dali::Extension;
+ *
+ * namespace
+ * {
+ * const char* const APPLICATION_TITLE = "EvasPluginExample";
+ * const int EVAS_PLUGIN_WIDTH = 480;
+ * const int EVAS_PLUGIN_HEIGHT = 800;
+ * }
+ *
+ * class DaliApplication : public ConnectionTracker
+ * {
+ * public:
+ * DaliApplication(EvasPlugin evasPlugin)
+ * : mEvasPlugin(evasPlugin)
+ * {
+ * mEvasPlugin.InitSignal().Connect(this, &DaliApplication::OnInitialize);
+ * mEvasPlugin.Run();
+ * }
+ *
+ * ~DaliApplication()
+ * {
+ * mEvasPlugin.Stop();
+ * }
+ *
+ * void OnInitialize(EvasPlugin& evasPlugin)
+ * {
+ * Stage stage = Stage::GetCurrent();
+ *
+ * TextLabel textLabel = TextLabel::New( "Hello World" );
+ * textLabel.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ * textLabel.SetName( "helloWorldLabel" );
+ * stage.Add( textLabel );
+ * }
+ *
+ * private:
+ * EvasPlugin mEvasPlugin;
+ * };
+ *
+ * struct app_data
+ * {
+ * Evas_Object* elm_win;
+ * DaliApplication* daliApplication;
+ * };
+ *
+ * static void win_del(void *data, Evas_Object * obj, void *event_info)
+ * {
+ * }
+ *
+ * static bool app_create(void *data)
+ * {
+ * struct app_data* ad = (struct app_data*)data;
+ *
+ * // Sets the GL backend for rendering
+ * elm_config_accel_preference_set("3d");
+ *
+ * // Creates the elm window
+ * ad->elm_win = elm_win_add(NULL, APPLICATION_TITLE, ELM_WIN_BASIC);
+ *
+ * DALI_ASSERT_ALWAYS(ad->elm_win != NULL && "Fail to create elm window.");
+ *
+ * elm_win_title_set(ad->elm_win, APPLICATION_TITLE);
+ * elm_win_rotation_with_resize_set(ad->elm_win, 0);
+ * evas_object_smart_callback_add(ad->elm_win, "delete,request", win_del, ad->elm_win);
+ * evas_object_show(ad->elm_win);
+ *
+ * // Adds the background
+ * Evas_Object* bg = elm_bg_add(ad->elm_win);
+ * elm_bg_color_set(bg, 255, 255, 255);
+ * evas_object_size_hint_weight_set(bg, 0,0);
+ * elm_win_resize_object_add(ad->elm_win, bg);
+ * evas_object_show(bg);
+ *
+ * // Creates an Evas plugin
+ * EvasPlugin evasPlugin = EvasPlugin::New(ad->elm_win, EVAS_PLUGIN_WIDTH, EVAS_PLUGIN_HEIGHT, true);
+ *
+ * // Creates a Dali application
+ * ad->daliApplication = new DaliApplication(evasPlugin);
+ *
+ * return true;
+ * }
+ *
+ * static void app_terminate(void *data)
+ * {
+ * struct app_data* ad = (struct app_data*)data;
+ *
+ * delete ad->daliApplication;
+ * ad->daliApplication = NULL;
+ * }
+ *
+ * static void app_pause(void *data)
+ * {
+ * }
+ *
+ * static void app_resume(void *data)
+ * {
+ * }
+ *
+ * static void app_control(app_control_h service, void *data)
+ * {
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ * // Initializes the Tizen application framework
+ * ui_app_lifecycle_callback_s event_callback;
+ *
+ * event_callback.create = app_create;
+ * event_callback.terminate = app_terminate;
+ * event_callback.pause = app_pause;
+ * event_callback.resume = app_resume;
+ * event_callback.app_control = app_control;
+ *
+ * struct app_data ad;
+ * memset(&ad, 0x0, sizeof(ad));
+ *
+ * // Runs the Tizen application framework
+ * return ui_app_main(argc, argv, &event_callback, &ad);
+ * }
+ * @endcode
+ */
+class DALI_IMPORT_API EvasPlugin : public BaseHandle
+{
+public:
+
+ typedef Signal<void (void)> EvasPluginSignalType;
+
+public:
+
+ /**
+ * @brief This is the constructor for Tizen EFL applications
+ *
+ * @param[in] parentEvasObject Parent of the new Evas object
+ * @param[in] width The initial width of the Dali view port
+ * @param[in] height The initial height of the Dali view port
+ * @param[in] transparent Whether the Evas object is transparent or not
+ */
+ static EvasPlugin New(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+ /**
+ * @brief Constructs an empty handle
+ */
+ EvasPlugin();
+
+ /**
+ * @brief Copy constructor
+ */
+ EvasPlugin(const EvasPlugin& evasPlugin);
+
+ /**
+ * @brief Assignment operator
+ */
+ EvasPlugin& operator=(const EvasPlugin& evasPlugin);
+
+ /**
+ * @brief Destructor
+ */
+ ~EvasPlugin();
+
+public:
+
+ /**
+ * @brief Runs the Evas plugin (rendering, event handling, etc)
+ */
+ void Run();
+
+ /**
+ * @brief Pauses the Evas plugin
+ */
+ void Pause();
+
+ /**
+ * @brief Resumes the Evas plugin
+ */
+ void Resume();
+
+ /**
+ * @brief Stops the Evas plugin
+ */
+ void Stop();
+
+ /**
+ * @brief This returns the Evas_Object* which is created internally for accessibility.
+ *
+ * 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* GetDaliAccessEvasObject();
+
+ /**
+ * @brief This returns the Evas_Object* which is created internally
+ *
+ * @return Evas_Object* Evas object which is rendered by Dali
+ */
+ Evas_Object* GetDaliEvasObject();
+
+public: // Signals
+
+ /**
+ * @brief Signal to notify the client when the application is ready to be initialized
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& InitSignal();
+
+ /**
+ * @brief Signal to notify the user when the application is about to be terminated
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& TerminateSignal();
+
+ /**
+ * @brief Signal to notify the client when the adaptor is about to be paused
+ *
+ * The user should connect to this signal if the user needs to perform any special
+ * activities when the application is about to be paused.
+ * @return The signal
+ */
+ EvasPluginSignalType& PauseSignal();
+
+ /**
+ * @brief Signal to notify the client when the adpator has resumed
+ *
+ * The user should connect to this signal if the user needs to perform any special
+ * activities when the application has resumed.
+ * @return The signal
+ */
+ EvasPluginSignalType& ResumeSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object is resized
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& ResizeSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object gets the keyboard focus
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& FocusedSignal();
+
+ /**
+ * @brief Signal to notify the client when the Evas object loses the keyboard focus
+ *
+ * @return The signal
+ */
+ EvasPluginSignalType& UnFocusedSignal();
+
+public: // Not intended for application developers
+ /**
+ * @brief Internal constructor
+ */
+ explicit DALI_INTERNAL EvasPlugin(Internal::EvasPlugin* evasPlugin);
+};
+
+/**
+ * @}
+ */
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // __DALI_EXTENSION_EVAS_PLUGIN_H__
--- /dev/null
+evas_plugin_public_header_files = \
+ $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.h
+
+evas_plugin_public_src_files = \
+ $(extension_src_dir)/devel-api/evas-plugin/evas-plugin.cpp
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "ecore-wl-event-handler.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+const int ECORE_WL_EVENT_COUNT = 4;
+
+//const char* CLIPBOARD_ATOM = "CBHM_MSG";
+//const char* CLIPBOARD_SET_OWNER_MESSAGE = "SET_OWNER";
+
+}
+
+struct EcoreWlEventHandler::Impl
+{
+ Impl(EcoreWlEventHandler* eventHandler, Ecore_Wl2_Window* window)
+ : mEventHandler(eventHandler)
+ , mWindow(window)
+ , mEcoreEventHandlers(ECORE_WL_EVENT_COUNT)
+ {
+#if 0
+ // Register Client message events - accessibility etc
+ mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, EcoreWlEventClientMessage, eventHandler));
+
+ // Register Selection events - clipboard selection, Drag & Drop selection etc
+ mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR, EcoreWlEventSelectionClear, eventHandler));
+ mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, EcoreWlEventSelectionNotify, eventHandler));
+#endif
+ // Register Window visibility change events
+ mEcoreEventHandlers.push_back(ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, EcoreWlEventWindowVisibilityChange, eventHandler));
+
+ }
+
+ ~Impl()
+ {
+ for(std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandlers.begin(), endIter = mEcoreEventHandlers.end(); iter != endIter; ++iter)
+ {
+ ecore_event_handler_del(*iter);
+ }
+ }
+
+ static Eina_Bool EcoreWlEventClientMessage(void* data, int type, void* event)
+ {
+#if 0
+ Ecore_X_Event_Client_Message* eventClientMessage = static_cast<Ecore_X_Event_Client_Message*>(event);
+ EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+ if (eventClientMessage->win == eventHandler->mImpl->mWindow)
+ {
+ if (eventClientMessage->message_type == ecore_x_atom_get(CLIPBOARD_ATOM))
+ {
+ if (!strcmp(eventClientMessage->data.b, CLIPBOARD_SET_OWNER_MESSAGE))
+ {
+ // Claim the ownership of the SECONDARY selection
+ ecore_x_selection_secondary_set(eventClientMessage->win, "", 1);
+
+ // Show the clipboard window
+ Clipboard::Get().ShowClipboard();
+ }
+ }
+ }
+#endif
+
+ return ECORE_CALLBACK_PASS_ON;
+ }
+
+ static Eina_Bool EcoreWlEventSelectionClear(void* data, int type, void* event)
+ {
+#if 0
+ Ecore_X_Event_Selection_Clear* eventSelectionClear = static_cast<Ecore_X_Event_Selection_Clear*>(event);
+ EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+ if (eventSelectionClear->win == eventHandler->mImpl->mWindow)
+ {
+ if (eventSelectionClear->selection == ECORE_X_SELECTION_SECONDARY)
+ {
+ // Request to get the content from Ecore
+ ecore_x_selection_secondary_request(eventSelectionClear->win, ECORE_X_SELECTION_TARGET_TEXT);
+ }
+ }
+#endif
+
+ return ECORE_CALLBACK_PASS_ON;
+ }
+
+ static Eina_Bool EcoreWlEventSelectionNotify(void* data, int type, void* event)
+ {
+#if 0
+ Ecore_X_Event_Selection_Notify* eventSelectionNotify = static_cast<Ecore_X_Event_Selection_Notify*>(event);
+ EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+ if (eventSelectionNotify->win == eventHandler->mImpl->mWindow)
+ {
+ Ecore_X_Selection_Data* selectionData = static_cast<Ecore_X_Selection_Data*>(eventSelectionNotify->data);
+ if (selectionData->data)
+ {
+ if (eventSelectionNotify->selection == ECORE_X_SELECTION_SECONDARY)
+ {
+ std::string content(reinterpret_cast<char*>(selectionData->data), selectionData->length);
+
+ ClipboardEventNotifier clipboardEventNotifier = ClipboardEventNotifier::Get();
+ clipboardEventNotifier.SetContent(content);
+ clipboardEventNotifier.EmitContentSelectedSignal();
+
+ // Claim the ownership of the SECONDARY selection
+ ecore_x_selection_secondary_set(eventSelectionNotify->win, "", 1);
+
+ DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreWlEventSelectionNotify: Content(%d):\n" , selectionData->length );
+ DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
+ DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
+ DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
+ }
+ }
+ }
+#endif
+
+ return ECORE_CALLBACK_PASS_ON;
+ }
+
+ static Eina_Bool EcoreWlEventWindowVisibilityChange(void* data, int type, void* event)
+ {
+ Ecore_Wl2_Event_Window_Visibility_Change* eventWindowVisibilityChange = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+
+ EcoreWlEventHandler* eventHandler = static_cast<EcoreWlEventHandler*>(data);
+
+ // 0 is visible and 1 is invisible
+ eventHandler->SendEcoreWlVisibility(!eventWindowVisibilityChange->fully_obscured);
+
+ return ECORE_CALLBACK_PASS_ON;
+ }
+
+ EcoreWlEventHandler* mEventHandler;
+ Ecore_Wl2_Window* mWindow;
+ std::vector<Ecore_Event_Handler*> mEcoreEventHandlers;
+};
+
+EcoreWlEventHandler::EcoreWlEventHandler(Ecore_Wl2_Window* window,
+ EvasPluginVisibilityInterface& evasPluginVisibilityInterface)
+: mEvasPluginVisibilityInterface(evasPluginVisibilityInterface)
+, mImpl(NULL)
+{
+ mImpl = new Impl(this, window);
+}
+
+EcoreWlEventHandler::~EcoreWlEventHandler()
+{
+ delete mImpl;
+ mImpl = NULL;
+}
+
+void EcoreWlEventHandler::SendEcoreWlVisibility(bool visibility)
+{
+ mEvasPluginVisibilityInterface.OnEcoreWlVisibility(visibility);
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_ECORE_X_EVENT_HANDLER__
+#define __DALI_EXTENSION_INTERNAL_ECORE_X_EVENT_HANDLER__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_Wl2.h>
+#include <vector>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include "evas-plugin-visibility-interface.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginVisibilityInterface;
+
+class EcoreWlEventHandler
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param[in] window is id of ecore wayland window.
+ * @param[in] evasPluginVisibilityInterface Used to send ecore wayland event to evas plugin
+ */
+ EcoreWlEventHandler(Ecore_Wl2_Window* window, EvasPluginVisibilityInterface& evasPluginVisibilityInterface);
+
+ /**
+ * @brief Destructor
+ */
+ ~EcoreWlEventHandler();
+
+ /**
+ * @brief Send the ecore wayland visibility.
+ *
+ * @param[in] visibility True is that ecore wayland window is show up and false is not
+ */
+ void SendEcoreWlVisibility(bool visibility);
+
+private:
+ EvasPluginVisibilityInterface& mEvasPluginVisibilityInterface;
+
+ struct Impl;
+ Impl* mImpl;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-event-handler.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+/**
+ * Copied from x server
+ * @brief Retrieve the current milliseconds.
+ *
+ * @return the current milliseconds.
+ */
+static unsigned int GetCurrentMilliSeconds(void)
+{
+ struct timeval tv;
+
+ struct timespec tp;
+ static clockid_t clockid;
+
+ if (!clockid)
+ {
+#ifdef CLOCK_MONOTONIC_COARSE
+ if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
+ (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
+ {
+ clockid = CLOCK_MONOTONIC_COARSE;
+ }
+ else
+#endif
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+ {
+ clockid = CLOCK_MONOTONIC;
+ }
+ else
+ {
+ clockid = ~0L;
+ }
+ }
+ if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
+ {
+ return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
+ }
+
+ gettimeofday(&tv, NULL);
+ return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
+}
+
+namespace
+{
+
+const int TOUCH_DEVICE_ID = 0;
+
+const char* EVAS_OBJECT_FOCUSED_EVENT_NAME = "focused";
+const char* EVAS_OBJECT_UNFOCUSED_EVENT_NAME = "unfocused";
+
+/**
+ * @brief Retrieve the dali screen touch point.
+ *
+ * @param[in] canvasX is the x of canvas position
+ * @param[in] canvasY is the y of canvas position
+ * @param[in] evasObject is rendered by dali
+ * @param[out] screenX is the x of local position of evasObject
+ * @param[out] screenY is the y of local position of evasObject
+ */
+void GetScreenPosition(Evas_Coord canvasX, Evas_Coord canvasY, Evas_Object* evasObject, Evas_Coord &screenX, Evas_Coord &screenY)
+{
+ Evas_Coord objX = 0, objY = 0, objW = 0, objH = 0;
+ evas_object_geometry_get(evasObject, &objX, &objY, &objW, &objH);
+
+ screenX = canvasX - objX;
+ screenY = canvasY - objY;
+}
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+/**
+ * @brief Evas_Modifier enums in Ecore_Input.h do not match Ecore_Event_Modifier in Ecore_Input.h.
+ * This function converts from Evas_Modifier to Ecore_Event_Modifier enums.
+ *
+ * @param[in] evasModifier the Evas_Modifier input.
+ * @return the Ecore_Event_Modifier output.
+ */
+unsigned int EvasModifierToEcoreModifier(Evas_Modifier* evasModifier)
+{
+ unsigned int modifier = 0; // If no other matches returns NONE.
+
+ if (evas_key_modifier_is_set(evasModifier, "Shift"))
+ {
+ modifier |= ECORE_EVENT_MODIFIER_SHIFT;
+ }
+
+ if (evas_key_modifier_is_set(evasModifier, "Alt"))
+ {
+ modifier |= ECORE_EVENT_MODIFIER_ALT;
+ }
+
+ if (evas_key_modifier_is_set(evasModifier, "AltGr"))
+ {
+ modifier |= ECORE_EVENT_MODIFIER_ALTGR;
+ }
+
+ if (evas_key_modifier_is_set(evasModifier, "Control"))
+ {
+ modifier |= ECORE_EVENT_MODIFIER_CTRL;
+ }
+
+ if (evas_key_modifier_is_set(evasModifier, "Win") ||
+ evas_key_modifier_is_set(evasModifier, "Super") ||
+ evas_key_modifier_is_set(evasModifier, "Hyper"))
+ {
+ modifier |= ECORE_EVENT_MODIFIER_WIN;
+ }
+
+ return modifier;
+}
+#endif
+
+
+void ConvertActionInfo(Elm_Access_Action_Info* elmActionInfo, Dali::Extension::Internal::AccessActionInfo& daliActionInfo)
+{
+ daliActionInfo.x = elmActionInfo->x;
+ daliActionInfo.y = elmActionInfo->y;
+ daliActionInfo.mouseType = elmActionInfo->mouse_type;
+
+ switch(elmActionInfo->action_type)
+ {
+ case ELM_ACCESS_ACTION_HIGHLIGHT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_READ:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_READ;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_PREV;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_HIGHLIGHT_NEXT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_ACTIVATE:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_ACTIVATE;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_UNHIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_SCROLL:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_SCROLL;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UP:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_UP;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_DOWN:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_DOWN;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_BACK:
+ {
+ daliActionInfo.actionType = ACCESS_ACTION_BACK;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ switch(elmActionInfo->action_by)
+ {
+ case ELM_ACCESS_ACTION_HIGHLIGHT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_READ:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_READ;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_PREV;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_HIGHLIGHT_NEXT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_ACTIVATE:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_ACTIVATE;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_UNHIGHLIGHT;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_SCROLL:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_SCROLL;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_UP:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_UP;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_DOWN:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_DOWN;
+ }
+ break;
+
+ case ELM_ACCESS_ACTION_BACK:
+ {
+ daliActionInfo.actionBy = ACCESS_ACTION_BACK;
+ }
+ break;
+
+ default:
+
+ break;
+ }
+
+ daliActionInfo.highlightCycle = elmActionInfo->highlight_cycle;
+ daliActionInfo.timeStamp = GetCurrentMilliSeconds();
+}
+
+} // namespace
+
+EvasEventHandler::EvasEventHandler(Evas_Object* imageEvasObject,
+ Evas_Object* elmAccessEvasObject,
+ Evas_Object* elmFocusEvasObject,
+ EvasPluginEventInterface& evasPluginEventInterface)
+: mEvasPluginEventInterface(evasPluginEventInterface)
+, mEvas(evas_object_evas_get(imageEvasObject))
+, mImageEvasObject(imageEvasObject)
+, mElmAccessEvasObject(elmAccessEvasObject)
+, mElmFocusEvasObject(elmFocusEvasObject)
+{
+ // Register the evas event callbacks
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_DOWN, OnEvasObjectMouseDown, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_UP, OnEvasObjectMouseUp, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_MOVE, OnEvasObjectMouseMove, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_DOWN, OnEvasObjectMultiTouchDown, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_UP, OnEvasObjectMultiTouchUp, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MULTI_MOVE, OnEvasObjectMultiTouchMove, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_KEY_DOWN, OnEvasObjectKeyDown, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_KEY_UP, OnEvasObjectKeyUp, &evasPluginEventInterface);
+
+ // Register the evas geometry callbacks
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_MOVE, OnEvasObjectMove, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_RESIZE, OnEvasObjectResize, &evasPluginEventInterface);
+
+ // Register the evas focus callbacks
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_FOCUS_IN, OnEvasObjectFocusIn, &evasPluginEventInterface);
+ evas_object_event_callback_add(mImageEvasObject, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut, &evasPluginEventInterface);
+
+ evas_event_callback_add(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, OnEvasFocusIn, &evasPluginEventInterface);
+ evas_event_callback_add(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut, &evasPluginEventInterface);
+
+ // Register the evas render callbacks
+ evas_event_callback_add(mEvas, EVAS_CALLBACK_RENDER_POST, OnEvasRenderPost, &evasPluginEventInterface);
+
+ // Register the elm access action callbacks and these callbacks are disconnected when mElmAccessEvasObject is unregistred
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT, OnElmAccessActionHighlight, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_UNHIGHLIGHT, OnElmAccessActionUnhighlight, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, OnElmAccessActionHighlightNext, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_HIGHLIGHT_PREV, OnElmAccessActionHighlightPrev, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_ACTIVATE, OnElmAccessActionActivate, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_UP, OnElmAccessActionUp, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_DOWN, OnElmAccessActionDown, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_SCROLL, OnElmAccessActionScroll, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_BACK, OnElmAccessActionBack, &evasPluginEventInterface);
+ elm_access_action_cb_set(mElmAccessEvasObject, ELM_ACCESS_ACTION_READ, OnElmAccessActionRead, &evasPluginEventInterface);
+
+ // Register the elm focus callbacks
+ evas_object_smart_callback_add(mElmFocusEvasObject, EVAS_OBJECT_FOCUSED_EVENT_NAME, OnEvasObjectSmartFocused, this);
+ evas_object_smart_callback_add(mElmFocusEvasObject, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused, this);
+}
+
+EvasEventHandler::~EvasEventHandler()
+{
+ // Unregister the evas event callbacks.
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_DOWN, OnEvasObjectMouseDown);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_UP, OnEvasObjectMouseUp);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_MOVE, OnEvasObjectMouseMove);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOUSE_WHEEL, OnEvasObjectMouseWheel);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_DOWN, OnEvasObjectMultiTouchDown);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_UP, OnEvasObjectMultiTouchUp);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MULTI_MOVE, OnEvasObjectMultiTouchMove);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_KEY_DOWN, OnEvasObjectKeyDown);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_KEY_UP, OnEvasObjectKeyUp);
+
+ // Unregister the evas geometry callbacks.
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_MOVE, OnEvasObjectMove);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_RESIZE, OnEvasObjectResize);
+
+ // Unregister the evas focus callbacks
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_FOCUS_IN, OnEvasObjectFocusIn);
+ evas_object_event_callback_del(mImageEvasObject, EVAS_CALLBACK_FOCUS_OUT, OnEvasObjectFocusOut);
+
+ evas_event_callback_del(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, OnEvasFocusIn);
+ evas_event_callback_del(mEvas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, OnEvasFocusOut);
+
+ // Register the evas render callbacks
+ evas_event_callback_del(mEvas, EVAS_CALLBACK_RENDER_POST, OnEvasRenderPost);
+
+ // Unregister the elm focus callbacks
+ evas_object_smart_callback_del(mElmFocusEvasObject, EVAS_OBJECT_FOCUSED_EVENT_NAME, OnEvasObjectSmartFocused);
+ evas_object_smart_callback_del(mElmFocusEvasObject, EVAS_OBJECT_UNFOCUSED_EVENT_NAME, OnEvasObjectSmartUnfocused);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Event callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectMouseDown(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Mouse_Down* eventMouseDown = static_cast<Evas_Event_Mouse_Down*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMouseDown->canvas.x, eventMouseDown->canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(TOUCH_DEVICE_ID, TouchPoint::Down, screenX, screenY);
+ unsigned long timeStamp = eventMouseDown->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectMouseUp(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Mouse_Up* eventMouseUp = static_cast<Evas_Event_Mouse_Up*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMouseUp->canvas.x, eventMouseUp->canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(TOUCH_DEVICE_ID, TouchPoint::Up, screenX, screenY);
+ unsigned long timeStamp = eventMouseUp->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectMouseMove(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Mouse_Move* eventMouseMove = static_cast<Evas_Event_Mouse_Move*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMouseMove->cur.canvas.x, eventMouseMove->cur.canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(TOUCH_DEVICE_ID, TouchPoint::Motion, screenX, screenY);
+ unsigned long timeStamp = eventMouseMove->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectMouseWheel(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Mouse_Wheel* eventMouseWheel = static_cast<Evas_Event_Mouse_Wheel*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMouseWheel->canvas.x, eventMouseWheel->canvas.y, evasObject, screenX, screenY);
+
+ int direction = eventMouseWheel->direction;
+ unsigned int modifiers = -1; // TODO: Need to check evas modifier
+ Vector2 point = Vector2(screenX, screenY);
+ int z = eventMouseWheel->z;
+ unsigned int timeStamp = eventMouseWheel->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ WheelEvent wheelEvent(WheelEvent::MOUSE_WHEEL, direction, modifiers, point, z, timeStamp);
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectWheelEvent(wheelEvent);
+}
+
+void EvasEventHandler::OnEvasObjectMultiTouchDown(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Multi_Down* eventMultiDown = static_cast<Evas_Event_Multi_Down*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMultiDown->canvas.x, eventMultiDown->canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(eventMultiDown->device, TouchPoint::Down, screenX, screenY);
+ unsigned long timeStamp = eventMultiDown->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectMultiTouchUp(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Multi_Up* eventMultiUp = static_cast<Evas_Event_Multi_Up*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMultiUp->canvas.x, eventMultiUp->canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(eventMultiUp->device, TouchPoint::Up, screenX, screenY);
+ unsigned long timeStamp = eventMultiUp->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectMultiTouchMove(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Evas_Event_Multi_Move* eventMultiMove = static_cast<Evas_Event_Multi_Move*>(event);
+
+ Evas_Coord screenX = 0.0f, screenY = 0.0f;
+ GetScreenPosition(eventMultiMove->cur.canvas.x, eventMultiMove->cur.canvas.y, evasObject, screenX, screenY);
+
+ TouchPoint touchPoint = TouchPoint(eventMultiMove->device, TouchPoint::Motion, screenX, screenY);
+ unsigned long timeStamp = eventMultiMove->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectTouchEvent(touchPoint, timeStamp);
+}
+
+void EvasEventHandler::OnEvasObjectKeyDown(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ Evas_Event_Key_Down* eventKeyDown = static_cast<Evas_Event_Key_Down*>(event);
+ bool eventHandled = false;
+
+ // If a device key then skip ecore_imf_context_filter_event.
+ if (!KeyLookup::IsDeviceButton(eventKeyDown->keyname))
+ {
+ ImfManager imfManager = ImfManager::Get();
+ if(imfManager)
+ {
+ Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+ if (imfContext)
+ {
+ // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
+ Ecore_IMF_Event_Key_Down imfEventKeyDown;
+ ecore_imf_evas_event_key_down_wrap(eventKeyDown, &imfEventKeyDown);
+
+ eventHandled = ecore_imf_context_filter_event(imfContext, ECORE_IMF_EVENT_KEY_DOWN, reinterpret_cast<Ecore_IMF_Event*>(&imfEventKeyDown));
+
+ if (!eventHandled)
+ {
+ // Menu, home, back button must skip ecore_imf_context_filter_event.
+ static const char* escapeKeyName = KeyLookup::GetKeyName(DALI_KEY_ESCAPE);
+ static const char* returnKeyName = KeyLookup::GetKeyName(static_cast<Dali::KEY>(DALI_EXTENSION_INTERNAL_KEY_RETURN));
+ static const char* kpEnterKeyName = KeyLookup::GetKeyName(static_cast<Dali::KEY>(DALI_EXTENSION_INTERNAL_KEY_KP_ENTER));
+ if ((escapeKeyName && !strcmp(eventKeyDown->keyname, escapeKeyName)) ||
+ (returnKeyName && !strcmp(eventKeyDown->keyname, returnKeyName)) ||
+ (kpEnterKeyName && !strcmp(eventKeyDown->keyname, kpEnterKeyName)))
+ {
+ ecore_imf_context_reset(imfContext);
+ }
+ }
+ }
+ }
+ }
+
+ // If the event wasn't handled then we should send a key event.
+ if (!eventHandled)
+ {
+ std::string keyName = eventKeyDown->keyname;
+ std::string keyString = (eventKeyDown->string != NULL) ? eventKeyDown->string : "";
+ int keyCode = KeyLookup::GetDaliKeyCode(eventKeyDown->keyname);
+ int modifier = EvasModifierToEcoreModifier(eventKeyDown->modifiers);
+ unsigned long timeStamp = eventKeyDown->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ KeyEvent keyEvent(keyName, keyString, keyCode, modifier, timeStamp, KeyEvent::Down);
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectKeyEvent(keyEvent);
+ }
+#endif
+}
+
+void EvasEventHandler::OnEvasObjectKeyUp(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ Evas_Event_Key_Up* eventKeyUp = static_cast<Evas_Event_Key_Up*>(event);
+ bool eventHandled = false;
+
+ // Menu, home, back button must skip ecore_imf_context_filter_event.
+ static const char* menuKeyName = KeyLookup::GetKeyName(DALI_KEY_MENU);
+ static const char* homeKeyName = KeyLookup::GetKeyName(DALI_KEY_HOME);
+ static const char* backKeyName = KeyLookup::GetKeyName(DALI_KEY_BACK);
+ if ((menuKeyName && !strcmp(eventKeyUp->keyname, menuKeyName)) &&
+ (homeKeyName && !strcmp(eventKeyUp->keyname, homeKeyName)) &&
+ (backKeyName && !strcmp(eventKeyUp->keyname, backKeyName)))
+ {
+ ImfManager imfManager = ImfManager::Get();
+ if(imfManager)
+ {
+ Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+
+ if (imfContext)
+ {
+ Ecore_IMF_Event_Key_Up imfEventKeyUp;
+ ecore_imf_evas_event_key_up_wrap(eventKeyUp, &imfEventKeyUp);
+
+ eventHandled = ecore_imf_context_filter_event(imfContext, ECORE_IMF_EVENT_KEY_UP, reinterpret_cast<Ecore_IMF_Event*>(&imfEventKeyUp));
+ }
+ }
+ }
+
+ if (!eventHandled)
+ {
+ std::string keyName = eventKeyUp->keyname;
+ std::string keyString = (eventKeyUp->string != NULL) ? eventKeyUp->string : "";
+ int keyCode = KeyLookup::GetDaliKeyCode(eventKeyUp->keyname);
+ int modifier = EvasModifierToEcoreModifier(eventKeyUp->modifiers);
+ unsigned long timeStamp = eventKeyUp->timestamp;
+ if (timeStamp < 1)
+ {
+ timeStamp = GetCurrentMilliSeconds();
+ }
+
+ KeyEvent keyEvent(keyName, keyString, keyCode, modifier, timeStamp, KeyEvent::Up);
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectKeyEvent(keyEvent);
+ }
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Geometry callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectMove(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Rect<int> geometry;
+ evas_object_geometry_get(evasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height);
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectMove(geometry);
+}
+
+void EvasEventHandler::OnEvasObjectResize(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ Rect<int> geometry;
+ evas_object_geometry_get(evasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height);
+
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectResize(geometry);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectFocusIn(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectFocusIn();
+}
+
+void EvasEventHandler::OnEvasObjectFocusOut(void *data, Evas* evas, Evas_Object* evasObject, void* event)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasObjectFocusOut();
+}
+
+void EvasEventHandler::OnEvasFocusIn(void *data, Evas* evas, void* event)
+{
+}
+
+void EvasEventHandler::OnEvasFocusOut(void *data, Evas* evas, void* event)
+{
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Render callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasRenderPost(void *data, Evas* evas, void* event)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ pEvasPlugin->OnEvasPostRender();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Access callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlight(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionHighlight(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionUnhighlight(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionUnhighlight(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlightNext(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionHighlightNext(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionHighlightPrev(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionHighlightPrev(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionActivate(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionActivate(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionScroll(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionScroll(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionUp(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionUp(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionDown(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionDown(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionBack(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionBack(daliActionInfo);
+}
+
+Eina_Bool EvasEventHandler::OnElmAccessActionRead(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* actionInfo)
+{
+ EvasPluginEventInterface* pEvasPlugin = static_cast<EvasPluginEventInterface*>(data);
+ Dali::Extension::Internal::AccessActionInfo daliActionInfo;
+ ConvertActionInfo(actionInfo, daliActionInfo);
+
+ return pEvasPlugin->OnElmAccessActionRead(daliActionInfo);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+// Elm Focus callbacks
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void EvasEventHandler::OnEvasObjectSmartFocused(void *data, Evas_Object* evasObject, void* event)
+{
+ EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>(data);
+ EvasPluginEventInterface& evasPlugin = eventHandler->GetEvasPluginInterface();
+
+ if (eventHandler->mElmFocusEvasObject == evasObject)
+ {
+ Evas_Object* topWidget = elm_object_top_widget_get(evasObject);
+
+ if (!strcmp("elm_win", elm_object_widget_type_get(topWidget)))
+ {
+ if (elm_win_focus_highlight_enabled_get(topWidget) == EINA_TRUE)
+ {
+ // To allow that KeyboardFocusManager can handle the keyboard focus
+ KeyEvent fakeKeyEvent("", "", 0, 0, 100, KeyEvent::Down);
+
+ evasPlugin.OnEvasObjectKeyEvent(fakeKeyEvent);
+ }
+ }
+
+ evas_object_focus_set(eventHandler->mImageEvasObject, EINA_TRUE);
+ }
+}
+
+void EvasEventHandler::OnEvasObjectSmartUnfocused(void *data, Evas_Object* evasObject, void* event)
+{
+ EvasEventHandler* eventHandler = static_cast<EvasEventHandler*>(data);
+ if (eventHandler->mElmFocusEvasObject == evasObject)
+ {
+ evas_object_focus_set(eventHandler->mImageEvasObject, EINA_FALSE);
+ }
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER__
+#define __DALI_EXTENSION_INTERNAL_EVAS_EVENT_HANDLER__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Evas.h>
+
+#include <Elementary.h>
+#include <Ecore_Wl2.h>
+#include <Ecore_Input.h>
+#include <Ecore_IMF.h>
+#include <Ecore_IMF_Evas.h>
+
+#include <dali/public-api/events/touch-point.h>
+#include <dali/public-api/events/wheel-event.h>
+#include <dali/public-api/events/key-event.h>
+#include <dali/public-api/math/rect.h>
+// #include <dali/integration-api/adaptors/input-method-context.h>
+
+#include <string>
+
+// INTERNAL INCLUDES
+#include "evas-plugin-event-interface.h"
+
+
+
+namespace Dali
+{
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginEventInterface;
+
+class EvasEventHandler
+{
+public:
+ /**
+ * @brief Constructor
+ *
+ * @param[in] imageEvasObject is stream showing the pixmap which is drawn by dali
+ *
+ *
+ * @param[in] evasPluginEventInterface Used to send event to evas plugin
+ */
+ EvasEventHandler(Evas_Object* imageEvasObject,
+ Evas_Object* elmAccessEvasObject,
+ Evas_Object* elmFocusEvasObject,
+ EvasPluginEventInterface& evasPluginEventInterface);
+
+ /**
+ * Destructor.
+ */
+ ~EvasEventHandler();
+
+public:
+
+ EvasPluginEventInterface& GetEvasPluginInterface() { return mEvasPluginEventInterface; }
+
+private:
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Event callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when the mouse down is received
+ */
+ static void OnEvasObjectMouseDown(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the mouse up is received
+ */
+ static void OnEvasObjectMouseUp(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the mouse move is received
+ */
+ static void OnEvasObjectMouseMove(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the mouse wheel is received
+ */
+ static void OnEvasObjectMouseWheel(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the multi-touch down is received
+ */
+ static void OnEvasObjectMultiTouchDown(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the multi-touch up is received
+ */
+ static void OnEvasObjectMultiTouchUp(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when the multi-touch move is received
+ */
+ static void OnEvasObjectMultiTouchMove(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when key down is received
+ */
+ static void OnEvasObjectKeyDown(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when key up is received
+ */
+ static void OnEvasObjectKeyUp(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Geometry callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when move is received
+ */
+ static void OnEvasObjectMove(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when resize is received
+ */
+ static void OnEvasObjectResize(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Focus callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when evas object focus in is received
+ */
+ static void OnEvasObjectFocusIn(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when evas object focus out is received
+ */
+ static void OnEvasObjectFocusOut(void *data, Evas* evas, Evas_Object* evasObject, void* event);
+
+ /**
+ * @brief Called when evas focus in is received
+ */
+ static void OnEvasFocusIn(void *data, Evas* evas, void* event);
+
+ /**
+ * @brief Called when evas focus out is received
+ */
+ static void OnEvasFocusOut(void *data, Evas* evas, void* event);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Render callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * @brief Called when evas render post
+ */
+ static void OnEvasRenderPost(void *data, Evas* evas, void* event);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Elm Access callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ static Eina_Bool OnElmAccessActionHighlight(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionUnhighlight(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionHighlightNext(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionHighlightPrev(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionActivate(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionScroll(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionUp(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionDown(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionBack(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ static Eina_Bool OnElmAccessActionRead(void* data, Evas_Object* evasObject, Elm_Access_Action_Info* info);
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Elm Focus callbacks
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ static void OnEvasObjectSmartFocused(void *data, Evas_Object* evasObject, void* event);
+
+ static void OnEvasObjectSmartUnfocused(void *data, Evas_Object* evasObject, void* event);
+
+private:
+ EvasPluginEventInterface& mEvasPluginEventInterface;
+
+ Evas* mEvas;
+ Evas_Object* mImageEvasObject;
+ Evas_Object* mElmAccessEvasObject;
+ Evas_Object* mElmFocusEvasObject;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_EVENT_INTERFACE_H__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_EVENT_INTERFACE_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+template <typename T>
+class Rect;
+
+struct TouchPoint;
+struct WheelEvent;
+struct KeyEvent;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+enum AccessActionType
+{
+ ACCESS_ACTION_FIRST = -1,
+
+ ACCESS_ACTION_HIGHLIGHT, /* highlight an object */
+ ACCESS_ACTION_UNHIGHLIGHT, /* unhighlight an object */
+ ACCESS_ACTION_HIGHLIGHT_NEXT, /* set highlight to next object */
+ ACCESS_ACTION_HIGHLIGHT_PREV, /* set highlight to previous object */
+ ACCESS_ACTION_ACTIVATE, /* activate a highlight object */
+ ACCESS_ACTION_SCROLL, /* scroll if one of highlight object parents
+ * is scrollable */
+ ACCESS_ACTION_UP, /* change value up of highlight object */
+ ACCESS_ACTION_DOWN, /* change value down of highlight object */
+ ACCESS_ACTION_BACK, /* go back to a previous view
+ ex: pop naviframe item */
+ ACCESS_ACTION_READ, /* highlight an object */
+
+ ACCESS_ACTION_LAST
+};
+
+struct AccessActionInfo
+{
+ int x;
+ int y;
+ unsigned int mouseType; /* 0: mouse down
+ 1: mouse move
+ 2: mouse up */
+ AccessActionType actionType;
+ AccessActionType actionBy;
+ bool highlightCycle : 1;
+ unsigned int timeStamp;
+};
+
+class EvasPluginEventInterface
+{
+public:
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] touchPoint is the information of touch
+ * @param[in] timeStamp is that touch is occured
+ */
+ virtual void OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp) = 0;
+
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] wheelEvent is the information of wheel
+ */
+ virtual void OnEvasObjectWheelEvent(WheelEvent& wheelEvent) = 0;
+
+ /**
+ * @brief Handle evas object event
+ *
+ * @param[in] keyEvent is the information of key
+ */
+ virtual void OnEvasObjectKeyEvent(KeyEvent& keyEvent) = 0;
+
+ /**
+ * @brief Handle evas object geometry
+ *
+ * @param geometry is the move information of evas object
+ */
+ virtual void OnEvasObjectMove(const Rect<int>& geometry) = 0;
+
+ /**
+ * @brief Handle evas object geometry
+ *
+ * @param geometry is the resize information of evas object
+ */
+ virtual void OnEvasObjectResize(const Rect<int>& geometry) = 0;
+
+ /**
+ * @brief Handle evas object focus in
+ */
+ virtual void OnEvasObjectFocusIn() = 0;
+
+ /**
+ * @brief Handle evas object focus out
+ */
+ virtual void OnEvasObjectFocusOut() = 0;
+
+ /**
+ * @brief Handle evas object render post
+ */
+ virtual void OnEvasPostRender() = 0;
+
+ virtual bool OnElmAccessActionHighlight(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionUnhighlight(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionHighlightNext(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionHighlightPrev(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionActivate(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionScroll(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionUp(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionDown(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionBack(AccessActionInfo& accessActionInfo) = 0;
+
+ virtual bool OnElmAccessActionRead(AccessActionInfo& accessActionInfo) = 0;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "evas-plugin-impl.h"
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+namespace
+{
+const char* IMAGE_EVAS_OBJECT_NAME = "dali-evas-plugin";
+const char* ELM_OBJECT_STYLE = "transparent";
+const char* ELM_OBJECT_CONTAINER_PART_NAME = "elm.swallow.content";
+}
+
+struct EvasPlugin::Impl
+{
+ Impl(EvasPlugin* evasPlugin, Evas_Object* parentEvasObject, int width, int height, bool transparent)
+ : mEvasPlugin(evasPlugin)
+ , mEcoreEvas(NULL)
+ , mImageEvasObject(NULL)
+ , mDaliAccessEvasObject(NULL)
+ , mDaliEvasObject(NULL)
+ {
+ Evas* evas = evas_object_evas_get(parentEvasObject);
+ mEcoreEvas = ecore_evas_ecore_evas_get(evas);
+
+ // Create the image evas object
+ mImageEvasObject = evas_object_image_filled_add(evas);
+ evas_object_name_set(mImageEvasObject, IMAGE_EVAS_OBJECT_NAME);
+ evas_object_image_content_hint_set(mImageEvasObject, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
+ evas_object_image_alpha_set(mImageEvasObject, transparent ? EINA_TRUE : EINA_FALSE);
+ evas_object_image_size_set(mImageEvasObject, width, height);
+ evas_object_size_hint_weight_set(mImageEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(mImageEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ // Register the elm access to image evas object
+ mDaliAccessEvasObject = elm_access_object_register(mImageEvasObject, parentEvasObject);
+
+ // Create a button and set style as "focus", if does not want to show the focus, then "transparent"
+ mDaliEvasObject = elm_button_add(parentEvasObject);
+
+ // Don't need to show the focus boundary here
+ elm_object_style_set(mDaliEvasObject, ELM_OBJECT_STYLE);
+
+ // Set the image evas object to focus object, but event should not be propagated
+ elm_object_part_content_set(mDaliEvasObject, ELM_OBJECT_CONTAINER_PART_NAME, mImageEvasObject);
+ evas_object_propagate_events_set(mImageEvasObject, EINA_FALSE);
+
+ // Set the evas object you want to make focusable as the content of the swallow part
+ evas_object_size_hint_weight_set(mDaliEvasObject, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(mDaliEvasObject, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+ evas_object_move(mDaliEvasObject, 0, 0);
+ evas_object_resize(mDaliEvasObject, width, height);
+ evas_object_show(mDaliEvasObject);
+ }
+
+ ~Impl()
+ {
+ // Delete the elm focus evas object
+ evas_object_del(mDaliEvasObject);
+ mDaliEvasObject = NULL;
+
+ // Unregister elm_access_object
+ elm_access_object_unregister(mImageEvasObject);
+ mDaliAccessEvasObject = NULL;
+
+ // Delete the image evas object
+ evas_object_del(mImageEvasObject);
+ mImageEvasObject = NULL;
+ }
+
+ Ecore_Wl2_Window* GetNativeWindow()
+ {
+ return ecore_evas_wayland2_window_get( mEcoreEvas );
+ }
+
+ PositionSize GetGeometry()
+ {
+ PositionSize geometry;
+ evas_object_geometry_get(mImageEvasObject, &geometry.x, &geometry.y, &geometry.width, &geometry.height);
+ return geometry;
+ }
+
+ void SetFocus()
+ {
+ evas_object_focus_set(mImageEvasObject, EINA_TRUE);
+ }
+
+ void BindTBMSurface( tbm_surface_h surface )
+ {
+#ifdef ENABLE_TTRACE
+ traceBegin( TTRACE_TAG_GRAPHICS, "EvasNativeSurfaceSet[%d]", pixmap );
+#endif
+
+ Evas_Native_Surface nativeSurface;
+ nativeSurface.type = EVAS_NATIVE_SURFACE_TBM;
+ nativeSurface.version = EVAS_NATIVE_SURFACE_VERSION;
+ nativeSurface.data.tbm.buffer = surface;
+ nativeSurface.data.tbm.rot = 0;
+ nativeSurface.data.tbm.ratio = 0;
+ nativeSurface.data.tbm.flip = 0;
+
+ evas_object_image_native_surface_set( mImageEvasObject, &nativeSurface );
+
+#ifdef ENABLE_TTRACE
+ traceEnd( TTRACE_TAG_GRAPHICS );
+#endif
+ }
+
+ void RequestRender()
+ {
+ evas_object_image_pixels_dirty_set( mImageEvasObject, EINA_TRUE );
+ ecore_evas_manual_render( mEcoreEvas );
+ }
+
+ EvasPlugin* mEvasPlugin;
+ Ecore_Evas* mEcoreEvas;
+ Evas_Object* mImageEvasObject;
+ Evas_Object* mDaliAccessEvasObject;
+ Evas_Object* mDaliEvasObject;
+};
+
+EvasPluginPtr EvasPlugin::New(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+{
+ EvasPluginPtr evasPlugin = new EvasPlugin(parentEvasObject, width, height, transparent);
+ return evasPlugin;
+}
+
+EvasPlugin::EvasPlugin(Evas_Object* parentEvasObject, int width, int height, bool transparent)
+: mState(READY)
+, mTBMRenderSurface(NULL)
+, mAdaptor(NULL)
+, mRenderNotification(NULL)
+, mEvasEventHandler(NULL)
+, mEcoreWlEventHandler(NULL)
+, mIsFocus(false)
+, mTransparent(transparent)
+, mImpl(NULL)
+{
+ DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the evas plugin." );
+
+ mImpl = new Impl(this, parentEvasObject, width, height, transparent);
+
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+ // Create the singleton service
+ mSingletonService = SingletonService::New();
+
+ // Create the pixmap render surface
+ mTBMRenderSurface = CreateNativeSurface( PositionSize( 0, 0, width, height ), transparent );
+
+ // Initialize dali
+ Any nativeWindow = mImpl->GetNativeWindow();
+ mAdaptor = &Adaptor::New(nativeWindow, *mTBMRenderSurface, Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
+#endif
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ ImfManager imfManager = ImfManager::Get();
+ if(imfManager)
+ {
+ imfManager.ActivatedSignal().Connect(this, &EvasPlugin::OnImfActivated);
+ }
+#endif
+
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+ TriggerEventFactory triggerEventFactory;
+ mRenderNotification = triggerEventFactory.CreateTriggerEvent(MakeCallback(this, &EvasPlugin::OnPostRender),
+ TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
+
+ mTBMRenderSurface->SetRenderNotification(mRenderNotification);
+#endif
+}
+
+EvasPlugin::~EvasPlugin()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+ mAdaptor->Stop();
+
+ if (mEcoreWlEventHandler)
+ {
+ delete mEcoreWlEventHandler;
+ mEcoreWlEventHandler = NULL;
+ }
+
+ if (mEvasEventHandler)
+ {
+ delete mEvasEventHandler;
+ mEvasEventHandler = NULL;
+ }
+
+ delete mRenderNotification;
+ mRenderNotification = NULL;
+
+ // the singleton service should be unregistered before adaptor deletion
+ mSingletonService.UnregisterAll();
+
+ delete mAdaptor;
+ mAdaptor = NULL;
+
+ delete mTBMRenderSurface;
+ mTBMRenderSurface = NULL;
+#endif
+
+ delete mImpl;
+ mImpl = NULL;
+}
+
+void EvasPlugin::Run()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+ if(READY == mState)
+ {
+ if (!mEvasEventHandler)
+ {
+ mEvasEventHandler = new Extension::Internal::EvasEventHandler(mImpl->mImageEvasObject, mImpl->mDaliAccessEvasObject, mImpl->mDaliEvasObject, *this);
+ }
+
+ // Start the adaptor
+ mAdaptor->Start();
+
+ mInitSignal.Emit();
+
+ mAdaptor->NotifySceneCreated();
+
+ mState = RUNNING;
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::Run");
+ }
+#endif
+}
+
+void EvasPlugin::Pause()
+{
+ if(mState == RUNNING)
+ {
+ mState = SUSPENDED;
+
+ mAdaptor->Pause();
+
+ mPauseSignal.Emit();
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::Pause");
+ }
+}
+
+void EvasPlugin::Resume()
+{
+ if(mState == SUSPENDED)
+ {
+ mAdaptor->Resume();
+
+ mResumeSignal.Emit();
+
+ mState = RUNNING;
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::Resume");
+ }
+}
+
+void EvasPlugin::Stop()
+{
+#ifdef DALI_PREVENT_TIZEN_40_FEATURE
+ if(mState != STOPPED)
+ {
+ // Stop the adaptor
+ mAdaptor->Stop();
+ mState = STOPPED;
+
+ mTerminateSignal.Emit();
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::Stop");
+ }
+#endif
+}
+
+Evas_Object* EvasPlugin::GetDaliAccessEvasObject()
+{
+ return mImpl->mDaliAccessEvasObject;
+}
+
+Evas_Object* EvasPlugin::GetDaliEvasObject()
+{
+ return mImpl->mDaliEvasObject;
+}
+
+void EvasPlugin::ResizeSurface()
+{
+#if 0
+ // Remember old surface
+ NativeRenderSurface* oldSurface = mTBMRenderSurface;
+ TriggerEventInterface* oldTriggerEvent = mRenderNotification;
+
+ PositionSize geometry = mImpl->GetGeometry();
+
+ mAdaptor->SurfaceSizeChanged( geometry );
+
+ // emit resized signal to application
+ mResizeSignal.Emit();
+
+ mTBMRenderSurface = CreateNativeSurface( PositionSize( 0, 0, geometry.width, geometry.height ), NATIVE_SURFACE_NAME, mTransparent );
+ mTBMRenderSurface->SetRenderNotification( mRenderNotification );
+
+ // Ask the replace the surface inside dali
+ Any nativeWindow = mImpl->GetNativeWindow();
+
+ mAdaptor->ReplaceSurface( nativeWindow, *mTBMRenderSurface ); // this method is synchronous => guarantee until rendering next frame
+
+ TriggerEventFactory triggerEventFactory;
+ mRenderNotification = triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &EvasPlugin::OnPostRender ),
+ TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER );
+
+ mTBMRenderSurface->SetRenderNotification( mRenderNotification );
+ delete oldTriggerEvent;
+
+ // Bind offscreen surface to the evas object
+ mTBMRenderSurface->WaitUntilSurfaceReplaced();
+ mImpl->BindTBMSurface( AnyCast<tbm_surface_h>( mTBMRenderSurface->GetDrawable() ) );
+ mAdaptor->ReleaseSurfaceLock();
+
+ // It's now safe to delete the old surface
+ delete oldSurface;
+#endif
+}
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+void EvasPlugin::OnImfActivated(ImfManager& imfManager)
+{
+ mImpl->SetFocus();
+}
+#endif
+
+void EvasPlugin::OnPostRender()
+{
+ // Bind offscreen surface to the evas object
+ mImpl->BindTBMSurface(AnyCast<tbm_surface_h>(mTBMRenderSurface->GetDrawable()));
+ mAdaptor->ReleaseSurfaceLock();
+
+ mImpl->RequestRender();
+}
+
+void EvasPlugin::OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp)
+{
+ mAdaptor->FeedTouchPoint(touchPoint, timeStamp);
+}
+
+void EvasPlugin::OnEvasObjectWheelEvent(WheelEvent& wheelEvent)
+{
+ mAdaptor->FeedWheelEvent( wheelEvent );
+}
+
+void EvasPlugin::OnEvasObjectKeyEvent(KeyEvent& keyEvent)
+{
+ mAdaptor->FeedKeyEvent( keyEvent );
+}
+
+void EvasPlugin::OnEvasObjectMove(const Rect<int>& geometry)
+{
+}
+
+void EvasPlugin::OnEvasObjectResize(const Rect<int>& geometry)
+{
+ DALI_LOG_RELEASE_INFO("EvasPlugin::OnEvasObjectResize (%d x %d)", geometry.width, geometry.height);
+
+ if (geometry.width <= 1 || geometry.height <= 1)
+ {
+ // skip meaningless resize signal
+ return;
+ }
+
+ Vector2 size = Stage::GetCurrent().GetSize();
+ if(size.width == geometry.width && size.height == geometry.height)
+ {
+ // skip meaningless resize signal
+ return;
+ }
+
+ ResizeSurface();
+}
+
+void EvasPlugin::OnEvasObjectFocusIn()
+{
+ if(!mIsFocus)
+ {
+ if (!mEcoreWlEventHandler)
+ {
+ mEcoreWlEventHandler = new Extension::Internal::EcoreWlEventHandler(mImpl->GetNativeWindow(), *this);
+ }
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ ImfManager imfManager = ImfManager::Get();
+ if(imfManager)
+ {
+ // TODO : Move to Impl
+ Ecore_Wl_Window* window = mImpl->GetNativeWindow();
+ Ecore_IMF_Context* imfContext = Dali::Internal::Adaptor::ImfManager::GetImplementation(imfManager).GetContext();
+ ecore_imf_context_client_window_set( imfContext, reinterpret_cast<void*>( window ) );
+
+ if(imfManager.RestoreAfterFocusLost())
+ {
+ imfManager.Activate();
+ }
+ }
+#endif
+
+ mFocusedSignal.Emit();
+
+ mIsFocus = true;
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::OnEvasObjectFocusIn");
+ }
+}
+
+void EvasPlugin::OnEvasObjectFocusOut()
+{
+ if(mIsFocus)
+ {
+ mIsFocus = false;
+
+ if (mEcoreWlEventHandler)
+ {
+ delete mEcoreWlEventHandler;
+ mEcoreWlEventHandler = NULL;
+ }
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ ImfManager imfManager = ImfManager::Get();
+ if(imfManager && imfManager.RestoreAfterFocusLost())
+ {
+ imfManager.Deactivate();
+ }
+#endif
+
+ Clipboard::Get().HideClipboard();
+
+ mUnFocusedSignal.Emit();
+
+ DALI_LOG_RELEASE_INFO("EvasPlugin::OnEvasObjectFocusOut");
+ }
+}
+
+void EvasPlugin::OnEvasPostRender()
+{
+}
+
+bool EvasPlugin::OnElmAccessActionHighlight(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionUnhighlight(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionHighlightNext(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionHighlightPrev(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionActivate(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionUp(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionDown(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionScroll(AccessActionInfo& accessActionInfo)
+{
+ bool ret = false;
+
+ Evas_Coord rel_x, rel_y;
+ Evas_Coord obj_x, obj_y, obj_w, obj_h;
+ Evas_Object* eo = this->GetDaliAccessEvasObject();
+
+ if(eo)
+ {
+ evas_object_geometry_get(eo, &obj_x, &obj_y, &obj_w, &obj_h);
+
+ rel_x = accessActionInfo.x - obj_x;
+ rel_y = accessActionInfo.y - obj_y;
+
+ ret = this->OnElmAccessibilityActionEvent(accessActionInfo, rel_x, rel_y);
+ }
+
+ return ret;
+}
+
+bool EvasPlugin::OnElmAccessActionBack(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+bool EvasPlugin::OnElmAccessActionRead(AccessActionInfo& accessActionInfo)
+{
+ return this->OnElmAccessibilityActionEvent(accessActionInfo);
+}
+
+void EvasPlugin::OnEcoreWlVisibility(bool visibility)
+{
+ if (!visibility)
+ {
+ mAdaptor->ReleaseSurfaceLock();
+ }
+}
+
+bool EvasPlugin::OnElmAccessibilityActionEvent(AccessActionInfo& accessActionInfo, int x, int y)
+{
+ bool ret = false;
+
+ if( NULL == mAdaptor)
+ {
+ return ret;
+ }
+
+ Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
+ if( accessibilityAdaptor )
+ {
+ int touchType = accessActionInfo.mouseType;
+ int touchX = x >= 0 ? x : accessActionInfo.x;
+ int touchY = y >= 0 ? y : accessActionInfo.y;
+
+ switch(accessActionInfo.actionBy)
+ {
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
+ case Dali::Extension::Internal::ACCESS_ACTION_READ:
+ {
+ ret = accessibilityAdaptor.HandleActionReadEvent((unsigned int)x, (unsigned int)y, true);
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
+ {
+ // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
+ ret = accessibilityAdaptor.HandleActionPreviousEvent(accessActionInfo.highlightCycle);
+ if(!ret)
+ {
+ // when focus moving was failed, clear the focus
+ accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
+ {
+ // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
+ ret = accessibilityAdaptor.HandleActionNextEvent(accessActionInfo.highlightCycle);
+ if(!ret)
+ {
+ // when focus moving was failed, clear the focus
+ accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
+ {
+ ret = accessibilityAdaptor.HandleActionActivateEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
+ {
+ ret = accessibilityAdaptor.HandleActionClearFocusEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
+ {
+ TouchPoint::State state(TouchPoint::Down);
+
+ if (touchType == 0)
+ {
+ state = TouchPoint::Down; // mouse down
+ }
+ else if (touchType == 1)
+ {
+ state = TouchPoint::Motion; // mouse move
+ }
+ else if (touchType == 2)
+ {
+ state = TouchPoint::Up; // mouse up
+ }
+ else
+ {
+ state = TouchPoint::Interrupted; // error
+ }
+
+ // Send touch event to accessibility manager.
+ TouchPoint point( 0, state, (float)touchX, (float)touchY );
+ ret = accessibilityAdaptor.HandleActionScrollEvent(point, accessActionInfo.timeStamp);
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_UP:
+ {
+ ret = accessibilityAdaptor.HandleActionUpEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
+ {
+ ret = accessibilityAdaptor.HandleActionDownEvent();
+ }
+ break;
+
+ case Dali::Extension::Internal::ACCESS_ACTION_BACK:
+ default:
+ {
+ DALI_LOG_WARNING("[%s:%d]\n", __FUNCTION__, __LINE__);
+ }
+
+ break;
+ }
+ }
+ else
+ {
+ DALI_LOG_WARNING("[%s:%d]\n", __FUNCTION__, __LINE__);
+ }
+
+ DALI_LOG_INFO(gEvasPluginLogFilter, Debug::General, "[%s:%d] [action : %d] focus manager returns %s\n", __FUNCTION__, __LINE__, (int)(actionType), ret?"TRUE":"FALSE");
+
+ return ret;
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <Elementary.h>
+#include <Ecore_IMF_Evas.h>
+#include <tbm_surface.h>
+
+#include <dali/public-api/dali-core.h>
+#include <dali/public-api/math/rect.h>
+#include <dali/public-api/object/base-object.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/signals/connection-tracker.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+
+#include <dali/devel-api/adaptor-framework/singleton-service.h>
+#include <dali/devel-api/adaptor-framework/clipboard.h>
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+#include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
+
+
+#include <dali/integration-api/debug.h>
+#include <dali/integration-api/adaptors/adaptor.h>
+#include <dali/integration-api/adaptors/native-render-surface.h>
+#include <dali/integration-api/adaptors/native-render-surface-factory.h>
+#include <dali/integration-api/adaptors/trigger-event-factory.h>
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+#include <dali/integration-api/adaptors/imf-manager-impl.h>
+#endif
+
+#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
+
+
+#ifdef ENABLE_TTRACE
+#include <ttrace.h>
+#endif
+
+
+// INTERNAL INCLUDES
+#include "evas-event-handler.h"
+#include "ecore-wl-event-handler.h"
+#include "evas-plugin-event-interface.h"
+#include "evas-plugin-visibility-interface.h"
+
+#include <dali-extension/devel-api/evas-plugin/evas-plugin.h>
+
+namespace Dali
+{
+class TriggerEventInterface;
+class NativeRenderSurface;
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+typedef Rect<int> PositionSize;
+
+class EvasPlugin;
+typedef IntrusivePtr<EvasPlugin> EvasPluginPtr;
+
+/**
+ * Implementation of the EvasPlugin class.
+ */
+class EvasPlugin : public BaseObject,
+ public ConnectionTracker,
+ public Extension::Internal::EvasPluginEventInterface,
+ public Extension::Internal::EvasPluginVisibilityInterface
+{
+public:
+
+ typedef Dali::Extension::EvasPlugin::EvasPluginSignalType EvasPluginSignalType;
+
+ /**
+ * @brief Create a new evas plugin
+ * @param[in] parentEvasObject A pointer of the parent evas object
+ * @param[in] width The width of Dali view port
+ * @param[in] height The height of Dali view port
+ * @param[in] transparent Whether the evas object is transparent or not
+ */
+ static EvasPluginPtr New(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+public:
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Start()
+ */
+ void Run();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Pause()
+ */
+ void Pause();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Resume()
+ */
+ void Resume();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::Stop()
+ */
+ void Stop();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::GetDaliAccessEvasObject()
+ */
+ Evas_Object* GetDaliAccessEvasObject();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::GetDaliEvasObject()
+ */
+ Evas_Object* GetDaliEvasObject();
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::InitSignal()
+ */
+ EvasPluginSignalType& InitSignal()
+ {
+ return mInitSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::TerminateSignal()
+ */
+ EvasPluginSignalType& TerminateSignal()
+ {
+ return mTerminateSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::PauseSignal()
+ */
+ EvasPluginSignalType& PauseSignal()
+ {
+ return mPauseSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::ResumeSignal()
+ */
+ EvasPluginSignalType& ResumeSignal()
+ {
+ return mResumeSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::ResizeSignal()
+ */
+ EvasPluginSignalType& ResizeSignal()
+ {
+ return mResizeSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::FocusedSignal()
+ */
+ EvasPluginSignalType& FocusedSignal()
+ {
+ return mFocusedSignal;
+ }
+
+ /**
+ * @copydoc Dali::Extension::EvasPlugin::UnFocusedSignal()
+ */
+ EvasPluginSignalType& UnFocusedSignal()
+ {
+ return mUnFocusedSignal;
+ }
+
+private:
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectTouchEvent
+ */
+ virtual void OnEvasObjectTouchEvent(TouchPoint& touchPoint, unsigned long timeStamp);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectWheelEvent
+ */
+ virtual void OnEvasObjectWheelEvent(WheelEvent& wheelEvent);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectKeyEvent
+ */
+ virtual void OnEvasObjectKeyEvent(KeyEvent& keyEvent);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectMove
+ */
+ virtual void OnEvasObjectMove(const Rect<int>& geometry);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectResize
+ */
+ virtual void OnEvasObjectResize(const Rect<int>& geometry);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusIn
+ */
+ virtual void OnEvasObjectFocusIn();
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasObjectFocusOut
+ */
+ virtual void OnEvasObjectFocusOut();
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnEvasRenderPost
+ */
+ virtual void OnEvasPostRender();
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlight
+ */
+ virtual bool OnElmAccessActionHighlight(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionUnhighlight
+ */
+ virtual bool OnElmAccessActionUnhighlight(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlightNext
+ */
+ virtual bool OnElmAccessActionHighlightNext(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionHighlightPrev
+ */
+ virtual bool OnElmAccessActionHighlightPrev(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionActivate
+ */
+ virtual bool OnElmAccessActionActivate(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionUp
+ */
+ virtual bool OnElmAccessActionUp(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionDown
+ */
+ virtual bool OnElmAccessActionDown(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionScroll
+ */
+ virtual bool OnElmAccessActionScroll(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface:OnElmAccessActionBack:
+ */
+ virtual bool OnElmAccessActionBack(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginEventInterface::OnElmAccessActionRead
+ */
+ virtual bool OnElmAccessActionRead(Dali::Extension::Internal::AccessActionInfo& accessActionInfo);
+
+ /**
+ * @copydoc Dali::Extension::Internal::EvasPluginVisibilityInterface::OnElmEcoreWlVisibility
+ */
+ virtual void OnEcoreWlVisibility(bool visibility);
+
+ /**
+ * Resize the surface
+ * To resize, create new surface with evas object's size and replace with it.
+ */
+ void ResizeSurface();
+
+#ifdef DALI_EVASPLUGIN_USE_IMF_MANAGER
+ /**
+ * For ImfActivated signal
+ * When the imf is activated, it will handle the focus
+ * @param[in] imfManager imfManager instance
+ */
+ void OnImfActivated(ImfManager& imfManager);
+#endif
+
+ /**
+ * This function is called after drawing by dali.
+ */
+ void OnPostRender();
+
+ /**
+ * Called when the accessibility action event dispatched from elm_access.
+ * @param[in] actionType elm accessibility action type structure
+ * @param[in] x x position for action, it could be unnecessary
+ * @param[in] y y position for action, it could be unnecessary
+ * @return True if the event was handled
+ */
+ bool OnElmAccessibilityActionEvent(AccessActionInfo& actionInfo, int x = -1, int y = -1);
+
+private:
+ /**
+ * Private constructor
+ * @param[in] parentEvasObject A pointer of the parent evas object
+ * @param[in] width The width of Dali view port
+ * @param[in] height The height of Dali view port
+ * @param[in] transparent Whether the evas object is transparent or not
+ */
+ EvasPlugin(Evas_Object* parentEvasObject, int width, int height, bool transparent);
+
+ /**
+ * Destructor
+ */
+ virtual ~EvasPlugin();
+
+ // Undefined
+ EvasPlugin(const EvasPlugin&);
+ EvasPlugin& operator=(EvasPlugin&);
+
+private:
+ enum State
+ {
+ READY,
+ RUNNING,
+ SUSPENDED,
+ STOPPED,
+ };
+
+ State mState;
+ NativeRenderSurface* mTBMRenderSurface;
+ Adaptor* mAdaptor;
+ TriggerEventInterface* mRenderNotification;
+ Extension::Internal::EvasEventHandler* mEvasEventHandler;
+ Extension::Internal::EcoreWlEventHandler* mEcoreWlEventHandler;
+
+ bool mIsFocus:1; ///< Flag
+ bool mTransparent:1; ///< Whether
+
+ SingletonService mSingletonService;
+
+ // Signals
+ EvasPluginSignalType mInitSignal;
+ EvasPluginSignalType mTerminateSignal;
+ EvasPluginSignalType mPauseSignal;
+ EvasPluginSignalType mResumeSignal;
+ EvasPluginSignalType mResizeSignal;
+ EvasPluginSignalType mFocusedSignal;
+ EvasPluginSignalType mUnFocusedSignal;
+
+ struct Impl;
+ Impl* mImpl;
+};
+
+inline EvasPlugin& GetImplementation(Extension::EvasPlugin& evasPlugin)
+{
+ DALI_ASSERT_ALWAYS(evasPlugin && "evasPluing handle is empty");
+
+ BaseObject& handle = evasPlugin.GetBaseObject();
+
+ return static_cast<EvasPlugin&>(handle);
+}
+
+inline const EvasPlugin& GetImplementation(const Extension::EvasPlugin& evasPlugin)
+{
+ DALI_ASSERT_ALWAYS(evasPlugin && "evasPlugin handle is empty");
+
+ const BaseObject& handle = evasPlugin.GetBaseObject();
+
+ return static_cast<const EvasPlugin&>(handle);
+}
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+
+#endif // __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_H__
--- /dev/null
+#ifndef __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_VISIBILITY_INTERFACE__
+#define __DALI_EXTENSION_INTERNAL_EVAS_PLUGIN_VISIBILITY_INTERFACE__
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Dali
+{
+
+namespace Extension
+{
+
+namespace Internal
+{
+
+class EvasPluginVisibilityInterface
+{
+public:
+ /**
+ * @brief Process the ecore wayland visibility.
+ *
+ * @param[in] visibility True is that ecore wayland window is show up and false is not
+ */
+ virtual void OnEcoreWlVisibility(bool visibility) = 0;
+};
+
+} // namespace Internal
+
+} // namespace Extension
+
+} // namespace Dali
+#endif
--- /dev/null
+evas_plugin_internal_header_files = \
+ $(extension_src_dir)/internal/evas-plugin/ecore-wl-event-handler.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-event-handler.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-event-interface.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-visibility-interface.h \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.h
+
+evas_plugin_internal_src_files = \
+ $(extension_src_dir)/internal/evas-plugin/ecore-wl-event-handler.cpp \
+ $(extension_src_dir)/internal/evas-plugin/evas-event-handler.cpp \
+ $(extension_src_dir)/internal/evas-plugin/evas-plugin-impl.cpp
BuildRequires: pkgconfig(dali-toolkit)
BuildRequires: pkgconfig(dlog)
+# For evas-plugin
+BuildRequires: pkgconfig(dali-adaptor-integration)
+BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(evas)
+BuildRequires: pkgconfig(ecore-wl2)
+
+
%description
dali-extension
%manifest dali-extension.manifest
%defattr(-,root,root,-)
%{_sysconfdir}/profile.d/dali.sh
+%{_libdir}/libdali-extension.so*
%license LICENSE
%files devel
%defattr(-,root,root,-)
-%{_includedir}/%{name}/
+%{_includedir}/%{name}/*
%{_libdir}/pkgconfig/*.pc
%files key-extension