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