Add Window auxiliary hint APIs
[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 #include <Ecore.h>
23 #include <Ecore_X.h>
24
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/system-overlay.h>
27 #include <dali/public-api/render-tasks/render-task.h>
28 #include <dali/public-api/render-tasks/render-task-list.h>
29
30 // INTERNAL HEADERS
31 #include <window-render-surface.h>
32 #include <drag-and-drop-detector-impl.h>
33 #include <ecore-indicator-impl.h>
34 #include <window-visibility-observer.h>
35 #include <orientation.h>
36 #include <orientation-impl.h>
37
38 namespace
39 {
40 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
41 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
42 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
43 }
44
45 namespace Dali
46 {
47 namespace Internal
48 {
49 namespace Adaptor
50 {
51 #if defined(DEBUG_ENABLED)
52 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_WINDOW");
53 #endif
54
55 /**
56  * TODO: Abstract Window class out and move this into a window implementation for Ecore
57  */
58 struct Window::EventHandler
59 {
60   /**
61    * Constructor
62    * @param[in]  window  A pointer to the window class.
63    */
64   EventHandler( Window* window )
65   : mWindow( window ),
66     mWindowPropertyHandler( NULL ),
67     mClientMessagehandler( NULL ),
68     mWindowDeleteRequestHandler( NULL ),
69     mEcoreWindow( 0 )
70   {
71     // store ecore window handle
72     ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
73     if( x11Window )
74     {
75       mEcoreWindow = x11Window->GetXWindow();
76     }
77     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore x window");
78
79 #ifndef DALI_PROFILE_UBUNTU
80     // set property on window to get deiconify approve client message
81     unsigned int tmp = 1;
82     ecore_x_window_prop_card32_set(mEcoreWindow,
83                              ECORE_X_ATOM_E_DEICONIFY_APPROVE,
84                              &tmp, 1);
85 #endif // DALI_PROFILE_UBUNTU
86
87     if( mWindow->mEcoreEventHander )
88     {
89       ecore_x_input_multi_select( mEcoreWindow );
90
91       // This ensures that we catch the window close (or delete) request
92       ecore_x_icccm_protocol_set( mEcoreWindow, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE );
93
94       mWindowPropertyHandler=  ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY,  EcoreEventWindowPropertyChanged, this );
95       mClientMessagehandler =  ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, this );
96       mWindowDeleteRequestHandler = ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest, this );
97     }
98   }
99
100   /**
101    * Destructor
102    */
103   ~EventHandler()
104   {
105     if ( mWindowPropertyHandler )
106     {
107       ecore_event_handler_del( mWindowPropertyHandler );
108     }
109     if ( mClientMessagehandler )
110     {
111       ecore_event_handler_del( mClientMessagehandler );
112     }
113     if ( mWindowDeleteRequestHandler )
114     {
115       ecore_event_handler_del( mWindowDeleteRequestHandler );
116     }
117   }
118
119   // Static methods
120
121   /// Called when the window properties are changed.
122   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
123   {
124     Ecore_X_Event_Window_Property* propertyChangedEvent( (Ecore_X_Event_Window_Property*)event );
125     EventHandler* handler( (EventHandler*)data );
126     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
127
128     if ( handler && handler->mWindow )
129     {
130       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
131       if ( observer && ( propertyChangedEvent->win == handler->mEcoreWindow ) )
132       {
133         Ecore_X_Window_State_Hint state( ecore_x_icccm_state_get( propertyChangedEvent->win ) );
134
135         switch ( state )
136         {
137           case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN:
138           {
139             // Window was hidden.
140             observer->OnWindowHidden();
141             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Withdrawn\n", handler->mEcoreWindow );
142             handled = ECORE_CALLBACK_DONE;
143           }
144           break;
145
146           case ECORE_X_WINDOW_STATE_HINT_ICONIC:
147           {
148             // Window was iconified (minimised).
149             observer->OnWindowHidden();
150             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Iconfied\n", handler->mEcoreWindow );
151             handled = ECORE_CALLBACK_DONE;
152           }
153           break;
154
155           case ECORE_X_WINDOW_STATE_HINT_NORMAL:
156           {
157             // Window was shown.
158             observer->OnWindowShown();
159             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Shown\n", handler->mEcoreWindow );
160             handled = ECORE_CALLBACK_DONE;
161           }
162           break;
163
164           default:
165             // Ignore
166             break;
167         }
168       }
169     }
170
171     return handled;
172   }
173
174   /// Called when the window properties are changed.
175   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
176   {
177     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
178 #ifndef DALI_PROFILE_UBUNTU
179     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
180     EventHandler* handler( (EventHandler*)data );
181
182     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
183     {
184       ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
185       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
186
187       if ( observer && ( (unsigned int)clientMessageEvent->data.l[0] == handler->mEcoreWindow ) )
188       {
189         if (clientMessageEvent->data.l[1] == 0) //wm sends request message using value 0
190         {
191           observer->OnWindowShown();
192
193           // request to approve the deiconify. render-surface should send proper event after real rendering
194           if(x11Window)
195           {
196             x11Window->RequestToApproveDeiconify();
197           }
198
199           handled = ECORE_CALLBACK_DONE;
200         }
201       }
202     }
203 #endif // DALI_PROFILE_UBUNTU
204
205     return handled;
206   }
207
208   /// Called when the window receives a delete request
209   static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* event )
210   {
211     EventHandler* handler( (EventHandler*)data );
212     handler->mWindow->mDeleteRequestSignal.Emit();
213     return ECORE_CALLBACK_DONE;
214   }
215
216   // Data
217   Window* mWindow;
218   Ecore_Event_Handler* mWindowPropertyHandler;
219   Ecore_Event_Handler* mClientMessagehandler;
220   Ecore_Event_Handler* mWindowDeleteRequestHandler;
221   Ecore_X_Window mEcoreWindow;
222 };
223
224
225 Window* Window::New(const PositionSize& posSize, const std::string& name, const std::string& className, bool isTransparent)
226 {
227   Window* window = new Window();
228   window->mIsTransparent = isTransparent;
229   window->Initialize(posSize, name, className);
230   return window;
231 }
232
233 void Window::SetAdaptor(Dali::Adaptor& adaptor)
234 {
235   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
236   mStarted = true;
237
238   // Only create one overlay per window
239   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
240   Integration::Core& core = adaptorImpl.GetCore();
241   mOverlay = &core.GetSystemOverlay();
242
243   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
244   taskList.CreateTask();
245
246   mAdaptor = &adaptorImpl;
247   mAdaptor->AddObserver( *this );
248
249   // Can only create the detector when we know the Core has been instantiated.
250   mDragAndDropDetector = DragAndDropDetector::New();
251   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
252
253   if( mOrientation )
254   {
255     mOrientation->SetAdaptor(adaptor);
256   }
257
258   if( mIndicator != NULL )
259   {
260     mIndicator->SetAdaptor(mAdaptor);
261   }
262 }
263
264 RenderSurface* Window::GetSurface()
265 {
266   return mSurface;
267 }
268
269 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
270 {
271   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
272   DALI_ASSERT_DEBUG(mOverlay);
273
274   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
275   DALI_ASSERT_DEBUG(x11Window);
276   Ecore_X_Window xWinId = x11Window->GetXWindow();
277
278   mIndicatorVisible = visibleMode;
279
280   if ( mIndicatorVisible == Dali::Window::VISIBLE )
281   {
282     // when the indicator is visible, set proper mode for indicator server according to bg mode
283     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
284     {
285       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
286     }
287     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
288     {
289       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
290     }
291 #if defined(DALI_PROFILE_MOBILE)
292     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
293     {
294       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
295     }
296 #endif
297   }
298   else
299   {
300     // when the indicator is not visible, set TRANSPARENT mode for indicator server
301     ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); // it means hidden indicator
302   }
303
304   DoShowIndicator( mIndicatorOrientation );
305 }
306
307 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
308 {
309   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
310
311   DoRotateIndicator( orientation );
312 }
313
314 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
315 {
316   mIndicatorOpacityMode = opacityMode;
317
318   if( mIndicator != NULL )
319   {
320     mIndicator->SetOpacityMode( opacityMode );
321   }
322 }
323
324 void Window::SetClass(std::string name, std::string klass)
325 {
326   // Get render surface's x11 window
327   if( mSurface )
328   {
329     ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
330     if( x11Window )
331     {
332       ecore_x_icccm_name_class_set( x11Window->GetXWindow(), name.c_str(), klass.c_str() );
333     }
334   }
335 }
336
337 Window::Window()
338 : mSurface( NULL ),
339   mIndicatorVisible( Dali::Window::INVISIBLE ),
340   mIndicatorIsShown( false ),
341   mShowRotatedIndicatorOnClose( false ),
342   mStarted( false ),
343   mIsTransparent( false ),
344   mWMRotationAppSet( false ),
345   mEcoreEventHander( true ),
346   mIsFocusAcceptable( true ),
347   mVisible( true ),
348   mIndicator( NULL ),
349   mIndicatorOrientation( Dali::Window::PORTRAIT ),
350   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
351   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
352   mOverlay( NULL ),
353   mAdaptor( NULL ),
354   mEventHandler( NULL ),
355   mPreferredOrientation( Dali::Window::PORTRAIT ),
356   mSupportedAuxiliaryHints(),
357   mAuxiliaryHints()
358 {
359
360   // Detect if we're not running in a ecore main loop (e.g. libuv).
361   // Typically ecore_x_init is called by app_efl_main->elm_init
362   // but if we're not using app_efl_main then we have to call it ourselves
363   // This is a hack until we create a pure X Window class
364   if( ecore_x_display_get() == NULL )
365   {
366     mEcoreEventHander = false;
367     ecore_x_init (NULL); //  internally calls _ecore_x_input_init
368   }
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& windowPosition, 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( windowPosition, 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()
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 #endif // DALI_PROFILE_UBUNTU
813   }
814 }
815
816 unsigned int Window::GetSupportedAuxiliaryHintCount()
817 {
818   return 0;
819 }
820
821 std::string Window::GetSupportedAuxiliaryHint( unsigned int index )
822 {
823   return std::string();
824 }
825
826 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
827 {
828   return -1;
829 }
830
831 bool Window::RemoveAuxiliaryHint( unsigned int id )
832 {
833   return false;
834 }
835
836 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
837 {
838   return false;
839 }
840
841 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
842 {
843   return std::string();
844 }
845
846 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
847 {
848   return -1;
849 }
850
851 void Window::SetInputRegion( const Rect< int >& inputRegion )
852 {
853 }
854
855 } // Adaptor
856 } // Internal
857 } // Dali