ef6454ee95070234be9bb00ced91ad64dc18b3f9
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-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 // 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/render-task-list-integ.h>
24 #include <dali/public-api/actors/actor.h>
25 #include <dali/public-api/actors/layer.h>
26 #include <dali/public-api/actors/camera-actor.h>
27 #include <dali/public-api/render-tasks/render-task.h>
28 #include <dali/public-api/render-tasks/render-task-list.h>
29 #include <dali/public-api/rendering/frame-buffer.h>
30 #include <dali/devel-api/adaptor-framework/orientation.h>
31
32 // INTERNAL HEADERS
33 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
34 #include <dali/internal/window-system/common/window-visibility-observer.h>
35 #include <dali/internal/window-system/common/orientation-impl.h>
36 #include <dali/internal/window-system/common/render-surface-factory.h>
37 #include <dali/internal/window-system/common/window-factory.h>
38 #include <dali/internal/window-system/common/window-base.h>
39 #include <dali/internal/window-system/common/window-render-surface.h>
40
41 namespace Dali
42 {
43 namespace Internal
44 {
45 namespace Adaptor
46 {
47
48 uint32_t Window::mWindowCounter = 0;
49
50 namespace
51 {
52
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
55 #endif
56
57 } // unnamed namespace
58
59 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
60 {
61   Window* window = new Window();
62   window->mIsTransparent = isTransparent;
63   window->Initialize( positionSize, name, className );
64   return window;
65 }
66
67 Window::Window()
68 : mId( mWindowCounter++ ),
69   mSurface( nullptr ),
70   mWindowBase(),
71   mStarted( false ),
72   mIsFocusAcceptable( true ),
73   mVisible( true ),
74   mIconified( false ),
75   mOpaqueState( false ),
76   mResizeEnabled( false ),
77   mAdaptor( NULL ),
78   mType( Dali::Window::NORMAL ),
79   mPreferredOrientation( Dali::Window::PORTRAIT ),
80   mFocusChangedSignal(),
81   mResizedSignal(),
82   mDeleteRequestSignal()
83 {
84 }
85
86 Window::~Window()
87 {
88   if ( mAdaptor )
89   {
90     mAdaptor->RemoveObserver( *this );
91     mAdaptor->SetDragAndDropDetector( NULL );
92     mAdaptor->RemoveWindow( this );
93     mAdaptor = NULL;
94   }
95
96   mSurface.reset( nullptr );
97 }
98
99 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
100 {
101   // Create a window render surface
102   Any surface;
103   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
104   mSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
105
106   // Get a window base
107   mWindowBase = mSurface->GetWindowBase();
108
109   // Connect signals
110   mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
111   mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
112   mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
113
114   mSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
115
116   if( !positionSize.IsEmpty() )
117   {
118     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
119     mResizeEnabled = true;
120   }
121
122   SetClass( name, className );
123
124   mSurface->Map();
125
126   mOrientation = Orientation::New( this );
127 }
128
129 void Window::SetAdaptor(Dali::Adaptor& adaptor)
130 {
131   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
132   mStarted = true;
133
134   PositionSize positionSize = mSurface->GetPositionSize();
135   mScene = Dali::Integration::Scene::New( Vector2(positionSize.width, positionSize.height) );
136   mScene.SetSurface( *mSurface.get() );
137
138   unsigned int dpiHorizontal, dpiVertical;
139   dpiHorizontal = dpiVertical = 0;
140
141   mSurface->GetDpi( dpiHorizontal, dpiVertical );
142   mScene.SetDpi( Vector2( static_cast<float>( dpiHorizontal ), static_cast<float>( dpiVertical ) ) );
143
144   // Create one overlay for the main window only
145   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
146   mAdaptor = &adaptorImpl;
147   mAdaptor->AddObserver( *this );
148
149   // Can only create the detector when we know the Core has been instantiated.
150   mDragAndDropDetector = DragAndDropDetector::New();
151   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
152
153   if( mOrientation )
154   {
155     mOrientation->SetAdaptor(adaptor);
156   }
157
158   mSurface->SetAdaptor( *mAdaptor );
159 }
160
161 WindowRenderSurface* Window::GetSurface()
162 {
163   return mSurface.get();
164 }
165
166 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
167 {
168 }
169
170 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
171 {
172 }
173
174 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
175 {
176 }
177
178 void Window::SetClass( std::string name, std::string className )
179 {
180   mWindowBase->SetClass( name, className );
181 }
182
183 void Window::Raise()
184 {
185   mWindowBase->Raise();
186 }
187
188 void Window::Lower()
189 {
190   mWindowBase->Lower();
191 }
192
193 void Window::Activate()
194 {
195   mWindowBase->Activate();
196 }
197
198 void Window::Add( Dali::Actor actor )
199 {
200   mScene.Add( actor );
201 }
202
203 void Window::Remove( Dali::Actor actor )
204 {
205   mScene.Remove( actor );
206 }
207
208 Dali::Layer Window::GetRootLayer() const
209 {
210   return mScene.GetRootLayer();
211 }
212
213 uint32_t Window::GetLayerCount() const
214 {
215   return mScene.GetLayerCount();
216 }
217
218 Dali::Layer Window::GetLayer( uint32_t depth ) const
219 {
220   return mScene.GetLayer( depth );
221 }
222
223 void Window::SetBackgroundColor( Vector4 color )
224 {
225   if ( mSurface )
226   {
227     mSurface->SetBackgroundColor( color );
228   }
229 }
230
231 Vector4 Window::GetBackgroundColor() const
232 {
233   return mSurface ? mSurface->GetBackgroundColor() : Vector4();
234 }
235
236 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
237 {
238   bool found = false;
239
240   if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
241   {
242     for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
243     {
244       if( mAvailableOrientations[i] == orientation )
245       {
246         found = true;
247         break;
248       }
249     }
250
251     if( !found )
252     {
253       mAvailableOrientations.push_back( orientation );
254       SetAvailableOrientations( mAvailableOrientations );
255     }
256   }
257 }
258
259 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
260 {
261   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
262        iter != mAvailableOrientations.end(); ++iter )
263   {
264     if( *iter == orientation )
265     {
266       mAvailableOrientations.erase( iter );
267       break;
268     }
269   }
270   SetAvailableOrientations( mAvailableOrientations );
271 }
272
273 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
274 {
275   if( orientations.size() > 4 )
276   {
277     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
278     return;
279   }
280
281   mAvailableOrientations = orientations;
282
283   mWindowBase->SetAvailableOrientations( mAvailableOrientations );
284 }
285
286 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
287 {
288   return mAvailableOrientations;
289 }
290
291 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
292 {
293   mPreferredOrientation = orientation;
294
295   mWindowBase->SetPreferredOrientation( mPreferredOrientation );
296 }
297
298 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
299 {
300   return mPreferredOrientation;
301 }
302
303 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
304 {
305   return mDragAndDropDetector;
306 }
307
308 Dali::Any Window::GetNativeHandle() const
309 {
310   return mSurface->GetNativeWindow();
311 }
312
313 void Window::SetAcceptFocus( bool accept )
314 {
315   mIsFocusAcceptable = accept;
316
317   mWindowBase->SetAcceptFocus( accept );
318 }
319
320 bool Window::IsFocusAcceptable() const
321 {
322   return mIsFocusAcceptable;
323 }
324
325 void Window::Show()
326 {
327   mVisible = true;
328
329   mWindowBase->Show();
330
331   if( !mIconified )
332   {
333     WindowVisibilityObserver* observer( mAdaptor );
334     observer->OnWindowShown();
335     DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
336   }
337 }
338
339 void Window::Hide()
340 {
341   mVisible = false;
342
343   mWindowBase->Hide();
344
345   if( !mIconified )
346   {
347     WindowVisibilityObserver* observer( mAdaptor );
348     observer->OnWindowHidden();
349     DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
350   }
351 }
352
353 bool Window::IsVisible() const
354 {
355   return mVisible;
356 }
357
358 unsigned int Window::GetSupportedAuxiliaryHintCount() const
359 {
360   return mWindowBase->GetSupportedAuxiliaryHintCount();
361 }
362
363 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
364 {
365   return mWindowBase->GetSupportedAuxiliaryHint( index );
366 }
367
368 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
369 {
370   return mWindowBase->AddAuxiliaryHint( hint, value );
371 }
372
373 bool Window::RemoveAuxiliaryHint( unsigned int id )
374 {
375   return mWindowBase->RemoveAuxiliaryHint( id );
376 }
377
378 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
379 {
380   return mWindowBase->SetAuxiliaryHintValue( id, value );
381 }
382
383 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
384 {
385   return mWindowBase->GetAuxiliaryHintValue( id );
386 }
387
388 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
389 {
390   return mWindowBase->GetAuxiliaryHintId( hint );
391 }
392
393 void Window::SetInputRegion( const Rect< int >& inputRegion )
394 {
395   mWindowBase->SetInputRegion( inputRegion );
396
397   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 );
398 }
399
400 void Window::SetType( Dali::Window::Type type )
401 {
402   if( type != mType )
403   {
404     mWindowBase->SetType( type );
405
406     mType = type;
407   }
408 }
409
410 Dali::Window::Type Window::GetType() const
411 {
412   return mType;
413 }
414
415 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
416 {
417   if( mType != Dali::Window::NOTIFICATION )
418   {
419     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
420     return false;
421   }
422
423   return mWindowBase->SetNotificationLevel( level );
424 }
425
426 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
427 {
428   if( mType != Dali::Window::NOTIFICATION )
429   {
430     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
431     return Dali::Window::NotificationLevel::NONE;
432   }
433
434   return mWindowBase->GetNotificationLevel();
435 }
436
437 void Window::SetOpaqueState( bool opaque )
438 {
439   mOpaqueState = opaque;
440
441   mWindowBase->SetOpaqueState( opaque );
442
443   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
444 }
445
446 bool Window::IsOpaqueState() const
447 {
448   return mOpaqueState;
449 }
450
451 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
452 {
453   return mWindowBase->SetScreenOffMode( screenOffMode );
454 }
455
456 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
457 {
458   return mWindowBase->GetScreenOffMode();
459 }
460
461 bool Window::SetBrightness( int brightness )
462 {
463   if( brightness < 0 || brightness > 100 )
464   {
465     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
466     return false;
467   }
468
469   return mWindowBase->SetBrightness( brightness );
470 }
471
472 int Window::GetBrightness() const
473 {
474   return mWindowBase->GetBrightness();
475 }
476
477 void Window::SetSize( Dali::Window::WindowSize size )
478 {
479   if( !mResizeEnabled )
480   {
481     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
482     mResizeEnabled = true;
483   }
484
485   PositionSize oldRect = mSurface->GetPositionSize();
486
487   mSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
488
489   PositionSize newRect = mSurface->GetPositionSize();
490
491   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
492   if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
493   {
494     Uint16Pair newSize( newRect.width, newRect.height );
495
496     mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
497
498     mResizedSignal.Emit( newSize );
499
500     mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
501   }
502 }
503
504 Dali::Window::WindowSize Window::GetSize() const
505 {
506   PositionSize positionSize = mSurface->GetPositionSize();
507
508   return Dali::Window::WindowSize( positionSize.width, positionSize.height );
509 }
510
511 void Window::SetPosition( Dali::Window::WindowPosition position )
512 {
513   if( !mResizeEnabled )
514   {
515     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
516     mResizeEnabled = true;
517   }
518
519   PositionSize oldRect = mSurface->GetPositionSize();
520
521   mSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
522 }
523
524 Dali::Window::WindowPosition Window::GetPosition() const
525 {
526   PositionSize positionSize = mSurface->GetPositionSize();
527
528   return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
529 }
530
531 void Window::SetPositionSize( PositionSize positionSize )
532 {
533   if( !mResizeEnabled )
534   {
535     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
536     mResizeEnabled = true;
537   }
538
539   PositionSize oldRect = mSurface->GetPositionSize();
540
541   mSurface->MoveResize( positionSize );
542
543   PositionSize newRect = mSurface->GetPositionSize();
544
545   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
546   if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
547   {
548     Uint16Pair newSize( newRect.width, newRect.height );
549
550     mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
551
552     mResizedSignal.Emit( newSize );
553
554     mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
555   }
556 }
557
558 void Window::SetTransparency( bool transparent )
559 {
560   mSurface->SetTransparency( transparent );
561 }
562
563 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
564 {
565   return mWindowBase->GrabKey( key, grabMode );
566 }
567
568 bool Window::UngrabKey( Dali::KEY key )
569 {
570   return mWindowBase->UngrabKey( key );
571 }
572
573 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
574 {
575   return mWindowBase->GrabKeyList( key, grabMode, result );
576 }
577
578 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
579 {
580   return mWindowBase->UngrabKeyList( key, result );
581 }
582
583 void Window::RotationDone( int orientation, int width, int height )
584 {
585   mSurface->RequestRotation( orientation, width, height );
586
587   mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( width, height ) );
588
589   // Emit signal
590   mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
591
592   mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( width, height ) );
593 }
594
595 void Window::OnIconifyChanged( bool iconified )
596 {
597   if( iconified )
598   {
599     mIconified = true;
600
601     if( mVisible )
602     {
603       WindowVisibilityObserver* observer( mAdaptor );
604       observer->OnWindowHidden();
605       DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
606     }
607   }
608   else
609   {
610     mIconified = false;
611
612     if( mVisible )
613     {
614       WindowVisibilityObserver* observer( mAdaptor );
615       observer->OnWindowShown();
616       DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
617     }
618   }
619 }
620
621 void Window::OnFocusChanged( bool focusIn )
622 {
623   mFocusChangedSignal.Emit( focusIn );
624 }
625
626 void Window::OnOutputTransformed()
627 {
628   PositionSize positionSize = mSurface->GetPositionSize();
629   mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
630   mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
631 }
632
633 void Window::OnDeleteRequest()
634 {
635   mDeleteRequestSignal.Emit();
636 }
637
638 void Window::OnStart()
639 {
640 }
641
642 void Window::OnPause()
643 {
644 }
645
646 void Window::OnResume()
647 {
648 }
649
650 void Window::OnStop()
651 {
652 }
653
654 void Window::OnDestroy()
655 {
656   mAdaptor = NULL;
657 }
658
659 uint32_t Window::GetId() const
660 {
661   return mId;
662 }
663
664 } // Adaptor
665
666 } // Internal
667
668 } // Dali