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