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/public-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" );
64 mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( PositionSize( 0, 0, static_cast<int>( width ), static_cast<int>( height ) ), isTranslucent ) );
67 void Scene::Initialize( EvasPlugin* evasPlugin, bool isDefaultScene )
69 mAdaptor = evasPlugin->GetAdaptor();
71 DALI_ASSERT_ALWAYS( mAdaptor && "Scene can not be created when the Adaptor is null" );
79 if( evasPlugin->GetState() != EvasPlugin::RUNNING )
81 evasPlugin->PreInitSignal().Connect( this, &Scene::OnPreInitEvasPlugin );
86 Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
87 mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
92 void Scene::Initialize()
94 // Connect callback to be notified when the surface is rendered
95 TriggerEventFactory triggerEventFactory;
97 mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Scene::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
99 NativeRenderSurface* surface = GetNativeRenderSurface();
106 surface->SetRenderNotification( mRenderNotification.get() );
108 if( !mEvasEventHandler )
110 mEvasEventHandler = std::unique_ptr< EvasEventHandler >( new EvasEventHandler( *this ) );
114 void Scene::OnPreInitEvasPlugin()
116 Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
117 mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
124 NativeRenderSurface* surface = GetNativeRenderSurface();
128 // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
129 surface->SetRenderNotification( nullptr );
133 uint32_t Scene::GetLayerCount() const
135 return mScene.GetLayerCount();
138 Layer Scene::GetLayer( uint32_t depth ) const
140 return mScene.GetLayer( depth );
143 Scene::SceneSize Scene::GetSize() const
145 Size size = mScene.GetSize();
147 return Scene::SceneSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
150 Dali::Any Scene::GetNativeHandle() const
152 return mEvasWrapper->GetNativeWindow();
155 NativeRenderSurface* Scene::GetNativeRenderSurface() const
157 return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
160 Evas_Object* Scene::GetAccessEvasObject()
162 return mEvasWrapper->GetAccessibilityTarget();
165 Evas_Object* Scene::GetDaliEvasObject()
167 return mEvasWrapper->GetFocusTarget();
170 void Scene::ResizeSurface( uint16_t width, uint16_t height )
172 if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
177 int intWidth = static_cast<int>( width );
178 int intHeight = static_cast<int>( height );
180 PositionSize currentSize = mSurface->GetPositionSize();
181 if( currentSize.width == intWidth && currentSize.height == intHeight )
186 mSurface->MoveResize( PositionSize( 0, 0, intWidth, intHeight ) );
188 SurfaceResized( true );
190 Adaptor::SurfaceSize newSize( width, height );
192 // When surface size is updated, inform adaptor of resizing and emit ResizedSignal
193 mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
195 mResizedSignal.Emit( Extension::Scene( this ), width, height );
197 mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
200 void Scene::OnPostRender()
202 // Bind offscreen surface to the evas object
203 NativeRenderSurface* surface = GetNativeRenderSurface();
210 tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
217 mEvasWrapper->BindTBMSurface( tbmSurface );
219 mEvasWrapper->RequestRender();
221 surface->ReleaseLock();
224 EvasWrapper* Scene::GetEvasWrapper() const
226 return mEvasWrapper.get();
229 void Scene::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
231 FeedTouchPoint( touchPoint, timeStamp );
234 void Scene::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
236 FeedWheelEvent( wheelEvent );
239 void Scene::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
241 FeedKeyEvent( keyEvent );
244 void Scene::OnEvasObjectMove( const Rect<int>& geometry )
248 void Scene::OnEvasObjectResize( const Rect<int>& geometry )
250 ResizeSurface( static_cast<uint16_t>( geometry.width ), static_cast<uint16_t>( geometry.height ) );
253 void Scene::OnEvasObjectVisiblityChanged( bool visible )
255 if( mVisible == visible )
259 DALI_LOG_RELEASE_INFO( "Scene::OnEvasObjectVisiblityChanged( %s )", visible ? "T" : "F" );
261 SetVisibility( visible );
264 void Scene::OnEvasObjectFocusIn()
268 mFocusChangedSignal.Emit( Extension::Scene( this ), true );
274 void Scene::OnEvasObjectFocusOut()
280 Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
281 Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
284 focusManager.RemoveFocus( currentFocused );
287 Clipboard::Get().HideClipboard();
289 mFocusChangedSignal.Emit( Extension::Scene( this ), false );
293 bool Scene::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
297 if( mAdaptor == nullptr )
302 Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
303 if( accessibilityAdaptor )
305 switch( accessActionInfo.actionBy )
307 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
308 case Dali::Extension::Internal::ACCESS_ACTION_READ:
310 ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
314 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
316 // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
317 ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
320 // when focus moving was failed, clear the focus
321 accessibilityAdaptor.HandleActionClearFocusEvent();
326 case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
328 // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
329 ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
332 // when focus moving was failed, clear the focus
333 accessibilityAdaptor.HandleActionClearFocusEvent();
338 case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
340 ret = accessibilityAdaptor.HandleActionActivateEvent();
344 case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
346 ret = accessibilityAdaptor.HandleActionClearFocusEvent();
350 case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
352 Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
356 int touchType = accessActionInfo.mouseType;
358 TouchPoint::State state( TouchPoint::Down );
362 state = TouchPoint::Down; // mouse down
364 else if( touchType == 1 )
366 state = TouchPoint::Motion; // mouse move
368 else if( touchType == 2 )
370 state = TouchPoint::Up; // mouse up
374 state = TouchPoint::Interrupted; // error
377 // Send touch event to accessibility manager.
378 Evas_Coord rel_x, rel_y, obj_x, obj_y, obj_w, obj_h;
380 evas_object_geometry_get( eo, &obj_x, &obj_y, &obj_w, &obj_h );
382 rel_x = accessActionInfo.x - obj_x;
383 rel_y = accessActionInfo.y - obj_y;
385 TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
387 ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
392 case Dali::Extension::Internal::ACCESS_ACTION_UP:
394 ret = accessibilityAdaptor.HandleActionUpEvent();
398 case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
400 ret = accessibilityAdaptor.HandleActionDownEvent();
404 case Dali::Extension::Internal::ACCESS_ACTION_BACK:
407 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
415 DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
421 void Scene::OnEcoreWl2VisibilityChange( bool visible )
423 DALI_LOG_RELEASE_INFO( "Scene::OnEcoreWl2VisibilityChange( %s )", visible ? "T" : "F" );
425 SetVisibility( visible );
428 void Scene::SetVisibility( bool visible )
430 if( mVisible == visible )
444 mAdaptor->OnWindowShown();
448 mAdaptor->OnWindowHidden();
450 mSurface->ReleaseLock();
453 mVisibilityChangedSignal.Emit( Extension::Scene( this ), mVisible );
456 } // namespace Internal
458 } // namespace Extension