Merge "[3.0] Add Privilege doxygen tags" into tizen
[platform/core/uifw/dali-adaptor.git] / adaptors / ecore / wayland / window-impl-ecore-wl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "window-impl.h"
20
21 // EXTERNAL HEADERS
22 #include <Ecore.h>
23 #include <Ecore_Wayland.h>
24
25 #include <dali/integration-api/core.h>
26 #include <dali/integration-api/system-overlay.h>
27 #include <dali/public-api/render-tasks/render-task.h>
28 #include <dali/public-api/render-tasks/render-task-list.h>
29 #include <orientation.h>
30
31 // INTERNAL HEADERS
32 #include <window-render-surface.h>
33 #include <drag-and-drop-detector-impl.h>
34 #include <ecore-indicator-impl.h>
35 #include <window-visibility-observer.h>
36 #include <orientation-impl.h>
37 namespace
38 {
39 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
40 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
41 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
42 }
43
44 namespace Dali
45 {
46 namespace Internal
47 {
48 namespace Adaptor
49 {
50 #if defined(DEBUG_ENABLED)
51 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_WINDOW");
52 #endif
53
54 /**
55  * TODO: Abstract Window class out and move this into a window implementation for Ecore
56  */
57 struct Window::EventHandler
58 {
59   /**
60    * Constructor
61    * @param[in]  window  A pointer to the window class.
62    */
63   EventHandler( Window* window )
64   : mWindow( window ),
65     mWindowPropertyHandler( NULL ),
66     mClientMessageHandler( NULL ),
67     mEcoreWindow( 0 )
68   {
69     // store ecore window handle
70     ECore::WindowRenderSurface* wlWindow( dynamic_cast< ECore::WindowRenderSurface * >( mWindow->mSurface ) );
71     if( wlWindow )
72     {
73       mEcoreWindow = wlWindow->GetWlWindow();
74     }
75     DALI_ASSERT_ALWAYS( mEcoreWindow != 0 && "There is no ecore Wl window");
76   }
77
78   /**
79    * Destructor
80    */
81   ~EventHandler()
82   {
83     if ( mWindowPropertyHandler )
84     {
85       ecore_event_handler_del( mWindowPropertyHandler );
86     }
87     if ( mClientMessageHandler )
88     {
89       ecore_event_handler_del( mClientMessageHandler );
90     }
91   }
92
93   // Static methods
94
95   /// Called when the window properties are changed.
96   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
97   {
98     return EINA_FALSE;
99   }
100
101   /// Called when the window properties are changed.
102   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
103   {
104     return EINA_FALSE;
105   }
106
107   // Data
108   Window* mWindow;
109   Ecore_Event_Handler* mWindowPropertyHandler;
110   Ecore_Event_Handler* mClientMessageHandler;
111   Ecore_Wl_Window* mEcoreWindow;
112 };
113
114
115 Window* Window::New(const PositionSize& posSize, const std::string& name, const std::string& className, bool isTransparent)
116 {
117   Window* window = new Window();
118   window->mIsTransparent = isTransparent;
119   window->Initialize(posSize, name, className);
120   return window;
121 }
122
123 void Window::SetAdaptor(Dali::Adaptor& adaptor)
124 {
125   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
126   mStarted = true;
127
128   // Only create one overlay per window
129   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
130   Integration::Core& core = adaptorImpl.GetCore();
131   mOverlay = &core.GetSystemOverlay();
132
133   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
134   taskList.CreateTask();
135
136   mAdaptor = &adaptorImpl;
137   mAdaptor->AddObserver( *this );
138
139   // Can only create the detector when we know the Core has been instantiated.
140   mDragAndDropDetector = DragAndDropDetector::New();
141   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
142
143   if( mOrientation )
144   {
145     mOrientation->SetAdaptor(adaptor);
146   }
147
148   if( mIndicator != NULL )
149   {
150     mIndicator->SetAdaptor(mAdaptor);
151   }
152 }
153
154 RenderSurface* Window::GetSurface()
155 {
156   return mSurface;
157 }
158
159 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
160 {
161   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
162   DALI_ASSERT_DEBUG(mOverlay);
163
164   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
165   DALI_ASSERT_DEBUG(wlSurface);
166   Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
167
168   mIndicatorVisible = visibleMode;
169
170   if ( mIndicatorVisible == Dali::Window::VISIBLE )
171   {
172     // when the indicator is visible, set proper mode for indicator server according to bg mode
173     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
174     {
175       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_OPAQUE);
176     }
177     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
178     {
179       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_TRANSLUCENT);
180     }
181     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
182     {
183       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_OPAQUE);
184     }
185   }
186   else
187   {
188     // when the indicator is not visible, set TRANSPARENT mode for indicator server
189     ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_TRANSPARENT); // it means hidden indicator
190   }
191
192   DoShowIndicator( mIndicatorOrientation );
193 }
194
195 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
196 {
197   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
198
199   DoRotateIndicator( orientation );
200 }
201
202 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
203 {
204   mIndicatorOpacityMode = opacityMode;
205
206   if( mIndicator != NULL )
207   {
208     mIndicator->SetOpacityMode( opacityMode );
209   }
210 }
211
212 void Window::SetClass(std::string name, std::string klass)
213 {
214 }
215
216 Window::Window()
217 : mSurface(NULL),
218   mIndicatorVisible(Dali::Window::VISIBLE),
219   mIndicatorIsShown(false),
220   mShowRotatedIndicatorOnClose(false),
221   mStarted(false),
222   mIsTransparent(false),
223   mWMRotationAppSet(false),
224   mIndicator(NULL),
225   mIndicatorOrientation(Dali::Window::PORTRAIT),
226   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
227   mIndicatorOpacityMode(Dali::Window::OPAQUE),
228   mOverlay(NULL),
229   mAdaptor(NULL),
230   mEventHandler(NULL),
231   mPreferredOrientation(Dali::Window::PORTRAIT)
232 {
233 }
234
235 Window::~Window()
236 {
237   delete mEventHandler;
238
239   if( mIndicator )
240   {
241     mIndicator->Close();
242     delete mIndicator;
243   }
244
245   if ( mAdaptor )
246   {
247     mAdaptor->RemoveObserver( *this );
248     mAdaptor->SetDragAndDropDetector( NULL );
249     mAdaptor = NULL;
250   }
251
252   delete mSurface;
253 }
254
255 void Window::Initialize(const PositionSize& windowPosition, const std::string& name, const std::string& className)
256 {
257   // create an Wayland window by default
258   Any surface;
259   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, mIsTransparent );
260   SetClass( name, className );
261   windowSurface->Map();
262
263   mSurface = windowSurface;
264
265   std::string appId;
266   mAdaptor->GetAppId( appId );
267   Ecore_Wl_Window* wlWindow = windowSurface ->GetWlWindow();
268   ecore_wl_window_class_name_set(wlWindow, appId.c_str());
269
270   mOrientation = Orientation::New(this);
271
272   // create event handler for Wayland window
273   mEventHandler = new EventHandler( this );
274 }
275
276 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
277 {
278   if( mIndicator == NULL )
279   {
280     if( mIndicatorVisible != Dali::Window::INVISIBLE )
281     {
282       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
283       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
284       Dali::Actor actor = mIndicator->GetActor();
285       SetIndicatorActorRotation();
286       mOverlay->Add(actor);
287     }
288     // else don't create a hidden indicator
289   }
290   else // Already have indicator
291   {
292     if( mIndicatorVisible == Dali::Window::VISIBLE )
293     {
294       // If we are resuming, and rotation has changed,
295       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
296       {
297         // then close current indicator and open new one
298         mShowRotatedIndicatorOnClose = true;
299         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
300         // Don't show actor - will contain indicator for old orientation.
301       }
302     }
303   }
304
305   // set indicator visible mode
306   if( mIndicator != NULL )
307   {
308     mIndicator->SetVisible( mIndicatorVisible );
309   }
310
311   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
312   SetIndicatorProperties( show, lastOrientation );
313   mIndicatorIsShown = show;
314 }
315
316 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
317 {
318   if( mIndicatorIsShown )
319   {
320     mShowRotatedIndicatorOnClose = true;
321     mNextIndicatorOrientation = orientation;
322     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
323   }
324   else
325   {
326     // Save orientation for when the indicator is next shown
327     mShowRotatedIndicatorOnClose = false;
328     mNextIndicatorOrientation = orientation;
329   }
330 }
331
332 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
333 {
334   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
335
336   if( wlSurface )
337   {
338     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
339     if ( isShow )
340     {
341       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_ON);
342     }
343     else
344     {
345       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_OFF);
346     }
347   }
348 }
349
350 void Window::IndicatorTypeChanged(Indicator::Type type)
351 {
352 #if defined(DALI_PROFILE_MOBILE)
353   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
354
355   if( wlSurface )
356   {
357     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
358     switch(type)
359     {
360       case Indicator::INDICATOR_TYPE_1:
361         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
362         break;
363
364       case Indicator::INDICATOR_TYPE_2:
365         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
366         break;
367
368       case Indicator::INDICATOR_TYPE_UNKNOWN:
369       default:
370         break;
371     }
372   }
373 #endif //MOBILE
374 }
375
376 void Window::IndicatorClosed( IndicatorInterface* indicator )
377 {
378   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
379
380   if( mShowRotatedIndicatorOnClose )
381   {
382     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
383     mIndicator->Open(mNextIndicatorOrientation);
384     mIndicatorOrientation = mNextIndicatorOrientation;
385     SetIndicatorActorRotation();
386     DoShowIndicator(currentOrientation);
387   }
388 }
389
390 void Window::IndicatorVisibilityChanged(bool isVisible)
391 {
392   mIndicatorVisibilityChangedSignal.Emit(isVisible);
393 }
394
395 void Window::SetIndicatorActorRotation()
396 {
397   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
398   DALI_ASSERT_DEBUG( mIndicator != NULL );
399
400   Dali::Actor actor = mIndicator->GetActor();
401   switch( mIndicatorOrientation )
402   {
403     case Dali::Window::PORTRAIT:
404       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
405       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
406       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
407       break;
408     case Dali::Window::PORTRAIT_INVERSE:
409       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
410       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
411       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
412       break;
413     case Dali::Window::LANDSCAPE:
414       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
415       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
416       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
417       break;
418     case Dali::Window::LANDSCAPE_INVERSE:
419       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
420       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
421       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
422       break;
423   }
424 }
425
426 void Window::Raise()
427 {
428 }
429
430 void Window::Lower()
431 {
432 }
433
434 void Window::Activate()
435 {
436 }
437
438 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
439 {
440   return mDragAndDropDetector;
441 }
442
443 Dali::Any Window::GetNativeHandle() const
444 {
445   if(mEventHandler)
446   {
447     return mEventHandler->mEcoreWindow;
448   }
449   else
450   {
451     return Dali::Any();
452   }
453 }
454
455 void Window::OnStart()
456 {
457   DoShowIndicator( mIndicatorOrientation );
458 }
459
460 void Window::OnPause()
461 {
462 }
463
464 void Window::OnResume()
465 {
466   // resume indicator status
467   if( mIndicator != NULL )
468   {
469     // Restore own indicator opacity
470     // Send opacity mode to indicator service when app resumed
471     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
472   }
473 }
474
475 void Window::OnStop()
476 {
477   if( mIndicator )
478   {
479     mIndicator->Close();
480   }
481
482   delete mIndicator;
483   mIndicator = NULL;
484 }
485
486 void Window::OnDestroy()
487 {
488   mAdaptor = NULL;
489 }
490
491 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
492 {
493   bool found = false;
494
495   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
496   {
497     if(mAvailableOrientations[i] == orientation)
498     {
499       found = true;
500       break;
501     }
502   }
503
504   if( ! found )
505   {
506     mAvailableOrientations.push_back(orientation);
507     SetAvailableOrientations( mAvailableOrientations );
508   }
509 }
510
511 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
512 {
513   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
514        iter != mAvailableOrientations.end(); ++iter )
515   {
516     if( *iter == orientation )
517     {
518       mAvailableOrientations.erase( iter );
519       break;
520     }
521   }
522   SetAvailableOrientations( mAvailableOrientations );
523 }
524
525 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
526 {
527   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
528 }
529
530 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
531 {
532   return mAvailableOrientations;
533 }
534
535 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
536 {
537   mPreferredOrientation = orientation;
538 }
539
540 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
541 {
542   return mPreferredOrientation;
543 }
544
545 void Window::RotationDone( int orientation, int width, int height )
546 {
547 }
548
549
550 } // Adaptor
551 } // Internal
552 } // Dali