Merge "Change a service name of the indicator and remove a unused indicator style...
[platform/core/uifw/dali-adaptor.git] / adaptors / wayland / window-impl-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 <indicator-impl.h>
35 #include <window-visibility-observer.h>
36 #include <orientation-impl.h>
37
38 namespace
39 {
40 const float INDICATOR_ANIMATION_DURATION( 0.18f ); // 180 milli seconds
41 const float INDICATOR_SHOW_Y_POSITION( 0.0f );
42 const float INDICATOR_HIDE_Y_POSITION( -52.0f );
43 }
44
45 namespace Dali
46 {
47 namespace Internal
48 {
49 namespace Adaptor
50 {
51 #if defined(DEBUG_ENABLED)
52 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_WINDOW");
53 #endif
54
55 /**
56  * TODO: Abstract Window class out and move this into a window implementation for Ecore
57  */
58 struct Window::EventHandler
59 {
60   /**
61    * Constructor
62    * @param[in]  window  A pointer to the window class.
63    */
64   EventHandler( Window* window )
65   : mWindow( window ),
66     mEcoreWindow( 0 )
67   {
68   }
69
70   /**
71    * Destructor
72    */
73   ~EventHandler()
74   {
75     if ( mWindowPropertyHandler )
76     {
77       ecore_event_handler_del( mWindowPropertyHandler );
78     }
79     if ( mClientMessagehandler )
80     {
81       ecore_event_handler_del( mClientMessagehandler );
82     }
83   }
84
85   // Static methods
86
87   /// Called when the window properties are changed.
88   static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
89   {
90     return EINA_FALSE;
91   }
92
93   /// Called when the window properties are changed.
94   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
95   {
96     return EINA_FALSE;
97   }
98
99   // Data
100   Window* mWindow;
101   Ecore_Event_Handler* mWindowPropertyHandler;
102   Ecore_Event_Handler* mClientMessagehandler;
103   Ecore_Wl_Window* mEcoreWindow;
104 };
105
106
107 Window* Window::New(const PositionSize& posSize, const std::string& name, bool isTransparent)
108 {
109   Window* window = new Window();
110   window->mIsTransparent = isTransparent;
111   window->Initialize(posSize, name);
112   return window;
113 }
114
115 void Window::SetAdaptor(Dali::Adaptor& adaptor)
116 {
117   DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
118   mStarted = true;
119
120   // Only create one overlay per window
121   Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
122   Integration::Core& core = adaptorImpl.GetCore();
123   mOverlay = &core.GetSystemOverlay();
124
125   Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
126   taskList.CreateTask();
127
128   mAdaptor = &adaptorImpl;
129   mAdaptor->AddObserver( *this );
130
131   // Can only create the detector when we know the Core has been instantiated.
132   mDragAndDropDetector = DragAndDropDetector::New();
133   mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
134
135   if( mOrientation )
136   {
137     mOrientation->SetAdaptor(adaptor);
138   }
139
140   if( mIndicator != NULL )
141   {
142     mIndicator->SetAdaptor(mAdaptor);
143   }
144 }
145
146 RenderSurface* Window::GetSurface()
147 {
148   return mSurface;
149 }
150
151 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
152 {
153   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
154   DALI_ASSERT_DEBUG(mOverlay);
155
156   DoShowIndicator( mIndicatorOrientation );
157 }
158
159 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
160 {
161   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
162
163   DoRotateIndicator( orientation );
164 }
165
166 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
167 {
168   mIndicatorOpacityMode = opacityMode;
169
170   if( mIndicator != NULL )
171   {
172     mIndicator->SetOpacityMode( opacityMode );
173   }
174 }
175
176 void Window::SetClass(std::string name, std::string klass)
177 {
178 }
179
180 Window::Window()
181 : mSurface(NULL),
182   mIndicatorVisible(Dali::Window::VISIBLE),
183   mIndicatorIsShown(false),
184   mShowRotatedIndicatorOnClose(false),
185   mStarted(false),
186   mIsTransparent(false),
187   mWMRotationAppSet(false),
188   mIndicator(NULL),
189   mIndicatorOrientation(Dali::Window::PORTRAIT),
190   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
191   mIndicatorOpacityMode(Dali::Window::OPAQUE),
192   mOverlay(NULL),
193   mAdaptor(NULL)
194 {
195 }
196
197 Window::~Window()
198 {
199   delete mEventHandler;
200
201   if( mIndicator )
202   {
203     mIndicator->Close();
204     delete mIndicator;
205   }
206
207   if ( mAdaptor )
208   {
209     mAdaptor->RemoveObserver( *this );
210     mAdaptor->SetDragAndDropDetector( NULL );
211     mAdaptor = NULL;
212   }
213
214   delete mSurface;
215 }
216
217 void Window::Initialize(const PositionSize& windowPosition, const std::string& name)
218 {
219   // create an Wayland window by default
220   Any surface;
221   ECore::WindowRenderSurface* windowSurface = new ECore::WindowRenderSurface( windowPosition, surface, name, mIsTransparent );
222   windowSurface->Map();
223
224   mSurface = windowSurface;
225
226   mOrientation = Orientation::New(this);
227
228   // create event handler for Wayland window
229   mEventHandler = new EventHandler( this );
230 }
231
232 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
233 {
234   if( mIndicator == NULL )
235   {
236     if( mIndicatorVisible != Dali::Window::INVISIBLE )
237     {
238       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, this );
239       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
240       Dali::Actor actor = mIndicator->GetActor();
241       SetIndicatorActorRotation();
242       mOverlay->Add(actor);
243     }
244     // else don't create a hidden indicator
245   }
246   else // Already have indicator
247   {
248     if( mIndicatorVisible == Dali::Window::VISIBLE )
249     {
250       // If we are resuming, and rotation has changed,
251       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
252       {
253         // then close current indicator and open new one
254         mShowRotatedIndicatorOnClose = true;
255         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
256         // Don't show actor - will contain indicator for old orientation.
257       }
258     }
259   }
260
261   // set indicator visible mode
262   if( mIndicator != NULL )
263   {
264     mIndicator->SetVisible( mIndicatorVisible );
265   }
266
267   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
268   SetIndicatorProperties( show, lastOrientation );
269   mIndicatorIsShown = show;
270 }
271
272 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
273 {
274   if( mIndicatorIsShown )
275   {
276     mShowRotatedIndicatorOnClose = true;
277     mNextIndicatorOrientation = orientation;
278     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
279   }
280   else
281   {
282     // Save orientation for when the indicator is next shown
283     mShowRotatedIndicatorOnClose = false;
284     mNextIndicatorOrientation = orientation;
285   }
286 }
287
288 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
289 {
290 }
291
292 void Window::IndicatorTypeChanged(Indicator::Type type)
293 {
294 }
295
296 void Window::IndicatorClosed( Indicator* indicator )
297 {
298   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
299
300   if( mShowRotatedIndicatorOnClose )
301   {
302     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
303     mIndicator->Open(mNextIndicatorOrientation);
304     mIndicatorOrientation = mNextIndicatorOrientation;
305     SetIndicatorActorRotation();
306     DoShowIndicator(currentOrientation);
307   }
308 }
309
310 void Window::IndicatorVisibilityChanged(bool isVisible)
311 {
312   mIndicatorVisibilityChangedSignal.Emit(isVisible);
313 }
314
315 void Window::SetIndicatorActorRotation()
316 {
317   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
318   DALI_ASSERT_DEBUG( mIndicator != NULL );
319
320   Dali::Actor actor = mIndicator->GetActor();
321   switch( mIndicatorOrientation )
322   {
323     case Dali::Window::PORTRAIT:
324       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
325       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
326       actor.SetOrientation( Degree(0), Vector3::ZAXIS );
327       break;
328     case Dali::Window::PORTRAIT_INVERSE:
329       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
330       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
331       actor.SetOrientation( Degree(180), Vector3::ZAXIS );
332       break;
333     case Dali::Window::LANDSCAPE:
334       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
335       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
336       actor.SetOrientation( Degree(270), Vector3::ZAXIS );
337       break;
338     case Dali::Window::LANDSCAPE_INVERSE:
339       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
340       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
341       actor.SetOrientation( Degree(90), Vector3::ZAXIS );
342       break;
343   }
344 }
345
346 void Window::Raise()
347 {
348 }
349
350 void Window::Lower()
351 {
352 }
353
354 void Window::Activate()
355 {
356 }
357
358 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
359 {
360   return mDragAndDropDetector;
361 }
362
363 Dali::Any Window::GetNativeHandle() const
364 {
365   if(mEventHandler)
366   {
367     return mEventHandler->mEcoreWindow;
368   }
369   else
370   {
371     return Dali::Any();
372   }
373 }
374
375 void Window::OnStart()
376 {
377   DoShowIndicator( mIndicatorOrientation );
378 }
379
380 void Window::OnPause()
381 {
382 }
383
384 void Window::OnResume()
385 {
386   // resume indicator status
387   if( mIndicator != NULL )
388   {
389     // Restore own indicator opacity
390     // Send opacity mode to indicator service when app resumed
391     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
392   }
393 }
394
395 void Window::OnStop()
396 {
397   if( mIndicator )
398   {
399     mIndicator->Close();
400   }
401
402   delete mIndicator;
403   mIndicator = NULL;
404 }
405
406 void Window::OnDestroy()
407 {
408   mAdaptor = NULL;
409 }
410
411 OrientationPtr Window::GetOrientation()
412 {
413   return mOrientation;
414 }
415
416 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
417 {
418   bool found = false;
419
420   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
421   {
422     if(mAvailableOrientations[i] == orientation)
423     {
424       found = true;
425       break;
426     }
427   }
428
429   if( ! found )
430   {
431     mAvailableOrientations.push_back(orientation);
432     SetAvailableOrientations( mAvailableOrientations );
433   }
434 }
435
436 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
437 {
438   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
439        iter != mAvailableOrientations.end(); ++iter )
440   {
441     if( *iter == orientation )
442     {
443       mAvailableOrientations.erase( iter );
444       break;
445     }
446   }
447   SetAvailableOrientations( mAvailableOrientations );
448 }
449
450 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
451 {
452   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
453 }
454
455 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
456 {
457   return mAvailableOrientations;
458 }
459
460 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
461 {
462   mPreferredOrientation = orientation;
463 }
464
465 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
466 {
467   return mPreferredOrientation;
468 }
469
470 void Window::RotationDone( int orientation, int width, int height )
471 {
472 }
473
474
475 } // Adaptor
476 } // Internal
477 } // Dali