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