Added performance logging back into adaptor build
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / tizen-wayland / event-handler-ecore-wl.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/window-system/common/event-handler.h>
20
21 // EXTERNAL INCLUDES
22 // Ecore is littered with C style cast
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wold-style-cast"
25 #include <Ecore.h>
26 #include <Ecore_Input.h>
27 #include <Ecore_IMF.h>
28 #include <dali/integration-api/wayland/ecore-wl-render-surface.h>
29 //#include <dali/window-system/tizen-wayland/window-render-surface-ecore-wl.h>
30 #include <cstring>
31
32 #include <sys/time.h>
33
34 #ifndef DALI_PROFILE_UBUNTU
35 #include <vconf.h>
36 #include <vconf-keys.h>
37 #endif // DALI_PROFILE_UBUNTU
38
39 #ifdef DALI_ELDBUS_AVAILABLE
40 #include <Eldbus.h>
41 #endif // DALI_ELDBUS_AVAILABLE
42
43 #include <dali/public-api/common/vector-wrapper.h>
44 #include <dali/public-api/events/device.h>
45 #include <dali/public-api/events/touch-point.h>
46 #include <dali/public-api/events/key-event.h>
47 #include <dali/public-api/events/wheel-event.h>
48 #include <dali/integration-api/debug.h>
49 #include <dali/integration-api/events/key-event-integ.h>
50 #include <dali/integration-api/events/touch-event-integ.h>
51 #include <dali/integration-api/events/hover-event-integ.h>
52 #include <dali/integration-api/events/wheel-event-integ.h>
53
54 // INTERNAL INCLUDES
55 #include <dali/internal/input/common/gesture-manager.h>
56 #include <dali/internal/window-system/tizen-wayland/window-render-surface-ecore-wl.h>
57 #include <dali/internal/clipboard/common/clipboard-impl.h>
58 #include <dali/internal/input/common/key-impl.h>
59 #include <dali/internal/input/common/physical-keyboard-impl.h>
60 #include <dali/internal/styling/common/style-monitor-impl.h>
61 #include <dali/internal/system/common/core-event-interface.h>
62 #include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
63
64 namespace Dali
65 {
66
67 namespace Internal
68 {
69
70 namespace Adaptor
71 {
72
73 #if defined(DEBUG_ENABLED)
74 namespace
75 {
76 Integration::Log::Filter* gTouchEventLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");
77 Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND");
78 Integration::Log::Filter* gImfLogging  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF");
79 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");
80 } // unnamed namespace
81 #endif
82
83
84 namespace
85 {
86
87 // DBUS accessibility
88 const char* BUS = "org.enlightenment.wm-screen-reader";
89 const char* INTERFACE = "org.tizen.GestureNavigation";
90 const char* PATH = "/org/tizen/GestureNavigation";
91
92 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
93
94 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
95
96 /**
97  * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.
98  * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.
99  * @param[in] ecoreModifier the Ecore_Event_Modifier input.
100  * @return the Ecore_IMF_Keyboard_Modifiers output.
101  */
102 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)
103 {
104    int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.
105
106
107    if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h
108    {
109      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h
110    }
111
112    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
113    {
114      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
115    }
116
117    if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
118    {
119      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
120    }
121
122    if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
123    {
124      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
125    }
126
127    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
128    {
129      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
130    }
131
132    return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
133 }
134
135
136 // Copied from x server
137 static unsigned int GetCurrentMilliSeconds(void)
138 {
139   struct timeval tv;
140
141   struct timespec tp;
142   static clockid_t clockid;
143
144   if (!clockid)
145   {
146 #ifdef CLOCK_MONOTONIC_COARSE
147     if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
148       (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
149     {
150       clockid = CLOCK_MONOTONIC_COARSE;
151     }
152     else
153 #endif
154     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
155     {
156       clockid = CLOCK_MONOTONIC;
157     }
158     else
159     {
160       clockid = ~0L;
161     }
162   }
163   if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
164   {
165     return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
166   }
167
168   gettimeofday(&tv, NULL);
169   return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
170 }
171
172 #ifndef DALI_PROFILE_UBUNTU
173 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE = "db/setting/accessibility/font_name";  // It will be update at vconf-key.h and replaced.
174 #endif // DALI_PROFILE_UBUNTU
175
176 /**
177  * Get the device name from the provided ecore key event
178  */
179 void GetDeviceName( Ecore_Event_Key* keyEvent, std::string& result )
180 {
181   const char* ecoreDeviceName = ecore_device_name_get( keyEvent->dev );
182
183   if ( ecoreDeviceName )
184   {
185     result = ecoreDeviceName;
186   }
187 }
188
189 /**
190  * Get the device class from the provided ecore event
191  */
192 void GetDeviceClass( Ecore_Device_Class ecoreDeviceClass, Device::Class::Type& deviceClass )
193 {
194   switch( ecoreDeviceClass )
195   {
196     case ECORE_DEVICE_CLASS_SEAT:
197     {
198       deviceClass = Device::Class::USER;
199       break;
200     }
201     case ECORE_DEVICE_CLASS_KEYBOARD:
202     {
203       deviceClass = Device::Class::KEYBOARD;
204       break;
205     }
206     case ECORE_DEVICE_CLASS_MOUSE:
207     {
208       deviceClass = Device::Class::MOUSE;
209       break;
210     }
211     case ECORE_DEVICE_CLASS_TOUCH:
212     {
213       deviceClass = Device::Class::TOUCH;
214       break;
215     }
216     case ECORE_DEVICE_CLASS_PEN:
217     {
218       deviceClass = Device::Class::PEN;
219       break;
220     }
221     case ECORE_DEVICE_CLASS_POINTER:
222     {
223       deviceClass = Device::Class::POINTER;
224       break;
225     }
226     case ECORE_DEVICE_CLASS_GAMEPAD:
227     {
228       deviceClass = Device::Class::GAMEPAD;
229       break;
230     }
231     default:
232     {
233       deviceClass = Device::Class::NONE;
234       break;
235     }
236   }
237 }
238
239 void GetDeviceSubclass( Ecore_Device_Subclass ecoreDeviceSubclass, Device::Subclass::Type& deviceSubclass )
240 {
241   switch( ecoreDeviceSubclass )
242   {
243     case ECORE_DEVICE_SUBCLASS_FINGER:
244     {
245       deviceSubclass = Device::Subclass::FINGER;
246       break;
247     }
248     case ECORE_DEVICE_SUBCLASS_FINGERNAIL:
249     {
250       deviceSubclass = Device::Subclass::FINGERNAIL;
251       break;
252     }
253     case ECORE_DEVICE_SUBCLASS_KNUCKLE:
254     {
255       deviceSubclass = Device::Subclass::KNUCKLE;
256       break;
257     }
258     case ECORE_DEVICE_SUBCLASS_PALM:
259     {
260       deviceSubclass = Device::Subclass::PALM;
261       break;
262     }
263     case ECORE_DEVICE_SUBCLASS_HAND_SIZE:
264     {
265       deviceSubclass = Device::Subclass::HAND_SIDE;
266       break;
267     }
268     case ECORE_DEVICE_SUBCLASS_HAND_FLAT:
269     {
270       deviceSubclass = Device::Subclass::HAND_FLAT;
271       break;
272     }
273     case ECORE_DEVICE_SUBCLASS_PEN_TIP:
274     {
275       deviceSubclass = Device::Subclass::PEN_TIP;
276       break;
277     }
278     case ECORE_DEVICE_SUBCLASS_TRACKPAD:
279     {
280       deviceSubclass = Device::Subclass::TRACKPAD;
281       break;
282     }
283     case ECORE_DEVICE_SUBCLASS_TRACKPOINT:
284     {
285       deviceSubclass = Device::Subclass::TRACKPOINT;
286       break;
287     }
288     case ECORE_DEVICE_SUBCLASS_TRACKBALL:
289     {
290       deviceSubclass = Device::Subclass::TRACKBALL;
291       break;
292     }
293 #ifdef OVER_TIZEN_VERSION_4
294     case ECORE_DEVICE_SUBCLASS_REMOCON:
295     {
296       deviceSubclass = Device::Subclass::REMOCON;
297       break;
298     }
299     case ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD:
300     {
301       deviceSubclass = Device::Subclass::VIRTUAL_KEYBOARD;
302       break;
303     }
304 #endif
305     default:
306     {
307       deviceSubclass = Device::Subclass::NONE;
308       break;
309     }
310   }
311 }
312
313 } // unnamed namespace
314
315 // Impl to hide EFL implementation.
316 struct EventHandler::Impl
317 {
318   // Construction & Destruction
319
320   /**
321    * Constructor
322    */
323   Impl( EventHandler* handler, Ecore_Wl_Window* window )
324   : mHandler( handler ),
325     mEcoreEventHandler(),
326     mWindow( window ),
327     mRotationAngle( 0 ),
328     mWindowWidth( 0 ),
329     mWindowHeight( 0 )
330 #ifdef DALI_ELDBUS_AVAILABLE
331   , mSystemConnection( NULL )
332 #endif // DALI_ELDBUS_AVAILABLE
333   {
334     // Only register for touch and key events if we have a window
335     if ( window != 0 )
336     {
337       // Register Touch events
338       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,   EcoreEventMouseButtonDown,   handler ) );
339       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,     EcoreEventMouseButtonUp,     handler ) );
340       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,          EcoreEventMouseButtonMove,   handler ) );
341       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_CANCEL, EcoreEventMouseButtonCancel, handler ) );
342
343       // Register Mouse wheel events
344       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,        EcoreEventMouseWheel,      handler ) );
345
346       // Register Focus events
347       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );
348       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );
349
350       // Register Key events
351       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
352       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
353
354       // Register Selection event - clipboard selection
355       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, handler ) );
356       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, handler ) );
357
358       // Register Rotate event
359       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_WINDOW_ROTATE, EcoreEventRotate, handler) );
360
361       // Register Detent event
362       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_DETENT_ROTATE, EcoreEventDetent, handler) );
363
364 #ifndef DALI_PROFILE_UBUNTU
365       // Register Vconf notify - font name and size
366       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged, handler );
367       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
368 #endif // DALI_PROFILE_UBUNTU
369
370 #ifdef DALI_ELDBUS_AVAILABLE
371       // Initialize ElDBus.
372       DALI_LOG_INFO( gImfLogging, Debug::General, "Starting DBus Initialization\n" );
373
374       // Pass in handler.
375       EcoreElDBusInitialisation( handler );
376
377       DALI_LOG_INFO( gImfLogging, Debug::General, "Finished DBus Initialization\n" );
378 #endif // DALI_ELDBUS_AVAILABLE
379     }
380   }
381
382   /**
383    * Destructor
384    */
385   ~Impl()
386   {
387 #ifndef DALI_PROFILE_UBUNTU
388     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
389     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged );
390 #endif // DALI_PROFILE_UBUNTU
391
392     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
393     {
394       ecore_event_handler_del( *iter );
395     }
396
397 #ifdef DALI_ELDBUS_AVAILABLE
398     // Close down ElDBus connections.
399     if( mSystemConnection )
400     {
401       eldbus_connection_unref( mSystemConnection );
402     }
403 #endif // DALI_ELDBUS_AVAILABLE
404   }
405
406   // Static methods
407
408   /////////////////////////////////////////////////////////////////////////////////////////////////
409   // Touch Callbacks
410   /////////////////////////////////////////////////////////////////////////////////////////////////
411
412   /**
413    * Called when a touch down is received.
414    */
415   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
416   {
417     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
418     EventHandler* handler( (EventHandler*)data );
419
420     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
421     {
422       PointState::Type state ( PointState::DOWN );
423
424       // Check if the buttons field is set and ensure it's the primary touch button.
425       // If this event was triggered by buttons other than the primary button (used for touch), then
426       // just send an interrupted event to Core.
427       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
428       {
429         state = PointState::INTERRUPTED;
430       }
431
432       Device::Class::Type deviceClass;
433       Device::Subclass::Type deviceSubclass;
434
435       GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass );
436       GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass );
437
438       Integration::Point point;
439       point.SetDeviceId( touchEvent->multi.device );
440       point.SetState( state );
441       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
442       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
443       point.SetPressure( touchEvent->multi.pressure );
444       point.SetAngle( Degree( touchEvent->multi.angle ) );
445       point.SetDeviceClass( deviceClass );
446       point.SetDeviceSubclass( deviceSubclass );
447
448       handler->SendEvent( point, touchEvent->timestamp );
449     }
450
451     return ECORE_CALLBACK_PASS_ON;
452   }
453
454   /**
455    * Called when a touch up is received.
456    */
457   static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
458   {
459     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
460     EventHandler* handler( (EventHandler*)data );
461
462     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
463     {
464       Device::Class::Type deviceClass;
465       Device::Subclass::Type deviceSubclass;
466
467       GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass );
468       GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass );
469
470       Integration::Point point;
471       point.SetDeviceId( touchEvent->multi.device );
472       point.SetState( PointState::UP );
473       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
474       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
475       point.SetPressure( touchEvent->multi.pressure );
476       point.SetAngle( Degree( touchEvent->multi.angle ) );
477       point.SetDeviceClass( deviceClass );
478       point.SetDeviceSubclass( deviceSubclass );
479
480       handler->SendEvent( point, touchEvent->timestamp );
481     }
482
483     return ECORE_CALLBACK_PASS_ON;
484   }
485
486   /**
487    * Called when a touch motion is received.
488    */
489   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
490   {
491     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
492     EventHandler* handler( (EventHandler*)data );
493
494     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
495     {
496       Device::Class::Type deviceClass;
497       Device::Subclass::Type deviceSubclass;
498
499       GetDeviceClass( ecore_device_class_get( touchEvent->dev ), deviceClass );
500       GetDeviceSubclass( ecore_device_subclass_get( touchEvent->dev ), deviceSubclass );
501
502       Integration::Point point;
503       point.SetDeviceId( touchEvent->multi.device );
504       point.SetState( PointState::MOTION );
505       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
506       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
507       point.SetPressure( touchEvent->multi.pressure );
508       point.SetAngle( Degree( touchEvent->multi.angle ) );
509       point.SetDeviceClass( deviceClass );
510       point.SetDeviceSubclass( deviceSubclass );
511
512       handler->SendEvent( point, touchEvent->timestamp );
513     }
514
515     return ECORE_CALLBACK_PASS_ON;
516   }
517
518   /**
519    * Called when a touch is canceled.
520    */
521   static Eina_Bool EcoreEventMouseButtonCancel( void* data, int type, void* event )
522   {
523     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
524     EventHandler* handler( (EventHandler*)data );
525
526     if( touchEvent->window == (unsigned int)ecore_wl_window_id_get( handler->mImpl->mWindow ) )
527     {
528       Integration::Point point;
529       point.SetDeviceId( touchEvent->multi.device );
530       point.SetState( PointState::INTERRUPTED );
531       point.SetScreenPosition( Vector2( 0.0f, 0.0f ) );
532       handler->SendEvent( point, touchEvent->timestamp );
533
534       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventMouseButtonCancel\n" );
535     }
536
537     return ECORE_CALLBACK_PASS_ON;
538   }
539
540   /**
541    * Called when a mouse wheel is received.
542    */
543   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
544   {
545     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
546
547     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT Ecore_Event_Mouse_Wheel: direction: %d, modifiers: %d, x: %d, y: %d, z: %d\n", mouseWheelEvent->direction, mouseWheelEvent->modifiers, mouseWheelEvent->x, mouseWheelEvent->y, mouseWheelEvent->z);
548
549     EventHandler* handler( (EventHandler*)data );
550     if ( mouseWheelEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
551     {
552       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
553       handler->SendWheelEvent( wheelEvent );
554     }
555     return ECORE_CALLBACK_PASS_ON;
556   }
557
558   /////////////////////////////////////////////////////////////////////////////////////////////////
559   // Key Callbacks
560   /////////////////////////////////////////////////////////////////////////////////////////////////
561
562   /**
563    * Called when a key down is received.
564    */
565   static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
566   {
567     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
568
569     EventHandler* handler( (EventHandler*)data );
570     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
571     bool eventHandled( false );
572
573     // If a device key then skip ecore_imf_context_filter_event.
574     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
575     {
576       Ecore_IMF_Context* imfContext = NULL;
577       Dali::ImfManager imfManager( ImfManager::Get() );
578       if ( imfManager )
579       {
580         imfContext = reinterpret_cast<Ecore_IMF_Context*>(ImfManager::GetImplementation( imfManager ).GetContext());
581       }
582
583       if ( imfContext )
584       {
585         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
586         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
587         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
588         ecoreKeyDownEvent.key       = keyEvent->key;
589         ecoreKeyDownEvent.string    = keyEvent->string;
590         ecoreKeyDownEvent.compose   = keyEvent->compose;
591         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
592         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
593         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
594         ecoreKeyDownEvent.dev_name  = ecore_device_name_get( keyEvent->dev );
595         ecoreKeyDownEvent.dev_class = static_cast<Ecore_IMF_Device_Class>( ecore_device_class_get( keyEvent->dev ) );
596         ecoreKeyDownEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass>( ecore_device_subclass_get( keyEvent->dev ) );
597
598         std::string checkDevice;
599         GetDeviceName( keyEvent, checkDevice );
600
601         // If the device is IME and the focused key is the direction keys, then we should send a key event to move a key cursor.
602         if( ( checkDevice == "ime" ) && ( ( !strncmp( keyEvent->keyname, "Left",  4 ) ) ||
603                                           ( !strncmp( keyEvent->keyname, "Right", 5 ) ) ||
604                                           ( !strncmp( keyEvent->keyname, "Up",    2 ) ) ||
605                                           ( !strncmp( keyEvent->keyname, "Down",  4 ) ) ) )
606         {
607           eventHandled = 0;
608         }
609         else
610         {
611           eventHandled = ecore_imf_context_filter_event( imfContext,
612                                                          ECORE_IMF_EVENT_KEY_DOWN,
613                                                          (Ecore_IMF_Event *) &ecoreKeyDownEvent );
614         }
615
616         // If the event has not been handled by IMF then check if we should reset our IMF context
617         if( !eventHandled )
618         {
619           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
620                !strcmp( keyEvent->keyname, "Return"   ) ||
621                !strcmp( keyEvent->keyname, "KP_Enter" ) )
622           {
623             ecore_imf_context_reset( imfContext );
624           }
625         }
626       }
627     }
628
629     // If the event wasn't handled then we should send a key event.
630     if ( !eventHandled )
631     {
632       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
633       {
634         std::string keyName( keyEvent->keyname );
635         std::string keyString( "" );
636         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
637         keyCode = (keyCode == -1) ? 0 : keyCode;
638         int modifier( keyEvent->modifiers );
639         unsigned long time = keyEvent->timestamp;
640         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
641           keyCode = atoi(keyEvent->keyname + 8);
642
643         // Ensure key event string is not NULL as keys like SHIFT have a null string.
644         if ( keyEvent->string )
645         {
646           keyString = keyEvent->string;
647         }
648
649         std::string deviceName;
650         Device::Class::Type deviceClass;
651         Device::Subclass::Type deviceSubclass;
652
653         GetDeviceName( keyEvent, deviceName );
654         GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass );
655         GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass );
656
657         DALI_LOG_INFO( gImfLogging, Debug::Verbose, "EVENT EcoreEventKeyDown - >>EcoreEventKeyDown deviceName(%s) deviceClass(%d)\n", deviceName.c_str(), deviceClass );
658
659         Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, deviceName, deviceClass, deviceSubclass );
660         handler->SendEvent( keyEvent );
661       }
662     }
663
664     return ECORE_CALLBACK_PASS_ON;
665   }
666
667   /**
668    * Called when a key up is received.
669    */
670   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
671   {
672     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp\n" );
673
674     EventHandler* handler( (EventHandler*)data );
675     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
676     bool eventHandled( false );
677
678     // Device keys like Menu, home, back button must skip ecore_imf_context_filter_event.
679     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
680     {
681       Ecore_IMF_Context* imfContext = NULL;
682       Dali::ImfManager imfManager( ImfManager::Get() );
683       if ( imfManager )
684       {
685         imfContext = reinterpret_cast<Ecore_IMF_Context*>(ImfManager::GetImplementation( imfManager ).GetContext());
686       }
687
688       if ( imfContext )
689       {
690         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
691         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
692         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
693         ecoreKeyUpEvent.key       = keyEvent->key;
694         ecoreKeyUpEvent.string    = keyEvent->string;
695         ecoreKeyUpEvent.compose   = keyEvent->compose;
696         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
697         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
698         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
699         ecoreKeyUpEvent.dev_name  = ecore_device_name_get( keyEvent->dev );
700         ecoreKeyUpEvent.dev_class = static_cast<Ecore_IMF_Device_Class>( ecore_device_class_get( keyEvent->dev ) );
701         ecoreKeyUpEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass>( ecore_device_subclass_get( keyEvent->dev ) );
702
703         eventHandled = ecore_imf_context_filter_event( imfContext,
704                                                        ECORE_IMF_EVENT_KEY_UP,
705                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
706       }
707     }
708
709     // If the event wasn't handled then we should send a key event.
710     if ( !eventHandled )
711     {
712       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
713       {
714         std::string keyName( keyEvent->keyname );
715         std::string keyString( "" );
716         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
717         keyCode = (keyCode == -1) ? 0 : keyCode;
718         int modifier( keyEvent->modifiers );
719         unsigned long time = keyEvent->timestamp;
720         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
721           keyCode = atoi(keyEvent->keyname + 8);
722
723         // Ensure key event string is not NULL as keys like SHIFT have a null string.
724         if ( keyEvent->string )
725         {
726           keyString = keyEvent->string;
727         }
728
729         std::string deviceName;
730         Device::Class::Type deviceClass;
731         Device::Subclass::Type deviceSubclass;
732
733         GetDeviceName( keyEvent, deviceName );
734         GetDeviceClass( ecore_device_class_get( keyEvent->dev ), deviceClass );
735         GetDeviceSubclass( ecore_device_subclass_get( keyEvent->dev ), deviceSubclass );
736
737         Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, deviceName, deviceClass, deviceSubclass );
738         handler->SendEvent( keyEvent );
739       }
740     }
741
742     return ECORE_CALLBACK_PASS_ON;
743   }
744
745   /////////////////////////////////////////////////////////////////////////////////////////////////
746   // Window Callbacks
747   /////////////////////////////////////////////////////////////////////////////////////////////////
748
749   /**
750    * Called when the window gains focus.
751    */
752   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
753   {
754     Ecore_Wl_Event_Focus_In* focusInEvent( (Ecore_Wl_Event_Focus_In*)event );
755     EventHandler* handler( (EventHandler*)data );
756
757     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
758
759     // If the window gains focus and we hid the keyboard then show it again.
760     if ( focusInEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
761     {
762       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
763
764       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
765       {
766         Dali::ImfManager imfManager( ImfManager::Get() );
767         if ( imfManager )
768         {
769           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
770           if( imfManagerImpl.RestoreAfterFocusLost() )
771           {
772             imfManagerImpl.Activate();
773           }
774         }
775       }
776       Dali::Clipboard clipboard = Clipboard::Get();
777       clipboard.HideClipboard();
778     }
779
780     return ECORE_CALLBACK_PASS_ON;
781   }
782
783   /**
784    * Called when the window loses focus.
785    */
786   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
787   {
788     Ecore_Wl_Event_Focus_Out* focusOutEvent( (Ecore_Wl_Event_Focus_Out*)event );
789     EventHandler* handler( (EventHandler*)data );
790
791     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
792
793     // If the window loses focus then hide the keyboard.
794     if ( focusOutEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
795     {
796       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
797       {
798         Dali::ImfManager imfManager( ImfManager::Get() );
799         if ( imfManager )
800         {
801           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
802           if( imfManagerImpl.RestoreAfterFocusLost() )
803           {
804             imfManagerImpl.Deactivate();
805           }
806         }
807       }
808
809       // Hiding clipboard event will be ignored once because window focus out event is always received on showing clipboard
810       Dali::Clipboard clipboard = Clipboard::Get();
811       if ( clipboard )
812       {
813         Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
814         clipBoardImpl.HideClipboard(true);
815       }
816     }
817
818     return ECORE_CALLBACK_PASS_ON;
819   }
820
821   /**
822    * Called when the window is damaged.
823    */
824   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
825   {
826     return ECORE_CALLBACK_PASS_ON;
827   }
828
829   /**
830    * Called when the window properties are changed.
831    * We are only interested in the font change.
832    */
833
834
835   /////////////////////////////////////////////////////////////////////////////////////////////////
836   // Drag & Drop Callbacks
837   /////////////////////////////////////////////////////////////////////////////////////////////////
838
839   /**
840    * Called when a dragged item enters our window's bounds.
841    * This is when items are dragged INTO our window.
842    */
843   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
844   {
845     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
846
847     return ECORE_CALLBACK_PASS_ON;
848   }
849
850   /**
851    * Called when a dragged item is moved within our window.
852    * This is when items are dragged INTO our window.
853    */
854   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
855   {
856     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
857
858     return ECORE_CALLBACK_PASS_ON;
859   }
860
861   /**
862    * Called when a dragged item leaves our window's bounds.
863    * This is when items are dragged INTO our window.
864    */
865   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
866   {
867     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
868
869     return ECORE_CALLBACK_PASS_ON;
870   }
871
872   /**
873    * Called when the dragged item is dropped within our window's bounds.
874    * This is when items are dragged INTO our window.
875    */
876   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
877   {
878     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
879
880     return ECORE_CALLBACK_PASS_ON;
881   }
882
883   /**
884    * Called when a dragged item is moved from our window and the target window has done processing it.
885    * This is when items are dragged FROM our window.
886    */
887   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
888   {
889     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
890     return ECORE_CALLBACK_PASS_ON;
891   }
892
893   /**
894    * Called when a dragged item is moved from our window and the target window has sent us a status.
895    * This is when items are dragged FROM our window.
896    */
897   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
898   {
899     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
900     return ECORE_CALLBACK_PASS_ON;
901   }
902
903   /**
904    * Called when the client messages (i.e. the accessibility events) are received.
905    */
906   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
907   {
908     return ECORE_CALLBACK_PASS_ON;
909   }
910
911
912   /////////////////////////////////////////////////////////////////////////////////////////////////
913   // ElDBus Accessibility Callbacks
914   /////////////////////////////////////////////////////////////////////////////////////////////////
915
916 #ifdef DALI_ELDBUS_AVAILABLE
917   // Callback for Ecore ElDBus accessibility events.
918   static void OnEcoreElDBusAccessibilityNotification( void *context EINA_UNUSED, const Eldbus_Message *message )
919   {
920     EventHandler* handler = static_cast< EventHandler* >( context );
921     // Ignore any accessibility events when paused.
922     if( handler->mPaused )
923     {
924       return;
925     }
926
927     if( !handler->mAccessibilityAdaptor )
928     {
929       DALI_LOG_ERROR( "Invalid accessibility adaptor\n" );
930       return;
931     }
932
933     AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( handler->mAccessibilityAdaptor ) );
934     if( !accessibilityAdaptor )
935     {
936       DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" );
937       return;
938     }
939
940     int gestureValue;
941     int xS, yS, xE, yE;
942     int state; // 0 - begin, 1 - ongoing, 2 - ended, 3 - aborted
943     int eventTime;
944
945     // The string defines the arg-list's respective types.
946     if( !eldbus_message_arguments_get( message, "iiiiiiu", &gestureValue, &xS, &yS, &xE, &yE, &state, &eventTime ) )
947     {
948       DALI_LOG_ERROR( "OnEcoreElDBusAccessibilityNotification: Error getting arguments\n" );
949     }
950
951     DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Name: %d  Args: %d,%d,%d,%d  State: %d\n", gestureValue, xS, yS, xE, yE );
952
953     // Create a touch point object.
954     TouchPoint::State touchPointState( TouchPoint::Down );
955     if( state == 0 )
956     {
957       touchPointState = TouchPoint::Down; // Mouse down.
958     }
959     else if( state == 1 )
960     {
961       touchPointState = TouchPoint::Motion; // Mouse move.
962     }
963     else if( state == 2 )
964     {
965       touchPointState = TouchPoint::Up; // Mouse up.
966     }
967     else
968     {
969       touchPointState = TouchPoint::Interrupted; // Error.
970     }
971
972     // Send touch event to accessibility adaptor.
973     TouchPoint point( 0, touchPointState, (float)xS, (float)yS );
974
975     // Perform actions based on received gestures.
976     // Note: This is seperated from the reading so we can have other input readers without changing the below code.
977     switch( gestureValue )
978     {
979       case 0: // OneFingerHover
980       {
981         // Focus, read out.
982         accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ );
983         break;
984       }
985       case 1: // TwoFingersHover
986       {
987         // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
988         accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
989         break;
990       }
991       case 2: // ThreeFingersHover
992       {
993         // Read from top item on screen continuously.
994         accessibilityAdaptor->HandleActionReadFromTopEvent();
995         break;
996       }
997       case 3: // OneFingerFlickLeft
998       {
999         // Move to previous item.
1000         accessibilityAdaptor->HandleActionReadPreviousEvent();
1001         break;
1002       }
1003       case 4: // OneFingerFlickRight
1004       {
1005         // Move to next item.
1006         accessibilityAdaptor->HandleActionReadNextEvent();
1007         break;
1008       }
1009       case 5: // OneFingerFlickUp
1010       {
1011         // Move to previous item.
1012         accessibilityAdaptor->HandleActionPreviousEvent();
1013         break;
1014       }
1015       case 6: // OneFingerFlickDown
1016       {
1017         // Move to next item.
1018         accessibilityAdaptor->HandleActionNextEvent();
1019         break;
1020       }
1021       case 7: // TwoFingersFlickUp
1022       {
1023         // Scroll up the list.
1024         accessibilityAdaptor->HandleActionScrollUpEvent();
1025         break;
1026       }
1027       case 8: // TwoFingersFlickDown
1028       {
1029         // Scroll down the list.
1030         accessibilityAdaptor->HandleActionScrollDownEvent();
1031         break;
1032       }
1033       case 9: // TwoFingersFlickLeft
1034       {
1035         // Scroll left to the previous page
1036         accessibilityAdaptor->HandleActionPageLeftEvent();
1037         break;
1038       }
1039       case 10: // TwoFingersFlickRight
1040       {
1041         // Scroll right to the next page
1042         accessibilityAdaptor->HandleActionPageRightEvent();
1043         break;
1044       }
1045       case 11: // ThreeFingersFlickLeft
1046       {
1047         // Not exist yet
1048         break;
1049       }
1050       case 12: // ThreeFingersFlickRight
1051       {
1052         // Not exist yet
1053         break;
1054       }
1055       case 13: // ThreeFingersFlickUp
1056       {
1057         // Not exist yet
1058         break;
1059       }
1060       case 14: // ThreeFingersFlickDown
1061       {
1062         // Not exist yet
1063         break;
1064       }
1065       case 15: // OneFingerSingleTap
1066       {
1067         // Focus, read out.
1068         accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ );
1069         break;
1070       }
1071       case 16: // OneFingerDoubleTap
1072       {
1073         // Activate selected item / active edit mode.
1074         accessibilityAdaptor->HandleActionActivateEvent();
1075         break;
1076       }
1077       case 17: // OneFingerTripleTap
1078       {
1079         // Zoom
1080         accessibilityAdaptor->HandleActionZoomEvent();
1081         break;
1082       }
1083       case 18: // TwoFingersSingleTap
1084       {
1085         // Pause/Resume current speech
1086         accessibilityAdaptor->HandleActionReadPauseResumeEvent();
1087         break;
1088       }
1089       case 19: // TwoFingersDoubleTap
1090       {
1091         // Start/Stop current action
1092         accessibilityAdaptor->HandleActionStartStopEvent();
1093         break;
1094       }
1095       case 20: // TwoFingersTripleTap
1096       {
1097         // Read information from indicator
1098         accessibilityAdaptor->HandleActionReadIndicatorInformationEvent();
1099         break;
1100       }
1101       case 21: // ThreeFingersSingleTap
1102       {
1103         // Read from top item on screen continuously.
1104         accessibilityAdaptor->HandleActionReadFromTopEvent();
1105         break;
1106       }
1107       case 22: // ThreeFingersDoubleTap
1108       {
1109         // Read from next item continuously.
1110         accessibilityAdaptor->HandleActionReadFromNextEvent();
1111         break;
1112       }
1113       case 23: // ThreeFingersTripleTap
1114       {
1115         // Not exist yet
1116         break;
1117       }
1118       case 24: // OneFingerFlickLeftReturn
1119       {
1120         // Scroll up to the previous page
1121         accessibilityAdaptor->HandleActionPageUpEvent();
1122         break;
1123       }
1124       case 25: // OneFingerFlickRightReturn
1125       {
1126         // Scroll down to the next page
1127         accessibilityAdaptor->HandleActionPageDownEvent();
1128         break;
1129       }
1130       case 26: // OneFingerFlickUpReturn
1131       {
1132         // Move to the first item on screen
1133         accessibilityAdaptor->HandleActionMoveToFirstEvent();
1134         break;
1135       }
1136       case 27: // OneFingerFlickDownReturn
1137       {
1138         // Move to the last item on screen
1139         accessibilityAdaptor->HandleActionMoveToLastEvent();
1140         break;
1141       }
1142       case 28: // TwoFingersFlickLeftReturn
1143       {
1144         // Not exist yet
1145         break;
1146       }
1147       case 29: // TwoFingersFlickRightReturn
1148       {
1149         // Not exist yet
1150         break;
1151       }
1152       case 30: // TwoFingersFlickUpReturn
1153       {
1154         // Not exist yet
1155         break;
1156       }
1157       case 31: // TwoFingersFlickDownReturn
1158       {
1159         // Not exist yet
1160         break;
1161       }
1162       case 32: // ThreeFingersFlickLeftReturn
1163       {
1164         // Not exist yet
1165         break;
1166       }
1167       case 33: // ThreeFingersFlickRightReturn
1168       {
1169         // Not exist yet
1170         break;
1171       }
1172       case 34: // ThreeFingersFlickUpReturn
1173       {
1174         // Not exist yet
1175         break;
1176       }
1177       case 35: // ThreeFingersFlickDownReturn
1178       {
1179         // Not exist yet
1180         break;
1181       }
1182     }
1183   }
1184
1185   void EcoreElDBusInitialisation( void *handle )
1186   {
1187     Eldbus_Object *object;
1188     Eldbus_Proxy *manager;
1189
1190     if( !( mSystemConnection = eldbus_connection_get(ELDBUS_CONNECTION_TYPE_SYSTEM) ) )
1191     {
1192       DALI_LOG_ERROR( "Unable to get system bus\n" );
1193     }
1194
1195     object = eldbus_object_get( mSystemConnection, BUS, PATH );
1196     if( !object )
1197     {
1198       DALI_LOG_ERROR( "Getting object failed\n" );
1199       return;
1200     }
1201
1202     manager = eldbus_proxy_get( object, INTERFACE );
1203     if( !manager )
1204     {
1205       DALI_LOG_ERROR( "Getting proxy failed\n" );
1206       return;
1207     }
1208
1209     if( !eldbus_proxy_signal_handler_add( manager, "GestureDetected", OnEcoreElDBusAccessibilityNotification, handle ) )
1210     {
1211       DALI_LOG_ERROR( "No signal handler returned\n" );
1212     }
1213   }
1214 #endif // DALI_ELDBUS_AVAILABLE
1215
1216   /**
1217    * Called when the source window notifies us the content in clipboard is selected.
1218    */
1219   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
1220   {
1221     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
1222     return ECORE_CALLBACK_PASS_ON;
1223   }
1224
1225   /**
1226    * Called when the source window sends us about the selected content.
1227    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
1228    */
1229   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
1230   {
1231     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
1232     return ECORE_CALLBACK_PASS_ON;
1233   }
1234
1235   /**
1236   * Called when the source window notifies us the content in clipboard is selected.
1237   */
1238   static Eina_Bool EcoreEventDataSend( void* data, int type, void* event )
1239   {
1240     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataSend\n" );
1241
1242     Dali::Clipboard clipboard = Clipboard::Get();
1243     if ( clipboard )
1244     {
1245       Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
1246       clipBoardImpl.ExcuteBuffered( true, event );
1247     }
1248     return ECORE_CALLBACK_PASS_ON;
1249   }
1250
1251    /**
1252     * Called when the source window sends us about the selected content.
1253     * For example, when item is selected in the clipboard.
1254     */
1255    static Eina_Bool EcoreEventDataReceive( void* data, int type, void* event )
1256    {
1257      DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataReceive\n" );
1258
1259      EventHandler* handler( (EventHandler*)data );
1260       Dali::Clipboard clipboard = Clipboard::Get();
1261       char *selectionData = NULL;
1262       if ( clipboard )
1263       {
1264         Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
1265         selectionData = clipBoardImpl.ExcuteBuffered( false, event );
1266       }
1267       if ( selectionData && handler->mClipboardEventNotifier )
1268       {
1269         ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) );
1270         std::string content( selectionData, strlen(selectionData) );
1271
1272         clipboardEventNotifier.SetContent( content );
1273         clipboardEventNotifier.EmitContentSelectedSignal();
1274       }
1275      return ECORE_CALLBACK_PASS_ON;
1276    }
1277
1278   /*
1279   * Called when rotate event is recevied
1280   */
1281   static Eina_Bool EcoreEventRotate( void* data, int type, void* event )
1282   {
1283     DALI_LOG_INFO( gSelectionEventLogFilter, Debug::Concise, "EcoreEventRotate\n" );
1284
1285     EventHandler* handler( (EventHandler*)data );
1286     Ecore_Wl_Event_Window_Rotate* ev( (Ecore_Wl_Event_Window_Rotate*)event );
1287
1288     if( ev->win != (unsigned int)ecore_wl_window_id_get( handler->mImpl->mWindow ) )
1289     {
1290       return ECORE_CALLBACK_PASS_ON;
1291     }
1292
1293     RotationEvent rotationEvent;
1294     rotationEvent.angle = ev->angle;
1295     rotationEvent.winResize = 0;
1296
1297     if( ev->angle == 0 || ev->angle == 180 )
1298     {
1299       rotationEvent.width = ev->w;
1300       rotationEvent.height = ev->h;
1301     }
1302     else
1303     {
1304       rotationEvent.width = ev->h;
1305       rotationEvent.height = ev->w;
1306     }
1307
1308     handler->SendRotationPrepareEvent( rotationEvent );
1309
1310     return ECORE_CALLBACK_PASS_ON;
1311   }
1312
1313   /*
1314   * Called when detent event is recevied
1315   */
1316   static Eina_Bool EcoreEventDetent( void* data, int type, void* event )
1317   {
1318     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDetent\n" );
1319     EventHandler* handler( (EventHandler*)data );
1320     Ecore_Event_Detent_Rotate *e((Ecore_Event_Detent_Rotate *)event);
1321     int direction = (e->direction == ECORE_DETENT_DIRECTION_CLOCKWISE) ? 1 : -1;
1322     int timeStamp = e->timestamp;
1323
1324     WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), direction, timeStamp );
1325     handler->SendWheelEvent( wheelEvent );
1326     return ECORE_CALLBACK_PASS_ON;
1327   }
1328
1329   /////////////////////////////////////////////////////////////////////////////////////////////////
1330   // Font Callbacks
1331   /////////////////////////////////////////////////////////////////////////////////////////////////
1332   /**
1333    * Called when a font name is changed.
1334    */
1335   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
1336   {
1337     EventHandler* handler = static_cast<EventHandler*>( data );
1338     handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
1339   }
1340
1341   /**
1342    * Called when a font size is changed.
1343    */
1344   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
1345   {
1346     EventHandler* handler = static_cast<EventHandler*>( data );
1347     handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
1348   }
1349
1350   void ConvertTouchPosition( Integration::Point& point )
1351   {
1352     Vector2 position = point.GetScreenPosition();
1353     Vector2 convertedPosition;
1354
1355     switch( mRotationAngle )
1356     {
1357       case 90:
1358       {
1359         convertedPosition.x = mWindowWidth - position.y;
1360         convertedPosition.y = position.x;
1361         break;
1362       }
1363       case 180:
1364       {
1365         convertedPosition.x = mWindowWidth - position.x;
1366         convertedPosition.y = mWindowHeight - position.y;
1367         break;
1368       }
1369       case 270:
1370       {
1371         convertedPosition.x = position.y;
1372         convertedPosition.y = mWindowHeight - position.x;
1373         break;
1374       }
1375       default:
1376       {
1377         convertedPosition = position;
1378         break;
1379       }
1380     }
1381
1382     point.SetScreenPosition( convertedPosition );
1383   }
1384
1385   // Data
1386   EventHandler* mHandler;
1387   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
1388   Ecore_Wl_Window* mWindow;
1389   int mRotationAngle;
1390   int mWindowWidth;
1391   int mWindowHeight;
1392 #ifdef DALI_ELDBUS_AVAILABLE
1393   Eldbus_Connection* mSystemConnection;
1394 #endif // DALI_ELDBUS_AVAILABLE
1395 };
1396
1397 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
1398 : mCoreEventInterface( coreEventInterface ),
1399   mGestureManager( gestureManager ),
1400   mStyleMonitor( StyleMonitor::Get() ),
1401   mDamageObserver( damageObserver ),
1402   mRotationObserver( NULL ),
1403   mDragAndDropDetector( dndDetector ),
1404   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
1405   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
1406   mClipboard( Clipboard::Get() ),
1407   mImpl( NULL ),
1408   mPaused( false )
1409 {
1410   Ecore_Wl_Window* window = 0;
1411
1412   // this code only works with the Ecore RenderSurface so need to downcast
1413   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
1414   if( ecoreSurface )
1415   {
1416     window = ecoreSurface->GetWlWindow();
1417   }
1418
1419   mImpl = new Impl(this, window);
1420 }
1421
1422 EventHandler::~EventHandler()
1423 {
1424   if(mImpl)
1425   {
1426     delete mImpl;
1427   }
1428
1429   mGestureManager.Stop();
1430 }
1431
1432 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)
1433 {
1434   if(timeStamp < 1)
1435   {
1436     timeStamp = GetCurrentMilliSeconds();
1437   }
1438
1439   mImpl->ConvertTouchPosition( point );
1440
1441   Integration::TouchEvent touchEvent;
1442   Integration::HoverEvent hoverEvent;
1443   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
1444   if(type != Integration::TouchEventCombiner::DispatchNone )
1445   {
1446     DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.GetDeviceId(), point.GetState(), point.GetScreenPosition().x, point.GetScreenPosition().y);
1447
1448     // First the touch and/or hover event & related gesture events are queued
1449     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
1450     {
1451       mCoreEventInterface.QueueCoreEvent( touchEvent );
1452       mGestureManager.SendEvent(touchEvent);
1453     }
1454
1455     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
1456     {
1457       mCoreEventInterface.QueueCoreEvent( hoverEvent );
1458     }
1459
1460     // Next the events are processed with a single call into Core
1461     mCoreEventInterface.ProcessCoreEvents();
1462   }
1463 }
1464
1465 void EventHandler::SendEvent(Integration::KeyEvent& keyEvent)
1466 {
1467   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
1468   if ( physicalKeyboard )
1469   {
1470     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyName.c_str() ) )
1471     {
1472       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
1473     }
1474   }
1475
1476   // Create send KeyEvent to Core.
1477   mCoreEventInterface.QueueCoreEvent( keyEvent );
1478   mCoreEventInterface.ProcessCoreEvents();
1479 }
1480
1481 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
1482 {
1483   // Create WheelEvent and send to Core.
1484   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
1485   mCoreEventInterface.QueueCoreEvent( event );
1486   mCoreEventInterface.ProcessCoreEvents();
1487 }
1488
1489 void EventHandler::SendEvent( StyleChange::Type styleChange )
1490 {
1491   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
1492   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
1493 }
1494
1495 void EventHandler::SendEvent( const DamageArea& area )
1496 {
1497   mDamageObserver.OnDamaged( area );
1498 }
1499
1500 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
1501 {
1502   if( mRotationObserver != NULL )
1503   {
1504     mImpl->mRotationAngle = event.angle;
1505     mImpl->mWindowWidth = event.width;
1506     mImpl->mWindowHeight = event.height;
1507
1508     mRotationObserver->OnRotationPrepare( event );
1509     mRotationObserver->OnRotationRequest();
1510   }
1511 }
1512
1513 void EventHandler::SendRotationRequestEvent( )
1514 {
1515   // No need to separate event into prepare and request in wayland
1516 }
1517
1518 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
1519 {
1520   Integration::Point convertedPoint( point );
1521   SendEvent(convertedPoint, timeStamp);
1522 }
1523
1524 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
1525 {
1526   SendWheelEvent( wheelEvent );
1527 }
1528
1529 void EventHandler::FeedKeyEvent( KeyEvent& event )
1530 {
1531   Integration::KeyEvent convertedEvent( event );
1532   SendEvent( convertedEvent );
1533 }
1534
1535 void EventHandler::FeedEvent( Integration::Event& event )
1536 {
1537   mCoreEventInterface.QueueCoreEvent( event );
1538   mCoreEventInterface.ProcessCoreEvents();
1539 }
1540
1541 void EventHandler::Reset()
1542 {
1543   mCombiner.Reset();
1544
1545   // Any touch listeners should be told of the interruption.
1546   Integration::TouchEvent event;
1547   Integration::Point point;
1548   point.SetState( PointState::INTERRUPTED );
1549   event.AddPoint( point );
1550
1551   // First the touch event & related gesture events are queued
1552   mCoreEventInterface.QueueCoreEvent( event );
1553   mGestureManager.SendEvent( event );
1554
1555   // Next the events are processed with a single call into Core
1556   mCoreEventInterface.ProcessCoreEvents();
1557 }
1558
1559 void EventHandler::Pause()
1560 {
1561   mPaused = true;
1562   Reset();
1563 }
1564
1565 void EventHandler::Resume()
1566 {
1567   mPaused = false;
1568   Reset();
1569 }
1570
1571 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
1572 {
1573   mDragAndDropDetector = detector;
1574 }
1575
1576 void EventHandler::SetRotationObserver( RotationObserver* observer )
1577 {
1578   mRotationObserver = observer;
1579 }
1580
1581 } // namespace Adaptor
1582
1583 } // namespace Internal
1584
1585 } // namespace Dali
1586
1587 #pragma GCC diagnostic pop