2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/devel-api/adaptor-framework/clipboard.h>
20 #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
21 #include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
22 #include <dali/integration-api/adaptor-framework/adaptor.h>
23 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
24 #include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
25 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/common/stage.h>
28 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
29 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
32 #include <dali-extension/internal/evas-plugin/evas-wrapper.h>
33 #include <dali-extension/internal/evas-plugin/evas-event-handler.h>
36 #include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
47 // Initialize static members
49 Adaptor* EvasPlugin::mAdaptor = nullptr;
51 uint32_t EvasPlugin::mEvasPluginCount = 0;
53 SingletonService EvasPlugin::mSingletonService = SingletonService();
56 IntrusivePtr< EvasPlugin > EvasPlugin::New( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent )
58 IntrusivePtr< EvasPlugin > evasPlugin = new EvasPlugin( parentEvasObject, width, height, isTranslucent );
62 EvasPlugin::EvasPlugin( Evas_Object* parentEvasObject, int width, int height, bool isTranslucent )
63 : mEvasWrapper( new EvasWrapper( parentEvasObject, width, height, isTranslucent ) ),
64 mRenderNotification(),
65 mEvasPluginEventHandler(),
68 mIsTranslucent( isTranslucent )
70 DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the evas plugin." );
72 // Increase plugin count.
76 mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( PositionSize( 0, 0, width, height ), isTranslucent ) );
79 void EvasPlugin::Initialize()
81 NativeRenderSurface* surface = static_cast<NativeRenderSurface*>( mSurface.get() );
83 Dali::Integration::SceneHolder sceneHolderHandler = Dali::Extension::EvasPlugin( this );
87 // Create the singleton service
88 mSingletonService = SingletonService::New();
90 // Create an adaptor or add new scene holder to the adaptor
91 mAdaptor = &Adaptor::New( sceneHolderHandler, *surface, Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS );
95 mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
98 // Connect callback to be notified when the surface is rendered
99 TriggerEventFactory triggerEventFactory;
101 mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &EvasPlugin::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
103 surface->SetRenderNotification( mRenderNotification.get() );
106 EvasPlugin::~EvasPlugin()
110 if( !mEvasPluginCount )
114 mSingletonService.UnregisterAll();
118 void EvasPlugin::Run()
120 if( READY == mState )
122 if( !mEvasPluginEventHandler )
124 mEvasPluginEventHandler = std::unique_ptr< EvasPluginEventHandler >( new EvasPluginEventHandler( *this ) );
132 mAdaptor->NotifySceneCreated();
138 void EvasPlugin::Pause()
140 if( mState == RUNNING )
150 void EvasPlugin::Resume()
152 if( mState == SUSPENDED )
156 mResumeSignal.Emit();
162 void EvasPlugin::Stop()
164 if( mState != STOPPED )
170 mTerminateSignal.Emit();
174 Dali::Any EvasPlugin::GetNativeHandle() const
176 return mEvasWrapper->GetNativeWindow();
179 NativeRenderSurface* EvasPlugin::GetNativeRenderSurface() const
181 return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
184 Evas_Object* EvasPlugin::GetAccessEvasObject()
186 return mEvasWrapper->GetAccessibilityTarget();
189 Evas_Object* EvasPlugin::GetDaliEvasObject()
191 return mEvasWrapper->GetFocusTarget();
194 void EvasPlugin::ResizeSurface( int width, int height )
196 if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
201 PositionSize currentSize = mSurface->GetPositionSize();
202 if( currentSize.width == width && currentSize.height == height )
207 mSurface->MoveResize( PositionSize( 0, 0, width, height ) );
209 SurfaceResized( true );
211 Adaptor::SurfaceSize newSize( width, height );
213 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
214 mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
216 mResizeSignal.Emit();
218 mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
221 void EvasPlugin::OnPostRender()
223 // Bind offscreen surface to the evas object
224 NativeRenderSurface* surface = GetNativeRenderSurface();
226 DALI_ASSERT_DEBUG( surface && "Surface is null in EvasPlugin" );
228 tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
235 mEvasWrapper->BindTBMSurface( tbmSurface );
237 mEvasWrapper->RequestRender();
239 surface->ReleaseLock();
242 EvasWrapper* EvasPlugin::GetEvasWrapper() const
244 return mEvasWrapper.get();
247 void EvasPlugin::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
249 FeedTouchPoint( touchPoint, timeStamp );
252 void EvasPlugin::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
254 FeedWheelEvent( wheelEvent );
257 void EvasPlugin::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
259 FeedKeyEvent( keyEvent );
262 void EvasPlugin::OnEvasObjectMove( const Rect<int>& geometry )
266 void EvasPlugin::OnEvasObjectResize( const Rect<int>& geometry )
268 ResizeSurface( geometry.width, geometry.height );
271 void EvasPlugin::OnEvasObjectFocusIn()
275 mFocusedSignal.Emit();
281 void EvasPlugin::OnEvasObjectFocusOut()
287 Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
288 Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
291 focusManager.RemoveFocus( currentFocused );
294 Clipboard::Get().HideClipboard();
296 mUnFocusedSignal.Emit();
300 void EvasPlugin::OnEvasPostRender()
304 bool EvasPlugin::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
308 if( mAdaptor == nullptr )
313 Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
314 if( accessibilityAdaptor )
316 switch( accessActionInfo.actionBy )
318 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
319 case Dali::Extension::Internal::ACCESS_ACTION_READ:
321 ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
325 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
327 // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
328 ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
331 // when focus moving was failed, clear the focus
332 accessibilityAdaptor.HandleActionClearFocusEvent();
337 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
339 // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
340 ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
343 // when focus moving was failed, clear the focus
344 accessibilityAdaptor.HandleActionClearFocusEvent();
349 case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
351 ret = accessibilityAdaptor.HandleActionActivateEvent();
355 case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
357 ret = accessibilityAdaptor.HandleActionClearFocusEvent();
361 case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
363 Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
367 int touchType = accessActionInfo.mouseType;
369 TouchPoint::State state( TouchPoint::Down );
373 state = TouchPoint::Down; // mouse down
375 else if( touchType == 1 )
377 state = TouchPoint::Motion; // mouse move
379 else if( touchType == 2 )
381 state = TouchPoint::Up; // mouse up
385 state = TouchPoint::Interrupted; // error
388 // Send touch event to accessibility manager.
389 Evas_Coord rel_x, rel_y, obj_x, obj_y, obj_w, obj_h;
391 evas_object_geometry_get( eo, &obj_x, &obj_y, &obj_w, &obj_h );
393 rel_x = accessActionInfo.x - obj_x;
394 rel_y = accessActionInfo.y - obj_y;
396 TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
398 ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
403 case Dali::Extension::Internal::ACCESS_ACTION_UP:
405 ret = accessibilityAdaptor.HandleActionUpEvent();
409 case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
411 ret = accessibilityAdaptor.HandleActionDownEvent();
415 case Dali::Extension::Internal::ACCESS_ACTION_BACK:
418 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
426 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
432 void EvasPlugin::OnEcoreWl2VisibilityChange( bool visibility )
434 DALI_LOG_RELEASE_INFO( "EvasPlugin::OnEcoreWl2VisibilityChange( %s )", visibility ? "T" : "F" );
444 mAdaptor->ReleaseSurfaceLock();
448 void EvasPlugin::Show()
454 mAdaptor->OnWindowShown();
458 void EvasPlugin::Hide()
464 mAdaptor->OnWindowHidden();
468 } // namespace Internal
470 } // namespace Extension