From 198ffaa848ba593dbefe2f9a0e25b36fe32d7d99 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Wed, 9 May 2018 13:24:09 +0900 Subject: [PATCH] [Tizen] Support Ecore-Wayland2 Change-Id: I39c04986930aef4ff6490fb925d4e7ab497a54ef --- build/tizen/adaptor/Makefile.am | 40 + build/tizen/adaptor/configure.ac | 16 +- dali/internal/adaptor/tizen/adaptor-impl-tizen.cpp | 16 +- .../tizen-wayland/clipboard-impl-ecore-wl.cpp | 28 +- .../input-method-context-impl-ecore-wl.cpp | 43 +- .../input-method-context-impl-ecore-wl.h | 7 +- .../virtual-keyboard-impl-ecore-wl.cpp | 1 - .../system/tizen/widget-application-impl-tizen.cpp | 6 + dali/internal/window-system/file.list | 23 +- .../display-connection-impl-ecore-wl.cpp | 14 +- .../{ => ecore-wl}/event-handler-ecore-wl.cpp | 2 +- .../render-surface-factory-ecore-wl.cpp | 4 +- .../render-surface-factory-ecore-wl.h | 0 .../{ => ecore-wl}/window-base-ecore-wl.cpp | 4 +- .../{ => ecore-wl}/window-base-ecore-wl.h | 2 +- .../{ => ecore-wl}/window-factory-ecore-wl.cpp | 4 +- .../{ => ecore-wl}/window-factory-ecore-wl.h | 0 .../window-render-surface-ecore-wl.cpp | 2 +- .../window-render-surface-ecore-wl.h | 0 .../ecore-wl2/event-handler-ecore-wl2.cpp | 1449 ++++++++++++++++++++ .../ecore-wl2/render-surface-factory-ecore-wl2.cpp | 63 + .../ecore-wl2/render-surface-factory-ecore-wl2.h | 46 + .../ecore-wl2/window-base-ecore-wl2.cpp | 1233 +++++++++++++++++ .../ecore-wl2/window-base-ecore-wl2.h | 319 +++++ .../ecore-wl2/window-factory-ecore-wl2.cpp | 52 + .../ecore-wl2/window-factory-ecore-wl2.h | 42 + .../ecore-wl2/window-render-surface-ecore-wl2.cpp | 571 ++++++++ .../ecore-wl2/window-render-surface-ecore-wl2.h | 238 ++++ .../tizen-wayland/indicator-impl-ecore-wl.cpp | 9 + .../native-render-surface-ecore-wl.cpp | 20 + packaging/dali-adaptor.spec | 16 + 31 files changed, 4225 insertions(+), 45 deletions(-) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/event-handler-ecore-wl.cpp (99%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/render-surface-factory-ecore-wl.cpp (92%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/render-surface-factory-ecore-wl.h (100%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-base-ecore-wl.cpp (99%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-base-ecore-wl.h (99%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-factory-ecore-wl.cpp (90%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-factory-ecore-wl.h (100%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-render-surface-ecore-wl.cpp (99%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-render-surface-ecore-wl.h (100%) create mode 100755 dali/internal/window-system/tizen-wayland/ecore-wl2/event-handler-ecore-wl2.cpp create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.cpp create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.h create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.cpp create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.h create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.cpp create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.h diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index 1da44af..80ad1c7 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -125,6 +125,14 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +if ECORE_WAYLAND2 +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl2_src_files) +else +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) +endif + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -179,6 +187,14 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +if ECORE_WAYLAND2 +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl2_src_files) +else +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) +endif + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -232,6 +248,14 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +if ECORE_WAYLAND2 +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl2_src_files) +else +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) +endif + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -284,6 +308,14 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +if ECORE_WAYLAND2 +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl2_src_files) +else +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) +endif + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -339,6 +371,14 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +if ECORE_WAYLAND2 +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl2_src_files) +else +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) +endif + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) diff --git a/build/tizen/adaptor/configure.ac b/build/tizen/adaptor/configure.ac index 6cff84b..19ad826 100644 --- a/build/tizen/adaptor/configure.ac +++ b/build/tizen/adaptor/configure.ac @@ -180,6 +180,11 @@ AC_ARG_ENABLE(wayland, enable_wayland=yes, enable_wayland=no) +AC_ARG_ENABLE(ecore_wayland2, + [ --enable-ecore-wayland2 Build on Ecore Wayland2], + enable_ecore_wayland2=yes, + enable_ecore_wayland2=no) + AC_ARG_ENABLE([cxx03_abi], [AC_HELP_STRING([--enable-cxx03-abi], [Specify abi for the build])], @@ -201,6 +206,7 @@ AM_CONDITIONAL([TV_PROFILE], [test x$enable_profile = xTV]) AM_CONDITIONAL([IVI_PROFILE], [test x$enable_profile = xIVI]) AM_CONDITIONAL([UBUNTU_PROFILE], [test x$enable_profile = xUBUNTU]) AM_CONDITIONAL([WAYLAND], [test x$enable_wayland = xyes]) +AM_CONDITIONAL([ECORE_WAYLAND2], [test x$enable_ecore_wayland2 = xyes]) AM_CONDITIONAL([USE_APPFW], [test x$enable_appfw = xyes]) AM_CONDITIONAL([USE_APPFW_EFL_BASE], [test x$enable_tizen_major_version = x3]) AM_CONDITIONAL([ENABLE_CXX03_ABI], [test x$enable_cxx03_abi = xyes]) @@ -298,9 +304,12 @@ fi # Using EFL api's for WAYLAND AND X11 to run on ecore mainloop if test "x$enable_wayland" = "xyes"; then -PKG_CHECK_MODULES(WAYLAND, [ecore-wayland egl wayland-egl wayland-client >= 1.2.0 xkbcommon libtbm], - [DALI_USE_ECORE_WAYLAND=1], - [DALI_USE_ECORE_WAYLAND=0]) + +if test "x$enable_ecore_wayland2" = "xyes"; then +PKG_CHECK_MODULES(WAYLAND, [ecore-wl2 egl wayland-egl wayland-client >= 1.2.0 xkbcommon libtbm]) +else +PKG_CHECK_MODULES(WAYLAND, [ecore-wayland egl wayland-egl wayland-client >= 1.2.0 xkbcommon libtbm]) +fi else PKG_CHECK_MODULES(ECORE_X, [ecore-x], @@ -318,7 +327,6 @@ if test "x$enable_profile" != "xCOMMON"; then PKG_CHECK_MODULES(WAYLAND_EXTENSION, xdg-shell-client text-client input-method-client) fi fi -AM_CONDITIONAL([USE_ECORE_WAYLAND], [test "$DALI_USE_ECORE_WAYLAND" -eq 1]) if test x$DALI_DATA_RW_DIR != x; then dataReadWriteDir=$DALI_DATA_RW_DIR diff --git a/dali/internal/adaptor/tizen/adaptor-impl-tizen.cpp b/dali/internal/adaptor/tizen/adaptor-impl-tizen.cpp index c81f12b..e9c44e4 100644 --- a/dali/internal/adaptor/tizen/adaptor-impl-tizen.cpp +++ b/dali/internal/adaptor/tizen/adaptor-impl-tizen.cpp @@ -20,11 +20,18 @@ // EXTERNAL INCLUDES #include +#include + #ifdef APPCORE_WATCH_AVAILABLE #include #endif + +#ifdef ECORE_WAYLAND2 +#include +#else #include -#include +#endif + namespace Dali { @@ -105,8 +112,13 @@ void Adaptor::SurfaceInitialized() // Use strdup() in app_get_id(), so need to free memory if( appId ) { +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Window* ecoreWlWindow = AnyCast( mNativeWindow ); + screen_connector_provider_remote_enable( appId, ecore_wl2_window_surface_get( ecoreWlWindow ) ); +#else Ecore_Wl_Window* ecoreWlWindow = AnyCast( mNativeWindow ); - screen_connector_provider_remote_enable(appId, ecore_wl_window_surface_get(ecoreWlWindow)); + screen_connector_provider_remote_enable( appId, ecore_wl_window_surface_get( ecoreWlWindow ) ); +#endif free( appId ); } #endif diff --git a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp index 821a730..77b48de 100644 --- a/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp +++ b/dali/internal/clipboard/tizen-wayland/clipboard-impl-ecore-wl.cpp @@ -23,7 +23,13 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #include + +#ifdef ECORE_WAYLAND2 +#include +#else #include +#endif + #include #include #include @@ -103,21 +109,37 @@ struct Clipboard::Impl // ELM_SEL_TYPE_CLIPBOARD - To distinguish clipboard selection in cbhm types[++i] = "CLIPBOARD_END"; - ecore_wl_dnd_selection_set(ecore_wl_input_get(), types); + +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get( ecore_wl2_connected_display_get( NULL ) ); + ecore_wl2_dnd_selection_set( input, types ); +#else + ecore_wl_dnd_selection_set( ecore_wl_input_get(), types ); +#endif } void RequestItem() { +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get( ecore_wl2_connected_display_get( NULL ) ); + ecore_wl2_dnd_selection_get( input ); +#else const char *types[10] = {0, }; int i = -1; types[++i] = "text/plain;charset=utf-8"; ecore_wl_dnd_selection_get(ecore_wl_input_get(), *types); +#endif } char *ExcuteSend( void *event ) { +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Event_Data_Source_Send *ev = (Ecore_Wl2_Event_Data_Source_Send *)event; +#else Ecore_Wl_Event_Data_Source_Send *ev = (Ecore_Wl_Event_Data_Source_Send *)event; +#endif + int len_buf = mSendBuffer.length(); int len_remained = len_buf; int len_written = 0, ret; @@ -137,7 +159,11 @@ struct Clipboard::Impl char *ExcuteReceive( void *event ) { +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Event_Selection_Data_Ready *ev = (Ecore_Wl2_Event_Selection_Data_Ready *)event; +#else Ecore_Wl_Event_Selection_Data_Ready *ev = (Ecore_Wl_Event_Selection_Data_Ready *)event; +#endif return (char *)ev->data; } diff --git a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp index b4f71ea..212c0c9 100755 --- a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp +++ b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp @@ -23,8 +23,14 @@ #include // EXTERNAL INCLUDES -#include #include + +#ifdef ECORE_WAYLAND2 +#include +#else +#include +#endif + #include #include #include @@ -271,15 +277,11 @@ InputMethodContextPtr InputMethodContextEcoreWl::New() Adaptor &adaptorImpl(Adaptor::GetImplementation(Adaptor::Get())); Any nativeWindow = adaptorImpl.GetNativeWindowHandle(); - // The Ecore_Wl_Window needs to use the InputMethodContext. - // Only when the render surface is window, we can get the Ecore_Wl_Window. - Ecore_Wl_Window *ecoreWwin(AnyCast(nativeWindow)); - if (ecoreWwin) + // The window needs to use the InputMethodContext. + // Only when the render surface is window, we can get the window. + if( !nativeWindow.Empty() ) { - // If we fail to get Ecore_Wl_Window, we can't use the InputMethodContext correctly. - // Thus you have to call "ecore_imf_context_client_window_set" somewhere. - // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent(). - inputMethodContext = new InputMethodContextEcoreWl(ecoreWwin); + inputMethodContext = new InputMethodContextEcoreWl(); } else { @@ -297,9 +299,8 @@ void InputMethodContextEcoreWl::Finalize() DeleteContext(); } -InputMethodContextEcoreWl::InputMethodContextEcoreWl( Ecore_Wl_Window *ecoreWlwin ) +InputMethodContextEcoreWl::InputMethodContextEcoreWl() : mIMFContext(), - mEcoreWlwin( ecoreWlwin ), mIMFCursorPosition( 0 ), mSurroundingText(), mRestoreAfterFocusLost( false ), @@ -316,11 +317,11 @@ InputMethodContextEcoreWl::~InputMethodContextEcoreWl() void InputMethodContextEcoreWl::Initialize() { - CreateContext( mEcoreWlwin ); + CreateContext(); ConnectCallbacks(); } -void InputMethodContextEcoreWl::CreateContext( Ecore_Wl_Window *ecoreWlwin ) +void InputMethodContextEcoreWl::CreateContext() { DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext::CreateContext\n" ); @@ -331,10 +332,22 @@ void InputMethodContextEcoreWl::CreateContext( Ecore_Wl_Window *ecoreWlwin ) if( mIMFContext ) { + // If we fail to get Ecore_Wl_Window, we can't use the InputMethodContext correctly. + // Thus you have to call "ecore_imf_context_client_window_set" somewhere. + // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent(). + Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) ); + Any nativeWindow = adaptorImpl.GetNativeWindowHandle(); + +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Window* ecoreWlwin( AnyCast< Ecore_Wl2_Window* >( nativeWindow ) ); + int windowId = ecore_wl2_window_id_get( ecoreWlwin ); +#else + Ecore_Wl_Window* ecoreWlwin( AnyCast< Ecore_Wl_Window* >( nativeWindow ) ); + int windowId = ecore_wl_window_id_get( ecoreWlwin ); +#endif if( ecoreWlwin ) { - ecore_imf_context_client_window_set( mIMFContext, - reinterpret_cast( ecore_wl_window_id_get(ecoreWlwin)) ); + ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( windowId ) ); } } else diff --git a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h index ac92677..24fcd0b 100755 --- a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h +++ b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h @@ -21,7 +21,6 @@ // EXTERNAL INCLUDES #include #include -#include #include #include @@ -230,9 +229,8 @@ public: private: /** * Context created the first time and kept until deleted. - * @param[in] ecoreWlwin, The window is created by application. */ - void CreateContext( Ecore_Wl_Window *ecoreWlwin ); + void CreateContext(); /** * @copydoc Dali::InputMethodContext::DeleteContext() @@ -276,7 +274,7 @@ private: /** * @brief Constructor. */ - explicit InputMethodContextEcoreWl( Ecore_Wl_Window *ecoreWlwin ); + explicit InputMethodContextEcoreWl(); protected: /** @@ -293,7 +291,6 @@ private: private: Ecore_IMF_Context* mIMFContext; - Ecore_Wl_Window* mEcoreWlwin; int mIMFCursorPosition; std::string mSurroundingText; diff --git a/dali/internal/input/tizen-wayland/virtual-keyboard-impl-ecore-wl.cpp b/dali/internal/input/tizen-wayland/virtual-keyboard-impl-ecore-wl.cpp index b163872..f1fe613 100755 --- a/dali/internal/input/tizen-wayland/virtual-keyboard-impl-ecore-wl.cpp +++ b/dali/internal/input/tizen-wayland/virtual-keyboard-impl-ecore-wl.cpp @@ -20,7 +20,6 @@ // EXTERNAL INCLUDES #include -#include #include #include diff --git a/dali/internal/system/tizen/widget-application-impl-tizen.cpp b/dali/internal/system/tizen/widget-application-impl-tizen.cpp index 9464f42..b12f417 100644 --- a/dali/internal/system/tizen/widget-application-impl-tizen.cpp +++ b/dali/internal/system/tizen/widget-application-impl-tizen.cpp @@ -51,7 +51,13 @@ int OnInstanceInit(widget_base_instance_h instanceHandle, bundle *content, int w Dali::Window window = application->GetWindow(); window.ShowIndicator(Dali::Window::INVISIBLE); Any nativeHandle = window.GetNativeHandle(); + +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Window * wlWindow = AnyCast( nativeHandle ); +#else Ecore_Wl_Window * wlWindow = AnyCast( nativeHandle ); +#endif + widget_base_context_window_bind( instanceHandle, id, wlWindow ); window.SetSize( Dali::Window::WindowSize( w, h ) ); diff --git a/dali/internal/window-system/file.list b/dali/internal/window-system/file.list index 29f2af0..d45fe45 100644 --- a/dali/internal/window-system/file.list +++ b/dali/internal/window-system/file.list @@ -13,13 +13,24 @@ adaptor_window_system_common_src_files=\ adaptor_window_system_tizen_wayland_src_files=\ ${adaptor_window_system_dir}/tizen-wayland/display-connection-factory-ecore-wl.cpp \ ${adaptor_window_system_dir}/tizen-wayland/display-connection-impl-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/event-handler-ecore-wl.cpp \ ${adaptor_window_system_dir}/tizen-wayland/indicator-impl-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/native-render-surface-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/render-surface-factory-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/window-render-surface-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/window-base-ecore-wl.cpp \ - ${adaptor_window_system_dir}/tizen-wayland/window-factory-ecore-wl.cpp + ${adaptor_window_system_dir}/tizen-wayland/native-render-surface-ecore-wl.cpp + +# module: window-system, backend: ecore-wl +adaptor_window_system_ecore_wl_src_files=\ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl/event-handler-ecore-wl.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl/window-factory-ecore-wl.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.cpp + +# module: window-system, backend: ecore-wl2 +adaptor_window_system_ecore_wl2_src_files=\ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl2/event-handler-ecore-wl2.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.cpp \ + ${adaptor_window_system_dir}/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.cpp # module: window-system, backend: ubuntu-x11 adaptor_window_system_ubuntu_x11_src_files=\ diff --git a/dali/internal/window-system/tizen-wayland/display-connection-impl-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/display-connection-impl-ecore-wl.cpp index b4d102f..ca46418 100755 --- a/dali/internal/window-system/tizen-wayland/display-connection-impl-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/display-connection-impl-ecore-wl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,14 @@ #include // EXTERNAL_HEADERS -#include #include +#ifdef ECORE_WAYLAND2 +#include +#else +#include +#endif + namespace Dali { @@ -84,7 +89,12 @@ void DisplayConnectionEcoreWl::SetSurfaceType( RenderSurface::Type type ) } else { +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Display* display = ecore_wl2_connected_display_get( NULL ); + mDisplay = reinterpret_cast< EGLNativeDisplayType >( ecore_wl2_display_get( display ) ); +#else mDisplay = reinterpret_cast< EGLNativeDisplayType >( ecore_wl_display_get() ); +#endif } } diff --git a/dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/event-handler-ecore-wl.cpp similarity index 99% rename from dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp rename to dali/internal/window-system/tizen-wayland/ecore-wl/event-handler-ecore-wl.cpp index acfc8d8..25a31d7 100755 --- a/dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/event-handler-ecore-wl.cpp @@ -51,7 +51,7 @@ // INTERNAL INCLUDES #include -#include +#include #include #include #include diff --git a/dali/internal/window-system/tizen-wayland/render-surface-factory-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.cpp similarity index 92% rename from dali/internal/window-system/tizen-wayland/render-surface-factory-ecore-wl.cpp rename to dali/internal/window-system/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.cpp index c2619ce..978a7a4 100644 --- a/dali/internal/window-system/tizen-wayland/render-surface-factory-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.cpp @@ -16,10 +16,10 @@ */ // CLASS HEADER -#include +#include // INTERNAL HEADERS -#include +#include #include #include #include diff --git a/dali/internal/window-system/tizen-wayland/render-surface-factory-ecore-wl.h b/dali/internal/window-system/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.h similarity index 100% rename from dali/internal/window-system/tizen-wayland/render-surface-factory-ecore-wl.h rename to dali/internal/window-system/tizen-wayland/ecore-wl/render-surface-factory-ecore-wl.h diff --git a/dali/internal/window-system/tizen-wayland/window-base-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp similarity index 99% rename from dali/internal/window-system/tizen-wayland/window-base-ecore-wl.cpp rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp index 7fa0ce4..7a77b01 100644 --- a/dali/internal/window-system/tizen-wayland/window-base-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp @@ -20,11 +20,11 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" // CLASS HEADER -#include +#include // INTERNAL HEADERS #include -#include +#include #include // EXTERNAL_HEADERS diff --git a/dali/internal/window-system/tizen-wayland/window-base-ecore-wl.h b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.h similarity index 99% rename from dali/internal/window-system/tizen-wayland/window-base-ecore-wl.h rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.h index e1f0874..1a8f747 100644 --- a/dali/internal/window-system/tizen-wayland/window-base-ecore-wl.h +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.h @@ -37,7 +37,7 @@ class WindowRenderSurface; class WindowRenderSurfaceEcoreWl; /** - * WindowBaseEcoreWl class provides an WindowBase EcoreX implementation. + * WindowBaseEcoreWl class provides an WindowBase Ecore-Wayland implementation. */ class WindowBaseEcoreWl : public WindowBase { diff --git a/dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/window-factory-ecore-wl.cpp similarity index 90% rename from dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.cpp rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-factory-ecore-wl.cpp index 7235703..fad701b 100644 --- a/dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-factory-ecore-wl.cpp @@ -16,10 +16,10 @@ */ // CLASS HEADER -#include +#include // INTERNAL HEADERS -#include +#include #include #include diff --git a/dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.h b/dali/internal/window-system/tizen-wayland/ecore-wl/window-factory-ecore-wl.h similarity index 100% rename from dali/internal/window-system/tizen-wayland/window-factory-ecore-wl.h rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-factory-ecore-wl.h diff --git a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.cpp similarity index 99% rename from dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.cpp index 50d0777..5ad3fbe 100644 --- a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include +#include // EXTERNAL INCLUDES #include diff --git a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h b/dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.h similarity index 100% rename from dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h rename to dali/internal/window-system/tizen-wayland/ecore-wl/window-render-surface-ecore-wl.h diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/event-handler-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/event-handler-ecore-wl2.cpp new file mode 100755 index 0000000..ccf79eb --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/event-handler-ecore-wl2.cpp @@ -0,0 +1,1449 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +// Ecore is littered with C style cast +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" +#include +#include +#include +#include + +#include + +#ifndef DALI_PROFILE_UBUNTU +#include +#include +#endif // DALI_PROFILE_UBUNTU + +#ifdef DALI_ELDBUS_AVAILABLE +#include +#endif // DALI_ELDBUS_AVAILABLE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +#if defined(DEBUG_ENABLED) +namespace +{ +Integration::Log::Filter* gTouchEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH"); +Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND"); +Integration::Log::Filter* gImfLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF"); +Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION"); +} // unnamed namespace +#endif + + +namespace +{ + +// DBUS accessibility +const char* BUS = "org.enlightenment.wm-screen-reader"; +const char* INTERFACE = "org.tizen.GestureNavigation"; +const char* PATH = "/org/tizen/GestureNavigation"; + +const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 ); + +const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3; + +// Copied from x server +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); +} + +#ifndef DALI_PROFILE_UBUNTU +const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced. +#endif // DALI_PROFILE_UBUNTU + +/** + * Get the device name from the provided ecore key event + */ +void GetDeviceName( Ecore_Event_Key* keyEvent, std::string& result ) +{ + const char* ecoreDeviceName = ecore_device_name_get( keyEvent->dev ); + + if ( ecoreDeviceName ) + { + result = ecoreDeviceName; + } +} + +/** + * Get the device class from the provided ecore event + */ +void GetDeviceClass( Ecore_Device_Class ecoreDeviceClass, Device::Class::Type& deviceClass ) +{ + switch( ecoreDeviceClass ) + { + case ECORE_DEVICE_CLASS_SEAT: + { + deviceClass = Device::Class::USER; + break; + } + case ECORE_DEVICE_CLASS_KEYBOARD: + { + deviceClass = Device::Class::KEYBOARD; + break; + } + case ECORE_DEVICE_CLASS_MOUSE: + { + deviceClass = Device::Class::MOUSE; + break; + } + case ECORE_DEVICE_CLASS_TOUCH: + { + deviceClass = Device::Class::TOUCH; + break; + } + case ECORE_DEVICE_CLASS_PEN: + { + deviceClass = Device::Class::PEN; + break; + } + case ECORE_DEVICE_CLASS_POINTER: + { + deviceClass = Device::Class::POINTER; + break; + } + case ECORE_DEVICE_CLASS_GAMEPAD: + { + deviceClass = Device::Class::GAMEPAD; + break; + } + default: + { + deviceClass = Device::Class::NONE; + break; + } + } +} + +void GetDeviceSubclass( Ecore_Device_Subclass ecoreDeviceSubclass, Device::Subclass::Type& deviceSubclass ) +{ + switch( ecoreDeviceSubclass ) + { + case ECORE_DEVICE_SUBCLASS_FINGER: + { + deviceSubclass = Device::Subclass::FINGER; + break; + } + case ECORE_DEVICE_SUBCLASS_FINGERNAIL: + { + deviceSubclass = Device::Subclass::FINGERNAIL; + break; + } + case ECORE_DEVICE_SUBCLASS_KNUCKLE: + { + deviceSubclass = Device::Subclass::KNUCKLE; + break; + } + case ECORE_DEVICE_SUBCLASS_PALM: + { + deviceSubclass = Device::Subclass::PALM; + break; + } + case ECORE_DEVICE_SUBCLASS_HAND_SIZE: + { + deviceSubclass = Device::Subclass::HAND_SIDE; + break; + } + case ECORE_DEVICE_SUBCLASS_HAND_FLAT: + { + deviceSubclass = Device::Subclass::HAND_FLAT; + break; + } + case ECORE_DEVICE_SUBCLASS_PEN_TIP: + { + deviceSubclass = Device::Subclass::PEN_TIP; + break; + } + case ECORE_DEVICE_SUBCLASS_TRACKPAD: + { + deviceSubclass = Device::Subclass::TRACKPAD; + break; + } + case ECORE_DEVICE_SUBCLASS_TRACKPOINT: + { + deviceSubclass = Device::Subclass::TRACKPOINT; + break; + } + case ECORE_DEVICE_SUBCLASS_TRACKBALL: + { + deviceSubclass = Device::Subclass::TRACKBALL; + break; + } +#ifdef OVER_TIZEN_VERSION_4 + case ECORE_DEVICE_SUBCLASS_REMOCON: + { + deviceSubclass = Device::Subclass::REMOCON; + break; + } + case ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD: + { + deviceSubclass = Device::Subclass::VIRTUAL_KEYBOARD; + break; + } +#endif + default: + { + deviceSubclass = Device::Subclass::NONE; + break; + } + } +} + +} // unnamed namespace + +// Impl to hide EFL implementation. +struct EventHandler::Impl +{ + // Construction & Destruction + + /** + * Constructor + */ + Impl( EventHandler* handler, Ecore_Wl2_Window* window ) + : mHandler( handler ), + mEcoreEventHandler(), + mWindow( window ), + mRotationAngle( 0 ), + mWindowWidth( 0 ), + mWindowHeight( 0 ) +#ifdef DALI_ELDBUS_AVAILABLE + , mSystemConnection( NULL ) +#endif // DALI_ELDBUS_AVAILABLE + { + // Only register for touch and key events if we have a window + if ( window != 0 ) + { + // Register Touch events + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN, EcoreEventMouseButtonDown, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP, EcoreEventMouseButtonUp, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE, EcoreEventMouseButtonMove, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_CANCEL, EcoreEventMouseButtonCancel, handler ) ); + + // Register Mouse wheel events + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL, EcoreEventMouseWheel, handler ) ); + + // Register Focus events + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, handler ) ); + + // Register Key events + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN, EcoreEventKeyDown, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP, EcoreEventKeyUp, handler ) ); + + // Register Selection event - clipboard selection + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, handler ) ); + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, handler ) ); + + // Register Rotate event + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL2_EVENT_WINDOW_ROTATE, EcoreEventRotate, handler) ); + + // Register Detent event + mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_DETENT_ROTATE, EcoreEventDetent, handler) ); + +#ifndef DALI_PROFILE_UBUNTU + // Register Vconf notify - font name and size + vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged, handler ); + vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler ); +#endif // DALI_PROFILE_UBUNTU + +#ifdef DALI_ELDBUS_AVAILABLE + // Initialize ElDBus. + DALI_LOG_INFO( gImfLogging, Debug::General, "Starting DBus Initialization\n" ); + + // Pass in handler. + EcoreElDBusInitialisation( handler ); + + DALI_LOG_INFO( gImfLogging, Debug::General, "Finished DBus Initialization\n" ); +#endif // DALI_ELDBUS_AVAILABLE + } + } + + /** + * Destructor + */ + ~Impl() + { +#ifndef DALI_PROFILE_UBUNTU + vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged ); + vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged ); +#endif // DALI_PROFILE_UBUNTU + + for( std::vector::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter ) + { + ecore_event_handler_del( *iter ); + } + +#ifdef DALI_ELDBUS_AVAILABLE + // Close down ElDBus connections. + if( mSystemConnection ) + { + eldbus_connection_unref( mSystemConnection ); + } +#endif // DALI_ELDBUS_AVAILABLE + } + + // Static methods + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Touch Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Called when a touch down is received. + */ + static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event ) + { + Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event ); + EventHandler* handler( (EventHandler*)data ); + + if ( touchEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + PointState::Type state ( PointState::DOWN ); + + // Check if the buttons field is set and ensure it's the primary touch button. + // If this event was triggered by buttons other than the primary button (used for touch), then + // just send an interrupted event to Core. + if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) ) + { + state = PointState::INTERRUPTED; + } + + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; + + GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass ); + + Integration::Point point; + point.SetDeviceId( touchEvent->multi.device ); + point.SetState( state ); + point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) ); + point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) ); + point.SetPressure( touchEvent->multi.pressure ); + point.SetAngle( Degree( touchEvent->multi.angle ) ); + point.SetDeviceClass( deviceClass ); + point.SetDeviceSubclass( deviceSubclass ); + + handler->SendEvent( point, touchEvent->timestamp ); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a touch up is received. + */ + static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event ) + { + Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event ); + EventHandler* handler( (EventHandler*)data ); + + if ( touchEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; + + GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass ); + + Integration::Point point; + point.SetDeviceId( touchEvent->multi.device ); + point.SetState( PointState::UP ); + point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) ); + point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) ); + point.SetPressure( touchEvent->multi.pressure ); + point.SetAngle( Degree( touchEvent->multi.angle ) ); + point.SetDeviceClass( deviceClass ); + point.SetDeviceSubclass( deviceSubclass ); + + handler->SendEvent( point, touchEvent->timestamp ); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a touch motion is received. + */ + static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event ) + { + Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event ); + EventHandler* handler( (EventHandler*)data ); + + if ( touchEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; + + GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass ); + + Integration::Point point; + point.SetDeviceId( touchEvent->multi.device ); + point.SetState( PointState::MOTION ); + point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) ); + point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) ); + point.SetPressure( touchEvent->multi.pressure ); + point.SetAngle( Degree( touchEvent->multi.angle ) ); + point.SetDeviceClass( deviceClass ); + point.SetDeviceSubclass( deviceSubclass ); + + handler->SendEvent( point, touchEvent->timestamp ); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a touch is canceled. + */ + static Eina_Bool EcoreEventMouseButtonCancel( void* data, int type, void* event ) + { + Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event ); + EventHandler* handler( (EventHandler*)data ); + + if( touchEvent->window == (unsigned int)ecore_wl2_window_id_get( handler->mImpl->mWindow ) ) + { + Integration::Point point; + point.SetDeviceId( touchEvent->multi.device ); + point.SetState( PointState::INTERRUPTED ); + point.SetScreenPosition( Vector2( 0.0f, 0.0f ) ); + handler->SendEvent( point, touchEvent->timestamp ); + + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventMouseButtonCancel\n" ); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a mouse wheel is received. + */ + static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event ) + { + Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event ); + + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT Ecore_Event_Mouse_Wheel: direction: %d, modifiers: %d, x: %d, y: %d, z: %d\n", mouseWheelEvent->direction, mouseWheelEvent->modifiers, mouseWheelEvent->x, mouseWheelEvent->y, mouseWheelEvent->z); + + EventHandler* handler( (EventHandler*)data ); + if ( mouseWheelEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp ); + handler->SendWheelEvent( wheelEvent ); + } + return ECORE_CALLBACK_PASS_ON; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Key Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Called when a key down is received. + */ + static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event ) + { + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" ); + + EventHandler* handler( (EventHandler*)data ); + Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event ); + bool eventHandled( false ); + + // If the event wasn't handled then we should send a key event. + if ( !eventHandled ) + { + if ( keyEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + std::string keyName( keyEvent->keyname ); + std::string keyString( "" ); + std::string compose( "" ); + + // Ensure key compose string is not NULL as keys like SHIFT or arrow have a null string. + if ( keyEvent->compose ) + { + compose = keyEvent->compose; + } + + int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname); + keyCode = (keyCode == -1) ? 0 : keyCode; + int modifier( keyEvent->modifiers ); + unsigned long time = keyEvent->timestamp; + if (!strncmp(keyEvent->keyname, "Keycode-", 8)) + keyCode = atoi(keyEvent->keyname + 8); + + // Ensure key event string is not NULL as keys like SHIFT have a null string. + if ( keyEvent->string ) + { + keyString = keyEvent->string; + } + + std::string deviceName; + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; + + GetDeviceName( keyEvent, deviceName ); + GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass ); + + DALI_LOG_INFO( gImfLogging, Debug::Verbose, "EVENT EcoreEventKeyDown - >>EcoreEventKeyDown deviceName(%s) deviceClass(%d)\n", deviceName.c_str(), deviceClass ); + + Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, deviceName, deviceClass, deviceSubclass ); + handler->SendEvent( keyEvent ); + } + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a key up is received. + */ + static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event ) + { + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp\n" ); + + EventHandler* handler( (EventHandler*)data ); + Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event ); + bool eventHandled( false ); + + // If the event wasn't handled then we should send a key event. + if ( !eventHandled ) + { + if ( keyEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + std::string keyName( keyEvent->keyname ); + std::string keyString( "" ); + std::string compose( "" ); + + // Ensure key compose string is not NULL as keys like SHIFT or arrow have a null string. + if ( keyEvent->compose ) + { + compose = keyEvent->compose; + } + + int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname); + keyCode = (keyCode == -1) ? 0 : keyCode; + int modifier( keyEvent->modifiers ); + unsigned long time = keyEvent->timestamp; + if (!strncmp(keyEvent->keyname, "Keycode-", 8)) + keyCode = atoi(keyEvent->keyname + 8); + + // Ensure key event string is not NULL as keys like SHIFT have a null string. + if ( keyEvent->string ) + { + keyString = keyEvent->string; + } + + std::string deviceName; + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; + + GetDeviceName( keyEvent, deviceName ); + GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass ); + + Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, deviceName, deviceClass, deviceSubclass ); + handler->SendEvent( keyEvent ); + } + } + + return ECORE_CALLBACK_PASS_ON; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Window Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Called when the window gains focus. + */ + static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event ) + { + Ecore_Wl2_Event_Focus_In* focusInEvent( (Ecore_Wl2_Event_Focus_In*)event ); + EventHandler* handler( (EventHandler*)data ); + + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" ); + + // If the window gains focus and we hid the keyboard then show it again. + if ( focusInEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" ); + + Dali::Clipboard clipboard = Clipboard::Get(); + clipboard.HideClipboard(); + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the window loses focus. + */ + static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event ) + { + Ecore_Wl2_Event_Focus_Out* focusOutEvent( (Ecore_Wl2_Event_Focus_Out*)event ); + EventHandler* handler( (EventHandler*)data ); + + DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" ); + + // If the window loses focus then hide the keyboard. + if ( focusOutEvent->window == (unsigned int)ecore_wl2_window_id_get(handler->mImpl->mWindow) ) + { + // Hiding clipboard event will be ignored once because window focus out event is always received on showing clipboard + Dali::Clipboard clipboard = Clipboard::Get(); + if ( clipboard ) + { + Clipboard& clipBoardImpl( GetImplementation( clipboard ) ); + clipBoardImpl.HideClipboard(true); + } + } + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the window is damaged. + */ + static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event) + { + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the window properties are changed. + * We are only interested in the font change. + */ + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Drag & Drop Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Called when a dragged item enters our window's bounds. + * This is when items are dragged INTO our window. + */ + static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event ) + { + DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" ); + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a dragged item is moved within our window. + * This is when items are dragged INTO our window. + */ + static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event ) + { + DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" ); + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a dragged item leaves our window's bounds. + * This is when items are dragged INTO our window. + */ + static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event ) + { + DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" ); + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the dragged item is dropped within our window's bounds. + * This is when items are dragged INTO our window. + */ + static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event ) + { + DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" ); + + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a dragged item is moved from our window and the target window has done processing it. + * This is when items are dragged FROM our window. + */ + static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event ) + { + DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" ); + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when a dragged item is moved from our window and the target window has sent us a status. + * This is when items are dragged FROM our window. + */ + static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event ) + { + DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" ); + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the client messages (i.e. the accessibility events) are received. + */ + static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event ) + { + return ECORE_CALLBACK_PASS_ON; + } + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // ElDBus Accessibility Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef DALI_ELDBUS_AVAILABLE + // Callback for Ecore ElDBus accessibility events. + static void OnEcoreElDBusAccessibilityNotification( void *context EINA_UNUSED, const Eldbus_Message *message ) + { + EventHandler* handler = static_cast< EventHandler* >( context ); + // Ignore any accessibility events when paused. + if( handler->mPaused ) + { + return; + } + + if( !handler->mAccessibilityAdaptor ) + { + DALI_LOG_ERROR( "Invalid accessibility adaptor\n" ); + return; + } + + AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( handler->mAccessibilityAdaptor ) ); + if( !accessibilityAdaptor ) + { + DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" ); + return; + } + + int gestureValue; + int xS, yS, xE, yE; + int state; // 0 - begin, 1 - ongoing, 2 - ended, 3 - aborted + int eventTime; + + // The string defines the arg-list's respective types. + if( !eldbus_message_arguments_get( message, "iiiiiiu", &gestureValue, &xS, &yS, &xE, &yE, &state, &eventTime ) ) + { + DALI_LOG_ERROR( "OnEcoreElDBusAccessibilityNotification: Error getting arguments\n" ); + } + + DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Name: %d Args: %d,%d,%d,%d State: %d\n", gestureValue, xS, yS, xE, yE ); + + // Create a touch point object. + TouchPoint::State touchPointState( TouchPoint::Down ); + if( state == 0 ) + { + touchPointState = TouchPoint::Down; // Mouse down. + } + else if( state == 1 ) + { + touchPointState = TouchPoint::Motion; // Mouse move. + } + else if( state == 2 ) + { + touchPointState = TouchPoint::Up; // Mouse up. + } + else + { + touchPointState = TouchPoint::Interrupted; // Error. + } + + // Send touch event to accessibility adaptor. + TouchPoint point( 0, touchPointState, (float)xS, (float)yS ); + + // Perform actions based on received gestures. + // Note: This is seperated from the reading so we can have other input readers without changing the below code. + switch( gestureValue ) + { + case 0: // OneFingerHover + { + // Focus, read out. + accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ ); + break; + } + case 1: // TwoFingersHover + { + // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control + accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() ); + break; + } + case 2: // ThreeFingersHover + { + // Read from top item on screen continuously. + accessibilityAdaptor->HandleActionReadFromTopEvent(); + break; + } + case 3: // OneFingerFlickLeft + { + // Move to previous item. + accessibilityAdaptor->HandleActionReadPreviousEvent(); + break; + } + case 4: // OneFingerFlickRight + { + // Move to next item. + accessibilityAdaptor->HandleActionReadNextEvent(); + break; + } + case 5: // OneFingerFlickUp + { + // Move to previous item. + accessibilityAdaptor->HandleActionPreviousEvent(); + break; + } + case 6: // OneFingerFlickDown + { + // Move to next item. + accessibilityAdaptor->HandleActionNextEvent(); + break; + } + case 7: // TwoFingersFlickUp + { + // Scroll up the list. + accessibilityAdaptor->HandleActionScrollUpEvent(); + break; + } + case 8: // TwoFingersFlickDown + { + // Scroll down the list. + accessibilityAdaptor->HandleActionScrollDownEvent(); + break; + } + case 9: // TwoFingersFlickLeft + { + // Scroll left to the previous page + accessibilityAdaptor->HandleActionPageLeftEvent(); + break; + } + case 10: // TwoFingersFlickRight + { + // Scroll right to the next page + accessibilityAdaptor->HandleActionPageRightEvent(); + break; + } + case 11: // ThreeFingersFlickLeft + { + // Not exist yet + break; + } + case 12: // ThreeFingersFlickRight + { + // Not exist yet + break; + } + case 13: // ThreeFingersFlickUp + { + // Not exist yet + break; + } + case 14: // ThreeFingersFlickDown + { + // Not exist yet + break; + } + case 15: // OneFingerSingleTap + { + // Focus, read out. + accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ ); + break; + } + case 16: // OneFingerDoubleTap + { + // Activate selected item / active edit mode. + accessibilityAdaptor->HandleActionActivateEvent(); + break; + } + case 17: // OneFingerTripleTap + { + // Zoom + accessibilityAdaptor->HandleActionZoomEvent(); + break; + } + case 18: // TwoFingersSingleTap + { + // Pause/Resume current speech + accessibilityAdaptor->HandleActionReadPauseResumeEvent(); + break; + } + case 19: // TwoFingersDoubleTap + { + // Start/Stop current action + accessibilityAdaptor->HandleActionStartStopEvent(); + break; + } + case 20: // TwoFingersTripleTap + { + // Read information from indicator + accessibilityAdaptor->HandleActionReadIndicatorInformationEvent(); + break; + } + case 21: // ThreeFingersSingleTap + { + // Read from top item on screen continuously. + accessibilityAdaptor->HandleActionReadFromTopEvent(); + break; + } + case 22: // ThreeFingersDoubleTap + { + // Read from next item continuously. + accessibilityAdaptor->HandleActionReadFromNextEvent(); + break; + } + case 23: // ThreeFingersTripleTap + { + // Not exist yet + break; + } + case 24: // OneFingerFlickLeftReturn + { + // Scroll up to the previous page + accessibilityAdaptor->HandleActionPageUpEvent(); + break; + } + case 25: // OneFingerFlickRightReturn + { + // Scroll down to the next page + accessibilityAdaptor->HandleActionPageDownEvent(); + break; + } + case 26: // OneFingerFlickUpReturn + { + // Move to the first item on screen + accessibilityAdaptor->HandleActionMoveToFirstEvent(); + break; + } + case 27: // OneFingerFlickDownReturn + { + // Move to the last item on screen + accessibilityAdaptor->HandleActionMoveToLastEvent(); + break; + } + case 28: // TwoFingersFlickLeftReturn + { + // Not exist yet + break; + } + case 29: // TwoFingersFlickRightReturn + { + // Not exist yet + break; + } + case 30: // TwoFingersFlickUpReturn + { + // Not exist yet + break; + } + case 31: // TwoFingersFlickDownReturn + { + // Not exist yet + break; + } + case 32: // ThreeFingersFlickLeftReturn + { + // Not exist yet + break; + } + case 33: // ThreeFingersFlickRightReturn + { + // Not exist yet + break; + } + case 34: // ThreeFingersFlickUpReturn + { + // Not exist yet + break; + } + case 35: // ThreeFingersFlickDownReturn + { + // Not exist yet + break; + } + } + } + + void EcoreElDBusInitialisation( void *handle ) + { + Eldbus_Object *object; + Eldbus_Proxy *manager; + + if( !( mSystemConnection = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM) ) ) + { + DALI_LOG_ERROR( "Unable to get system bus\n" ); + } + + object = eldbus_object_get( mSystemConnection, BUS, PATH ); + if( !object ) + { + DALI_LOG_ERROR( "Getting object failed\n" ); + return; + } + + manager = eldbus_proxy_get( object, INTERFACE ); + if( !manager ) + { + DALI_LOG_ERROR( "Getting proxy failed\n" ); + return; + } + + if( !eldbus_proxy_signal_handler_add( manager, "GestureDetected", OnEcoreElDBusAccessibilityNotification, handle ) ) + { + DALI_LOG_ERROR( "No signal handler returned\n" ); + } + } +#endif // DALI_ELDBUS_AVAILABLE + + /** + * Called when the source window notifies us the content in clipboard is selected. + */ + static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event ) + { + DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" ); + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the source window sends us about the selected content. + * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard. + */ + static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event ) + { + DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" ); + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the source window notifies us the content in clipboard is selected. + */ + static Eina_Bool EcoreEventDataSend( void* data, int type, void* event ) + { + DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataSend\n" ); + + Dali::Clipboard clipboard = Clipboard::Get(); + if ( clipboard ) + { + Clipboard& clipBoardImpl( GetImplementation( clipboard ) ); + clipBoardImpl.ExcuteBuffered( true, event ); + } + return ECORE_CALLBACK_PASS_ON; + } + + /** + * Called when the source window sends us about the selected content. + * For example, when item is selected in the clipboard. + */ + static Eina_Bool EcoreEventDataReceive( void* data, int type, void* event ) + { + DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataReceive\n" ); + + EventHandler* handler( (EventHandler*)data ); + Dali::Clipboard clipboard = Clipboard::Get(); + char *selectionData = NULL; + if ( clipboard ) + { + Clipboard& clipBoardImpl( GetImplementation( clipboard ) ); + selectionData = clipBoardImpl.ExcuteBuffered( false, event ); + } + if ( selectionData && handler->mClipboardEventNotifier ) + { + ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) ); + std::string content( selectionData, strlen(selectionData) ); + + clipboardEventNotifier.SetContent( content ); + clipboardEventNotifier.EmitContentSelectedSignal(); + } + return ECORE_CALLBACK_PASS_ON; + } + + /* + * Called when rotate event is recevied + */ + static Eina_Bool EcoreEventRotate( void* data, int type, void* event ) + { + DALI_LOG_INFO( gSelectionEventLogFilter, Debug::Concise, "EcoreEventRotate\n" ); + + EventHandler* handler( (EventHandler*)data ); + Ecore_Wl2_Event_Window_Rotation* ev( (Ecore_Wl2_Event_Window_Rotation*)event ); + + if( ev->win != (unsigned int)ecore_wl2_window_id_get( handler->mImpl->mWindow ) ) + { + return ECORE_CALLBACK_PASS_ON; + } + + RotationEvent rotationEvent; + rotationEvent.angle = ev->angle; + rotationEvent.winResize = 0; + + if( ev->angle == 0 || ev->angle == 180 ) + { + rotationEvent.width = ev->w; + rotationEvent.height = ev->h; + } + else + { + rotationEvent.width = ev->h; + rotationEvent.height = ev->w; + } + + handler->SendRotationPrepareEvent( rotationEvent ); + + return ECORE_CALLBACK_PASS_ON; + } + + /* + * Called when detent event is recevied + */ + static Eina_Bool EcoreEventDetent( void* data, int type, void* event ) + { + DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDetent\n" ); + EventHandler* handler( (EventHandler*)data ); + Ecore_Event_Detent_Rotate *e((Ecore_Event_Detent_Rotate *)event); + int direction = (e->direction == ECORE_DETENT_DIRECTION_CLOCKWISE) ? 1 : -1; + int timeStamp = e->timestamp; + + WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), direction, timeStamp ); + handler->SendWheelEvent( wheelEvent ); + return ECORE_CALLBACK_PASS_ON; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Font Callbacks + ///////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Called when a font name is changed. + */ + static void VconfNotifyFontNameChanged( keynode_t* node, void* data ) + { + EventHandler* handler = static_cast( data ); + handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE ); + } + + /** + * Called when a font size is changed. + */ + static void VconfNotifyFontSizeChanged( keynode_t* node, void* data ) + { + EventHandler* handler = static_cast( data ); + handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE ); + } + + void ConvertTouchPosition( Integration::Point& point ) + { + Vector2 position = point.GetScreenPosition(); + Vector2 convertedPosition; + + switch( mRotationAngle ) + { + case 90: + { + convertedPosition.x = mWindowWidth - position.y; + convertedPosition.y = position.x; + break; + } + case 180: + { + convertedPosition.x = mWindowWidth - position.x; + convertedPosition.y = mWindowHeight - position.y; + break; + } + case 270: + { + convertedPosition.x = position.y; + convertedPosition.y = mWindowHeight - position.x; + break; + } + default: + { + convertedPosition = position; + break; + } + } + + point.SetScreenPosition( convertedPosition ); + } + + // Data + EventHandler* mHandler; + std::vector mEcoreEventHandler; + Ecore_Wl2_Window* mWindow; + int mRotationAngle; + int mWindowWidth; + int mWindowHeight; +#ifdef DALI_ELDBUS_AVAILABLE + Eldbus_Connection* mSystemConnection; +#endif // DALI_ELDBUS_AVAILABLE +}; + +EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector ) +: mCoreEventInterface( coreEventInterface ), + mGestureManager( gestureManager ), + mStyleMonitor( StyleMonitor::Get() ), + mDamageObserver( damageObserver ), + mRotationObserver( NULL ), + mDragAndDropDetector( dndDetector ), + mAccessibilityAdaptor( AccessibilityAdaptor::Get() ), + mClipboardEventNotifier( ClipboardEventNotifier::Get() ), + mClipboard( Clipboard::Get() ), + mImpl( NULL ), + mPaused( false ) +{ + Ecore_Wl2_Window* window = 0; + + // this code only works with the WindowRenderSurface so need to downcast + WindowRenderSurfaceEcoreWl2* ecoreSurface = static_cast< WindowRenderSurfaceEcoreWl2* >( surface ); + if( ecoreSurface ) + { + window = ecoreSurface->GetWlWindow(); + } + + mImpl = new Impl(this, window); +} + +EventHandler::~EventHandler() +{ + if(mImpl) + { + delete mImpl; + } + + mGestureManager.Stop(); +} + +void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp) +{ + if(timeStamp < 1) + { + timeStamp = GetCurrentMilliSeconds(); + } + + mImpl->ConvertTouchPosition( point ); + + Integration::TouchEvent touchEvent; + Integration::HoverEvent hoverEvent; + Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent); + if(type != Integration::TouchEventCombiner::DispatchNone ) + { + DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.GetDeviceId(), point.GetState(), point.GetScreenPosition().x, point.GetScreenPosition().y); + + // First the touch and/or hover event & related gesture events are queued + if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth) + { + mCoreEventInterface.QueueCoreEvent( touchEvent ); + mGestureManager.SendEvent(touchEvent); + } + + if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth) + { + mCoreEventInterface.QueueCoreEvent( hoverEvent ); + } + + // Next the events are processed with a single call into Core + mCoreEventInterface.ProcessCoreEvents(); + } +} + +void EventHandler::SendEvent(Integration::KeyEvent& keyEvent) +{ + Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get(); + if ( physicalKeyboard ) + { + if ( ! KeyLookup::IsDeviceButton( keyEvent.keyName.c_str() ) ) + { + GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 ); + } + } + + // Create send KeyEvent to Core. + mCoreEventInterface.QueueCoreEvent( keyEvent ); + mCoreEventInterface.ProcessCoreEvents(); +} + +void EventHandler::SendWheelEvent( WheelEvent& wheelEvent ) +{ + // Create WheelEvent and send to Core. + Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp ); + mCoreEventInterface.QueueCoreEvent( event ); + mCoreEventInterface.ProcessCoreEvents(); +} + +void EventHandler::SendEvent( StyleChange::Type styleChange ) +{ + DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" ); + GetImplementation( mStyleMonitor ).StyleChanged(styleChange); +} + +void EventHandler::SendEvent( const DamageArea& area ) +{ + mDamageObserver.OnDamaged( area ); +} + +void EventHandler::SendRotationPrepareEvent( const RotationEvent& event ) +{ + if( mRotationObserver != NULL ) + { + mImpl->mRotationAngle = event.angle; + mImpl->mWindowWidth = event.width; + mImpl->mWindowHeight = event.height; + + mRotationObserver->OnRotationPrepare( event ); + mRotationObserver->OnRotationRequest(); + } +} + +void EventHandler::SendRotationRequestEvent( ) +{ + // No need to separate event into prepare and request in wayland +} + +void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp) +{ + Integration::Point convertedPoint( point ); + SendEvent(convertedPoint, timeStamp); +} + +void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent ) +{ + SendWheelEvent( wheelEvent ); +} + +void EventHandler::FeedKeyEvent( KeyEvent& event ) +{ + Integration::KeyEvent convertedEvent( event ); + SendEvent( convertedEvent ); +} + +void EventHandler::FeedEvent( Integration::Event& event ) +{ + mCoreEventInterface.QueueCoreEvent( event ); + mCoreEventInterface.ProcessCoreEvents(); +} + +void EventHandler::Reset() +{ + mCombiner.Reset(); + + // Any touch listeners should be told of the interruption. + Integration::TouchEvent event; + Integration::Point point; + point.SetState( PointState::INTERRUPTED ); + event.AddPoint( point ); + + // First the touch event & related gesture events are queued + mCoreEventInterface.QueueCoreEvent( event ); + mGestureManager.SendEvent( event ); + + // Next the events are processed with a single call into Core + mCoreEventInterface.ProcessCoreEvents(); +} + +void EventHandler::Pause() +{ + mPaused = true; + Reset(); +} + +void EventHandler::Resume() +{ + mPaused = false; + Reset(); +} + +void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector ) +{ + mDragAndDropDetector = detector; +} + +void EventHandler::SetRotationObserver( RotationObserver* observer ) +{ + mRotationObserver = observer; +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#pragma GCC diagnostic pop diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.cpp new file mode 100644 index 0000000..b372d38 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL HEADERS +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +std::unique_ptr< WindowRenderSurface > RenderSurfaceFactoryEcoreWl2::CreateWindowRenderSurface( Dali::PositionSize positionSize, + Any surface, + const std::string& name, + const std::string& className, + bool isTransparent ) +{ + return Utils::MakeUnique< WindowRenderSurfaceEcoreWl2 >( positionSize, surface, name, isTransparent ); +} + +std::unique_ptr< PixmapRenderSurface > RenderSurfaceFactoryEcoreWl2::CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, + const std::string& name, bool isTransparent ) +{ + return std::unique_ptr< PixmapRenderSurface >( nullptr ); +} + +std::unique_ptr< NativeRenderSurface > RenderSurfaceFactoryEcoreWl2::CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent ) +{ + return Utils::MakeUnique< NativeRenderSurfaceEcoreWl >( positionSize, name, isTransparent ); +} + +// this should be created from somewhere +std::unique_ptr< RenderSurfaceFactory > GetRenderSurfaceFactory() +{ + // returns Window factory + return Utils::MakeUnique< RenderSurfaceFactoryEcoreWl2 >(); +} + +} // namespace Adaptor +} // namespace Internal +} // namespace Dali diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.h new file mode 100644 index 0000000..0bcc4d0 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/render-surface-factory-ecore-wl2.h @@ -0,0 +1,46 @@ +#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_RENDER_SURFACE_FACTORY_ECORE_WL2_H +#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_RENDER_SURFACE_FACTORY_ECORE_WL2_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +class RenderSurfaceFactoryEcoreWl2 : public RenderSurfaceFactory +{ +public: + std::unique_ptr< WindowRenderSurface > CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, + const std::string& name, const std::string& className, bool isTransparent = false ) override; + + std::unique_ptr< PixmapRenderSurface > CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, + const std::string& name, bool isTransparent = false ) override; + + std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent = false ) override; +}; + +} // namespace Adaptor +} // namespace Internal +} // namespace Dali + +#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_RENDER_SURFACE_FACTORY_ECORE_WL2_H diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp new file mode 100644 index 0000000..d4017ca --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp @@ -0,0 +1,1233 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Ecore is littered with C style cast +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + +// CLASS HEADER +#include + +// INTERNAL HEADERS +#include +#include +#include + +// EXTERNAL_HEADERS +#include +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +namespace +{ + +#if defined(DEBUG_ENABLED) +Debug::Filter* gWindowBaseLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW_BASE" ); +#endif + +const uint32_t MAX_TIZEN_CLIENT_VERSION = 7; + +/// Called when the window iconify state is changed. +static Eina_Bool EcoreEventWindowIconifyStateChanged( void* data, int type, void* event ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + return windowBase->OnIconifyStateChanged( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +/// Called when the window gains focus +static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + return windowBase->OnFocusIn( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +/// Called when the window loses focus +static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + return windowBase->OnFocusOut( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +/// Called when the output is transformed +static Eina_Bool EcoreEventOutputTransform( void* data, int type, void* event ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + return windowBase->OnOutputTransform( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +/// Called when the output transform should be ignored +static Eina_Bool EcoreEventIgnoreOutputTransform( void* data, int type, void* event ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + return windowBase->OnIgnoreOutputTransform( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +static void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + windowBase->RegistryGlobalCallback( data, registry, name, interface, version ); + } +} + +static void RegistryGlobalCallbackRemove( void* data, struct wl_registry* registry, uint32_t id ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + windowBase->RegistryGlobalCallbackRemove( data, registry, id ); + } +} + +static void TizenPolicyConformant( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t isConformant ) +{ +} + +static void TizenPolicyConformantArea( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h ) +{ +} + +static void TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + windowBase->TizenPolicyNotificationChangeDone( data, tizenPolicy, surface, level, state ); + } +} + +static void TizenPolicyTransientForDone( void* data, struct tizen_policy* tizenPolicy, uint32_t childId ) +{ +} + +static void TizenPolicyScreenModeChangeDone( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t mode, uint32_t state ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + windowBase->TizenPolicyScreenModeChangeDone( data, tizenPolicy, surface, mode, state ); + } +} + +static void TizenPolicyIconifyStateChanged( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t iconified, uint32_t force ) +{ +} + +static void TizenPolicySupportedAuxiliaryHints( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, struct wl_array* hints, uint32_t numNints ) +{ +} + +static void TizenPolicyAllowedAuxiliaryHint( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int id ) +{ +} + +static void TizenPolicyAuxiliaryMessage( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, const char* key, const char* val, struct wl_array* options ) +{ +} + +static void TizenPolicyConformantRegion( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t serial ) +{ +} + +static void DisplayPolicyBrightnessChangeDone( void* data, struct tizen_display_policy *displayPolicy, struct wl_surface* surface, int32_t brightness, uint32_t state ) +{ + WindowBaseEcoreWl2* windowBase = static_cast< WindowBaseEcoreWl2* >( data ); + if( windowBase ) + { + windowBase->DisplayPolicyBrightnessChangeDone( data, displayPolicy, surface, brightness, state ); + } +} + +const struct wl_registry_listener registryListener = +{ + RegistryGlobalCallback, + RegistryGlobalCallbackRemove +}; + +const struct tizen_policy_listener tizenPolicyListener = +{ + TizenPolicyConformant, + TizenPolicyConformantArea, + TizenPolicyNotificationChangeDone, + TizenPolicyTransientForDone, + TizenPolicyScreenModeChangeDone, + TizenPolicyIconifyStateChanged, + TizenPolicySupportedAuxiliaryHints, + TizenPolicyAllowedAuxiliaryHint, + TizenPolicyAuxiliaryMessage, + TizenPolicyConformantRegion +}; + +const struct tizen_display_policy_listener tizenDisplayPolicyListener = +{ + DisplayPolicyBrightnessChangeDone +}; + +} // unnamed namespace + +WindowBaseEcoreWl2::WindowBaseEcoreWl2( Window* window, WindowRenderSurface* windowRenderSurface ) +: mEcoreEventHandler(), + mWindow( window ), + mWindowSurface( NULL ), + mEcoreWindow( NULL ), + mDisplay( NULL ), + mEventQueue( NULL ), + mTizenPolicy( NULL ), + mTizenDisplayPolicy( NULL ), + mSupportedAuxiliaryHints(), + mAuxiliaryHints(), + mNotificationLevel( -1 ), + mNotificationChangeState( 0 ), + mNotificationLevelChangeDone( true ), + mScreenOffMode( 0 ), + mScreenOffModeChangeState( 0 ), + mScreenOffModeChangeDone( true ), + mBrightness( 0 ), + mBrightnessChangeState( 0 ), + mBrightnessChangeDone( true ) +{ + mWindowSurface = dynamic_cast< WindowRenderSurfaceEcoreWl2* >( windowRenderSurface ); +} + +WindowBaseEcoreWl2::~WindowBaseEcoreWl2() +{ + for( Dali::Vector< Ecore_Event_Handler* >::Iterator iter = mEcoreEventHandler.Begin(), endIter = mEcoreEventHandler.End(); iter != endIter; ++iter ) + { + ecore_event_handler_del( *iter ); + } + mEcoreEventHandler.Clear(); + + if( mEventQueue ) + { + wl_event_queue_destroy( mEventQueue ); + } + + mSupportedAuxiliaryHints.clear(); + mAuxiliaryHints.clear(); +} + +void WindowBaseEcoreWl2::Initialize() +{ + if( !mWindowSurface ) + { + DALI_ASSERT_ALWAYS( "Invalid window surface" ); + } + + mEcoreWindow = mWindowSurface->GetWlWindow(); + DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no EcoreWl window" ); + + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_OUTPUT_TRANSFORM, EcoreEventOutputTransform, this) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM, EcoreEventIgnoreOutputTransform, this) ); + + Ecore_Wl2_Display* display = ecore_wl2_connected_display_get( NULL ); + mDisplay = ecore_wl2_display_get( display ); + + if( mDisplay ) + { + wl_display* displayWrapper = static_cast< wl_display* >( wl_proxy_create_wrapper( mDisplay ) ); + if( displayWrapper ) + { + mEventQueue = wl_display_create_queue( mDisplay ); + if( mEventQueue ) + { + wl_proxy_set_queue( reinterpret_cast< wl_proxy* >( displayWrapper ), mEventQueue ); + + wl_registry* registry = wl_display_get_registry( displayWrapper ); + wl_registry_add_listener( registry, ®istryListener, this ); + } + + wl_proxy_wrapper_destroy( displayWrapper ); + } + } + + // get auxiliary hint + Eina_List* hints = ecore_wl2_window_aux_hints_supported_get( mEcoreWindow ); + if( hints ) + { + Eina_List* l = NULL; + char* hint = NULL; + + for( l = hints, ( hint = static_cast< char* >( eina_list_data_get(l) ) ); l; l = eina_list_next(l), ( hint = static_cast< char* >( eina_list_data_get(l) ) ) ) + { + mSupportedAuxiliaryHints.push_back( hint ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::Initialize: %s\n", hint ); + } + } +} + +Eina_Bool WindowBaseEcoreWl2::OnIconifyStateChanged( void* data, int type, void* event ) +{ + Ecore_Wl2_Event_Window_Iconify_State_Change* iconifyChangedEvent( static_cast< Ecore_Wl2_Event_Window_Iconify_State_Change* >( event ) ); + Eina_Bool handled( ECORE_CALLBACK_PASS_ON ); + + if( iconifyChangedEvent->win == static_cast< unsigned int>( ecore_wl2_window_id_get( mEcoreWindow ) ) ) + { + if( iconifyChangedEvent->iconified == EINA_TRUE ) + { + mWindow->OnIconifyChanged( true ); + } + else + { + mWindow->OnIconifyChanged( false ); + } + handled = ECORE_CALLBACK_DONE; + } + + return handled; +} + +Eina_Bool WindowBaseEcoreWl2::OnFocusIn( void* data, int type, void* event ) +{ + Ecore_Wl2_Event_Focus_In* focusInEvent( static_cast< Ecore_Wl2_Event_Focus_In* >( event ) ); + + if( focusInEvent->window == static_cast< unsigned int >( ecore_wl2_window_id_get( mEcoreWindow ) ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" ); + + mWindow->OnFocusChanged( true ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl2::OnFocusOut( void* data, int type, void* event ) +{ + Ecore_Wl2_Event_Focus_Out* focusOutEvent( static_cast< Ecore_Wl2_Event_Focus_Out* >( event ) ); + + if( focusOutEvent->window == static_cast< unsigned int >( ecore_wl2_window_id_get( mEcoreWindow ) ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" ); + + mWindow->OnFocusChanged( false ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl2::OnOutputTransform( void* data, int type, void* event ) +{ + Ecore_Wl2_Event_Output_Transform* transformEvent( static_cast< Ecore_Wl2_Event_Output_Transform* >( event ) ); + + if( transformEvent->output == ecore_wl2_window_output_find( mEcoreWindow ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventOutputTransform\n", mEcoreWindow ); + + mWindowSurface->OutputTransformed(); + + mWindow->OnOutputTransformed(); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl2::OnIgnoreOutputTransform( void* data, int type, void* event ) +{ + Ecore_Wl2_Event_Ignore_Output_Transform* ignoreTransformEvent( static_cast< Ecore_Wl2_Event_Ignore_Output_Transform* >( event ) ); + + if( ignoreTransformEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventIgnoreOutputTransform\n", mEcoreWindow ); + + mWindowSurface->OutputTransformed(); + + mWindow->OnOutputTransformed(); + } + + return ECORE_CALLBACK_PASS_ON; +} + +void WindowBaseEcoreWl2::RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ) +{ + if( strcmp( interface, tizen_policy_interface.name ) == 0 ) + { + uint32_t clientVersion = std::min( version, MAX_TIZEN_CLIENT_VERSION ); + + mTizenPolicy = static_cast< tizen_policy* >( wl_registry_bind( registry, name, &tizen_policy_interface, clientVersion ) ); + if( !mTizenPolicy ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::RegistryGlobalCallback: wl_registry_bind(tizen_policy_interface) is failed.\n" ); + return; + } + + tizen_policy_add_listener( mTizenPolicy, &tizenPolicyListener, data ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::RegistryGlobalCallback: tizen_policy_add_listener is called.\n" ); + } + else if( strcmp( interface, tizen_display_policy_interface.name ) == 0 ) + { + mTizenDisplayPolicy = static_cast< tizen_display_policy* >( wl_registry_bind( registry, name, &tizen_display_policy_interface, version ) ); + if( !mTizenDisplayPolicy ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::RegistryGlobalCallback: wl_registry_bind(tizen_display_policy_interface) is failed.\n" ); + return; + } + + tizen_display_policy_add_listener( mTizenDisplayPolicy, &tizenDisplayPolicyListener, data ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::RegistryGlobalCallback: tizen_display_policy_add_listener is called.\n" ); + } +} + +void WindowBaseEcoreWl2::RegistryGlobalCallbackRemove( void* data, struct wl_registry* registry, uint32_t id ) +{ + mTizenPolicy = NULL; + mTizenDisplayPolicy = NULL; +} + +void WindowBaseEcoreWl2::TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state ) +{ + mNotificationLevel = level; + mNotificationChangeState = state; + mNotificationLevelChangeDone = true; + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::TizenPolicyNotificationChangeDone: level = %d, state = %d\n", level, state ); +} + +void WindowBaseEcoreWl2::TizenPolicyScreenModeChangeDone( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t mode, uint32_t state ) +{ + mScreenOffMode = mode; + mScreenOffModeChangeState = state; + mScreenOffModeChangeDone = true; + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::TizenPolicyScreenModeChangeDone: mode = %d, state = %d\n", mode, state ); +} + +void WindowBaseEcoreWl2::DisplayPolicyBrightnessChangeDone( void* data, struct tizen_display_policy *displayPolicy, struct wl_surface* surface, int32_t brightness, uint32_t state ) +{ + mBrightness = brightness; + mBrightnessChangeState = state; + mBrightnessChangeDone = true; + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::DisplayPolicyBrightnessChangeDone: brightness = %d, state = %d\n", brightness, state ); +} + +void WindowBaseEcoreWl2::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode, Dali::Window::IndicatorBgOpacity opacityMode ) +{ + DALI_LOG_TRACE_METHOD_FMT( gWindowBaseLogFilter, "visible : %d\n", visibleMode ); + + if( visibleMode == Dali::Window::VISIBLE ) + { + // when the indicator is visible, set proper mode for indicator server according to bg mode + if( opacityMode == Dali::Window::OPAQUE ) + { + ecore_wl2_window_indicator_opacity_set( mEcoreWindow, ECORE_WL2_INDICATOR_OPAQUE ); + } + else if( opacityMode == Dali::Window::TRANSLUCENT ) + { + ecore_wl2_window_indicator_opacity_set( mEcoreWindow, ECORE_WL2_INDICATOR_TRANSLUCENT ); + } + else if( opacityMode == Dali::Window::TRANSPARENT ) + { + ecore_wl2_window_indicator_opacity_set( mEcoreWindow, ECORE_WL2_INDICATOR_OPAQUE ); + } + } + else + { + // when the indicator is not visible, set TRANSPARENT mode for indicator server + ecore_wl2_window_indicator_opacity_set( mEcoreWindow, ECORE_WL2_INDICATOR_TRANSPARENT); // it means hidden indicator + } +} + +void WindowBaseEcoreWl2::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation ) +{ + if( isShow ) + { + ecore_wl2_window_indicator_state_set( mEcoreWindow, ECORE_WL2_INDICATOR_STATE_ON ); + } + else + { + ecore_wl2_window_indicator_state_set( mEcoreWindow, ECORE_WL2_INDICATOR_STATE_OFF ); + } +} + +void WindowBaseEcoreWl2::IndicatorTypeChanged( IndicatorInterface::Type type ) +{ +#if defined(DALI_PROFILE_MOBILE) + switch( type ) + { + case IndicatorInterface::INDICATOR_TYPE_1: + { + ecore_wl2_indicator_visible_type_set( mEcoreWindow, ECORE_WL2_INDICATOR_VISIBLE_TYPE_SHOWN ); + break; + } + case IndicatorInterface::INDICATOR_TYPE_2: + { + ecore_wl2_indicator_visible_type_set( mEcoreWindow, ECORE_WL2_INDICATOR_VISIBLE_TYPE_HIDDEN ); + break; + } + case IndicatorInterface::INDICATOR_TYPE_UNKNOWN: + default: + { + break; + } + } +#endif //MOBILE +} + +void WindowBaseEcoreWl2::SetClass( std::string name, std::string className ) +{ + ecore_wl2_window_title_set( mEcoreWindow, name.c_str() ); + ecore_wl2_window_class_set( mEcoreWindow, className.c_str() ); +} + +void WindowBaseEcoreWl2::Raise() +{ + // Use ecore_wl2_window_activate to prevent the window shown without rendering + ecore_wl2_window_activate( mEcoreWindow ); +} + +void WindowBaseEcoreWl2::Lower() +{ + ecore_wl2_window_lower( mEcoreWindow ); +} + +void WindowBaseEcoreWl2::Activate() +{ + ecore_wl2_window_activate( mEcoreWindow ); +} + +void WindowBaseEcoreWl2::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations ) +{ + int rotations[4] = { 0 }; + for( std::size_t i = 0; i < orientations.size(); ++i ) + { + rotations[i] = static_cast< int >( orientations[i] ); + } + ecore_wl2_window_available_rotations_set( mEcoreWindow, rotations, orientations.size() ); +} + +void WindowBaseEcoreWl2::SetPreferredOrientation( Dali::Window::WindowOrientation orientation ) +{ + ecore_wl2_window_preferred_rotation_set( mEcoreWindow, orientation ); +} + +void WindowBaseEcoreWl2::SetAcceptFocus( bool accept ) +{ + ecore_wl2_window_focus_skip_set( mEcoreWindow, !accept ); +} + +void WindowBaseEcoreWl2::Show() +{ + ecore_wl2_window_show( mEcoreWindow ); +} + +void WindowBaseEcoreWl2::Hide() +{ + ecore_wl2_window_hide( mEcoreWindow ); +} + +unsigned int WindowBaseEcoreWl2::GetSupportedAuxiliaryHintCount() const +{ + return mSupportedAuxiliaryHints.size(); +} + +std::string WindowBaseEcoreWl2::GetSupportedAuxiliaryHint( unsigned int index ) const +{ + if( index >= GetSupportedAuxiliaryHintCount() ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetSupportedAuxiliaryHint: Invalid index! [%d]\n", index ); + } + + return mSupportedAuxiliaryHints[index]; +} + +unsigned int WindowBaseEcoreWl2::AddAuxiliaryHint( const std::string& hint, const std::string& value ) +{ + bool supported = false; + + // Check if the hint is suppported + for( std::vector< std::string >::iterator iter = mSupportedAuxiliaryHints.begin(); iter != mSupportedAuxiliaryHints.end(); ++iter ) + { + if( *iter == hint ) + { + supported = true; + break; + } + } + + if( !supported ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, "WindowBaseEcoreWl2::AddAuxiliaryHint: Not supported auxiliary hint [%s]\n", hint.c_str() ); + return 0; + } + + // Check if the hint is already added + for( unsigned int i = 0; i < mAuxiliaryHints.size(); i++ ) + { + if( mAuxiliaryHints[i].first == hint ) + { + // Just change the value + mAuxiliaryHints[i].second = value; + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::AddAuxiliaryHint: Change! hint = %s, value = %s, id = %d\n", hint.c_str(), value.c_str(), i + 1 ); + + return i + 1; // id is index + 1 + } + } + + // Add the hint + mAuxiliaryHints.push_back( std::pair< std::string, std::string >( hint, value ) ); + + unsigned int id = mAuxiliaryHints.size(); + + ecore_wl2_window_aux_hint_add( mEcoreWindow, static_cast< int >( id ), hint.c_str(), value.c_str() ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::AddAuxiliaryHint: hint = %s, value = %s, id = %d\n", hint.c_str(), value.c_str(), id ); + + return id; +} + +bool WindowBaseEcoreWl2::RemoveAuxiliaryHint( unsigned int id ) +{ + if( id == 0 || id > mAuxiliaryHints.size() ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, "WindowBaseEcoreWl2::RemoveAuxiliaryHint: Invalid id [%d]\n", id ); + return false; + } + + mAuxiliaryHints[id - 1].second = std::string(); + + ecore_wl2_window_aux_hint_del( mEcoreWindow, static_cast< int >( id ) ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::RemoveAuxiliaryHint: id = %d, hint = %s\n", id, mAuxiliaryHints[id - 1].first.c_str() ); + + return true; +} + +bool WindowBaseEcoreWl2::SetAuxiliaryHintValue( unsigned int id, const std::string& value ) +{ + if( id == 0 || id > mAuxiliaryHints.size() ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, "WindowBaseEcoreWl2::SetAuxiliaryHintValue: Invalid id [%d]\n", id ); + return false; + } + + mAuxiliaryHints[id - 1].second = value; + + ecore_wl2_window_aux_hint_change( mEcoreWindow, static_cast< int >( id ), value.c_str() ); + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetAuxiliaryHintValue: id = %d, hint = %s, value = %s\n", id, mAuxiliaryHints[id - 1].first.c_str(), mAuxiliaryHints[id - 1].second.c_str() ); + + return true; +} + +std::string WindowBaseEcoreWl2::GetAuxiliaryHintValue( unsigned int id ) const +{ + if( id == 0 || id > mAuxiliaryHints.size() ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, "WindowBaseEcoreWl2::GetAuxiliaryHintValue: Invalid id [%d]\n", id ); + return std::string(); + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetAuxiliaryHintValue: id = %d, hint = %s, value = %s\n", id, mAuxiliaryHints[id - 1].first.c_str(), mAuxiliaryHints[id - 1].second.c_str() ); + + return mAuxiliaryHints[id - 1].second; +} + +unsigned int WindowBaseEcoreWl2::GetAuxiliaryHintId( const std::string& hint ) const +{ + for( unsigned int i = 0; i < mAuxiliaryHints.size(); i++ ) + { + if( mAuxiliaryHints[i].first == hint ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetAuxiliaryHintId: hint = %s, id = %d\n", hint.c_str(), i + 1 ); + return i + 1; + } + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetAuxiliaryHintId: Invalid hint! [%s]\n", hint.c_str() ); + + return 0; +} + +void WindowBaseEcoreWl2::SetInputRegion( const Rect< int >& inputRegion ) +{ + ecore_wl2_window_input_region_set( mEcoreWindow, inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height ); +} + +void WindowBaseEcoreWl2::SetType( Dali::Window::Type type ) +{ + Ecore_Wl2_Window_Type windowType; + + switch( type ) + { + case Dali::Window::NORMAL: + { + windowType = ECORE_WL2_WINDOW_TYPE_TOPLEVEL; + break; + } + case Dali::Window::NOTIFICATION: + { + windowType = ECORE_WL2_WINDOW_TYPE_NOTIFICATION; + break; + } + case Dali::Window::UTILITY: + { + windowType = ECORE_WL2_WINDOW_TYPE_UTILITY; + break; + } + case Dali::Window::DIALOG: + { + windowType = ECORE_WL2_WINDOW_TYPE_DIALOG; + break; + } + default: + { + windowType = ECORE_WL2_WINDOW_TYPE_TOPLEVEL; + break; + } + } + + ecore_wl2_window_type_set( mEcoreWindow, windowType ); +} + +bool WindowBaseEcoreWl2::SetNotificationLevel( Dali::Window::NotificationLevel::Type level ) +{ + while( !mTizenPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + int notificationLevel; + + switch( level ) + { + case Dali::Window::NotificationLevel::NONE: + { + notificationLevel = TIZEN_POLICY_LEVEL_NONE; + break; + } + case Dali::Window::NotificationLevel::BASE: + { + notificationLevel = TIZEN_POLICY_LEVEL_DEFAULT; + break; + } + case Dali::Window::NotificationLevel::MEDIUM: + { + notificationLevel = TIZEN_POLICY_LEVEL_MEDIUM; + break; + } + case Dali::Window::NotificationLevel::HIGH: + { + notificationLevel = TIZEN_POLICY_LEVEL_HIGH; + break; + } + case Dali::Window::NotificationLevel::TOP: + { + notificationLevel = TIZEN_POLICY_LEVEL_TOP; + break; + } + default: + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: invalid level [%d]\n", level ); + notificationLevel = TIZEN_POLICY_LEVEL_DEFAULT; + break; + } + } + + mNotificationLevelChangeDone = false; + mNotificationChangeState = TIZEN_POLICY_ERROR_STATE_NONE; + + tizen_policy_set_notification_level( mTizenPolicy, ecore_wl2_window_surface_get( mEcoreWindow ), notificationLevel ); + + int count = 0; + + while( !mNotificationLevelChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mNotificationLevelChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Level change is failed [%d, %d]\n", level, mNotificationChangeState ); + return false; + } + else if( mNotificationChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Permission denied! [%d]\n", level ); + return false; + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetNotificationLevel: Level is changed [%d]\n", mNotificationLevel ); + + return true; +} + +Dali::Window::NotificationLevel::Type WindowBaseEcoreWl2::GetNotificationLevel() const +{ + while( !mTizenPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + int count = 0; + + while( !mNotificationLevelChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mNotificationLevelChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetNotificationLevel: Error! [%d]\n", mNotificationChangeState ); + return Dali::Window::NotificationLevel::NONE; + } + + Dali::Window::NotificationLevel::Type level; + + switch( mNotificationLevel ) + { + case TIZEN_POLICY_LEVEL_NONE: + { + level = Dali::Window::NotificationLevel::NONE; + break; + } + case TIZEN_POLICY_LEVEL_DEFAULT: + { + level = Dali::Window::NotificationLevel::BASE; + break; + } + case TIZEN_POLICY_LEVEL_MEDIUM: + { + level = Dali::Window::NotificationLevel::MEDIUM; + break; + } + case TIZEN_POLICY_LEVEL_HIGH: + { + level = Dali::Window::NotificationLevel::HIGH; + break; + } + case TIZEN_POLICY_LEVEL_TOP: + { + level = Dali::Window::NotificationLevel::TOP; + break; + } + default: + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetNotificationLevel: invalid level [%d]\n", mNotificationLevel ); + level = Dali::Window::NotificationLevel::NONE; + break; + } + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetNotificationLevel: level [%d]\n", mNotificationLevel ); + + return level; +} + +void WindowBaseEcoreWl2::SetOpaqueState( bool opaque ) +{ + while( !mTizenPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + tizen_policy_set_opaque_state( mTizenPolicy, ecore_wl2_window_surface_get( mEcoreWindow ), ( opaque ? 1 : 0 ) ); +} + +bool WindowBaseEcoreWl2::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode) +{ + while( !mTizenPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + mScreenOffModeChangeDone = false; + mScreenOffModeChangeState = TIZEN_POLICY_ERROR_STATE_NONE; + + unsigned int mode = 0; + + switch( screenOffMode ) + { + case Dali::Window::ScreenOffMode::TIMEOUT: + { + mode = 0; + break; + } + case Dali::Window::ScreenOffMode::NEVER: + { + mode = 1; + break; + } + } + + tizen_policy_set_window_screen_mode( mTizenPolicy, ecore_wl2_window_surface_get( mEcoreWindow ), mode ); + + int count = 0; + + while( !mScreenOffModeChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mScreenOffModeChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Screen mode change is failed [%d, %d]\n", screenOffMode, mScreenOffModeChangeState ); + return false; + } + else if( mScreenOffModeChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Permission denied! [%d]\n", screenOffMode ); + return false; + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetScreenOffMode: Screen mode is changed [%d]\n", mScreenOffMode ); + + return true; +} + +Dali::Window::ScreenOffMode::Type WindowBaseEcoreWl2::GetScreenOffMode() const +{ + while( !mTizenPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + int count = 0; + + while( !mScreenOffModeChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mScreenOffModeChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetScreenOffMode: Error! [%d]\n", mScreenOffModeChangeState ); + return Dali::Window::ScreenOffMode::TIMEOUT; + } + + Dali::Window::ScreenOffMode::Type screenMode = Dali::Window::ScreenOffMode::TIMEOUT; + + switch( mScreenOffMode ) + { + case 0: + { + screenMode = Dali::Window::ScreenOffMode::TIMEOUT; + break; + } + case 1: + { + screenMode = Dali::Window::ScreenOffMode::NEVER; + break; + } + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetScreenOffMode: screen mode [%d]\n", mScreenOffMode ); + + return screenMode; +} + +bool WindowBaseEcoreWl2::SetBrightness( int brightness ) +{ + while( !mTizenDisplayPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + mBrightnessChangeDone = false; + mBrightnessChangeState = TIZEN_POLICY_ERROR_STATE_NONE; + + tizen_display_policy_set_window_brightness( mTizenDisplayPolicy, ecore_wl2_window_surface_get( mEcoreWindow ), brightness ); + + int count = 0; + + while( !mBrightnessChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mBrightnessChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Brightness change is failed [%d, %d]\n", brightness, mBrightnessChangeState ); + return false; + } + else if( mBrightnessChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Permission denied! [%d]\n", brightness ); + return false; + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::SetBrightness: Brightness is changed [%d]\n", mBrightness ); + + return true; +} + +int WindowBaseEcoreWl2::GetBrightness() const +{ + while( !mTizenDisplayPolicy ) + { + wl_display_dispatch_queue( mDisplay, mEventQueue ); + } + + int count = 0; + + while( !mBrightnessChangeDone && count < 3 ) + { + ecore_wl2_display_flush( ecore_wl2_connected_display_get( NULL ) ); + wl_display_dispatch_queue( mDisplay, mEventQueue ); + count++; + } + + if( !mBrightnessChangeDone ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetBrightness: Error! [%d]\n", mBrightnessChangeState ); + return 0; + } + + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl2::GetBrightness: Brightness [%d]\n", mBrightness ); + + return mBrightness; +} + +bool WindowBaseEcoreWl2::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode ) +{ + Ecore_Wl2_Window_Keygrab_Mode mode; + + switch( grabMode ) + { + case KeyGrab::TOPMOST: + { + mode = ECORE_WL2_WINDOW_KEYGRAB_TOPMOST; + break; + } + case KeyGrab::SHARED: + { + mode = ECORE_WL2_WINDOW_KEYGRAB_SHARED; + break; + } + case KeyGrab::OVERRIDE_EXCLUSIVE: + { + mode = ECORE_WL2_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE; + break; + } + case KeyGrab::EXCLUSIVE: + { + mode = ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE; + break; + } + default: + { + return false; + } + } + + return ecore_wl2_window_keygrab_set( mEcoreWindow, KeyLookup::GetKeyName( key ), 0, 0, 0, mode ); +} + +bool WindowBaseEcoreWl2::UngrabKey( Dali::KEY key ) +{ + return ecore_wl2_window_keygrab_unset( mEcoreWindow, KeyLookup::GetKeyName( key ), 0, 0 ); +} + +bool WindowBaseEcoreWl2::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result ) +{ + int keyCount = key.Count(); + int keyGrabModeCount = grabMode.Count(); + + if( keyCount != keyGrabModeCount || keyCount == 0 ) + { + return false; + } + + eina_init(); + + Eina_List* keyList = NULL; + Ecore_Wl2_Window_Keygrab_Info* info = new Ecore_Wl2_Window_Keygrab_Info[keyCount]; + + for( int index = 0; index < keyCount; ++index ) + { + info[index].key = const_cast< char* >( KeyLookup::GetKeyName( key[index] ) ); + + switch( grabMode[index] ) + { + case KeyGrab::TOPMOST: + { + info[index].mode = ECORE_WL2_WINDOW_KEYGRAB_TOPMOST; + break; + } + case KeyGrab::SHARED: + { + info[index].mode = ECORE_WL2_WINDOW_KEYGRAB_SHARED; + break; + } + case KeyGrab::OVERRIDE_EXCLUSIVE: + { + info[index].mode = ECORE_WL2_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE; + break; + } + case KeyGrab::EXCLUSIVE: + { + info[index].mode = ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE; + break; + } + default: + { + info[index].mode = ECORE_WL2_WINDOW_KEYGRAB_UNKNOWN; + break; + } + } + + keyList = eina_list_append( keyList, &info ); + } + + Eina_List* grabList = ecore_wl2_window_keygrab_list_set( mEcoreWindow, keyList ); + + result.Resize( keyCount, true ); + + Eina_List* l = NULL; + Eina_List* m = NULL; + void* listData = NULL; + void* data = NULL; + if( grabList != NULL ) + { + EINA_LIST_FOREACH( grabList, m, data ) + { + int index = 0; + EINA_LIST_FOREACH( keyList, l, listData ) + { + if( static_cast< Ecore_Wl2_Window_Keygrab_Info* >( listData )->key == NULL ) + { + DALI_LOG_ERROR( "input key list has null data!" ); + break; + } + + if( strcmp( static_cast< char* >( data ), static_cast< Ecore_Wl2_Window_Keygrab_Info* >( listData )->key ) == 0 ) + { + result[index] = false; + } + ++index; + } + } + } + + delete [] info; + + eina_list_free( keyList ); + eina_list_free( grabList ); + eina_shutdown(); + + return true; +} + +bool WindowBaseEcoreWl2::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result ) +{ + int keyCount = key.Count(); + if( keyCount == 0 ) + { + return false; + } + + eina_init(); + + Eina_List* keyList = NULL; + Ecore_Wl2_Window_Keygrab_Info* info = new Ecore_Wl2_Window_Keygrab_Info[keyCount]; + + for( int index = 0; index < keyCount; ++index ) + { + info[index].key = const_cast< char* >( KeyLookup::GetKeyName( key[index] ) ); + keyList = eina_list_append( keyList, &info ); + } + + Eina_List* ungrabList = ecore_wl2_window_keygrab_list_unset( mEcoreWindow, keyList ); + + result.Resize( keyCount, true ); + + Eina_List* l = NULL; + Eina_List* m = NULL; + void *listData = NULL; + void *data = NULL; + + if( ungrabList != NULL ) + { + EINA_LIST_FOREACH( ungrabList, m, data ) + { + int index = 0; + EINA_LIST_FOREACH( keyList, l, listData ) + { + if( strcmp( static_cast< char* >( data ), static_cast< Ecore_Wl2_Window_Keygrab_Info* >( listData )->key ) == 0 ) + { + result[index] = false; + } + ++index; + } + } + } + + delete [] info; + + eina_list_free( keyList ); + eina_list_free( ungrabList ); + eina_shutdown(); + + return true; +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#pragma GCC diagnostic pop diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h new file mode 100644 index 0000000..a5bf2b2 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h @@ -0,0 +1,319 @@ +#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_ECORE_WL2_H +#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_ECORE_WL2_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +// EXTERNAL HEADERS +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +class WindowRenderSurface; +class WindowRenderSurfaceEcoreWl2; + +/** + * WindowBaseEcoreWl2 class provides an WindowBase Ecore-Wayland2 implementation. + */ +class WindowBaseEcoreWl2 : public WindowBase +{ +public: + + /** + * @brief Constructor + */ + WindowBaseEcoreWl2( Window* window, WindowRenderSurface* windowRenderSurface ); + + /** + * @brief Destructor + */ + virtual ~WindowBaseEcoreWl2(); + +public: + + /** + * @brief Called when the window iconify state is changed. + */ + Eina_Bool OnIconifyStateChanged( void* data, int type, void* event ); + + /** + * @brief Called when the window gains focus. + */ + Eina_Bool OnFocusIn( void* data, int type, void* event ); + + /** + * @brief Called when the window loses focus. + */ + Eina_Bool OnFocusOut( void* data, int type, void* event ); + + /** + * @brief Called when the output is transformed. + */ + Eina_Bool OnOutputTransform( void* data, int type, void* event ); + + /** + * @brief Called when the output transform should be ignored. + */ + Eina_Bool OnIgnoreOutputTransform( void* data, int type, void* event ); + + /** + * @brief RegistryGlobalCallback + */ + void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ); + + /** + * @brief RegistryGlobalCallbackRemove + */ + void RegistryGlobalCallbackRemove( void* data, struct wl_registry* registry, uint32_t id ); + + /** + * @brief TizenPolicyNotificationChangeDone + */ + void TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state ); + + /** + * @brief TizenPolicyScreenModeChangeDone + */ + void TizenPolicyScreenModeChangeDone( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t mode, uint32_t state ); + + /** + * @brief DisplayPolicyBrightnessChangeDone + */ + void DisplayPolicyBrightnessChangeDone( void* data, struct tizen_display_policy *displayPolicy, struct wl_surface* surface, int32_t brightness, uint32_t state ); + +public: + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Initialize() + */ + virtual void Initialize() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::ShowIndicator() + */ + virtual void ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode, Dali::Window::IndicatorBgOpacity opacityMode ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetIndicatorProperties() + */ + virtual void SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::IndicatorTypeChanged() + */ + virtual void IndicatorTypeChanged( IndicatorInterface::Type type ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetClass() + */ + virtual void SetClass( std::string name, std::string className ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Raise() + */ + virtual void Raise() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Lower() + */ + virtual void Lower() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Activate() + */ + virtual void Activate() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetAvailableOrientations() + */ + virtual void SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetPreferredOrientation() + */ + virtual void SetPreferredOrientation( Dali::Window::WindowOrientation orientation ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetAcceptFocus() + */ + virtual void SetAcceptFocus( bool accept ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Show() + */ + virtual void Show() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Hide() + */ + virtual void Hide() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetSupportedAuxiliaryHintCount() + */ + virtual unsigned int GetSupportedAuxiliaryHintCount() const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetSupportedAuxiliaryHint() + */ + virtual std::string GetSupportedAuxiliaryHint( unsigned int index ) const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::AddAuxiliaryHint() + */ + virtual unsigned int AddAuxiliaryHint( const std::string& hint, const std::string& value ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::RemoveAuxiliaryHint() + */ + virtual bool RemoveAuxiliaryHint( unsigned int id ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetAuxiliaryHintValue() + */ + virtual bool SetAuxiliaryHintValue( unsigned int id, const std::string& value ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetAuxiliaryHintValue() + */ + virtual std::string GetAuxiliaryHintValue( unsigned int id ) const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetAuxiliaryHintId() + */ + virtual unsigned int GetAuxiliaryHintId( const std::string& hint ) const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetInputRegion() + */ + virtual void SetInputRegion( const Rect< int >& inputRegion ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetType() + */ + virtual void SetType( Dali::Window::Type type ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetNotificationLevel() + */ + virtual bool SetNotificationLevel( Dali::Window::NotificationLevel::Type level ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetNotificationLevel() + */ + virtual Dali::Window::NotificationLevel::Type GetNotificationLevel() const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetOpaqueState() + */ + virtual void SetOpaqueState( bool opaque ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetScreenOffMode() + */ + virtual bool SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenOffMode() + */ + virtual Dali::Window::ScreenOffMode::Type GetScreenOffMode() const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetBrightness() + */ + virtual bool SetBrightness( int brightness ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetBrightness() + */ + virtual int GetBrightness() const override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GrabKey() + */ + virtual bool GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::UngrabKey() + */ + virtual bool UngrabKey( Dali::KEY key ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GrabKeyList() + */ + virtual bool GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::UngrabKeyList() + */ + virtual bool UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result ) override; + +protected: + + // Undefined + WindowBaseEcoreWl2(const WindowBaseEcoreWl2&) = delete; + + // Undefined + WindowBaseEcoreWl2& operator=(const WindowBaseEcoreWl2& rhs) = delete; + +private: + + typedef std::vector< std::pair< std::string, std::string > > AuxiliaryHints; + + Dali::Vector< Ecore_Event_Handler* > mEcoreEventHandler; + + Window* mWindow; + WindowRenderSurfaceEcoreWl2* mWindowSurface; + Ecore_Wl2_Window* mEcoreWindow; + wl_display* mDisplay; + wl_event_queue* mEventQueue; + tizen_policy* mTizenPolicy; + tizen_display_policy* mTizenDisplayPolicy; + + std::vector< std::string > mSupportedAuxiliaryHints; + AuxiliaryHints mAuxiliaryHints; + + int mNotificationLevel; + uint32_t mNotificationChangeState; + bool mNotificationLevelChangeDone; + + int mScreenOffMode; + uint32_t mScreenOffModeChangeState; + bool mScreenOffModeChangeDone; + + int mBrightness; + uint32_t mBrightnessChangeState; + bool mBrightnessChangeDone; +}; + +} // namespace Adaptor + +} // namespace internal + +} // namespace Dali + +#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_BASE_ECORE_WL2_H diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.cpp new file mode 100644 index 0000000..3f951a6 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// INTERNAL HEADERS +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +std::unique_ptr< WindowBase > WindowFactoryEcoreWl2::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) +{ + return Utils::MakeUnique< WindowBaseEcoreWl2 >( window, windowRenderSurface ); +} + +std::unique_ptr< IndicatorInterface > WindowFactoryEcoreWl2::CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) +{ + return Utils::MakeUnique< IndicatorEcoreWl >( adaptor, orientation, observer ); +} + +// this should be created from Window impl +std::unique_ptr< WindowFactory > GetWindowFactory() +{ + // returns Window factory + return Utils::MakeUnique< WindowFactoryEcoreWl2 >(); +} + +} // namespace Adaptor +} // namespace Internal +} // namespace Dali diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.h new file mode 100644 index 0000000..b5a0111 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-factory-ecore-wl2.h @@ -0,0 +1,42 @@ +#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL2_H +#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL2_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +class WindowFactoryEcoreWl2 : public WindowFactory +{ +public: + std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override; + + std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) override; +}; + +} // namespace Adaptor +} // namespace Internal +} // namespace Dali + +#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_FACTORY_ECORE_WL2_H diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.cpp new file mode 100644 index 0000000..7553402 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.cpp @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +namespace +{ + +const int MINIMUM_DIMENSION_CHANGE( 1 ); ///< Minimum change for window to be considered to have moved + +#if defined(DEBUG_ENABLED) +Debug::Filter* gWindowRenderSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, false, "LOG_WINDOW_RENDER_SURFACE_ECORE_WL2"); +#endif + +} // unnamed namespace + +WindowRenderSurfaceEcoreWl2::WindowRenderSurfaceEcoreWl2( Dali::PositionSize positionSize, + Any surface, + const std::string& name, + bool isTransparent) +: mTitle( name ), + mPositionSize( positionSize ), + mWlWindow( NULL ), + mWlSurface( NULL ), + mEglWindow( NULL ), + mThreadSynchronization( NULL ), + mRenderNotification( NULL ), + mRotationTrigger( NULL ), + mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), + mRotationAngle( 0 ), + mScreenRotationAngle( 0 ), + mOwnSurface( false ), + mRotationSupported( false ), + mRotationFinished( true ), + mScreenRotationFinished( true ), + mResizeFinished( true ) +{ + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" ); + Initialize( surface ); +} + +WindowRenderSurfaceEcoreWl2::~WindowRenderSurfaceEcoreWl2() +{ + if( mEglWindow != NULL ) + { + wl_egl_window_destroy(mEglWindow); + mEglWindow = NULL; + } + + if( mOwnSurface ) + { + ecore_wl2_window_free( mWlWindow ); + } + + if( mRotationTrigger ) + { + delete mRotationTrigger; + } + + if( mOwnSurface ) + { + ecore_wl2_shutdown(); + } +} + +void WindowRenderSurfaceEcoreWl2::Initialize( Any surface ) +{ + // see if there is a surface in Any surface + unsigned int surfaceId = GetSurfaceId( surface ); + + // if the surface is empty, create a new one. + if( surfaceId == 0 ) + { + // we own the surface about to created + ecore_wl2_init(); + mOwnSurface = true; + CreateRenderable(); + } + else + { + // XLib should already be initialized so no point in calling XInitThreads + UseExistingRenderable( surfaceId ); + } +} + +Ecore_Wl2_Window* WindowRenderSurfaceEcoreWl2::GetWlWindow() +{ + return mWlWindow; +} + +void WindowRenderSurfaceEcoreWl2::OutputTransformed() +{ + int transform; + + if( ecore_wl2_window_ignore_output_transform_get( mWlWindow ) ) + { + transform = 0; + } + else + { + transform = ecore_wl2_output_transform_get( ecore_wl2_window_output_find( mWlWindow ) ); + } + + mScreenRotationAngle = transform * 90; + mScreenRotationFinished = false; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); +} + +Any WindowRenderSurfaceEcoreWl2::GetWindow() +{ + return mWlWindow; +} + +void WindowRenderSurfaceEcoreWl2::Map() +{ + ecore_wl2_window_show( mWlWindow ); +} + +void WindowRenderSurfaceEcoreWl2::SetRenderNotification( TriggerEventInterface* renderNotification ) +{ + mRenderNotification = renderNotification; +} + +void WindowRenderSurfaceEcoreWl2::SetTransparency( bool transparent ) +{ + ecore_wl2_window_alpha_set( mWlWindow, transparent ); +} + +void WindowRenderSurfaceEcoreWl2::RequestRotation( int angle, int width, int height ) +{ + if( !mRotationSupported ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::Rotate: Rotation is not supported!\n" ); + return; + } + + if( !mRotationTrigger ) + { + TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface(); + mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurfaceEcoreWl2::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); + } + + mPositionSize.width = width; + mPositionSize.height = height; + + mRotationAngle = angle; + mRotationFinished = false; + + ecore_wl2_window_rotation_set( mWlWindow, mRotationAngle ); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); +} + +PositionSize WindowRenderSurfaceEcoreWl2::GetPositionSize() const +{ + return mPositionSize; +} + +void WindowRenderSurfaceEcoreWl2::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +{ + // calculate DPI + float xres, yres; + + Ecore_Wl2_Output* output = ecore_wl2_window_output_find( mWlWindow ); + + // 1 inch = 25.4 millimeters + xres = ecore_wl2_output_dpi_get( output ); + yres = ecore_wl2_output_dpi_get( output ); + + dpiHorizontal = int( xres + 0.5f ); // rounding + dpiVertical = int( yres + 0.5f ); +} + +void WindowRenderSurfaceEcoreWl2::InitializeEgl( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + + eglImpl.ChooseConfig(true, mColorDepth); +} + +void WindowRenderSurfaceEcoreWl2::CreateEglSurface( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + + // create the EGL window + if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + { + mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height ); + } + else + { + mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width ); + } + + EGLNativeWindowType windowType( mEglWindow ); + eglImpl.CreateSurfaceWindow( windowType, mColorDepth ); + + // Check capability + wl_egl_window_capability capability = static_cast< wl_egl_window_capability >( wl_egl_window_get_capabilities( mEglWindow ) ); + if( capability == WL_EGL_WINDOW_CAPABILITY_ROTATION_SUPPORTED ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::CreateEglSurface: capability = %d\n", capability ); + mRotationSupported = true; + } + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle ); +} + +void WindowRenderSurfaceEcoreWl2::DestroyEglSurface( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + eglImpl.DestroySurface(); + + if( mEglWindow != NULL ) + { + wl_egl_window_destroy(mEglWindow); + mEglWindow = NULL; + } +} + +bool WindowRenderSurfaceEcoreWl2::ReplaceEGLSurface( EglInterface& egl ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + if( mEglWindow != NULL ) + { + wl_egl_window_destroy(mEglWindow); + mEglWindow = NULL; + } + + if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + { + mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.width, mPositionSize.height ); + } + else + { + mEglWindow = wl_egl_window_create( mWlSurface, mPositionSize.height, mPositionSize.width ); + } + + // Set screen rotation + mScreenRotationFinished = false; + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); + EGLNativeWindowType windowType( mEglWindow ); + return eglImpl.ReplaceSurfaceWindow( windowType ); +} + +void WindowRenderSurfaceEcoreWl2::MoveResize( Dali::PositionSize positionSize ) +{ + bool needToMove = false; + bool needToResize = false; + + // check moving + if( (fabs(positionSize.x - mPositionSize.x) > MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.y - mPositionSize.y) > MINIMUM_DIMENSION_CHANGE) ) + { + needToMove = true; + } + + // check resizing + if( (fabs(positionSize.width - mPositionSize.width) > MINIMUM_DIMENSION_CHANGE) || + (fabs(positionSize.height - mPositionSize.height) > MINIMUM_DIMENSION_CHANGE) ) + { + needToResize = true; + } + + if( needToMove || needToResize ) + { + ecore_wl2_window_geometry_set( mWlWindow, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); + + if( needToResize ) + { + mResizeFinished = false; + } + } + + mPositionSize = positionSize; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height ); +} + +void WindowRenderSurfaceEcoreWl2::SetViewMode( ViewMode viewMode ) +{ +} + +void WindowRenderSurfaceEcoreWl2::StartRender() +{ +} + +bool WindowRenderSurfaceEcoreWl2::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) +{ + if( resizingSurface ) + { +#ifdef OVER_TIZEN_VERSION_4 + // Window rotate or screen rotate + if( !mRotationFinished || !mScreenRotationFinished ) + { + wl_egl_window_rotation rotation; + wl_output_transform bufferTransform; + int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360; + + switch( totalAngle ) + { + case 0: + { + rotation = ROTATION_0; + bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + case 90: + { + rotation = ROTATION_270; + bufferTransform = WL_OUTPUT_TRANSFORM_90; + break; + } + case 180: + { + rotation = ROTATION_180; + bufferTransform = WL_OUTPUT_TRANSFORM_180; + break; + } + case 270: + { + rotation = ROTATION_90; + bufferTransform = WL_OUTPUT_TRANSFORM_270; + break; + } + default: + { + rotation = ROTATION_0; + bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + } + + wl_egl_window_set_rotation( mEglWindow, rotation ); + + wl_egl_window_set_buffer_transform( mEglWindow, bufferTransform ); + + // Reset only screen rotation flag + mScreenRotationFinished = true; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle ); + } + + // Only window rotate + if( !mRotationFinished ) + { + wl_output_transform windowTransform; + + switch( mRotationAngle ) + { + case 0: + { + windowTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + case 90: + { + windowTransform = WL_OUTPUT_TRANSFORM_90; + break; + } + case 180: + { + windowTransform = WL_OUTPUT_TRANSFORM_180; + break; + } + case 270: + { + windowTransform = WL_OUTPUT_TRANSFORM_270; + break; + } + default: + { + windowTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + } + + wl_egl_window_set_window_transform( mEglWindow, windowTransform ); + } +#endif + + // Resize case + if( !mResizeFinished ) + { + wl_egl_window_resize( mEglWindow, mPositionSize.width, mPositionSize.height, mPositionSize.x, mPositionSize.y ); + mResizeFinished = true; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::PreRender: Set resize\n" ); + } + } + + return true; +} + +void WindowRenderSurfaceEcoreWl2::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) +{ + if( resizingSurface ) + { + if( !mRotationFinished ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::PostRender: Trigger rotation event\n" ); + + mRotationTrigger->Trigger(); + + if( mThreadSynchronization ) + { + // Wait until the event-thread complete the rotation event processing + mThreadSynchronization->PostRenderWaitForCompletion(); + } + } + } + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); + eglImpl.SwapBuffers(); + + if( mRenderNotification ) + { + mRenderNotification->Trigger(); + } +} + +void WindowRenderSurfaceEcoreWl2::StopRender() +{ +} + +void WindowRenderSurfaceEcoreWl2::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) +{ + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::SetThreadSynchronization: called\n" ); + + mThreadSynchronization = &threadSynchronization; +} + +void WindowRenderSurfaceEcoreWl2::ReleaseLock() +{ + // Nothing to do. +} + +RenderSurface::Type WindowRenderSurfaceEcoreWl2::GetSurfaceType() +{ + return RenderSurface::WINDOW_RENDER_SURFACE; +} + +void WindowRenderSurfaceEcoreWl2::CreateRenderable() +{ + Ecore_Wl2_Display* display = ecore_wl2_display_connect( NULL ); + if ( !display ) + { + DALI_ASSERT_ALWAYS(0 && "Failed to get display"); + } + + // if width or height are zero, go full screen. + if ( (mPositionSize.width == 0) || (mPositionSize.height == 0) ) + { + // Default window size == screen size + mPositionSize.x = 0; + mPositionSize.y = 0; + + ecore_wl2_display_screen_size_get( display, &mPositionSize.width, &mPositionSize.height ); + } + + mWlWindow = ecore_wl2_window_new( display, NULL, mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height ); + + if ( mWlWindow == 0 ) + { + DALI_ASSERT_ALWAYS(0 && "Failed to create Wayland window"); + } + + mWlSurface = ecore_wl2_window_surface_get( mWlWindow ); + + if( mColorDepth == COLOR_DEPTH_32 ) + { + ecore_wl2_window_alpha_set( mWlWindow, true ); + } + else + { + ecore_wl2_window_alpha_set( mWlWindow, false ); + } + + ecore_wl2_window_type_set( mWlWindow, ECORE_WL2_WINDOW_TYPE_TOPLEVEL ); + + // Get output transform + if( !ecore_wl2_window_ignore_output_transform_get( mWlWindow ) ) + { + Ecore_Wl2_Output* output = ecore_wl2_window_output_find( mWlWindow ); + + int transform = ecore_wl2_output_transform_get( output ); + + mScreenRotationAngle = transform * 90; + mScreenRotationFinished = false; + } +} + +void WindowRenderSurfaceEcoreWl2::UseExistingRenderable( unsigned int surfaceId ) +{ + mWlWindow = AnyCast< Ecore_Wl2_Window* >( surfaceId ); +} + +unsigned int WindowRenderSurfaceEcoreWl2::GetSurfaceId( Any surface ) const +{ + unsigned int surfaceId = 0; + + if( surface.Empty() == false ) + { + // check we have a valid type + DALI_ASSERT_ALWAYS( ( (surface.GetType() == typeid (Ecore_Wl2_Window *) ) ) + && "Surface type is invalid" ); + + surfaceId = AnyCast( surface ); + } + return surfaceId; +} + +void WindowRenderSurfaceEcoreWl2::ProcessRotationRequest() +{ + mRotationFinished = true; + + ecore_wl2_window_rotation_change_done_send( mWlWindow, mRotationAngle, mPositionSize.width, mPositionSize.height ); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl2::ProcessRotationRequest: Rotation Done\n" ); + + if( mThreadSynchronization ) + { + mThreadSynchronization->PostRenderComplete(); + } +} + +} // namespace Adaptor + +} // namespace internal + +} // namespace Dali diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.h new file mode 100644 index 0000000..8c19653 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.h @@ -0,0 +1,238 @@ +#ifndef DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_RENDER_SURFACE_ECORE_WL2_H +#define DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_RENDER_SURFACE_ECORE_WL2_H + +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ +namespace Adaptor +{ + +/** + * Ecore Wayland2 Window implementation of render surface. + */ +class WindowRenderSurfaceEcoreWl2 : public WindowRenderSurface +{ +public: + + /** + * Uses an Wayland surface to render to. + * @param [in] positionSize the position and size of the surface + * @param [in] surface can be a Wayland-window or Wayland-pixmap (type must be unsigned int). + * @param [in] name optional name of surface passed in + * @param [in] isTransparent if it is true, surface has 32 bit color depth, otherwise, 24 bit + */ + WindowRenderSurfaceEcoreWl2( Dali::PositionSize positionSize, + Any surface, + const std::string& name, + bool isTransparent = false ); + + /** + * @brief Destructor + */ + virtual ~WindowRenderSurfaceEcoreWl2(); + +public: // API + + /** + * @brief Get window handle + * @return the Ecore Waylnad window handle + */ + Ecore_Wl2_Window* GetWlWindow(); + + /** + * Notify output is transformed. + */ + void OutputTransformed(); + +public: // from WindowRenderSurface + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::GetWindow() + */ + virtual Any GetWindow() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::Map() + */ + virtual void Map() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::SetRenderNotification() + */ + virtual void SetRenderNotification( TriggerEventInterface* renderNotification ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::SetTransparency() + */ + virtual void SetTransparency( bool transparent ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::RequestRotation() + */ + virtual void RequestRotation( int angle, int width, int height ) override; + +public: // from Dali::RenderSurface + + /** + * @copydoc Dali::RenderSurface::GetPositionSize() + */ + virtual PositionSize GetPositionSize() const override; + + /** + * @copydoc Dali::RenderSurface::GetDpi() + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) override; + + /** + * @copydoc Dali::RenderSurface::InitializeEgl() + */ + virtual void InitializeEgl( EglInterface& egl ) override; + + /** + * @copydoc Dali::RenderSurface::CreateEglSurface() + */ + virtual void CreateEglSurface( EglInterface& egl ) override; + + /** + * @copydoc Dali::RenderSurface::DestroyEglSurface() + */ + virtual void DestroyEglSurface( EglInterface& egl ) override; + + /** + * @copydoc Dali::RenderSurface::ReplaceEGLSurface() + */ + virtual bool ReplaceEGLSurface( EglInterface& egl ) override; + + /** + * @copydoc Dali::RenderSurface::MoveResize() + */ + virtual void MoveResize( Dali::PositionSize positionSize) override; + + /** + * @copydoc Dali::RenderSurface::SetViewMode() + */ + virtual void SetViewMode( ViewMode viewMode ) override; + + /** + * @copydoc Dali::RenderSurface::StartRender() + */ + virtual void StartRender() override; + + /** + * @copydoc Dali::RenderSurface::PreRender() + */ + virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) override; + + /** + * @copydoc Dali::RenderSurface::PostRender() + */ + virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) override; + + /** + * @copydoc Dali::RenderSurface::StopRender() + */ + virtual void StopRender() override; + + /** + * @copydoc Dali::RenderSurface::SetThreadSynchronization + */ + virtual void SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) override; + + /** + * @copydoc Dali::RenderSurface::ReleaseLock() + */ + virtual void ReleaseLock() override; + + /** + * @copydoc Dali::RenderSurface::GetSurfaceType() + */ + virtual RenderSurface::Type GetSurfaceType() override; + +private: // from WindowRenderSurface + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::Initialize() + */ + void Initialize( Any surface ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::CreateRenderable() + */ + void CreateRenderable() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowRenderSurface::UseExistingRenderable() + */ + void UseExistingRenderable( unsigned int surfaceId ) override; + +private: + + /** + * Get the surface id if the surface parameter is not empty + * @param surface Any containing a surface id, or can be empty + * @return surface id, or zero if surface is empty + */ + unsigned int GetSurfaceId( Any surface ) const; + + /** + * Used as the callback for the rotation-trigger. + */ + void ProcessRotationRequest(); + +private: // Data + + std::string mTitle; ///< Title of window which shows from "xinfo -topvwins" command + PositionSize mPositionSize; ///< Position + Ecore_Wl2_Window* mWlWindow; ///< Wayland-Window + wl_surface* mWlSurface; + wl_egl_window* mEglWindow; + ThreadSynchronizationInterface* mThreadSynchronization; + TriggerEventInterface* mRenderNotification; ///< Render notification trigger + TriggerEventInterface* mRotationTrigger; + ColorDepth mColorDepth; ///< Color depth of surface (32 bit or 24 bit) + int mRotationAngle; + int mScreenRotationAngle; + bool mOwnSurface; ///< Whether we own the surface (responsible for deleting it) + bool mRotationSupported; + bool mRotationFinished; + bool mScreenRotationFinished; + bool mResizeFinished; + +}; // class WindowRenderSurfaceEcoreWl2 + +} // namespace Adaptor + +} // namespace internal + +} // namespace Dali + +#endif // DALI_INTERNAL_WINDOWSYSTEM_TIZENWAYLAND_WINDOW_RENDER_SURFACE_ECORE_WL2_H diff --git a/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.cpp index b54492a..8d6d04f 100644 --- a/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.cpp @@ -24,7 +24,12 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" #include #include + +#ifdef ECORE_WAYLAND2 +#include +#else #include +#endif #include #include @@ -345,7 +350,11 @@ struct IndicatorEcoreWl::Impl mEcoreEventHandler(NULL) { #if defined(DALI_PROFILE_MOBILE) +#ifdef ECORE_WAYLAND2 + mEcoreEventHandler = ecore_event_handler_add(ECORE_WL2_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this); +#else mEcoreEventHandler = ecore_event_handler_add(ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this); +#endif #endif // DALI_PROFILE_MOBILE } diff --git a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp index 73b0169..f23b126 100644 --- a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.cpp @@ -22,7 +22,12 @@ #include #include +#ifdef ECORE_WAYLAND2 +#include +#else #include +#endif + #include #include @@ -56,7 +61,12 @@ NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize posit mConsumeSurface( NULL ), mThreadSynchronization( NULL ) { +#ifdef ECORE_WAYLAND2 + ecore_wl2_init(); +#else ecore_wl_init( NULL ); +#endif + CreateNativeRenderable(); setenv( "EGL_PLATFORM", "tbm", 1 ); } @@ -76,7 +86,11 @@ NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl() DALI_LOG_INFO( gNativeSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" ); } +#ifdef ECORE_WAYLAND2 + ecore_wl2_shutdown(); +#else ecore_wl_shutdown(); +#endif } Any NativeRenderSurfaceEcoreWl::GetDrawable() @@ -111,8 +125,14 @@ void NativeRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned i float xres, yres; // 1 inch = 25.4 millimeters +#ifdef ECORE_WAYLAND2 + // TODO: Application should set dpi value in wayland2 + xres = 96; + yres = 96; +#else xres = ecore_wl_dpi_get(); yres = ecore_wl_dpi_get(); +#endif dpiHorizontal = int( xres + 0.5f ); // rounding dpiVertical = int( yres + 0.5f ); diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 7f5fe94..1307ba1 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -96,7 +96,11 @@ BuildRequires: wayland-devel BuildRequires: wayland-extension-client-devel # dali-adaptor uses ecore mainloop +%if 0%{?tizen_version_major} >= 5 +BuildRequires: pkgconfig(ecore-wl2) +%else BuildRequires: pkgconfig(ecore-wayland) +%endif # dali-adaptor needs tbm_surface in tizen 3.0 wayland BuildRequires: pkgconfig(libtbm) @@ -451,6 +455,18 @@ CXXFLAGS+=" -D_ARCH_ARM_ -lgcc" CFLAGS+=" -DWAYLAND" CXXFLAGS+=" -DWAYLAND" configure_flags="--enable-wayland" + +# Need Ecore-Wayland2 when Tizen version is 5.x or greater +%if 0%{?tizen_version_major} >= 5 +CFLAGS+=" -DECORE_WAYLAND2 -DEFL_BETA_API_SUPPORT" +CXXFLAGS+=" -DECORE_WAYLAND2 -DEFL_BETA_API_SUPPORT" +configure_flags+=" --enable-ecore-wayland2" +%endif +%endif + +# Use this conditional when Tizen version is 5.x or greater +%if 0%{?tizen_version_major} >= 5 +CXXFLAGS+=" -DOVER_TIZEN_VERSION_5" %endif # Use this conditional when Tizen version is 4.x or greater -- 2.7.4