[Tizen] ecore-wl2: applying ecore-wl2
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / tizen-wayland / ecore-wl2 / window-impl-ecore-wl2.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 <dali/internal/window-system/common/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_Wl2.h>
27 #include <tizen-extension-client-protocol.h>
28
29 #include <dali/integration-api/core.h>
30 #include <dali/integration-api/system-overlay.h>
31 #include <dali/public-api/render-tasks/render-task.h>
32 #include <dali/public-api/render-tasks/render-task-list.h>
33 #include <dali/devel-api/adaptor-framework/orientation.h>
34
35 // INTERNAL HEADERS
36 #include <dali/internal/window-system/tizen-wayland/ecore-wl2/window-render-surface-ecore-wl2.h>
37 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
38 #include <dali/internal/window-system/common/ecore-indicator-impl.h>
39 #include <dali/internal/window-system/common/window-visibility-observer.h>
40 #include <dali/internal/window-system/common/orientation-impl.h>
41
42 namespace
43 {
44
45 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
46 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
47 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
48
49 const uint32_t MAX_TIZEN_CLIENT_VERSION = 7;
50
51 }
52
53 namespace Dali
54 {
55 namespace Internal
56 {
57 namespace Adaptor
58 {
59
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_WINDOW");
62 #endif
63
64 /**
65  * TODO: Abstract Window class out and move this into a window implementation for Ecore
66  */
67 struct Window::EventHandler
68 {
69   /**
70    * Constructor
71    * @param[in]  window  A pointer to the window class.
72    */
73   EventHandler( Window* window )
74   : mWindow( window ),
75     mEcoreEventHandler(),
76     mEcoreWindow( 0 ),
77     mDisplay( NULL ),
78     mEventQueue( NULL ),
79     mTizenPolicy( NULL ),
80     mTizenDisplayPolicy( NULL ),
81     mNotificationLevel( -1 ),
82     mNotificationChangeState( 0 ),
83     mNotificationLevelChangeDone( true ),
84     mScreenOffMode( 0 ),
85     mScreenOffModeChangeState( 0 ),
86     mScreenOffModeChangeDone( true ),
87     mBrightness( 0 ),
88     mBrightnessChangeState( 0 ),
89     mBrightnessChangeDone( true )
90   {
91     // store ecore window handle
92     ECore::WindowRenderSurface* wlWindow( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
93     if( wlWindow )
94     {
95       mEcoreWindow = wlWindow->GetWlWindow();
96     }
97     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore Wl window");
98
99     if( mWindow->mEcoreEventHander )
100     {
101       mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this ) );
102       mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_IN, EcoreEventWindowFocusIn, this ) );
103       mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut, this ) );
104       mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_OUTPUT_TRANSFORM, EcoreEventOutputTransform, this) );
105       mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_WL2_EVENT_IGNORE_OUTPUT_TRANSFORM, EcoreEventIgnoreOutputTransform, this) );
106     }
107
108     Ecore_Wl2_Display *ecore_wl2_display = ecore_wl2_connected_display_get(NULL);
109     mDisplay = ecore_wl2_display_get(ecore_wl2_display);
110
111     if( mDisplay )
112     {
113       wl_display* displayWrapper = static_cast< wl_display* >( wl_proxy_create_wrapper( mDisplay ) );
114       if( displayWrapper )
115       {
116         mEventQueue = wl_display_create_queue( mDisplay );
117         if( mEventQueue )
118         {
119           wl_proxy_set_queue( reinterpret_cast< wl_proxy* >( displayWrapper ), mEventQueue );
120
121           wl_registry* registry = wl_display_get_registry( displayWrapper );
122           wl_registry_add_listener( registry, &mRegistryListener, this );
123         }
124
125         wl_proxy_wrapper_destroy( displayWrapper );
126       }
127     }
128   }
129
130   /**
131    * Destructor
132    */
133   ~EventHandler()
134   {
135     for( Dali::Vector< Ecore_Event_Handler* >::Iterator iter = mEcoreEventHandler.Begin(), endIter = mEcoreEventHandler.End(); iter != endIter; ++iter )
136     {
137       ecore_event_handler_del( *iter );
138     }
139     mEcoreEventHandler.Clear();
140
141     if( mEventQueue )
142     {
143       wl_event_queue_destroy( mEventQueue );
144     }
145   }
146
147   // Static methods
148
149   /// Called when the window iconify state is changed.
150   static Eina_Bool EcoreEventWindowIconifyStateChanged( void* data, int type, void* event )
151   {
152     Ecore_Wl2_Event_Window_Iconify_State_Change* iconifyChangedEvent( static_cast< Ecore_Wl2_Event_Window_Iconify_State_Change* >( event ) );
153     EventHandler* handler( static_cast< EventHandler* >( data ) );
154     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
155
156     if ( handler && handler->mWindow )
157     {
158       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
159       if ( observer && ( iconifyChangedEvent->win == static_cast< unsigned int> ( ecore_wl2_window_id_get( handler->mEcoreWindow ) ) ) )
160       {
161         if( iconifyChangedEvent->iconified == EINA_TRUE )
162         {
163           handler->mWindow->mIconified = true;
164           if( handler->mWindow->mVisible )
165           {
166             observer->OnWindowHidden();
167           }
168           DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", handler->mEcoreWindow);
169         }
170         else
171         {
172           handler->mWindow->mIconified = false;
173           if( handler->mWindow->mVisible )
174           {
175             observer->OnWindowShown();
176           }
177           DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", handler->mEcoreWindow );
178         }
179         handled = ECORE_CALLBACK_DONE;
180       }
181     }
182
183     return handled;
184   }
185
186   /// Called when the window gains focus
187   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
188   {
189     Ecore_Wl2_Event_Focus_In* focusInEvent( static_cast< Ecore_Wl2_Event_Focus_In* >( event ) );
190     EventHandler* handler( static_cast< EventHandler* >( data ) );
191
192     if ( handler && handler->mWindow && focusInEvent->window == static_cast< unsigned int >( ecore_wl2_window_id_get( handler->mEcoreWindow ) ) )
193     {
194       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" );
195
196       handler->mWindow->mFocusChangedSignal.Emit( true );
197     }
198
199     return ECORE_CALLBACK_PASS_ON;
200   }
201
202   /// Called when the window loses focus
203   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
204   {
205     Ecore_Wl2_Event_Focus_Out* focusOutEvent( static_cast< Ecore_Wl2_Event_Focus_Out* >( event ) );
206     EventHandler* handler( static_cast< EventHandler* >( data ) );
207
208     if ( handler && handler->mWindow && focusOutEvent->window == static_cast< unsigned int >(ecore_wl2_window_id_get( handler->mEcoreWindow ) ) )
209     {
210       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" );
211
212       handler->mWindow->mFocusChangedSignal.Emit( false );
213     }
214
215     return ECORE_CALLBACK_PASS_ON;
216   }
217
218   /// Called when the output is transformed
219   static Eina_Bool EcoreEventOutputTransform( void* data, int type, void* event )
220   {
221     Ecore_Wl2_Event_Output_Transform* transformEvent( static_cast< Ecore_Wl2_Event_Output_Transform* >( event ) );
222     EventHandler* handler( static_cast< EventHandler* >( data ) );
223
224     if ( handler && handler->mWindow && transformEvent->output == ecore_wl2_window_output_find( handler->mEcoreWindow ) )
225     {
226       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%p) EcoreEventOutputTransform\n", handler->mEcoreWindow );
227
228       ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
229       if( wlSurface )
230       {
231         wlSurface->OutputTransformed();
232
233         PositionSize positionSize = wlSurface->GetPositionSize();
234         handler->mWindow->mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
235         handler->mWindow->mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
236       }
237     }
238
239     return ECORE_CALLBACK_PASS_ON;
240   }
241
242   /// Called when the output transform should be ignored
243   static Eina_Bool EcoreEventIgnoreOutputTransform( void* data, int type, void* event )
244   {
245     Ecore_Wl2_Event_Ignore_Output_Transform* ignoreTransformEvent( static_cast< Ecore_Wl2_Event_Ignore_Output_Transform* >( event ) );
246     EventHandler* handler( static_cast< EventHandler* >( data ) );
247
248     if ( handler && handler->mWindow && ignoreTransformEvent->win == handler->mEcoreWindow )
249     {
250       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%p) EcoreEventIgnoreOutputTransform\n", handler->mEcoreWindow );
251
252       ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( handler->mWindow->mSurface ) );
253       if( wlSurface )
254       {
255         wlSurface->OutputTransformed();
256
257         PositionSize positionSize = wlSurface->GetPositionSize();
258         handler->mWindow->mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
259         handler->mWindow->mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
260       }
261     }
262
263     return ECORE_CALLBACK_PASS_ON;
264   }
265
266   static void RegistryGlobalCallback( void* data, struct wl_registry *registry, uint32_t name, const char* interface, uint32_t version )
267   {
268     Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data );
269
270     if( strcmp( interface, tizen_policy_interface.name ) == 0 )
271     {
272       uint32_t clientVersion = std::min( version, MAX_TIZEN_CLIENT_VERSION );
273
274       eventHandler->mTizenPolicy = static_cast< tizen_policy* >( wl_registry_bind( registry, name, &tizen_policy_interface, clientVersion ) );
275       if( !eventHandler->mTizenPolicy )
276       {
277         DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::RegistryGlobalCallback: wl_registry_bind(tizen_policy_interface) is failed.\n" );
278         return;
279       }
280
281       tizen_policy_add_listener( eventHandler->mTizenPolicy, &eventHandler->mTizenPolicyListener, data );
282
283       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::RegistryGlobalCallback: tizen_policy_add_listener is called.\n" );
284     }
285     else if( strcmp( interface, tizen_display_policy_interface.name ) == 0 )
286     {
287       eventHandler->mTizenDisplayPolicy = static_cast< tizen_display_policy* >( wl_registry_bind( registry, name, &tizen_display_policy_interface, version ) );
288       if( !eventHandler->mTizenDisplayPolicy )
289       {
290         DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::RegistryGlobalCallback: wl_registry_bind(tizen_display_policy_interface) is failed.\n" );
291         return;
292       }
293
294       tizen_display_policy_add_listener( eventHandler->mTizenDisplayPolicy, &eventHandler->mTizenDisplayPolicyListener, data );
295
296       DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::RegistryGlobalCallback: tizen_display_policy_add_listener is called.\n" );
297     }
298   }
299
300   static void RegistryGlobalCallbackRemove( void* data, struct wl_registry* registry, uint32_t id )
301   {
302     Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data );
303     eventHandler->mTizenPolicy = NULL;
304     eventHandler->mTizenDisplayPolicy = NULL;
305   }
306
307   static void TizenPolicyConformant( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t isConformant )
308   {
309   }
310
311   static void TizenPolicyConformantArea( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h )
312   {
313   }
314
315   static void TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state )
316   {
317     Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data );
318
319     eventHandler->mNotificationLevel = level;
320     eventHandler->mNotificationChangeState = state;
321     eventHandler->mNotificationLevelChangeDone = true;
322
323     DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::TizenPolicyNotificationChangeDone: level = %d, state = %d\n", level, state );
324   }
325
326   static void TizenPolicyTransientForDone( void* data, struct tizen_policy* tizenPolicy, uint32_t childId )
327   {
328   }
329
330   static void TizenPolicyScreenModeChangeDone( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t mode, uint32_t state )
331   {
332     Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data );
333
334     eventHandler->mScreenOffMode = mode;
335     eventHandler->mScreenOffModeChangeState = state;
336     eventHandler->mScreenOffModeChangeDone = true;
337
338     DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::TizenPolicyScreenModeChangeDone: mode = %d, state = %d\n", mode, state );
339   }
340
341   static void TizenPolicyIconifyStateChanged( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t iconified, uint32_t force )
342   {
343   }
344
345   static void TizenPolicySupportedAuxiliaryHints( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, struct wl_array* hints, uint32_t numNints )
346   {
347   }
348
349   static void TizenPolicyAllowedAuxiliaryHint( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int id )
350   {
351   }
352
353   static void TizenPolicyAuxiliaryMessage( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, const char* key, const char* val, struct wl_array* options )
354   {
355   }
356
357   static void TizenPolicyConformantRegion( void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h, uint32_t serial )
358   {
359   }
360
361   static void DisplayPolicyBrightnessChangeDone( void* data, struct tizen_display_policy *displayPolicy, struct wl_surface* surface, int32_t brightness, uint32_t state )
362   {
363     Window::EventHandler* eventHandler = static_cast< Window::EventHandler* >( data );
364
365     eventHandler->mBrightness = brightness;
366     eventHandler->mBrightnessChangeState = state;
367     eventHandler->mBrightnessChangeDone = true;
368
369     DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window::EventHandler::DisplayPolicyBrightnessChangeDone: brightness = %d, state = %d\n", brightness, state );
370   }
371
372   const struct wl_registry_listener mRegistryListener =
373   {
374      RegistryGlobalCallback,
375      RegistryGlobalCallbackRemove
376   };
377
378   const struct tizen_policy_listener mTizenPolicyListener =
379   {
380      TizenPolicyConformant,
381      TizenPolicyConformantArea,
382      TizenPolicyNotificationChangeDone,
383      TizenPolicyTransientForDone,
384      TizenPolicyScreenModeChangeDone,
385      TizenPolicyIconifyStateChanged,
386      TizenPolicySupportedAuxiliaryHints,
387      TizenPolicyAllowedAuxiliaryHint,
388      TizenPolicyAuxiliaryMessage,
389      TizenPolicyConformantRegion
390   };
391
392   const struct tizen_display_policy_listener mTizenDisplayPolicyListener =
393   {
394     DisplayPolicyBrightnessChangeDone
395   };
396
397   // Data
398   Window* mWindow;
399   Dali::Vector< Ecore_Event_Handler* > mEcoreEventHandler;
400   Ecore_Wl2_Window* mEcoreWindow;
401
402   wl_display* mDisplay;
403   wl_event_queue* mEventQueue;
404   tizen_policy* mTizenPolicy;
405   tizen_display_policy* mTizenDisplayPolicy;
406
407   int mNotificationLevel;
408   uint32_t mNotificationChangeState;
409   bool mNotificationLevelChangeDone;
410
411   int mScreenOffMode;
412   uint32_t mScreenOffModeChangeState;
413   bool mScreenOffModeChangeDone;
414
415   int mBrightness;
416   uint32_t mBrightnessChangeState;
417   bool mBrightnessChangeDone;
418 };
419
420 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
421 {
422   Window* window = new Window();
423   window->mIsTransparent = isTransparent;
424   window->Initialize( positionSize, name, className );
425   return window;
426 }
427
428 void Window::SetAdaptor(Dali::Adaptor& adaptor)
429 {
430   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
431   mStarted = true;
432
433   // Only create one overlay per window
434   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
435   Integration::Core& core = adaptorImpl.GetCore();
436   mOverlay = &core.GetSystemOverlay();
437
438   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
439   taskList.CreateTask();
440
441   mAdaptor = &adaptorImpl;
442   mAdaptor->AddObserver( *this );
443
444   // Can only create the detector when we know the Core has been instantiated.
445   mDragAndDropDetector = DragAndDropDetector::New();
446   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
447
448   if( mOrientation )
449   {
450     mOrientation->SetAdaptor(adaptor);
451   }
452
453   if( mIndicator != NULL )
454   {
455     mIndicator->SetAdaptor(mAdaptor);
456   }
457 }
458
459 RenderSurface* Window::GetSurface()
460 {
461   return mSurface;
462 }
463
464 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
465 {
466   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
467   DALI_ASSERT_DEBUG(mOverlay);
468
469   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
470   DALI_ASSERT_DEBUG(wlSurface);
471
472   if( wlSurface )
473   {
474     Ecore_Wl2_Window* wlWindow = wlSurface->GetWlWindow();
475
476     mIndicatorVisible = visibleMode;
477
478     if ( mIndicatorVisible == Dali::Window::VISIBLE )
479     {
480       // when the indicator is visible, set proper mode for indicator server according to bg mode
481       if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
482       {
483         ecore_wl2_window_indicator_opacity_set(wlWindow, ECORE_WL2_INDICATOR_OPAQUE);
484       }
485       else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
486       {
487         ecore_wl2_window_indicator_opacity_set(wlWindow, ECORE_WL2_INDICATOR_TRANSLUCENT);
488       }
489       else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
490       {
491         ecore_wl2_window_indicator_opacity_set(wlWindow, ECORE_WL2_INDICATOR_OPAQUE);
492       }
493     }
494     else
495     {
496       // when the indicator is not visible, set TRANSPARENT mode for indicator server
497       ecore_wl2_window_indicator_opacity_set(wlWindow, ECORE_WL2_INDICATOR_TRANSPARENT); // it means hidden indicator
498     }
499   }
500
501   DoShowIndicator( mIndicatorOrientation );
502 }
503
504 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
505 {
506   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
507
508   DoRotateIndicator( orientation );
509 }
510
511 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
512 {
513   mIndicatorOpacityMode = opacityMode;
514
515   if( mIndicator != NULL )
516   {
517     mIndicator->SetOpacityMode( opacityMode );
518   }
519 }
520
521 void Window::SetClass(std::string name, std::string klass)
522 {
523   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
524
525   if( wlSurface )
526   {
527     Ecore_Wl2_Window* wlWindow = wlSurface->GetWlWindow();
528     ecore_wl2_window_title_set( wlWindow, name.c_str() );
529     ecore_wl2_window_class_set( wlWindow, klass.c_str() );
530   }
531   else
532   {
533     DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window has no surface\n" );
534   }
535 }
536
537 Window::Window()
538 : mSurface( NULL ),
539   mIndicatorVisible( Dali::Window::VISIBLE ),
540   mIndicatorIsShown( false ),
541   mShowRotatedIndicatorOnClose( false ),
542   mStarted( false ),
543   mIsTransparent( false ),
544   mWMRotationAppSet( false ),
545   mEcoreEventHander( true ),
546   mIsFocusAcceptable( true ),
547   mVisible( true ),
548   mIconified( false ),
549   mOpaqueState( false ),
550   mResizeEnabled( false ),
551   mIndicator( NULL ),
552   mIndicatorOrientation( Dali::Window::PORTRAIT ),
553   mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
554   mIndicatorOpacityMode( Dali::Window::OPAQUE ),
555   mOverlay( NULL ),
556   mAdaptor( NULL ),
557   mType( Dali::Window::NORMAL ),
558   mEventHandler( NULL ),
559   mPreferredOrientation( Dali::Window::PORTRAIT ),
560   mSupportedAuxiliaryHints(),
561   mAuxiliaryHints(),
562   mIndicatorVisibilityChangedSignal(),
563   mFocusChangedSignal(),
564   mResizedSignal(),
565   mDeleteRequestSignal()
566 {
567 }
568
569 Window::~Window()
570 {
571   delete mEventHandler;
572
573   if( mIndicator )
574   {
575     mIndicator->Close();
576     delete mIndicator;
577   }
578
579   if ( mAdaptor )
580   {
581     mAdaptor->RemoveObserver( *this );
582     mAdaptor->SetDragAndDropDetector( NULL );
583     mAdaptor = NULL;
584   }
585
586   delete mSurface;
587
588   mSupportedAuxiliaryHints.clear();
589   mAuxiliaryHints.clear();
590 }
591
592 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
593 {
594   // create an Wayland window by default
595   Any surface;
596   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( positionSize, surface, name, mIsTransparent );
597
598   mSurface = windowSurface;
599
600   // create event handler for Wayland window
601   mEventHandler = new EventHandler( this );
602
603   // get auxiliary hint
604   Eina_List* hints = ecore_wl2_window_aux_hints_supported_get( mEventHandler->mEcoreWindow );
605   if( hints )
606   {
607     Eina_List* l = NULL;
608     char* hint = NULL;
609
610     for( l = hints, ( hint =  static_cast< char* >( eina_list_data_get(l) ) ); l; l = eina_list_next(l), ( hint = static_cast< char* >( eina_list_data_get(l) ) ) )
611     {
612       mSupportedAuxiliaryHints.push_back( hint );
613
614       DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::Initialize: %s\n", hint );
615     }
616   }
617
618   if( !positionSize.IsEmpty() )
619   {
620     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
621     mResizeEnabled = true;
622   }
623
624   SetClass( name, className );
625   windowSurface->Map();
626
627   mOrientation = Orientation::New(this);
628 }
629
630 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
631 {
632   if( mIndicator == NULL )
633   {
634     if( mIndicatorVisible != Dali::Window::INVISIBLE )
635     {
636       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
637       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
638       Dali::Actor actor = mIndicator->GetActor();
639       SetIndicatorActorRotation();
640       mOverlay->Add(actor);
641     }
642     // else don't create a hidden indicator
643   }
644   else // Already have indicator
645   {
646     if( mIndicatorVisible == Dali::Window::VISIBLE )
647     {
648       // If we are resuming, and rotation has changed,
649       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
650       {
651         // then close current indicator and open new one
652         mShowRotatedIndicatorOnClose = true;
653         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
654         // Don't show actor - will contain indicator for old orientation.
655       }
656     }
657   }
658
659   // set indicator visible mode
660   if( mIndicator != NULL )
661   {
662     mIndicator->SetVisible( mIndicatorVisible );
663   }
664
665   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
666   SetIndicatorProperties( show, lastOrientation );
667   mIndicatorIsShown = show;
668 }
669
670 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
671 {
672   if( mIndicatorIsShown )
673   {
674     mShowRotatedIndicatorOnClose = true;
675     mNextIndicatorOrientation = orientation;
676     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
677   }
678   else
679   {
680     // Save orientation for when the indicator is next shown
681     mShowRotatedIndicatorOnClose = false;
682     mNextIndicatorOrientation = orientation;
683   }
684 }
685
686 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
687 {
688   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
689
690   if( wlSurface )
691   {
692     Ecore_Wl2_Window* wlWindow = wlSurface->GetWlWindow();
693     if ( isShow )
694     {
695       ecore_wl2_window_indicator_state_set(wlWindow, ECORE_WL2_INDICATOR_STATE_ON);
696     }
697     else
698     {
699       ecore_wl2_window_indicator_state_set(wlWindow, ECORE_WL2_INDICATOR_STATE_OFF);
700     }
701   }
702 }
703
704 void Window::IndicatorTypeChanged(Indicator::Type type)
705 {
706 #if defined(DALI_PROFILE_MOBILE)
707   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
708
709   if( wlSurface )
710   {
711     Ecore_Wl2_Window* wlWindow = wlSurface->GetWlWindow();
712     switch(type)
713     {
714       case Indicator::INDICATOR_TYPE_1:
715         ecore_wl2_indicator_visible_type_set(wlWindow, ECORE_WL2_INDICATOR_VISIBLE_TYPE_SHOWN);
716         break;
717
718       case Indicator::INDICATOR_TYPE_2:
719         ecore_wl2_indicator_visible_type_set(wlWindow, ECORE_WL2_INDICATOR_VISIBLE_TYPE_HIDDEN);
720         break;
721
722       case Indicator::INDICATOR_TYPE_UNKNOWN:
723       default:
724         break;
725     }
726   }
727 #endif //MOBILE
728 }
729
730 void Window::IndicatorClosed( IndicatorInterface* indicator )
731 {
732   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
733
734   if( mShowRotatedIndicatorOnClose )
735   {
736     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
737     mIndicator->Open(mNextIndicatorOrientation);
738     mIndicatorOrientation = mNextIndicatorOrientation;
739     SetIndicatorActorRotation();
740     DoShowIndicator(currentOrientation);
741   }
742 }
743
744 void Window::IndicatorVisibilityChanged(bool isVisible)
745 {
746   mIndicatorVisibilityChangedSignal.Emit(isVisible);
747 }
748
749 void Window::SetIndicatorActorRotation()
750 {
751   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
752   DALI_ASSERT_DEBUG( mIndicator != NULL );
753
754   Dali::Actor actor = mIndicator->GetActor();
755   switch( mIndicatorOrientation )
756   {
757     case Dali::Window::PORTRAIT:
758       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
759       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
760       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
761       break;
762     case Dali::Window::PORTRAIT_INVERSE:
763       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
764       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
765       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
766       break;
767     case Dali::Window::LANDSCAPE:
768       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
769       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
770       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
771       break;
772     case Dali::Window::LANDSCAPE_INVERSE:
773       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
774       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
775       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
776       break;
777   }
778 }
779
780 void Window::Raise()
781 {
782   // Use ecore_wl2_window_activate to prevent the window shown without rendering
783   ecore_wl2_window_activate( mEventHandler->mEcoreWindow );
784 }
785
786 void Window::Lower()
787 {
788   ecore_wl2_window_lower( mEventHandler->mEcoreWindow );
789 }
790
791 void Window::Activate()
792 {
793   ecore_wl2_window_activate( mEventHandler->mEcoreWindow );
794 }
795
796 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
797 {
798   return mDragAndDropDetector;
799 }
800
801 Dali::Any Window::GetNativeHandle() const
802 {
803   if(mEventHandler)
804   {
805     return mEventHandler->mEcoreWindow;
806   }
807   else
808   {
809     return Dali::Any();
810   }
811 }
812
813 void Window::OnStart()
814 {
815   DoShowIndicator( mIndicatorOrientation );
816 }
817
818 void Window::OnPause()
819 {
820 }
821
822 void Window::OnResume()
823 {
824   // resume indicator status
825   if( mIndicator != NULL )
826   {
827     // Restore own indicator opacity
828     // Send opacity mode to indicator service when app resumed
829     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
830   }
831 }
832
833 void Window::OnStop()
834 {
835   if( mIndicator )
836   {
837     mIndicator->Close();
838   }
839
840   delete mIndicator;
841   mIndicator = NULL;
842 }
843
844 void Window::OnDestroy()
845 {
846   mAdaptor = NULL;
847 }
848
849 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
850 {
851   bool found = false;
852
853   if ( orientation <= Dali::Window::LANDSCAPE_INVERSE )
854   {
855     for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
856     {
857       if( mAvailableOrientations[i] == orientation )
858       {
859         found = true;
860         break;
861       }
862     }
863
864     if( ! found )
865     {
866       mAvailableOrientations.push_back(orientation);
867       SetAvailableOrientations( mAvailableOrientations );
868     }
869   }
870 }
871
872 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
873 {
874   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
875        iter != mAvailableOrientations.end(); ++iter )
876   {
877     if( *iter == orientation )
878     {
879       mAvailableOrientations.erase( iter );
880       break;
881     }
882   }
883   SetAvailableOrientations( mAvailableOrientations );
884 }
885
886 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
887 {
888   int rotations[4];
889   for( std::size_t i = 0; i < mAvailableOrientations.size(); ++i )
890   {
891     rotations[i] = static_cast< int >( mAvailableOrientations[i] );
892   }
893   ecore_wl2_window_available_rotations_set( mEventHandler->mEcoreWindow, rotations, mAvailableOrientations.size() );
894 }
895
896 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
897 {
898   return mAvailableOrientations;
899 }
900
901 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
902 {
903   mPreferredOrientation = orientation;
904
905   ecore_wl2_window_preferred_rotation_set( mEventHandler->mEcoreWindow, orientation );
906 }
907
908 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
909 {
910   return mPreferredOrientation;
911 }
912
913 void Window::SetAcceptFocus( bool accept )
914 {
915   mIsFocusAcceptable = accept;
916
917   ecore_wl2_window_focus_skip_set( mEventHandler->mEcoreWindow, !accept );
918 }
919
920 bool Window::IsFocusAcceptable() const
921 {
922   return mIsFocusAcceptable;
923 }
924
925 void Window::Show()
926 {
927   mVisible = true;
928   ecore_wl2_window_show( mEventHandler->mEcoreWindow );
929
930   if( !mIconified )
931   {
932     if( mAdaptor )
933     {
934       WindowVisibilityObserver* observer( mAdaptor );
935       observer->OnWindowShown();
936       DALI_LOG_RELEASE_INFO( "Window (%p) ::Show() \n", mEventHandler->mEcoreWindow);
937     }
938   }
939 }
940
941 void Window::Hide()
942 {
943   mVisible = false;
944   ecore_wl2_window_hide( mEventHandler->mEcoreWindow );
945
946   if( !mIconified )
947   {
948     if( mAdaptor )
949     {
950       WindowVisibilityObserver* observer( mAdaptor );
951       observer->OnWindowHidden();
952       DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", mEventHandler->mEcoreWindow);
953     }
954   }
955 }
956
957 bool Window::IsVisible() const
958 {
959   return mVisible;
960 }
961
962 void Window::RotationDone( int orientation, int width, int height )
963 {
964   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
965   if( wlSurface )
966   {
967     wlSurface->RequestRotation( orientation, width, height );
968   }
969
970   mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
971
972   // Emit signal
973   mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
974
975   mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
976 }
977
978 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
979 {
980   mIndicatorVisible = mode;
981 }
982
983 unsigned int Window::GetSupportedAuxiliaryHintCount() const
984 {
985   return mSupportedAuxiliaryHints.size();
986 }
987
988 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
989 {
990   if( index >= GetSupportedAuxiliaryHintCount() )
991   {
992     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetSupportedAuxiliaryHint: Invalid index! [%d]\n", index );
993   }
994
995   return mSupportedAuxiliaryHints[index];
996 }
997
998 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
999 {
1000   bool supported = false;
1001
1002   // Check if the hint is suppported
1003   for( std::vector< std::string >::iterator iter = mSupportedAuxiliaryHints.begin(); iter != mSupportedAuxiliaryHints.end(); ++iter )
1004   {
1005     if( *iter == hint )
1006     {
1007       supported = true;
1008       break;
1009     }
1010   }
1011
1012   if( !supported )
1013   {
1014     DALI_LOG_INFO( gWindowLogFilter, Debug::Concise, "Window::AddAuxiliaryHint: Not supported auxiliary hint [%s]\n", hint.c_str() );
1015     return 0;
1016   }
1017
1018   // Check if the hint is already added
1019   for( unsigned int i = 0; i < mAuxiliaryHints.size(); i++ )
1020   {
1021     if( mAuxiliaryHints[i].first == hint )
1022     {
1023       // Just change the value
1024       mAuxiliaryHints[i].second = value;
1025
1026       DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::AddAuxiliaryHint: Change! hint = %s, value = %s, id = %d\n", hint.c_str(), value.c_str(), i + 1 );
1027
1028       return i + 1;   // id is index + 1
1029     }
1030   }
1031
1032   // Add the hint
1033   mAuxiliaryHints.push_back( std::pair< std::string, std::string >( hint, value ) );
1034
1035   unsigned int id = mAuxiliaryHints.size();
1036
1037   ecore_wl2_window_aux_hint_add( mEventHandler->mEcoreWindow, static_cast< int >( id ), hint.c_str(), value.c_str() );
1038
1039   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::AddAuxiliaryHint: hint = %s, value = %s, id = %d\n", hint.c_str(), value.c_str(), id );
1040
1041   return id;
1042 }
1043
1044 bool Window::RemoveAuxiliaryHint( unsigned int id )
1045 {
1046   if( id == 0 || id > mAuxiliaryHints.size() )
1047   {
1048     DALI_LOG_INFO( gWindowLogFilter, Debug::Concise, "Window::RemoveAuxiliaryHint: Invalid id [%d]\n", id );
1049     return false;
1050   }
1051
1052   mAuxiliaryHints[id - 1].second = std::string();
1053
1054   ecore_wl2_window_aux_hint_del( mEventHandler->mEcoreWindow, static_cast< int >( id ) );
1055
1056   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::RemoveAuxiliaryHint: id = %d, hint = %s\n", id, mAuxiliaryHints[id - 1].first.c_str() );
1057
1058   return true;
1059 }
1060
1061 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
1062 {
1063   if( id == 0 || id > mAuxiliaryHints.size() )
1064   {
1065     DALI_LOG_INFO( gWindowLogFilter, Debug::Concise, "Window::SetAuxiliaryHintValue: Invalid id [%d]\n", id );
1066     return false;
1067   }
1068
1069   mAuxiliaryHints[id - 1].second = value;
1070
1071   ecore_wl2_window_aux_hint_change( mEventHandler->mEcoreWindow, static_cast< int >( id ), value.c_str() );
1072
1073   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAuxiliaryHintValue: id = %d, hint = %s, value = %s\n", id, mAuxiliaryHints[id - 1].first.c_str(), mAuxiliaryHints[id - 1].second.c_str() );
1074
1075   return true;
1076 }
1077
1078 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
1079 {
1080   if( id == 0 || id > mAuxiliaryHints.size() )
1081   {
1082     DALI_LOG_INFO( gWindowLogFilter, Debug::Concise, "Window::GetAuxiliaryHintValue: Invalid id [%d]\n", id );
1083     return std::string();
1084   }
1085
1086   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetAuxiliaryHintValue: id = %d, hint = %s, value = %s\n", id, mAuxiliaryHints[id - 1].first.c_str(), mAuxiliaryHints[id - 1].second.c_str() );
1087
1088   return mAuxiliaryHints[id - 1].second;
1089 }
1090
1091 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
1092 {
1093   for( unsigned int i = 0; i < mAuxiliaryHints.size(); i++ )
1094   {
1095     if( mAuxiliaryHints[i].first == hint )
1096     {
1097       DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetAuxiliaryHintId: hint = %s, id = %d\n", hint.c_str(), i + 1 );
1098       return i + 1;
1099     }
1100   }
1101
1102   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetAuxiliaryHintId: Invalid hint! [%s]\n", hint.c_str() );
1103
1104   return 0;
1105 }
1106
1107 void Window::SetInputRegion( const Rect< int >& inputRegion )
1108 {
1109   ecore_wl2_window_input_region_set( mEventHandler->mEcoreWindow, inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height );
1110
1111   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height );
1112 }
1113
1114 void Window::SetType( Dali::Window::Type type )
1115 {
1116   Ecore_Wl2_Window_Type windowType;
1117
1118   if( type != mType )
1119   {
1120     switch( type )
1121     {
1122       case Dali::Window::NORMAL:
1123       {
1124         windowType = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
1125         break;
1126       }
1127       case Dali::Window::NOTIFICATION:
1128       {
1129         windowType = ECORE_WL2_WINDOW_TYPE_NOTIFICATION;
1130         break;
1131       }
1132       case Dali::Window::UTILITY:
1133       {
1134         windowType = ECORE_WL2_WINDOW_TYPE_UTILITY;
1135         break;
1136       }
1137       case Dali::Window::DIALOG:
1138       {
1139         windowType = ECORE_WL2_WINDOW_TYPE_DIALOG;
1140         break;
1141       }
1142       default:
1143       {
1144         windowType = ECORE_WL2_WINDOW_TYPE_TOPLEVEL;
1145         break;
1146       }
1147     }
1148
1149     ecore_wl2_window_type_set( mEventHandler->mEcoreWindow, windowType );
1150   }
1151
1152   mType = type;
1153 }
1154
1155 Dali::Window::Type Window::GetType() const
1156 {
1157   return mType;
1158 }
1159
1160 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
1161 {
1162   if( mType != Dali::Window::NOTIFICATION )
1163   {
1164     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
1165     return false;
1166   }
1167
1168   while( !mEventHandler->mTizenPolicy )
1169   {
1170     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1171   }
1172
1173   int notificationLevel;
1174
1175   switch( level )
1176   {
1177     case Dali::Window::NotificationLevel::NONE:
1178     {
1179       notificationLevel = TIZEN_POLICY_LEVEL_NONE;
1180       break;
1181     }
1182     case Dali::Window::NotificationLevel::BASE:
1183     {
1184       notificationLevel = TIZEN_POLICY_LEVEL_DEFAULT;
1185       break;
1186     }
1187     case Dali::Window::NotificationLevel::MEDIUM:
1188     {
1189       notificationLevel = TIZEN_POLICY_LEVEL_MEDIUM;
1190       break;
1191     }
1192     case Dali::Window::NotificationLevel::HIGH:
1193     {
1194       notificationLevel = TIZEN_POLICY_LEVEL_HIGH;
1195       break;
1196     }
1197     case Dali::Window::NotificationLevel::TOP:
1198     {
1199       notificationLevel = TIZEN_POLICY_LEVEL_TOP;
1200       break;
1201     }
1202     default:
1203     {
1204       DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: invalid level [%d]\n", level );
1205       notificationLevel = TIZEN_POLICY_LEVEL_DEFAULT;
1206       break;
1207     }
1208   }
1209
1210   mEventHandler->mNotificationLevelChangeDone = false;
1211   mEventHandler->mNotificationChangeState = TIZEN_POLICY_ERROR_STATE_NONE;
1212
1213   tizen_policy_set_notification_level( mEventHandler->mTizenPolicy, ecore_wl2_window_surface_get( mEventHandler->mEcoreWindow ), notificationLevel );
1214
1215   int count = 0;
1216
1217   while( !mEventHandler->mNotificationLevelChangeDone && count < 3 )
1218   {
1219     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1220     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1221     count++;
1222   }
1223
1224   if( !mEventHandler->mNotificationLevelChangeDone )
1225   {
1226     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Level change is failed [%d, %d]\n", level, mEventHandler->mNotificationChangeState );
1227     return false;
1228   }
1229   else if( mEventHandler->mNotificationChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED )
1230   {
1231     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Permission denied! [%d]\n", level );
1232     return false;
1233   }
1234
1235   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Level is changed [%d]\n", mEventHandler->mNotificationLevel );
1236
1237   return true;
1238 }
1239
1240 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
1241 {
1242   if( mType != Dali::Window::NOTIFICATION )
1243   {
1244     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
1245     return Dali::Window::NotificationLevel::NONE;
1246   }
1247
1248   while( !mEventHandler->mTizenPolicy )
1249   {
1250     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1251   }
1252
1253   int count = 0;
1254
1255   while( !mEventHandler->mNotificationLevelChangeDone && count < 3 )
1256   {
1257     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1258     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1259     count++;
1260   }
1261
1262   if( !mEventHandler->mNotificationLevelChangeDone )
1263   {
1264     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Error! [%d]\n", mEventHandler->mNotificationChangeState );
1265     return Dali::Window::NotificationLevel::NONE;
1266   }
1267
1268   Dali::Window::NotificationLevel::Type level;
1269
1270   switch( mEventHandler->mNotificationLevel )
1271   {
1272     case TIZEN_POLICY_LEVEL_NONE:
1273     {
1274       level = Dali::Window::NotificationLevel::NONE;
1275       break;
1276     }
1277     case TIZEN_POLICY_LEVEL_DEFAULT:
1278     {
1279       level = Dali::Window::NotificationLevel::BASE;
1280       break;
1281     }
1282     case TIZEN_POLICY_LEVEL_MEDIUM:
1283     {
1284       level = Dali::Window::NotificationLevel::MEDIUM;
1285       break;
1286     }
1287     case TIZEN_POLICY_LEVEL_HIGH:
1288     {
1289       level = Dali::Window::NotificationLevel::HIGH;
1290       break;
1291     }
1292     case TIZEN_POLICY_LEVEL_TOP:
1293     {
1294       level = Dali::Window::NotificationLevel::TOP;
1295       break;
1296     }
1297     default:
1298     {
1299       DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: invalid level [%d]\n", mEventHandler->mNotificationLevel );
1300       level = Dali::Window::NotificationLevel::NONE;
1301       break;
1302     }
1303   }
1304
1305   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: level [%d]\n", mEventHandler->mNotificationLevel );
1306
1307   return level;
1308 }
1309
1310 void Window::SetOpaqueState( bool opaque )
1311 {
1312   while( !mEventHandler->mTizenPolicy )
1313   {
1314     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1315   }
1316
1317   tizen_policy_set_opaque_state( mEventHandler->mTizenPolicy, ecore_wl2_window_surface_get( mEventHandler->mEcoreWindow ), ( opaque ? 1 : 0 ) );
1318
1319   mOpaqueState = opaque;
1320
1321   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
1322 }
1323
1324 bool Window::IsOpaqueState() const
1325 {
1326   return mOpaqueState;
1327 }
1328
1329 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
1330 {
1331   while( !mEventHandler->mTizenPolicy )
1332   {
1333     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1334   }
1335
1336   mEventHandler->mScreenOffModeChangeDone = false;
1337   mEventHandler->mScreenOffModeChangeState = TIZEN_POLICY_ERROR_STATE_NONE;
1338
1339   unsigned int mode = 0;
1340
1341   switch( screenOffMode )
1342   {
1343     case Dali::Window::ScreenOffMode::TIMEOUT:
1344     {
1345       mode = 0;
1346       break;
1347     }
1348     case Dali::Window::ScreenOffMode::NEVER:
1349     {
1350       mode = 1;
1351       break;
1352     }
1353   }
1354
1355   tizen_policy_set_window_screen_mode( mEventHandler->mTizenPolicy, ecore_wl2_window_surface_get( mEventHandler->mEcoreWindow ), mode );
1356
1357   int count = 0;
1358
1359   while( !mEventHandler->mScreenOffModeChangeDone && count < 3 )
1360   {
1361     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1362     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1363     count++;
1364   }
1365
1366   if( !mEventHandler->mScreenOffModeChangeDone )
1367   {
1368     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetScreenOffMode: Screen mode change is failed [%d, %d]\n", screenOffMode, mEventHandler->mScreenOffModeChangeState );
1369     return false;
1370   }
1371   else if( mEventHandler->mScreenOffModeChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED )
1372   {
1373     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetScreenOffMode: Permission denied! [%d]\n", screenOffMode );
1374     return false;
1375   }
1376
1377   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetScreenOffMode: Screen mode is changed [%d]\n", mEventHandler->mScreenOffMode );
1378
1379   return true;
1380 }
1381
1382 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
1383 {
1384   while( !mEventHandler->mTizenPolicy )
1385   {
1386     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1387   }
1388
1389   int count = 0;
1390
1391   while( !mEventHandler->mScreenOffModeChangeDone && count < 3 )
1392   {
1393     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1394     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1395     count++;
1396   }
1397
1398   if( !mEventHandler->mScreenOffModeChangeDone )
1399   {
1400     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetScreenOffMode: Error! [%d]\n", mEventHandler->mScreenOffModeChangeState );
1401     return Dali::Window::ScreenOffMode::TIMEOUT;
1402   }
1403
1404   Dali::Window::ScreenOffMode::Type screenMode = Dali::Window::ScreenOffMode::TIMEOUT;
1405
1406   switch( mEventHandler->mScreenOffMode )
1407   {
1408     case 0:
1409     {
1410       screenMode = Dali::Window::ScreenOffMode::TIMEOUT;
1411       break;
1412     }
1413     case 1:
1414     {
1415       screenMode = Dali::Window::ScreenOffMode::NEVER;
1416       break;
1417     }
1418   }
1419
1420   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetScreenOffMode: screen mode [%d]\n", mEventHandler->mScreenOffMode );
1421
1422   return screenMode;
1423 }
1424
1425 bool Window::SetBrightness( int brightness )
1426 {
1427   if( brightness < 0 || brightness > 100 )
1428   {
1429     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
1430     return false;
1431   }
1432
1433   while( !mEventHandler->mTizenDisplayPolicy )
1434   {
1435     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1436   }
1437
1438   mEventHandler->mBrightnessChangeDone = false;
1439   mEventHandler->mBrightnessChangeState = TIZEN_POLICY_ERROR_STATE_NONE;
1440
1441   tizen_display_policy_set_window_brightness( mEventHandler->mTizenDisplayPolicy, ecore_wl2_window_surface_get( mEventHandler->mEcoreWindow ), brightness );
1442
1443   int count = 0;
1444
1445   while( !mEventHandler->mBrightnessChangeDone && count < 3 )
1446   {
1447     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1448     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1449     count++;
1450   }
1451
1452   if( !mEventHandler->mBrightnessChangeDone )
1453   {
1454     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Brightness change is failed [%d, %d]\n", brightness, mEventHandler->mBrightnessChangeState );
1455     return false;
1456   }
1457   else if( mEventHandler->mBrightnessChangeState == TIZEN_POLICY_ERROR_STATE_PERMISSION_DENIED )
1458   {
1459     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Permission denied! [%d]\n", brightness );
1460     return false;
1461   }
1462
1463   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Brightness is changed [%d]\n", mEventHandler->mBrightness );
1464
1465   return true;
1466 }
1467
1468 int Window::GetBrightness() const
1469 {
1470   while( !mEventHandler->mTizenDisplayPolicy )
1471   {
1472     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1473   }
1474
1475   int count = 0;
1476
1477   while( !mEventHandler->mBrightnessChangeDone && count < 3 )
1478   {
1479     ecore_wl2_display_flush(ecore_wl2_connected_display_get(NULL));
1480     wl_display_dispatch_queue( mEventHandler->mDisplay, mEventHandler->mEventQueue );
1481     count++;
1482   }
1483
1484   if( !mEventHandler->mBrightnessChangeDone )
1485   {
1486     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetBrightness: Error! [%d]\n", mEventHandler->mBrightnessChangeState );
1487     return 0;
1488   }
1489
1490   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetBrightness: Brightness [%d]\n", mEventHandler->mBrightness );
1491
1492   return mEventHandler->mBrightness;
1493 }
1494
1495 void Window::SetSize( Dali::Window::WindowSize size )
1496 {
1497   if( !mResizeEnabled )
1498   {
1499     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
1500     mResizeEnabled = true;
1501   }
1502
1503   PositionSize positionSize = mSurface->GetPositionSize();
1504
1505   if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
1506   {
1507     positionSize.width = size.GetWidth();
1508     positionSize.height = size.GetHeight();
1509
1510     mSurface->MoveResize( positionSize );
1511
1512     mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
1513
1514     // Emit signal
1515     mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
1516
1517     mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
1518   }
1519 }
1520
1521 Dali::Window::WindowSize Window::GetSize() const
1522 {
1523   PositionSize positionSize = mSurface->GetPositionSize();
1524
1525   return Dali::Window::WindowSize( positionSize.width, positionSize.height );
1526 }
1527
1528 void Window::SetPosition( Dali::Window::WindowPosition position )
1529 {
1530   if( !mResizeEnabled )
1531   {
1532     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
1533     mResizeEnabled = true;
1534   }
1535
1536   PositionSize positionSize = mSurface->GetPositionSize();
1537
1538   if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
1539   {
1540     positionSize.x = position.GetX();
1541     positionSize.y = position.GetY();
1542
1543     mSurface->MoveResize( positionSize );
1544   }
1545 }
1546
1547 Dali::Window::WindowPosition Window::GetPosition() const
1548 {
1549   PositionSize positionSize = mSurface->GetPositionSize();
1550
1551   return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
1552 }
1553
1554 void Window::SetTransparency( bool transparent )
1555 {
1556   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
1557   if( wlSurface )
1558   {
1559     wlSurface->SetTransparency( transparent );
1560   }
1561 }
1562
1563 } // Adaptor
1564
1565 } // Internal
1566
1567 } // Dali
1568
1569 #pragma GCC diagnostic pop