[dali_1.0.4] Merge branch 'tizen'
[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::SetIndicatorStyle( Dali::Window::IndicatorStyle style )
152 {
153   mIndicatorStyle = style;
154 }
155
156 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
157 {
158   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "visible : %d\n", visibleMode );
159   DALI_ASSERT_DEBUG(mOverlay);
160
161   DoShowIndicator( mIndicatorOrientation );
162 }
163
164 void Window::RotateIndicator(Dali::Window::WindowOrientation orientation)
165 {
166   DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
167
168   DoRotateIndicator( orientation );
169 }
170
171 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
172 {
173   mIndicatorOpacityMode = opacityMode;
174
175   if( mIndicator != NULL )
176   {
177     mIndicator->SetOpacityMode( opacityMode );
178   }
179 }
180
181 void Window::SetClass(std::string name, std::string klass)
182 {
183 }
184
185 Window::Window()
186 : mSurface(NULL),
187   mIndicatorStyle(Dali::Window::CHANGEABLE_COLOR),
188   mIndicatorVisible(Dali::Window::VISIBLE),
189   mIndicatorIsShown(false),
190   mShowRotatedIndicatorOnClose(false),
191   mStarted(false),
192   mIsTransparent(false),
193   mWMRotationAppSet(false),
194   mIndicator(NULL),
195   mIndicatorOrientation(Dali::Window::PORTRAIT),
196   mNextIndicatorOrientation(Dali::Window::PORTRAIT),
197   mIndicatorOpacityMode(Dali::Window::OPAQUE),
198   mOverlay(NULL),
199   mAdaptor(NULL)
200 {
201 }
202
203 Window::~Window()
204 {
205   delete mEventHandler;
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   Any display;
222   mSurface = new ECore::WindowRenderSurface( windowPosition, surface, display, name, mIsTransparent );
223   mOrientation = Orientation::New(this);
224
225   // create event handler for Wayland window
226   mEventHandler = new EventHandler( this );
227 }
228
229 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
230 {
231   if( mIndicator == NULL )
232   {
233     if( mIndicatorVisible != Dali::Window::INVISIBLE )
234     {
235       mIndicator = new Indicator( mAdaptor, mIndicatorOrientation, mIndicatorStyle, this );
236       mIndicator->SetOpacityMode( mIndicatorOpacityMode );
237       Dali::Actor actor = mIndicator->GetActor();
238       SetIndicatorActorRotation();
239       mOverlay->Add(actor);
240     }
241     // else don't create a hidden indicator
242   }
243   else // Already have indicator
244   {
245     if( mIndicatorVisible == Dali::Window::VISIBLE )
246     {
247       // If we are resuming, and rotation has changed,
248       if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
249       {
250         // then close current indicator and open new one
251         mShowRotatedIndicatorOnClose = true;
252         mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
253         // Don't show actor - will contain indicator for old orientation.
254       }
255     }
256   }
257
258   // set indicator visible mode
259   if( mIndicator != NULL )
260   {
261     mIndicator->SetVisible( mIndicatorVisible );
262   }
263
264   bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
265   SetIndicatorProperties( show, lastOrientation );
266   mIndicatorIsShown = show;
267 }
268
269 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
270 {
271   if( mIndicatorIsShown )
272   {
273     mShowRotatedIndicatorOnClose = true;
274     mNextIndicatorOrientation = orientation;
275     mIndicator->Close(); // May synchronously call IndicatorClosed() callback
276   }
277   else
278   {
279     // Save orientation for when the indicator is next shown
280     mShowRotatedIndicatorOnClose = false;
281     mNextIndicatorOrientation = orientation;
282   }
283 }
284
285 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
286 {
287 }
288
289 void Window::IndicatorTypeChanged(Indicator::Type type)
290 {
291 }
292
293 void Window::IndicatorClosed( Indicator* indicator )
294 {
295   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
296
297   if( mShowRotatedIndicatorOnClose )
298   {
299     Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
300     mIndicator->Open(mNextIndicatorOrientation);
301     mIndicatorOrientation = mNextIndicatorOrientation;
302     SetIndicatorActorRotation();
303     DoShowIndicator(currentOrientation);
304   }
305 }
306
307 void Window::SetIndicatorActorRotation()
308 {
309   DALI_LOG_TRACE_METHOD( gWindowLogFilter );
310   DALI_ASSERT_DEBUG( mIndicator != NULL );
311
312   Dali::Actor actor = mIndicator->GetActor();
313   switch( mIndicatorOrientation )
314   {
315     case Dali::Window::PORTRAIT:
316       actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
317       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
318       actor.SetRotation( Degree(0), Vector3::ZAXIS );
319       break;
320     case Dali::Window::PORTRAIT_INVERSE:
321       actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
322       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
323       actor.SetRotation( Degree(180), Vector3::ZAXIS );
324       break;
325     case Dali::Window::LANDSCAPE:
326       actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
327       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
328       actor.SetRotation( Degree(270), Vector3::ZAXIS );
329       break;
330     case Dali::Window::LANDSCAPE_INVERSE:
331       actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
332       actor.SetAnchorPoint(  AnchorPoint::TOP_CENTER );
333       actor.SetRotation( Degree(90), Vector3::ZAXIS );
334       break;
335   }
336 }
337
338 void Window::Raise()
339 {
340 }
341
342 void Window::Lower()
343 {
344 }
345
346 void Window::Activate()
347 {
348 }
349
350 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
351 {
352   return mDragAndDropDetector;
353 }
354
355 void Window::OnStart()
356 {
357   DoShowIndicator( mIndicatorOrientation );
358 }
359
360 void Window::OnPause()
361 {
362 }
363
364 void Window::OnResume()
365 {
366   // resume indicator status
367   if( mIndicator != NULL )
368   {
369     // Restore own indicator opacity
370     // Send opacity mode to indicator service when app resumed
371     mIndicator->SetOpacityMode( mIndicatorOpacityMode );
372   }
373 }
374
375 void Window::OnStop()
376 {
377   if( mIndicator )
378   {
379     mIndicator->Close();
380   }
381
382   delete mIndicator;
383   mIndicator = NULL;
384 }
385
386 void Window::OnDestroy()
387 {
388   mAdaptor = NULL;
389 }
390
391 OrientationPtr Window::GetOrientation()
392 {
393   return mOrientation;
394 }
395
396 void Window::AddAvailableOrientation(Dali::Window::WindowOrientation orientation)
397 {
398   bool found = false;
399
400   for( std::size_t i=0; i<mAvailableOrientations.size(); i++ )
401   {
402     if(mAvailableOrientations[i] == orientation)
403     {
404       found = true;
405       break;
406     }
407   }
408
409   if( ! found )
410   {
411     mAvailableOrientations.push_back(orientation);
412     SetAvailableOrientations( mAvailableOrientations );
413   }
414 }
415
416 void Window::RemoveAvailableOrientation(Dali::Window::WindowOrientation orientation)
417 {
418   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
419        iter != mAvailableOrientations.end(); ++iter )
420   {
421     if( *iter == orientation )
422     {
423       mAvailableOrientations.erase( iter );
424       break;
425     }
426   }
427   SetAvailableOrientations( mAvailableOrientations );
428 }
429
430 void Window::SetAvailableOrientations(const std::vector<Dali::Window::WindowOrientation>& orientations)
431 {
432   DALI_ASSERT_ALWAYS( mAvailableOrientations.size() <= 4 && "Incorrect number of available orientations" );
433 }
434
435 const std::vector<Dali::Window::WindowOrientation>& Window::GetAvailableOrientations()
436 {
437   return mAvailableOrientations;
438 }
439
440 void Window::SetPreferredOrientation(Dali::Window::WindowOrientation orientation)
441 {
442   mPreferredOrientation = orientation;
443 }
444
445 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
446 {
447   return mPreferredOrientation;
448 }
449
450 void Window::RotationDone( int orientation, int width, int height )
451 {
452 }
453
454
455 } // Adaptor
456 } // Internal
457 } // Dali