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