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