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