From 116fbd0c8799b78ecfe44724bd0ee24b3d8d9340 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Mon, 21 May 2018 16:10:28 +0900 Subject: [PATCH] WindowRenderSurface and EventHandler refactoring Change-Id: If0b82acc6ed1f7ddb11777fbb32ab393f9942b17 --- build/tizen/adaptor/Makefile.am | 15 + .../clipboard/ubuntu-x11/clipboard-impl-x.cpp | 17 + .../input-method-context-impl-ecore-wl.cpp | 45 +- .../input-method-context-impl-ecore-wl.h | 7 +- .../virtual-keyboard-impl-ecore-wl.cpp | 1 - .../window-system/common/event-handler.cpp | 662 ++++++++ dali/internal/window-system/common/event-handler.h | 62 +- .../window-system/common/indicator-interface.h | 7 +- .../common/native-render-surface-factory.cpp | 7 +- .../window-system/common/render-surface-factory.h | 8 +- dali/internal/window-system/common/window-base.cpp | 128 ++ dali/internal/window-system/common/window-base.h | 232 ++- .../internal/window-system/common/window-factory.h | 4 +- dali/internal/window-system/common/window-impl.cpp | 112 +- dali/internal/window-system/common/window-impl.h | 54 +- .../window-system/common/window-render-surface.cpp | 415 +++++ .../window-system/common/window-render-surface.h | 152 +- dali/internal/window-system/common/window-system.h | 52 + dali/internal/window-system/file.list | 25 +- .../render-surface-factory-ecore-wl.cpp | 22 +- .../render-surface-factory-ecore-wl.h | 8 +- .../{ => ecore-wl}/window-base-ecore-wl.cpp | 1175 ++++++++++++- .../{ => ecore-wl}/window-base-ecore-wl.h | 204 ++- .../{ => ecore-wl}/window-factory-ecore-wl.cpp | 8 +- .../{ => ecore-wl}/window-factory-ecore-wl.h | 2 +- .../ecore-wl/window-system-ecore-wl.cpp | 59 + .../tizen-wayland/event-handler-ecore-wl.cpp | 1449 ---------------- .../tizen-wayland/indicator-impl-ecore-wl.cpp | 96 +- .../tizen-wayland/indicator-impl-ecore-wl.h | 8 +- .../native-render-surface-ecore-wl.cpp | 10 +- .../tizen-wayland/native-render-surface-ecore-wl.h | 6 +- .../window-render-surface-ecore-wl.cpp | 561 ------- .../tizen-wayland/window-render-surface-ecore-wl.h | 238 --- .../ubuntu-x11/event-handler-ecore-x.cpp | 1765 -------------------- .../ubuntu-x11/pixmap-render-surface-ecore-x.cpp | 6 +- .../ubuntu-x11/pixmap-render-surface-ecore-x.h | 7 +- .../ubuntu-x11/render-surface-factory-ecore-x.cpp | 20 +- .../ubuntu-x11/render-surface-factory-ecore-x.h | 8 +- .../ubuntu-x11/window-base-ecore-x.cpp | 640 ++++++- .../window-system/ubuntu-x11/window-base-ecore-x.h | 181 +- .../ubuntu-x11/window-factory-ecore-x.cpp | 4 +- .../ubuntu-x11/window-factory-ecore-x.h | 2 +- .../ubuntu-x11/window-render-surface-ecore-x.cpp | 387 ----- .../ubuntu-x11/window-render-surface-ecore-x.h | 224 --- .../ubuntu-x11/window-system-ecore-x.cpp | 59 + 45 files changed, 4085 insertions(+), 5069 deletions(-) create mode 100755 dali/internal/window-system/common/event-handler.cpp create mode 100644 dali/internal/window-system/common/window-base.cpp create mode 100644 dali/internal/window-system/common/window-render-surface.cpp create mode 100644 dali/internal/window-system/common/window-system.h rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/render-surface-factory-ecore-wl.cpp (61%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/render-surface-factory-ecore-wl.h (72%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-base-ecore-wl.cpp (53%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-base-ecore-wl.h (63%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-factory-ecore-wl.cpp (81%) rename dali/internal/window-system/tizen-wayland/{ => ecore-wl}/window-factory-ecore-wl.h (90%) create mode 100644 dali/internal/window-system/tizen-wayland/ecore-wl/window-system-ecore-wl.cpp delete mode 100755 dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp delete mode 100644 dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp delete mode 100644 dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h delete mode 100755 dali/internal/window-system/ubuntu-x11/event-handler-ecore-x.cpp delete mode 100644 dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.cpp delete mode 100644 dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.h create mode 100644 dali/internal/window-system/ubuntu-x11/window-system-ecore-x.cpp diff --git a/build/tizen/adaptor/Makefile.am b/build/tizen/adaptor/Makefile.am index dd26888..aee5843 100644 --- a/build/tizen/adaptor/Makefile.am +++ b/build/tizen/adaptor/Makefile.am @@ -123,6 +123,9 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -176,6 +179,9 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -228,6 +234,9 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -279,6 +288,9 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) @@ -333,6 +345,9 @@ LIBDALI_ADAPTOR_LA_SOURCES = \ $(static_libraries_glyphy_src_files) \ $(static_libraries_libunibreak_src_files) +LIBDALI_ADAPTOR_LA_SOURCES += \ + $(adaptor_window_system_ecore_wl_src_files) + if ENABLE_NETWORK_LOGGING LIBDALI_ADAPTOR_LA_SOURCES += \ $(adaptor_performance_logging_src_files) diff --git a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp index 18434a1..0a6b1f4 100644 --- a/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp +++ b/dali/internal/clipboard/ubuntu-x11/clipboard-impl-x.cpp @@ -212,6 +212,23 @@ bool Clipboard::IsVisible() const char* Clipboard::ExcuteBuffered( bool type, void *event ) { + if( !type ) + { + // Receive + Ecore_X_Event_Selection_Notify* selectionNotifyEvent = static_cast< Ecore_X_Event_Selection_Notify* >( event ); + + Ecore_X_Selection_Data* selectionData = static_cast< Ecore_X_Selection_Data* >( selectionNotifyEvent->data ); + if( selectionData->data ) + { + if( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY ) + { + // Claim the ownership of the SECONDARY selection. + ecore_x_selection_secondary_set( mImpl->mApplicationWindow, "", 1 ); + + return ( reinterpret_cast< char* >( selectionData->data ) ); + } + } + } return NULL; } 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..6a83c43 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,8 @@ #include // EXTERNAL INCLUDES -#include #include + #include #include #include @@ -33,10 +33,10 @@ // INTERNAL INCLUDES #include #include -#include #include #include #include +#include #define TOKEN_STRING(x) #x @@ -265,21 +265,17 @@ Dali::TypeRegistration type( typeid(Dali::InputMethodContext), typeid(Dali::Base InputMethodContextPtr InputMethodContextEcoreWl::New() { InputMethodContextPtr inputMethodContext; - if ( Adaptor::IsAvailable() ) + + // Create instance only if the adaptor is available + if ( Dali::Adaptor::IsAvailable() ) { - // Create instance only if the adaptor is available - 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) + Any nativeWindow = Dali::Adaptor::Get().GetNativeWindowHandle(); + + // 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 +293,8 @@ void InputMethodContextEcoreWl::Finalize() DeleteContext(); } -InputMethodContextEcoreWl::InputMethodContextEcoreWl( Ecore_Wl_Window *ecoreWlwin ) +InputMethodContextEcoreWl::InputMethodContextEcoreWl() : mIMFContext(), - mEcoreWlwin( ecoreWlwin ), mIMFCursorPosition( 0 ), mSurroundingText(), mRestoreAfterFocusLost( false ), @@ -316,11 +311,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 +326,16 @@ void InputMethodContextEcoreWl::CreateContext( Ecore_Wl_Window *ecoreWlwin ) if( mIMFContext ) { - if( ecoreWlwin ) + // If we fail to get window id, 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(). + RenderSurface& renderSurface = Dali::Adaptor::Get().GetSurface(); + WindowRenderSurface& windowRenderSurface = static_cast< WindowRenderSurface& >( renderSurface ); + + int windowId = windowRenderSurface.GetNativeWindowId(); + if( windowId != 0 ) { - 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/window-system/common/event-handler.cpp b/dali/internal/window-system/common/event-handler.cpp new file mode 100755 index 0000000..919af42 --- /dev/null +++ b/dali/internal/window-system/common/event-handler.cpp @@ -0,0 +1,662 @@ +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#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* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION"); +} // unnamed namespace +#endif + +namespace +{ + +// 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); +} + +} // unnamed namespace + +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() ), + mRotationAngle( 0 ), + mWindowWidth( 0 ), + mWindowHeight( 0 ), + mPaused( false ) +{ + // this code only works with the WindowRenderSurface so need to downcast + WindowRenderSurface* windowRenderSurface = static_cast< WindowRenderSurface* >( surface ); + if( windowRenderSurface ) + { + WindowBase* windowBase = windowRenderSurface->GetWindowBase(); + + // Connect signals + windowBase->FocusChangedSignal().Connect( this, &EventHandler::OnFocusChanged ); + windowBase->RotationSignal().Connect( this, &EventHandler::SendRotationPrepareEvent ); + windowBase->TouchEventSignal().Connect( this, &EventHandler::OnTouchEvent ); + windowBase->WheelEventSignal().Connect( this, &EventHandler::OnWheelEvent ); + windowBase->KeyEventSignal().Connect( this, &EventHandler::OnKeyEvent ); + windowBase->SelectionDataSendSignal().Connect( this, &EventHandler::OnSelectionDataSend ); + windowBase->SelectionDataReceivedSignal().Connect( this, &EventHandler::OnSelectionDataReceived ); + windowBase->StyleChangedSignal().Connect( this, &EventHandler::OnStyleChanged ); + windowBase->AccessibilitySignal().Connect( this, &EventHandler::OnAccessibilityNotification ); + } +} + +EventHandler::~EventHandler() +{ + mGestureManager.Stop(); +} + +void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp) +{ + if(timeStamp < 1) + { + timeStamp = GetCurrentMilliSeconds(); + } + + 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 ) + { + mRotationAngle = event.angle; + mWindowWidth = event.width; + mWindowHeight = event.height; + + mRotationObserver->OnRotationPrepare( event ); + mRotationObserver->OnRotationRequest(); + } +} + +void EventHandler::SendRotationRequestEvent( ) +{ + // No need to separate event into prepare and request +} + +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; +} + +void EventHandler::OnTouchEvent( Integration::Point& point, unsigned long timeStamp ) +{ + SendEvent( point, timeStamp ); +} + +void EventHandler::OnWheelEvent( WheelEvent& wheelEvent ) +{ + SendWheelEvent( wheelEvent ); +} + +void EventHandler::OnKeyEvent( Integration::KeyEvent& keyEvent ) +{ + SendEvent( keyEvent ); +} + +void EventHandler::OnFocusChanged( bool focusIn ) +{ + // If the window gains focus and we hid the keyboard then show it again. + if( focusIn ) + { + Dali::Clipboard clipboard = Clipboard::Get(); + if ( clipboard ) + { + clipboard.HideClipboard(); + } + } + else + { + // 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); + } + } +} + +void EventHandler::OnWindowDamaged( const DamageArea& area ) +{ + SendEvent( area ); +} + +void EventHandler::OnSelectionDataSend( void* event ) +{ + Dali::Clipboard clipboard = Clipboard::Get(); + if( clipboard ) + { + Clipboard& clipBoardImpl( GetImplementation( clipboard ) ); + clipBoardImpl.ExcuteBuffered( true, event ); + } +} + +void EventHandler::OnSelectionDataReceived( void* event ) +{ + // We have got the selected content, inform the clipboard event listener (if we have one). + Dali::Clipboard clipboard = Clipboard::Get(); + char* selectionData = NULL; + if( clipboard ) + { + Clipboard& clipBoardImpl( GetImplementation( clipboard ) ); + selectionData = clipBoardImpl.ExcuteBuffered( false, event ); + } + + if( selectionData && mClipboardEventNotifier ) + { + ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( mClipboardEventNotifier ) ); + std::string content( selectionData, strlen( selectionData ) ); + + clipboardEventNotifier.SetContent( content ); + clipboardEventNotifier.EmitContentSelectedSignal(); + + DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d): %s\n" , strlen(selectionData), selectionData ); + } +} + +void EventHandler::OnStyleChanged( StyleChange::Type styleChange ) +{ + SendEvent( styleChange ); +} + +void EventHandler::OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info ) +{ +#ifdef DALI_ELDBUS_AVAILABLE + if( mPaused ) + { + return; + } + + if( !mAccessibilityAdaptor ) + { + DALI_LOG_ERROR( "Invalid accessibility adaptor\n" ); + return; + } + + AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( mAccessibilityAdaptor ) ); + if( !accessibilityAdaptor ) + { + DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" ); + return; + } + + // Create a touch point object. + TouchPoint::State touchPointState( TouchPoint::Down ); + if( info.state == 0 ) + { + touchPointState = TouchPoint::Down; // Mouse down. + } + else if( info.state == 1 ) + { + touchPointState = TouchPoint::Motion; // Mouse move. + } + else if( info.state == 2 ) + { + touchPointState = TouchPoint::Up; // Mouse up. + } + else + { + touchPointState = TouchPoint::Interrupted; // Error. + } + + // Send touch event to accessibility adaptor. + TouchPoint point( 0, touchPointState, static_cast< float >( info.startX ), static_cast< float >( info.startY ) ); + + // 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( info.gestureValue ) + { + case 0: // OneFingerHover + { + // Focus, read out. + accessibilityAdaptor->HandleActionReadEvent( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), 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( static_cast< unsigned int >( info.startX ), static_cast< unsigned int >( info.startY ), 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; + } + } +#endif +} + +void EventHandler::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 ); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali diff --git a/dali/internal/window-system/common/event-handler.h b/dali/internal/window-system/common/event-handler.h index 7f65a46..18125f8 100755 --- a/dali/internal/window-system/common/event-handler.h +++ b/dali/internal/window-system/common/event-handler.h @@ -2,7 +2,7 @@ #define __DALI_INTERNAL_EVENT_HANDLER_H__ /* - * Copyright (c) 2014 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. @@ -30,6 +30,7 @@ #include #include #include +#include namespace Dali { @@ -52,7 +53,7 @@ class StyleMonitor; * * These TouchEvents are then passed on to Core. */ -class EventHandler +class EventHandler : public ConnectionTracker { public: @@ -167,6 +168,58 @@ private: */ void Reset(); + /** + * Called when a touch event is received. + */ + void OnTouchEvent( Integration::Point& point, unsigned long timeStamp ); + + /** + * Called when a mouse wheel is received. + */ + void OnWheelEvent( WheelEvent& wheelEvent ); + + /** + * Called when a key event is received. + */ + void OnKeyEvent( Integration::KeyEvent& keyEvent ); + + /** + * Called when the window focus is changed. + */ + void OnFocusChanged( bool focusIn ); + + /** + * Called when the window is damaged. + */ + void OnWindowDamaged( const DamageArea& area ); + + /** + * Called when the source window notifies us the content in clipboard is selected. + */ + void OnSelectionDataSend( void* event ); + + /** + * Called when the source window sends us about the selected content. + */ + void OnSelectionDataReceived( void* event ); + + /** + * Called when the style is changed. + */ + void OnStyleChanged( StyleChange::Type styleChange ); + + /** + * Called when Ecore ElDBus accessibility event is received. + */ + void OnAccessibilityNotification( const WindowBase::AccessibilityInfo& info ); + +private: + + /** + * Convert touch event position + */ + void ConvertTouchPosition( Integration::Point& point ); + private: // Undefined @@ -189,8 +242,9 @@ private: Dali::ClipboardEventNotifier mClipboardEventNotifier; ///< Pointer to the clipboard event notifier Dali::Clipboard mClipboard;///< Pointer to the clipboard - struct Impl; ///< Implementation - Impl* mImpl; ///< Created on construction and destroyed on destruction. + int mRotationAngle; + int mWindowWidth; + int mWindowHeight; bool mPaused; ///< The paused state of the adaptor. }; diff --git a/dali/internal/window-system/common/indicator-interface.h b/dali/internal/window-system/common/indicator-interface.h index e0c0e77..c0b1f73 100644 --- a/dali/internal/window-system/common/indicator-interface.h +++ b/dali/internal/window-system/common/indicator-interface.h @@ -122,6 +122,11 @@ public: virtual void Close() = 0; /** + * Notify the indicator flicked. + */ + virtual void Flicked() = 0; + + /** * Set the opacity mode of the indicator background. * @param[in] mode opacity mode */ @@ -149,8 +154,6 @@ public: * @return whether the message is sent successfully or not */ virtual bool SendMessage( int messageDomain, int messageId, const void *data, int size ) = 0; - - }; } // Adaptor diff --git a/dali/internal/window-system/common/native-render-surface-factory.cpp b/dali/internal/window-system/common/native-render-surface-factory.cpp index 069ee0a..ded1216 100644 --- a/dali/internal/window-system/common/native-render-surface-factory.cpp +++ b/dali/internal/window-system/common/native-render-surface-factory.cpp @@ -22,13 +22,10 @@ namespace Dali { -DALI_ADAPTOR_API NativeRenderSurface* CreateNativeSurface( - PositionSize positionSize, - const std::string& name, - bool isTransparent) +DALI_ADAPTOR_API NativeRenderSurface* CreateNativeSurface( PositionSize positionSize, bool isTransparent ) { auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory(); - auto nativeRenderSurface = renderSurfaceFactory->CreateNativeRenderSurface( positionSize, name, isTransparent ); + auto nativeRenderSurface = renderSurfaceFactory->CreateNativeRenderSurface( positionSize, isTransparent ); return nativeRenderSurface.release(); } diff --git a/dali/internal/window-system/common/render-surface-factory.h b/dali/internal/window-system/common/render-surface-factory.h index 024adb3..6c7a255 100644 --- a/dali/internal/window-system/common/render-surface-factory.h +++ b/dali/internal/window-system/common/render-surface-factory.h @@ -45,13 +45,11 @@ public: RenderSurfaceFactory() = default; virtual ~RenderSurfaceFactory() = default; - virtual std::unique_ptr< WindowRenderSurface > CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, - const std::string& name, const std::string& className, bool isTransparent = false ) = 0; + virtual std::unique_ptr< WindowRenderSurface > CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ) = 0; - virtual std::unique_ptr< PixmapRenderSurface > CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, - const std::string& name, bool isTransparent = false ) = 0; + virtual std::unique_ptr< PixmapRenderSurface > CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ) = 0; - virtual std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent = false ) = 0; + virtual std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, bool isTransparent = false ) = 0; }; extern std::unique_ptr< RenderSurfaceFactory > GetRenderSurfaceFactory(); diff --git a/dali/internal/window-system/common/window-base.cpp b/dali/internal/window-system/common/window-base.cpp new file mode 100644 index 0000000..94d396c --- /dev/null +++ b/dali/internal/window-system/common/window-base.cpp @@ -0,0 +1,128 @@ +/* + * 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 + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +WindowBase::WindowBase() +: mIconifyChangedSignal(), + mFocusChangedSignal(), + mOutputTransformedSignal(), + mDeleteRequestSignal(), + mWindowDamagedSignal(), + mRotationSignal(), + mTouchEventSignal(), + mWheelEventSignal(), + mKeyEventSignal(), + mSelectionDataSendSignal(), + mSelectionDataReceivedSignal(), + mStyleChangedSignal(), + mAccessibilitySignal(), + mIndicatorFlickedSignal() +{ +} + +WindowBase::~WindowBase() +{ +} + +WindowBase::IconifySignalType& WindowBase::IconifyChangedSignal() +{ + return mIconifyChangedSignal; +} + +WindowBase::FocusSignalType& WindowBase::FocusChangedSignal() +{ + return mFocusChangedSignal; +} + +WindowBase::OutputSignalType& WindowBase::OutputTransformedSignal() +{ + return mOutputTransformedSignal; +} + +WindowBase::DeleteSignalType& WindowBase::DeleteRequestSignal() +{ + return mDeleteRequestSignal; +} + +WindowBase::DamageSignalType& WindowBase::WindowDamagedSignal() +{ + return mWindowDamagedSignal; +} + +WindowBase::RotationSignalType& WindowBase::RotationSignal() +{ + return mRotationSignal; +} + +WindowBase::TouchEventSignalType& WindowBase::TouchEventSignal() +{ + return mTouchEventSignal; +} + +WindowBase::WheelEventSignalType& WindowBase::WheelEventSignal() +{ + return mWheelEventSignal; +} + +WindowBase::KeyEventSignalType& WindowBase::KeyEventSignal() +{ + return mKeyEventSignal; +} + +WindowBase::SelectionSignalType& WindowBase::SelectionDataSendSignal() +{ + return mSelectionDataSendSignal; +} + +WindowBase::SelectionSignalType& WindowBase::SelectionDataReceivedSignal() +{ + return mSelectionDataReceivedSignal; +} + +WindowBase::StyleSignalType& WindowBase::StyleChangedSignal() +{ + return mStyleChangedSignal; +} + +WindowBase::AccessibilitySignalType& WindowBase::AccessibilitySignal() +{ + return mAccessibilitySignal; +} + +WindowBase::IndicatorSignalType& WindowBase::IndicatorFlickedSignal() +{ + return mIndicatorFlickedSignal; +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#pragma GCC diagnostic pop diff --git a/dali/internal/window-system/common/window-base.h b/dali/internal/window-system/common/window-base.h index 2fc06dd..ec4f805 100644 --- a/dali/internal/window-system/common/window-base.h +++ b/dali/internal/window-system/common/window-base.h @@ -21,9 +21,16 @@ // INTERNAL INCLUDES #include #include +#include #include +#include +#include +#include // EXTERNAL INCLUDES +#include +#include +#include #include #include @@ -42,21 +49,115 @@ class WindowBase public: /** + * @brief Struct used to retrieve accessibility information + */ + struct AccessibilityInfo + { + int gestureValue; + int startX; + int startY; + int endX; + int endY; + int state; + int eventTime; + }; + + // Window + typedef Signal< void ( bool ) > IconifySignalType; + typedef Signal< void ( bool ) > FocusSignalType; + typedef Signal< void ( ) > OutputSignalType; + typedef Signal< void ( ) > DeleteSignalType; + typedef Signal< void ( const DamageArea& ) > DamageSignalType; + typedef Signal< void ( const RotationEvent& ) > RotationSignalType; + + // Input events + typedef Signal< void ( Integration::Point&, unsigned long ) > TouchEventSignalType; + typedef Signal< void ( WheelEvent& ) > WheelEventSignalType; + typedef Signal< void( Integration::KeyEvent& ) > KeyEventSignalType; + + // Clipboard + typedef Signal< void ( void* ) > SelectionSignalType; + + // Accessibility + typedef Signal< void ( StyleChange::Type ) > StyleSignalType; + typedef Signal< void ( const AccessibilityInfo& ) > AccessibilitySignalType; + + // Indicator + typedef Signal< void ( ) > IndicatorSignalType; + + /** * @brief Default constructor */ - WindowBase() = default; + WindowBase(); /** * @brief Destructor */ - virtual ~WindowBase() = default; + virtual ~WindowBase(); public: /** - * Second stage initialization + * @brief Get the native window handle + * @return The native window handle + */ + virtual Any GetNativeWindow() = 0; + + /** + * @brief Get the native window id + * @return The native window id + */ + virtual int GetNativeWindowId() = 0; + + /** + * @brief Create the egl window + */ + virtual EGLNativeWindowType CreateEglWindow( int width, int height ) = 0; + + /** + * @brief Destroy the egl window + */ + virtual void DestroyEglWindow() = 0; + + /** + * @brief Set the egl window rotation + */ + virtual void SetEglWindowRotation( int angle ) = 0; + + /** + * @brief Set the egl window buffer transform + */ + virtual void SetEglWindowBufferTransform( int angle ) = 0; + + /** + * @brief Set the egl window transform */ - virtual void Initialize() = 0; + virtual void SetEglWindowTransform( int angle ) = 0; + + /** + * @brief Resize the egl window + */ + virtual void ResizeEglWindow( Dali::PositionSize positionSize ) = 0; + + /** + * @brief Returns whether the egl window support rotation or not + */ + virtual bool IsEglWindowRotationSupported() = 0; + + /** + * @brief Move the window + */ + virtual void Move( Dali::PositionSize positionSize ) = 0; + + /** + * @brief Resize the window + */ + virtual void Resize( Dali::PositionSize positionSize ) = 0; + + /** + * @brief Move and resize the window + */ + virtual void MoveResize( Dali::PositionSize positionSize ) = 0; /** * @copydoc Dali::Window::ShowIndicator() @@ -76,7 +177,7 @@ public: /** * @copydoc Dali::Window::SetClass() */ - virtual void SetClass( std::string name, std::string className ) = 0; + virtual void SetClass( const std::string& name, const std::string& className ) = 0; /** * @copydoc Dali::Window::Raise() @@ -218,6 +319,111 @@ public: */ virtual bool UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result ) = 0; + /** + * @brief Get DPI + * @param[out] dpiHorizontal set to the horizontal dpi + * @param[out] dpiVertical set to the vertical dpi + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) = 0; + + /** + * @brief Set the stereoscopic 3D view mode + * @param[in] viewMode The new view mode + */ + virtual void SetViewMode( ViewMode viewMode ) = 0; + + /** + * @brief Get the screen rotation angle of the window + */ + virtual int GetScreenRotationAngle() = 0; + + /** + * @brief Set the rotation angle of the window + */ + virtual void SetWindowRotationAngle( int degree ) = 0; + + /** + * @brief Inform the window rotation is completed + */ + virtual void WindowRotationCompleted( int degree, int width, int height ) = 0; + + /** + * @copydoc Dali::Window::SetTransparency() + */ + virtual void SetTransparency( bool transparent ) = 0; + + // Signals + + /** + * @brief This signal is emitted when the window becomes iconified or deiconified. + */ + IconifySignalType& IconifyChangedSignal(); + + /** + * @brief This signal is emitted when the window focus is changed. + */ + FocusSignalType& FocusChangedSignal(); + + /** + * @brief This signal is emitted when the output is transformed. + */ + OutputSignalType& OutputTransformedSignal(); + + /** + * @brief This signal is emitted when the window receives a delete request. + */ + DeleteSignalType& DeleteRequestSignal(); + + /** + * @brief This signal is emitted when the window is damaged. + */ + DamageSignalType& WindowDamagedSignal(); + + /** + * @brief This signal is emitted when a rotation event is recevied. + */ + RotationSignalType& RotationSignal(); + + /** + * @brief This signal is emitted when a touch event is received. + */ + TouchEventSignalType& TouchEventSignal(); + + /** + * @brief This signal is emitted when a mouse wheel is received. + */ + WheelEventSignalType& WheelEventSignal(); + + /** + * @brief This signal is emitted when a key event is received. + */ + KeyEventSignalType& KeyEventSignal(); + + /** + * @brief This signal is emitted when the source window notifies us the content in clipboard is selected. + */ + SelectionSignalType& SelectionDataSendSignal(); + + /** + * @brief This signal is emitted when the source window sends us about the selected content. + */ + SelectionSignalType& SelectionDataReceivedSignal(); + + /** + * @brief This signal is emitted when the style is changed. + */ + StyleSignalType& StyleChangedSignal(); + + /** + * @brief This signal is emitted when an accessibility event is received. + */ + AccessibilitySignalType& AccessibilitySignal(); + + /** + * @brief This signal is emitted when an indicator is flicked. + */ + IndicatorSignalType& IndicatorFlickedSignal(); + protected: // Undefined @@ -226,6 +432,22 @@ protected: // Undefined WindowBase& operator=(const WindowBase& rhs) = delete; +protected: + + IconifySignalType mIconifyChangedSignal; + FocusSignalType mFocusChangedSignal; + OutputSignalType mOutputTransformedSignal; + DeleteSignalType mDeleteRequestSignal; + DamageSignalType mWindowDamagedSignal; + RotationSignalType mRotationSignal; + TouchEventSignalType mTouchEventSignal; + WheelEventSignalType mWheelEventSignal; + KeyEventSignalType mKeyEventSignal; + SelectionSignalType mSelectionDataSendSignal; + SelectionSignalType mSelectionDataReceivedSignal; + StyleSignalType mStyleChangedSignal; + AccessibilitySignalType mAccessibilitySignal; + IndicatorSignalType mIndicatorFlickedSignal; }; } // namespace Adaptor diff --git a/dali/internal/window-system/common/window-factory.h b/dali/internal/window-system/common/window-factory.h index 717a917..9c584da 100644 --- a/dali/internal/window-system/common/window-factory.h +++ b/dali/internal/window-system/common/window-factory.h @@ -34,8 +34,6 @@ namespace Adaptor class Adaptor; class WindowBase; -class Window; -class WindowRenderSurface; class WindowFactory { @@ -44,7 +42,7 @@ public: WindowFactory() = default; virtual ~WindowFactory() = default; - virtual std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) = 0; + virtual std::unique_ptr< WindowBase > CreateWindowBase( Dali::PositionSize positionSize, Any surface, bool isTransparent ) = 0; virtual std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) = 0; }; diff --git a/dali/internal/window-system/common/window-impl.cpp b/dali/internal/window-system/common/window-impl.cpp index 0d84262..62adc5a 100644 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -109,17 +109,21 @@ Window::~Window() void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className) { - // create a window render surface + // Create a window render surface Any surface; auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory(); - auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, name, className, mIsTransparent ); + auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent ); mSurface = windowRenderSurface.release(); - // create a window base - auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory(); - mWindowBase = windowFactory->CreateWindowBase( this, mSurface ); + // Get a window base + mWindowBase = mSurface->GetWindowBase(); - mWindowBase->Initialize(); + // Connect signals + mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged ); + mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged ); + mWindowBase->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed ); + mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest ); + mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked ); if( !positionSize.IsEmpty() ) { @@ -295,7 +299,7 @@ Dali::DragAndDropDetector Window::GetDragAndDropDetector() const Dali::Any Window::GetNativeHandle() const { - return mSurface->GetWindow(); + return mSurface->GetNativeWindow(); } void Window::SetAcceptFocus( bool accept ) @@ -558,49 +562,6 @@ void Window::RotationDone( int orientation, int width, int height ) mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) ); } -void Window::OnIconifyChanged( bool iconified ) -{ - if( iconified ) - { - mIconified = true; - - if( mVisible ) - { - WindowVisibilityObserver* observer( mAdaptor ); - observer->OnWindowHidden(); - DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this ); - } - } - else - { - mIconified = false; - - if( mVisible ) - { - WindowVisibilityObserver* observer( mAdaptor ); - observer->OnWindowShown(); - DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this ); - } - } -} - -void Window::OnFocusChanged( bool focusIn ) -{ - mFocusChangedSignal.Emit( focusIn ); -} - -void Window::OnOutputTransformed() -{ - PositionSize positionSize = mSurface->GetPositionSize(); - mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); - mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); -} - -void Window::OnDeleteRequest() -{ - mDeleteRequestSignal.Emit(); -} - void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation ) { if( mIndicator == NULL ) @@ -701,6 +662,57 @@ void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientatio mWindowBase->SetIndicatorProperties( isShow, lastOrientation ); } +void Window::OnIconifyChanged( bool iconified ) +{ + if( iconified ) + { + mIconified = true; + + if( mVisible ) + { + WindowVisibilityObserver* observer( mAdaptor ); + observer->OnWindowHidden(); + DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this ); + } + } + else + { + mIconified = false; + + if( mVisible ) + { + WindowVisibilityObserver* observer( mAdaptor ); + observer->OnWindowShown(); + DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this ); + } + } +} + +void Window::OnFocusChanged( bool focusIn ) +{ + mFocusChangedSignal.Emit( focusIn ); +} + +void Window::OnOutputTransformed() +{ + PositionSize positionSize = mSurface->GetPositionSize(); + mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); + mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) ); +} + +void Window::OnDeleteRequest() +{ + mDeleteRequestSignal.Emit(); +} + +void Window::OnIndicatorFlicked() +{ + if( mIndicator ) + { + mIndicator->Flicked(); + } +} + void Window::IndicatorTypeChanged( IndicatorInterface::Type type ) { mWindowBase->IndicatorTypeChanged( type ); diff --git a/dali/internal/window-system/common/window-impl.h b/dali/internal/window-system/common/window-impl.h index 6c62910..c2a2b48 100644 --- a/dali/internal/window-system/common/window-impl.h +++ b/dali/internal/window-system/common/window-impl.h @@ -24,8 +24,8 @@ // INTERNAL INCLUDES #include -#include #include +#include #include #include #include @@ -44,8 +44,8 @@ namespace Internal namespace Adaptor { class Orientation; -class WindowBase; class WindowRenderSurface; +class WindowBase; class Window; typedef IntrusivePtr WindowPtr; @@ -54,7 +54,7 @@ typedef IntrusivePtr OrientationPtr; /** * Window provides a surface to render onto with orientation & indicator properties. */ -class Window : public Dali::BaseObject, public IndicatorInterface::Observer, public LifeCycleObserver +class Window : public Dali::BaseObject, public IndicatorInterface::Observer, public LifeCycleObserver, public ConnectionTracker { public: typedef Dali::Window::IndicatorSignalType IndicatorSignalType; @@ -329,27 +329,8 @@ public: */ void RotationDone( int orientation, int width, int height ); - /** - * Called when the window becomes iconified or deiconified. - */ - void OnIconifyChanged( bool iconified ); - - /** - * Called when the window focus is changed. - */ - void OnFocusChanged( bool focusIn ); - - /** - * Called when the output is transformed. - */ - void OnOutputTransformed(); - - /** - * Called when the window receives a delete request - */ - void OnDeleteRequest(); - private: + /** * Private constructor. * @sa Window::New() @@ -388,6 +369,31 @@ private: */ void SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation ); + /** + * Called when the window becomes iconified or deiconified. + */ + void OnIconifyChanged( bool iconified ); + + /** + * Called when the window focus is changed. + */ + void OnFocusChanged( bool focusIn ); + + /** + * Called when the output is transformed. + */ + void OnOutputTransformed(); + + /** + * Called when the window receives a delete request. + */ + void OnDeleteRequest(); + + /** + * Called when the Ecore indicator event is received. + */ + void OnIndicatorFlicked(); + private: // IndicatorInterface::Observer interface /** @@ -457,7 +463,7 @@ public: // Signals private: WindowRenderSurface* mSurface; - std::unique_ptr< WindowBase > mWindowBase; + WindowBase* mWindowBase; Dali::Window::IndicatorVisibleMode mIndicatorVisible; ///< public state bool mIndicatorIsShown:1; ///< private state bool mShowRotatedIndicatorOnClose:1; diff --git a/dali/internal/window-system/common/window-render-surface.cpp b/dali/internal/window-system/common/window-render-surface.cpp new file mode 100644 index 0000000..7d73395 --- /dev/null +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -0,0 +1,415 @@ +/* + * 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 +#include +#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"); +#endif + +} // unnamed namespace + +WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent ) +: mPositionSize( positionSize ), + mWindowBase(), + 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 ); +} + +WindowRenderSurface::~WindowRenderSurface() +{ + if( mRotationTrigger ) + { + delete mRotationTrigger; + } +} + +void WindowRenderSurface::Initialize( Any surface ) +{ + // 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; + + WindowSystem::GetScreenSize( mPositionSize.width, mPositionSize.height ); + } + + // Create a window base + auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory(); + mWindowBase = windowFactory->CreateWindowBase( mPositionSize, surface, ( mColorDepth == COLOR_DEPTH_32 ? true : false ) ); + + // Connect signals + mWindowBase->OutputTransformedSignal().Connect( this, &WindowRenderSurface::OutputTransformed ); + + // Check screen rotation + mScreenRotationAngle = mWindowBase->GetScreenRotationAngle(); + if( mScreenRotationAngle != 0 ) + { + mScreenRotationFinished = false; + } +} + +Any WindowRenderSurface::GetNativeWindow() +{ + return mWindowBase->GetNativeWindow(); +} + +int WindowRenderSurface::GetNativeWindowId() +{ + return mWindowBase->GetNativeWindowId(); +} + +void WindowRenderSurface::Map() +{ + mWindowBase->Show(); +} + +void WindowRenderSurface::SetRenderNotification( TriggerEventInterface* renderNotification ) +{ + mRenderNotification = renderNotification; +} + +void WindowRenderSurface::SetTransparency( bool transparent ) +{ + mWindowBase->SetTransparency( transparent ); +} + +void WindowRenderSurface::RequestRotation( int angle, int width, int height ) +{ + if( !mRotationSupported ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: Rotation is not supported!\n" ); + return; + } + + if( !mRotationTrigger ) + { + TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface(); + mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); + } + + mPositionSize.width = width; + mPositionSize.height = height; + + mRotationAngle = angle; + mRotationFinished = false; + + mWindowBase->SetWindowRotationAngle( mRotationAngle ); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); +} + +WindowBase* WindowRenderSurface::GetWindowBase() +{ + return mWindowBase.get(); +} + +PositionSize WindowRenderSurface::GetPositionSize() const +{ + return mPositionSize; +} + +void WindowRenderSurface::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +{ + mWindowBase->GetDpi( dpiHorizontal, dpiVertical ); +} + +void WindowRenderSurface::InitializeEgl( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + + eglImpl.ChooseConfig(true, mColorDepth); +} + +void WindowRenderSurface::CreateEglSurface( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + int width, height; + if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + { + width = mPositionSize.width; + height = mPositionSize.height; + } + else + { + width = mPositionSize.height; + height = mPositionSize.width; + } + + // create the EGL window + EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + eglImpl.CreateSurfaceWindow( window, mColorDepth ); + + // Check rotation capability + mRotationSupported = mWindowBase->IsEglWindowRotationSupported(); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle ); +} + +void WindowRenderSurface::DestroyEglSurface( EglInterface& eglIf ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); + eglImpl.DestroySurface(); + + mWindowBase->DestroyEglWindow(); +} + +bool WindowRenderSurface::ReplaceEGLSurface( EglInterface& egl ) +{ + DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); + + // Destroy the old one + mWindowBase->DestroyEglWindow(); + + int width, height; + if( mScreenRotationAngle == 0 || mScreenRotationAngle == 180 ) + { + width = mPositionSize.width; + height = mPositionSize.height; + } + else + { + width = mPositionSize.height; + height = mPositionSize.width; + } + + // create the EGL window + EGLNativeWindowType window = mWindowBase->CreateEglWindow( width, height ); + + // Set screen rotation + mScreenRotationFinished = false; + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); + return eglImpl.ReplaceSurfaceWindow( window ); +} + +void WindowRenderSurface::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( needToResize ) + { + if( needToMove ) + { + mWindowBase->MoveResize( positionSize ); + } + else + { + mWindowBase->Resize( positionSize ); + } + + mResizeFinished = false; + mPositionSize = positionSize; + } + else + { + if( needToMove ) + { + mWindowBase->Move( positionSize ); + + mPositionSize = positionSize; + } + } + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height ); +} + +void WindowRenderSurface::SetViewMode( ViewMode viewMode ) +{ + mWindowBase->SetViewMode( viewMode ); +} + +void WindowRenderSurface::StartRender() +{ +} + +bool WindowRenderSurface::PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, bool resizingSurface ) +{ + if( resizingSurface ) + { +#ifdef OVER_TIZEN_VERSION_4 + // Window rotate or screen rotate + if( !mRotationFinished || !mScreenRotationFinished ) + { + int totalAngle = (mRotationAngle + mScreenRotationAngle) % 360; + + mWindowBase->SetEglWindowRotation( totalAngle ); + mWindowBase->SetEglWindowBufferTransform( totalAngle ); + + // Reset only screen rotation flag + mScreenRotationFinished = true; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set rotation [%d] [%d]\n", mRotationAngle, mScreenRotationAngle ); + } + + // Only window rotate + if( !mRotationFinished ) + { + mWindowBase->SetEglWindowTransform( mRotationAngle ); + } +#endif + + // Resize case + if( !mResizeFinished ) + { + mWindowBase->ResizeEglWindow( mPositionSize ); + mResizeFinished = true; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: Set resize\n" ); + } + } + + return true; +} + +void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, Dali::DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) +{ + if( resizingSurface ) + { + if( !mRotationFinished ) + { + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::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 WindowRenderSurface::StopRender() +{ +} + +void WindowRenderSurface::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) +{ + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::SetThreadSynchronization: called\n" ); + + mThreadSynchronization = &threadSynchronization; +} + +void WindowRenderSurface::ReleaseLock() +{ + // Nothing to do. +} + +RenderSurface::Type WindowRenderSurface::GetSurfaceType() +{ + return RenderSurface::WINDOW_RENDER_SURFACE; +} + +void WindowRenderSurface::OutputTransformed() +{ + mScreenRotationAngle = mWindowBase->GetScreenRotationAngle(); + mScreenRotationFinished = false; + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); +} + +void WindowRenderSurface::ProcessRotationRequest() +{ + mRotationFinished = true; + + mWindowBase->WindowRotationCompleted( mRotationAngle, mPositionSize.width, mPositionSize.height ); + + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::ProcessRotationRequest: Rotation Done\n" ); + + if( mThreadSynchronization ) + { + mThreadSynchronization->PostRenderComplete(); + } +} + +} // namespace Adaptor + +} // namespace internal + +} // namespace Dali diff --git a/dali/internal/window-system/common/window-render-surface.h b/dali/internal/window-system/common/window-render-surface.h index 1e0e5b0..5c87efe 100644 --- a/dali/internal/window-system/common/window-render-surface.h +++ b/dali/internal/window-system/common/window-render-surface.h @@ -20,6 +20,11 @@ // INTERNAL INCLUDES #include +#include + +// EXTERNAL INCLUDES +#include +#include namespace Dali { @@ -31,47 +36,58 @@ namespace Internal namespace Adaptor { +class WindowBase; + /** * Window interface of render surface. */ -class WindowRenderSurface : public Dali::RenderSurface +class WindowRenderSurface : public Dali::RenderSurface, public ConnectionTracker { public: /** - * @brief Default constructor - */ - WindowRenderSurface() = default; + * Uses an window surface to render to. + * @param [in] positionSize the position and size of the surface + * @param [in] surface can be a window or pixmap. + * @param [in] isTransparent if it is true, surface has 32 bit color depth, otherwise, 24 bit + */ + WindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ); /** * @brief Destructor */ - virtual ~WindowRenderSurface() = default; + virtual ~WindowRenderSurface(); public: // API /** - * @brief Get the render surface the adaptor is using to render to. - * @return reference to current render surface + * @brief Get the native window handle + * @return The native window handle + */ + Any GetNativeWindow(); + + /** + * @brief Get the native window id + * @return The native window id */ - virtual Any GetWindow() = 0; + int GetNativeWindowId(); /** * @brief Map window */ - virtual void Map() = 0; + void Map(); /** * @brief Sets the render notification trigger to call when render thread is completed a frame * @param renderNotification to use */ - virtual void SetRenderNotification( TriggerEventInterface* renderNotification ) = 0; + void SetRenderNotification( TriggerEventInterface* renderNotification ); /** * @brief Sets whether the surface is transparent or not. * @param[in] transparent Whether the surface is transparent */ - virtual void SetTransparency( bool transparent ) = 0; + void SetTransparency( bool transparent ); /** * Request surface rotation @@ -79,25 +95,107 @@ public: // API * @param[in] width A new width of the surface * @param[in] height A new height of the surface */ - virtual void RequestRotation( int angle, int width, int height ) = 0; + void RequestRotation( int angle, int width, int height ); -protected: + /** + * @brief Gets the window base object + * @return The window base object + */ + WindowBase* GetWindowBase(); + +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, Dali::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: /** * @brief Second stage construction */ - virtual void Initialize( Any surface ) = 0; + void Initialize( Any surface ); /** - * @brief Create window + * Notify output is transformed. */ - virtual void CreateRenderable() = 0; + void OutputTransformed(); /** - * @brief Use an existing render surface - * @param surfaceId the id of the surface + * @brief Used as the callback for the rotation-trigger. */ - virtual void UseExistingRenderable( unsigned int surfaceId ) = 0; + void ProcessRotationRequest(); protected: @@ -107,6 +205,22 @@ protected: // Undefined WindowRenderSurface& operator=(const WindowRenderSurface& rhs) = delete; +private: // Data + + PositionSize mPositionSize; ///< Position + std::unique_ptr< WindowBase > mWindowBase; + 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 WindowRenderSurface } // namespace Adaptor diff --git a/dali/internal/window-system/common/window-system.h b/dali/internal/window-system/common/window-system.h new file mode 100644 index 0000000..fc5f983 --- /dev/null +++ b/dali/internal/window-system/common/window-system.h @@ -0,0 +1,52 @@ +#ifndef DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_SYSTEM_H +#define DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_SYSTEM_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. + * + */ + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +namespace WindowSystem +{ + +/** + * @brief Initialize a window system + */ +void Initialize(); + +/** + * @brief Shutdown a window system + */ +void Shutdown(); + +/** + * @brief Get the screen size + */ +void GetScreenSize( int& width, int& height ); + +} // namespace WindowSystem + +} // namespace Adaptor +} // namespace internal +} // namespace Dali + +#endif // DALI_INTERNAL_WINDOWSYSTEM_COMMON_WINDOW_SYSTEM_H diff --git a/dali/internal/window-system/file.list b/dali/internal/window-system/file.list index 29f2af0..4a61900 100644 --- a/dali/internal/window-system/file.list +++ b/dali/internal/window-system/file.list @@ -4,31 +4,36 @@ adaptor_window_system_common_src_files=\ ${adaptor_window_system_dir}/common/display-connection.cpp \ ${adaptor_window_system_dir}/common/ecore-server-connection.cpp \ + ${adaptor_window_system_dir}/common/event-handler.cpp \ ${adaptor_window_system_dir}/common/indicator-buffer.cpp \ ${adaptor_window_system_dir}/common/native-render-surface-factory.cpp \ ${adaptor_window_system_dir}/common/orientation-impl.cpp \ - ${adaptor_window_system_dir}/common/window-impl.cpp + ${adaptor_window_system_dir}/common/window-base.cpp \ + ${adaptor_window_system_dir}/common/window-impl.cpp \ + ${adaptor_window_system_dir}/common/window-render-surface.cpp # module: window-system, backend: tizen-wayland 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/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-system-ecore-wl.cpp # module: window-system, backend: ubuntu-x11 adaptor_window_system_ubuntu_x11_src_files=\ ${adaptor_window_system_dir}/ubuntu-x11/display-connection-factory-x.cpp \ ${adaptor_window_system_dir}/ubuntu-x11/display-connection-impl-x.cpp \ - ${adaptor_window_system_dir}/ubuntu-x11/event-handler-ecore-x.cpp \ ${adaptor_window_system_dir}/ubuntu-x11/pixmap-render-surface-ecore-x.cpp \ ${adaptor_window_system_dir}/ubuntu-x11/render-surface-factory-ecore-x.cpp \ ${adaptor_window_system_dir}/ubuntu-x11/window-interface-ecore-x.cpp \ - ${adaptor_window_system_dir}/ubuntu-x11/window-render-surface-ecore-x.cpp \ ${adaptor_window_system_dir}/ubuntu-x11/window-base-ecore-x.cpp \ - ${adaptor_window_system_dir}/ubuntu-x11/window-factory-ecore-x.cpp + ${adaptor_window_system_dir}/ubuntu-x11/window-factory-ecore-x.cpp \ + ${adaptor_window_system_dir}/ubuntu-x11/window-system-ecore-x.cpp + 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 61% 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..ef2f93b 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,14 +16,17 @@ */ // CLASS HEADER -#include +#include // INTERNAL HEADERS -#include +#include #include #include #include +// EXTERNAL INCLUDES +#include + namespace Dali { namespace Internal @@ -31,24 +34,19 @@ namespace Internal namespace Adaptor { -std::unique_ptr< WindowRenderSurface > RenderSurfaceFactoryEcoreWl::CreateWindowRenderSurface( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - const std::string& className, - bool isTransparent ) +std::unique_ptr< WindowRenderSurface > RenderSurfaceFactoryEcoreWl::CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { - return Utils::MakeUnique< WindowRenderSurfaceEcoreWl >( positionSize, surface, name, isTransparent ); + return Utils::MakeUnique< WindowRenderSurface >( positionSize, surface, isTransparent ); } -std::unique_ptr< PixmapRenderSurface > RenderSurfaceFactoryEcoreWl::CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, - const std::string& name, bool isTransparent ) +std::unique_ptr< PixmapRenderSurface > RenderSurfaceFactoryEcoreWl::CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { return std::unique_ptr< PixmapRenderSurface >( nullptr ); } -std::unique_ptr< NativeRenderSurface > RenderSurfaceFactoryEcoreWl::CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent ) +std::unique_ptr< NativeRenderSurface > RenderSurfaceFactoryEcoreWl::CreateNativeRenderSurface( Dali::PositionSize positionSize, bool isTransparent ) { - return Utils::MakeUnique< NativeRenderSurfaceEcoreWl >( positionSize, name, isTransparent ); + return Utils::MakeUnique< NativeRenderSurfaceEcoreWl >( positionSize, isTransparent ); } // this should be created from somewhere 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 72% 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 index b954247..8db3813 100644 --- 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 @@ -30,13 +30,11 @@ namespace Adaptor class RenderSurfaceFactoryEcoreWl : 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< WindowRenderSurface > CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, 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< PixmapRenderSurface > CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ) override; - std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent = false ) override; + std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, bool isTransparent = false ) override; }; } // namespace Adaptor 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 53% 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..6af5474 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,16 +20,20 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" // CLASS HEADER -#include +#include // INTERNAL HEADERS #include -#include +#include +#include #include // EXTERNAL_HEADERS #include #include +#include +#include +#include namespace Dali { @@ -48,6 +52,155 @@ Debug::Filter* gWindowBaseLogFilter = Debug::Filter::New( Debug::NoLogging, fals #endif const uint32_t MAX_TIZEN_CLIENT_VERSION = 7; +const unsigned int PRIMARY_TOUCH_BUTTON_ID = 1; + +const char* DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced. + +// DBUS accessibility +const char* BUS = "org.enlightenment.wm-screen-reader"; +const char* INTERFACE = "org.tizen.GestureNavigation"; +const char* PATH = "/org/tizen/GestureNavigation"; + +/** + * 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; + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Window Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// /// Called when the window iconify state is changed. static Eina_Bool EcoreEventWindowIconifyStateChanged( void* data, int type, void* event ) @@ -109,6 +262,225 @@ static Eina_Bool EcoreEventIgnoreOutputTransform( void* data, int type, void* ev return ECORE_CALLBACK_PASS_ON; } +/** + * Called when rotate event is recevied. + */ +static Eina_Bool EcoreEventRotate( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnRotation( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Touch Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a touch down is received. + */ +static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonDown( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a touch up is received. + */ +static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonUp( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a touch motion is received. + */ +static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonMove( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a touch is canceled. + */ +static Eina_Bool EcoreEventMouseButtonCancel( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonCancel( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a mouse wheel is received. + */ +static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnMouseWheel( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a detent rotation event is recevied. + */ +static Eina_Bool EcoreEventDetentRotation( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnDetentRotation( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Key Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a key down is received. + */ +static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnKeyDown( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a key up is received. + */ +static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnKeyUp( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Selection Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when the source window notifies us the content in clipboard is selected. + */ +static Eina_Bool EcoreEventDataSend( void* data, int type, void* event ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnDataSend( data, type, 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 ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnDataReceive( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Indicator Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +#if defined (DALI_PROFILE_MOBILE) + /** + * Called when the Ecore indicator event is received. + */ + static Eina_Bool EcoreEventIndicator( void* data, int type, void* event ) + { + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnIndicatorFlicked( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; + } +#endif // DALI_PROFILE_MOBILE + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Font Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a font name is changed. + */ +static void VconfNotifyFontNameChanged( keynode_t* node, void* data ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnFontNameChanged(); + } +} + +/** + * Called when a font size is changed. + */ +static void VconfNotifyFontSizeChanged( keynode_t* node, void* data ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); + if( windowBase ) + { + windowBase->OnFontSizeChanged(); + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// ElDBus Accessibility Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef DALI_ELDBUS_AVAILABLE +// Callback for Ecore ElDBus accessibility events. +static void EcoreElDBusAccessibilityNotification( void* context, const Eldbus_Message* message ) +{ + WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( context ); + if( windowBase ) + { + windowBase->OnEcoreElDBusAccessibilityNotification( context, message ); + } +} +#endif // DALI_ELDBUS_AVAILABLE + static void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ) { WindowBaseEcoreWl* windowBase = static_cast< WindowBaseEcoreWl* >( data ); @@ -213,11 +585,11 @@ const struct tizen_display_policy_listener tizenDisplayPolicyListener = } // unnamed namespace -WindowBaseEcoreWl::WindowBaseEcoreWl( Window* window, WindowRenderSurface* windowRenderSurface ) +WindowBaseEcoreWl::WindowBaseEcoreWl( Dali::PositionSize positionSize, Any surface, bool isTransparent ) : mEcoreEventHandler(), - mWindow( window ), - mWindowSurface( NULL ), mEcoreWindow( NULL ), + mWlSurface( NULL ), + mEglWindow( NULL ), mDisplay( NULL ), mEventQueue( NULL ), mTizenPolicy( NULL ), @@ -232,13 +604,28 @@ WindowBaseEcoreWl::WindowBaseEcoreWl( Window* window, WindowRenderSurface* windo mScreenOffModeChangeDone( true ), mBrightness( 0 ), mBrightnessChangeState( 0 ), - mBrightnessChangeDone( true ) + mBrightnessChangeDone( true ), + mOwnSurface( false ) +#ifdef DALI_ELDBUS_AVAILABLE + , mSystemConnection( NULL ) +#endif { - mWindowSurface = dynamic_cast< WindowRenderSurfaceEcoreWl* >( windowRenderSurface ); + Initialize( positionSize, surface, isTransparent ); } WindowBaseEcoreWl::~WindowBaseEcoreWl() { +#ifdef DALI_ELDBUS_AVAILABLE + // Close down ElDBus connections. + if( mSystemConnection ) + { + eldbus_connection_unref( mSystemConnection ); + } +#endif // DALI_ELDBUS_AVAILABLE + + vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged ); + vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged ); + for( Dali::Vector< Ecore_Event_Handler* >::Iterator iter = mEcoreEventHandler.Begin(), endIter = mEcoreEventHandler.End(); iter != endIter; ++iter ) { ecore_event_handler_del( *iter ); @@ -252,139 +639,488 @@ WindowBaseEcoreWl::~WindowBaseEcoreWl() mSupportedAuxiliaryHints.clear(); mAuxiliaryHints.clear(); + + if( mEglWindow != NULL ) + { + wl_egl_window_destroy( mEglWindow ); + mEglWindow = NULL; + } + + if( mOwnSurface ) + { + ecore_wl_window_free( mEcoreWindow ); + + WindowSystem::Shutdown(); + } +} + +void WindowBaseEcoreWl::Initialize( PositionSize positionSize, Any surface, bool isTransparent ) +{ + if( surface.Empty() == false ) + { + // check we have a valid type + DALI_ASSERT_ALWAYS( ( surface.GetType() == typeid (Ecore_Wl_Window *) ) && "Surface type is invalid" ); + + mEcoreWindow = AnyCast< Ecore_Wl_Window* >( surface ); + } + else + { + // we own the surface about to created + WindowSystem::Initialize(); + + mOwnSurface = true; + CreateWindow( positionSize ); + } + + mWlSurface = ecore_wl_window_surface_create( mEcoreWindow ); + + SetTransparency( isTransparent ); + + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_OUTPUT_TRANSFORM, EcoreEventOutputTransform, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM, EcoreEventIgnoreOutputTransform, this ) ); + + // Register Rotate event + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ROTATE, EcoreEventRotate, this ) ); + + // Register Touch events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN, EcoreEventMouseButtonDown, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP, EcoreEventMouseButtonUp, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE, EcoreEventMouseButtonMove, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_CANCEL, EcoreEventMouseButtonCancel, this ) ); + + // Register Mouse wheel events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL, EcoreEventMouseWheel, this ) ); + + // Register Detent event + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_DETENT_ROTATE, EcoreEventDetentRotation, this ) ); + + // Register Key events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN, EcoreEventKeyDown, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_UP, EcoreEventKeyUp, this ) ); + + // Register Selection event - clipboard selection + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, this ) ); + +#if defined (DALI_PROFILE_MOBILE) + // Register indicator event + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this ) ); +#endif + + // Register Vconf notify - font name and size + vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this ); + vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, this ); + + InitializeEcoreElDBus(); + + mDisplay = ecore_wl_display_get(); + + 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_wl_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, "WindowBaseEcoreWl::Initialize: %s\n", hint ); + } + } +} + +Eina_Bool WindowBaseEcoreWl::OnIconifyStateChanged( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Window_Iconify_State_Change* iconifyChangedEvent( static_cast< Ecore_Wl_Event_Window_Iconify_State_Change* >( event ) ); + Eina_Bool handled( ECORE_CALLBACK_PASS_ON ); + + if( iconifyChangedEvent->win == static_cast< unsigned int>( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + if( iconifyChangedEvent->iconified == EINA_TRUE ) + { + mIconifyChangedSignal.Emit( true ); + } + else + { + mIconifyChangedSignal.Emit( false ); + } + handled = ECORE_CALLBACK_DONE; + } + + return handled; +} + +Eina_Bool WindowBaseEcoreWl::OnFocusIn( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Focus_In* focusInEvent( static_cast< Ecore_Wl_Event_Focus_In* >( event ) ); + + if( focusInEvent->win == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" ); + + mFocusChangedSignal.Emit( true ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl::OnFocusOut( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Focus_Out* focusOutEvent( static_cast< Ecore_Wl_Event_Focus_Out* >( event ) ); + + if( focusOutEvent->win == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" ); + + mFocusChangedSignal.Emit( false ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl::OnOutputTransform( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Output_Transform* transformEvent( static_cast< Ecore_Wl_Event_Output_Transform* >( event ) ); + + if( transformEvent->output == ecore_wl_window_output_find( mEcoreWindow ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventOutputTransform\n", mEcoreWindow ); + + mOutputTransformedSignal.Emit(); + } + + return ECORE_CALLBACK_PASS_ON; +} + +Eina_Bool WindowBaseEcoreWl::OnIgnoreOutputTransform( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Ignore_Output_Transform* ignoreTransformEvent( static_cast< Ecore_Wl_Event_Ignore_Output_Transform* >( event ) ); + + if( ignoreTransformEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventIgnoreOutputTransform\n", mEcoreWindow ); + + mOutputTransformedSignal.Emit(); + } + + return ECORE_CALLBACK_PASS_ON; +} + +void WindowBaseEcoreWl::OnRotation( void* data, int type, void* event ) +{ + Ecore_Wl_Event_Window_Rotate* ev( static_cast< Ecore_Wl_Event_Window_Rotate* >( event ) ); + + if( ev->win == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, "WindowBaseEcoreWl::OnRotation\n" ); + + 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; + } + + mRotationSignal.Emit( rotationEvent ); + } +} + +void WindowBaseEcoreWl::OnMouseButtonDown( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event ); + + if( touchEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + 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 ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } +} + +void WindowBaseEcoreWl::OnMouseButtonUp( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event ); + + if( touchEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + 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 ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } +} + +void WindowBaseEcoreWl::OnMouseButtonMove( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Move* touchEvent = static_cast< Ecore_Event_Mouse_Move* >( event ); + + if( touchEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + { + 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 ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } } -void WindowBaseEcoreWl::Initialize() +void WindowBaseEcoreWl::OnMouseButtonCancel( void* data, int type, void* event ) { - if( !mWindowSurface ) + Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event ); + + if( touchEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) { - DALI_ASSERT_ALWAYS( "Invalid window surface" ); - } + Integration::Point point; + point.SetDeviceId( touchEvent->multi.device ); + point.SetState( PointState::INTERRUPTED ); + point.SetScreenPosition( Vector2( 0.0f, 0.0f ) ); - mEcoreWindow = mWindowSurface->GetWlWindow(); - DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no EcoreWl window" ); + mTouchEventSignal.Emit( point, touchEvent->timestamp ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ) ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ) ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ) ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_OUTPUT_TRANSFORM, EcoreEventOutputTransform, this) ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL_EVENT_IGNORE_OUTPUT_TRANSFORM, EcoreEventIgnoreOutputTransform, this) ); + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl::OnMouseButtonCancel\n" ); + } +} - mDisplay = ecore_wl_display_get(); +void WindowBaseEcoreWl::OnMouseWheel( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Wheel* mouseWheelEvent = static_cast< Ecore_Event_Mouse_Wheel* >( event ); - if( mDisplay ) + if( mouseWheelEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) { - 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 ); + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl::OnMouseWheel: direction: %d, modifiers: %d, x: %d, y: %d, z: %d\n", mouseWheelEvent->direction, mouseWheelEvent->modifiers, mouseWheelEvent->x, mouseWheelEvent->y, mouseWheelEvent->z ); - wl_registry* registry = wl_display_get_registry( displayWrapper ); - wl_registry_add_listener( registry, ®istryListener, this ); - } + WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2( mouseWheelEvent->x, mouseWheelEvent->y ), mouseWheelEvent->z, mouseWheelEvent->timestamp ); - wl_proxy_wrapper_destroy( displayWrapper ); - } + mWheelEventSignal.Emit( wheelEvent ); } +} - // get auxiliary hint - Eina_List* hints = ecore_wl_window_aux_hints_supported_get( mEcoreWindow ); - if( hints ) - { - Eina_List* l = NULL; - char* hint = NULL; +void WindowBaseEcoreWl::OnDetentRotation( void* data, int type, void* event ) +{ + Ecore_Event_Detent_Rotate* detentEvent = static_cast< Ecore_Event_Detent_Rotate* >( event ); - 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::Concise, "WindowBaseEcoreWl::OnDetentRotation\n" ); - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Verbose, "WindowBaseEcoreWl::Initialize: %s\n", hint ); - } - } + int direction = ( detentEvent->direction == ECORE_DETENT_DIRECTION_CLOCKWISE ) ? 1 : -1; + int timeStamp = detentEvent->timestamp; + + WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2( 0.0f, 0.0f ), direction, timeStamp ); + + mWheelEventSignal.Emit( wheelEvent ); } -Eina_Bool WindowBaseEcoreWl::OnIconifyStateChanged( void* data, int type, void* event ) +void WindowBaseEcoreWl::OnKeyDown( void* data, int type, void* event ) { - Ecore_Wl_Event_Window_Iconify_State_Change* iconifyChangedEvent( static_cast< Ecore_Wl_Event_Window_Iconify_State_Change* >( event ) ); - Eina_Bool handled( ECORE_CALLBACK_PASS_ON ); + Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event ); - if( iconifyChangedEvent->win == static_cast< unsigned int>( ecore_wl_window_id_get( mEcoreWindow ) ) ) + if( keyEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) { - if( iconifyChangedEvent->iconified == EINA_TRUE ) + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl::OnKeyDown\n" ); + + 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 ) { - mWindow->OnIconifyChanged( true ); + compose = keyEvent->compose; } - else + + 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 ) ) { - mWindow->OnIconifyChanged( false ); + keyCode = atoi( keyEvent->keyname + 8 ); } - handled = ECORE_CALLBACK_DONE; - } - return handled; -} + // Ensure key event string is not NULL as keys like SHIFT have a null string. + if( keyEvent->string ) + { + keyString = keyEvent->string; + } -Eina_Bool WindowBaseEcoreWl::OnFocusIn( void* data, int type, void* event ) -{ - Ecore_Wl_Event_Focus_In* focusInEvent( static_cast< Ecore_Wl_Event_Focus_In* >( event ) ); + std::string deviceName; + Device::Class::Type deviceClass; + Device::Subclass::Type deviceSubclass; - if( focusInEvent->win == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) - { - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" ); + GetDeviceName( keyEvent, deviceName ); + GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass ); - mWindow->OnFocusChanged( true ); - } + Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, deviceName, deviceClass, deviceSubclass ); - return ECORE_CALLBACK_PASS_ON; + mKeyEventSignal.Emit( keyEvent ); + } } -Eina_Bool WindowBaseEcoreWl::OnFocusOut( void* data, int type, void* event ) +void WindowBaseEcoreWl::OnKeyUp( void* data, int type, void* event ) { - Ecore_Wl_Event_Focus_Out* focusOutEvent( static_cast< Ecore_Wl_Event_Focus_Out* >( event ) ); + Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event ); - if( focusOutEvent->win == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) + if( keyEvent->window == static_cast< unsigned int >( ecore_wl_window_id_get( mEcoreWindow ) ) ) { - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" ); + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl::OnKeyUp\n" ); - mWindow->OnFocusChanged( false ); - } + std::string keyName( keyEvent->keyname ); + std::string keyString( "" ); + std::string compose( "" ); - return ECORE_CALLBACK_PASS_ON; -} + // Ensure key compose string is not NULL as keys like SHIFT or arrow have a null string. + if( keyEvent->compose ) + { + compose = keyEvent->compose; + } -Eina_Bool WindowBaseEcoreWl::OnOutputTransform( void* data, int type, void* event ) -{ - Ecore_Wl_Event_Output_Transform* transformEvent( static_cast< Ecore_Wl_Event_Output_Transform* >( event ) ); + 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 ); + } - if( transformEvent->output == ecore_wl_window_output_find( mEcoreWindow ) ) - { - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventOutputTransform\n", mEcoreWindow ); + // 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; - mWindowSurface->OutputTransformed(); + GetDeviceName( keyEvent, deviceName ); + GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass ); + GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass ); - mWindow->OnOutputTransformed(); + Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, deviceName, deviceClass, deviceSubclass ); + + mKeyEventSignal.Emit( keyEvent ); } +} - return ECORE_CALLBACK_PASS_ON; +void WindowBaseEcoreWl::OnDataSend( void* data, int type, void* event ) +{ + mSelectionDataSendSignal.Emit( event ); } -Eina_Bool WindowBaseEcoreWl::OnIgnoreOutputTransform( void* data, int type, void* event ) +void WindowBaseEcoreWl::OnDataReceive( void* data, int type, void* event ) { - Ecore_Wl_Event_Ignore_Output_Transform* ignoreTransformEvent( static_cast< Ecore_Wl_Event_Ignore_Output_Transform* >( event ) ); + mSelectionDataReceivedSignal.Emit( event ); +} - if( ignoreTransformEvent->win == mEcoreWindow ) - { - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%p) EcoreEventIgnoreOutputTransform\n", mEcoreWindow ); +void WindowBaseEcoreWl::OnIndicatorFlicked( void* data, int type, void* event ) +{ + mIndicatorFlickedSignal.Emit(); +} + +void WindowBaseEcoreWl::OnFontNameChanged() +{ + mStyleChangedSignal.Emit( StyleChange::DEFAULT_FONT_CHANGE ); +} + +void WindowBaseEcoreWl::OnFontSizeChanged() +{ + mStyleChangedSignal.Emit( StyleChange::DEFAULT_FONT_SIZE_CHANGE ); +} - mWindowSurface->OutputTransformed(); +void WindowBaseEcoreWl::OnEcoreElDBusAccessibilityNotification( void* context, const Eldbus_Message* message ) +{ +#ifdef DALI_ELDBUS_AVAILABLE + AccessibilityInfo info; - mWindow->OnOutputTransformed(); + // The string defines the arg-list's respective types. + if( !eldbus_message_arguments_get( message, "iiiiiiu", &info.gestureValue, &info.startX, &info.startY, &info.endX, &info.endY, &info.state, &info.eventTime ) ) + { + DALI_LOG_ERROR( "OnEcoreElDBusAccessibilityNotification: Error getting arguments\n" ); } - return ECORE_CALLBACK_PASS_ON; + mAccessibilitySignal.Emit( info ); +#endif } void WindowBaseEcoreWl::RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ) @@ -452,6 +1188,173 @@ void WindowBaseEcoreWl::DisplayPolicyBrightnessChangeDone( void* data, struct ti DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl::DisplayPolicyBrightnessChangeDone: brightness = %d, state = %d\n", brightness, state ); } +Any WindowBaseEcoreWl::GetNativeWindow() +{ + return mEcoreWindow; +} + +int WindowBaseEcoreWl::GetNativeWindowId() +{ + return ecore_wl_window_id_get( mEcoreWindow ); +} + +EGLNativeWindowType WindowBaseEcoreWl::CreateEglWindow( int width, int height ) +{ + mEglWindow = wl_egl_window_create( mWlSurface, width, height ); + + return static_cast< EGLNativeWindowType >( mEglWindow ); +} + +void WindowBaseEcoreWl::DestroyEglWindow() +{ + if( mEglWindow != NULL ) + { + wl_egl_window_destroy( mEglWindow ); + mEglWindow = NULL; + } +} + +void WindowBaseEcoreWl::SetEglWindowRotation( int angle ) +{ + wl_egl_window_rotation rotation; + + switch( angle ) + { + case 0: + { + rotation = ROTATION_0; + break; + } + case 90: + { + rotation = ROTATION_270; + break; + } + case 180: + { + rotation = ROTATION_180; + break; + } + case 270: + { + rotation = ROTATION_90; + break; + } + default: + { + rotation = ROTATION_0; + break; + } + } + + wl_egl_window_set_rotation( mEglWindow, rotation ); +} + +void WindowBaseEcoreWl::SetEglWindowBufferTransform( int angle ) +{ + wl_output_transform bufferTransform; + + switch( angle ) + { + case 0: + { + bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + case 90: + { + bufferTransform = WL_OUTPUT_TRANSFORM_90; + break; + } + case 180: + { + bufferTransform = WL_OUTPUT_TRANSFORM_180; + break; + } + case 270: + { + bufferTransform = WL_OUTPUT_TRANSFORM_270; + break; + } + default: + { + bufferTransform = WL_OUTPUT_TRANSFORM_NORMAL; + break; + } + } + + wl_egl_window_set_buffer_transform( mEglWindow, bufferTransform ); +} + +void WindowBaseEcoreWl::SetEglWindowTransform( int angle ) +{ + wl_output_transform windowTransform; + + switch( angle ) + { + 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 ); +} + +void WindowBaseEcoreWl::ResizeEglWindow( PositionSize positionSize ) +{ + wl_egl_window_resize( mEglWindow, positionSize.width, positionSize.height, positionSize.x, positionSize.y ); +} + +bool WindowBaseEcoreWl::IsEglWindowRotationSupported() +{ + // 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 ) + { + return true; + } + + return false; +} + +void WindowBaseEcoreWl::Move( PositionSize positionSize ) +{ + ecore_wl_window_position_set( mEcoreWindow, positionSize.x, positionSize.y ); +} + +void WindowBaseEcoreWl::Resize( PositionSize positionSize ) +{ + ecore_wl_window_update_size( mEcoreWindow, positionSize.width, positionSize.height ); +} + +void WindowBaseEcoreWl::MoveResize( PositionSize positionSize ) +{ + ecore_wl_window_position_set( mEcoreWindow, positionSize.x, positionSize.y ); + ecore_wl_window_update_size( mEcoreWindow, positionSize.width, positionSize.height ); +} + void WindowBaseEcoreWl::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode, Dali::Window::IndicatorBgOpacity opacityMode ) { DALI_LOG_TRACE_METHOD_FMT( gWindowBaseLogFilter, "visible : %d\n", visibleMode ); @@ -515,7 +1418,7 @@ void WindowBaseEcoreWl::IndicatorTypeChanged( IndicatorInterface::Type type ) #endif //MOBILE } -void WindowBaseEcoreWl::SetClass( std::string name, std::string className ) +void WindowBaseEcoreWl::SetClass( const std::string& name, const std::string& className ) { ecore_wl_window_title_set( mEcoreWindow, name.c_str() ); ecore_wl_window_class_name_set( mEcoreWindow, className.c_str() ); @@ -1223,6 +2126,96 @@ bool WindowBaseEcoreWl::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dal return true; } +void WindowBaseEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +{ + // calculate DPI + float xres, yres; + + // 1 inch = 25.4 millimeters + xres = ecore_wl_dpi_get(); + yres = ecore_wl_dpi_get(); + + dpiHorizontal = int( xres + 0.5f ); // rounding + dpiVertical = int( yres + 0.5f ); +} + +void WindowBaseEcoreWl::SetViewMode( ViewMode viewMode ) +{ +} + +int WindowBaseEcoreWl::GetScreenRotationAngle() +{ + int transform = 0; + + if( ecore_wl_window_ignore_output_transform_get( mEcoreWindow ) ) + { + transform = 0; + } + else + { + transform = ecore_wl_output_transform_get( ecore_wl_window_output_find( mEcoreWindow ) ); + } + + return transform * 90; +} + +void WindowBaseEcoreWl::SetWindowRotationAngle( int degree ) +{ + ecore_wl_window_rotation_set( mEcoreWindow, degree ); +} + +void WindowBaseEcoreWl::WindowRotationCompleted( int degree, int width, int height ) +{ + ecore_wl_window_rotation_change_done_send( mEcoreWindow ); +} + +void WindowBaseEcoreWl::SetTransparency( bool transparent ) +{ + ecore_wl_window_alpha_set( mEcoreWindow, transparent ); +} + +void WindowBaseEcoreWl::InitializeEcoreElDBus() +{ +#ifdef DALI_ELDBUS_AVAILABLE + 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", EcoreElDBusAccessibilityNotification, this ) ) + { + DALI_LOG_ERROR( "No signal handler returned\n" ); + } +#endif +} + +void WindowBaseEcoreWl::CreateWindow( PositionSize positionSize ) +{ + mEcoreWindow = ecore_wl_window_new( 0, positionSize.x, positionSize.y, positionSize.width, positionSize.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW ); + + if ( mEcoreWindow == 0 ) + { + DALI_ASSERT_ALWAYS( 0 && "Failed to create Wayland window" ); + } +} + } // namespace Adaptor } // namespace Internal 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 63% 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..da8e8b3 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 @@ -25,6 +25,11 @@ #include #include #include +#include + +#ifdef DALI_ELDBUS_AVAILABLE +#include +#endif namespace Dali { @@ -37,7 +42,7 @@ class WindowRenderSurface; class WindowRenderSurfaceEcoreWl; /** - * WindowBaseEcoreWl class provides an WindowBase EcoreX implementation. + * WindowBaseEcoreWl class provides an WindowBase Ecore-Wayland implementation. */ class WindowBaseEcoreWl : public WindowBase { @@ -46,7 +51,7 @@ public: /** * @brief Constructor */ - WindowBaseEcoreWl( Window* window, WindowRenderSurface* windowRenderSurface ); + WindowBaseEcoreWl( PositionSize positionSize, Any surface, bool isTransparent ); /** * @brief Destructor @@ -81,6 +86,83 @@ public: Eina_Bool OnIgnoreOutputTransform( void* data, int type, void* event ); /** + * @brief Called when a rotation event is recevied. + */ + void OnRotation( void* data, int type, void* event ); + + /** + * @brief Called when a touch down is received. + */ + void OnMouseButtonDown( void* data, int type, void* event ); + + /** + * @brief Called when a touch up is received. + */ + void OnMouseButtonUp( void* data, int type, void* event ); + + /** + * @brief Called when a touch motion is received. + */ + void OnMouseButtonMove( void* data, int type, void* event ); + + /** + * @brief Called when a touch is canceled. + */ + void OnMouseButtonCancel( void* data, int type, void* event ); + + /** + * @brief Called when a mouse wheel is received. + */ + void OnMouseWheel( void* data, int type, void* event ); + + /** + * @brief Called when a detent rotation event is recevied. + */ + void OnDetentRotation( void* data, int type, void* event ); + + /** + * @brief Called when a key down is received. + */ + void OnKeyDown( void* data, int type, void* event ); + + /** + * @brief Called when a key up is received. + */ + void OnKeyUp( void* data, int type, void* event ); + + /** + * @brief Called when the source window notifies us the content in clipboard is selected. + */ + void OnDataSend( void* data, int type, void* event ); + + /** + * @brief Called when the source window sends us about the selected content. + */ + void OnDataReceive( void* data, int type, void* event ); + + /** + * @brief Called when the indicator event is received. + */ + void OnIndicatorFlicked( void* data, int type, void* event ); + + /** + * @brief Called when a font name is changed. + */ + void OnFontNameChanged(); + + /** + * @brief Called when a font size is changed. + */ + void OnFontSizeChanged(); + +#ifdef DALI_ELDBUS_AVAILABLE + /** + * @brief Called when Ecore ElDBus accessibility event is received. + */ + void OnEcoreElDBusAccessibilityNotification( void* context, const Eldbus_Message* message ); +#endif + + /** * @brief RegistryGlobalCallback */ void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version ); @@ -108,9 +190,64 @@ public: public: /** - * @copydoc Dali::Internal::Adaptor::WindowBase::Initialize() + * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeWindow() + */ + virtual Any GetNativeWindow() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeWindowId() + */ + virtual int GetNativeWindowId() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::CreateEglWindow() + */ + virtual EGLNativeWindowType CreateEglWindow( int width, int height ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::DestroyEglWindow() */ - virtual void Initialize() override; + virtual void DestroyEglWindow() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowRotation() + */ + virtual void SetEglWindowRotation( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowBufferTransform() + */ + virtual void SetEglWindowBufferTransform( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowTransform() + */ + virtual void SetEglWindowTransform( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::ResizeEglWindow() + */ + virtual void ResizeEglWindow( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::IsEglWindowRotationSupported() + */ + virtual bool IsEglWindowRotationSupported() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Move() + */ + virtual void Move( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Resize() + */ + virtual void Resize( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::MoveResize() + */ + virtual void MoveResize( PositionSize positionSize ) override; /** * @copydoc Dali::Internal::Adaptor::WindowBase::ShowIndicator() @@ -130,7 +267,7 @@ public: /** * @copydoc Dali::Internal::Adaptor::WindowBase::SetClass() */ - virtual void SetClass( std::string name, std::string className ) override; + virtual void SetClass( const std::string& name, const std::string& className ) override; /** * @copydoc Dali::Internal::Adaptor::WindowBase::Raise() @@ -272,6 +409,53 @@ public: */ virtual bool UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result ) override; + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetDpi() + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetViewMode() + */ + virtual void SetViewMode( ViewMode viewMode ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenRotationAngle() + */ + virtual int GetScreenRotationAngle() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetWindowRotationAngle() + */ + virtual void SetWindowRotationAngle( int degree ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::WindowRotationCompleted() + */ + virtual void WindowRotationCompleted( int degree, int width, int height ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetTransparency() + */ + virtual void SetTransparency( bool transparent ) override; + +private: + + /** + * Second stage initialization + */ + void Initialize( PositionSize positionSize, Any surface, bool isTransparent ); + + /** + * Initialize Ecore ElDBus + */ + void InitializeEcoreElDBus(); + + /** + * @brief Create window + */ + void CreateWindow( PositionSize positionSize ); + protected: // Undefined @@ -286,9 +470,9 @@ private: Dali::Vector< Ecore_Event_Handler* > mEcoreEventHandler; - Window* mWindow; - WindowRenderSurfaceEcoreWl* mWindowSurface; Ecore_Wl_Window* mEcoreWindow; + wl_surface* mWlSurface; + wl_egl_window* mEglWindow; wl_display* mDisplay; wl_event_queue* mEventQueue; tizen_policy* mTizenPolicy; @@ -308,6 +492,12 @@ private: int mBrightness; uint32_t mBrightnessChangeState; bool mBrightnessChangeDone; + + bool mOwnSurface; + +#ifdef DALI_ELDBUS_AVAILABLE + Eldbus_Connection* mSystemConnection; +#endif // DALI_ELDBUS_AVAILABLE }; } // namespace Adaptor 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 81% 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..2f6638a 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,11 +16,11 @@ */ // CLASS HEADER -#include +#include // INTERNAL HEADERS -#include #include +#include #include namespace Dali @@ -30,9 +30,9 @@ namespace Internal namespace Adaptor { -std::unique_ptr< WindowBase > WindowFactoryEcoreWl::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) +std::unique_ptr< WindowBase > WindowFactoryEcoreWl::CreateWindowBase( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { - return Utils::MakeUnique< WindowBaseEcoreWl >( window, windowRenderSurface ); + return Utils::MakeUnique< WindowBaseEcoreWl >( positionSize, surface, isTransparent ); } std::unique_ptr< IndicatorInterface > WindowFactoryEcoreWl::CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) 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 90% 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 index 5ec717f..1d31bf8 100644 --- 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 @@ -30,7 +30,7 @@ namespace Adaptor class WindowFactoryEcoreWl : public WindowFactory { public: - std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override; + std::unique_ptr< WindowBase > CreateWindowBase( Dali::PositionSize positionSize, Any surface, bool isTransparent ) override; std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) override; }; diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl/window-system-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/window-system-ecore-wl.cpp new file mode 100644 index 0000000..b515bc7 --- /dev/null +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-system-ecore-wl.cpp @@ -0,0 +1,59 @@ +/* + * 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 HEADERS +#include + +// EXTERNAL_HEADERS +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +namespace WindowSystem +{ + +void Initialize() +{ + ecore_wl_init( NULL ); +} + +void Shutdown() +{ + ecore_wl_shutdown(); +} + +void GetScreenSize( int& width, int& height ) +{ + ecore_wl_screen_size_get( &width, &height ); +} + +} // namespace WindowSystem + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#pragma GCC diagnostic pop diff --git a/dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp deleted file mode 100755 index 6cdb165..0000000 --- a/dali/internal/window-system/tizen-wayland/event-handler-ecore-wl.cpp +++ /dev/null @@ -1,1449 +0,0 @@ -/* - * 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_Wl_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_WL_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, handler ) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_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_WL_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, handler ) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, handler ) ); - - // Register Rotate event - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_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_wl_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_wl_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_wl_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_wl_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_wl_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_wl_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_wl_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_Wl_Event_Focus_In* focusInEvent( (Ecore_Wl_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->win == (unsigned int)ecore_wl_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_Wl_Event_Focus_Out* focusOutEvent( (Ecore_Wl_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->win == (unsigned int)ecore_wl_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_Wl_Event_Window_Rotate* ev( (Ecore_Wl_Event_Window_Rotate*)event ); - - if( ev->win != (unsigned int)ecore_wl_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_Wl_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_Wl_Window* window = 0; - - // this code only works with the WindowRenderSurface so need to downcast - WindowRenderSurfaceEcoreWl* ecoreSurface = static_cast< WindowRenderSurfaceEcoreWl* >( 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/indicator-impl-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.cpp index b54492a..b77457e 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,6 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" #include #include -#include #include #include @@ -327,82 +326,6 @@ namespace Adaptor Debug::Filter* gIndicatorLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_INDICATOR"); #endif -// Impl to hide EFL implementation. - -struct IndicatorEcoreWl::Impl -{ - enum // operation mode - { - INDICATOR_HIDE, - INDICATOR_STAY_WITH_DURATION - }; - - /** - * Constructor - */ - Impl(IndicatorEcoreWl* indicator) - : mIndicator(indicator), - mEcoreEventHandler(NULL) - { -#if defined(DALI_PROFILE_MOBILE) - mEcoreEventHandler = ecore_event_handler_add(ECORE_WL_EVENT_INDICATOR_FLICK, EcoreEventIndicator, this); -#endif // DALI_PROFILE_MOBILE - } - - /** - * Destructor - */ - ~Impl() - { - if ( mEcoreEventHandler ) - { - ecore_event_handler_del(mEcoreEventHandler); - } - } - - static void SetIndicatorVisibility( void* data, int operation ) - { - IndicatorEcoreWl::Impl* indicatorImpl((IndicatorEcoreWl::Impl*)data); - - if ( indicatorImpl == NULL || indicatorImpl->mIndicator == NULL) - { - return; - } - if ( operation == INDICATOR_STAY_WITH_DURATION ) - { - // if indicator is not showing, INDICATOR_FLICK_DONE is given - if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO && - !indicatorImpl->mIndicator->mIsShowing ) - { - indicatorImpl->mIndicator->ShowIndicator( AUTO_INDICATOR_STAY_DURATION ); - } - } - else if( operation == INDICATOR_HIDE ) - { - if( indicatorImpl->mIndicator->mVisible == Dali::Window::AUTO && - indicatorImpl->mIndicator->mIsShowing ) - { - indicatorImpl->mIndicator->ShowIndicator( HIDE_NOW ); - } - } - } - -#if defined(DALI_PROFILE_MOBILE) - /** - * Called when the Ecore indicator event is received. - */ - static Eina_Bool EcoreEventIndicator( void* data, int type, void* event ) - { - SetIndicatorVisibility( data, INDICATOR_STAY_WITH_DURATION ); - return ECORE_CALLBACK_PASS_ON; - } -#endif // DALI_PROFILE_MOBILE - - // Data - IndicatorEcoreWl* mIndicator; - Ecore_Event_Handler* mEcoreEventHandler; -}; - IndicatorEcoreWl::LockFile::LockFile(const std::string filename) : mFilename(filename), mErrorThrown(false) @@ -521,7 +444,6 @@ IndicatorEcoreWl::IndicatorEcoreWl( Adaptor* adaptor, Dali::Window::WindowOrient mIsShowing( true ), mIsAnimationPlaying( false ), mCurrentSharedFile( 0 ), - mImpl( NULL ), mBackgroundVisible( false ), mTopMargin( 0 ) { @@ -560,19 +482,10 @@ IndicatorEcoreWl::IndicatorEcoreWl( Adaptor* adaptor, Dali::Window::WindowOrient } // hide the indicator by default mIndicatorActor.SetVisible( false ); - - // create impl to handle ecore event - mImpl = new Impl(this); } IndicatorEcoreWl::~IndicatorEcoreWl() { - if(mImpl) - { - delete mImpl; - mImpl = NULL; - } - if(mEventActor) { mEventActor.TouchSignal().Disconnect( this, &IndicatorEcoreWl::OnTouch ); @@ -635,6 +548,15 @@ void IndicatorEcoreWl::Close() SetForegroundImage( emptyTexture ); } +void IndicatorEcoreWl::Flicked() +{ + // if indicator is not showing, INDICATOR_FLICK_DONE is given + if( mVisible == Dali::Window::AUTO && !mIsShowing ) + { + ShowIndicator( AUTO_INDICATOR_STAY_DURATION ); + } +} + void IndicatorEcoreWl::SetOpacityMode( Dali::Window::IndicatorBgOpacity mode ) { mOpacityMode = mode; diff --git a/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h b/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h index 964583e..1f33fc1 100644 --- a/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h +++ b/dali/internal/window-system/tizen-wayland/indicator-impl-ecore-wl.h @@ -161,6 +161,11 @@ public: // Dali::Internal::Adaptor::IndicicatorInterface virtual void Close(); /** + * @copydoc Dali::Internal::IndicatorInterface::Flicked + */ + virtual void Flicked() override; + + /** * @copydoc Dali::Internal::IndicatorInterface::SetOpacityMode */ virtual void SetOpacityMode( Dali::Window::IndicatorBgOpacity mode ); @@ -416,9 +421,6 @@ private: int mCurrentSharedFile; ///< Current shared file number SharedFileInfo mSharedFileInfo[SHARED_FILE_NUMBER]; ///< Table to store shared file info - struct Impl; ///< Contains Ecore specific information - Impl* mImpl; ///< Created on construction and destroyed on destruction. - bool mBackgroundVisible; ///< Indicate whether background is visible int mTopMargin; ///< Top margin of the stage for indicator }; 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..c3fb051 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 @@ -23,6 +23,7 @@ #include #include + #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include namespace Dali @@ -44,9 +46,8 @@ Debug::Filter* gNativeSurfaceLogFilter = Debug::Filter::New(Debug::Verbose, fals } // unnamed namespace -NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, const std::string& name, bool isTransparent ) +NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, bool isTransparent ) : mPosition( positionSize ), - mTitle( name ), mRenderNotification( NULL ), mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), mTbmFormat( isTransparent ? TBM_FORMAT_ARGB8888 : TBM_FORMAT_RGB888 ), @@ -56,7 +57,8 @@ NativeRenderSurfaceEcoreWl::NativeRenderSurfaceEcoreWl( Dali::PositionSize posit mConsumeSurface( NULL ), mThreadSynchronization( NULL ) { - ecore_wl_init( NULL ); + Dali::Internal::Adaptor::WindowSystem::Initialize(); + CreateNativeRenderable(); setenv( "EGL_PLATFORM", "tbm", 1 ); } @@ -76,7 +78,7 @@ NativeRenderSurfaceEcoreWl::~NativeRenderSurfaceEcoreWl() DALI_LOG_INFO( gNativeSurfaceLogFilter, Debug::General, "Own tbm surface queue destroy\n" ); } - ecore_wl_shutdown(); + Dali::Internal::Adaptor::WindowSystem::Shutdown(); } Any NativeRenderSurfaceEcoreWl::GetDrawable() diff --git a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h index ae52443..cfc3d5a 100644 --- a/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h +++ b/dali/internal/window-system/tizen-wayland/native-render-surface-ecore-wl.h @@ -40,12 +40,9 @@ public: /** * Uses an Wayland surface to render to. * @param [in] positionSize the position and size of the surface - * @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 */ - NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, - const std::string& name, - bool isTransparent = false ); + NativeRenderSurfaceEcoreWl( Dali::PositionSize positionSize, bool isTransparent = false ); /** * @brief Destructor @@ -161,7 +158,6 @@ private: private: // Data PositionSize mPosition; - std::string mTitle; TriggerEventInterface* mRenderNotification; ColorDepth mColorDepth; tbm_format mTbmFormat; diff --git a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp deleted file mode 100644 index 50d0777..0000000 --- a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.cpp +++ /dev/null @@ -1,561 +0,0 @@ -/* - * 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_WL"); -#endif - -} // unnamed namespace - -WindowRenderSurfaceEcoreWl::WindowRenderSurfaceEcoreWl( 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 ); -} - -WindowRenderSurfaceEcoreWl::~WindowRenderSurfaceEcoreWl() -{ - if( mEglWindow != NULL ) - { - wl_egl_window_destroy(mEglWindow); - mEglWindow = NULL; - } - - if( mOwnSurface ) - { - ecore_wl_window_free( mWlWindow ); - } - - if( mRotationTrigger ) - { - delete mRotationTrigger; - } - - if( mOwnSurface ) - { - ecore_wl_shutdown(); - } -} - -void WindowRenderSurfaceEcoreWl::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_wl_init( NULL ); - mOwnSurface = true; - CreateRenderable(); - } - else - { - // XLib should already be initialized so no point in calling XInitThreads - UseExistingRenderable( surfaceId ); - } -} - -Ecore_Wl_Window* WindowRenderSurfaceEcoreWl::GetWlWindow() -{ - return mWlWindow; -} - -void WindowRenderSurfaceEcoreWl::OutputTransformed() -{ - int transform; - - if( ecore_wl_window_ignore_output_transform_get( mWlWindow ) ) - { - transform = 0; - } - else - { - transform = ecore_wl_output_transform_get( ecore_wl_window_output_find( mWlWindow ) ); - } - - mScreenRotationAngle = transform * 90; - mScreenRotationFinished = false; - - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::OutputTransformed: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); -} - -Any WindowRenderSurfaceEcoreWl::GetWindow() -{ - return mWlWindow; -} - -void WindowRenderSurfaceEcoreWl::Map() -{ - ecore_wl_window_show( mWlWindow ); -} - -void WindowRenderSurfaceEcoreWl::SetRenderNotification( TriggerEventInterface* renderNotification ) -{ - mRenderNotification = renderNotification; -} - -void WindowRenderSurfaceEcoreWl::SetTransparency( bool transparent ) -{ - ecore_wl_window_alpha_set( mWlWindow, transparent ); -} - -void WindowRenderSurfaceEcoreWl::RequestRotation( int angle, int width, int height ) -{ - if( !mRotationSupported ) - { - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::Rotate: Rotation is not supported!\n" ); - return; - } - - if( !mRotationTrigger ) - { - TriggerEventFactoryInterface& triggerFactory = Internal::Adaptor::Adaptor::GetImplementation( Adaptor::Get() ).GetTriggerEventFactoryInterface(); - mRotationTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &WindowRenderSurfaceEcoreWl::ProcessRotationRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); - } - - mPositionSize.width = width; - mPositionSize.height = height; - - mRotationAngle = angle; - mRotationFinished = false; - - ecore_wl_window_rotation_set( mWlWindow, mRotationAngle ); - - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::Rotate: angle = %d screen rotation = %d\n", mRotationAngle, mScreenRotationAngle ); -} - -PositionSize WindowRenderSurfaceEcoreWl::GetPositionSize() const -{ - return mPositionSize; -} - -void WindowRenderSurfaceEcoreWl::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) -{ - // calculate DPI - float xres, yres; - - // 1 inch = 25.4 millimeters - xres = ecore_wl_dpi_get(); - yres = ecore_wl_dpi_get(); - - dpiHorizontal = int( xres + 0.5f ); // rounding - dpiVertical = int( yres + 0.5f ); -} - -void WindowRenderSurfaceEcoreWl::InitializeEgl( EglInterface& eglIf ) -{ - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); - - Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); - - eglImpl.ChooseConfig(true, mColorDepth); -} - -void WindowRenderSurfaceEcoreWl::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, "WindowRenderSurfaceEcoreWl::CreateEglSurface: capability = %d\n", capability ); - mRotationSupported = true; - } - - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::CreateEglSurface: w = %d h = %d angle = %d screen rotation = %d\n", mPositionSize.width, mPositionSize.height, mRotationAngle, mScreenRotationAngle ); -} - -void WindowRenderSurfaceEcoreWl::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 WindowRenderSurfaceEcoreWl::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 WindowRenderSurfaceEcoreWl::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 ) - { - ecore_wl_window_position_set( mWlWindow, positionSize.x, positionSize.y ); - } - if( needToResize ) - { - ecore_wl_window_update_size( mWlWindow, positionSize.width, positionSize.height ); - mResizeFinished = false; - } - - mPositionSize = positionSize; - - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::MoveResize: %d, %d, %d, %d\n", mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height ); -} - -void WindowRenderSurfaceEcoreWl::SetViewMode( ViewMode viewMode ) -{ -} - -void WindowRenderSurfaceEcoreWl::StartRender() -{ -} - -bool WindowRenderSurfaceEcoreWl::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, "WindowRenderSurfaceEcoreWl::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, "WindowRenderSurfaceEcoreWl::PreRender: Set resize\n" ); - } - } - - return true; -} - -void WindowRenderSurfaceEcoreWl::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) -{ - if( resizingSurface ) - { - if( !mRotationFinished ) - { - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::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 WindowRenderSurfaceEcoreWl::StopRender() -{ -} - -void WindowRenderSurfaceEcoreWl::SetThreadSynchronization( ThreadSynchronizationInterface& threadSynchronization ) -{ - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::SetThreadSynchronization: called\n" ); - - mThreadSynchronization = &threadSynchronization; -} - -void WindowRenderSurfaceEcoreWl::ReleaseLock() -{ - // Nothing to do. -} - -RenderSurface::Type WindowRenderSurfaceEcoreWl::GetSurfaceType() -{ - return RenderSurface::WINDOW_RENDER_SURFACE; -} - -void WindowRenderSurfaceEcoreWl::CreateRenderable() -{ - // 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_wl_screen_size_get( &mPositionSize.width, &mPositionSize.height ); - } - - mWlWindow = ecore_wl_window_new( 0, mPositionSize.x, mPositionSize.y, mPositionSize.width, mPositionSize.height, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW ); - - if ( mWlWindow == 0 ) - { - DALI_ASSERT_ALWAYS(0 && "Failed to create Wayland window"); - } - - mWlSurface = ecore_wl_window_surface_create( mWlWindow ); - - if( mColorDepth == COLOR_DEPTH_32 ) - { - ecore_wl_window_alpha_set( mWlWindow, true ); - } - else - { - ecore_wl_window_alpha_set( mWlWindow, false ); - } - - // Get output transform - if( !ecore_wl_window_ignore_output_transform_get( mWlWindow ) ) - { - Ecore_Wl_Output* output = ecore_wl_window_output_find( mWlWindow ); - - int transform = ecore_wl_output_transform_get( output ); - - mScreenRotationAngle = transform * 90; - mScreenRotationFinished = false; - } -} - -void WindowRenderSurfaceEcoreWl::UseExistingRenderable( unsigned int surfaceId ) -{ - mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId ); -} - -unsigned int WindowRenderSurfaceEcoreWl::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_Wl_Window *) ) ) - && "Surface type is invalid" ); - - surfaceId = AnyCast( surface ); - } - return surfaceId; -} - -void WindowRenderSurfaceEcoreWl::ProcessRotationRequest() -{ - mRotationFinished = true; - - ecore_wl_window_rotation_change_done_send( mWlWindow ); - - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurfaceEcoreWl::ProcessRotationRequest: Rotation Done\n" ); - - if( mThreadSynchronization ) - { - mThreadSynchronization->PostRenderComplete(); - } -} - -} // namespace Adaptor - -} // namespace internal - -} // namespace Dali diff --git a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h b/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h deleted file mode 100644 index 420bc92..0000000 --- a/dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h +++ /dev/null @@ -1,238 +0,0 @@ -#ifndef __DALI_INTERNAL_ECORE_WL_WINDOW_RENDER_SURFACE_H__ -#define __DALI_INTERNAL_ECORE_WL_WINDOW_RENDER_SURFACE_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 - -// INTERNAL INCLUDES -#include -#include -#include -#include - -namespace Dali -{ - -namespace Internal -{ -namespace Adaptor -{ - -/** - * Ecore Wayland Window implementation of render surface. - */ -class WindowRenderSurfaceEcoreWl : 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 - */ - WindowRenderSurfaceEcoreWl( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - bool isTransparent = false ); - - /** - * @brief Destructor - */ - virtual ~WindowRenderSurfaceEcoreWl(); - -public: // API - - /** - * @brief Get window handle - * @return the Ecore Waylnad window handle - */ - Ecore_Wl_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_Wl_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 WindowRenderSurfaceEcoreWl - -} // namespace Adaptor - -} // namespace internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_ECORE_WL_WINDOW_RENDER_SURFACE_H__ diff --git a/dali/internal/window-system/ubuntu-x11/event-handler-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/event-handler-ecore-x.cpp deleted file mode 100755 index 7ab646d..0000000 --- a/dali/internal/window-system/ubuntu-x11/event-handler-ecore-x.cpp +++ /dev/null @@ -1,1765 +0,0 @@ -/* - * 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 -#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 - -// INTERNAL INCLUDES -#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* gClientMessageLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_CLIENT_MESSAGE"); -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 -{ - -const char * DETENT_DEVICE_NAME = "tizen_detent"; -const std::string DEFAULT_DEVICE_NAME = ""; -const Device::Class::Type DEFAULT_DEVICE_CLASS = Device::Class::NONE; -const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE; - -// DBUS accessibility -#define A11Y_BUS "org.a11y.Bus" -#define A11Y_INTERFACE "org.a11y.Bus" -#define A11Y_PATH "/org/a11y/bus" -#define A11Y_GET_ADDRESS "GetAddress" -#define BUS "com.samsung.EModule" -#define INTERFACE "com.samsung.GestureNavigation" -#define PATH "/com/samsung/GestureNavigation" -#define SIGNAL "GestureDetected" - -#ifndef DALI_PROFILE_UBUNTU -const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced. -#endif // DALI_PROFILE_UBUNTU - -const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 ); - -#ifndef DALI_PROFILE_UBUNTU -const char * CLIPBOARD_ATOM = "CBHM_MSG"; -const char * CLIPBOARD_SET_OWNER_MESSAGE = "SET_OWNER"; -#endif // DALI_PROFILE_UBUNTU - -/// The atoms required by Ecore for Drag & Drop behaviour. -Ecore_X_Atom DRAG_AND_DROP_ATOMS[] = -{ - ECORE_X_ATOM_XDND_ACTION_COPY, -}; - -/// The types that we support. -const char * DRAG_AND_DROP_TYPES[] = -{ - ECORE_X_SELECTION_TARGET_UTF8_STRING, -}; - -const unsigned int DRAG_AND_DROP_ATOMS_NUMBER = sizeof( DRAG_AND_DROP_ATOMS ) / sizeof( Ecore_X_Atom ); -const unsigned int DRAG_AND_DROP_TYPES_NUMBER = sizeof( DRAG_AND_DROP_TYPES ) / sizeof( const char * ); - -const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3; - -#ifdef DALI_ELDBUS_AVAILABLE -// DBus gesture string matching lists. -// TODO: This needs moving to its own module. -const char * ElDBusAccessibilityFingerCountStrings[] = -{ - "OneFinger", - "TwoFingers", - "ThreeFingers" -}; -const unsigned int FingerCountStringsTotal = sizeof( ElDBusAccessibilityFingerCountStrings ) / sizeof( ElDBusAccessibilityFingerCountStrings[0] ); -enum GestureType -{ - GESTURE_TYPE_NONE, - GESTURE_TYPE_HOVER, - GESTURE_TYPE_SINGLE_TAP, - GESTURE_TYPE_DOUBLE_TAP, - GESTURE_TYPE_TRIPLE_TAP -}; -struct GestureTypeTable -{ - const char* name; - const GestureType type; -}; -GestureTypeTable ElDBusAccessibilityFullEventTypeStrings[] = -{ - { "Hover", GESTURE_TYPE_HOVER }, - { "SingleTap", GESTURE_TYPE_SINGLE_TAP }, - { "DoubleTap", GESTURE_TYPE_DOUBLE_TAP }, - { "TripleTap", GESTURE_TYPE_TRIPLE_TAP } -}; -const unsigned int FullEventTypeStringsTotal = sizeof( ElDBusAccessibilityFullEventTypeStrings ) / sizeof( ElDBusAccessibilityFullEventTypeStrings[0] ); -enum SubGestureType -{ - SUB_GESTURE_TYPE_NONE, - SUB_GESTURE_TYPE_FLICK -}; -struct SubGestureTypeTable -{ - const char* name; - const SubGestureType type; -}; -SubGestureTypeTable ElDBusAccessibilityDirectionalEventTypeStrings[] = -{ - { "Flick", SUB_GESTURE_TYPE_FLICK } -}; -const unsigned int DirectionalEventTypeStringsTotal = sizeof( ElDBusAccessibilityDirectionalEventTypeStrings ) / sizeof( ElDBusAccessibilityDirectionalEventTypeStrings[0] ); -enum GestureDirection -{ - GESTURE_DIRECTION_NONE, - GESTURE_DIRECTION_UP, - GESTURE_DIRECTION_DOWN, - GESTURE_DIRECTION_LEFT, - GESTURE_DIRECTION_RIGHT, - GESTURE_DIRECTION_UP_RETURN, - GESTURE_DIRECTION_DOWN_RETURN, - GESTURE_DIRECTION_LEFT_RETURN, - GESTURE_DIRECTION_RIGHT_RETURN -}; -struct GestureDirectionTable -{ - const char* name; - const GestureDirection direction; -}; -GestureDirectionTable ElDBusAccessibilityDirectionStrings[] = -{ - { "Up", GESTURE_DIRECTION_UP }, - { "Down", GESTURE_DIRECTION_DOWN }, - { "Left", GESTURE_DIRECTION_LEFT }, - { "Right", GESTURE_DIRECTION_RIGHT }, - { "UpReturn", GESTURE_DIRECTION_UP_RETURN }, - { "DownReturn", GESTURE_DIRECTION_DOWN_RETURN }, - { "LeftReturn", GESTURE_DIRECTION_LEFT_RETURN }, - { "RightReturn", GESTURE_DIRECTION_RIGHT_RETURN } -}; -const unsigned int DirectionStringsTotal = sizeof( ElDBusAccessibilityDirectionStrings ) / sizeof( ElDBusAccessibilityDirectionStrings[0] ); -#endif // DALI_ELDBUS_AVAILABLE - -// 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); -} - -} // unnamed namespace - -// Impl to hide EFL implementation. -struct EventHandler::Impl -{ - // Construction & Destruction - - /** - * Constructor - */ - Impl( EventHandler* handler, Ecore_X_Window window ) - : mHandler( handler ), - mEcoreEventHandler(), - mWindow( window ), - mXiDeviceId( 0 ) -#ifdef DALI_ELDBUS_AVAILABLE - , mSessionConnection( NULL ), - mA11yConnection( NULL ) -#endif - { - // 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_OUT, EcoreEventMouseButtonUp, handler ) ); // process mouse out event like up event - - // Register Mouse wheel events - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL, EcoreEventMouseWheel, 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 Focus events - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN, EcoreEventWindowFocusIn, handler ) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut, handler ) ); - - // Register Window damage events - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE, EcoreEventWindowDamaged, handler ) ); - - // Enable Drag & Drop and register DnD events - ecore_x_dnd_aware_set( window, EINA_TRUE ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_ENTER, EcoreEventDndEnter, handler) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_POSITION, EcoreEventDndPosition, handler) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_LEAVE, EcoreEventDndLeave, handler) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_DROP, EcoreEventDndDrop, handler) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_FINISHED, EcoreEventDndFinished, handler) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_STATUS, EcoreEventDndStatus, handler) ); - - // Register Client message events - accessibility etc. - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE, EcoreEventClientMessage, handler ) ); - - // Register Selection event - clipboard selection, Drag & Drop selection etc. - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) ); - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) ); - - // Initialize Xi2 system - Display* display = static_cast< Display* >(ecore_x_display_get()); - Ecore_X_Window rootWindow = ecore_x_window_root_first_get(); - int opcode = 0, event = 0, error = 0; - int major = XI_2_Major; - int minor = XI_2_Minor; - int deviceCount = 0; - XIEventMask xiEventMask; - - // Check if X input extension available - if( XQueryExtension( display, "XInputExtension", &opcode, &event, &error ) ) - { - // We support version 2.0 - if( XIQueryVersion( display, &major, &minor ) != BadRequest ) - { - xiEventMask.deviceid = XIAllDevices; - - // Check device id - bool match = false; - XIDeviceInfo* deviceInfo = NULL; - deviceInfo = XIQueryDevice( display, XIAllDevices, &deviceCount ); - - for( int i = 0; i < deviceCount; i++ ) - { - if( !strncmp( deviceInfo[i].name, DETENT_DEVICE_NAME, strlen( DETENT_DEVICE_NAME ) ) ) - { - xiEventMask.deviceid = deviceInfo[i].deviceid; - match = true; - break; - } - } - - if( match ) - { - mXiDeviceId = xiEventMask.deviceid; - - // SelectXi2Event - Dali::Vector< unsigned char > mask; - std::size_t xiMaskLen = XIMaskLen( XI_LASTEVENT ); - mask.Reserve( xiMaskLen ); - xiEventMask.mask = mask.Begin(); - - XISetMask( xiEventMask.mask, XI_RawMotion ); - - xiEventMask.mask_len = xiMaskLen * sizeof( unsigned char ); - - int ret = XISelectEvents( display, rootWindow, &xiEventMask, 1 ); - if( ret == 0 ) - { - // Register custom wheel events - mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_GENERIC, EcoreEventCustomWheel, handler ) ); - } - else - { - DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to Select Events\n" ); - } - } - - if( deviceInfo != NULL ) - { - XIFreeDeviceInfo( deviceInfo ); - } - } - else - { - DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XI Version\n" ); - } - } - else - { - DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XInputExtension\n" ); - } - -#ifndef DALI_PROFILE_UBUNTU - // Register Vconf notify - font name, font size and style - vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, 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" ); - eldbus_init(); - - mSessionConnection = eldbus_connection_get( ELDBUS_CONNECTION_TYPE_SESSION ); - - Eldbus_Object *a11yObject = eldbus_object_get( mSessionConnection, A11Y_BUS, A11Y_PATH ); - Eldbus_Proxy *elDBusManager = eldbus_proxy_get( a11yObject, A11Y_INTERFACE ); - - // Pass in handler in the cb_data field so we can access the accessibility adaptor within the callback. - eldbus_proxy_call( elDBusManager, A11Y_GET_ADDRESS, EcoreElDBusInitialisation, handler, -1, "" ); - - 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_NAME, 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 - if( mA11yConnection ) - { - eldbus_connection_unref( mA11yConnection ); - } - - if( mSessionConnection ) - { - eldbus_connection_unref( mSessionConnection ); - } - - eldbus_shutdown(); -#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 == 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; - } - - 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 ) ); - 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 == handler->mImpl->mWindow ) - { - 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 ) ); - 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 == handler->mImpl->mWindow ) - { - 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 ) ); - handler->SendEvent( point, touchEvent->timestamp ); - } - - return ECORE_CALLBACK_PASS_ON; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - // Wheel Callbacks - ///////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * 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 == 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; - } - - /** - * Called when a custom wheel is received. - */ - static Eina_Bool EcoreEventCustomWheel( void* data, int type, void* event ) - { - Ecore_X_Event_Generic *genericEvent( (Ecore_X_Event_Generic*)event ); - EventHandler* handler( (EventHandler*)data ); - - switch( genericEvent->evtype ) - { - case XI_RawMotion: - { - XIRawEvent* xiRawEvent = static_cast< XIRawEvent* >( genericEvent->data ); - unsigned int timeStamp = 0; - - if( xiRawEvent->deviceid != handler->mImpl->mXiDeviceId ) - { - return ECORE_CALLBACK_PASS_ON; - } - - // X(0): rotate: NOT USED - // Y(1): timestamp - // Z(2): direction - - double* value = xiRawEvent->raw_values; - - if( XIMaskIsSet( xiRawEvent->valuators.mask, 1) ) - { - timeStamp = static_cast< unsigned int >( *(value + 1) ); - } - - if( XIMaskIsSet( xiRawEvent->valuators.mask, 2) ) - { - // if z == 1, clockwise - // otherwise counter-clockwise - int z = static_cast< int >( *(value + 2) ); - - // In DALi, positive value means clockwise, and negative value means counter-clockwise - if( z == 0 ) - { - z = -1; - } - - DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventCustomWheel: z: %d\n", z ); - - WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), z, timeStamp ); - handler->SendWheelEvent( wheelEvent ); - } - break; - } - default: - { - break; - } - } - - 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 == 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 = ecore_x_keysym_keycode_get(keyEvent->keyname); - int modifier( keyEvent->modifiers ); - unsigned long time = keyEvent->timestamp; - - // Ensure key event string is not NULL as keys like SHIFT have a null string. - if ( keyEvent->string ) - { - keyString = keyEvent->string; - } - - Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS ); - 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 == 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 = ecore_x_keysym_keycode_get(keyEvent->keyname); - int modifier( keyEvent->modifiers ); - unsigned long time( keyEvent->timestamp ); - - // Ensure key event string is not NULL as keys like SHIFT have a null string. - if ( keyEvent->string ) - { - keyString = keyEvent->string; - } - - Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS ); - - 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_X_Event_Window_Focus_In* focusInEvent( (Ecore_X_Event_Window_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->win == handler->mImpl->mWindow ) - { - DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" ); - } - - return ECORE_CALLBACK_PASS_ON; - } - - /** - * Called when the window loses focus. - */ - static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event ) - { - Ecore_X_Event_Window_Focus_Out* focusOutEvent( (Ecore_X_Event_Window_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->win == handler->mImpl->mWindow ) - { - // Clipboard don't support that whether clipboard is shown or not. Hide clipboard. - Dali::Clipboard clipboard = Clipboard::Get(); - clipboard.HideClipboard(); - } - - return ECORE_CALLBACK_PASS_ON; - } - - /** - * Called when the window is damaged. - */ - static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event) - { - Ecore_X_Event_Window_Damage* windowDamagedEvent( (Ecore_X_Event_Window_Damage*)event ); - EventHandler* handler( (EventHandler*)data ); - - if( windowDamagedEvent->win == handler->mImpl->mWindow ) - { - DamageArea area; - area.x = windowDamagedEvent->x; - area.y = windowDamagedEvent->y; - area.width = windowDamagedEvent->w; - area.height = windowDamagedEvent->h; - - handler->SendEvent( area ); - } - - 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" ); - - Ecore_X_Event_Xdnd_Enter* enterEvent( (Ecore_X_Event_Xdnd_Enter*) event ); - EventHandler* handler( (EventHandler*)data ); - Ecore_X_Window window ( handler->mImpl->mWindow ); - - if ( enterEvent->win == window ) - { - DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector ); - - // Check whether the Drag & Drop detector has Drag & Drop behaviour enabled before we accept. - if ( dndDetector && dndDetector->IsEnabled() ) - { - // Tell Ecore that we want to enable drop in the entire window. - Ecore_X_Rectangle rect; - rect.x = rect.y = 0; - ecore_x_window_geometry_get( window, NULL, NULL, (int*)&rect.width, (int*)&rect.height ); - - // Tell Ecore that we are able to process a drop. - ecore_x_dnd_send_status( EINA_TRUE, EINA_FALSE, rect, ECORE_X_ATOM_XDND_DROP ); - - // Register the required atoms and types. - ecore_x_dnd_actions_set( window, DRAG_AND_DROP_ATOMS, DRAG_AND_DROP_ATOMS_NUMBER ); - ecore_x_dnd_types_set( window, DRAG_AND_DROP_TYPES, DRAG_AND_DROP_TYPES_NUMBER ); - - // Request to get the content from Ecore. - ecore_x_selection_xdnd_request( window, ECORE_X_SELECTION_TARGET_UTF8_STRING ); - - DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndEnter: Requesting Drag & Drop\n" ); - - // Clear the previous content - dndDetector->ClearContent(); - - // Emit the entered signal - dndDetector->EmitEnteredSignal(); - } - } - - 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" ); - - Ecore_X_Event_Xdnd_Position* positionEvent( (Ecore_X_Event_Xdnd_Position*) event ); - EventHandler* handler( (EventHandler*)data ); - - if ( positionEvent->win == handler->mImpl->mWindow ) - { - DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector ); - - // If we have a detector then update its latest position. - if ( dndDetector ) - { - DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndPosition: position ( %d x %d )\n", positionEvent->position.x, positionEvent->position.y ); - dndDetector->SetPosition( Vector2( positionEvent->position.x, positionEvent->position.y )); - dndDetector->EmitMovedSignal(); - } - } - - 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" ); - - Ecore_X_Event_Xdnd_Leave* leaveEvent( (Ecore_X_Event_Xdnd_Leave*) event ); - EventHandler* handler( (EventHandler*)data ); - - if ( leaveEvent->win == handler->mImpl->mWindow ) - { - DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector ); - - // If we have a detector then clear its content and emit the exited-signal. Also tell Ecore that we have finished. - if ( dndDetector ) - { - dndDetector->ClearContent(); - dndDetector->EmitExitedSignal(); - - ecore_x_dnd_send_finished(); - - DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndLeave: Finished\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" ); - - Ecore_X_Event_Xdnd_Drop* dropEvent ( (Ecore_X_Event_Xdnd_Drop*) event); - EventHandler* handler( (EventHandler*)data ); - - if ( dropEvent->win == handler->mImpl->mWindow ) - { - DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector ); - - // Something has been dropped, inform the detector (if we have one) and tell Ecore that we have finished. - if ( dndDetector ) - { - DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: position ( %d x %d )\n", dropEvent->position.x, dropEvent->position.y ); - - dndDetector->SetPosition( Vector2( dropEvent->position.x, dropEvent->position.y ) ); - dndDetector->EmitDroppedSignal(); - ecore_x_dnd_send_finished(); - - DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: Finished\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 ) - { -#ifndef DALI_PROFILE_UBUNTU - Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event ); - EventHandler* handler( (EventHandler*)data ); - - if (clientMessageEvent->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) - { - if ( ( (unsigned int)clientMessageEvent->data.l[0] == handler->mImpl->mWindow ) && handler->mAccessibilityAdaptor ) - { - AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( handler->mAccessibilityAdaptor ) ); - - if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL) - { - // 2 finger touch & move, 2 finger flick - - // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up) - // x : e->data.l[3] - // y : e->data.l[4] - TouchPoint::State state(TouchPoint::Down); - - if ((unsigned int)clientMessageEvent->data.l[2] == 0) - { - state = TouchPoint::Down; // mouse down - } - else if ((unsigned int)clientMessageEvent->data.l[2] == 1) - { - state = TouchPoint::Motion; // mouse move - } - else if ((unsigned int)clientMessageEvent->data.l[2] == 2) - { - state = TouchPoint::Up; // mouse up - } - else - { - state = TouchPoint::Interrupted; // error - } - - DALI_LOG_INFO(gClientMessageLogFilter, Debug::General, - "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__, - (unsigned int)clientMessageEvent->data.l[2], - (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]); - - // Send touch event to accessibility adaptor. - TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] ); - - // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control - accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() ); - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE) - { - // 1 finger double tap and hold - - // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up) - // x : e->data.l[3] - // y : e->data.l[4] - TouchPoint::State state(TouchPoint::Down); - - if ((unsigned int)clientMessageEvent->data.l[2] == 0) - { - state = TouchPoint::Down; // mouse down - } - else if ((unsigned int)clientMessageEvent->data.l[2] == 1) - { - state = TouchPoint::Motion; // mouse move - } - else if ((unsigned int)clientMessageEvent->data.l[2] == 2) - { - state = TouchPoint::Up; // mouse up - } - else - { - state = TouchPoint::Interrupted; // error - } - - DALI_LOG_INFO(gClientMessageLogFilter, Debug::General, - "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__, - (unsigned int)clientMessageEvent->data.l[2], - (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]); - - // Send touch event to accessibility adaptor. - TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] ); - - // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control - accessibilityAdaptor->HandleActionTouchEvent( point, GetCurrentMilliSeconds() ); - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK) - { - // 2 finger circle draw, do back - accessibilityAdaptor->HandleActionBackEvent(); - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT) - { - // one finger flick down - // focus next object - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionNextEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV) - { - // one finger flick up - // focus previous object - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionPreviousEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) - { - // one finger double tap - // same as one finger tap in normal mode (i.e. execute focused actor) - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionActivateEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) - { - // one finger tap - // focus & read an actor at ( e->data.l[2], e->data.l[3] ) position according to finger - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[2], (unsigned int)clientMessageEvent->data.l[3], true /* allow read again*/); - } - } -#if defined(DALI_PROFILE_MOBILE) - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER) - { - // one finger tap & move - // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up) - // x : e->data.l[3] - // y : e->data.l[4] - // focus & read an actor at (x, y) position according to finger - if(accessibilityAdaptor && (unsigned int)clientMessageEvent->data.l[2] == 1 /*only work for move event*/) - { - accessibilityAdaptor->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4], false /* not allow read again*/); - } - } -#endif - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT) - { - // one finger flick right - // focus next object - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionReadNextEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV) - { - // one finger flick left - // focus previous object - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionReadPreviousEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP) - { - // double down and move (right, up) - // change slider value - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionUpEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN) - { - // double down and move (left, down) - // change slider value - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionDownEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE) - { - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionEnableEvent(); - } - } - else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE) - { - if(accessibilityAdaptor) - { - accessibilityAdaptor->HandleActionDisableEvent(); - } - } - // TODO: some more actions could be added later - } - } - else if(clientMessageEvent->message_type == ecore_x_atom_get(CLIPBOARD_ATOM)) - { - std::string message(clientMessageEvent->data.b); - if( message == CLIPBOARD_SET_OWNER_MESSAGE) - { - // Claim the ownership of the SECONDARY selection. - ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1); - - // Show the clipboard window - Dali::Clipboard clipboard = Dali::Clipboard::Get(); - clipboard.ShowClipboard(); - } - } - else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE ) - { - RotationEvent rotationEvent; - rotationEvent.angle = static_cast(clientMessageEvent->data.l[1]); - rotationEvent.winResize = static_cast(clientMessageEvent->data.l[2]); - rotationEvent.width = static_cast(clientMessageEvent->data.l[3]); - rotationEvent.height = static_cast(clientMessageEvent->data.l[4]); - handler->SendRotationPrepareEvent( rotationEvent ); - } - else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST ) - { - handler->SendRotationRequestEvent(); - } - -#endif // DALI_PROFILE_UBUNTU - 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; - } - - const char *gestureName; - int xS, yS, xE, yE; - unsigned int state; - - // The string defines the arg-list's respective types. - if( !eldbus_message_arguments_get( message, "siiiiu", &gestureName, &xS, &yS, &xE, &yE, &state ) ) - { - DALI_LOG_ERROR( "OnEcoreElDBusAccessibilityNotification: Error getting arguments\n" ); - } - - DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Name: %s Args: %d,%d,%d,%d State: %d\n", gestureName, xS, yS, xE, yE ); - - unsigned int fingers = 0; - char* stringPosition = ( char* )gestureName; - - // Check how many fingers the gesture uses. - for( unsigned int i = 0; i < FingerCountStringsTotal; ++i ) - { - unsigned int matchLength = strlen( ElDBusAccessibilityFingerCountStrings[ i ] ); - if( strncmp( gestureName, ElDBusAccessibilityFingerCountStrings[ i ], matchLength ) == 0 ) - { - fingers = i + 1; - stringPosition += matchLength; - break; - } - } - - if( fingers == 0 ) - { - // Error: invalid gesture. - return; - } - - GestureType gestureType = GESTURE_TYPE_NONE; - SubGestureType subGestureType = SUB_GESTURE_TYPE_NONE; - GestureDirection direction = GESTURE_DIRECTION_NONE; - - // Check for full gesture type names first. - for( unsigned int i = 0; i < FullEventTypeStringsTotal; ++i ) - { - unsigned int matchLength = strlen( ElDBusAccessibilityFullEventTypeStrings[ i ].name ); - if( strncmp( stringPosition, ElDBusAccessibilityFullEventTypeStrings[ i ].name, matchLength ) == 0 ) - { - gestureType = ElDBusAccessibilityFullEventTypeStrings[ i ].type; - break; - } - } - - // If we didn't find a full gesture, check for sub gesture type names. - if( gestureType == GESTURE_TYPE_NONE ) - { - // No full gesture name found, look for partial types. - for( unsigned int i = 0; i < DirectionalEventTypeStringsTotal; ++i ) - { - unsigned int matchLength = strlen( ElDBusAccessibilityDirectionalEventTypeStrings[ i ].name ); - if( strncmp( stringPosition, ElDBusAccessibilityDirectionalEventTypeStrings[ i ].name, matchLength ) == 0 ) - { - subGestureType = ElDBusAccessibilityDirectionalEventTypeStrings[ i ].type; - stringPosition += matchLength; - break; - } - } - - if( subGestureType == SUB_GESTURE_TYPE_NONE ) - { - // ERROR: Gesture not recognised. - return; - } - - // If the gesture was a sub type, get it's respective direction. - for( unsigned int i = 0; i < DirectionStringsTotal; ++i ) - { - unsigned int matchLength = strlen( ElDBusAccessibilityDirectionStrings[ i ].name ); - if( strncmp( stringPosition, ElDBusAccessibilityDirectionStrings[ i ].name, matchLength ) == 0 ) - { - direction = ElDBusAccessibilityDirectionStrings[ i ].direction; - stringPosition += matchLength; - break; - } - } - - if( direction == GESTURE_DIRECTION_NONE ) - { - // ERROR: Gesture not recognised. - return; - } - } - - // Action the detected gesture here. - if( gestureType != GESTURE_TYPE_NONE ) - { - DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Fingers: %d Gesture type: %d\n", fingers, gestureType ); - } - else - { - DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Fingers: %d Gesture sub type: %d Gesture direction: %d\n", - fingers, subGestureType, direction ); - } - - // 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 (in future) - // have other input readers without changing the below code. - switch( fingers ) - { - case 1: - { - if( gestureType == GESTURE_TYPE_SINGLE_TAP || ( gestureType == GESTURE_TYPE_HOVER && touchPointState == TouchPoint::Motion ) ) - { - // Focus, read out. - accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ ); - } - else if( gestureType == GESTURE_TYPE_DOUBLE_TAP ) - { - if( false ) // TODO: how to detect double tap + hold? - { - // Move or drag icon / view more options for selected items. - // accessibilityAdaptor->HandleActionTouchEvent( point, GetCurrentMilliSeconds() ); - } - else - { - // Activate selected item / active edit mode. - accessibilityAdaptor->HandleActionActivateEvent(); - } - } - else if( gestureType == GESTURE_TYPE_TRIPLE_TAP ) - { - // Zoom - accessibilityAdaptor->HandleActionZoomEvent(); - } - else if( subGestureType == SUB_GESTURE_TYPE_FLICK ) - { - if( direction == GESTURE_DIRECTION_LEFT ) - { - // Move to previous item. - accessibilityAdaptor->HandleActionReadPreviousEvent(); - } - else if( direction == GESTURE_DIRECTION_RIGHT ) - { - // Move to next item. - accessibilityAdaptor->HandleActionReadNextEvent(); - } - else if( direction == GESTURE_DIRECTION_UP ) - { - // Move to next item. - accessibilityAdaptor->HandleActionPreviousEvent(); - } - else if( direction == GESTURE_DIRECTION_DOWN ) - { - // Move to next item. - accessibilityAdaptor->HandleActionNextEvent(); - } - else if( direction == GESTURE_DIRECTION_LEFT_RETURN ) - { - // Scroll up to the previous page - accessibilityAdaptor->HandleActionPageUpEvent(); - } - else if( direction == GESTURE_DIRECTION_RIGHT_RETURN ) - { - // Scroll down to the next page - accessibilityAdaptor->HandleActionPageDownEvent(); - } - else if( direction == GESTURE_DIRECTION_UP_RETURN ) - { - // Move to the first item on screen - accessibilityAdaptor->HandleActionMoveToFirstEvent(); - } - else if( direction == GESTURE_DIRECTION_DOWN_RETURN ) - { - // Move to the last item on screen - accessibilityAdaptor->HandleActionMoveToLastEvent(); - } - } - break; - } - - case 2: - { - if( gestureType == GESTURE_TYPE_HOVER ) - { - // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control - accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() ); - } - else if( gestureType == GESTURE_TYPE_SINGLE_TAP ) - { - // Pause/Resume current speech - accessibilityAdaptor->HandleActionReadPauseResumeEvent(); - } - else if( gestureType == GESTURE_TYPE_DOUBLE_TAP ) - { - // Start/Stop current action - accessibilityAdaptor->HandleActionStartStopEvent(); - } - else if( gestureType == GESTURE_TYPE_TRIPLE_TAP ) - { - // Read information from indicator - accessibilityAdaptor->HandleActionReadIndicatorInformationEvent(); - } - else if( subGestureType == SUB_GESTURE_TYPE_FLICK ) - { - if( direction == GESTURE_DIRECTION_LEFT ) - { - // Scroll left to the previous page - accessibilityAdaptor->HandleActionPageLeftEvent(); - } - else if( direction == GESTURE_DIRECTION_RIGHT ) - { - // Scroll right to the next page - accessibilityAdaptor->HandleActionPageRightEvent(); - } - else if( direction == GESTURE_DIRECTION_UP ) - { - // Scroll up the list. - accessibilityAdaptor->HandleActionScrollUpEvent(); - } - else if( direction == GESTURE_DIRECTION_DOWN ) - { - // Scroll down the list. - accessibilityAdaptor->HandleActionScrollDownEvent(); - } - } - break; - } - - case 3: - { - if( gestureType == GESTURE_TYPE_SINGLE_TAP ) - { - // Read from top item on screen continuously. - accessibilityAdaptor->HandleActionReadFromTopEvent(); - } - else if( gestureType == GESTURE_TYPE_DOUBLE_TAP ) - { - // Read from next item continuously. - accessibilityAdaptor->HandleActionReadFromNextEvent(); - } - break; - } - } - } - - // Callback for to set up Ecore ElDBus for accessibility callbacks. - static void EcoreElDBusInitialisation( void *handle, const Eldbus_Message *message, Eldbus_Pending *pending EINA_UNUSED ) - { - Eldbus_Object *object; - Eldbus_Proxy *manager; - const char *a11yBusAddress = NULL; - EventHandler* handler = static_cast< EventHandler* >( handle ); - - // The string defines the arg-list's respective types. - if( !eldbus_message_arguments_get( message, "s", &a11yBusAddress ) ) - { - DALI_LOG_ERROR( "EcoreElDBusInitialisation: Error getting arguments\n" ); - } - - DALI_LOG_INFO( gImfLogging, Debug::General, "Ecore ElDBus Accessibility address: %s\n", a11yBusAddress ); - - handler->mImpl->mA11yConnection = eldbus_address_connection_get( a11yBusAddress ); - - object = eldbus_object_get( handler->mImpl->mA11yConnection, BUS, PATH ); - manager = eldbus_proxy_get( object, INTERFACE ); - - // Pass the callback data through to the signal handler. - eldbus_proxy_signal_handler_add( manager, SIGNAL, OnEcoreElDBusAccessibilityNotification, handle ); - } -#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" ); - Ecore_X_Event_Selection_Clear* selectionClearEvent( (Ecore_X_Event_Selection_Clear*) event ); - EventHandler* handler( (EventHandler*)data ); - - if ( selectionClearEvent->win == handler->mImpl->mWindow ) - { - if ( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY ) - { - // Request to get the content from Ecore. - ecore_x_selection_secondary_request(selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT); - } - } - 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" ); - - Ecore_X_Event_Selection_Notify* selectionNotifyEvent( (Ecore_X_Event_Selection_Notify*) event ); - EventHandler* handler( (EventHandler*)data ); - - if ( selectionNotifyEvent->win == handler->mImpl->mWindow ) - { - Ecore_X_Selection_Data* selectionData( (Ecore_X_Selection_Data*) selectionNotifyEvent->data ); - if ( selectionData->data ) - { - if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_XDND ) - { - DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector ); - - // We have got the content that is to be dropped, inform the DndListener (if we have one). - if ( dndDetector ) - { - std::string content( (char*) selectionData->data, selectionData->length ); - dndDetector->SetContent( content ); - - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" ); - } - } - else if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY ) - { - // We have got the selected content, inform the clipboard event listener (if we have one). - if ( handler->mClipboardEventNotifier ) - { - ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) ); - std::string content( (char*) selectionData->data, selectionData->length ); - clipboardEventNotifier.SetContent( content ); - clipboardEventNotifier.EmitContentSelectedSignal(); - } - - // Claim the ownership of the SECONDARY selection. - ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1); - - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data ); - DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" ); - } - } - } - return ECORE_CALLBACK_PASS_ON; - } - - -#ifndef DALI_PROFILE_UBUNTU - ///////////////////////////////////////////////////////////////////////////////////////////////// - // 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 ) - { - DALI_LOG_INFO(gTouchEventLogFilter, Debug::Verbose, "VconfNotifyFontSizeChanged\n" ); - EventHandler* handler = static_cast( data ); - handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE ); - } -#endif // DALI_PROFILE_UBUNTU - - // Data - EventHandler* mHandler; - std::vector mEcoreEventHandler; - Ecore_X_Window mWindow; - int mXiDeviceId; - -#ifdef DALI_ELDBUS_AVAILABLE - Eldbus_Connection* mSessionConnection; - Eldbus_Connection* mA11yConnection; -#endif -}; - -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_X_Window window = 0; - - // this code only works with the WindowRenderSurface so need to downcast - WindowRenderSurfaceEcoreX* ecoreSurface = static_cast< WindowRenderSurfaceEcoreX* >( surface ); - if( ecoreSurface ) - { - // enable multi touch - window = ecoreSurface->GetXWindow(); - } - - mImpl = new Impl(this, window); -} - -EventHandler::~EventHandler() -{ - delete mImpl; - - mGestureManager.Stop(); -} - -void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp) -{ - if(timeStamp < 1) - { - timeStamp = GetCurrentMilliSeconds(); - } - - 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 ); - } - } - - // Send to KeyEvent 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 ) - { - mRotationObserver->OnRotationPrepare( event ); - } -} - -void EventHandler::SendRotationRequestEvent( ) -{ - if( mRotationObserver != NULL ) - { - mRotationObserver->OnRotationRequest( ); - } -} - -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/ubuntu-x11/pixmap-render-surface-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp index ce91867..d9eabf3 100644 --- a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp +++ b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.cpp @@ -52,12 +52,8 @@ static const int INITIAL_PRODUCE_BUFFER_INDEX = 0; static const int INITIAL_CONSUME_BUFFER_INDEX = 1; } -PixmapRenderSurfaceEcoreX::PixmapRenderSurfaceEcoreX(Dali::PositionSize positionSize, - Any surface, - const std::string& name, - bool isTransparent) +PixmapRenderSurfaceEcoreX::PixmapRenderSurfaceEcoreX( Dali::PositionSize positionSize, Any surface, bool isTransparent ) : mPosition( positionSize ), - mTitle( name ), mRenderNotification( NULL ), mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), mOwnSurface( false ), diff --git a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h index d52e793..2cb3927 100644 --- a/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h +++ b/dali/internal/window-system/ubuntu-x11/pixmap-render-surface-ecore-x.h @@ -47,13 +47,9 @@ public: * Uses an X11 surface to render to. * @param [in] positionSize the position and size of the surface * @param [in] surface can be a X-window or X-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 */ - PixmapRenderSurfaceEcoreX( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - bool isTransparent = false); + PixmapRenderSurfaceEcoreX( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ); /** * @brief Destructor @@ -180,7 +176,6 @@ private: // Data static const int BUFFER_COUNT = 2; PositionSize mPosition; ///< Position - std::string mTitle; ///< Title of window which shows from "xinfo -topvwins" command TriggerEventInterface* mRenderNotification; ///< Render notification trigger ColorDepth mColorDepth; ///< Color depth of surface (32 bit or 24 bit) bool mOwnSurface; ///< Whether we own the surface (responsible for deleting it) diff --git a/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.cpp index 1740552..95a619d 100644 --- a/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.cpp +++ b/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.cpp @@ -19,11 +19,14 @@ #include // INTERNAL HEADERS -#include +#include #include #include #include +// EXTERNAL INCLUDES +#include + namespace Dali { namespace Internal @@ -31,22 +34,17 @@ namespace Internal namespace Adaptor { -std::unique_ptr< WindowRenderSurface > RenderSurfaceFactoryEcoreX::CreateWindowRenderSurface( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - const std::string& className, - bool isTransparent ) +std::unique_ptr< WindowRenderSurface > RenderSurfaceFactoryEcoreX::CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { - return Utils::MakeUnique< WindowRenderSurfaceEcoreX >( positionSize, surface, name, className, isTransparent ); + return Utils::MakeUnique< WindowRenderSurface >( positionSize, surface, isTransparent ); } -std::unique_ptr< PixmapRenderSurface > RenderSurfaceFactoryEcoreX::CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, - const std::string& name, bool isTransparent ) +std::unique_ptr< PixmapRenderSurface > RenderSurfaceFactoryEcoreX::CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { - return Utils::MakeUnique< PixmapRenderSurfaceEcoreX >( positionSize, surface, name, isTransparent ); + return Utils::MakeUnique< PixmapRenderSurfaceEcoreX >( positionSize, surface, isTransparent ); } -std::unique_ptr< NativeRenderSurface > RenderSurfaceFactoryEcoreX::CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent ) +std::unique_ptr< NativeRenderSurface > RenderSurfaceFactoryEcoreX::CreateNativeRenderSurface( Dali::PositionSize positionSize, bool isTransparent ) { return std::unique_ptr< NativeRenderSurface >( nullptr ); } diff --git a/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.h b/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.h index 5ba5e70..47086a6 100644 --- a/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.h +++ b/dali/internal/window-system/ubuntu-x11/render-surface-factory-ecore-x.h @@ -30,13 +30,11 @@ namespace Adaptor class RenderSurfaceFactoryEcoreX : 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< WindowRenderSurface > CreateWindowRenderSurface( Dali::PositionSize positionSize, Any surface, 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< PixmapRenderSurface > CreatePixmapRenderSurface( Dali::PositionSize positionSize, Any surface, bool isTransparent = false ) override; - std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, const std::string& name, bool isTransparent = false ) override; + std::unique_ptr< NativeRenderSurface > CreateNativeRenderSurface( Dali::PositionSize positionSize, bool isTransparent = false ) override; }; } // namespace Adaptor diff --git a/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp index 1352668..5f92464 100644 --- a/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp +++ b/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.cpp @@ -24,11 +24,13 @@ // INTERNAL HEADERS #include -#include +#include +#include // EXTERNAL_HEADERS #include #include +#include namespace Dali { @@ -42,10 +44,20 @@ namespace Adaptor namespace { +const std::string DEFAULT_DEVICE_NAME = ""; +const Device::Class::Type DEFAULT_DEVICE_CLASS = Device::Class::NONE; +const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE; + +const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 ); + #if defined(DEBUG_ENABLED) Debug::Filter* gWindowBaseLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW_BASE" ); #endif +///////////////////////////////////////////////////////////////////////////////////////////////// +// Window Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event ) { WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); @@ -57,7 +69,9 @@ static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* ev return ECORE_CALLBACK_PASS_ON; } -/// Called when the window receives a delete request +/** + * Called when the window receives a delete request + */ static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* event ) { WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); @@ -68,16 +82,176 @@ static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* even return ECORE_CALLBACK_DONE; } +/** + * Called when the window gains focus. + */ +static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + 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 ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnFocusOut( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when the window is damaged. + */ +static Eina_Bool EcoreEventWindowDamaged( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnWindowDamaged( data, type, event ); + } + + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Selection Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when the source window notifies us the content in clipboard is selected. + */ +static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnSelectionClear( data, type, event ); + } + 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 ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnSelectionNotify( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Touch Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a touch down is received. + */ +static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonDown( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a touch up is received. + */ +static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonUp( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a touch motion is received. + */ +static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnMouseButtonMove( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Wheel Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a mouse wheel is received. + */ +static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnMouseWheel( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Key Callbacks +///////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Called when a key down is received. + */ +static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnKeyDown( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + +/** + * Called when a key up is received. + */ +static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event ) +{ + WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data ); + if( windowBase ) + { + windowBase->OnKeyUp( data, type, event ); + } + return ECORE_CALLBACK_PASS_ON; +} + } // unnamed namespace -WindowBaseEcoreX::WindowBaseEcoreX( Window* window, WindowRenderSurface* windowRenderSurface ) +WindowBaseEcoreX::WindowBaseEcoreX( Dali::PositionSize positionSize, Any surface, bool isTransparent ) : mEcoreEventHandler(), - mWindow( window ), - mWindowSurface( NULL ), mEcoreWindow( 0 ), + mOwnSurface( false ), mRotationAppSet( false ) { - mWindowSurface = dynamic_cast< WindowRenderSurfaceEcoreX* >( windowRenderSurface ); + Initialize( positionSize, surface, isTransparent ); } WindowBaseEcoreX::~WindowBaseEcoreX() @@ -87,25 +261,84 @@ WindowBaseEcoreX::~WindowBaseEcoreX() ecore_event_handler_del( *iter ); } mEcoreEventHandler.Clear(); + + if( mOwnSurface ) + { + ecore_x_window_free( mEcoreWindow ); + } } -void WindowBaseEcoreX::Initialize() +void WindowBaseEcoreX::Initialize( PositionSize positionSize, Any surface, bool isTransparent ) { - if( !mWindowSurface ) + // 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 + mOwnSurface = true; + CreateWindow( positionSize, isTransparent ); + } + else { - DALI_ASSERT_ALWAYS( "Invalid window surface" ); + // XLib should already be initialized so no point in calling XInitThreads + mEcoreWindow = static_cast< Ecore_X_Window >( surfaceId ); } - mEcoreWindow = mWindowSurface->GetXWindow(); - DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no EcoreX window" ); + // set up etc properties to match with ecore-evas + char *id = NULL; + if( ( id = getenv("DESKTOP_STARTUP_ID") ) ) + { + ecore_x_netwm_startup_id_set( mEcoreWindow, id ); + } + + ecore_x_icccm_hints_set( mEcoreWindow, + 1, // accepts_focus + ECORE_X_WINDOW_STATE_HINT_NORMAL, // initial_state + 0, // icon_pixmap + 0, // icon_mask + 0, // icon_window + 0, // window_group + 0 ); // is_urgent + + // we SHOULD guarantee the x11 window was created in x server. + ecore_x_sync(); ecore_x_input_multi_select( mEcoreWindow ); // This ensures that we catch the window close (or delete) request ecore_x_icccm_protocol_set( mEcoreWindow, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY, EcoreEventWindowPropertyChanged, this ) ); - mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest, this ) ); + // Enable Drag & Drop + ecore_x_dnd_aware_set( mEcoreWindow, EINA_TRUE ); + + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY, EcoreEventWindowPropertyChanged, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest, this ) ); + + // Register window focus events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN, EcoreEventWindowFocusIn, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut, this ) ); + + // Register Window damage events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE, EcoreEventWindowDamaged, this ) ); + + // Register Touch events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN, EcoreEventMouseButtonDown, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP, EcoreEventMouseButtonUp, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE, EcoreEventMouseButtonMove, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT, EcoreEventMouseButtonUp, this ) ); // process mouse out event like up event + + // Register Mouse wheel events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL, EcoreEventMouseWheel, this ) ); + + // Register Key events + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN, EcoreEventKeyDown, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_UP, EcoreEventKeyUp, this ) ); + + // Register Selection event + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, this ) ); + mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, this ) ); } Eina_Bool WindowBaseEcoreX::OnWindowPropertyChanged( void* data, int type, void* event ) @@ -122,24 +355,21 @@ Eina_Bool WindowBaseEcoreX::OnWindowPropertyChanged( void* data, int type, void* case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN: { // Window was hidden. - mWindow->OnIconifyChanged( true ); - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%d) Withdrawn\n", mWindow ); + mIconifyChangedSignal.Emit( true ); handled = ECORE_CALLBACK_DONE; break; } case ECORE_X_WINDOW_STATE_HINT_ICONIC: { // Window was iconified (minimised). - mWindow->OnIconifyChanged( true ); - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%d) Iconfied\n", mWindow ); + mIconifyChangedSignal.Emit( true ); handled = ECORE_CALLBACK_DONE; break; } case ECORE_X_WINDOW_STATE_HINT_NORMAL: { // Window was shown. - mWindow->OnIconifyChanged( false ); - DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window (%d) Shown\n", mWindow ); + mIconifyChangedSignal.Emit( false ); handled = ECORE_CALLBACK_DONE; break; } @@ -156,7 +386,285 @@ Eina_Bool WindowBaseEcoreX::OnWindowPropertyChanged( void* data, int type, void* void WindowBaseEcoreX::OnDeleteRequest() { - mWindow->OnDeleteRequest(); + mDeleteRequestSignal.Emit(); +} + +void WindowBaseEcoreX::OnFocusIn( void* data, int type, void* event ) +{ + Ecore_X_Event_Window_Focus_In* focusInEvent = static_cast< Ecore_X_Event_Window_Focus_In* >( event ); + + if( focusInEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" ); + + mFocusChangedSignal.Emit( true ); + } +} + +void WindowBaseEcoreX::OnFocusOut( void* data, int type, void* event ) +{ + Ecore_X_Event_Window_Focus_Out* focusOutEvent = static_cast< Ecore_X_Event_Window_Focus_Out* >( event ); + + // If the window loses focus then hide the keyboard. + if( focusOutEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" ); + + mFocusChangedSignal.Emit( false ); + } +} + +void WindowBaseEcoreX::OnWindowDamaged( void* data, int type, void* event ) +{ + Ecore_X_Event_Window_Damage* windowDamagedEvent = static_cast< Ecore_X_Event_Window_Damage* >( event ); + + if( windowDamagedEvent->win == mEcoreWindow ) + { + DamageArea area; + area.x = windowDamagedEvent->x; + area.y = windowDamagedEvent->y; + area.width = windowDamagedEvent->w; + area.height = windowDamagedEvent->h; + + mWindowDamagedSignal.Emit( area ); + } +} + +void WindowBaseEcoreX::OnMouseButtonDown( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event ); + + if( touchEvent->window == mEcoreWindow ) + { + 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; + } + + 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 ) ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } +} + +void WindowBaseEcoreX::OnMouseButtonUp( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event ); + + if( touchEvent->window == mEcoreWindow ) + { + 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 ) ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } +} + +void WindowBaseEcoreX::OnMouseButtonMove( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Move* touchEvent = static_cast< Ecore_Event_Mouse_Move* >( event ); + + if( touchEvent->window == mEcoreWindow ) + { + 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 ) ); + + mTouchEventSignal.Emit( point, touchEvent->timestamp ); + } +} + +void WindowBaseEcoreX::OnMouseWheel( void* data, int type, void* event ) +{ + Ecore_Event_Mouse_Wheel* mouseWheelEvent = static_cast< Ecore_Event_Mouse_Wheel* >( event ); + + if( mouseWheelEvent->window == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreX::OnMouseWheel: direction: %d, modifiers: %d, x: %d, y: %d, z: %d\n", mouseWheelEvent->direction, mouseWheelEvent->modifiers, mouseWheelEvent->x, mouseWheelEvent->y, mouseWheelEvent->z ); + + WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2( mouseWheelEvent->x, mouseWheelEvent->y ), mouseWheelEvent->z, mouseWheelEvent->timestamp ); + + mWheelEventSignal.Emit( wheelEvent ); + } +} + +void WindowBaseEcoreX::OnKeyDown( void* data, int type, void* event ) +{ + Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event ); + + if( keyEvent->window == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreX::OnKeyDown\n" ); + + 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 = ecore_x_keysym_keycode_get( keyEvent->keyname ); + int modifier( keyEvent->modifiers ); + unsigned long time = keyEvent->timestamp; + + // Ensure key event string is not NULL as keys like SHIFT have a null string. + if( keyEvent->string ) + { + keyString = keyEvent->string; + } + + Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS ); + + mKeyEventSignal.Emit( keyEvent ); + } +} + +void WindowBaseEcoreX::OnKeyUp( void* data, int type, void* event ) +{ + Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event ); + + if ( keyEvent->window == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, " WindowBaseEcoreX::OnKeyUp\n" ); + + 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 = ecore_x_keysym_keycode_get( keyEvent->keyname ); + int modifier( keyEvent->modifiers ); + unsigned long time( keyEvent->timestamp ); + + // Ensure key event string is not NULL as keys like SHIFT have a null string. + if( keyEvent->string ) + { + keyString = keyEvent->string; + } + + Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS ); + + mKeyEventSignal.Emit( keyEvent ); + } +} + +void WindowBaseEcoreX::OnSelectionClear( void* data, int type, void* event ) +{ + Ecore_X_Event_Selection_Clear* selectionClearEvent = static_cast< Ecore_X_Event_Selection_Clear* >( event ); + + if( selectionClearEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, " WindowBaseEcoreX::OnSelectionClear\n" ); + + if( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY ) + { + // Request to get the content from Ecore. + ecore_x_selection_secondary_request( selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT ); + } + } +} + +void WindowBaseEcoreX::OnSelectionNotify( void* data, int type, void* event ) +{ + Ecore_X_Event_Selection_Notify* selectionNotifyEvent = static_cast< Ecore_X_Event_Selection_Notify* >( event ); + + if( selectionNotifyEvent->win == mEcoreWindow ) + { + DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, " WindowBaseEcoreX::OnSelectionNotify\n" ); + + Ecore_X_Selection_Data* selectionData = static_cast< Ecore_X_Selection_Data* >( selectionNotifyEvent->data ); + if( selectionData->data ) + { + if( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY ) + { + mSelectionDataReceivedSignal.Emit( event ); + } + } + } +} + +Any WindowBaseEcoreX::GetNativeWindow() +{ + return mEcoreWindow; +} + +int WindowBaseEcoreX::GetNativeWindowId() +{ + return mEcoreWindow; +} + +EGLNativeWindowType WindowBaseEcoreX::CreateEglWindow( int width, int height ) +{ + // need to create X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit + XWindow window( mEcoreWindow ); + return reinterpret_cast< EGLNativeWindowType >( window ); +} + +void WindowBaseEcoreX::DestroyEglWindow() +{ +} + +void WindowBaseEcoreX::SetEglWindowRotation( int angle ) +{ +} + +void WindowBaseEcoreX::SetEglWindowBufferTransform( int angle ) +{ +} + +void WindowBaseEcoreX::SetEglWindowTransform( int angle ) +{ +} + +void WindowBaseEcoreX::ResizeEglWindow( PositionSize positionSize ) +{ +} + +bool WindowBaseEcoreX::IsEglWindowRotationSupported() +{ + return false; +} + +void WindowBaseEcoreX::Move( PositionSize positionSize ) +{ + ecore_x_window_move( mEcoreWindow, positionSize.x, positionSize.y ); +} + +void WindowBaseEcoreX::Resize( PositionSize positionSize ) +{ + ecore_x_window_resize( mEcoreWindow, positionSize.width, positionSize.height ); +} + +void WindowBaseEcoreX::MoveResize( PositionSize positionSize ) +{ + ecore_x_window_move_resize( mEcoreWindow, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); } void WindowBaseEcoreX::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode, Dali::Window::IndicatorBgOpacity opacityMode ) @@ -174,12 +682,6 @@ void WindowBaseEcoreX::ShowIndicator( Dali::Window::IndicatorVisibleMode visible { ecore_x_e_illume_indicator_opacity_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT ); } -#if defined (DALI_PROFILE_MOBILE) - else if( opacityMode == Dali::Window::TRANSPARENT ) - { - ecore_x_e_illume_indicator_opacity_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_OPAQUE ); - } -#endif } else { @@ -208,8 +710,10 @@ void WindowBaseEcoreX::IndicatorTypeChanged( IndicatorInterface::Type type ) { } -void WindowBaseEcoreX::SetClass( std::string name, std::string className ) +void WindowBaseEcoreX::SetClass( const std::string& name, const std::string& className ) { + ecore_x_icccm_title_set( mEcoreWindow, name.c_str() ); + ecore_x_netwm_name_set( mEcoreWindow, name.c_str() ); ecore_x_icccm_name_class_set( mEcoreWindow, name.c_str(), className.c_str() ); } @@ -347,6 +851,88 @@ bool WindowBaseEcoreX::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali return false; } +void WindowBaseEcoreX::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) +{ + // calculate DPI + float xres, yres; + + // 1 inch = 25.4 millimeters + xres = ecore_x_dpi_get(); + yres = ecore_x_dpi_get(); + + dpiHorizontal = int( xres + 0.5f ); // rounding + dpiVertical = int( yres + 0.5f ); +} + +void WindowBaseEcoreX::SetViewMode( ViewMode viewMode ) +{ + Ecore_X_Atom viewModeAtom( ecore_x_atom_get( "_E_COMP_3D_APP_WIN" ) ); + + if( viewModeAtom != None ) + { + unsigned int value( static_cast< unsigned int >( viewMode ) ); + ecore_x_window_prop_card32_set( mEcoreWindow, viewModeAtom, &value, 1 ); + } +} + +int WindowBaseEcoreX::GetScreenRotationAngle() +{ + return 0; +} + +void WindowBaseEcoreX::SetWindowRotationAngle( int degree ) +{ +} + +void WindowBaseEcoreX::WindowRotationCompleted( int degree, int width, int height ) +{ +} + +void WindowBaseEcoreX::SetTransparency( bool transparent ) +{ +} + +unsigned int WindowBaseEcoreX::GetSurfaceId( Any surface ) const +{ + unsigned int surfaceId = 0; + + if ( surface.Empty() == false ) + { + // check we have a valid type + DALI_ASSERT_ALWAYS( ( (surface.GetType() == typeid (XWindow) ) || (surface.GetType() == typeid (Ecore_X_Window) ) ) + && "Surface type is invalid" ); + + if ( surface.GetType() == typeid (Ecore_X_Window) ) + { + surfaceId = AnyCast< Ecore_X_Window >( surface ); + } + else + { + surfaceId = AnyCast< XWindow >( surface ); + } + } + return surfaceId; +} + +void WindowBaseEcoreX::CreateWindow( PositionSize positionSize, bool isTransparent ) +{ + if( isTransparent ) + { + // create 32 bit window + mEcoreWindow = ecore_x_window_argb_new( 0, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); + } + else + { + // create 24 bit window + mEcoreWindow = ecore_x_window_new( 0, positionSize.x, positionSize.y, positionSize.width, positionSize.height ); + } + + if ( mEcoreWindow == 0 ) + { + DALI_ASSERT_ALWAYS( 0 && "Failed to create X window" ); + } +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h b/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h index 6255279..2873bbc 100644 --- a/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h +++ b/dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h @@ -32,10 +32,6 @@ namespace Internal namespace Adaptor { -class Window; -class WindowRenderSurface; -class WindowRenderSurfaceEcoreX; - /** * WindowBaseEcoreX class provides an WindowBase EcoreX implementation. */ @@ -46,7 +42,7 @@ public: /** * @brief Constructor */ - WindowBaseEcoreX( Window* window, WindowRenderSurface* windowRenderSurface ); + WindowBaseEcoreX( PositionSize positionSize, Any surface, bool isTransparent ); /** * @brief Destructor @@ -61,16 +57,126 @@ public: Eina_Bool OnWindowPropertyChanged( void* data, int type, void* event ); /** - * Called when the window receives a delete request + * @brief Called when the window receives a delete request */ void OnDeleteRequest(); + /** + * @brief Called when the window gains focus. + */ + void OnFocusIn( void* data, int type, void* event ); + + /** + * @brief Called when the window loses focus. + */ + void OnFocusOut( void* data, int type, void* event ); + + /** + * @brief Called when the window is damaged. + */ + void OnWindowDamaged( void* data, int type, void* event ); + + /** + * @brief Called when a touch down is received. + */ + void OnMouseButtonDown( void* data, int type, void* event ); + + /** + * @brief Called when a touch up is received. + */ + void OnMouseButtonUp( void* data, int type, void* event ); + + /** + * @brief Called when a touch motion is received. + */ + void OnMouseButtonMove( void* data, int type, void* event ); + + /** + * @brief Called when a mouse wheel is received. + */ + void OnMouseWheel( void* data, int type, void* event ); + + /** + * @brief Called when a key down is received. + */ + void OnKeyDown( void* data, int type, void* event ); + + /** + * @brief Called when a key up is received. + */ + void OnKeyUp( void* data, int type, void* event ); + + /** + * @brief Called when the source window notifies us the content in clipboard is selected. + */ + void OnSelectionClear( void* data, int type, void* event ); + + /** + * @brief Called when the source window sends us about the selected content. + */ + void OnSelectionNotify( void* data, int type, void* event ); + public: /** - * @copydoc Dali::Internal::Adaptor::WindowBase::Initialize() + * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeWindow() + */ + virtual Any GetNativeWindow() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetNativeWindowId() + */ + virtual int GetNativeWindowId() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::CreateEglWindow() + */ + virtual EGLNativeWindowType CreateEglWindow( int width, int height ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::DestroyEglWindow() + */ + virtual void DestroyEglWindow() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowRotation() + */ + virtual void SetEglWindowRotation( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowBufferTransform() */ - virtual void Initialize() override; + virtual void SetEglWindowBufferTransform( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetEglWindowTransform() + */ + virtual void SetEglWindowTransform( int angle ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::ResizeEglWindow() + */ + virtual void ResizeEglWindow( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::IsEglWindowRotationSupported() + */ + virtual bool IsEglWindowRotationSupported() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Move() + */ + virtual void Move( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::Resize() + */ + virtual void Resize( PositionSize positionSize ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::MoveResize() + */ + virtual void MoveResize( PositionSize positionSize ) override; /** * @copydoc Dali::Internal::Adaptor::WindowBase::ShowIndicator() @@ -90,7 +196,7 @@ public: /** * @copydoc Dali::Internal::Adaptor::WindowBase::SetClass() */ - virtual void SetClass( std::string name, std::string className ) override; + virtual void SetClass( const std::string& name, const std::string& className ) override; /** * @copydoc Dali::Internal::Adaptor::WindowBase::Raise() @@ -232,6 +338,55 @@ public: */ virtual bool UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result ) override; + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetDpi() + */ + virtual void GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetViewMode() + */ + virtual void SetViewMode( ViewMode viewMode ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::GetScreenRotationAngle() + */ + virtual int GetScreenRotationAngle() override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetWindowRotationAngle() + */ + virtual void SetWindowRotationAngle( int degree ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::WindowRotationCompleted() + */ + virtual void WindowRotationCompleted( int degree, int width, int height ) override; + + /** + * @copydoc Dali::Internal::Adaptor::WindowBase::SetTransparency() + */ + virtual void SetTransparency( bool transparent ) override; + +private: + + /** + * Second stage initialization + */ + void Initialize( PositionSize positionSize, Any surface, bool isTransparent ); + + /** + * @brief 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; + + /** + * @brief Create window + */ + void CreateWindow( PositionSize positionSize, bool isTransparent ); + protected: // Undefined @@ -243,11 +398,9 @@ protected: private: Dali::Vector< Ecore_Event_Handler* > mEcoreEventHandler; - - Window* mWindow; - WindowRenderSurfaceEcoreX* mWindowSurface; - Ecore_X_Window mEcoreWindow; - + Ecore_X_Window mEcoreWindow; ///< Native window handle + bool mOwnSurface:1; ///< Whether we own the surface (responsible for deleting it) + bool mIsTransparent; ///< Whether the window is transparent (32 bit or 24 bit) bool mRotationAppSet:1; }; diff --git a/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.cpp index 2a9d086..bfb34f9 100644 --- a/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.cpp +++ b/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.cpp @@ -29,9 +29,9 @@ namespace Internal namespace Adaptor { -std::unique_ptr< WindowBase > WindowFactoryEcoreX::CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) +std::unique_ptr< WindowBase > WindowFactoryEcoreX::CreateWindowBase( Dali::PositionSize positionSize, Any surface, bool isTransparent ) { - return Utils::MakeUnique< WindowBaseEcoreX >( window, windowRenderSurface ); + return Utils::MakeUnique< WindowBaseEcoreX >( positionSize, surface, isTransparent ); } std::unique_ptr< IndicatorInterface > WindowFactoryEcoreX::CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) diff --git a/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.h b/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.h index 744668e..5af7c20 100644 --- a/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.h +++ b/dali/internal/window-system/ubuntu-x11/window-factory-ecore-x.h @@ -30,7 +30,7 @@ namespace Adaptor class WindowFactoryEcoreX : public WindowFactory { public: - std::unique_ptr< WindowBase > CreateWindowBase( Window* window, WindowRenderSurface* windowRenderSurface ) override; + std::unique_ptr< WindowBase > CreateWindowBase( Dali::PositionSize positionSize, Any surface, bool isTransparent ) override; std::unique_ptr< IndicatorInterface > CreateIndicator( Adaptor* adaptor, Dali::Window::WindowOrientation orientation, IndicatorInterface::Observer* observer ) override; }; diff --git a/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.cpp deleted file mode 100644 index f050c2b..0000000 --- a/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* - * 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 -#include - -#include // for damage notify -#include // for damage notify - -#include -#include - -// INTERNAL INCLUDES -#include -#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_X"); -#endif - -} // unnamed namespace - -WindowRenderSurfaceEcoreX::WindowRenderSurfaceEcoreX( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - const std::string& className, - bool isTransparent) -: mTitle( name ), - mClassName( className ), - mPosition( positionSize ), - mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), - mX11Window( 0 ), - mOwnSurface( false ), - mNeedToApproveDeiconify( false ) -{ - DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "Creating Window\n" ); - Initialize( surface ); -} - -WindowRenderSurfaceEcoreX::~WindowRenderSurfaceEcoreX() -{ - if( mOwnSurface ) - { - ecore_x_window_free( mX11Window ); - } -} - -void WindowRenderSurfaceEcoreX::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 - mOwnSurface = true; - CreateRenderable(); - } - else - { - // XLib should already be initialized so no point in calling XInitThreads - UseExistingRenderable( surfaceId ); - } -} - -Ecore_X_Window WindowRenderSurfaceEcoreX::GetXWindow() -{ - return mX11Window; -} - -void WindowRenderSurfaceEcoreX::RequestToApproveDeiconify() -{ - mNeedToApproveDeiconify = true; -} - -Any WindowRenderSurfaceEcoreX::GetWindow() -{ - return mX11Window; -} - -void WindowRenderSurfaceEcoreX::Map() -{ - ecore_x_window_show( mX11Window ); -} - -void WindowRenderSurfaceEcoreX::SetRenderNotification( TriggerEventInterface* renderNotification ) -{ -} - -void WindowRenderSurfaceEcoreX::SetTransparency( bool transparent ) -{ -} - -void WindowRenderSurfaceEcoreX::RequestRotation( int angle, int width, int height ) -{ -} - -PositionSize WindowRenderSurfaceEcoreX::GetPositionSize() const -{ - return mPosition; -} - -void WindowRenderSurfaceEcoreX::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical ) -{ - // calculate DPI - float xres, yres; - - // 1 inch = 25.4 millimeters - xres = ecore_x_dpi_get(); - yres = ecore_x_dpi_get(); - - dpiHorizontal = int( xres + 0.5f ); // rounding - dpiVertical = int( yres + 0.5f ); -} - -void WindowRenderSurfaceEcoreX::InitializeEgl( EglInterface& eglIf ) -{ - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); - - Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); - - eglImpl.ChooseConfig(true, mColorDepth); -} - -void WindowRenderSurfaceEcoreX::CreateEglSurface( EglInterface& eglIf ) -{ - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); - - Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); - - // create the EGL surface - // need to create X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit - XWindow window( mX11Window ); - eglImpl.CreateSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( window ), mColorDepth ); -} - -void WindowRenderSurfaceEcoreX::DestroyEglSurface( EglInterface& eglIf ) -{ - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); - - Internal::Adaptor::EglImplementation& eglImpl = static_cast( eglIf ); - eglImpl.DestroySurface(); -} - -bool WindowRenderSurfaceEcoreX::ReplaceEGLSurface( EglInterface& egl ) -{ - DALI_LOG_TRACE_METHOD( gWindowRenderSurfaceLogFilter ); - - // need to create X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit - XWindow window( mX11Window ); - Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); - - return eglImpl.ReplaceSurfaceWindow( reinterpret_cast< EGLNativeWindowType >( window ) ); -} - -void WindowRenderSurfaceEcoreX::MoveResize( Dali::PositionSize positionSize ) -{ - bool needToMove = false; - bool needToResize = false; - - // check moving - if( (fabs(positionSize.x - mPosition.x) > MINIMUM_DIMENSION_CHANGE) || - (fabs(positionSize.y - mPosition.y) > MINIMUM_DIMENSION_CHANGE) ) - { - needToMove = true; - } - - // check resizing - if( (fabs(positionSize.width - mPosition.width) > MINIMUM_DIMENSION_CHANGE) || - (fabs(positionSize.height - mPosition.height) > MINIMUM_DIMENSION_CHANGE) ) - { - needToResize = true; - } - - if( needToMove && needToResize) - { - ecore_x_window_move_resize(mX11Window, positionSize.x, positionSize.y, positionSize.width, positionSize.height); - mPosition = positionSize; - } - else if(needToMove) - { - ecore_x_window_move(mX11Window, positionSize.x, positionSize.y); - mPosition = positionSize; - } - else if (needToResize) - { - ecore_x_window_resize(mX11Window, positionSize.width, positionSize.height); - mPosition = positionSize; - } -} - -void WindowRenderSurfaceEcoreX::SetViewMode( ViewMode viewMode ) -{ - Ecore_X_Atom viewModeAtom( ecore_x_atom_get( "_E_COMP_3D_APP_WIN" ) ); - - if( viewModeAtom != None ) - { - unsigned int value( static_cast( viewMode ) ); - ecore_x_window_prop_card32_set( mX11Window, viewModeAtom, &value, 1 ); - } -} - -void WindowRenderSurfaceEcoreX::StartRender() -{ -} - -bool WindowRenderSurfaceEcoreX::PreRender( EglInterface&, Integration::GlAbstraction&, bool ) -{ - // nothing to do for windows - return true; -} - -void WindowRenderSurfaceEcoreX::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, Dali::DisplayConnection* displayConnection, bool replacingSurface, bool resizingSurface ) -{ - Internal::Adaptor::EglImplementation& eglImpl = static_cast( egl ); - eglImpl.SwapBuffers(); - - // When the window is deiconified, it approves the deiconify operation to window manager after rendering - if(mNeedToApproveDeiconify) - { - // SwapBuffer is desychronized. So make sure to sychronize when window is deiconified. - glAbstraction.Finish(); - - XDisplay* display = AnyCast(displayConnection->GetDisplay()); - -#ifndef DALI_PROFILE_UBUNTU - /* client sends immediately reply message using value 1 */ - XEvent xev; - - xev.xclient.window = mX11Window; - xev.xclient.type = ClientMessage; - xev.xclient.message_type = ECORE_X_ATOM_E_DEICONIFY_APPROVE; - xev.xclient.format = 32; - xev.xclient.data.l[0] = mX11Window; - xev.xclient.data.l[1] = 1; - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - XSendEvent(display, mX11Window, false, ECORE_X_EVENT_MASK_WINDOW_CONFIGURE, &xev); -#endif // DALI_PROFILE_UBUNTU - - XSync(display, false); - - mNeedToApproveDeiconify = false; - } -} - -void WindowRenderSurfaceEcoreX::StopRender() -{ -} - -void WindowRenderSurfaceEcoreX::SetThreadSynchronization( ThreadSynchronizationInterface& /* threadSynchronization */ ) -{ - // Nothing to do. -} - -void WindowRenderSurfaceEcoreX::ReleaseLock() -{ - // Nothing to do. -} - -RenderSurface::Type WindowRenderSurfaceEcoreX::GetSurfaceType() -{ - return WINDOW_RENDER_SURFACE; -} - -void WindowRenderSurfaceEcoreX::CreateRenderable() -{ - // if width or height are zero, go full screen. - if ( (mPosition.width == 0) || (mPosition.height == 0) ) - { - // Default window size == screen size - mPosition.x = 0; - mPosition.y = 0; - - ecore_x_screen_size_get( ecore_x_default_screen_get(), &mPosition.width, &mPosition.height ); - } - - if(mColorDepth == COLOR_DEPTH_32) - { - // create 32 bit window - mX11Window = ecore_x_window_argb_new( 0, mPosition.x, mPosition.y, mPosition.width, mPosition.height ); - } - else - { - // create 24 bit window - mX11Window = ecore_x_window_new( 0, mPosition.x, mPosition.y, mPosition.width, mPosition.height ); - } - - if ( mX11Window == 0 ) - { - DALI_ASSERT_ALWAYS(0 && "Failed to create X window"); - } - - // set up window title which will be helpful for debug utitilty - ecore_x_icccm_title_set( mX11Window, mTitle.c_str() ); - ecore_x_netwm_name_set( mX11Window, mTitle.c_str() ); - ecore_x_icccm_name_class_set( mX11Window, mTitle.c_str(), mClassName.c_str() ); - - // set up etc properties to match with ecore-evas - char *id = NULL; - if( ( id = getenv("DESKTOP_STARTUP_ID") ) ) - { - ecore_x_netwm_startup_id_set( mX11Window, id ); - } - - ecore_x_icccm_hints_set( mX11Window, - 1, // accepts_focus - ECORE_X_WINDOW_STATE_HINT_NORMAL, // initial_state - 0, // icon_pixmap - 0, // icon_mask - 0, // icon_window - 0, // window_group - 0 ); // is_urgent - - // we SHOULD guarantee the x11 window was created in x server. - ecore_x_sync(); -} - -void WindowRenderSurfaceEcoreX::UseExistingRenderable( unsigned int surfaceId ) -{ - mX11Window = static_cast< Ecore_X_Window >( surfaceId ); -} - -unsigned int WindowRenderSurfaceEcoreX::GetSurfaceId( Any surface ) const -{ - unsigned int surfaceId = 0; - - if ( surface.Empty() == false ) - { - // check we have a valid type - DALI_ASSERT_ALWAYS( ( (surface.GetType() == typeid (XWindow) ) || - (surface.GetType() == typeid (Ecore_X_Window) ) ) - && "Surface type is invalid" ); - - if ( surface.GetType() == typeid (Ecore_X_Window) ) - { - surfaceId = AnyCast( surface ); - } - else - { - surfaceId = AnyCast( surface ); - } - } - return surfaceId; -} - -} // namespace Adaptor - -} // namespace internal - -} // namespace Dali diff --git a/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.h b/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.h deleted file mode 100644 index cff4b2a..0000000 --- a/dali/internal/window-system/ubuntu-x11/window-render-surface-ecore-x.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef __DALI_INTERNAL_ECORE_X_WINDOW_RENDER_SURFACE_H__ -#define __DALI_INTERNAL_ECORE_X_WINDOW_RENDER_SURFACE_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 -#include -#include - -// EXTERNAL INCLUDES -#include - -namespace Dali -{ -namespace Internal -{ -namespace Adaptor -{ - -/** - * Ecore X11 Window implementation of render surface. - */ -class WindowRenderSurfaceEcoreX : public WindowRenderSurface -{ -public: - - /** - * Uses an X11 surface to render to. - * @param [in] positionSize the position and size of the surface - * @param [in] surface can be a X-window or X-pixmap (type must be unsigned int). - * @param [in] name optional name of surface passed in - * @param [in] className optional class name of the surface passed in - * @param [in] isTransparent if it is true, surface has 32 bit color depth, otherwise, 24 bit - */ - WindowRenderSurfaceEcoreX( Dali::PositionSize positionSize, - Any surface, - const std::string& name, - const std::string& className, - bool isTransparent = false ); - - /** - * @brief Destructor - */ - virtual ~WindowRenderSurfaceEcoreX(); - -public: // API - - /** - * @brief Get window handle - * @return the Ecore X window handle - */ - Ecore_X_Window GetXWindow(); - - /** - * Request to approve deiconify operation - * If it is requested, it will send ECORE_X_ATOM_E_DEICONIFY_APPROVE event to window manager after rendering - */ - void RequestToApproveDeiconify(); - -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; - -private: // Data - - std::string mTitle; ///< Title of window which shows from "xinfo -topvwins" command - std::string mClassName; ///< The class name of the window - PositionSize mPosition; ///< Position - ColorDepth mColorDepth; ///< Color depth of surface (32 bit or 24 bit) - Ecore_X_Window mX11Window; ///< X-Window - bool mOwnSurface; ///< Whether we own the surface (responsible for deleting it) - bool mNeedToApproveDeiconify; ///< Whether need to send ECORE_X_ATOM_E_DEICONIFY_APPROVE event - -}; // class WindowRenderSurfaceEcoreX - -} // namespace Adaptor - -} // namespace internal - -} // namespace Dali - -#endif // __DALI_INTERNAL_ECORE_X_WINDOW_RENDER_SURFACE_H__ diff --git a/dali/internal/window-system/ubuntu-x11/window-system-ecore-x.cpp b/dali/internal/window-system/ubuntu-x11/window-system-ecore-x.cpp new file mode 100644 index 0000000..f38402d --- /dev/null +++ b/dali/internal/window-system/ubuntu-x11/window-system-ecore-x.cpp @@ -0,0 +1,59 @@ +/* + * 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 HEADERS +#include + +// EXTERNAL_HEADERS +#include + +namespace Dali +{ + +namespace Internal +{ + +namespace Adaptor +{ + +namespace WindowSystem +{ + +void Initialize() +{ + ecore_x_init( NULL ); +} + +void Shutdown() +{ + ecore_x_shutdown(); +} + +void GetScreenSize( int& width, int& height ) +{ + ecore_x_screen_size_get( ecore_x_default_screen_get(), &width, &height ); +} + +} // namespace WindowSystem + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali + +#pragma GCC diagnostic pop -- 2.7.4