[4.0] Pause adaptor when the window is hidden
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / window-impl-x.cpp
1 /*
2  * Copyright (c) 2017 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 "window-impl.h"
20
21 // EXTERNAL HEADERS
22 // Ecore is littered with C style cast
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #include <Ecore.h>
26 #include <Ecore_X.h>
27
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/system-overlay.h>
30 #include <dali/public-api/render-tasks/render-task.h>
31 #include <dali/public-api/render-tasks/render-task-list.h>
32
33 // INTERNAL HEADERS
34 #include <window-render-surface.h>
35 #include <drag-and-drop-detector-impl.h>
36 #include <ecore-indicator-impl.h>
37 #include <window-visibility-observer.h>
38 #include <orientation.h>
39 #include <orientation-impl.h>
40
41 namespace
42 {
43 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
44 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
45 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
46 }
47
48 namespace Dali
49 {
50 namespace Internal
51 {
52 namespace Adaptor
53 {
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_WINDOW");
56 #endif
57
58 /**
59  * TODO: Abstract Window class out and move this into a window implementation for Ecore
60  */
61 struct Window::EventHandler
62 {
63   /**
64    * Constructor
65    * @param[in]  window  A pointer to the window class.
66    */
67   EventHandler( Window* window )
68   : mWindow( window ),
69     mWindowPropertyHandler( NULL ),
70     mClientMessagehandler( NULL ),
71     mWindowDeleteRequestHandler( NULL ),
72     mEcoreWindow( 0 )
73   {
74     // store ecore window handle
75     ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
76     if( x11Window )
77     {
78       mEcoreWindow = x11Window->GetXWindow();
79     }
80     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore x window");
81
82 #ifndef DALI_PROFILE_UBUNTU
83     // set property on window to get deiconify approve client message
84     unsigned int tmp = 1;
85     ecore_x_window_prop_card32_set(mEcoreWindow,
86                              ECORE_X_ATOM_E_DEICONIFY_APPROVE,
87                              &tmp, 1);
88 #endif // DALI_PROFILE_UBUNTU
89
90     if( mWindow->mEcoreEventHander )
91     {
92       ecore_x_input_multi_select( mEcoreWindow );
93
94       // This ensures that we catch the window close (or delete) request
95       ecore_x_icccm_protocol_set( mEcoreWindow, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE );
96
97       mWindowPropertyHandler=  ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY,  EcoreEventWindowPropertyChanged, this );
98       mClientMessagehandler =  ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, this );
99       mWindowDeleteRequestHandler = ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest, this );
100     }
101   }
102
103   /**
104    * Destructor
105    */
106   ~EventHandler()
107   {
108     if ( mWindowPropertyHandler )
109     {
110       ecore_event_handler_del( mWindowPropertyHandler );
111     }
112     if ( mClientMessagehandler )
113     {
114       ecore_event_handler_del( mClientMessagehandler );
115     }
116     if ( mWindowDeleteRequestHandler )
117     {
118       ecore_event_handler_del( mWindowDeleteRequestHandler );
119     }
120   }
121
122   // Static methods
123
124   /// Called when the window properties are changed.
125   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
126   {
127     Ecore_X_Event_Window_Property* propertyChangedEvent( (Ecore_X_Event_Window_Property*)event );
128     EventHandler* handler( (EventHandler*)data );
129     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
130
131     if ( handler && handler->mWindow )
132     {
133       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
134       if ( observer && ( propertyChangedEvent->win == handler->mEcoreWindow ) )
135       {
136         Ecore_X_Window_State_Hint state( ecore_x_icccm_state_get( propertyChangedEvent->win ) );
137
138         switch ( state )
139         {
140           case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN:
141           {
142             // Window was hidden.
143             observer->OnWindowHidden();
144             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Withdrawn\n", handler->mEcoreWindow );
145             handled = ECORE_CALLBACK_DONE;
146           }
147           break;
148
149           case ECORE_X_WINDOW_STATE_HINT_ICONIC:
150           {
151             // Window was iconified (minimised).
152             observer->OnWindowHidden();
153             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Iconfied\n", handler->mEcoreWindow );
154             handled = ECORE_CALLBACK_DONE;
155           }
156           break;
157
158           case ECORE_X_WINDOW_STATE_HINT_NORMAL:
159           {
160             // Window was shown.
161             observer->OnWindowShown();
162             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Shown\n", handler->mEcoreWindow );
163             handled = ECORE_CALLBACK_DONE;
164           }
165           break;
166
167           default:
168             // Ignore
169             break;
170         }
171       }
172     }
173
174     return handled;
175   }
176
177   /// Called when the window properties are changed.
178   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
179   {
180     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
181 #ifndef DALI_PROFILE_UBUNTU
182     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
183     EventHandler* handler( (EventHandler*)data );
184
185     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
186     {
187       ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
188       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
189
190       if ( observer && ( (unsigned int)clientMessageEvent->data.l[0] == handler->mEcoreWindow ) )
191       {
192         if (clientMessageEvent->data.l[1] == 0) //wm sends request message using value 0
193         {
194           observer->OnWindowShown();
195
196           // request to approve the deiconify. render-surface should send proper event after real rendering
197           if(x11Window)
198           {
199             x11Window->RequestToApproveDeiconify();
200           }
201
202           handled = ECORE_CALLBACK_DONE;
203         }
204       }
205     }
206 #endif // DALI_PROFILE_UBUNTU
207
208     return handled;
209   }
210
211   /// Called when the window receives a delete request
212   static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* event )
213   {
214     EventHandler* handler( (EventHandler*)data );
215     handler->mWindow->mDeleteRequestSignal.Emit();
216     return ECORE_CALLBACK_DONE;
217   }
218
219   // Data
220   Window* mWindow;
221   Ecore_Event_Handler* mWindowPropertyHandler;
222   Ecore_Event_Handler* mClientMessagehandler;
223   Ecore_Event_Handler* mWindowDeleteRequestHandler;
224   Ecore_X_Window mEcoreWindow;
225 };
226
227
228 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
229 {
230   Window* window = new Window();
231   window->mIsTransparent = isTransparent;
232   window->Initialize( positionSize, name, className );
233   return window;
234 }
235
236 void Window::SetAdaptor(Dali::Adaptor& adaptor)
237 {
238   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
239   mStarted = true;
240
241   // Only create one overlay per window
242   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
243   Integration::Core& core = adaptorImpl.GetCore();
244   mOverlay = &core.GetSystemOverlay();
245
246   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
247   taskList.CreateTask();
248
249   mAdaptor = &adaptorImpl;
250   mAdaptor->AddObserver( *this );
251
252   // Can only create the detector when we know the Core has been instantiated.
253   mDragAndDropDetector = DragAndDropDetector::New();
254   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
255
256   if( mOrientation )
257   {
258     mOrientation->SetAdaptor(adaptor);
259   }
260
261   if( mIndicator != NULL )
262   {
263     mIndicator->SetAdaptor(mAdaptor);
264   }
265 }
266
267 RenderSurface* Window::GetSurface()
268 {
269   return mSurface;
270 }
271
272 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
273 {
274   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
275   DALI_ASSERT_DEBUG(mOverlay);
276
277   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
278   DALI_ASSERT_DEBUG(x11Window);
279   Ecore_X_Window xWinId = x11Window->GetXWindow();
280
281   mIndicatorVisible = visibleMode;
282
283   if ( mIndicatorVisible == Dali::Window::VISIBLE )
284   {
285     // when the indicator is visible, set proper mode for indicator server according to bg mode
286     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
287     {
288       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
289     }
290     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
291     {
292       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
293     }
294 #if defined(DALI_PROFILE_MOBILE)
295     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
296     {
297       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
298     }
299 #endif
300   }
301   else
302   {
303     // when the indicator is not visible, set TRANSPARENT mode for indicator server
304     ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); // it means hidden indicator
305   }
306
307   DoShowIndicator( mIndicatorOrientation );
308 }
309
310 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
311 {
312   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
313
314   DoRotateIndicator( orientation );
315 }
316
317 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
318 {
319   mIndicatorOpacityMode = opacityMode;
320
321   if( mIndicator != NULL )
322   {
323     mIndicator->SetOpacityMode( opacityMode );
324   }
325 }
326
327 void Window::SetClass(std::string name, std::string klass)
328 {
329   // Get render surface's x11 window
330   if( mSurface )
331   {
332     ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
333     if( x11Window )
334     {
335       ecore_x_icccm_name_class_set( x11Window->GetXWindow(), name.c_str(), klass.c_str() );
336     }
337   }
338 }
339
340 Window::Window()
341 : mSurface( NULL ),
342   mIndicatorVisible( Dali::Window::INVISIBLE ),
343   mIndicatorIsShown( false ),
344   mShowRotatedIndicatorOnClose( false ),
345   mStarted( false ),
346   mIsTransparent( false ),
347   mWMRotationAppSet( false ),
348   mEcoreEventHander( true ),
349   mIsFocusAcceptable( true ),
350   mVisible( true ),
351   mIconified( false ),
352   mOpaqueState( false ),
353   mResizeEnabled( true ),
354   mIndicator( NULL ),
355   mIndicatorOrientation( Dali::Window::PORTRAIT ),
356   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
357   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
358   mOverlay( NULL ),
359   mAdaptor( NULL ),
360   mType( Dali::Window::NORMAL ),
361   mEventHandler( NULL ),
362   mPreferredOrientation( Dali::Window::PORTRAIT ),
363   mSupportedAuxiliaryHints(),
364   mAuxiliaryHints(),
365   mIndicatorVisibilityChangedSignal(),
366   mFocusChangedSignal(),
367   mResizedSignal(),
368   mDeleteRequestSignal()
369 {
370 }
371
372 Window::~Window()
373 {
374   delete mEventHandler;
375
376   if( mIndicator )
377   {
378     mOverlay->Remove( mIndicator->GetActor() );
379     Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
380     Dali::RenderTask indicatorTask = taskList.GetTask(0);
381     mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
382     mIndicator->Close();
383     delete mIndicator;
384   }
385
386   if( mAdaptor )
387   {
388     mAdaptor->RemoveObserver( *this );
389     mAdaptor->SetDragAndDropDetector( NULL );
390     mAdaptor = NULL;
391   }
392
393   delete mSurface;
394 }
395
396 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
397 {
398   // create an X11 window by default
399   Any surface;
400   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( positionSize, surface, name, className, mIsTransparent );
401   windowSurface->Map();
402
403   mSurface = windowSurface;
404
405   mOrientation = Orientation::New(this);
406
407   // create event handler for X11 window
408   mEventHandler = new EventHandler( this );
409 }
410
411 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
412 {
413   if( mIndicator == NULL )
414   {
415     if( mIndicatorVisible != Dali::Window::INVISIBLE )
416     {
417       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
418       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
419       Dali::Actor actor = mIndicator->GetActor();
420       SetIndicatorActorRotation();
421       mOverlay->Add(actor);
422     }
423     // else don't create a hidden indicator
424   }
425   else // Already have indicator
426   {
427     if( mIndicatorVisible == Dali::Window::VISIBLE )
428     {
429       // If we are resuming, and rotation has changed,
430       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
431       {
432         // then close current indicator and open new one
433         mShowRotatedIndicatorOnClose = true;
434         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
435         // Don't show actor - will contain indicator for old orientation.
436       }
437     }
438   }
439
440   // set indicator visible mode
441   if( mIndicator != NULL )
442   {
443     mIndicator->SetVisible( mIndicatorVisible );
444   }
445
446   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
447   SetIndicatorProperties( show, lastOrientation );
448   mIndicatorIsShown = show;
449 }
450
451 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
452 {
453   if( mIndicatorIsShown )
454   {
455     mShowRotatedIndicatorOnClose = true;
456     mNextIndicatorOrientation = orientation;
457     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
458   }
459   else
460   {
461     // Save orientation for when the indicator is next shown
462     mShowRotatedIndicatorOnClose = false;
463     mNextIndicatorOrientation = orientation;
464   }
465 }
466
467 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
468 {
469   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
470   if( x11Window )
471   {
472     Ecore_X_Window win = x11Window->GetXWindow();
473
474     int show_state = static_cast<int>( isShow );
475     ecore_x_window_prop_property_set( win,
476                                       ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
477                                       ECORE_X_ATOM_CARDINAL, 32, &show_state, 1);
478
479     if ( isShow )
480     {
481       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_ON);
482     }
483     else
484     {
485       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
486     }
487   }
488 }
489
490 void Window::IndicatorTypeChanged(Indicator::Type type)
491 {
492   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
493   if( x11Window )
494   {
495 #ifndef DALI_PROFILE_UBUNTU
496     Ecore_X_Window win = x11Window->GetXWindow();
497     switch(type)
498     {
499       case Indicator::INDICATOR_TYPE_1:
500         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_1 );
501         break;
502
503       case Indicator::INDICATOR_TYPE_2:
504         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_2 );
505         break;
506
507       case Indicator::INDICATOR_TYPE_UNKNOWN:
508       default:
509         break;
510     }
511 #endif // DALI_PROFILE_UBUNTU
512   }
513 }
514
515 void Window::IndicatorClosed( IndicatorInterface* indicator )
516 {
517   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
518
519   if( mShowRotatedIndicatorOnClose )
520   {
521     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
522     mIndicator->Open(mNextIndicatorOrientation);
523     mIndicatorOrientation = mNextIndicatorOrientation;
524     SetIndicatorActorRotation();
525     DoShowIndicator(currentOrientation);
526   }
527 }
528
529 void Window::IndicatorVisibilityChanged(bool isVisible)
530 {
531   mIndicatorVisibilityChangedSignal.Emit(isVisible);
532 }
533
534 void Window::SetIndicatorActorRotation()
535 {
536   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
537   DALI_ASSERT_DEBUG( mIndicator != NULL );
538
539   Dali::Actor actor = mIndicator->GetActor();
540   switch( mIndicatorOrientation )
541   {
542     case Dali::Window::PORTRAIT:
543       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
544       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
545       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
546       break;
547     case Dali::Window::PORTRAIT_INVERSE:
548       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
549       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
550       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
551       break;
552     case Dali::Window::LANDSCAPE:
553       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
554       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
555       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
556       break;
557     case Dali::Window::LANDSCAPE_INVERSE:
558       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
559       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
560       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
561       break;
562   }
563 }
564
565 void Window::Raise()
566 {
567   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
568   if( x11Window )
569   {
570     Ecore_X_Window win = x11Window->GetXWindow();
571     ecore_x_window_raise(win);
572   }
573 }
574
575 void Window::Lower()
576 {
577   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
578   if( x11Window )
579   {
580     Ecore_X_Window win = x11Window->GetXWindow();
581     ecore_x_window_lower(win);
582   }
583 }
584
585 void Window::Activate()
586 {
587   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
588   if( x11Window )
589   {
590     Ecore_X_Window win = x11Window->GetXWindow();
591     ecore_x_netwm_client_active_request(ecore_x_window_root_get(win), win, 1 /* request type, 1:application, 2:pager */, 0);
592   }
593 }
594
595 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
596 {
597   return mDragAndDropDetector;
598 }
599
600 Dali::Any Window::GetNativeHandle() const
601 {
602   if(mEventHandler)
603   {
604     return mEventHandler->mEcoreWindow;
605   }
606   else
607   {
608     return Dali::Any();
609   }
610 }
611
612 void Window::OnStart()
613 {
614   ShowIndicator( mIndicatorVisible );
615 }
616
617 void Window::OnPause()
618 {
619 }
620
621 void Window::OnResume()
622 {
623   // resume indicator status
624   if( mIndicator != NULL )
625   {
626     // Restore own indicator opacity
627     // Send opacity mode to indicator service when app resumed
628     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
629   }
630 }
631
632 void Window::OnStop()
633 {
634   if( mIndicator )
635   {
636     mIndicator->Close();
637   }
638
639   delete mIndicator;
640   mIndicator = NULL;
641 }
642
643 void Window::OnDestroy()
644 {
645   mAdaptor = NULL;
646 }
647
648 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
649 {
650   bool found = false;
651
652   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
653   {
654     if(mAvailableOrientations[i] == orientation)
655     {
656       found = true;
657       break;
658     }
659   }
660
661   if( ! found )
662   {
663     mAvailableOrientations.push_back(orientation);
664     SetAvailableOrientations( mAvailableOrientations );
665   }
666 }
667
668 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
669 {
670   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
671        iter != mAvailableOrientations.end(); ++iter )
672   {
673     if( *iter == orientation )
674     {
675       mAvailableOrientations.erase( iter );
676       break;
677     }
678   }
679   SetAvailableOrientations( mAvailableOrientations );
680 }
681
682 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
683 {
684   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
685
686   mAvailableOrientations = orientations;
687   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
688   if( x11Window )
689   {
690 #ifndef DALI_PROFILE_UBUNTU
691     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
692     if( ! mWMRotationAppSet )
693     {
694       mWMRotationAppSet = true;
695       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
696     }
697
698     int rotations[4];
699     for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
700     {
701       rotations[i] = static_cast<int>(mAvailableOrientations[i]);
702     }
703     ecore_x_e_window_rotation_available_rotations_set(ecoreWindow, rotations, mAvailableOrientations.size() );
704 #endif // DALI_PROFILE_UBUNTU
705   }
706 }
707
708 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
709 {
710   return mAvailableOrientations;
711 }
712
713 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
714 {
715   mPreferredOrientation = orientation;
716
717   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
718   if( x11Window )
719   {
720 #ifndef DALI_PROFILE_UBUNTU
721     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
722
723     if( ! mWMRotationAppSet )
724     {
725       mWMRotationAppSet = true;
726       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
727     }
728
729     ecore_x_e_window_rotation_preferred_rotation_set(ecoreWindow, orientation);
730 #endif // DALI_PROFILE_UBUNTU
731   }
732 }
733
734 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
735 {
736   return mPreferredOrientation;
737 }
738
739 void Window::SetAcceptFocus( bool accept )
740 {
741   mIsFocusAcceptable = accept;
742 }
743
744 bool Window::IsFocusAcceptable() const
745 {
746   return mIsFocusAcceptable;
747 }
748
749 void Window::Show()
750 {
751   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
752   if( x11Window )
753   {
754     Ecore_X_Window win = x11Window->GetXWindow();
755     ecore_x_window_show( win );
756
757     // Need an update request
758     if( mAdaptor )
759     {
760       mAdaptor->RequestUpdateOnce();
761     }
762   }
763 }
764
765 void Window::Hide()
766 {
767   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
768   if( x11Window )
769   {
770     Ecore_X_Window win = x11Window->GetXWindow();
771     ecore_x_window_hide( win );
772   }
773 }
774
775 bool Window::IsVisible() const
776 {
777   bool visible = false;
778
779   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
780   if( x11Window )
781   {
782     Ecore_X_Window win = x11Window->GetXWindow();
783     visible = static_cast< bool >( ecore_x_window_visible_get( win ) );
784   }
785   return visible;
786 }
787
788 void Window::RotationDone( int orientation, int width, int height )
789 {
790   // Tell window manager we're done
791   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
792   if( x11Window )
793   {
794 #ifndef DALI_PROFILE_UBUNTU
795     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
796     Ecore_X_Window root = ecore_x_window_root_get(ecoreWindow);
797
798     /**
799      * send rotation done message to wm, even if window is already rotated.
800      * that's why wm must be wait for comming rotation done message
801      * after sending rotation request.
802      */
803     ecore_x_e_window_rotation_change_done_send(root, ecoreWindow, orientation, width, height);
804
805     /**
806      * set rotate window property
807      */
808     int angles[2] = { orientation, orientation };
809     ecore_x_window_prop_property_set( ecoreWindow,
810                                      ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
811                                      ECORE_X_ATOM_CARDINAL, 32, &angles, 2 );
812
813     mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
814
815     // Emit signal
816     mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
817
818     mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
819 #endif // DALI_PROFILE_UBUNTU
820   }
821 }
822
823 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
824 {
825   mIndicatorVisible = mode;
826 }
827
828 unsigned int Window::GetSupportedAuxiliaryHintCount() const
829 {
830   return 0;
831 }
832
833 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
834 {
835   return std::string();
836 }
837
838 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
839 {
840   return -1;
841 }
842
843 bool Window::RemoveAuxiliaryHint( unsigned int id )
844 {
845   return false;
846 }
847
848 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
849 {
850   return false;
851 }
852
853 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
854 {
855   return std::string();
856 }
857
858 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
859 {
860   return -1;
861 }
862
863 void Window::SetInputRegion( const Rect< int >& inputRegion )
864 {
865 }
866
867 void Window::SetType( Dali::Window::Type type )
868 {
869   mType = type;
870 }
871
872 Dali::Window::Type Window::GetType() const
873 {
874   return mType;
875 }
876
877 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
878 {
879   return false;
880 }
881
882 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
883 {
884   return Dali::Window::NotificationLevel::NONE;
885 }
886
887 void Window::SetOpaqueState( bool opaque )
888 {
889   mOpaqueState = opaque;
890 }
891
892 bool Window::IsOpaqueState() const
893 {
894   return mOpaqueState;
895 }
896
897 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
898 {
899   return false;
900 }
901
902 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
903 {
904   return Dali::Window::ScreenOffMode::TIMEOUT;
905 }
906
907 bool Window::SetBrightness( int brightness )
908 {
909   return false;
910 }
911
912 int Window::GetBrightness() const
913 {
914   return 0;
915 }
916
917 void Window::SetSize( Dali::Window::WindowSize size )
918 {
919   PositionSize positionSize = mSurface->GetPositionSize();
920
921   if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
922   {
923     positionSize.width = size.GetWidth();
924     positionSize.height = size.GetHeight();
925
926     mSurface->MoveResize( positionSize );
927
928     mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
929
930     // Emit signal
931     mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
932
933     mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
934   }
935 }
936
937 Dali::Window::WindowSize Window::GetSize() const
938 {
939   PositionSize positionSize = mSurface->GetPositionSize();
940
941   return Dali::Window::WindowSize( positionSize.width, positionSize.height );
942 }
943
944 void Window::SetPosition( Dali::Window::WindowPosition position )
945 {
946   PositionSize positionSize = mSurface->GetPositionSize();
947
948   if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
949   {
950     positionSize.x = position.GetX();
951     positionSize.y = position.GetY();
952
953     mSurface->MoveResize( positionSize );
954   }
955 }
956
957 Dali::Window::WindowPosition Window::GetPosition() const
958 {
959   PositionSize positionSize = mSurface->GetPositionSize();
960
961   return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
962 }
963
964 void Window::SetTransparency( bool transparent )
965 {
966 }
967
968 } // Adaptor
969
970 } // Internal
971
972 } // Dali
973
974 #pragma GCC diagnostic pop