Merge "Remove non-public APIs of Animation" into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / window-impl-x.cpp
1 /*
2  * Copyright (c) 2014 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 <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( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY,  EcoreEventWindowPropertyChanged, this ) ),
67     mClientMessagehandler( ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, this ) ),
68     mEcoreWindow( 0 )
69   {
70     // store ecore window handle
71     ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
72     if( x11Window )
73     {
74       mEcoreWindow = x11Window->GetXWindow();
75     }
76     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore x window");
77
78 #ifndef DALI_PROFILE_UBUNTU
79     // set property on window to get deiconify approve client message
80     unsigned int tmp = 1;
81     ecore_x_window_prop_card32_set(mEcoreWindow,
82                              ECORE_X_ATOM_E_DEICONIFY_APPROVE,
83                              &tmp, 1);
84 #endif // DALI_PROFILE_UBUNTU
85
86     ecore_x_input_multi_select( mEcoreWindow );
87   }
88
89   /**
90    * Destructor
91    */
92   ~EventHandler()
93   {
94     if ( mWindowPropertyHandler )
95     {
96       ecore_event_handler_del( mWindowPropertyHandler );
97     }
98     if ( mClientMessagehandler )
99     {
100       ecore_event_handler_del( mClientMessagehandler );
101     }
102   }
103
104   // Static methods
105
106   /// Called when the window properties are changed.
107   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
108   {
109     Ecore_X_Event_Window_Property* propertyChangedEvent( (Ecore_X_Event_Window_Property*)event );
110     EventHandler* handler( (EventHandler*)data );
111     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
112
113     if ( handler && handler->mWindow )
114     {
115       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
116       if ( observer && ( propertyChangedEvent->win == handler->mEcoreWindow ) )
117       {
118         Ecore_X_Window_State_Hint state( ecore_x_icccm_state_get( propertyChangedEvent->win ) );
119
120         switch ( state )
121         {
122           case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN:
123           {
124             // Window was hidden.
125             observer->OnWindowHidden();
126             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Withdrawn\n", handler->mEcoreWindow );
127             handled = ECORE_CALLBACK_DONE;
128           }
129           break;
130
131           case ECORE_X_WINDOW_STATE_HINT_ICONIC:
132           {
133             // Window was iconified (minimised).
134             observer->OnWindowHidden();
135             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Iconfied\n", handler->mEcoreWindow );
136             handled = ECORE_CALLBACK_DONE;
137           }
138           break;
139
140           case ECORE_X_WINDOW_STATE_HINT_NORMAL:
141           {
142             // Window was shown.
143             observer->OnWindowShown();
144             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Shown\n", handler->mEcoreWindow );
145             handled = ECORE_CALLBACK_DONE;
146           }
147           break;
148
149           default:
150             // Ignore
151             break;
152         }
153       }
154     }
155
156     return handled;
157   }
158
159   /// Called when the window properties are changed.
160   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
161   {
162     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
163 #ifndef DALI_PROFILE_UBUNTU
164     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
165     EventHandler* handler( (EventHandler*)data );
166
167     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
168     {
169       ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
170       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
171
172       if ( observer && ( (unsigned int)clientMessageEvent->data.l[0] == handler->mEcoreWindow ) )
173       {
174         if (clientMessageEvent->data.l[1] == 0) //wm sends request message using value 0
175         {
176           observer->OnWindowShown();
177
178           // request to approve the deiconify. render-surface should send proper event after real rendering
179           if(x11Window)
180           {
181             x11Window->RequestToApproveDeiconify();
182           }
183
184           handled = ECORE_CALLBACK_DONE;
185         }
186       }
187     }
188 #endif // DALI_PROFILE_UBUNTU
189
190     return handled;
191   }
192
193   // Data
194   Window* mWindow;
195   Ecore_Event_Handler* mWindowPropertyHandler;
196   Ecore_Event_Handler* mClientMessagehandler;
197   Ecore_X_Window mEcoreWindow;
198 };
199
200
201 Window* Window::New(const PositionSize& posSize, const std::string& name, bool isTransparent)
202 {
203   Window* window = new Window();
204   window->mIsTransparent = isTransparent;
205   window->Initialize(posSize, name);
206   return window;
207 }
208
209 void Window::SetAdaptor(Dali::Adaptor& adaptor)
210 {
211   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
212   mStarted = true;
213
214   // Only create one overlay per window
215   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
216   Integration::Core& core = adaptorImpl.GetCore();
217   mOverlay = &core.GetSystemOverlay();
218
219   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
220   taskList.CreateTask();
221
222   mAdaptor = &adaptorImpl;
223   mAdaptor->AddObserver( *this );
224
225   // Can only create the detector when we know the Core has been instantiated.
226   mDragAndDropDetector = DragAndDropDetector::New();
227   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
228
229   if( mOrientation )
230   {
231     mOrientation->SetAdaptor(adaptor);
232   }
233
234   if( mIndicator != NULL )
235   {
236     mIndicator->SetAdaptor(mAdaptor);
237   }
238 }
239
240 RenderSurface* Window::GetSurface()
241 {
242   return mSurface;
243 }
244
245 void Window::SetIndicatorStyle( Dali::Window::IndicatorStyle style )
246 {
247   mIndicatorStyle = style;
248 }
249
250 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
251 {
252   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
253   DALI_ASSERT_DEBUG(mOverlay);
254
255   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
256   DALI_ASSERT_DEBUG(x11Window);
257   Ecore_X_Window xWinId = x11Window->GetXWindow();
258
259   mIndicatorVisible = visibleMode;
260
261   if ( mIndicatorVisible == Dali::Window::VISIBLE )
262   {
263     // when the indicator is visible, set proper mode for indicator server according to bg mode
264     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
265     {
266       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
267     }
268     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
269     {
270       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
271     }
272 #if defined(DALI_PROFILE_MOBILE)
273     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
274     {
275       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
276     }
277 #endif
278   }
279   else
280   {
281     // when the indicator is not visible, set TRANSPARENT mode for indicator server
282     ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); // it means hidden indicator
283   }
284
285   DoShowIndicator( mIndicatorOrientation );
286 }
287
288 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
289 {
290   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
291
292   DoRotateIndicator( orientation );
293 }
294
295 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
296 {
297   mIndicatorOpacityMode = opacityMode;
298
299   if( mIndicator != NULL )
300   {
301     mIndicator->SetOpacityMode( opacityMode );
302   }
303 }
304
305 void Window::SetClass(std::string name, std::string klass)
306 {
307   // Get render surface's x11 window
308   if( mSurface )
309   {
310     ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
311     if( x11Window )
312     {
313       ecore_x_icccm_name_class_set( x11Window->GetXWindow(), name.c_str(), klass.c_str() );
314     }
315   }
316 }
317
318 Window::Window()
319 : mSurface(NULL),
320   mIndicatorStyle(Dali::Window::CHANGEABLE_COLOR),
321   mIndicatorVisible(Dali::Window::INVISIBLE),
322   mIndicatorIsShown(false),
323   mShowRotatedIndicatorOnClose(false),
324   mStarted(false),
325   mIsTransparent(false),
326   mWMRotationAppSet(false),
327   mIndicator(NULL),
328   mIndicatorOrientation(Dali::Window::PORTRAIT),
329   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
330   mIndicatorOpacityMode(Dali::Window::OPAQUE),
331   mOverlay(NULL),
332   mAdaptor(NULL),
333   mEventHandler(NULL),
334   mPreferredOrientation(Dali::Window::PORTRAIT)
335 {
336 }
337
338 Window::~Window()
339 {
340   delete mEventHandler;
341
342   if( mIndicator )
343   {
344     mOverlay->Remove( mIndicator->GetActor() );
345     Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
346     Dali::RenderTask indicatorTask = taskList.GetTask(0);
347     mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
348     mIndicator->Close();
349     delete mIndicator;
350   }
351
352   if( mAdaptor )
353   {
354     mAdaptor->RemoveObserver( *this );
355     mAdaptor->SetDragAndDropDetector( NULL );
356     mAdaptor = NULL;
357   }
358
359   delete mSurface;
360 }
361
362 void Window::Initialize(const PositionSize& windowPosition, const std::string& name)
363 {
364   // create an X11 window by default
365   Any surface;
366   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, mIsTransparent );
367   windowSurface->Map();
368
369   mSurface = windowSurface;
370
371   mOrientation = Orientation::New(this);
372
373   // create event handler for X11 window
374   mEventHandler = new EventHandler( this );
375 }
376
377 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
378 {
379   if( mIndicator == NULL )
380   {
381     if( mIndicatorVisible != Dali::Window::INVISIBLE )
382     {
383       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, mIndicatorStyle, this );
384       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
385       Dali::Actor actor = mIndicator->GetActor();
386       SetIndicatorActorRotation();
387       mOverlay->Add(actor);
388     }
389     // else don't create a hidden indicator
390   }
391   else // Already have indicator
392   {
393     if( mIndicatorVisible == Dali::Window::VISIBLE )
394     {
395       // If we are resuming, and rotation has changed,
396       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
397       {
398         // then close current indicator and open new one
399         mShowRotatedIndicatorOnClose = true;
400         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
401         // Don't show actor - will contain indicator for old orientation.
402       }
403     }
404   }
405
406   // set indicator visible mode
407   if( mIndicator != NULL )
408   {
409     mIndicator->SetVisible( mIndicatorVisible );
410   }
411
412   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
413   SetIndicatorProperties( show, lastOrientation );
414   mIndicatorIsShown = show;
415 }
416
417 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
418 {
419   if( mIndicatorIsShown )
420   {
421     mShowRotatedIndicatorOnClose = true;
422     mNextIndicatorOrientation = orientation;
423     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
424   }
425   else
426   {
427     // Save orientation for when the indicator is next shown
428     mShowRotatedIndicatorOnClose = false;
429     mNextIndicatorOrientation = orientation;
430   }
431 }
432
433 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
434 {
435   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
436   if( x11Window )
437   {
438     Ecore_X_Window win = x11Window->GetXWindow();
439
440     int show_state = static_cast<int>( isShow );
441     ecore_x_window_prop_property_set( win,
442                                       ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
443                                       ECORE_X_ATOM_CARDINAL, 32, &show_state, 1);
444
445     if ( isShow )
446     {
447       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_ON);
448     }
449     else
450     {
451       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
452     }
453   }
454 }
455
456 void Window::IndicatorTypeChanged(Indicator::Type type)
457 {
458   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
459   if( x11Window )
460   {
461 #ifndef DALI_PROFILE_UBUNTU
462     Ecore_X_Window win = x11Window->GetXWindow();
463     switch(type)
464     {
465       case Indicator::INDICATOR_TYPE_1:
466         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_1 );
467         break;
468
469       case Indicator::INDICATOR_TYPE_2:
470         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_2 );
471         break;
472
473       case Indicator::INDICATOR_TYPE_UNKNOWN:
474       default:
475         break;
476     }
477 #endif // DALI_PROFILE_UBUNTU
478   }
479 }
480
481 void Window::IndicatorClosed( Indicator* indicator )
482 {
483   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
484
485   if( mShowRotatedIndicatorOnClose )
486   {
487     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
488     mIndicator->Open(mNextIndicatorOrientation);
489     mIndicatorOrientation = mNextIndicatorOrientation;
490     SetIndicatorActorRotation();
491     DoShowIndicator(currentOrientation);
492   }
493 }
494
495 void Window::IndicatorVisibilityChanged(bool isVisible)
496 {
497   mIndicatorVisibilityChangedSignal.Emit(isVisible);
498 }
499
500 void Window::SetIndicatorActorRotation()
501 {
502   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
503   DALI_ASSERT_DEBUG( mIndicator != NULL );
504
505   Dali::Actor actor = mIndicator->GetActor();
506   switch( mIndicatorOrientation )
507   {
508     case Dali::Window::PORTRAIT:
509       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
510       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
511       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
512       break;
513     case Dali::Window::PORTRAIT_INVERSE:
514       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
515       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
516       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
517       break;
518     case Dali::Window::LANDSCAPE:
519       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
520       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
521       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
522       break;
523     case Dali::Window::LANDSCAPE_INVERSE:
524       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
525       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
526       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
527       break;
528   }
529 }
530
531 void Window::Raise()
532 {
533   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
534   if( x11Window )
535   {
536     Ecore_X_Window win = x11Window->GetXWindow();
537     ecore_x_window_raise(win);
538   }
539 }
540
541 void Window::Lower()
542 {
543   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
544   if( x11Window )
545   {
546     Ecore_X_Window win = x11Window->GetXWindow();
547     ecore_x_window_lower(win);
548   }
549 }
550
551 void Window::Activate()
552 {
553   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
554   if( x11Window )
555   {
556     Ecore_X_Window win = x11Window->GetXWindow();
557     ecore_x_netwm_client_active_request(ecore_x_window_root_get(win), win, 1 /* request type, 1:application, 2:pager */, 0);
558   }
559 }
560
561 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
562 {
563   return mDragAndDropDetector;
564 }
565
566 Dali::Any Window::GetNativeHandle() const
567 {
568   if(mEventHandler)
569   {
570     return mEventHandler->mEcoreWindow;
571   }
572   else
573   {
574     return Dali::Any();
575   }
576 }
577
578 void Window::OnStart()
579 {
580   ShowIndicator( mIndicatorVisible );
581 }
582
583 void Window::OnPause()
584 {
585 }
586
587 void Window::OnResume()
588 {
589   // resume indicator status
590   if( mIndicator != NULL )
591   {
592     // Restore own indicator opacity
593     // Send opacity mode to indicator service when app resumed
594     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
595   }
596 }
597
598 void Window::OnStop()
599 {
600   if( mIndicator )
601   {
602     mIndicator->Close();
603   }
604
605   delete mIndicator;
606   mIndicator = NULL;
607 }
608
609 void Window::OnDestroy()
610 {
611   mAdaptor = NULL;
612 }
613
614 OrientationPtr Window::GetOrientation()
615 {
616   return mOrientation;
617 }
618
619 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
620 {
621   bool found = false;
622
623   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
624   {
625     if(mAvailableOrientations[i] == orientation)
626     {
627       found = true;
628       break;
629     }
630   }
631
632   if( ! found )
633   {
634     mAvailableOrientations.push_back(orientation);
635     SetAvailableOrientations( mAvailableOrientations );
636   }
637 }
638
639 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
640 {
641   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
642        iter != mAvailableOrientations.end(); ++iter )
643   {
644     if( *iter == orientation )
645     {
646       mAvailableOrientations.erase( iter );
647       break;
648     }
649   }
650   SetAvailableOrientations( mAvailableOrientations );
651 }
652
653 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
654 {
655   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
656
657   mAvailableOrientations = orientations;
658   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
659   if( x11Window )
660   {
661 #ifndef DALI_PROFILE_UBUNTU
662     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
663     if( ! mWMRotationAppSet )
664     {
665       mWMRotationAppSet = true;
666       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
667     }
668
669     int rotations[4];
670     for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
671     {
672       rotations[i] = static_cast<int>(mAvailableOrientations[i]);
673     }
674     ecore_x_e_window_rotation_available_rotations_set(ecoreWindow, rotations, mAvailableOrientations.size() );
675 #endif // DALI_PROFILE_UBUNTU
676   }
677 }
678
679 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
680 {
681   return mAvailableOrientations;
682 }
683
684 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
685 {
686   mPreferredOrientation = orientation;
687
688   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
689   if( x11Window )
690   {
691 #ifndef DALI_PROFILE_UBUNTU
692     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
693
694     if( ! mWMRotationAppSet )
695     {
696       mWMRotationAppSet = true;
697       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
698     }
699
700     ecore_x_e_window_rotation_preferred_rotation_set(ecoreWindow, orientation);
701 #endif // DALI_PROFILE_UBUNTU
702   }
703 }
704
705 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
706 {
707   return mPreferredOrientation;
708 }
709
710 void Window::RotationDone( int orientation, int width, int height )
711 {
712   // Tell window manager we're done
713   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
714   if( x11Window )
715   {
716 #ifndef DALI_PROFILE_UBUNTU
717     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
718     Ecore_X_Window root = ecore_x_window_root_get(ecoreWindow);
719
720     /**
721      * send rotation done message to wm, even if window is already rotated.
722      * that's why wm must be wait for comming rotation done message
723      * after sending rotation request.
724      */
725     ecore_x_e_window_rotation_change_done_send(root, ecoreWindow, orientation, width, height);
726
727     /**
728      * set rotate window property
729      */
730     int angles[2] = { orientation, orientation };
731     ecore_x_window_prop_property_set( ecoreWindow,
732                                      ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
733                                      ECORE_X_ATOM_CARDINAL, 32, &angles, 2 );
734 #endif // DALI_PROFILE_UBUNTU
735   }
736 }
737
738
739 } // Adaptor
740 } // Internal
741 } // Dali