e4b5975b1931399b9967f56e01fbddaeee441914
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / ubuntu-x11 / window-base-ecore-x.cpp
1 /*
2  * Copyright (c) 2018 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 // Ecore is littered with C style cast
19 #pragma GCC diagnostic push
20 #pragma GCC diagnostic ignored "-Wold-style-cast"
21
22 // CLASS HEADER
23 #include <dali/internal/window-system/ubuntu-x11/window-base-ecore-x.h>
24
25 // INTERNAL HEADERS
26 #include <dali/internal/window-system/common/window-impl.h>
27 #include <dali/internal/window-system/common/window-render-surface.h>
28 #include <dali/internal/window-system/ubuntu-x11/ecore-x-types.h>
29
30 // EXTERNAL_HEADERS
31 #include <dali/public-api/object/any.h>
32 #include <dali/integration-api/debug.h>
33 #include <Ecore_Input.h>
34
35 namespace Dali
36 {
37
38 namespace Internal
39 {
40
41 namespace Adaptor
42 {
43
44 namespace
45 {
46
47 const std::string DEFAULT_DEVICE_NAME = "";
48 const Device::Class::Type DEFAULT_DEVICE_CLASS = Device::Class::NONE;
49 const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE;
50
51 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
52
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gWindowBaseLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW_BASE" );
55 #endif
56
57 /////////////////////////////////////////////////////////////////////////////////////////////////
58 // Window Callbacks
59 /////////////////////////////////////////////////////////////////////////////////////////////////
60
61 static Eina_Bool EcoreEventWindowPropertyChanged( void* data, int type, void* event )
62 {
63   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
64   if( windowBase )
65   {
66     return windowBase->OnWindowPropertyChanged( data, type, event );
67   }
68
69   return ECORE_CALLBACK_PASS_ON;
70 }
71
72 /**
73  * Called when the window receives a delete request
74  */
75 static Eina_Bool EcoreEventWindowDeleteRequest( void* data, int type, void* event )
76 {
77   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
78   if( windowBase )
79   {
80     windowBase->OnDeleteRequest();
81   }
82   return ECORE_CALLBACK_DONE;
83 }
84
85 /**
86  * Called when the window gains focus.
87  */
88 static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
89 {
90   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
91   if( windowBase )
92   {
93     windowBase->OnFocusIn( data, type, event );
94   }
95   return ECORE_CALLBACK_PASS_ON;
96 }
97
98 /**
99  * Called when the window loses focus.
100  */
101 static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
102 {
103   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
104   if( windowBase )
105   {
106     windowBase->OnFocusOut( data, type, event );
107   }
108   return ECORE_CALLBACK_PASS_ON;
109 }
110
111 /**
112  * Called when the window is damaged.
113  */
114 static Eina_Bool EcoreEventWindowDamaged( void* data, int type, void* event )
115 {
116   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
117   if( windowBase )
118   {
119     windowBase->OnWindowDamaged( data, type, event );
120   }
121
122   return ECORE_CALLBACK_PASS_ON;
123 }
124
125 /////////////////////////////////////////////////////////////////////////////////////////////////
126 // Selection Callbacks
127 /////////////////////////////////////////////////////////////////////////////////////////////////
128
129 /**
130  * Called when the source window notifies us the content in clipboard is selected.
131  */
132 static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
133 {
134   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
135   if( windowBase )
136   {
137     windowBase->OnSelectionClear( data, type, event );
138   }
139   return ECORE_CALLBACK_PASS_ON;
140 }
141
142 /**
143  * Called when the source window sends us about the selected content.
144  * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
145  */
146 static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
147 {
148   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
149   if( windowBase )
150   {
151     windowBase->OnSelectionNotify( data, type, event );
152   }
153   return ECORE_CALLBACK_PASS_ON;
154 }
155
156 /////////////////////////////////////////////////////////////////////////////////////////////////
157 // Touch Callbacks
158 /////////////////////////////////////////////////////////////////////////////////////////////////
159
160 /**
161  * Called when a touch down is received.
162  */
163 static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
164 {
165   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
166   if( windowBase )
167   {
168     windowBase->OnMouseButtonDown( data, type, event );
169   }
170   return ECORE_CALLBACK_PASS_ON;
171 }
172
173 /**
174  * Called when a touch up is received.
175  */
176 static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
177 {
178   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
179   if( windowBase )
180   {
181     windowBase->OnMouseButtonUp( data, type, event );
182   }
183   return ECORE_CALLBACK_PASS_ON;
184 }
185
186 /**
187  * Called when a touch motion is received.
188  */
189 static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
190 {
191   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
192   if( windowBase )
193   {
194     windowBase->OnMouseButtonMove( data, type, event );
195   }
196   return ECORE_CALLBACK_PASS_ON;
197 }
198
199 /////////////////////////////////////////////////////////////////////////////////////////////////
200 // Wheel Callbacks
201 /////////////////////////////////////////////////////////////////////////////////////////////////
202
203 /**
204  * Called when a mouse wheel is received.
205  */
206 static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
207 {
208   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
209   if( windowBase )
210   {
211     windowBase->OnMouseWheel( data, type, event );
212   }
213   return ECORE_CALLBACK_PASS_ON;
214 }
215
216 /////////////////////////////////////////////////////////////////////////////////////////////////
217 // Key Callbacks
218 /////////////////////////////////////////////////////////////////////////////////////////////////
219
220 /**
221  * Called when a key down is received.
222  */
223 static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
224 {
225   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
226   if( windowBase )
227   {
228     windowBase->OnKeyDown( data, type, event );
229   }
230   return ECORE_CALLBACK_PASS_ON;
231 }
232
233 /**
234  * Called when a key up is received.
235  */
236 static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
237 {
238   WindowBaseEcoreX* windowBase = static_cast< WindowBaseEcoreX* >( data );
239   if( windowBase )
240   {
241     windowBase->OnKeyUp( data, type, event );
242   }
243   return ECORE_CALLBACK_PASS_ON;
244 }
245
246 } // unnamed namespace
247
248 WindowBaseEcoreX::WindowBaseEcoreX( Dali::PositionSize positionSize, Any surface, bool isTransparent )
249 : mEcoreEventHandler(),
250   mEcoreWindow( 0 ),
251   mOwnSurface( false ),
252   mIsTransparent( false ), // Should only be set to true once we actually create a transparent window regardless of what isTransparent is.
253   mRotationAppSet( false )
254 {
255   Initialize( positionSize, surface, isTransparent );
256 }
257
258 WindowBaseEcoreX::~WindowBaseEcoreX()
259 {
260   for( Dali::Vector< Ecore_Event_Handler* >::Iterator iter = mEcoreEventHandler.Begin(), endIter = mEcoreEventHandler.End(); iter != endIter; ++iter )
261   {
262     ecore_event_handler_del( *iter );
263   }
264   mEcoreEventHandler.Clear();
265
266   if( mOwnSurface )
267   {
268     ecore_x_window_free( mEcoreWindow );
269   }
270 }
271
272 void WindowBaseEcoreX::Initialize( PositionSize positionSize, Any surface, bool isTransparent )
273 {
274   // see if there is a surface in Any surface
275   unsigned int surfaceId = GetSurfaceId( surface );
276
277   // if the surface is empty, create a new one.
278   if( surfaceId == 0 )
279   {
280     // we own the surface about to created
281     mOwnSurface = true;
282     CreateWindow( positionSize, isTransparent );
283   }
284   else
285   {
286     // XLib should already be initialized so no point in calling XInitThreads
287     mEcoreWindow = static_cast< Ecore_X_Window >( surfaceId );
288   }
289
290   // set up etc properties to match with ecore-evas
291   char *id = NULL;
292   if( ( id = getenv("DESKTOP_STARTUP_ID") ) )
293   {
294     ecore_x_netwm_startup_id_set( mEcoreWindow, id );
295   }
296
297   ecore_x_icccm_hints_set( mEcoreWindow,
298                            1,                                // accepts_focus
299                            ECORE_X_WINDOW_STATE_HINT_NORMAL, // initial_state
300                            0,                                // icon_pixmap
301                            0,                                // icon_mask
302                            0,                                // icon_window
303                            0,                                // window_group
304                            0 );                              // is_urgent
305
306   // we SHOULD guarantee the x11 window was created in x server.
307   ecore_x_sync();
308
309   ecore_x_input_multi_select( mEcoreWindow );
310
311   // This ensures that we catch the window close (or delete) request
312   ecore_x_icccm_protocol_set( mEcoreWindow, ECORE_X_WM_PROTOCOL_DELETE_REQUEST, EINA_TRUE );
313
314   // Enable Drag & Drop
315   ecore_x_dnd_aware_set( mEcoreWindow, EINA_TRUE );
316
317   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_PROPERTY,       EcoreEventWindowPropertyChanged, this ) );
318   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DELETE_REQUEST, EcoreEventWindowDeleteRequest,   this ) );
319
320   // Register window focus events
321   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN,       EcoreEventWindowFocusIn,   this ) );
322   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT,      EcoreEventWindowFocusOut,  this ) );
323
324   // Register Window damage events
325   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE,         EcoreEventWindowDamaged,   this ) );
326
327   // Register Touch events
328   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,       EcoreEventMouseButtonDown, this ) );
329   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,         EcoreEventMouseButtonUp,   this ) );
330   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,              EcoreEventMouseButtonMove, this ) );
331   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT,               EcoreEventMouseButtonUp,   this ) ); // process mouse out event like up event
332
333   // Register Mouse wheel events
334   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,             EcoreEventMouseWheel,      this ) );
335
336   // Register Key events
337   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,                EcoreEventKeyDown,         this ) );
338   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_EVENT_KEY_UP,                  EcoreEventKeyUp,           this ) );
339
340   // Register Selection event
341   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR,       EcoreEventSelectionClear,  this ) );
342   mEcoreEventHandler.PushBack( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY,      EcoreEventSelectionNotify, this ) );
343 }
344
345 Eina_Bool WindowBaseEcoreX::OnWindowPropertyChanged( void* data, int type, void* event )
346 {
347   Ecore_X_Event_Window_Property* propertyChangedEvent = static_cast< Ecore_X_Event_Window_Property* >( event );
348   Eina_Bool handled( ECORE_CALLBACK_PASS_ON );
349
350   if( propertyChangedEvent->win == mEcoreWindow )
351   {
352     Ecore_X_Window_State_Hint state( ecore_x_icccm_state_get( propertyChangedEvent->win ) );
353
354     switch( state )
355     {
356       case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN:
357       {
358         // Window was hidden.
359         mIconifyChangedSignal.Emit( true );
360         handled = ECORE_CALLBACK_DONE;
361         break;
362       }
363       case ECORE_X_WINDOW_STATE_HINT_ICONIC:
364       {
365         // Window was iconified (minimised).
366         mIconifyChangedSignal.Emit( true );
367         handled = ECORE_CALLBACK_DONE;
368         break;
369       }
370       case ECORE_X_WINDOW_STATE_HINT_NORMAL:
371       {
372         // Window was shown.
373         mIconifyChangedSignal.Emit( false );
374         handled = ECORE_CALLBACK_DONE;
375         break;
376       }
377       default:
378       {
379         // Ignore
380         break;
381       }
382     }
383   }
384
385   return handled;
386 }
387
388 void WindowBaseEcoreX::OnDeleteRequest()
389 {
390   mDeleteRequestSignal.Emit();
391 }
392
393 void WindowBaseEcoreX::OnFocusIn( void* data, int type, void* event )
394 {
395   Ecore_X_Event_Window_Focus_In* focusInEvent = static_cast< Ecore_X_Event_Window_Focus_In* >( event );
396
397   if( focusInEvent->win == mEcoreWindow )
398   {
399     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusIn\n" );
400
401     mFocusChangedSignal.Emit( true );
402   }
403 }
404
405 void WindowBaseEcoreX::OnFocusOut( void* data, int type, void* event )
406 {
407   Ecore_X_Event_Window_Focus_Out* focusOutEvent = static_cast< Ecore_X_Event_Window_Focus_Out* >( event );
408
409   // If the window loses focus then hide the keyboard.
410   if( focusOutEvent->win == mEcoreWindow )
411   {
412     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "Window EcoreEventWindowFocusOut\n" );
413
414     mFocusChangedSignal.Emit( false );
415   }
416 }
417
418 void WindowBaseEcoreX::OnWindowDamaged( void* data, int type, void* event )
419 {
420   Ecore_X_Event_Window_Damage* windowDamagedEvent = static_cast< Ecore_X_Event_Window_Damage* >( event );
421
422   if( windowDamagedEvent->win == mEcoreWindow )
423   {
424     DamageArea area;
425     area.x = windowDamagedEvent->x;
426     area.y = windowDamagedEvent->y;
427     area.width = windowDamagedEvent->w;
428     area.height = windowDamagedEvent->h;
429
430     mWindowDamagedSignal.Emit( area );
431   }
432 }
433
434 void WindowBaseEcoreX::OnMouseButtonDown( void* data, int type, void* event )
435 {
436   Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event );
437
438   if( touchEvent->window == mEcoreWindow )
439   {
440     PointState::Type state ( PointState::DOWN );
441
442     // Check if the buttons field is set and ensure it's the primary touch button.
443     // If this event was triggered by buttons other than the primary button (used for touch), then
444     // just send an interrupted event to Core.
445     if( touchEvent->buttons && ( touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
446     {
447       state = PointState::INTERRUPTED;
448     }
449
450     Integration::Point point;
451     point.SetDeviceId( touchEvent->multi.device );
452     point.SetState( state );
453     point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
454     point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
455     point.SetPressure( touchEvent->multi.pressure );
456     point.SetAngle( Degree( touchEvent->multi.angle ) );
457
458     mTouchEventSignal.Emit( point, touchEvent->timestamp );
459   }
460 }
461
462 void WindowBaseEcoreX::OnMouseButtonUp( void* data, int type, void* event )
463 {
464   Ecore_Event_Mouse_Button* touchEvent = static_cast< Ecore_Event_Mouse_Button* >( event );
465
466   if( touchEvent->window == mEcoreWindow )
467   {
468     Integration::Point point;
469     point.SetDeviceId( touchEvent->multi.device );
470     point.SetState( PointState::UP );
471     point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
472     point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
473     point.SetPressure( touchEvent->multi.pressure );
474     point.SetAngle( Degree( touchEvent->multi.angle ) );
475
476     mTouchEventSignal.Emit( point, touchEvent->timestamp );
477   }
478 }
479
480 void WindowBaseEcoreX::OnMouseButtonMove( void* data, int type, void* event )
481 {
482   Ecore_Event_Mouse_Move* touchEvent = static_cast< Ecore_Event_Mouse_Move* >( event );
483
484   if( touchEvent->window == mEcoreWindow )
485   {
486     Integration::Point point;
487     point.SetDeviceId( touchEvent->multi.device );
488     point.SetState( PointState::MOTION );
489     point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
490     point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
491     point.SetPressure( touchEvent->multi.pressure );
492     point.SetAngle( Degree( touchEvent->multi.angle ) );
493
494     mTouchEventSignal.Emit( point, touchEvent->timestamp );
495   }
496 }
497
498 void WindowBaseEcoreX::OnMouseWheel( void* data, int type, void* event )
499 {
500   Ecore_Event_Mouse_Wheel* mouseWheelEvent = static_cast< Ecore_Event_Mouse_Wheel* >( event );
501
502   if( mouseWheelEvent->window == mEcoreWindow )
503   {
504     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreX::OnMouseWheel: direction: %d, modifiers: %d, x: %d, y: %d, z: %d\n", mouseWheelEvent->direction, mouseWheelEvent->modifiers, mouseWheelEvent->x, mouseWheelEvent->y, mouseWheelEvent->z );
505
506     WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2( mouseWheelEvent->x, mouseWheelEvent->y ), mouseWheelEvent->z, mouseWheelEvent->timestamp );
507
508     mWheelEventSignal.Emit( wheelEvent );
509   }
510 }
511
512 void WindowBaseEcoreX::OnKeyDown( void* data, int type, void* event )
513 {
514   Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event );
515
516   if( keyEvent->window == mEcoreWindow )
517   {
518     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreX::OnKeyDown\n" );
519
520     std::string keyName( keyEvent->keyname );
521     std::string keyString( "" );
522     std::string compose( "" );
523
524     // Ensure key compose string is not NULL as keys like SHIFT or arrow have a null string.
525     if( keyEvent->compose )
526     {
527       compose = keyEvent->compose;
528     }
529
530     int keyCode = ecore_x_keysym_keycode_get( keyEvent->keyname );
531     int modifier( keyEvent->modifiers );
532     unsigned long time = keyEvent->timestamp;
533
534     // Ensure key event string is not NULL as keys like SHIFT have a null string.
535     if( keyEvent->string )
536     {
537       keyString = keyEvent->string;
538     }
539
540     Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );
541
542     mKeyEventSignal.Emit( keyEvent );
543   }
544 }
545
546 void WindowBaseEcoreX::OnKeyUp( void* data, int type, void* event )
547 {
548   Ecore_Event_Key* keyEvent = static_cast< Ecore_Event_Key* >( event );
549
550   if ( keyEvent->window == mEcoreWindow )
551   {
552     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::General, " WindowBaseEcoreX::OnKeyUp\n" );
553
554     std::string keyName( keyEvent->keyname );
555     std::string keyString( "" );
556     std::string compose( "" );
557
558     // Ensure key compose string is not NULL as keys like SHIFT or arrow have a null string.
559     if( keyEvent->compose )
560     {
561       compose = keyEvent->compose;
562     }
563     int keyCode = ecore_x_keysym_keycode_get( keyEvent->keyname );
564     int modifier( keyEvent->modifiers );
565     unsigned long time( keyEvent->timestamp );
566
567     // Ensure key event string is not NULL as keys like SHIFT have a null string.
568     if( keyEvent->string )
569     {
570       keyString = keyEvent->string;
571     }
572
573     Integration::KeyEvent keyEvent( keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );
574
575     mKeyEventSignal.Emit( keyEvent );
576   }
577 }
578
579 void WindowBaseEcoreX::OnSelectionClear( void* data, int type, void* event )
580 {
581   Ecore_X_Event_Selection_Clear* selectionClearEvent = static_cast< Ecore_X_Event_Selection_Clear* >( event );
582
583   if( selectionClearEvent->win == mEcoreWindow )
584   {
585     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, " WindowBaseEcoreX::OnSelectionClear\n" );
586
587     if( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY )
588     {
589       // Request to get the content from Ecore.
590       ecore_x_selection_secondary_request( selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT );
591     }
592   }
593 }
594
595 void WindowBaseEcoreX::OnSelectionNotify( void* data, int type, void* event )
596 {
597   Ecore_X_Event_Selection_Notify* selectionNotifyEvent = static_cast< Ecore_X_Event_Selection_Notify* >( event );
598
599   if( selectionNotifyEvent->win == mEcoreWindow )
600   {
601     DALI_LOG_INFO( gWindowBaseLogFilter, Debug::Concise, " WindowBaseEcoreX::OnSelectionNotify\n" );
602
603     Ecore_X_Selection_Data* selectionData = static_cast< Ecore_X_Selection_Data* >( selectionNotifyEvent->data );
604     if( selectionData->data )
605     {
606       if( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY )
607       {
608         mSelectionDataReceivedSignal.Emit( event  );
609       }
610     }
611   }
612 }
613
614 Any WindowBaseEcoreX::GetNativeWindow()
615 {
616   return mEcoreWindow;
617 }
618
619 int WindowBaseEcoreX::GetNativeWindowId()
620 {
621   return mEcoreWindow;
622 }
623
624 EGLNativeWindowType WindowBaseEcoreX::CreateEglWindow( int width, int height )
625 {
626   // need to create X handle as in 64bit system ECore handle is 32 bit whereas EGLnative and XWindow are 64 bit
627   XWindow window( mEcoreWindow );
628   return reinterpret_cast< EGLNativeWindowType >( window );
629 }
630
631 void WindowBaseEcoreX::DestroyEglWindow()
632 {
633 }
634
635 void WindowBaseEcoreX::SetEglWindowRotation( int angle )
636 {
637 }
638
639 void WindowBaseEcoreX::SetEglWindowBufferTransform( int angle )
640 {
641 }
642
643 void WindowBaseEcoreX::SetEglWindowTransform( int angle )
644 {
645 }
646
647 void WindowBaseEcoreX::ResizeEglWindow( PositionSize positionSize )
648 {
649 }
650
651 bool WindowBaseEcoreX::IsEglWindowRotationSupported()
652 {
653   return false;
654 }
655
656 void WindowBaseEcoreX::Move( PositionSize positionSize )
657 {
658   ecore_x_window_move( mEcoreWindow, positionSize.x, positionSize.y );
659 }
660
661 void WindowBaseEcoreX::Resize( PositionSize positionSize )
662 {
663   ecore_x_window_resize( mEcoreWindow, positionSize.width, positionSize.height );
664 }
665
666 void WindowBaseEcoreX::MoveResize( PositionSize positionSize )
667 {
668   ecore_x_window_move_resize( mEcoreWindow, positionSize.x, positionSize.y, positionSize.width, positionSize.height );
669 }
670
671 void WindowBaseEcoreX::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode, Dali::Window::IndicatorBgOpacity opacityMode )
672 {
673   DALI_LOG_TRACE_METHOD_FMT( gWindowBaseLogFilter, "visible : %d\n", visibleMode );
674
675   if( visibleMode == Dali::Window::VISIBLE )
676   {
677     // when the indicator is visible, set proper mode for indicator server according to bg mode
678     if( opacityMode == Dali::Window::OPAQUE )
679     {
680       ecore_x_e_illume_indicator_opacity_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_OPAQUE );
681     }
682     else if( opacityMode == Dali::Window::TRANSLUCENT )
683     {
684       ecore_x_e_illume_indicator_opacity_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_TRANSLUCENT );
685     }
686   }
687   else
688   {
689     // when the indicator is not visible, set TRANSPARENT mode for indicator server
690     ecore_x_e_illume_indicator_opacity_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_TRANSPARENT ); // it means hidden indicator
691   }
692 }
693
694 void WindowBaseEcoreX::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
695 {
696   int show_state = static_cast< int >( isShow );
697   ecore_x_window_prop_property_set( mEcoreWindow, ECORE_X_ATOM_E_ILLUME_INDICATOR_STATE,
698                                     ECORE_X_ATOM_CARDINAL, 32, &show_state, 1 );
699
700   if( isShow )
701   {
702     ecore_x_e_illume_indicator_state_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_STATE_ON );
703   }
704   else
705   {
706     ecore_x_e_illume_indicator_state_set( mEcoreWindow, ECORE_X_ILLUME_INDICATOR_STATE_OFF );
707   }
708 }
709
710 void WindowBaseEcoreX::IndicatorTypeChanged( IndicatorInterface::Type type )
711 {
712 }
713
714 void WindowBaseEcoreX::SetClass( const std::string& name, const std::string& className )
715 {
716   ecore_x_icccm_title_set( mEcoreWindow, name.c_str() );
717   ecore_x_netwm_name_set( mEcoreWindow, name.c_str() );
718   ecore_x_icccm_name_class_set( mEcoreWindow, name.c_str(), className.c_str() );
719 }
720
721 void WindowBaseEcoreX::Raise()
722 {
723   ecore_x_window_raise( mEcoreWindow );
724 }
725
726 void WindowBaseEcoreX::Lower()
727 {
728   ecore_x_window_lower( mEcoreWindow );
729 }
730
731 void WindowBaseEcoreX::Activate()
732 {
733   ecore_x_netwm_client_active_request( ecore_x_window_root_get( mEcoreWindow ), mEcoreWindow, 1 /* request type, 1:application, 2:pager */, 0 );
734 }
735
736 void WindowBaseEcoreX::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
737 {
738 }
739
740 void WindowBaseEcoreX::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
741 {
742 }
743
744 void WindowBaseEcoreX::SetAcceptFocus( bool accept )
745 {
746 }
747
748 void WindowBaseEcoreX::Show()
749 {
750   ecore_x_window_show( mEcoreWindow );
751 }
752
753 void WindowBaseEcoreX::Hide()
754 {
755   ecore_x_window_hide( mEcoreWindow );
756 }
757
758 unsigned int WindowBaseEcoreX::GetSupportedAuxiliaryHintCount() const
759 {
760   return 0;
761 }
762
763 std::string WindowBaseEcoreX::GetSupportedAuxiliaryHint( unsigned int index ) const
764 {
765   return std::string();
766 }
767
768 unsigned int WindowBaseEcoreX::AddAuxiliaryHint( const std::string& hint, const std::string& value )
769 {
770   return 0;
771 }
772
773 bool WindowBaseEcoreX::RemoveAuxiliaryHint( unsigned int id )
774 {
775   return false;
776 }
777
778 bool WindowBaseEcoreX::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
779 {
780   return false;
781 }
782
783 std::string WindowBaseEcoreX::GetAuxiliaryHintValue( unsigned int id ) const
784 {
785   return std::string();
786 }
787
788 unsigned int WindowBaseEcoreX::GetAuxiliaryHintId( const std::string& hint ) const
789 {
790   return 0;
791 }
792
793 void WindowBaseEcoreX::SetInputRegion( const Rect< int >& inputRegion )
794 {
795 }
796
797 void WindowBaseEcoreX::SetType( Dali::Window::Type type )
798 {
799 }
800
801 bool WindowBaseEcoreX::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
802 {
803   return false;
804 }
805
806 Dali::Window::NotificationLevel::Type WindowBaseEcoreX::GetNotificationLevel() const
807 {
808   return Dali::Window::NotificationLevel::NONE;
809 }
810
811 void WindowBaseEcoreX::SetOpaqueState( bool opaque )
812 {
813 }
814
815 bool WindowBaseEcoreX::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
816 {
817   return false;
818 }
819
820 Dali::Window::ScreenOffMode::Type WindowBaseEcoreX::GetScreenOffMode() const
821 {
822   return Dali::Window::ScreenOffMode::TIMEOUT;
823 }
824
825 bool WindowBaseEcoreX::SetBrightness( int brightness )
826 {
827   return false;
828 }
829
830 int WindowBaseEcoreX::GetBrightness() const
831 {
832   return 0;
833 }
834
835 bool WindowBaseEcoreX::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
836 {
837   return false;
838 }
839
840 bool WindowBaseEcoreX::UngrabKey( Dali::KEY key )
841 {
842   return false;
843 }
844
845 bool WindowBaseEcoreX::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
846 {
847   return false;
848 }
849
850 bool WindowBaseEcoreX::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
851 {
852   return false;
853 }
854
855 void WindowBaseEcoreX::GetDpi( unsigned int& dpiHorizontal, unsigned int& dpiVertical )
856 {
857   // calculate DPI
858   float xres, yres;
859
860   // 1 inch = 25.4 millimeters
861   xres = ecore_x_dpi_get();
862   yres = ecore_x_dpi_get();
863
864   dpiHorizontal = int( xres + 0.5f );  // rounding
865   dpiVertical   = int( yres + 0.5f );
866 }
867
868 void WindowBaseEcoreX::SetViewMode( ViewMode viewMode )
869 {
870   Ecore_X_Atom viewModeAtom( ecore_x_atom_get( "_E_COMP_3D_APP_WIN" ) );
871
872   if( viewModeAtom != None )
873   {
874     unsigned int value( static_cast< unsigned int >( viewMode ) );
875     ecore_x_window_prop_card32_set( mEcoreWindow, viewModeAtom, &value, 1 );
876   }
877 }
878
879 int WindowBaseEcoreX::GetScreenRotationAngle()
880 {
881   return 0;
882 }
883
884 void WindowBaseEcoreX::SetWindowRotationAngle( int degree )
885 {
886 }
887
888 void WindowBaseEcoreX::WindowRotationCompleted( int degree, int width, int height )
889 {
890 }
891
892 void WindowBaseEcoreX::SetTransparency( bool transparent )
893 {
894 }
895
896 unsigned int WindowBaseEcoreX::GetSurfaceId( Any surface ) const
897 {
898   unsigned int surfaceId = 0;
899
900   if ( surface.Empty() == false )
901   {
902     // check we have a valid type
903     DALI_ASSERT_ALWAYS( ( (surface.GetType() == typeid (XWindow) ) || (surface.GetType() == typeid (Ecore_X_Window) ) )
904                         && "Surface type is invalid" );
905
906     if ( surface.GetType() == typeid (Ecore_X_Window) )
907     {
908       surfaceId = AnyCast< Ecore_X_Window >( surface );
909     }
910     else
911     {
912       surfaceId = AnyCast< XWindow >( surface );
913     }
914   }
915   return surfaceId;
916 }
917
918 void WindowBaseEcoreX::CreateWindow( PositionSize positionSize, bool isTransparent )
919 {
920  if( isTransparent )
921  {
922    // create 32 bit window
923    mEcoreWindow = ecore_x_window_argb_new( 0, positionSize.x, positionSize.y, positionSize.width, positionSize.height );
924    mIsTransparent = true;
925  }
926  else
927  {
928    // create 24 bit window
929    mEcoreWindow = ecore_x_window_new( 0, positionSize.x, positionSize.y, positionSize.width, positionSize.height );
930  }
931
932  if ( mEcoreWindow == 0 )
933  {
934    DALI_ASSERT_ALWAYS( 0 && "Failed to create X window" );
935  }
936 }
937
938 } // namespace Adaptor
939
940 } // namespace Internal
941
942 } // namespace Dali
943
944 #pragma GCC diagnostic pop