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