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