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