Revert "[Tizen] Apply modified interface of SurfaceResized"
[platform/core/uifw/dali-extension.git] / dali-extension / internal / evas-plugin / scene-impl.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // EXTERNAL INCLUDES
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>
29
30 // INTERNAL INCLUDES
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>
34
35 // CLASS HEADER
36 #include <dali-extension/internal/evas-plugin/scene-impl.h>
37
38 namespace Dali
39 {
40
41 namespace Extension
42 {
43
44 namespace Internal
45 {
46
47 IntrusivePtr< Scene > Scene::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
48 {
49   IntrusivePtr< Scene > scene = new Scene( parentEvasObject, width, height, isTranslucent );
50   return scene;
51 }
52
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 ) ),
56   mEvasEventHandler(),
57   mRenderNotification(),
58   mIsFocus( false ),
59   mIsTranslucent( isTranslucent )
60 {
61   DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the scene" );
62
63   // Create surface
64   Any surface;
65   mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( SurfaceSize( width, height ), surface, isTranslucent ) );
66 }
67
68 void Scene::Initialize( EvasPlugin* evasPlugin, bool isDefaultScene )
69 {
70   mAdaptor = evasPlugin->GetAdaptor();
71
72   DALI_ASSERT_ALWAYS( mAdaptor && "Scene can not be created when the Adaptor is null" );
73
74   if( isDefaultScene )
75   {
76     Initialize();
77     return;
78   }
79
80   if( evasPlugin->GetState() != EvasPlugin::RUNNING )
81   {
82     evasPlugin->PreInitSignal().Connect( this, &Scene::OnPreInitEvasPlugin );
83
84     return;
85   }
86
87   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
88   mAdaptor->AddWindow( sceneHolderHandler );
89
90   Initialize();
91 }
92
93 void Scene::Initialize()
94 {
95   // Connect callback to be notified when the surface is rendered
96   TriggerEventFactory triggerEventFactory;
97
98   mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Scene::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
99
100   NativeRenderSurface* surface = GetNativeRenderSurface();
101
102   if( !surface )
103   {
104     return;
105   }
106
107   surface->SetRenderNotification( mRenderNotification.get() );
108
109   if( !mEvasEventHandler )
110   {
111     mEvasEventHandler = std::unique_ptr< EvasEventHandler >( new EvasEventHandler( *this ) );
112   }
113 }
114
115 void Scene::OnPreInitEvasPlugin()
116 {
117   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
118   mAdaptor->AddWindow( sceneHolderHandler );
119
120   Initialize();
121 }
122
123 Scene::~Scene()
124 {
125   NativeRenderSurface* surface = GetNativeRenderSurface();
126
127   if( surface )
128   {
129     // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
130     surface->SetRenderNotification( nullptr );
131   }
132 }
133
134 uint32_t Scene::GetLayerCount() const
135 {
136   return mScene.GetLayerCount();
137 }
138
139 Layer Scene::GetLayer( uint32_t depth ) const
140 {
141   return mScene.GetLayer( depth );
142 }
143
144 Scene::SceneSize Scene::GetSize() const
145 {
146   Size size = mScene.GetSize();
147
148   return Scene::SceneSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
149 }
150
151 Dali::Any Scene::GetNativeHandle() const
152 {
153   return mEvasWrapper->GetNativeWindow();
154 }
155
156 NativeRenderSurface* Scene::GetNativeRenderSurface() const
157 {
158   return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
159 }
160
161 Evas_Object* Scene::GetAccessEvasObject()
162 {
163   return mEvasWrapper->GetAccessibilityTarget();
164 }
165
166 Evas_Object* Scene::GetDaliEvasObject()
167 {
168   return mEvasWrapper->GetFocusTarget();
169 }
170
171 void Scene::ResizeSurface( uint16_t width, uint16_t height )
172 {
173   if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
174   {
175     return;
176   }
177
178   int intWidth = static_cast<int>( width );
179   int intHeight = static_cast<int>( height );
180
181   PositionSize currentSize = mSurface->GetPositionSize();
182   if( currentSize.width == intWidth && currentSize.height == intHeight )
183   {
184     return;
185   }
186
187   mSurface->MoveResize( PositionSize( 0, 0, intWidth, intHeight ) );
188
189   SurfaceResized();
190
191   Adaptor::SurfaceSize newSize( width, height );
192
193   // When surface size is updated, inform adaptor of resizing and emit ResizedSignal
194   mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
195
196   mResizedSignal.Emit( Extension::Scene( this ), width, height );
197
198   mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
199 }
200
201 void Scene::OnPostRender()
202 {
203   // Bind offscreen surface to the evas object
204   NativeRenderSurface* surface = GetNativeRenderSurface();
205
206   if( !surface )
207   {
208     return;
209   }
210
211   tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
212
213   if( !tbmSurface )
214   {
215     return;
216   }
217
218   mEvasWrapper->BindTBMSurface( tbmSurface );
219
220   mEvasWrapper->RequestRender();
221
222   surface->ReleaseLock();
223 }
224
225 EvasWrapper* Scene::GetEvasWrapper() const
226 {
227   return mEvasWrapper.get();
228 }
229
230 void Scene::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
231 {
232   FeedTouchPoint( touchPoint, timeStamp );
233 }
234
235 void Scene::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
236 {
237   FeedWheelEvent( wheelEvent );
238 }
239
240 void Scene::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
241 {
242   FeedKeyEvent( keyEvent );
243 }
244
245 void Scene::OnEvasObjectMove( const Rect<int>& geometry )
246 {
247 }
248
249 void Scene::OnEvasObjectResize( const Rect<int>& geometry )
250 {
251   ResizeSurface( static_cast<uint16_t>( geometry.width ), static_cast<uint16_t>( geometry.height ) );
252 }
253
254 void Scene::OnEvasObjectVisiblityChanged( bool visible )
255 {
256   if( mVisible == visible )
257   {
258     return;
259   }
260   DALI_LOG_RELEASE_INFO( "Scene::OnEvasObjectVisiblityChanged( %s )", visible ? "T" : "F" );
261
262   SetVisibility( visible );
263 }
264
265 void Scene::OnEvasObjectFocusIn()
266 {
267   if( !mIsFocus )
268   {
269     mFocusChangedSignal.Emit( Extension::Scene( this ), true );
270
271     mIsFocus = true;
272   }
273 }
274
275 void Scene::OnEvasObjectFocusOut()
276 {
277   if( mIsFocus )
278   {
279     mIsFocus = false;
280
281     Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
282     Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
283     if( currentFocused )
284     {
285       focusManager.RemoveFocus( currentFocused );
286     }
287
288     Clipboard::Get().HideClipboard();
289
290     mFocusChangedSignal.Emit( Extension::Scene( this ), false );
291   }
292 }
293
294 bool Scene::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
295 {
296   bool ret = false;
297
298   if( mAdaptor == nullptr )
299   {
300     return ret;
301   }
302
303   Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
304   if( accessibilityAdaptor )
305   {
306     switch( accessActionInfo.actionBy )
307     {
308       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
309       case Dali::Extension::Internal::ACCESS_ACTION_READ:
310       {
311         ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
312       }
313       break;
314
315       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
316       {
317         // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
318         ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
319         if(!ret)
320         {
321           // when focus moving was failed, clear the focus
322           accessibilityAdaptor.HandleActionClearFocusEvent();
323         }
324       }
325       break;
326
327       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
328       {
329         // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
330         ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
331         if(!ret)
332         {
333           // when focus moving was failed, clear the focus
334           accessibilityAdaptor.HandleActionClearFocusEvent();
335         }
336       }
337       break;
338
339       case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
340       {
341         ret = accessibilityAdaptor.HandleActionActivateEvent();
342       }
343       break;
344
345       case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
346       {
347         ret = accessibilityAdaptor.HandleActionClearFocusEvent();
348       }
349       break;
350
351       case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
352       {
353         Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
354
355         if( eo )
356         {
357           int touchType = accessActionInfo.mouseType;
358
359           PointState::Type state( PointState::DOWN );
360
361           if( touchType == 0 )
362           {
363             state = PointState::DOWN; // mouse down
364           }
365           else if( touchType == 1 )
366           {
367             state = PointState::MOTION; // mouse move
368           }
369           else if( touchType == 2 )
370           {
371             state = PointState::UP; // mouse up
372           }
373           else
374           {
375             state = PointState::INTERRUPTED; // error
376           }
377
378           // Send touch event to accessibility manager.
379           Evas_Coord rel_x, rel_y, obj_x,  obj_y, obj_w, obj_h;
380
381           evas_object_geometry_get( eo, &obj_x,  &obj_y, &obj_w, &obj_h );
382
383           rel_x = accessActionInfo.x - obj_x;
384           rel_y = accessActionInfo.y - obj_y;
385
386           TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
387
388           ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
389         }
390       }
391       break;
392
393       case Dali::Extension::Internal::ACCESS_ACTION_UP:
394       {
395         ret = accessibilityAdaptor.HandleActionUpEvent();
396       }
397       break;
398
399       case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
400       {
401         ret = accessibilityAdaptor.HandleActionDownEvent();
402       }
403       break;
404
405       case Dali::Extension::Internal::ACCESS_ACTION_BACK:
406       default:
407       {
408         DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
409       }
410
411       break;
412     }
413   }
414   else
415   {
416     DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
417   }
418
419   return ret;
420 }
421
422 void Scene::OnEcoreWl2VisibilityChange( bool visible )
423 {
424   DALI_LOG_RELEASE_INFO( "Scene::OnEcoreWl2VisibilityChange( %s )", visible ? "T" : "F" );
425
426   SetVisibility( visible );
427 }
428
429 void Scene::SetVisibility( bool visible )
430 {
431   if( mVisible == visible )
432   {
433     return;
434   }
435
436   mVisible = visible;
437
438   if( !mAdaptor )
439   {
440     return;
441   }
442
443   if( mVisible )
444   {
445     mAdaptor->OnWindowShown();
446   }
447   else
448   {
449     mAdaptor->OnWindowHidden();
450
451     mSurface->ReleaseLock();
452   }
453
454   mVisibilityChangedSignal.Emit( Extension::Scene( this ), mVisible );
455 }
456
457 } // namespace Internal
458
459 } // namespace Extension
460
461 } // namespace Dali