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