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