92e6f74ffb8b59e16d7ba0da079df6a862dce86f
[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   mOpaqueState( false ),
352   mResizeEnabled( true ),
353   mIndicator( NULL ),
354   mIndicatorOrientation( Dali::Window::PORTRAIT ),
355   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
356   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
357   mOverlay( NULL ),
358   mAdaptor( NULL ),
359   mType( Dali::DevelWindow::NORMAL ),
360   mEventHandler( NULL ),
361   mPreferredOrientation( Dali::Window::PORTRAIT ),
362   mSupportedAuxiliaryHints(),
363   mAuxiliaryHints(),
364   mIndicatorVisibilityChangedSignal(),
365   mFocusChangedSignal(),
366   mResizedSignal(),
367   mDeleteRequestSignal()
368 {
369 }
370
371 Window::~Window()
372 {
373   delete mEventHandler;
374
375   if( mIndicator )
376   {
377     mOverlay->Remove( mIndicator->GetActor() );
378     Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
379     Dali::RenderTask indicatorTask = taskList.GetTask(0);
380     mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
381     mIndicator->Close();
382     delete mIndicator;
383   }
384
385   if( mAdaptor )
386   {
387     mAdaptor->RemoveObserver( *this );
388     mAdaptor->SetDragAndDropDetector( NULL );
389     mAdaptor = NULL;
390   }
391
392   delete mSurface;
393 }
394
395 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
396 {
397   // create an X11 window by default
398   Any surface;
399   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( positionSize, surface, name, className, mIsTransparent );
400   windowSurface->Map();
401
402   mSurface = windowSurface;
403
404   mOrientation = Orientation::New(this);
405
406   // create event handler for X11 window
407   mEventHandler = new EventHandler( this );
408 }
409
410 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
411 {
412   if( mIndicator == NULL )
413   {
414     if( mIndicatorVisible != Dali::Window::INVISIBLE )
415     {
416       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
417       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
418       Dali::Actor actor = mIndicator->GetActor();
419       SetIndicatorActorRotation();
420       mOverlay->Add(actor);
421     }
422     // else don't create a hidden indicator
423   }
424   else // Already have indicator
425   {
426     if( mIndicatorVisible == Dali::Window::VISIBLE )
427     {
428       // If we are resuming, and rotation has changed,
429       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
430       {
431         // then close current indicator and open new one
432         mShowRotatedIndicatorOnClose = true;
433         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
434         // Don't show actor - will contain indicator for old orientation.
435       }
436     }
437   }
438
439   // set indicator visible mode
440   if( mIndicator != NULL )
441   {
442     mIndicator->SetVisible( mIndicatorVisible );
443   }
444
445   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
446   SetIndicatorProperties( show, lastOrientation );
447   mIndicatorIsShown = show;
448 }
449
450 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
451 {
452   if( mIndicatorIsShown )
453   {
454     mShowRotatedIndicatorOnClose = true;
455     mNextIndicatorOrientation = orientation;
456     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
457   }
458   else
459   {
460     // Save orientation for when the indicator is next shown
461     mShowRotatedIndicatorOnClose = false;
462     mNextIndicatorOrientation = orientation;
463   }
464 }
465
466 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
467 {
468   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
469   if( x11Window )
470   {
471     Ecore_X_Window win = x11Window->GetXWindow();
472
473     int show_state = static_cast<int>( isShow );
474     ecore_x_window_prop_property_set( win,
475                                       ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
476                                       ECORE_X_ATOM_CARDINAL, 32, &show_state, 1);
477
478     if ( isShow )
479     {
480       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_ON);
481     }
482     else
483     {
484       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
485     }
486   }
487 }
488
489 void Window::IndicatorTypeChanged(Indicator::Type type)
490 {
491   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
492   if( x11Window )
493   {
494 #ifndef DALI_PROFILE_UBUNTU
495     Ecore_X_Window win = x11Window->GetXWindow();
496     switch(type)
497     {
498       case Indicator::INDICATOR_TYPE_1:
499         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_1 );
500         break;
501
502       case Indicator::INDICATOR_TYPE_2:
503         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_2 );
504         break;
505
506       case Indicator::INDICATOR_TYPE_UNKNOWN:
507       default:
508         break;
509     }
510 #endif // DALI_PROFILE_UBUNTU
511   }
512 }
513
514 void Window::IndicatorClosed( IndicatorInterface* indicator )
515 {
516   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
517
518   if( mShowRotatedIndicatorOnClose )
519   {
520     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
521     mIndicator->Open(mNextIndicatorOrientation);
522     mIndicatorOrientation = mNextIndicatorOrientation;
523     SetIndicatorActorRotation();
524     DoShowIndicator(currentOrientation);
525   }
526 }
527
528 void Window::IndicatorVisibilityChanged(bool isVisible)
529 {
530   mIndicatorVisibilityChangedSignal.Emit(isVisible);
531 }
532
533 void Window::SetIndicatorActorRotation()
534 {
535   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
536   DALI_ASSERT_DEBUG( mIndicator != NULL );
537
538   Dali::Actor actor = mIndicator->GetActor();
539   switch( mIndicatorOrientation )
540   {
541     case Dali::Window::PORTRAIT:
542       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
543       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
544       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
545       break;
546     case Dali::Window::PORTRAIT_INVERSE:
547       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
548       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
549       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
550       break;
551     case Dali::Window::LANDSCAPE:
552       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
553       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
554       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
555       break;
556     case Dali::Window::LANDSCAPE_INVERSE:
557       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
558       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
559       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
560       break;
561   }
562 }
563
564 void Window::Raise()
565 {
566   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
567   if( x11Window )
568   {
569     Ecore_X_Window win = x11Window->GetXWindow();
570     ecore_x_window_raise(win);
571   }
572 }
573
574 void Window::Lower()
575 {
576   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
577   if( x11Window )
578   {
579     Ecore_X_Window win = x11Window->GetXWindow();
580     ecore_x_window_lower(win);
581   }
582 }
583
584 void Window::Activate()
585 {
586   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
587   if( x11Window )
588   {
589     Ecore_X_Window win = x11Window->GetXWindow();
590     ecore_x_netwm_client_active_request(ecore_x_window_root_get(win), win, 1 /* request type, 1:application, 2:pager */, 0);
591   }
592 }
593
594 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
595 {
596   return mDragAndDropDetector;
597 }
598
599 Dali::Any Window::GetNativeHandle() const
600 {
601   if(mEventHandler)
602   {
603     return mEventHandler->mEcoreWindow;
604   }
605   else
606   {
607     return Dali::Any();
608   }
609 }
610
611 void Window::OnStart()
612 {
613   ShowIndicator( mIndicatorVisible );
614 }
615
616 void Window::OnPause()
617 {
618 }
619
620 void Window::OnResume()
621 {
622   // resume indicator status
623   if( mIndicator != NULL )
624   {
625     // Restore own indicator opacity
626     // Send opacity mode to indicator service when app resumed
627     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
628   }
629 }
630
631 void Window::OnStop()
632 {
633   if( mIndicator )
634   {
635     mIndicator->Close();
636   }
637
638   delete mIndicator;
639   mIndicator = NULL;
640 }
641
642 void Window::OnDestroy()
643 {
644   mAdaptor = NULL;
645 }
646
647 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
648 {
649   bool found = false;
650
651   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
652   {
653     if(mAvailableOrientations[i] == orientation)
654     {
655       found = true;
656       break;
657     }
658   }
659
660   if( ! found )
661   {
662     mAvailableOrientations.push_back(orientation);
663     SetAvailableOrientations( mAvailableOrientations );
664   }
665 }
666
667 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
668 {
669   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
670        iter != mAvailableOrientations.end(); ++iter )
671   {
672     if( *iter == orientation )
673     {
674       mAvailableOrientations.erase( iter );
675       break;
676     }
677   }
678   SetAvailableOrientations( mAvailableOrientations );
679 }
680
681 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
682 {
683   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
684
685   mAvailableOrientations = orientations;
686   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
687   if( x11Window )
688   {
689 #ifndef DALI_PROFILE_UBUNTU
690     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
691     if( ! mWMRotationAppSet )
692     {
693       mWMRotationAppSet = true;
694       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
695     }
696
697     int rotations[4];
698     for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
699     {
700       rotations[i] = static_cast<int>(mAvailableOrientations[i]);
701     }
702     ecore_x_e_window_rotation_available_rotations_set(ecoreWindow, rotations, mAvailableOrientations.size() );
703 #endif // DALI_PROFILE_UBUNTU
704   }
705 }
706
707 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
708 {
709   return mAvailableOrientations;
710 }
711
712 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
713 {
714   mPreferredOrientation = orientation;
715
716   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
717   if( x11Window )
718   {
719 #ifndef DALI_PROFILE_UBUNTU
720     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
721
722     if( ! mWMRotationAppSet )
723     {
724       mWMRotationAppSet = true;
725       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
726     }
727
728     ecore_x_e_window_rotation_preferred_rotation_set(ecoreWindow, orientation);
729 #endif // DALI_PROFILE_UBUNTU
730   }
731 }
732
733 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
734 {
735   return mPreferredOrientation;
736 }
737
738 void Window::SetAcceptFocus( bool accept )
739 {
740   mIsFocusAcceptable = accept;
741 }
742
743 bool Window::IsFocusAcceptable()
744 {
745   return mIsFocusAcceptable;
746 }
747
748 void Window::Show()
749 {
750   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
751   if( x11Window )
752   {
753     Ecore_X_Window win = x11Window->GetXWindow();
754     ecore_x_window_show( win );
755
756     // Need an update request
757     if( mAdaptor )
758     {
759       mAdaptor->RequestUpdateOnce();
760     }
761   }
762 }
763
764 void Window::Hide()
765 {
766   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
767   if( x11Window )
768   {
769     Ecore_X_Window win = x11Window->GetXWindow();
770     ecore_x_window_hide( win );
771   }
772 }
773
774 bool Window::IsVisible() const
775 {
776   bool visible = false;
777
778   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
779   if( x11Window )
780   {
781     Ecore_X_Window win = x11Window->GetXWindow();
782     visible = static_cast< bool >( ecore_x_window_visible_get( win ) );
783   }
784   return visible;
785 }
786
787 void Window::RotationDone( int orientation, int width, int height )
788 {
789   // Tell window manager we're done
790   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
791   if( x11Window )
792   {
793 #ifndef DALI_PROFILE_UBUNTU
794     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
795     Ecore_X_Window root = ecore_x_window_root_get(ecoreWindow);
796
797     /**
798      * send rotation done message to wm, even if window is already rotated.
799      * that's why wm must be wait for comming rotation done message
800      * after sending rotation request.
801      */
802     ecore_x_e_window_rotation_change_done_send(root, ecoreWindow, orientation, width, height);
803
804     /**
805      * set rotate window property
806      */
807     int angles[2] = { orientation, orientation };
808     ecore_x_window_prop_property_set( ecoreWindow,
809                                      ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
810                                      ECORE_X_ATOM_CARDINAL, 32, &angles, 2 );
811 #endif // DALI_PROFILE_UBUNTU
812   }
813 }
814
815 unsigned int Window::GetSupportedAuxiliaryHintCount()
816 {
817   return 0;
818 }
819
820 std::string Window::GetSupportedAuxiliaryHint( unsigned int index )
821 {
822   return std::string();
823 }
824
825 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
826 {
827   return -1;
828 }
829
830 bool Window::RemoveAuxiliaryHint( unsigned int id )
831 {
832   return false;
833 }
834
835 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
836 {
837   return false;
838 }
839
840 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
841 {
842   return std::string();
843 }
844
845 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
846 {
847   return -1;
848 }
849
850 void Window::SetInputRegion( const Rect< int >& inputRegion )
851 {
852 }
853
854 void Window::SetType( Dali::DevelWindow::Type type )
855 {
856   mType = type;
857 }
858
859 Dali::DevelWindow::Type Window::GetType() const
860 {
861   return mType;
862 }
863
864 bool Window::SetNotificationLevel( Dali::DevelWindow::NotificationLevel::Type level )
865 {
866   return false;
867 }
868
869 Dali::DevelWindow::NotificationLevel::Type Window::GetNotificationLevel()
870 {
871   return Dali::DevelWindow::NotificationLevel::NONE;
872 }
873
874 void Window::SetOpaqueState( bool opaque )
875 {
876   mOpaqueState = opaque;
877 }
878
879 bool Window::IsOpaqueState()
880 {
881   return mOpaqueState;
882 }
883
884 bool Window::SetScreenMode( Dali::DevelWindow::ScreenMode::Type screenMode )
885 {
886   return false;
887 }
888
889 Dali::DevelWindow::ScreenMode::Type Window::GetScreenMode()
890 {
891   return Dali::DevelWindow::ScreenMode::DEFAULT;
892 }
893
894 bool Window::SetBrightness( int brightness )
895 {
896   return false;
897 }
898
899 int Window::GetBrightness()
900 {
901   return 0;
902 }
903
904 void Window::SetSize( Dali::DevelWindow::WindowSize size )
905 {
906   PositionSize positionSize = mSurface->GetPositionSize();
907
908   if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
909   {
910     positionSize.width = size.GetWidth();
911     positionSize.height = size.GetHeight();
912
913     mSurface->MoveResize( positionSize );
914
915     mAdaptor->SurfaceSizeChanged( Dali::Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
916
917     // Emit signal
918     mResizedSignal.Emit( Dali::DevelWindow::WindowSize( positionSize.width, positionSize.height ) );
919   }
920 }
921
922 Dali::DevelWindow::WindowSize Window::GetSize()
923 {
924   PositionSize positionSize = mSurface->GetPositionSize();
925
926   return Dali::DevelWindow::WindowSize( positionSize.width, positionSize.height );
927 }
928
929 void Window::SetPosition( Dali::DevelWindow::WindowPosition position )
930 {
931   PositionSize positionSize = mSurface->GetPositionSize();
932
933   if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
934   {
935     positionSize.x = position.GetX();
936     positionSize.y = position.GetY();
937
938     mSurface->MoveResize( positionSize );
939   }
940 }
941
942 Dali::DevelWindow::WindowPosition Window::GetPosition()
943 {
944   PositionSize positionSize = mSurface->GetPositionSize();
945
946   return Dali::DevelWindow::WindowPosition( positionSize.x, positionSize.y );
947 }
948
949 void Window::SetTransparency( bool transparent )
950 {
951 }
952
953 } // Adaptor
954
955 } // Internal
956
957 } // Dali
958
959 #pragma GCC diagnostic pop