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