Calling ProcessCoreEvents synchronously in time tick callback of WatchApplication
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / ecore-x-event-handler.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 <events/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_X.h>
28
29 #include <X11/Xlib.h>
30 #include <X11/extensions/XInput2.h>
31 #include <X11/extensions/XI2.h>
32
33 #include <cstring>
34
35 #include <sys/time.h>
36
37 #ifndef DALI_PROFILE_UBUNTU
38 #include <vconf.h>
39 #include <vconf-keys.h>
40 #endif // DALI_PROFILE_UBUNTU
41
42 #ifdef DALI_ELDBUS_AVAILABLE
43 #include <Eldbus.h>
44 #endif // DALI_ELDBUS_AVAILABLE
45
46 #include <dali/public-api/common/vector-wrapper.h>
47 #include <dali/public-api/events/touch-point.h>
48 #include <dali/public-api/events/key-event.h>
49 #include <dali/public-api/events/wheel-event.h>
50 #include <dali/integration-api/debug.h>
51 #include <dali/integration-api/events/key-event-integ.h>
52 #include <dali/integration-api/events/touch-event-integ.h>
53 #include <dali/integration-api/events/hover-event-integ.h>
54 #include <dali/integration-api/events/wheel-event-integ.h>
55 #include <dali/devel-api/events/key-event-devel.h>
56
57 // INTERNAL INCLUDES
58 #include <events/gesture-manager.h>
59 #include <window-render-surface.h>
60 #include <clipboard-impl.h>
61 #include <key-impl.h>
62 #include <physical-keyboard-impl.h>
63 #include <style-monitor-impl.h>
64 #include <base/core-event-interface.h>
65
66 namespace Dali
67 {
68
69 namespace Internal
70 {
71
72 namespace Adaptor
73 {
74
75 #if defined(DEBUG_ENABLED)
76 namespace
77 {
78 Integration::Log::Filter* gTouchEventLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");
79 Integration::Log::Filter* gClientMessageLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_CLIENT_MESSAGE");
80 Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND");
81 Integration::Log::Filter* gImfLogging  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF");
82 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");
83 } // unnamed namespace
84 #endif
85
86
87 namespace
88 {
89
90 const char * DETENT_DEVICE_NAME = "tizen_detent";
91 const std::string DEFAULT_DEVICE_NAME = "";
92 const DevelDevice::Class::Type DEFAULT_DEVICE_CLASS = DevelDevice::Class::NONE;
93 const DevelDevice::Subclass::Type DEFAULT_DEVICE_SUBCLASS = DevelDevice::Subclass::NONE;
94
95 // DBUS accessibility
96 #define A11Y_BUS "org.a11y.Bus"
97 #define A11Y_INTERFACE "org.a11y.Bus"
98 #define A11Y_PATH "/org/a11y/bus"
99 #define A11Y_GET_ADDRESS "GetAddress"
100 #define BUS "com.samsung.EModule"
101 #define INTERFACE "com.samsung.GestureNavigation"
102 #define PATH "/com/samsung/GestureNavigation"
103 #define SIGNAL "GestureDetected"
104
105 #ifndef DALI_PROFILE_UBUNTU
106 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced.
107 #endif // DALI_PROFILE_UBUNTU
108
109 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
110
111 #ifndef DALI_PROFILE_UBUNTU
112 const char * CLIPBOARD_ATOM                = "CBHM_MSG";
113 const char * CLIPBOARD_SET_OWNER_MESSAGE   = "SET_OWNER";
114 #endif // DALI_PROFILE_UBUNTU
115
116 /// The atoms required by Ecore for Drag & Drop behaviour.
117 Ecore_X_Atom DRAG_AND_DROP_ATOMS[] =
118 {
119   ECORE_X_ATOM_XDND_ACTION_COPY,
120 };
121
122 /// The types that we support.
123 const char * DRAG_AND_DROP_TYPES[] =
124 {
125   ECORE_X_SELECTION_TARGET_UTF8_STRING,
126 };
127
128 const unsigned int DRAG_AND_DROP_ATOMS_NUMBER = sizeof( DRAG_AND_DROP_ATOMS ) / sizeof( Ecore_X_Atom );
129 const unsigned int DRAG_AND_DROP_TYPES_NUMBER = sizeof( DRAG_AND_DROP_TYPES ) / sizeof( const char * );
130
131 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
132
133 #ifdef DALI_ELDBUS_AVAILABLE
134 // DBus gesture string matching lists.
135 // TODO: This needs moving to its own module.
136 const char * ElDBusAccessibilityFingerCountStrings[] =
137 {
138   "OneFinger",
139   "TwoFingers",
140   "ThreeFingers"
141 };
142 const unsigned int FingerCountStringsTotal = sizeof( ElDBusAccessibilityFingerCountStrings ) / sizeof( ElDBusAccessibilityFingerCountStrings[0] );
143 enum GestureType
144 {
145   GESTURE_TYPE_NONE,
146   GESTURE_TYPE_HOVER,
147   GESTURE_TYPE_SINGLE_TAP,
148   GESTURE_TYPE_DOUBLE_TAP,
149   GESTURE_TYPE_TRIPLE_TAP
150 };
151 struct GestureTypeTable
152 {
153   const char* name;
154   const GestureType type;
155 };
156 GestureTypeTable ElDBusAccessibilityFullEventTypeStrings[] =
157 {
158   { "Hover",     GESTURE_TYPE_HOVER      },
159   { "SingleTap", GESTURE_TYPE_SINGLE_TAP },
160   { "DoubleTap", GESTURE_TYPE_DOUBLE_TAP },
161   { "TripleTap", GESTURE_TYPE_TRIPLE_TAP }
162 };
163 const unsigned int FullEventTypeStringsTotal = sizeof( ElDBusAccessibilityFullEventTypeStrings ) / sizeof( ElDBusAccessibilityFullEventTypeStrings[0] );
164 enum SubGestureType
165 {
166   SUB_GESTURE_TYPE_NONE,
167   SUB_GESTURE_TYPE_FLICK
168 };
169 struct SubGestureTypeTable
170 {
171   const char* name;
172   const SubGestureType type;
173 };
174 SubGestureTypeTable ElDBusAccessibilityDirectionalEventTypeStrings[] =
175 {
176   { "Flick", SUB_GESTURE_TYPE_FLICK }
177 };
178 const unsigned int DirectionalEventTypeStringsTotal = sizeof( ElDBusAccessibilityDirectionalEventTypeStrings ) / sizeof( ElDBusAccessibilityDirectionalEventTypeStrings[0] );
179 enum GestureDirection
180 {
181   GESTURE_DIRECTION_NONE,
182   GESTURE_DIRECTION_UP,
183   GESTURE_DIRECTION_DOWN,
184   GESTURE_DIRECTION_LEFT,
185   GESTURE_DIRECTION_RIGHT,
186   GESTURE_DIRECTION_UP_RETURN,
187   GESTURE_DIRECTION_DOWN_RETURN,
188   GESTURE_DIRECTION_LEFT_RETURN,
189   GESTURE_DIRECTION_RIGHT_RETURN
190 };
191 struct GestureDirectionTable
192 {
193         const char* name;
194         const GestureDirection direction;
195 };
196 GestureDirectionTable ElDBusAccessibilityDirectionStrings[] =
197 {
198   { "Up",           GESTURE_DIRECTION_UP           },
199   { "Down",         GESTURE_DIRECTION_DOWN         },
200   { "Left",         GESTURE_DIRECTION_LEFT         },
201   { "Right",        GESTURE_DIRECTION_RIGHT        },
202   { "UpReturn",     GESTURE_DIRECTION_UP_RETURN    },
203   { "DownReturn",   GESTURE_DIRECTION_DOWN_RETURN  },
204   { "LeftReturn",   GESTURE_DIRECTION_LEFT_RETURN  },
205   { "RightReturn",  GESTURE_DIRECTION_RIGHT_RETURN }
206 };
207 const unsigned int DirectionStringsTotal = sizeof( ElDBusAccessibilityDirectionStrings ) / sizeof( ElDBusAccessibilityDirectionStrings[0] );
208 #endif // DALI_ELDBUS_AVAILABLE
209
210 /**
211  * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.
212  * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.
213  * @param[in] ecoreModifier the Ecore_Event_Modifier input.
214  * @return the Ecore_IMF_Keyboard_Modifiers output.
215  */
216 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)
217 {
218    int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.
219
220
221    if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h
222    {
223      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h
224    }
225
226    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
227    {
228      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
229    }
230
231    if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
232    {
233      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
234    }
235
236    if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
237    {
238      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
239    }
240
241    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
242    {
243      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
244    }
245
246    return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
247 }
248
249
250 // Copied from x server
251 static unsigned int GetCurrentMilliSeconds(void)
252 {
253   struct timeval tv;
254
255   struct timespec tp;
256   static clockid_t clockid;
257
258   if (!clockid)
259   {
260 #ifdef CLOCK_MONOTONIC_COARSE
261     if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
262       (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
263     {
264       clockid = CLOCK_MONOTONIC_COARSE;
265     }
266     else
267 #endif
268     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
269     {
270       clockid = CLOCK_MONOTONIC;
271     }
272     else
273     {
274       clockid = ~0L;
275     }
276   }
277   if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
278   {
279     return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
280   }
281
282   gettimeofday(&tv, NULL);
283   return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
284 }
285
286 } // unnamed namespace
287
288 // Impl to hide EFL implementation.
289 struct EventHandler::Impl
290 {
291   // Construction & Destruction
292
293   /**
294    * Constructor
295    */
296   Impl( EventHandler* handler, Ecore_X_Window window )
297   : mHandler( handler ),
298     mEcoreEventHandler(),
299     mWindow( window ),
300     mXiDeviceId( 0 )
301 #ifdef DALI_ELDBUS_AVAILABLE
302   , mSessionConnection( NULL ),
303     mA11yConnection( NULL )
304 #endif
305   {
306     // Only register for touch and key events if we have a window
307     if ( window != 0 )
308     {
309       // Register Touch events
310       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,  EcoreEventMouseButtonDown, handler ) );
311       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,    EcoreEventMouseButtonUp,   handler ) );
312       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,         EcoreEventMouseButtonMove, handler ) );
313       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT,          EcoreEventMouseButtonUp,   handler ) ); // process mouse out event like up event
314
315       // Register Mouse wheel events
316       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,        EcoreEventMouseWheel,      handler ) );
317
318       // Register Key events
319       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
320       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
321
322       // Register Focus events
323       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );
324       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );
325
326       // Register Window damage events
327       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE,    EcoreEventWindowDamaged, handler ) );
328
329       // Enable Drag & Drop and register DnD events
330       ecore_x_dnd_aware_set( window, EINA_TRUE );
331       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_ENTER,       EcoreEventDndEnter,            handler) );
332       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_POSITION,    EcoreEventDndPosition,         handler) );
333       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_LEAVE,       EcoreEventDndLeave,            handler) );
334       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_DROP,        EcoreEventDndDrop,             handler) );
335       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_FINISHED,    EcoreEventDndFinished,         handler) );
336       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_STATUS,      EcoreEventDndStatus,           handler) );
337
338       // Register Client message events - accessibility etc.
339       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, handler ) );
340
341       // Register Selection event - clipboard selection, Drag & Drop selection etc.
342       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) );
343       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) );
344
345       // Initialize Xi2 system
346       Display* display = static_cast< Display* >(ecore_x_display_get());
347       Ecore_X_Window rootWindow = ecore_x_window_root_first_get();
348       int opcode = 0, event = 0, error = 0;
349       int major = XI_2_Major;
350       int minor = XI_2_Minor;
351       int deviceCount = 0;
352       XIEventMask xiEventMask;
353
354       // Check if X input extension available
355       if( XQueryExtension( display, "XInputExtension", &opcode, &event, &error ) )
356       {
357         // We support version 2.0
358         if( XIQueryVersion( display, &major, &minor ) != BadRequest )
359         {
360           xiEventMask.deviceid = XIAllDevices;
361
362           // Check device id
363           bool match = false;
364           XIDeviceInfo* deviceInfo = NULL;
365           deviceInfo = XIQueryDevice( display, XIAllDevices, &deviceCount );
366
367           for( int i = 0; i < deviceCount; i++ )
368           {
369             if( !strncmp( deviceInfo[i].name, DETENT_DEVICE_NAME, strlen( DETENT_DEVICE_NAME ) ) )
370             {
371               xiEventMask.deviceid = deviceInfo[i].deviceid;
372               match = true;
373               break;
374             }
375           }
376
377           if( match )
378           {
379             mXiDeviceId = xiEventMask.deviceid;
380
381             // SelectXi2Event
382             Dali::Vector< unsigned char > mask;
383             std::size_t xiMaskLen = XIMaskLen( XI_LASTEVENT );
384             mask.Reserve( xiMaskLen );
385             xiEventMask.mask = mask.Begin();
386
387             XISetMask( xiEventMask.mask, XI_RawMotion );
388
389             xiEventMask.mask_len = xiMaskLen * sizeof( unsigned char );
390
391             int ret = XISelectEvents( display, rootWindow, &xiEventMask, 1 );
392             if( ret == 0 )
393             {
394               // Register custom wheel events
395               mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_GENERIC, EcoreEventCustomWheel, handler ) );
396             }
397             else
398             {
399               DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to Select Events\n" );
400             }
401           }
402
403           if( deviceInfo != NULL )
404           {
405             XIFreeDeviceInfo( deviceInfo );
406           }
407         }
408         else
409         {
410           DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XI Version\n" );
411         }
412       }
413       else
414       {
415         DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XInputExtension\n" );
416       }
417
418 #ifndef DALI_PROFILE_UBUNTU
419       // Register Vconf notify - font name, font size and style
420       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, handler );
421       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
422 #endif // DALI_PROFILE_UBUNTU
423
424 #ifdef DALI_ELDBUS_AVAILABLE
425
426       // Initialize ElDBus.
427       DALI_LOG_INFO( gImfLogging, Debug::General, "Starting DBus Initialization\n" );
428       eldbus_init();
429
430       mSessionConnection = eldbus_connection_get( ELDBUS_CONNECTION_TYPE_SESSION );
431
432       Eldbus_Object *a11yObject = eldbus_object_get( mSessionConnection, A11Y_BUS, A11Y_PATH );
433       Eldbus_Proxy *elDBusManager = eldbus_proxy_get( a11yObject, A11Y_INTERFACE );
434
435       // Pass in handler in the cb_data field so we can access the accessibility adaptor within the callback.
436       eldbus_proxy_call( elDBusManager, A11Y_GET_ADDRESS, EcoreElDBusInitialisation, handler, -1, "" );
437
438       DALI_LOG_INFO( gImfLogging, Debug::General, "Finished DBus Initialization\n" );
439
440 #endif // DALI_ELDBUS_AVAILABLE
441     }
442   }
443
444   /**
445    * Destructor
446    */
447   ~Impl()
448   {
449 #ifndef DALI_PROFILE_UBUNTU
450     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
451     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged );
452 #endif // DALI_PROFILE_UBUNTU
453
454     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
455     {
456       ecore_event_handler_del( *iter );
457     }
458
459 #ifdef DALI_ELDBUS_AVAILABLE
460     // Close down ElDBus
461     if( mA11yConnection )
462     {
463       eldbus_connection_unref( mA11yConnection );
464     }
465
466     if( mSessionConnection )
467     {
468       eldbus_connection_unref( mSessionConnection );
469     }
470
471     eldbus_shutdown();
472 #endif // DALI_ELDBUS_AVAILABLE
473   }
474
475   // Static methods
476
477   /////////////////////////////////////////////////////////////////////////////////////////////////
478   // Touch Callbacks
479   /////////////////////////////////////////////////////////////////////////////////////////////////
480
481   /**
482    * Called when a touch down is received.
483    */
484   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
485   {
486     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
487     EventHandler* handler( (EventHandler*)data );
488
489     if ( touchEvent->window == handler->mImpl->mWindow )
490     {
491       PointState::Type state ( PointState::DOWN );
492
493       // Check if the buttons field is set and ensure it's the primary touch button.
494       // If this event was triggered by buttons other than the primary button (used for touch), then
495       // just send an interrupted event to Core.
496       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
497       {
498         state = PointState::INTERRUPTED;
499       }
500
501       Integration::Point point;
502       point.SetDeviceId( touchEvent->multi.device );
503       point.SetState( state );
504       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
505       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
506       point.SetPressure( touchEvent->multi.pressure );
507       point.SetAngle( Degree( touchEvent->multi.angle ) );
508       handler->SendEvent( point, touchEvent->timestamp );
509     }
510
511     return ECORE_CALLBACK_PASS_ON;
512   }
513
514   /**
515    * Called when a touch up is received.
516    */
517   static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
518   {
519     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
520     EventHandler* handler( (EventHandler*)data );
521
522     if ( touchEvent->window == handler->mImpl->mWindow )
523     {
524       Integration::Point point;
525       point.SetDeviceId( touchEvent->multi.device );
526       point.SetState( PointState::UP );
527       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
528       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
529       point.SetPressure( touchEvent->multi.pressure );
530       point.SetAngle( Degree( touchEvent->multi.angle ) );
531       handler->SendEvent( point, touchEvent->timestamp );
532     }
533
534     return ECORE_CALLBACK_PASS_ON;
535   }
536
537   /**
538    * Called when a touch motion is received.
539    */
540   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
541   {
542     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
543     EventHandler* handler( (EventHandler*)data );
544
545     if ( touchEvent->window == handler->mImpl->mWindow )
546     {
547       Integration::Point point;
548       point.SetDeviceId( touchEvent->multi.device );
549       point.SetState( PointState::MOTION );
550       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
551       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
552       point.SetPressure( touchEvent->multi.pressure );
553       point.SetAngle( Degree( touchEvent->multi.angle ) );
554       handler->SendEvent( point, touchEvent->timestamp );
555     }
556
557     return ECORE_CALLBACK_PASS_ON;
558   }
559
560   /////////////////////////////////////////////////////////////////////////////////////////////////
561   // Wheel Callbacks
562   /////////////////////////////////////////////////////////////////////////////////////////////////
563
564   /**
565    * Called when a mouse wheel is received.
566    */
567   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
568   {
569     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
570
571     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 );
572
573     EventHandler* handler( (EventHandler*)data );
574     if ( mouseWheelEvent->window == handler->mImpl->mWindow )
575     {
576       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
577       handler->SendWheelEvent( wheelEvent );
578     }
579     return ECORE_CALLBACK_PASS_ON;
580   }
581
582   /**
583    * Called when a custom wheel is received.
584    */
585   static Eina_Bool EcoreEventCustomWheel( void* data, int type, void* event )
586   {
587     Ecore_X_Event_Generic *genericEvent( (Ecore_X_Event_Generic*)event );
588     EventHandler* handler( (EventHandler*)data );
589
590     switch( genericEvent->evtype )
591     {
592       case XI_RawMotion:
593       {
594         XIRawEvent* xiRawEvent = static_cast< XIRawEvent* >( genericEvent->data );
595         unsigned int timeStamp = 0;
596
597         if( xiRawEvent->deviceid != handler->mImpl->mXiDeviceId )
598         {
599           return ECORE_CALLBACK_PASS_ON;
600         }
601
602         // X(0): rotate: NOT USED
603         // Y(1): timestamp
604         // Z(2): direction
605
606         double* value = xiRawEvent->raw_values;
607
608         if( XIMaskIsSet( xiRawEvent->valuators.mask, 1) )
609         {
610           timeStamp = static_cast< unsigned int >( *(value + 1) );
611         }
612
613         if( XIMaskIsSet( xiRawEvent->valuators.mask, 2) )
614         {
615           // if z == 1, clockwise
616           // otherwise counter-clockwise
617           int z = static_cast< int >( *(value + 2) );
618
619           // In DALi, positive value means clockwise, and negative value means counter-clockwise
620           if( z == 0 )
621           {
622             z = -1;
623           }
624
625           DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventCustomWheel: z: %d\n", z );
626
627           WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), z, timeStamp );
628           handler->SendWheelEvent( wheelEvent );
629         }
630         break;
631       }
632       default:
633       {
634         break;
635       }
636     }
637
638     return ECORE_CALLBACK_PASS_ON;
639   }
640
641   /////////////////////////////////////////////////////////////////////////////////////////////////
642   // Key Callbacks
643   /////////////////////////////////////////////////////////////////////////////////////////////////
644
645   /**
646    * Called when a key down is received.
647    */
648   static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
649   {
650     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
651
652     EventHandler* handler( (EventHandler*)data );
653     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
654     bool eventHandled( false );
655
656     // If a device key then skip ecore_imf_context_filter_event.
657     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
658     {
659       Ecore_IMF_Context* imfContext = NULL;
660       Dali::ImfManager imfManager( ImfManager::Get() );
661       if ( imfManager )
662       {
663         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
664       }
665
666       if ( imfContext )
667       {
668         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
669         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
670         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
671         ecoreKeyDownEvent.key       = keyEvent->key;
672         ecoreKeyDownEvent.string    = keyEvent->string;
673         ecoreKeyDownEvent.compose   = keyEvent->compose;
674         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
675         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
676         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
677 #ifdef ECORE_IMF_1_13
678         ecoreKeyDownEvent.dev_name  = "";
679         ecoreKeyDownEvent.dev_class = ECORE_IMF_DEVICE_CLASS_KEYBOARD;
680         ecoreKeyDownEvent.dev_subclass = ECORE_IMF_DEVICE_SUBCLASS_NONE;
681 #endif // ECORE_IMF_1_13
682
683         eventHandled = ecore_imf_context_filter_event( imfContext,
684                                                        ECORE_IMF_EVENT_KEY_DOWN,
685                                                        (Ecore_IMF_Event *) &ecoreKeyDownEvent );
686
687         // If the event has not been handled by IMF then check if we should reset our IMF context
688         if( !eventHandled )
689         {
690           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
691                !strcmp( keyEvent->keyname, "Return"   ) ||
692                !strcmp( keyEvent->keyname, "KP_Enter" ) )
693           {
694             ecore_imf_context_reset( imfContext );
695           }
696         }
697       }
698     }
699
700     // If the event wasn't handled then we should send a key event.
701     if ( !eventHandled )
702     {
703       if ( keyEvent->window == handler->mImpl->mWindow )
704       {
705         std::string keyName( keyEvent->keyname );
706         std::string keyString( "" );
707         int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
708         int modifier( keyEvent->modifiers );
709         unsigned long time = keyEvent->timestamp;
710
711         // Ensure key event string is not NULL as keys like SHIFT have a null string.
712         if ( keyEvent->string )
713         {
714           keyString = keyEvent->string;
715         }
716
717         Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );
718         handler->SendEvent( keyEvent );
719       }
720     }
721
722     return ECORE_CALLBACK_PASS_ON;
723   }
724
725   /**
726    * Called when a key up is received.
727    */
728   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
729   {
730     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp \n" );
731
732     EventHandler* handler( (EventHandler*)data );
733     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
734     bool eventHandled( false );
735
736     // Device keys like Menu, home, back button must skip ecore_imf_context_filter_event.
737     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
738     {
739       Ecore_IMF_Context* imfContext = NULL;
740       Dali::ImfManager imfManager( ImfManager::Get() );
741       if ( imfManager )
742       {
743         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
744       }
745
746       if ( imfContext )
747       {
748         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
749         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
750         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
751         ecoreKeyUpEvent.key       = keyEvent->key;
752         ecoreKeyUpEvent.string    = keyEvent->string;
753         ecoreKeyUpEvent.compose   = keyEvent->compose;
754         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
755         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
756         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
757 #ifdef ECORE_IMF_1_13
758         ecoreKeyUpEvent.dev_name  = "";
759 #endif // ECORE_IMF_1_13
760
761         eventHandled = ecore_imf_context_filter_event( imfContext,
762                                                        ECORE_IMF_EVENT_KEY_UP,
763                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
764       }
765     }
766
767     // If the event wasn't handled then we should send a key event.
768     if ( !eventHandled )
769     {
770       if ( keyEvent->window == handler->mImpl->mWindow )
771       {
772         std::string keyName( keyEvent->keyname );
773         std::string keyString( "" );
774         int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
775         int modifier( keyEvent->modifiers );
776         unsigned long time( keyEvent->timestamp );
777
778         // Ensure key event string is not NULL as keys like SHIFT have a null string.
779         if ( keyEvent->string )
780         {
781           keyString = keyEvent->string;
782         }
783
784         Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );
785
786         handler->SendEvent( keyEvent );
787       }
788     }
789
790     return ECORE_CALLBACK_PASS_ON;
791   }
792
793   /////////////////////////////////////////////////////////////////////////////////////////////////
794   // Window Callbacks
795   /////////////////////////////////////////////////////////////////////////////////////////////////
796
797   /**
798    * Called when the window gains focus.
799    */
800   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
801   {
802     Ecore_X_Event_Window_Focus_In* focusInEvent( (Ecore_X_Event_Window_Focus_In*)event );
803     EventHandler* handler( (EventHandler*)data );
804
805     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
806
807     // If the window gains focus and we hid the keyboard then show it again.
808     if ( focusInEvent->win == handler->mImpl->mWindow )
809     {
810       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
811
812       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
813       {
814         Dali::ImfManager imfManager( ImfManager::Get() );
815         if ( imfManager )
816         {
817           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
818           if( imfManagerImpl.RestoreAfterFocusLost() )
819           {
820             imfManagerImpl.Activate();
821           }
822         }
823       }
824       // No need to connect callbacks as KeyboardStatusChanged will be called.
825     }
826
827     return ECORE_CALLBACK_PASS_ON;
828   }
829
830   /**
831    * Called when the window loses focus.
832    */
833   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
834   {
835     Ecore_X_Event_Window_Focus_Out* focusOutEvent( (Ecore_X_Event_Window_Focus_Out*)event );
836     EventHandler* handler( (EventHandler*)data );
837
838     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
839
840     // If the window loses focus then hide the keyboard.
841     if ( focusOutEvent->win == handler->mImpl->mWindow )
842     {
843       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
844       {
845         Dali::ImfManager imfManager( ImfManager::Get() );
846         if ( imfManager )
847         {
848           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
849           if( imfManagerImpl.RestoreAfterFocusLost() )
850           {
851             imfManagerImpl.Deactivate();
852           }
853         }
854       }
855
856       // Clipboard don't support that whether clipboard is shown or not. Hide clipboard.
857       Dali::Clipboard clipboard = Clipboard::Get();
858       clipboard.HideClipboard();
859     }
860
861     return ECORE_CALLBACK_PASS_ON;
862   }
863
864   /**
865    * Called when the window is damaged.
866    */
867   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
868   {
869     Ecore_X_Event_Window_Damage* windowDamagedEvent( (Ecore_X_Event_Window_Damage*)event );
870     EventHandler* handler( (EventHandler*)data );
871
872     if( windowDamagedEvent->win == handler->mImpl->mWindow )
873     {
874       DamageArea area;
875       area.x = windowDamagedEvent->x;
876       area.y = windowDamagedEvent->y;
877       area.width = windowDamagedEvent->w;
878       area.height = windowDamagedEvent->h;
879
880       handler->SendEvent( area );
881     }
882
883     return ECORE_CALLBACK_PASS_ON;
884   }
885
886   /**
887    * Called when the window properties are changed.
888    * We are only interested in the font change.
889    */
890
891
892   /////////////////////////////////////////////////////////////////////////////////////////////////
893   // Drag & Drop Callbacks
894   /////////////////////////////////////////////////////////////////////////////////////////////////
895
896   /**
897    * Called when a dragged item enters our window's bounds.
898    * This is when items are dragged INTO our window.
899    */
900   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
901   {
902     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
903
904     Ecore_X_Event_Xdnd_Enter* enterEvent( (Ecore_X_Event_Xdnd_Enter*) event );
905     EventHandler* handler( (EventHandler*)data );
906     Ecore_X_Window window ( handler->mImpl->mWindow );
907
908     if ( enterEvent->win == window )
909     {
910       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
911
912       // Check whether the Drag & Drop detector has Drag & Drop behaviour enabled before we accept.
913       if ( dndDetector && dndDetector->IsEnabled() )
914       {
915         // Tell Ecore that we want to enable drop in the entire window.
916         Ecore_X_Rectangle rect;
917         rect.x = rect.y = 0;
918         ecore_x_window_geometry_get( window, NULL, NULL, (int*)&rect.width, (int*)&rect.height );
919
920         // Tell Ecore that we are able to process a drop.
921         ecore_x_dnd_send_status( EINA_TRUE, EINA_FALSE, rect, ECORE_X_ATOM_XDND_DROP );
922
923         // Register the required atoms and types.
924         ecore_x_dnd_actions_set( window, DRAG_AND_DROP_ATOMS, DRAG_AND_DROP_ATOMS_NUMBER );
925         ecore_x_dnd_types_set(   window, DRAG_AND_DROP_TYPES, DRAG_AND_DROP_TYPES_NUMBER );
926
927         // Request to get the content from Ecore.
928         ecore_x_selection_xdnd_request( window, ECORE_X_SELECTION_TARGET_UTF8_STRING );
929
930         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndEnter: Requesting Drag & Drop\n" );
931
932         // Clear the previous content
933         dndDetector->ClearContent();
934
935         // Emit the entered signal
936         dndDetector->EmitEnteredSignal();
937       }
938     }
939
940     return ECORE_CALLBACK_PASS_ON;
941   }
942
943   /**
944    * Called when a dragged item is moved within our window.
945    * This is when items are dragged INTO our window.
946    */
947   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
948   {
949     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
950
951     Ecore_X_Event_Xdnd_Position* positionEvent( (Ecore_X_Event_Xdnd_Position*) event );
952     EventHandler* handler( (EventHandler*)data );
953
954     if ( positionEvent->win == handler->mImpl->mWindow )
955     {
956       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
957
958       // If we have a detector then update its latest position.
959       if ( dndDetector )
960       {
961         DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndPosition: position ( %d x %d )\n", positionEvent->position.x, positionEvent->position.y );
962         dndDetector->SetPosition( Vector2( positionEvent->position.x, positionEvent->position.y ));
963         dndDetector->EmitMovedSignal();
964       }
965     }
966
967     return ECORE_CALLBACK_PASS_ON;
968   }
969
970   /**
971    * Called when a dragged item leaves our window's bounds.
972    * This is when items are dragged INTO our window.
973    */
974   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
975   {
976     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
977
978     Ecore_X_Event_Xdnd_Leave* leaveEvent( (Ecore_X_Event_Xdnd_Leave*) event );
979     EventHandler* handler( (EventHandler*)data );
980
981     if ( leaveEvent->win == handler->mImpl->mWindow )
982     {
983       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
984
985       // If we have a detector then clear its content and emit the exited-signal. Also tell Ecore that we have finished.
986       if ( dndDetector )
987       {
988         dndDetector->ClearContent();
989         dndDetector->EmitExitedSignal();
990
991         ecore_x_dnd_send_finished();
992
993         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndLeave: Finished\n" );
994       }
995     }
996
997     return ECORE_CALLBACK_PASS_ON;
998   }
999
1000   /**
1001    * Called when the dragged item is dropped within our window's bounds.
1002    * This is when items are dragged INTO our window.
1003    */
1004   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
1005   {
1006     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
1007
1008     Ecore_X_Event_Xdnd_Drop* dropEvent ( (Ecore_X_Event_Xdnd_Drop*) event);
1009     EventHandler* handler( (EventHandler*)data );
1010
1011     if ( dropEvent->win == handler->mImpl->mWindow )
1012     {
1013       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
1014
1015       // Something has been dropped, inform the detector (if we have one) and tell Ecore that we have finished.
1016       if ( dndDetector )
1017       {
1018         DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: position ( %d x %d )\n", dropEvent->position.x, dropEvent->position.y );
1019
1020         dndDetector->SetPosition( Vector2( dropEvent->position.x, dropEvent->position.y ) );
1021         dndDetector->EmitDroppedSignal();
1022         ecore_x_dnd_send_finished();
1023
1024         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: Finished\n" );
1025       }
1026     }
1027
1028     return ECORE_CALLBACK_PASS_ON;
1029   }
1030
1031   /**
1032    * Called when a dragged item is moved from our window and the target window has done processing it.
1033    * This is when items are dragged FROM our window.
1034    */
1035   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
1036   {
1037     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
1038     return ECORE_CALLBACK_PASS_ON;
1039   }
1040
1041   /**
1042    * Called when a dragged item is moved from our window and the target window has sent us a status.
1043    * This is when items are dragged FROM our window.
1044    */
1045   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
1046   {
1047     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
1048     return ECORE_CALLBACK_PASS_ON;
1049   }
1050
1051   /**
1052    * Called when the client messages (i.e. the accessibility events) are received.
1053    */
1054   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
1055   {
1056 #ifndef DALI_PROFILE_UBUNTU
1057     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
1058     EventHandler* handler( (EventHandler*)data );
1059
1060     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
1061     {
1062       if ( ( (unsigned int)clientMessageEvent->data.l[0] == handler->mImpl->mWindow ) && handler->mAccessibilityAdaptor )
1063       {
1064         AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( handler->mAccessibilityAdaptor ) );
1065
1066         if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL)
1067         {
1068           // 2 finger touch & move, 2 finger flick
1069
1070           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
1071           // x : e->data.l[3]
1072           // y : e->data.l[4]
1073           TouchPoint::State state(TouchPoint::Down);
1074
1075           if ((unsigned int)clientMessageEvent->data.l[2] == 0)
1076           {
1077             state = TouchPoint::Down; // mouse down
1078           }
1079           else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
1080           {
1081             state = TouchPoint::Motion; // mouse move
1082           }
1083           else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
1084           {
1085             state = TouchPoint::Up; // mouse up
1086           }
1087           else
1088           {
1089             state = TouchPoint::Interrupted; // error
1090           }
1091
1092           DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
1093             "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
1094             (unsigned int)clientMessageEvent->data.l[2],
1095             (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
1096
1097           // Send touch event to accessibility adaptor.
1098           TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
1099
1100           // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
1101           accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
1102         }
1103         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE)
1104         {
1105           // 1 finger double tap and hold
1106
1107           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
1108           // x : e->data.l[3]
1109           // y : e->data.l[4]
1110           TouchPoint::State state(TouchPoint::Down);
1111
1112           if ((unsigned int)clientMessageEvent->data.l[2] == 0)
1113           {
1114             state = TouchPoint::Down; // mouse down
1115           }
1116           else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
1117           {
1118             state = TouchPoint::Motion; // mouse move
1119           }
1120           else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
1121           {
1122             state = TouchPoint::Up; // mouse up
1123           }
1124           else
1125           {
1126             state = TouchPoint::Interrupted; // error
1127           }
1128
1129           DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
1130             "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
1131             (unsigned int)clientMessageEvent->data.l[2],
1132             (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
1133
1134           // Send touch event to accessibility adaptor.
1135           TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
1136
1137           // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
1138           accessibilityAdaptor->HandleActionTouchEvent( point, GetCurrentMilliSeconds() );
1139         }
1140         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK)
1141         {
1142           // 2 finger circle draw, do back
1143           accessibilityAdaptor->HandleActionBackEvent();
1144         }
1145         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
1146         {
1147           // one finger flick down
1148           // focus next object
1149           if(accessibilityAdaptor)
1150           {
1151             accessibilityAdaptor->HandleActionNextEvent();
1152           }
1153         }
1154         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
1155         {
1156           // one finger flick up
1157           // focus previous object
1158           if(accessibilityAdaptor)
1159           {
1160             accessibilityAdaptor->HandleActionPreviousEvent();
1161           }
1162         }
1163         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
1164         {
1165           // one finger double tap
1166           // same as one finger tap in normal mode (i.e. execute focused actor)
1167           if(accessibilityAdaptor)
1168           {
1169             accessibilityAdaptor->HandleActionActivateEvent();
1170           }
1171         }
1172         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
1173         {
1174           // one finger tap
1175           // focus & read an actor at ( e->data.l[2], e->data.l[3] ) position according to finger
1176           if(accessibilityAdaptor)
1177           {
1178             accessibilityAdaptor->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[2], (unsigned int)clientMessageEvent->data.l[3], true /* allow read again*/);
1179           }
1180         }
1181 #if defined(DALI_PROFILE_MOBILE)
1182         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER)
1183         {
1184           // one finger tap & move
1185           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
1186           // x : e->data.l[3]
1187           // y : e->data.l[4]
1188           // focus & read an actor at (x, y) position according to finger
1189           if(accessibilityAdaptor && (unsigned int)clientMessageEvent->data.l[2] == 1 /*only work for move event*/)
1190           {
1191             accessibilityAdaptor->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4], false /* not allow read again*/);
1192           }
1193         }
1194 #endif
1195         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
1196         {
1197           // one finger flick right
1198           // focus next object
1199            if(accessibilityAdaptor)
1200           {
1201             accessibilityAdaptor->HandleActionReadNextEvent();
1202           }
1203         }
1204         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
1205         {
1206           // one finger flick left
1207           // focus previous object
1208           if(accessibilityAdaptor)
1209           {
1210             accessibilityAdaptor->HandleActionReadPreviousEvent();
1211           }
1212         }
1213         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
1214         {
1215           // double down and move (right, up)
1216           // change slider value
1217           if(accessibilityAdaptor)
1218           {
1219             accessibilityAdaptor->HandleActionUpEvent();
1220           }
1221         }
1222         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
1223         {
1224           // double down and move (left, down)
1225           // change slider value
1226           if(accessibilityAdaptor)
1227           {
1228             accessibilityAdaptor->HandleActionDownEvent();
1229           }
1230         }
1231         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE)
1232         {
1233            if(accessibilityAdaptor)
1234           {
1235             accessibilityAdaptor->HandleActionEnableEvent();
1236           }
1237         }
1238         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE)
1239         {
1240           if(accessibilityAdaptor)
1241           {
1242             accessibilityAdaptor->HandleActionDisableEvent();
1243           }
1244         }
1245         // TODO: some more actions could be added later
1246       }
1247     }
1248     else if(clientMessageEvent->message_type == ecore_x_atom_get(CLIPBOARD_ATOM))
1249     {
1250       std::string message(clientMessageEvent->data.b);
1251       if( message == CLIPBOARD_SET_OWNER_MESSAGE)
1252       {
1253         // Claim the ownership of the SECONDARY selection.
1254         ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
1255
1256         // Show the clipboard window
1257         Dali::Clipboard clipboard = Dali::Clipboard::Get();
1258         clipboard.ShowClipboard();
1259       }
1260     }
1261     else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE )
1262     {
1263       RotationEvent rotationEvent;
1264       rotationEvent.angle      = static_cast<int>(clientMessageEvent->data.l[1]);
1265       rotationEvent.winResize  = static_cast<int>(clientMessageEvent->data.l[2]);
1266       rotationEvent.width      = static_cast<int>(clientMessageEvent->data.l[3]);
1267       rotationEvent.height     = static_cast<int>(clientMessageEvent->data.l[4]);
1268       handler->SendRotationPrepareEvent( rotationEvent );
1269     }
1270     else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST )
1271     {
1272       handler->SendRotationRequestEvent();
1273     }
1274
1275 #endif // DALI_PROFILE_UBUNTU
1276     return ECORE_CALLBACK_PASS_ON;
1277   }
1278
1279
1280   /////////////////////////////////////////////////////////////////////////////////////////////////
1281   // ElDBus Accessibility Callbacks
1282   /////////////////////////////////////////////////////////////////////////////////////////////////
1283
1284 #ifdef DALI_ELDBUS_AVAILABLE
1285   // Callback for Ecore ElDBus accessibility events.
1286   static void OnEcoreElDBusAccessibilityNotification( void *context EINA_UNUSED, const Eldbus_Message *message )
1287   {
1288     EventHandler* handler = static_cast< EventHandler* >( context );
1289     // Ignore any accessibility events when paused.
1290     if( handler->mPaused )
1291     {
1292       return;
1293     }
1294
1295     if ( !handler->mAccessibilityAdaptor )
1296     {
1297       DALI_LOG_ERROR( "Invalid accessibility adaptor\n" );
1298       return;
1299     }
1300
1301     AccessibilityAdaptor* accessibilityAdaptor( &AccessibilityAdaptor::GetImplementation( handler->mAccessibilityAdaptor ) );
1302     if ( !accessibilityAdaptor )
1303     {
1304       DALI_LOG_ERROR( "Cannot access accessibility adaptor\n" );
1305       return;
1306     }
1307
1308     const char *gestureName;
1309     int xS, yS, xE, yE;
1310     unsigned int state;
1311
1312     // The string defines the arg-list's respective types.
1313     if( !eldbus_message_arguments_get( message, "siiiiu", &gestureName, &xS, &yS, &xE, &yE, &state ) )
1314     {
1315       DALI_LOG_ERROR( "OnEcoreElDBusAccessibilityNotification: Error getting arguments\n" );
1316     }
1317
1318     DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Name: %s  Args: %d,%d,%d,%d  State: %d\n", gestureName, xS, yS, xE, yE );
1319
1320     unsigned int fingers = 0;
1321     char* stringPosition = ( char* )gestureName;
1322
1323     // Check how many fingers the gesture uses.
1324     for( unsigned int i = 0; i < FingerCountStringsTotal; ++i )
1325     {
1326       unsigned int matchLength = strlen( ElDBusAccessibilityFingerCountStrings[ i ] );
1327       if( strncmp( gestureName, ElDBusAccessibilityFingerCountStrings[ i ], matchLength ) == 0 )
1328       {
1329         fingers = i + 1;
1330         stringPosition += matchLength;
1331         break;
1332       }
1333     }
1334
1335     if( fingers == 0 )
1336     {
1337       // Error: invalid gesture.
1338       return;
1339     }
1340
1341     GestureType gestureType = GESTURE_TYPE_NONE;
1342     SubGestureType subGestureType = SUB_GESTURE_TYPE_NONE;
1343     GestureDirection direction = GESTURE_DIRECTION_NONE;
1344
1345     // Check for full gesture type names first.
1346     for( unsigned int i = 0; i < FullEventTypeStringsTotal; ++i )
1347     {
1348       unsigned int matchLength = strlen( ElDBusAccessibilityFullEventTypeStrings[ i ].name );
1349       if( strncmp( stringPosition, ElDBusAccessibilityFullEventTypeStrings[ i ].name, matchLength ) == 0 )
1350       {
1351         gestureType = ElDBusAccessibilityFullEventTypeStrings[ i ].type;
1352         break;
1353       }
1354     }
1355
1356     // If we didn't find a full gesture, check for sub gesture type names.
1357     if( gestureType == GESTURE_TYPE_NONE )
1358     {
1359       // No full gesture name found, look for partial types.
1360       for( unsigned int i = 0; i < DirectionalEventTypeStringsTotal; ++i )
1361       {
1362         unsigned int matchLength = strlen( ElDBusAccessibilityDirectionalEventTypeStrings[ i ].name );
1363         if( strncmp( stringPosition, ElDBusAccessibilityDirectionalEventTypeStrings[ i ].name, matchLength ) == 0 )
1364         {
1365           subGestureType = ElDBusAccessibilityDirectionalEventTypeStrings[ i ].type;
1366           stringPosition += matchLength;
1367         break;
1368         }
1369       }
1370
1371       if( subGestureType == SUB_GESTURE_TYPE_NONE )
1372       {
1373         // ERROR: Gesture not recognised.
1374         return;
1375       }
1376
1377       // If the gesture was a sub type, get it's respective direction.
1378       for( unsigned int i = 0; i < DirectionStringsTotal; ++i )
1379       {
1380         unsigned int matchLength = strlen( ElDBusAccessibilityDirectionStrings[ i ].name );
1381         if( strncmp( stringPosition, ElDBusAccessibilityDirectionStrings[ i ].name, matchLength ) == 0 )
1382         {
1383           direction = ElDBusAccessibilityDirectionStrings[ i ].direction;
1384           stringPosition += matchLength;
1385           break;
1386         }
1387       }
1388
1389       if( direction == GESTURE_DIRECTION_NONE )
1390       {
1391         // ERROR: Gesture not recognised.
1392         return;
1393       }
1394     }
1395
1396     // Action the detected gesture here.
1397     if( gestureType != GESTURE_TYPE_NONE )
1398     {
1399       DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Fingers: %d  Gesture type: %d\n", fingers, gestureType );
1400     }
1401     else
1402     {
1403       DALI_LOG_INFO( gImfLogging, Debug::General, "Got gesture: Fingers: %d  Gesture sub type: %d Gesture direction: %d\n",
1404         fingers, subGestureType, direction );
1405     }
1406
1407     // Create a touch point object.
1408     TouchPoint::State touchPointState( TouchPoint::Down );
1409     if ( state == 0 )
1410     {
1411       touchPointState = TouchPoint::Down; // Mouse down.
1412     }
1413     else if ( state == 1 )
1414     {
1415       touchPointState = TouchPoint::Motion; // Mouse move.
1416     }
1417     else if ( state == 2 )
1418     {
1419       touchPointState = TouchPoint::Up; // Mouse up.
1420     }
1421     else
1422     {
1423       touchPointState = TouchPoint::Interrupted; // Error.
1424     }
1425
1426     // Send touch event to accessibility adaptor.
1427     TouchPoint point( 0, touchPointState, (float)xS, (float)yS );
1428
1429     // Perform actions based on received gestures.
1430     // Note: This is seperated from the reading so we can (in future)
1431     // have other input readers without changing the below code.
1432     switch( fingers )
1433     {
1434       case 1:
1435       {
1436         if( gestureType == GESTURE_TYPE_SINGLE_TAP || ( gestureType == GESTURE_TYPE_HOVER && touchPointState == TouchPoint::Motion ) )
1437         {
1438           // Focus, read out.
1439           accessibilityAdaptor->HandleActionReadEvent( (unsigned int)xS, (unsigned int)yS, true /* allow read again */ );
1440         }
1441         else if( gestureType == GESTURE_TYPE_DOUBLE_TAP )
1442         {
1443           if( false ) // TODO: how to detect double tap + hold?
1444           {
1445             // Move or drag icon / view more options for selected items.
1446             // accessibilityAdaptor->HandleActionTouchEvent( point, GetCurrentMilliSeconds() );
1447           }
1448           else
1449           {
1450             // Activate selected item / active edit mode.
1451             accessibilityAdaptor->HandleActionActivateEvent();
1452           }
1453         }
1454         else if( gestureType == GESTURE_TYPE_TRIPLE_TAP )
1455         {
1456           // Zoom
1457           accessibilityAdaptor->HandleActionZoomEvent();
1458         }
1459         else if( subGestureType == SUB_GESTURE_TYPE_FLICK )
1460         {
1461           if( direction == GESTURE_DIRECTION_LEFT )
1462           {
1463             // Move to previous item.
1464             accessibilityAdaptor->HandleActionReadPreviousEvent();
1465           }
1466           else if( direction == GESTURE_DIRECTION_RIGHT )
1467           {
1468             // Move to next item.
1469             accessibilityAdaptor->HandleActionReadNextEvent();
1470           }
1471           else if( direction == GESTURE_DIRECTION_UP )
1472           {
1473             // Move to next item.
1474             accessibilityAdaptor->HandleActionPreviousEvent();
1475           }
1476           else if( direction == GESTURE_DIRECTION_DOWN )
1477           {
1478             // Move to next item.
1479             accessibilityAdaptor->HandleActionNextEvent();
1480           }
1481           else if( direction == GESTURE_DIRECTION_LEFT_RETURN )
1482           {
1483             // Scroll up to the previous page
1484             accessibilityAdaptor->HandleActionPageUpEvent();
1485           }
1486           else if( direction == GESTURE_DIRECTION_RIGHT_RETURN )
1487           {
1488             // Scroll down to the next page
1489             accessibilityAdaptor->HandleActionPageDownEvent();
1490           }
1491           else if( direction == GESTURE_DIRECTION_UP_RETURN )
1492           {
1493             // Move to the first item on screen
1494             accessibilityAdaptor->HandleActionMoveToFirstEvent();
1495           }
1496           else if( direction == GESTURE_DIRECTION_DOWN_RETURN )
1497           {
1498             // Move to the last item on screen
1499             accessibilityAdaptor->HandleActionMoveToLastEvent();
1500           }
1501         }
1502         break;
1503       }
1504
1505       case 2:
1506       {
1507         if( gestureType == GESTURE_TYPE_HOVER )
1508         {
1509           // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
1510           accessibilityAdaptor->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
1511         }
1512         else if( gestureType == GESTURE_TYPE_SINGLE_TAP )
1513         {
1514           // Pause/Resume current speech
1515           accessibilityAdaptor->HandleActionReadPauseResumeEvent();
1516         }
1517         else if( gestureType == GESTURE_TYPE_DOUBLE_TAP )
1518         {
1519           // Start/Stop current action
1520           accessibilityAdaptor->HandleActionStartStopEvent();
1521         }
1522         else if( gestureType == GESTURE_TYPE_TRIPLE_TAP )
1523         {
1524           // Read information from indicator
1525           accessibilityAdaptor->HandleActionReadIndicatorInformationEvent();
1526         }
1527         else if( subGestureType == SUB_GESTURE_TYPE_FLICK )
1528         {
1529           if( direction == GESTURE_DIRECTION_LEFT )
1530           {
1531             // Scroll left to the previous page
1532             accessibilityAdaptor->HandleActionPageLeftEvent();
1533           }
1534           else if( direction == GESTURE_DIRECTION_RIGHT )
1535           {
1536             // Scroll right to the next page
1537             accessibilityAdaptor->HandleActionPageRightEvent();
1538           }
1539           else if( direction == GESTURE_DIRECTION_UP )
1540           {
1541             // Scroll up the list.
1542             accessibilityAdaptor->HandleActionScrollUpEvent();
1543           }
1544           else if( direction == GESTURE_DIRECTION_DOWN )
1545           {
1546             // Scroll down the list.
1547             accessibilityAdaptor->HandleActionScrollDownEvent();
1548           }
1549         }
1550         break;
1551       }
1552
1553       case 3:
1554       {
1555         if( gestureType == GESTURE_TYPE_SINGLE_TAP )
1556         {
1557           // Read from top item on screen continuously.
1558           accessibilityAdaptor->HandleActionReadFromTopEvent();
1559         }
1560         else if( gestureType == GESTURE_TYPE_DOUBLE_TAP )
1561         {
1562           // Read from next item continuously.
1563           accessibilityAdaptor->HandleActionReadFromNextEvent();
1564         }
1565         break;
1566       }
1567     }
1568   }
1569
1570   // Callback for to set up Ecore ElDBus for accessibility callbacks.
1571   static void EcoreElDBusInitialisation( void *handle, const Eldbus_Message *message, Eldbus_Pending *pending EINA_UNUSED )
1572   {
1573     Eldbus_Object *object;
1574     Eldbus_Proxy *manager;
1575     const char *a11yBusAddress = NULL;
1576     EventHandler* handler = static_cast< EventHandler* >( handle );
1577
1578     // The string defines the arg-list's respective types.
1579     if( !eldbus_message_arguments_get( message, "s", &a11yBusAddress ) )
1580     {
1581       DALI_LOG_ERROR( "EcoreElDBusInitialisation: Error getting arguments\n" );
1582     }
1583
1584     DALI_LOG_INFO( gImfLogging, Debug::General, "Ecore ElDBus Accessibility address: %s\n", a11yBusAddress );
1585
1586     handler->mImpl->mA11yConnection = eldbus_address_connection_get( a11yBusAddress );
1587
1588     object = eldbus_object_get( handler->mImpl->mA11yConnection, BUS, PATH );
1589     manager = eldbus_proxy_get( object, INTERFACE );
1590
1591     // Pass the callback data through to the signal handler.
1592     eldbus_proxy_signal_handler_add( manager, SIGNAL, OnEcoreElDBusAccessibilityNotification, handle );
1593   }
1594 #endif // DALI_ELDBUS_AVAILABLE
1595
1596   /**
1597    * Called when the source window notifies us the content in clipboard is selected.
1598    */
1599   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
1600   {
1601     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
1602     Ecore_X_Event_Selection_Clear* selectionClearEvent( (Ecore_X_Event_Selection_Clear*) event );
1603     EventHandler* handler( (EventHandler*)data );
1604
1605     if ( selectionClearEvent->win == handler->mImpl->mWindow )
1606     {
1607       if ( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY )
1608       {
1609         // Request to get the content from Ecore.
1610         ecore_x_selection_secondary_request(selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT);
1611       }
1612     }
1613     return ECORE_CALLBACK_PASS_ON;
1614   }
1615
1616   /**
1617    * Called when the source window sends us about the selected content.
1618    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
1619    */
1620   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
1621   {
1622     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
1623
1624     Ecore_X_Event_Selection_Notify* selectionNotifyEvent( (Ecore_X_Event_Selection_Notify*) event );
1625     EventHandler* handler( (EventHandler*)data );
1626
1627     if ( selectionNotifyEvent->win == handler->mImpl->mWindow )
1628     {
1629       Ecore_X_Selection_Data* selectionData( (Ecore_X_Selection_Data*) selectionNotifyEvent->data );
1630       if ( selectionData->data )
1631       {
1632         if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_XDND )
1633         {
1634           DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
1635
1636           // We have got the content that is to be dropped, inform the DndListener (if we have one).
1637           if ( dndDetector )
1638           {
1639             std::string content( (char*) selectionData->data, selectionData->length );
1640             dndDetector->SetContent( content );
1641
1642             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1643             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1644             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1645             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1646           }
1647         }
1648         else if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY )
1649         {
1650           // We have got the selected content, inform the clipboard event listener (if we have one).
1651           if ( handler->mClipboardEventNotifier )
1652           {
1653             ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) );
1654             std::string content( (char*) selectionData->data, selectionData->length );
1655             clipboardEventNotifier.SetContent( content );
1656             clipboardEventNotifier.EmitContentSelectedSignal();
1657           }
1658
1659           // Claim the ownership of the SECONDARY selection.
1660           ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
1661
1662           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1663           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1664           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1665           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1666         }
1667       }
1668     }
1669     return ECORE_CALLBACK_PASS_ON;
1670   }
1671
1672
1673 #ifndef DALI_PROFILE_UBUNTU
1674   /////////////////////////////////////////////////////////////////////////////////////////////////
1675   // Font Callbacks
1676   /////////////////////////////////////////////////////////////////////////////////////////////////
1677   /**
1678    * Called when a font name is changed.
1679    */
1680   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
1681   {
1682     EventHandler* handler = static_cast<EventHandler*>( data );
1683     handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
1684   }
1685
1686   /**
1687    * Called when a font size is changed.
1688    */
1689   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
1690   {
1691     DALI_LOG_INFO(gTouchEventLogFilter, Debug::Verbose, "VconfNotifyFontSizeChanged\n" );
1692     EventHandler* handler = static_cast<EventHandler*>( data );
1693     handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
1694   }
1695 #endif // DALI_PROFILE_UBUNTU
1696
1697   // Data
1698   EventHandler* mHandler;
1699   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
1700   Ecore_X_Window mWindow;
1701   int mXiDeviceId;
1702
1703 #ifdef DALI_ELDBUS_AVAILABLE
1704   Eldbus_Connection* mSessionConnection;
1705   Eldbus_Connection* mA11yConnection;
1706 #endif
1707 };
1708
1709 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
1710 : mCoreEventInterface( coreEventInterface ),
1711   mGestureManager( gestureManager ),
1712   mStyleMonitor( StyleMonitor::Get() ),
1713   mDamageObserver( damageObserver ),
1714   mRotationObserver( NULL ),
1715   mDragAndDropDetector( dndDetector ),
1716   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
1717   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
1718   mClipboard( Clipboard::Get() ),
1719   mImpl( NULL ),
1720   mPaused( false )
1721 {
1722   Ecore_X_Window window = 0;
1723
1724   // this code only works with the EcoreX11 RenderSurface so need to downcast
1725   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
1726   if( ecoreSurface )
1727   {
1728     // enable multi touch
1729     window = ecoreSurface->GetXWindow();
1730   }
1731
1732   mImpl = new Impl(this, window);
1733 }
1734
1735 EventHandler::~EventHandler()
1736 {
1737   delete mImpl;
1738
1739   mGestureManager.Stop();
1740 }
1741
1742 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)
1743 {
1744   if(timeStamp < 1)
1745   {
1746     timeStamp = GetCurrentMilliSeconds();
1747   }
1748
1749   Integration::TouchEvent touchEvent;
1750   Integration::HoverEvent hoverEvent;
1751   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
1752   if(type != Integration::TouchEventCombiner::DispatchNone )
1753   {
1754     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);
1755
1756     // First the touch and/or hover event & related gesture events are queued
1757     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
1758     {
1759       mCoreEventInterface.QueueCoreEvent( touchEvent );
1760       mGestureManager.SendEvent(touchEvent);
1761     }
1762
1763     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
1764     {
1765       mCoreEventInterface.QueueCoreEvent( hoverEvent );
1766     }
1767
1768     // Next the events are processed with a single call into Core
1769     mCoreEventInterface.ProcessCoreEvents();
1770   }
1771 }
1772
1773 void EventHandler::SendEvent(Integration::KeyEvent& keyEvent)
1774 {
1775   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
1776   if ( physicalKeyboard )
1777   {
1778     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyName.c_str() ) )
1779     {
1780       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
1781     }
1782   }
1783
1784   // Send to KeyEvent Core.
1785   mCoreEventInterface.QueueCoreEvent( keyEvent );
1786   mCoreEventInterface.ProcessCoreEvents();
1787 }
1788
1789 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
1790 {
1791   // Create WheelEvent and send to Core.
1792   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
1793   mCoreEventInterface.QueueCoreEvent( event );
1794   mCoreEventInterface.ProcessCoreEvents();
1795 }
1796
1797 void EventHandler::SendEvent( StyleChange::Type styleChange )
1798 {
1799   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
1800   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
1801 }
1802
1803 void EventHandler::SendEvent( const DamageArea& area )
1804 {
1805   mDamageObserver.OnDamaged( area );
1806 }
1807
1808 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
1809 {
1810   if( mRotationObserver != NULL )
1811   {
1812     mRotationObserver->OnRotationPrepare( event );
1813   }
1814 }
1815
1816 void EventHandler::SendRotationRequestEvent( )
1817 {
1818   if( mRotationObserver != NULL )
1819   {
1820     mRotationObserver->OnRotationRequest( );
1821   }
1822 }
1823
1824 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
1825 {
1826   Integration::Point convertedPoint( point );
1827
1828   SendEvent(convertedPoint, timeStamp);
1829 }
1830
1831 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
1832 {
1833   SendWheelEvent( wheelEvent );
1834 }
1835
1836 void EventHandler::FeedKeyEvent( KeyEvent& event )
1837 {
1838   Integration::KeyEvent convertedEvent( event );
1839   SendEvent( convertedEvent );
1840 }
1841
1842 void EventHandler::FeedEvent( Integration::Event& event )
1843 {
1844   mCoreEventInterface.QueueCoreEvent( event );
1845   mCoreEventInterface.ProcessCoreEvents();
1846 }
1847
1848 void EventHandler::Reset()
1849 {
1850   mCombiner.Reset();
1851
1852   // Any touch listeners should be told of the interruption.
1853   Integration::TouchEvent event;
1854   Integration::Point point;
1855   point.SetState( PointState::INTERRUPTED );
1856   event.AddPoint( point );
1857
1858   // First the touch event & related gesture events are queued
1859   mCoreEventInterface.QueueCoreEvent( event );
1860   mGestureManager.SendEvent( event );
1861
1862   // Next the events are processed with a single call into Core
1863   mCoreEventInterface.ProcessCoreEvents();
1864 }
1865
1866 void EventHandler::Pause()
1867 {
1868   mPaused = true;
1869   Reset();
1870 }
1871
1872 void EventHandler::Resume()
1873 {
1874   mPaused = false;
1875   Reset();
1876 }
1877
1878 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
1879 {
1880   mDragAndDropDetector = detector;
1881 }
1882
1883 void EventHandler::SetRotationObserver( RotationObserver* observer )
1884 {
1885   mRotationObserver = observer;
1886 }
1887
1888 } // namespace Adaptor
1889
1890 } // namespace Internal
1891
1892 } // namespace Dali
1893
1894 #pragma GCC diagnostic pop