Fixed to register inconify callback normally
[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   mEcoreEventHander(true),
225   mIndicator(NULL),
226   mIndicatorOrientation(Dali::Window::PORTRAIT),
227   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
228   mIndicatorOpacityMode(Dali::Window::OPAQUE),
229   mOverlay(NULL),
230   mAdaptor(NULL),
231   mEventHandler(NULL),
232   mPreferredOrientation(Dali::Window::PORTRAIT)
233 {
234 }
235
236 Window::~Window()
237 {
238   delete mEventHandler;
239
240   if( mIndicator )
241   {
242     mIndicator->Close();
243     delete mIndicator;
244   }
245
246   if ( mAdaptor )
247   {
248     mAdaptor->RemoveObserver( *this );
249     mAdaptor->SetDragAndDropDetector( NULL );
250     mAdaptor = NULL;
251   }
252
253   delete mSurface;
254 }
255
256 void Window::Initialize(const PositionSize& windowPosition, const std::string& name, const std::string& className)
257 {
258   // create an Wayland window by default
259   Any surface;
260   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, mIsTransparent );
261   SetClass( name, className );
262   windowSurface->Map();
263
264   mSurface = windowSurface;
265
266   std::string appId;
267   mAdaptor->GetAppId( appId );
268   Ecore_Wl_Window* wlWindow = windowSurface ->GetWlWindow();
269   ecore_wl_window_class_name_set(wlWindow, appId.c_str());
270
271   mOrientation = Orientation::New(this);
272
273   // create event handler for Wayland window
274   mEventHandler = new EventHandler( this );
275 }
276
277 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
278 {
279   if( mIndicator == NULL )
280   {
281     if( mIndicatorVisible != Dali::Window::INVISIBLE )
282     {
283       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
284       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
285       Dali::Actor actor = mIndicator->GetActor();
286       SetIndicatorActorRotation();
287       mOverlay->Add(actor);
288     }
289     // else don't create a hidden indicator
290   }
291   else // Already have indicator
292   {
293     if( mIndicatorVisible == Dali::Window::VISIBLE )
294     {
295       // If we are resuming, and rotation has changed,
296       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
297       {
298         // then close current indicator and open new one
299         mShowRotatedIndicatorOnClose = true;
300         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
301         // Don't show actor - will contain indicator for old orientation.
302       }
303     }
304   }
305
306   // set indicator visible mode
307   if( mIndicator != NULL )
308   {
309     mIndicator->SetVisible( mIndicatorVisible );
310   }
311
312   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
313   SetIndicatorProperties( show, lastOrientation );
314   mIndicatorIsShown = show;
315 }
316
317 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
318 {
319   if( mIndicatorIsShown )
320   {
321     mShowRotatedIndicatorOnClose = true;
322     mNextIndicatorOrientation = orientation;
323     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
324   }
325   else
326   {
327     // Save orientation for when the indicator is next shown
328     mShowRotatedIndicatorOnClose = false;
329     mNextIndicatorOrientation = orientation;
330   }
331 }
332
333 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
334 {
335   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
336
337   if( wlSurface )
338   {
339     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
340     if ( isShow )
341     {
342       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_ON);
343     }
344     else
345     {
346       ecore_wl_window_indicator_state_set(wlWindow, ECORE_WL_INDICATOR_STATE_OFF);
347     }
348   }
349 }
350
351 void Window::IndicatorTypeChanged(Indicator::Type type)
352 {
353 #if defined(DALI_PROFILE_MOBILE)
354   ECore::WindowRenderSurface* wlSurface( dynamic_cast< ECore::WindowRenderSurface * >( mSurface ) );
355
356   if( wlSurface )
357   {
358     Ecore_Wl_Window* wlWindow = wlSurface->GetWlWindow();
359     switch(type)
360     {
361       case Indicator::INDICATOR_TYPE_1:
362         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_SHOWN);
363         break;
364
365       case Indicator::INDICATOR_TYPE_2:
366         ecore_wl_indicator_visible_type_set(wlWindow, ECORE_WL_INDICATOR_VISIBLE_TYPE_HIDDEN);
367         break;
368
369       case Indicator::INDICATOR_TYPE_UNKNOWN:
370       default:
371         break;
372     }
373   }
374 #endif //MOBILE
375 }
376
377 void Window::IndicatorClosed( IndicatorInterface* indicator )
378 {
379   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
380
381   if( mShowRotatedIndicatorOnClose )
382   {
383     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
384     mIndicator->Open(mNextIndicatorOrientation);
385     mIndicatorOrientation = mNextIndicatorOrientation;
386     SetIndicatorActorRotation();
387     DoShowIndicator(currentOrientation);
388   }
389 }
390
391 void Window::IndicatorVisibilityChanged(bool isVisible)
392 {
393   mIndicatorVisibilityChangedSignal.Emit(isVisible);
394 }
395
396 void Window::SetIndicatorActorRotation()
397 {
398   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
399   DALI_ASSERT_DEBUG( mIndicator != NULL );
400
401   Dali::Actor actor = mIndicator->GetActor();
402   switch( mIndicatorOrientation )
403   {
404     case Dali::Window::PORTRAIT:
405       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
406       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
407       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
408       break;
409     case Dali::Window::PORTRAIT_INVERSE:
410       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
411       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
412       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
413       break;
414     case Dali::Window::LANDSCAPE:
415       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
416       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
417       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
418       break;
419     case Dali::Window::LANDSCAPE_INVERSE:
420       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
421       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
422       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
423       break;
424   }
425 }
426
427 void Window::Raise()
428 {
429 }
430
431 void Window::Lower()
432 {
433 }
434
435 void Window::Activate()
436 {
437 }
438
439 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
440 {
441   return mDragAndDropDetector;
442 }
443
444 Dali::Any Window::GetNativeHandle() const
445 {
446   if(mEventHandler)
447   {
448     return mEventHandler->mEcoreWindow;
449   }
450   else
451   {
452     return Dali::Any();
453   }
454 }
455
456 void Window::OnStart()
457 {
458   DoShowIndicator( mIndicatorOrientation );
459 }
460
461 void Window::OnPause()
462 {
463 }
464
465 void Window::OnResume()
466 {
467   // resume indicator status
468   if( mIndicator != NULL )
469   {
470     // Restore own indicator opacity
471     // Send opacity mode to indicator service when app resumed
472     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
473   }
474 }
475
476 void Window::OnStop()
477 {
478   if( mIndicator )
479   {
480     mIndicator->Close();
481   }
482
483   delete mIndicator;
484   mIndicator = NULL;
485 }
486
487 void Window::OnDestroy()
488 {
489   mAdaptor = NULL;
490 }
491
492 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
493 {
494   bool found = false;
495
496   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
497   {
498     if(mAvailableOrientations[i] == orientation)
499     {
500       found = true;
501       break;
502     }
503   }
504
505   if( ! found )
506   {
507     mAvailableOrientations.push_back(orientation);
508     SetAvailableOrientations( mAvailableOrientations );
509   }
510 }
511
512 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
513 {
514   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
515        iter != mAvailableOrientations.end(); ++iter )
516   {
517     if( *iter == orientation )
518     {
519       mAvailableOrientations.erase( iter );
520       break;
521     }
522   }
523   SetAvailableOrientations( mAvailableOrientations );
524 }
525
526 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
527 {
528   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
529 }
530
531 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
532 {
533   return mAvailableOrientations;
534 }
535
536 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
537 {
538   mPreferredOrientation = orientation;
539 }
540
541 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
542 {
543   return mPreferredOrientation;
544 }
545
546 void Window::RotationDone( int orientation, int width, int height )
547 {
548 }
549
550
551 } // Adaptor
552 } // Internal
553 } // Dali