Merge "Initialize a member about tbm surface format" into devel/master
[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     mWindowIconifyStateHandler( 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     if( mWindow->mEcoreEventHander )
78     {
79       mWindowIconifyStateHandler = ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ICONIFY_STATE_CHANGE, EcoreEventWindowIconifyStateChanged, this );
80     }
81
82   }
83
84   /**
85    * Destructor
86    */
87   ~EventHandler()
88   {
89     if ( mWindowPropertyHandler )
90     {
91       ecore_event_handler_del( mWindowPropertyHandler );
92     }
93     if ( mWindowIconifyStateHandler )
94     {
95       ecore_event_handler_del( mWindowIconifyStateHandler );
96     }
97   }
98
99   // Static methods
100
101   /// Called when the window properties are changed.
102   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
103   {
104     return EINA_FALSE;
105   }
106
107   /// Called when the window iconify state is changed.
108   static Eina_Bool EcoreEventWindowIconifyStateChanged( void* data, int type, void* event )
109   {
110     Ecore_Wl_Event_Window_Iconify_State_Change* iconifyChangedEvent( (Ecore_Wl_Event_Window_Iconify_State_Change*)event );
111     EventHandler* handler( (EventHandler*)data );
112     Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
113
114     if ( handler && handler->mWindow )
115     {
116       WindowVisibilityObserver* observer( handler->mWindow->mAdaptor );
117       if ( observer && ( iconifyChangedEvent->win == (unsigned int) ecore_wl_window_id_get( handler->mEcoreWindow ) ) )
118       {
119         if( iconifyChangedEvent->iconified == EINA_TRUE )
120         {
121           observer->OnWindowHidden();
122           DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Iconfied\n", handler->mEcoreWindow );
123         }
124         else
125         {
126           observer->OnWindowShown();
127           DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window (%d) Shown\n", handler->mEcoreWindow );
128         }
129         handled = ECORE_CALLBACK_DONE;
130       }
131     }
132
133     return handled;
134   }
135
136   // Data
137   Window* mWindow;
138   Ecore_Event_Handler* mWindowPropertyHandler;
139   Ecore_Event_Handler* mWindowIconifyStateHandler;
140   Ecore_Wl_Window* mEcoreWindow;
141 };
142
143
144 Window* Window::New(const PositionSize& posSize, const std::string& name, const std::string& className, bool isTransparent)
145 {
146   Window* window = new Window();
147   window->mIsTransparent = isTransparent;
148   window->Initialize(posSize, name, className);
149   return window;
150 }
151
152 void Window::SetAdaptor(Dali::Adaptor& adaptor)
153 {
154   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
155   mStarted = true;
156
157   // Only create one overlay per window
158   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
159   Integration::Core& core = adaptorImpl.GetCore();
160   mOverlay = &core.GetSystemOverlay();
161
162   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
163   taskList.CreateTask();
164
165   mAdaptor = &adaptorImpl;
166   mAdaptor->AddObserver( *this );
167
168   // Can only create the detector when we know the Core has been instantiated.
169   mDragAndDropDetector = DragAndDropDetector::New();
170   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
171
172   if( mOrientation )
173   {
174     mOrientation->SetAdaptor(adaptor);
175   }
176
177   if( mIndicator != NULL )
178   {
179     mIndicator->SetAdaptor(mAdaptor);
180   }
181 }
182
183 RenderSurface* Window::GetSurface()
184 {
185   return mSurface;
186 }
187
188 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
189 {
190   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
191   DALI_ASSERT_DEBUG(mOverlay);
192
193   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
194   DALI_ASSERT_DEBUG(wlSurface);
195   Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
196
197   mIndicatorVisible = visibleMode;
198
199   if ( mIndicatorVisible == Dali::Window::VISIBLE )
200   {
201     // when the indicator is visible, set proper mode for indicator server according to bg mode
202     if ( mIndicatorOpacityMode == Dali::Window::OPAQUE )
203     {
204       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_OPAQUE);
205     }
206     else if ( mIndicatorOpacityMode == Dali::Window::TRANSLUCENT )
207     {
208       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_TRANSLUCENT);
209     }
210     else if ( mIndicatorOpacityMode == Dali::Window::TRANSPARENT )
211     {
212       ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_OPAQUE);
213     }
214   }
215   else
216   {
217     // when the indicator is not visible, set TRANSPARENT mode for indicator server
218     ecore_wl_window_indicator_opacity_set(wlWindow, ECORE_WL_INDICATOR_TRANSPARENT); // it means hidden indicator
219   }
220
221   DoShowIndicator( mIndicatorOrientation );
222 }
223
224 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
225 {
226   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
227
228   DoRotateIndicator( orientation );
229 }
230
231 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
232 {
233   mIndicatorOpacityMode = opacityMode;
234
235   if( mIndicator != NULL )
236   {
237     mIndicator->SetOpacityMode( opacityMode );
238   }
239 }
240
241 void Window::SetClass(std::string name, std::string klass)
242 {
243   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
244
245   if( wlSurface )
246   {
247     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
248     ecore_wl_window_title_set( wlWindow, name.c_str() );
249     ecore_wl_window_class_name_set( wlWindow, klass.c_str() );
250   }
251   else
252   {
253     DALI_LOG_INFO( gWindowLogFilter, Debug::General, "Window has no surface\n" );
254   }
255 }
256
257 Window::Window()
258 : mSurface(NULL),
259   mIndicatorVisible(Dali::Window::VISIBLE),
260   mIndicatorIsShown(false),
261   mShowRotatedIndicatorOnClose(false),
262   mStarted(false),
263   mIsTransparent(false),
264   mWMRotationAppSet(false),
265   mEcoreEventHander(true),
266   mIndicator(NULL),
267   mIndicatorOrientation(Dali::Window::PORTRAIT),
268   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
269   mIndicatorOpacityMode(Dali::Window::OPAQUE),
270   mOverlay(NULL),
271   mAdaptor(NULL),
272   mEventHandler(NULL),
273   mPreferredOrientation(Dali::Window::PORTRAIT)
274 {
275 }
276
277 Window::~Window()
278 {
279   delete mEventHandler;
280
281   if( mIndicator )
282   {
283     mIndicator->Close();
284     delete mIndicator;
285   }
286
287   if ( mAdaptor )
288   {
289     mAdaptor->RemoveObserver( *this );
290     mAdaptor->SetDragAndDropDetector( NULL );
291     mAdaptor = NULL;
292   }
293
294   delete mSurface;
295 }
296
297 void Window::Initialize(const PositionSize& windowPosition, const std::string& name, const std::string& className)
298 {
299   // create an Wayland window by default
300   Any surface;
301   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, mIsTransparent );
302
303   mSurface = windowSurface;
304   SetClass( name, className );
305   windowSurface->Map();
306
307   mOrientation = Orientation::New(this);
308
309   // create event handler for Wayland window
310   mEventHandler = new EventHandler( this );
311 }
312
313 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
314 {
315   if( mIndicator == NULL )
316   {
317     if( mIndicatorVisible != Dali::Window::INVISIBLE )
318     {
319       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
320       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
321       Dali::Actor actor = mIndicator->GetActor();
322       SetIndicatorActorRotation();
323       mOverlay->Add(actor);
324     }
325     // else don't create a hidden indicator
326   }
327   else // Already have indicator
328   {
329     if( mIndicatorVisible == Dali::Window::VISIBLE )
330     {
331       // If we are resuming, and rotation has changed,
332       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
333       {
334         // then close current indicator and open new one
335         mShowRotatedIndicatorOnClose = true;
336         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
337         // Don't show actor - will contain indicator for old orientation.
338       }
339     }
340   }
341
342   // set indicator visible mode
343   if( mIndicator != NULL )
344   {
345     mIndicator->SetVisible( mIndicatorVisible );
346   }
347
348   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
349   SetIndicatorProperties( show, lastOrientation );
350   mIndicatorIsShown = show;
351 }
352
353 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
354 {
355   if( mIndicatorIsShown )
356   {
357     mShowRotatedIndicatorOnClose = true;
358     mNextIndicatorOrientation = orientation;
359     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
360   }
361   else
362   {
363     // Save orientation for when the indicator is next shown
364     mShowRotatedIndicatorOnClose = false;
365     mNextIndicatorOrientation = orientation;
366   }
367 }
368
369 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
370 {
371   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
372
373   if( wlSurface )
374   {
375     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
376     if ( isShow )
377     {
378       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_ON);
379     }
380     else
381     {
382       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_OFF);
383     }
384   }
385 }
386
387 void Window::IndicatorTypeChanged(Indicator::Type type)
388 {
389 #if defined(DALI_PROFILE_MOBILE)
390   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
391
392   if( wlSurface )
393   {
394     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
395     switch(type)
396     {
397       case Indicator::INDICATOR_TYPE_1:
398         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
399         break;
400
401       case Indicator::INDICATOR_TYPE_2:
402         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
403         break;
404
405       case Indicator::INDICATOR_TYPE_UNKNOWN:
406       default:
407         break;
408     }
409   }
410 #endif //MOBILE
411 }
412
413 void Window::IndicatorClosed( IndicatorInterface* indicator )
414 {
415   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
416
417   if( mShowRotatedIndicatorOnClose )
418   {
419     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
420     mIndicator->Open(mNextIndicatorOrientation);
421     mIndicatorOrientation = mNextIndicatorOrientation;
422     SetIndicatorActorRotation();
423     DoShowIndicator(currentOrientation);
424   }
425 }
426
427 void Window::IndicatorVisibilityChanged(bool isVisible)
428 {
429   mIndicatorVisibilityChangedSignal.Emit(isVisible);
430 }
431
432 void Window::SetIndicatorActorRotation()
433 {
434   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
435   DALI_ASSERT_DEBUG( mIndicator != NULL );
436
437   Dali::Actor actor = mIndicator->GetActor();
438   switch( mIndicatorOrientation )
439   {
440     case Dali::Window::PORTRAIT:
441       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
442       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
443       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
444       break;
445     case Dali::Window::PORTRAIT_INVERSE:
446       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
447       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
448       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
449       break;
450     case Dali::Window::LANDSCAPE:
451       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
452       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
453       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
454       break;
455     case Dali::Window::LANDSCAPE_INVERSE:
456       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
457       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
458       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
459       break;
460   }
461 }
462
463 void Window::Raise()
464 {
465   ecore_wl_window_raise( mEventHandler->mEcoreWindow );
466 }
467
468 void Window::Lower()
469 {
470   ecore_wl_window_lower( mEventHandler->mEcoreWindow );
471 }
472
473 void Window::Activate()
474 {
475   ecore_wl_window_activate( mEventHandler->mEcoreWindow );
476 }
477
478 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
479 {
480   return mDragAndDropDetector;
481 }
482
483 Dali::Any Window::GetNativeHandle() const
484 {
485   if(mEventHandler)
486   {
487     return mEventHandler->mEcoreWindow;
488   }
489   else
490   {
491     return Dali::Any();
492   }
493 }
494
495 void Window::OnStart()
496 {
497   DoShowIndicator( mIndicatorOrientation );
498 }
499
500 void Window::OnPause()
501 {
502 }
503
504 void Window::OnResume()
505 {
506   // resume indicator status
507   if( mIndicator != NULL )
508   {
509     // Restore own indicator opacity
510     // Send opacity mode to indicator service when app resumed
511     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
512   }
513 }
514
515 void Window::OnStop()
516 {
517   if( mIndicator )
518   {
519     mIndicator->Close();
520   }
521
522   delete mIndicator;
523   mIndicator = NULL;
524 }
525
526 void Window::OnDestroy()
527 {
528   mAdaptor = NULL;
529 }
530
531 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
532 {
533   bool found = false;
534
535   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
536   {
537     if(mAvailableOrientations[i] == orientation)
538     {
539       found = true;
540       break;
541     }
542   }
543
544   if( ! found )
545   {
546     mAvailableOrientations.push_back(orientation);
547     SetAvailableOrientations( mAvailableOrientations );
548   }
549 }
550
551 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
552 {
553   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
554        iter != mAvailableOrientations.end(); ++iter )
555   {
556     if( *iter == orientation )
557     {
558       mAvailableOrientations.erase( iter );
559       break;
560     }
561   }
562   SetAvailableOrientations( mAvailableOrientations );
563 }
564
565 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
566 {
567   int rotations[4];
568   for( std::size_t i = 0; i < mAvailableOrientations.size(); ++i )
569   {
570     rotations[i] = static_cast< int >( mAvailableOrientations[i] );
571   }
572   ecore_wl_window_rotation_available_rotations_set( mEventHandler->mEcoreWindow, rotations, mAvailableOrientations.size() );
573 }
574
575 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
576 {
577   return mAvailableOrientations;
578 }
579
580 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
581 {
582   mPreferredOrientation = orientation;
583
584   ecore_wl_window_rotation_preferred_rotation_set( mEventHandler->mEcoreWindow, orientation );
585 }
586
587 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
588 {
589   return mPreferredOrientation;
590 }
591
592 void Window::RotationDone( int orientation, int width, int height )
593 {
594   ecore_wl_window_rotation_change_done_send( mEventHandler->mEcoreWindow );
595 }
596
597
598 } // Adaptor
599 } // Internal
600 } // Dali