Revert "[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 // Ecore is littered with C style cast
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #include <Ecore.h>
26 #include <Ecore_X.h>
27
28 #include <dali/integration-api/core.h>
29 #include <dali/integration-api/system-overlay.h>
30 #include <dali/public-api/render-tasks/render-task.h>
31 #include <dali/public-api/render-tasks/render-task-list.h>
32
33 // INTERNAL HEADERS
34 #include <window-render-surface.h>
35 #include <drag-and-drop-detector-impl.h>
36 #include <ecore-indicator-impl.h>
37 #include <window-visibility-observer.h>
38 #include <orientation.h>
39 #include <orientation-impl.h>
40
41 namespace
42 {
43 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
44 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
45 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
46 }
47
48 namespace Dali
49 {
50 namespace Internal
51 {
52 namespace Adaptor
53 {
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_WINDOW");
56 #endif
57
58 /**
59  * TODO: Abstract Window class out and move this into a window implementation for Ecore
60  */
61 struct Window::EventHandler
62 {
63   /**
64    * Constructor
65    * @param[in]  window  A pointer to the window class.
66    */
67   EventHandler( Window* window )
68   : mWindow( window ),
69     mWindowPropertyHandler( NULL ),
70     mClientMessagehandler( NULL ),
71     mWindowDeleteRequestHandler( NULL ),
72     mEcoreWindow( 0 )
73   {
74     // store ecore window handle
75     ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
76     if( x11Window )
77     {
78       mEcoreWindow = x11Window->GetXWindow();
79     }
80     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore x window");
81
82 #ifndef DALI_PROFILE_UBUNTU
83     // set property on window to get deiconify approve client message
84     unsigned int tmp = 1;
85     ecore_x_window_prop_card32_set(mEcoreWindow,
86                              ECORE_X_ATOM_E_DEICONIFY_APPROVE,
87                              &tmp, 1);
88 #endif // DALI_PROFILE_UBUNTU
89
90     if( mWindow->mEcoreEventHander )
91     {
92       ecore_x_input_multi_select( mEcoreWindow );
93
94       // This ensures that we catch the window close (or delete) request
95       ecore_x_icccm_protocol_set( mEcoreWindow, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE );
96
97       mWindowPropertyHandler=  ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY,  EcoreEventWindowPropertyChanged, this );
98       mClientMessagehandler =  ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, this );
99       mWindowDeleteRequestHandler = ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest, this );
100     }
101   }
102
103   /**
104    * Destructor
105    */
106   ~EventHandler()
107   {
108     if ( mWindowPropertyHandler )
109     {
110       ecore_event_handler_del( mWindowPropertyHandler );
111     }
112     if ( mClientMessagehandler )
113     {
114       ecore_event_handler_del( mClientMessagehandler );
115     }
116     if ( mWindowDeleteRequestHandler )
117     {
118       ecore_event_handler_del( mWindowDeleteRequestHandler );
119     }
120   }
121
122   // Static methods
123
124   /// Called when the window properties are changed.
125   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
126   {
127     Ecore_X_Event_Window_Property* propertyChangedEvent( (Ecore_X_Event_Window_Property*)event );
128     EventHandler* handler( (EventHandler*)data );
129     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
130
131     if ( handler && handler->mWindow )
132     {
133       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
134       if ( observer && ( propertyChangedEvent->win == handler->mEcoreWindow ) )
135       {
136         Ecore_X_Window_State_Hint state( ecore_x_icccm_state_get( propertyChangedEvent->win ) );
137
138         switch ( state )
139         {
140           case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN:
141           {
142             // Window was hidden.
143             observer->OnWindowHidden();
144             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Withdrawn\n", handler->mEcoreWindow );
145             handled = ECORE_CALLBACK_DONE;
146           }
147           break;
148
149           case ECORE_X_WINDOW_STATE_HINT_ICONIC:
150           {
151             // Window was iconified (minimised).
152             observer->OnWindowHidden();
153             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Iconfied\n", handler->mEcoreWindow );
154             handled = ECORE_CALLBACK_DONE;
155           }
156           break;
157
158           case ECORE_X_WINDOW_STATE_HINT_NORMAL:
159           {
160             // Window was shown.
161             observer->OnWindowShown();
162             DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Shown\n", handler->mEcoreWindow );
163             handled = ECORE_CALLBACK_DONE;
164           }
165           break;
166
167           default:
168             // Ignore
169             break;
170         }
171       }
172     }
173
174     return handled;
175   }
176
177   /// Called when the window properties are changed.
178   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
179   {
180     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
181 #ifndef DALI_PROFILE_UBUNTU
182     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
183     EventHandler* handler( (EventHandler*)data );
184
185     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
186     {
187       ECore::WindowRenderSurface* x11Window( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
188       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
189
190       if ( observer && ( (unsigned int)clientMessageEvent->data.l[0] == handler->mEcoreWindow ) )
191       {
192         if (clientMessageEvent->data.l[1] == 0) //wm sends request message using value 0
193         {
194           observer->OnWindowShown();
195
196           // request to approve the deiconify. render-surface should send proper event after real rendering
197           if(x11Window)
198           {
199             x11Window->RequestToApproveDeiconify();
200           }
201
202           handled = ECORE_CALLBACK_DONE;
203         }
204       }
205     }
206 #endif // DALI_PROFILE_UBUNTU
207
208     return handled;
209   }
210
211   /// Called when the window receives a delete request
212   static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* event )
213   {
214     EventHandler* handler( (EventHandler*)data );
215     handler->mWindow->mDeleteRequestSignal.Emit();
216     return ECORE_CALLBACK_DONE;
217   }
218
219   // Data
220   Window* mWindow;
221   Ecore_Event_Handler* mWindowPropertyHandler;
222   Ecore_Event_Handler* mClientMessagehandler;
223   Ecore_Event_Handler* mWindowDeleteRequestHandler;
224   Ecore_X_Window mEcoreWindow;
225 };
226
227
228 Window* Window::New(const PositionSize& posSize, const std::string& name, const std::string& className, bool isTransparent)
229 {
230   Window* window = new Window();
231   window->mIsTransparent = isTransparent;
232   window->Initialize(posSize, name, className);
233   return window;
234 }
235
236 void Window::SetAdaptor(Dali::Adaptor& adaptor)
237 {
238   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
239   mStarted = true;
240
241   // Only create one overlay per window
242   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
243   Integration::Core& core = adaptorImpl.GetCore();
244   mOverlay = &core.GetSystemOverlay();
245
246   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
247   taskList.CreateTask();
248
249   mAdaptor = &adaptorImpl;
250   mAdaptor->AddObserver( *this );
251
252   // Can only create the detector when we know the Core has been instantiated.
253   mDragAndDropDetector = DragAndDropDetector::New();
254   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
255
256   if( mOrientation )
257   {
258     mOrientation->SetAdaptor(adaptor);
259   }
260
261   if( mIndicator != NULL )
262   {
263     mIndicator->SetAdaptor(mAdaptor);
264   }
265 }
266
267 RenderSurface* Window::GetSurface()
268 {
269   return mSurface;
270 }
271
272 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
273 {
274   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
275   DALI_ASSERT_DEBUG(mOverlay);
276
277   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
278   DALI_ASSERT_DEBUG(x11Window);
279   Ecore_X_Window xWinId = x11Window->GetXWindow();
280
281   mIndicatorVisible = visibleMode;
282
283   if ( mIndicatorVisible == Dali::Window::VISIBLE )
284   {
285     // when the indicator is visible, set proper mode for indicator server according to bg mode
286     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
287     {
288       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
289     }
290     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
291     {
292       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT);
293     }
294 #if defined(DALI_PROFILE_MOBILE)
295     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
296     {
297       ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_OPAQUE);
298     }
299 #endif
300   }
301   else
302   {
303     // when the indicator is not visible, set TRANSPARENT mode for indicator server
304     ecore_x_e_illume_indicator_opacity_set(xWinId, ECORE_X_ILLUME_INDICATOR_TRANSPARENT); // it means hidden indicator
305   }
306
307   DoShowIndicator( mIndicatorOrientation );
308 }
309
310 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
311 {
312   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
313
314   DoRotateIndicator( orientation );
315 }
316
317 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
318 {
319   mIndicatorOpacityMode = opacityMode;
320
321   if( mIndicator != NULL )
322   {
323     mIndicator->SetOpacityMode( opacityMode );
324   }
325 }
326
327 void Window::SetClass(std::string name, std::string klass)
328 {
329   // Get render surface's x11 window
330   if( mSurface )
331   {
332     ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
333     if( x11Window )
334     {
335       ecore_x_icccm_name_class_set( x11Window->GetXWindow(), name.c_str(), klass.c_str() );
336     }
337   }
338 }
339
340 Window::Window()
341 : mSurface( NULL ),
342   mIndicatorVisible( Dali::Window::INVISIBLE ),
343   mIndicatorIsShown( false ),
344   mShowRotatedIndicatorOnClose( false ),
345   mStarted( false ),
346   mIsTransparent( false ),
347   mWMRotationAppSet( false ),
348   mEcoreEventHander( true ),
349   mIsFocusAcceptable( true ),
350   mVisible( true ),
351   mOpaqueState( false ),
352   mIndicator( NULL ),
353   mIndicatorOrientation( Dali::Window::PORTRAIT ),
354   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
355   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
356   mOverlay( NULL ),
357   mAdaptor( NULL ),
358   mType( Dali::DevelWindow::NORMAL ),
359   mEventHandler( NULL ),
360   mPreferredOrientation( Dali::Window::PORTRAIT ),
361   mSupportedAuxiliaryHints(),
362   mAuxiliaryHints()
363 {
364
365   // Detect if we're not running in a ecore main loop (e.g. libuv).
366   // Typically ecore_x_init is called by app_efl_main->elm_init
367   // but if we're not using app_efl_main then we have to call it ourselves
368   // This is a hack until we create a pure X Window class
369   if( ecore_x_display_get() == NULL )
370   {
371     mEcoreEventHander = false;
372     ecore_x_init (NULL); //  internally calls _ecore_x_input_init
373   }
374
375 }
376
377 Window::~Window()
378 {
379   delete mEventHandler;
380
381   if( mIndicator )
382   {
383     mOverlay->Remove( mIndicator->GetActor() );
384     Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
385     Dali::RenderTask indicatorTask = taskList.GetTask(0);
386     mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
387     mIndicator->Close();
388     delete mIndicator;
389   }
390
391   if( mAdaptor )
392   {
393     mAdaptor->RemoveObserver( *this );
394     mAdaptor->SetDragAndDropDetector( NULL );
395     mAdaptor = NULL;
396   }
397
398   delete mSurface;
399 }
400
401 void Window::Initialize(const PositionSize& windowPosition, const std::string& name, const std::string& className)
402 {
403   // create an X11 window by default
404   Any surface;
405   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, className, mIsTransparent );
406   windowSurface->Map();
407
408   mSurface = windowSurface;
409
410   mOrientation = Orientation::New(this);
411
412   // create event handler for X11 window
413   mEventHandler = new EventHandler( this );
414 }
415
416 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
417 {
418   if( mIndicator == NULL )
419   {
420     if( mIndicatorVisible != Dali::Window::INVISIBLE )
421     {
422       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
423       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
424       Dali::Actor actor = mIndicator->GetActor();
425       SetIndicatorActorRotation();
426       mOverlay->Add(actor);
427     }
428     // else don't create a hidden indicator
429   }
430   else // Already have indicator
431   {
432     if( mIndicatorVisible == Dali::Window::VISIBLE )
433     {
434       // If we are resuming, and rotation has changed,
435       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
436       {
437         // then close current indicator and open new one
438         mShowRotatedIndicatorOnClose = true;
439         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
440         // Don't show actor - will contain indicator for old orientation.
441       }
442     }
443   }
444
445   // set indicator visible mode
446   if( mIndicator != NULL )
447   {
448     mIndicator->SetVisible( mIndicatorVisible );
449   }
450
451   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
452   SetIndicatorProperties( show, lastOrientation );
453   mIndicatorIsShown = show;
454 }
455
456 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
457 {
458   if( mIndicatorIsShown )
459   {
460     mShowRotatedIndicatorOnClose = true;
461     mNextIndicatorOrientation = orientation;
462     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
463   }
464   else
465   {
466     // Save orientation for when the indicator is next shown
467     mShowRotatedIndicatorOnClose = false;
468     mNextIndicatorOrientation = orientation;
469   }
470 }
471
472 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
473 {
474   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
475   if( x11Window )
476   {
477     Ecore_X_Window win = x11Window->GetXWindow();
478
479     int show_state = static_cast<int>( isShow );
480     ecore_x_window_prop_property_set( win,
481                                       ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
482                                       ECORE_X_ATOM_CARDINAL, 32, &show_state, 1);
483
484     if ( isShow )
485     {
486       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_ON);
487     }
488     else
489     {
490       ecore_x_e_illume_indicator_state_set(win, ECORE_X_ILLUME_INDICATOR_STATE_OFF);
491     }
492   }
493 }
494
495 void Window::IndicatorTypeChanged(Indicator::Type type)
496 {
497   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
498   if( x11Window )
499   {
500 #ifndef DALI_PROFILE_UBUNTU
501     Ecore_X_Window win = x11Window->GetXWindow();
502     switch(type)
503     {
504       case Indicator::INDICATOR_TYPE_1:
505         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_1 );
506         break;
507
508       case Indicator::INDICATOR_TYPE_2:
509         ecore_x_e_illume_indicator_type_set( win, ECORE_X_ILLUME_INDICATOR_TYPE_2 );
510         break;
511
512       case Indicator::INDICATOR_TYPE_UNKNOWN:
513       default:
514         break;
515     }
516 #endif // DALI_PROFILE_UBUNTU
517   }
518 }
519
520 void Window::IndicatorClosed( IndicatorInterface* indicator )
521 {
522   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
523
524   if( mShowRotatedIndicatorOnClose )
525   {
526     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
527     mIndicator->Open(mNextIndicatorOrientation);
528     mIndicatorOrientation = mNextIndicatorOrientation;
529     SetIndicatorActorRotation();
530     DoShowIndicator(currentOrientation);
531   }
532 }
533
534 void Window::IndicatorVisibilityChanged(bool isVisible)
535 {
536   mIndicatorVisibilityChangedSignal.Emit(isVisible);
537 }
538
539 void Window::SetIndicatorActorRotation()
540 {
541   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
542   DALI_ASSERT_DEBUG( mIndicator != NULL );
543
544   Dali::Actor actor = mIndicator->GetActor();
545   switch( mIndicatorOrientation )
546   {
547     case Dali::Window::PORTRAIT:
548       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
549       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
550       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
551       break;
552     case Dali::Window::PORTRAIT_INVERSE:
553       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
554       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
555       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
556       break;
557     case Dali::Window::LANDSCAPE:
558       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
559       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
560       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
561       break;
562     case Dali::Window::LANDSCAPE_INVERSE:
563       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
564       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
565       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
566       break;
567   }
568 }
569
570 void Window::Raise()
571 {
572   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
573   if( x11Window )
574   {
575     Ecore_X_Window win = x11Window->GetXWindow();
576     ecore_x_window_raise(win);
577   }
578 }
579
580 void Window::Lower()
581 {
582   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
583   if( x11Window )
584   {
585     Ecore_X_Window win = x11Window->GetXWindow();
586     ecore_x_window_lower(win);
587   }
588 }
589
590 void Window::Activate()
591 {
592   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
593   if( x11Window )
594   {
595     Ecore_X_Window win = x11Window->GetXWindow();
596     ecore_x_netwm_client_active_request(ecore_x_window_root_get(win), win, 1 /* request type, 1:application, 2:pager */, 0);
597   }
598 }
599
600 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
601 {
602   return mDragAndDropDetector;
603 }
604
605 Dali::Any Window::GetNativeHandle() const
606 {
607   if(mEventHandler)
608   {
609     return mEventHandler->mEcoreWindow;
610   }
611   else
612   {
613     return Dali::Any();
614   }
615 }
616
617 void Window::OnStart()
618 {
619   ShowIndicator( mIndicatorVisible );
620 }
621
622 void Window::OnPause()
623 {
624 }
625
626 void Window::OnResume()
627 {
628   // resume indicator status
629   if( mIndicator != NULL )
630   {
631     // Restore own indicator opacity
632     // Send opacity mode to indicator service when app resumed
633     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
634   }
635 }
636
637 void Window::OnStop()
638 {
639   if( mIndicator )
640   {
641     mIndicator->Close();
642   }
643
644   delete mIndicator;
645   mIndicator = NULL;
646 }
647
648 void Window::OnDestroy()
649 {
650   mAdaptor = NULL;
651 }
652
653 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
654 {
655   bool found = false;
656
657   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
658   {
659     if(mAvailableOrientations[i] == orientation)
660     {
661       found = true;
662       break;
663     }
664   }
665
666   if( ! found )
667   {
668     mAvailableOrientations.push_back(orientation);
669     SetAvailableOrientations( mAvailableOrientations );
670   }
671 }
672
673 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
674 {
675   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
676        iter != mAvailableOrientations.end(); ++iter )
677   {
678     if( *iter == orientation )
679     {
680       mAvailableOrientations.erase( iter );
681       break;
682     }
683   }
684   SetAvailableOrientations( mAvailableOrientations );
685 }
686
687 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
688 {
689   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
690
691   mAvailableOrientations = orientations;
692   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
693   if( x11Window )
694   {
695 #ifndef DALI_PROFILE_UBUNTU
696     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
697     if( ! mWMRotationAppSet )
698     {
699       mWMRotationAppSet = true;
700       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
701     }
702
703     int rotations[4];
704     for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
705     {
706       rotations[i] = static_cast<int>(mAvailableOrientations[i]);
707     }
708     ecore_x_e_window_rotation_available_rotations_set(ecoreWindow, rotations, mAvailableOrientations.size() );
709 #endif // DALI_PROFILE_UBUNTU
710   }
711 }
712
713 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
714 {
715   return mAvailableOrientations;
716 }
717
718 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
719 {
720   mPreferredOrientation = orientation;
721
722   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
723   if( x11Window )
724   {
725 #ifndef DALI_PROFILE_UBUNTU
726     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
727
728     if( ! mWMRotationAppSet )
729     {
730       mWMRotationAppSet = true;
731       ecore_x_e_window_rotation_app_set(ecoreWindow, EINA_TRUE);
732     }
733
734     ecore_x_e_window_rotation_preferred_rotation_set(ecoreWindow, orientation);
735 #endif // DALI_PROFILE_UBUNTU
736   }
737 }
738
739 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
740 {
741   return mPreferredOrientation;
742 }
743
744 void Window::SetAcceptFocus( bool accept )
745 {
746   mIsFocusAcceptable = accept;
747 }
748
749 bool Window::IsFocusAcceptable()
750 {
751   return mIsFocusAcceptable;
752 }
753
754 void Window::Show()
755 {
756   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
757   if( x11Window )
758   {
759     Ecore_X_Window win = x11Window->GetXWindow();
760     ecore_x_window_show( win );
761
762     // Need an update request
763     if( mAdaptor )
764     {
765       mAdaptor->RequestUpdateOnce();
766     }
767   }
768 }
769
770 void Window::Hide()
771 {
772   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
773   if( x11Window )
774   {
775     Ecore_X_Window win = x11Window->GetXWindow();
776     ecore_x_window_hide( win );
777   }
778 }
779
780 bool Window::IsVisible() const
781 {
782   bool visible = false;
783
784   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
785   if( x11Window )
786   {
787     Ecore_X_Window win = x11Window->GetXWindow();
788     visible = static_cast< bool >( ecore_x_window_visible_get( win ) );
789   }
790   return visible;
791 }
792
793 void Window::RotationDone( int orientation, int width, int height )
794 {
795   // Tell window manager we're done
796   ECore::WindowRenderSurface* x11Window = dynamic_cast< ECore::WindowRenderSurface * >( mSurface );
797   if( x11Window )
798   {
799 #ifndef DALI_PROFILE_UBUNTU
800     Ecore_X_Window ecoreWindow = x11Window->GetXWindow();
801     Ecore_X_Window root = ecore_x_window_root_get(ecoreWindow);
802
803     /**
804      * send rotation done message to wm, even if window is already rotated.
805      * that's why wm must be wait for comming rotation done message
806      * after sending rotation request.
807      */
808     ecore_x_e_window_rotation_change_done_send(root, ecoreWindow, orientation, width, height);
809
810     /**
811      * set rotate window property
812      */
813     int angles[2] = { orientation, orientation };
814     ecore_x_window_prop_property_set( ecoreWindow,
815                                      ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
816                                      ECORE_X_ATOM_CARDINAL, 32, &angles, 2 );
817 #endif // DALI_PROFILE_UBUNTU
818   }
819 }
820
821 unsigned int Window::GetSupportedAuxiliaryHintCount()
822 {
823   return 0;
824 }
825
826 std::string Window::GetSupportedAuxiliaryHint( unsigned int index )
827 {
828   return std::string();
829 }
830
831 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
832 {
833   return -1;
834 }
835
836 bool Window::RemoveAuxiliaryHint( unsigned int id )
837 {
838   return false;
839 }
840
841 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
842 {
843   return false;
844 }
845
846 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
847 {
848   return std::string();
849 }
850
851 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
852 {
853   return -1;
854 }
855
856 void Window::SetInputRegion( const Rect< int >& inputRegion )
857 {
858 }
859
860 void Window::SetType( Dali::DevelWindow::Type type )
861 {
862   mType = type;
863 }
864
865 Dali::DevelWindow::Type Window::GetType() const
866 {
867   return mType;
868 }
869
870 bool Window::SetNotificationLevel( Dali::DevelWindow::NotificationLevel::Type level )
871 {
872   return false;
873 }
874
875 Dali::DevelWindow::NotificationLevel::Type Window::GetNotificationLevel()
876 {
877   return Dali::DevelWindow::NotificationLevel::NONE;
878 }
879
880 void Window::SetOpaqueState( bool opaque )
881 {
882   mOpaqueState = opaque;
883 }
884
885 bool Window::IsOpaqueState()
886 {
887   return mOpaqueState;
888 }
889
890 bool Window::SetScreenMode( Dali::DevelWindow::ScreenMode::Type screenMode )
891 {
892   return false;
893 }
894
895 Dali::DevelWindow::ScreenMode::Type Window::GetScreenMode()
896 {
897   return Dali::DevelWindow::ScreenMode::DEFAULT;
898 }
899
900 bool Window::SetBrightness( int brightness )
901 {
902   return false;
903 }
904
905 int Window::GetBrightness()
906 {
907   return 0;
908 }
909
910 } // Adaptor
911
912 } // Internal
913
914 } // Dali
915
916 #pragma GCC diagnostic pop