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