[dali_1.3.22] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-impl.cpp
1 /*
2  * Copyright (c) 2018 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 // CLASS HEADER
19 #include <dali/internal/window-system/common/window-impl.h>
20
21 // EXTERNAL HEADERS
22 #include <dali/integration-api/core.h>
23 #include <dali/integration-api/system-overlay.h>
24 #include <dali/public-api/render-tasks/render-task.h>
25 #include <dali/public-api/render-tasks/render-task-list.h>
26 #include <dali/devel-api/adaptor-framework/orientation.h>
27
28 // INTERNAL HEADERS
29 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
30 #include <dali/internal/window-system/common/ecore-indicator-impl.h>
31 #include <dali/internal/window-system/common/window-visibility-observer.h>
32 #include <dali/internal/window-system/common/orientation-impl.h>
33 #include <dali/internal/window-system/common/render-surface-factory.h>
34 #include <dali/internal/window-system/common/window-base-factory.h>
35 #include <dali/internal/window-system/common/window-base.h>
36 #include <dali/internal/window-system/common/window-render-surface.h>
37
38 namespace Dali
39 {
40 namespace Internal
41 {
42 namespace Adaptor
43 {
44
45 namespace
46 {
47
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
50 #endif
51
52 } // unnamed namespace
53
54 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
55 {
56   Window* window = new Window();
57   window->mIsTransparent = isTransparent;
58   window->Initialize( positionSize, name, className );
59   return window;
60 }
61
62 Window::Window()
63 : mSurface( NULL ),
64   mWindowBase(),
65   mIndicatorVisible( Dali::Window::VISIBLE ),
66   mIndicatorIsShown( false ),
67   mShowRotatedIndicatorOnClose( false ),
68   mStarted( false ),
69   mIsTransparent( false ),
70   mIsFocusAcceptable( true ),
71   mVisible( true ),
72   mIconified( false ),
73   mOpaqueState( false ),
74   mResizeEnabled( false ),
75   mIndicator( NULL ),
76   mIndicatorOrientation( Dali::Window::PORTRAIT ),
77   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
78   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
79   mOverlay( NULL ),
80   mAdaptor( NULL ),
81   mType( Dali::Window::NORMAL ),
82   mPreferredOrientation( Dali::Window::PORTRAIT ),
83   mIndicatorVisibilityChangedSignal(),
84   mFocusChangedSignal(),
85   mResizedSignal(),
86   mDeleteRequestSignal()
87 {
88 }
89
90 Window::~Window()
91 {
92   if( mIndicator )
93   {
94     mOverlay->Remove( mIndicator->GetActor() );
95     Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
96     Dali::RenderTask indicatorTask = taskList.GetTask(0);
97     mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
98     mIndicator->Close();
99     delete mIndicator;
100   }
101
102   if ( mAdaptor )
103   {
104     mAdaptor->RemoveObserver( *this );
105     mAdaptor->SetDragAndDropDetector( NULL );
106     mAdaptor = NULL;
107   }
108
109   delete mSurface;
110 }
111
112 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
113 {
114   // create a window render surface
115   Any surface;
116   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
117   auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, name, className, mIsTransparent );
118   mSurface = windowRenderSurface.release();
119
120   // create a window base
121   auto windowBaseFactory = Dali::Internal::Adaptor::GetWindowBaseFactory();
122   mWindowBase = windowBaseFactory->CreateWindowBase( this, mSurface );
123
124   mWindowBase->Initialize();
125
126   if( !positionSize.IsEmpty() )
127   {
128     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
129     mResizeEnabled = true;
130   }
131
132   SetClass( name, className );
133
134   mSurface->Map();
135
136   mOrientation = Orientation::New( this );
137 }
138
139 void Window::SetAdaptor(Dali::Adaptor& adaptor)
140 {
141   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
142   mStarted = true;
143
144   // Only create one overlay per window
145   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
146   Integration::Core& core = adaptorImpl.GetCore();
147   mOverlay = &core.GetSystemOverlay();
148
149   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
150   taskList.CreateTask();
151
152   mAdaptor = &adaptorImpl;
153   mAdaptor->AddObserver( *this );
154
155   // Can only create the detector when we know the Core has been instantiated.
156   mDragAndDropDetector = DragAndDropDetector::New();
157   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
158
159   if( mOrientation )
160   {
161     mOrientation->SetAdaptor(adaptor);
162   }
163
164   if( mIndicator != NULL )
165   {
166     mIndicator->SetAdaptor(mAdaptor);
167   }
168 }
169
170 WindowRenderSurface* Window::GetSurface()
171 {
172   return mSurface;
173 }
174
175 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
176 {
177   mIndicatorVisible = visibleMode;
178
179   mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
180
181   DoShowIndicator( mIndicatorOrientation );
182 }
183
184 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
185 {
186   mIndicatorOpacityMode = opacityMode;
187
188   if( mIndicator != NULL )
189   {
190     mIndicator->SetOpacityMode( opacityMode );
191   }
192 }
193
194 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
195 {
196   mIndicatorVisible = mode;
197 }
198
199 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
200 {
201   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
202
203   DoRotateIndicator( orientation );
204 }
205
206 void Window::SetClass( std::string name, std::string className )
207 {
208   mWindowBase->SetClass( name, className );
209 }
210
211 void Window::Raise()
212 {
213   mWindowBase->Raise();
214 }
215
216 void Window::Lower()
217 {
218   mWindowBase->Lower();
219 }
220
221 void Window::Activate()
222 {
223   mWindowBase->Activate();
224 }
225
226 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
227 {
228   bool found = false;
229
230   if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
231   {
232     for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
233     {
234       if( mAvailableOrientations[i] == orientation )
235       {
236         found = true;
237         break;
238       }
239     }
240
241     if( !found )
242     {
243       mAvailableOrientations.push_back( orientation );
244       SetAvailableOrientations( mAvailableOrientations );
245     }
246   }
247 }
248
249 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
250 {
251   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
252        iter != mAvailableOrientations.end(); ++iter )
253   {
254     if( *iter == orientation )
255     {
256       mAvailableOrientations.erase( iter );
257       break;
258     }
259   }
260   SetAvailableOrientations( mAvailableOrientations );
261 }
262
263 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
264 {
265   if( orientations.size() > 4 )
266   {
267     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
268     return;
269   }
270
271   mAvailableOrientations = orientations;
272
273   mWindowBase->SetAvailableOrientations( mAvailableOrientations );
274 }
275
276 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
277 {
278   return mAvailableOrientations;
279 }
280
281 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
282 {
283   mPreferredOrientation = orientation;
284
285   mWindowBase->SetPreferredOrientation( mPreferredOrientation );
286 }
287
288 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
289 {
290   return mPreferredOrientation;
291 }
292
293 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
294 {
295   return mDragAndDropDetector;
296 }
297
298 Dali::Any Window::GetNativeHandle() const
299 {
300   return mSurface->GetWindow();
301 }
302
303 void Window::SetAcceptFocus( bool accept )
304 {
305   mIsFocusAcceptable = accept;
306
307   mWindowBase->SetAcceptFocus( accept );
308 }
309
310 bool Window::IsFocusAcceptable() const
311 {
312   return mIsFocusAcceptable;
313 }
314
315 void Window::Show()
316 {
317   mVisible = true;
318
319   mWindowBase->Show();
320
321   if( !mIconified )
322   {
323     WindowVisibilityObserver* observer( mAdaptor );
324     observer->OnWindowShown();
325     DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
326   }
327 }
328
329 void Window::Hide()
330 {
331   mVisible = false;
332
333   mWindowBase->Hide();
334
335   if( !mIconified )
336   {
337     WindowVisibilityObserver* observer( mAdaptor );
338     observer->OnWindowHidden();
339     DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
340   }
341 }
342
343 bool Window::IsVisible() const
344 {
345   return mVisible;
346 }
347
348 unsigned int Window::GetSupportedAuxiliaryHintCount() const
349 {
350   return mWindowBase->GetSupportedAuxiliaryHintCount();
351 }
352
353 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
354 {
355   return mWindowBase->GetSupportedAuxiliaryHint( index );
356 }
357
358 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
359 {
360   return mWindowBase->AddAuxiliaryHint( hint, value );
361 }
362
363 bool Window::RemoveAuxiliaryHint( unsigned int id )
364 {
365   return mWindowBase->RemoveAuxiliaryHint( id );
366 }
367
368 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
369 {
370   return mWindowBase->SetAuxiliaryHintValue( id, value );
371 }
372
373 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
374 {
375   return mWindowBase->GetAuxiliaryHintValue( id );
376 }
377
378 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
379 {
380   return mWindowBase->GetAuxiliaryHintId( hint );
381 }
382
383 void Window::SetInputRegion( const Rect< int >& inputRegion )
384 {
385   mWindowBase->SetInputRegion( inputRegion );
386
387   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height );
388 }
389
390 void Window::SetType( Dali::Window::Type type )
391 {
392   if( type != mType )
393   {
394     mWindowBase->SetType( type );
395
396     mType = type;
397   }
398 }
399
400 Dali::Window::Type Window::GetType() const
401 {
402   return mType;
403 }
404
405 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
406 {
407   if( mType != Dali::Window::NOTIFICATION )
408   {
409     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
410     return false;
411   }
412
413   return mWindowBase->SetNotificationLevel( level );
414 }
415
416 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
417 {
418   if( mType != Dali::Window::NOTIFICATION )
419   {
420     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
421     return Dali::Window::NotificationLevel::NONE;
422   }
423
424   return mWindowBase->GetNotificationLevel();
425 }
426
427 void Window::SetOpaqueState( bool opaque )
428 {
429   mOpaqueState = opaque;
430
431   mWindowBase->SetOpaqueState( opaque );
432
433   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
434 }
435
436 bool Window::IsOpaqueState() const
437 {
438   return mOpaqueState;
439 }
440
441 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
442 {
443   return mWindowBase->SetScreenOffMode( screenOffMode );
444 }
445
446 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
447 {
448   return mWindowBase->GetScreenOffMode();
449 }
450
451 bool Window::SetBrightness( int brightness )
452 {
453   if( brightness < 0 || brightness > 100 )
454   {
455     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
456     return false;
457   }
458
459   return mWindowBase->SetBrightness( brightness );
460 }
461
462 int Window::GetBrightness() const
463 {
464   return mWindowBase->GetBrightness();
465 }
466
467 void Window::SetSize( Dali::Window::WindowSize size )
468 {
469   if( !mResizeEnabled )
470   {
471     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
472     mResizeEnabled = true;
473   }
474
475   PositionSize positionSize = mSurface->GetPositionSize();
476
477   if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
478   {
479     positionSize.width = size.GetWidth();
480     positionSize.height = size.GetHeight();
481
482     mSurface->MoveResize( positionSize );
483
484     mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
485
486     // Emit signal
487     mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
488
489     mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
490   }
491 }
492
493 Dali::Window::WindowSize Window::GetSize() const
494 {
495   PositionSize positionSize = mSurface->GetPositionSize();
496
497   return Dali::Window::WindowSize( positionSize.width, positionSize.height );
498 }
499
500 void Window::SetPosition( Dali::Window::WindowPosition position )
501 {
502   if( !mResizeEnabled )
503   {
504     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
505     mResizeEnabled = true;
506   }
507
508   PositionSize positionSize = mSurface->GetPositionSize();
509
510   if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
511   {
512     positionSize.x = position.GetX();
513     positionSize.y = position.GetY();
514
515     mSurface->MoveResize( positionSize );
516   }
517 }
518
519 Dali::Window::WindowPosition Window::GetPosition() const
520 {
521   PositionSize positionSize = mSurface->GetPositionSize();
522
523   return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
524 }
525
526 void Window::SetTransparency( bool transparent )
527 {
528   mSurface->SetTransparency( transparent );
529 }
530
531 void Window::RotationDone( int orientation, int width, int height )
532 {
533   mSurface->RequestRotation( orientation, width, height );
534
535   mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
536
537   // Emit signal
538   mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
539
540   mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
541 }
542
543 void Window::OnIconifyChanged( bool iconified )
544 {
545   if( iconified )
546   {
547     mIconified = true;
548
549     if( mVisible )
550     {
551       WindowVisibilityObserver* observer( mAdaptor );
552       observer->OnWindowHidden();
553       DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
554     }
555   }
556   else
557   {
558     mIconified = false;
559
560     if( mVisible )
561     {
562       WindowVisibilityObserver* observer( mAdaptor );
563       observer->OnWindowShown();
564       DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
565     }
566   }
567 }
568
569 void Window::OnFocusChanged( bool focusIn )
570 {
571   mFocusChangedSignal.Emit( focusIn );
572 }
573
574 void Window::OnOutputTransformed()
575 {
576   PositionSize positionSize = mSurface->GetPositionSize();
577   mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
578   mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
579 }
580
581 void Window::OnDeleteRequest()
582 {
583   mDeleteRequestSignal.Emit();
584 }
585
586 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
587 {
588   if( mIndicator == NULL )
589   {
590     if( mIndicatorVisible != Dali::Window::INVISIBLE )
591     {
592       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
593       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
594       Dali::Actor actor = mIndicator->GetActor();
595       SetIndicatorActorRotation();
596       mOverlay->Add(actor);
597     }
598     // else don't create a hidden indicator
599   }
600   else // Already have indicator
601   {
602     if( mIndicatorVisible == Dali::Window::VISIBLE )
603     {
604       // If we are resuming, and rotation has changed,
605       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
606       {
607         // then close current indicator and open new one
608         mShowRotatedIndicatorOnClose = true;
609         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
610         // Don't show actor - will contain indicator for old orientation.
611       }
612     }
613   }
614
615   // set indicator visible mode
616   if( mIndicator != NULL )
617   {
618     mIndicator->SetVisible( mIndicatorVisible );
619   }
620
621   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
622   SetIndicatorProperties( show, lastOrientation );
623   mIndicatorIsShown = show;
624 }
625
626 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
627 {
628   if( mIndicatorIsShown )
629   {
630     mShowRotatedIndicatorOnClose = true;
631     mNextIndicatorOrientation = orientation;
632     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
633   }
634   else
635   {
636     // Save orientation for when the indicator is next shown
637     mShowRotatedIndicatorOnClose = false;
638     mNextIndicatorOrientation = orientation;
639   }
640 }
641
642 void Window::SetIndicatorActorRotation()
643 {
644   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
645   DALI_ASSERT_DEBUG( mIndicator != NULL );
646
647   Dali::Actor actor = mIndicator->GetActor();
648   switch( mIndicatorOrientation )
649   {
650     case Dali::Window::PORTRAIT:
651       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
652       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
653       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
654       break;
655     case Dali::Window::PORTRAIT_INVERSE:
656       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
657       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
658       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
659       break;
660     case Dali::Window::LANDSCAPE:
661       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
662       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
663       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
664       break;
665     case Dali::Window::LANDSCAPE_INVERSE:
666       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
667       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
668       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
669       break;
670   }
671 }
672
673 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
674 {
675   mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
676 }
677
678 void Window::IndicatorTypeChanged(Indicator::Type type)
679 {
680   mWindowBase->IndicatorTypeChanged( type );
681 }
682
683 void Window::IndicatorClosed( IndicatorInterface* indicator )
684 {
685   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
686
687   if( mShowRotatedIndicatorOnClose )
688   {
689     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
690     mIndicator->Open( mNextIndicatorOrientation );
691     mIndicatorOrientation = mNextIndicatorOrientation;
692     SetIndicatorActorRotation();
693     DoShowIndicator( currentOrientation );
694   }
695 }
696
697 void Window::IndicatorVisibilityChanged( bool isVisible )
698 {
699   mIndicatorVisibilityChangedSignal.Emit( isVisible );
700 }
701
702 void Window::OnStart()
703 {
704   DoShowIndicator( mIndicatorOrientation );
705 }
706
707 void Window::OnPause()
708 {
709 }
710
711 void Window::OnResume()
712 {
713   // resume indicator status
714   if( mIndicator != NULL )
715   {
716     // Restore own indicator opacity
717     // Send opacity mode to indicator service when app resumed
718     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
719   }
720 }
721
722 void Window::OnStop()
723 {
724   if( mIndicator )
725   {
726     mIndicator->Close();
727   }
728
729   delete mIndicator;
730   mIndicator = NULL;
731 }
732
733 void Window::OnDestroy()
734 {
735   mAdaptor = NULL;
736 }
737
738 } // Adaptor
739
740 } // Internal
741
742 } // Dali