2 * Copyright (c) 2020 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/accessibility-adaptor.h>
21 #include <dali/integration-api/adaptor-framework/adaptor.h>
22 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
23 #include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
24 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <dali-toolkit/devel-api/accessibility-manager/accessibility-manager.h>
28 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
31 #include <dali-extension/internal/evas-plugin/evas-event-handler.h>
32 #include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
33 #include <dali-extension/internal/evas-plugin/evas-wrapper.h>
36 #include <dali-extension/internal/evas-plugin/scene-impl.h>
47 IntrusivePtr< Scene > Scene::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
49 IntrusivePtr< Scene > scene = new Scene( parentEvasObject, width, height, isTranslucent );
53 Scene::Scene( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
54 : mAdaptor( nullptr ),
55 mEvasWrapper( new EvasWrapper( parentEvasObject, width, height, isTranslucent ) ),
57 mRenderNotification(),
59 mIsTranslucent( isTranslucent )
61 DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the scene" );
65 mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( SurfaceSize( width, height ), surface, isTranslucent ) );
68 void Scene::Initialize( EvasPlugin* evasPlugin, bool isDefaultScene )
70 mAdaptor = evasPlugin->GetAdaptor();
72 DALI_ASSERT_ALWAYS( mAdaptor && "Scene can not be created when the Adaptor is null" );
80 if( evasPlugin->GetState() != EvasPlugin::RUNNING )
82 evasPlugin->PreInitSignal().Connect( this, &Scene::OnPreInitEvasPlugin );
87 Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
88 mAdaptor->AddWindow( sceneHolderHandler );
93 void Scene::Initialize()
95 // Connect callback to be notified when the surface is rendered
96 TriggerEventFactory triggerEventFactory;
98 mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Scene::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
100 NativeRenderSurface* surface = GetNativeRenderSurface();
107 surface->SetRenderNotification( mRenderNotification.get() );
109 if( !mEvasEventHandler )
111 mEvasEventHandler = std::unique_ptr< EvasEventHandler >( new EvasEventHandler( *this ) );
115 void Scene::OnPreInitEvasPlugin()
117 Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
118 mAdaptor->AddWindow( sceneHolderHandler );
125 NativeRenderSurface* surface = GetNativeRenderSurface();
129 // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
130 surface->SetRenderNotification( nullptr );
134 uint32_t Scene::GetLayerCount() const
136 return mScene.GetLayerCount();
139 Layer Scene::GetLayer( uint32_t depth ) const
141 return mScene.GetLayer( depth );
144 Scene::SceneSize Scene::GetSize() const
146 Size size = mScene.GetSize();
148 return Scene::SceneSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
151 Dali::Any Scene::GetNativeHandle() const
153 return mEvasWrapper->GetNativeWindow();
156 NativeRenderSurface* Scene::GetNativeRenderSurface() const
158 return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
161 Evas_Object* Scene::GetAccessEvasObject()
163 return mEvasWrapper->GetAccessibilityTarget();
166 Evas_Object* Scene::GetDaliEvasObject()
168 return mEvasWrapper->GetFocusTarget();
171 void Scene::ResizeSurface( uint16_t width, uint16_t height )
173 if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
178 int intWidth = static_cast<int>( width );
179 int intHeight = static_cast<int>( height );
181 PositionSize currentSize = mSurface->GetPositionSize();
182 if( currentSize.width == intWidth && currentSize.height == intHeight )
187 mSurface->MoveResize( PositionSize( 0, 0, intWidth, intHeight ) );
191 Adaptor::SurfaceSize newSize( width, height );
193 // When surface size is updated, inform adaptor of resizing and emit ResizedSignal
194 mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
196 mResizedSignal.Emit( Extension::Scene( this ), width, height );
198 mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
201 void Scene::OnPostRender()
203 // Bind offscreen surface to the evas object
204 NativeRenderSurface* surface = GetNativeRenderSurface();
211 tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
218 mEvasWrapper->BindTBMSurface( tbmSurface );
220 mEvasWrapper->RequestRender();
222 surface->ReleaseLock();
225 EvasWrapper* Scene::GetEvasWrapper() const
227 return mEvasWrapper.get();
230 void Scene::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
232 FeedTouchPoint( touchPoint, timeStamp );
235 void Scene::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
237 FeedWheelEvent( wheelEvent );
240 void Scene::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
242 FeedKeyEvent( keyEvent );
245 void Scene::OnEvasObjectMove( const Rect<int>& geometry )
249 void Scene::OnEvasObjectResize( const Rect<int>& geometry )
251 ResizeSurface( static_cast<uint16_t>( geometry.width ), static_cast<uint16_t>( geometry.height ) );
254 void Scene::OnEvasObjectVisiblityChanged( bool visible )
256 if( mVisible == visible )
260 DALI_LOG_RELEASE_INFO( "Scene::OnEvasObjectVisiblityChanged( %s )", visible ? "T" : "F" );
262 SetVisibility( visible );
265 void Scene::OnEvasObjectFocusIn()
269 mFocusChangedSignal.Emit( Extension::Scene( this ), true );
275 void Scene::OnEvasObjectFocusOut()
281 Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
282 Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
285 focusManager.RemoveFocus( currentFocused );
288 Clipboard::Get().HideClipboard();
290 mFocusChangedSignal.Emit( Extension::Scene( this ), false );
294 bool Scene::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
298 if( mAdaptor == nullptr )
303 Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
304 if( accessibilityAdaptor )
306 switch( accessActionInfo.actionBy )
308 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
309 case Dali::Extension::Internal::ACCESS_ACTION_READ:
311 ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
315 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
317 // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
318 ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
321 // when focus moving was failed, clear the focus
322 accessibilityAdaptor.HandleActionClearFocusEvent();
327 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
329 // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
330 ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
333 // when focus moving was failed, clear the focus
334 accessibilityAdaptor.HandleActionClearFocusEvent();
339 case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
341 ret = accessibilityAdaptor.HandleActionActivateEvent();
345 case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
347 ret = accessibilityAdaptor.HandleActionClearFocusEvent();
351 case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
353 Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
357 int touchType = accessActionInfo.mouseType;
359 PointState::Type state( PointState::DOWN );
363 state = PointState::DOWN; // mouse down
365 else if( touchType == 1 )
367 state = PointState::MOTION; // mouse move
369 else if( touchType == 2 )
371 state = PointState::UP; // mouse up
375 state = PointState::INTERRUPTED; // error
378 // Send touch event to accessibility manager.
379 Evas_Coord rel_x, rel_y, obj_x, obj_y, obj_w, obj_h;
381 evas_object_geometry_get( eo, &obj_x, &obj_y, &obj_w, &obj_h );
383 rel_x = accessActionInfo.x - obj_x;
384 rel_y = accessActionInfo.y - obj_y;
386 TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
388 ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
393 case Dali::Extension::Internal::ACCESS_ACTION_UP:
395 ret = accessibilityAdaptor.HandleActionUpEvent();
399 case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
401 ret = accessibilityAdaptor.HandleActionDownEvent();
405 case Dali::Extension::Internal::ACCESS_ACTION_BACK:
408 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
416 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
422 void Scene::OnEcoreWl2VisibilityChange( bool visible )
424 DALI_LOG_RELEASE_INFO( "Scene::OnEcoreWl2VisibilityChange( %s )", visible ? "T" : "F" );
426 SetVisibility( visible );
429 void Scene::SetVisibility( bool visible )
431 if( mVisible == visible )
445 mAdaptor->OnWindowShown();
449 mAdaptor->OnWindowHidden();
451 mSurface->ReleaseLock();
454 mVisibilityChangedSignal.Emit( Extension::Scene( this ), mVisible );
457 } // namespace Internal
459 } // namespace Extension