[3.0] Implement detent event handler for wayland
[platform/core/uifw/dali-adaptor.git] / adaptors / ecore / wayland / event-handler-ecore-wl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <events/event-handler.h>
20
21 // EXTERNAL INCLUDES
22 #include <Ecore.h>
23 #include <Ecore_Input.h>
24 #include <ecore-wl-render-surface.h>
25 #include <cstring>
26
27 #include <sys/time.h>
28
29 #ifndef DALI_PROFILE_UBUNTU
30 #include <vconf.h>
31 #include <vconf-keys.h>
32 #endif // DALI_PROFILE_UBUNTU
33
34 #include <dali/public-api/common/vector-wrapper.h>
35 #include <dali/public-api/events/touch-point.h>
36 #include <dali/public-api/events/key-event.h>
37 #include <dali/public-api/events/wheel-event.h>
38 #include <dali/integration-api/debug.h>
39 #include <dali/integration-api/events/key-event-integ.h>
40 #include <dali/integration-api/events/touch-event-integ.h>
41 #include <dali/integration-api/events/hover-event-integ.h>
42 #include <dali/integration-api/events/wheel-event-integ.h>
43
44 // INTERNAL INCLUDES
45 #include <events/gesture-manager.h>
46 #include <window-render-surface.h>
47 #include <clipboard-impl.h>
48 #include <key-impl.h>
49 #include <physical-keyboard-impl.h>
50 #include <style-monitor-impl.h>
51 #include <base/core-event-interface.h>
52 #include <virtual-keyboard.h>
53
54 namespace Dali
55 {
56
57 namespace Internal
58 {
59
60 namespace Adaptor
61 {
62
63 #if defined(DEBUG_ENABLED)
64 namespace
65 {
66 Integration::Log::Filter* gTouchEventLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");
67 Integration::Log::Filter* gClientMessageLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_CLIENT_MESSAGE");
68 Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND");
69 Integration::Log::Filter* gImfLogging  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF");
70 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");
71 } // unnamed namespace
72 #endif
73
74
75 namespace
76 {
77 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
78
79 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
80
81 /**
82  * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.
83  * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.
84  * @param[in] ecoreModifier the Ecore_Event_Modifier input.
85  * @return the Ecore_IMF_Keyboard_Modifiers output.
86  */
87 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)
88 {
89    int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.
90
91
92    if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h
93    {
94      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h
95    }
96
97    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
98    {
99      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
100    }
101
102    if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
103    {
104      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
105    }
106
107    if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
108    {
109      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
110    }
111
112    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
113    {
114      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
115    }
116
117    return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
118 }
119
120
121 // Copied from x server
122 static unsigned int GetCurrentMilliSeconds(void)
123 {
124   struct timeval tv;
125
126   struct timespec tp;
127   static clockid_t clockid;
128
129   if (!clockid)
130   {
131 #ifdef CLOCK_MONOTONIC_COARSE
132     if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
133       (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
134     {
135       clockid = CLOCK_MONOTONIC_COARSE;
136     }
137     else
138 #endif
139     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
140     {
141       clockid = CLOCK_MONOTONIC;
142     }
143     else
144     {
145       clockid = ~0L;
146     }
147   }
148   if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
149   {
150     return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
151   }
152
153   gettimeofday(&tv, NULL);
154   return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
155 }
156
157 #ifndef DALI_PROFILE_UBUNTU
158 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE = "db/setting/accessibility/font_name";  // It will be update at vconf-key.h and replaced.
159 #endif // DALI_PROFILE_UBUNTU
160
161 } // unnamed namespace
162
163 // Impl to hide EFL implementation.
164 struct EventHandler::Impl
165 {
166   // Construction & Destruction
167
168   /**
169    * Constructor
170    */
171   Impl( EventHandler* handler, Ecore_Wl_Window* window )
172   : mHandler( handler ),
173     mEcoreEventHandler(),
174     mWindow( window )
175   {
176     // Only register for touch and key events if we have a window
177     if ( window != 0 )
178     {
179       // Register Touch events
180       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,  EcoreEventMouseButtonDown, handler ) );
181       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,    EcoreEventMouseButtonUp,   handler ) );
182       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,         EcoreEventMouseButtonMove, handler ) );
183       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT,          EcoreEventMouseButtonUp,   handler ) ); // process mouse out event like up event
184
185       // Register Mouse wheel events
186       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,        EcoreEventMouseWheel,      handler ) );
187
188       // Register Focus events
189       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );
190       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );
191
192       // Register Key events
193       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
194       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
195
196       // Register Detent event
197       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_DETENT_ROTATE, EcoreEventDetent, handler) );
198 #ifndef DALI_PROFILE_UBUNTU
199       // Register Vconf notify - font name and size
200       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged, handler );
201       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
202 #endif // DALI_PROFILE_UBUNTU
203     }
204   }
205
206   /**
207    * Destructor
208    */
209   ~Impl()
210   {
211 #ifndef DALI_PROFILE_UBUNTU
212     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
213     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged );
214 #endif // DALI_PROFILE_UBUNTU
215
216     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
217     {
218       ecore_event_handler_del( *iter );
219     }
220   }
221
222   // Static methods
223
224   /////////////////////////////////////////////////////////////////////////////////////////////////
225   // Touch Callbacks
226   /////////////////////////////////////////////////////////////////////////////////////////////////
227
228   /**
229    * Called when a touch down is received.
230    */
231   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
232   {
233     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
234     EventHandler* handler( (EventHandler*)data );
235
236     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
237     {
238       PointState::Type state ( PointState::DOWN );
239
240       // Check if the buttons field is set and ensure it's the primary touch button.
241       // If this event was triggered by buttons other than the primary button (used for touch), then
242       // just send an interrupted event to Core.
243       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
244       {
245         state = PointState::INTERRUPTED;
246       }
247
248       Integration::Point point;
249       point.SetDeviceId( touchEvent->multi.device );
250       point.SetState( state );
251       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
252       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
253       point.SetPressure( touchEvent->multi.pressure );
254       point.SetAngle( Degree( touchEvent->multi.angle ) );
255       handler->SendEvent( point, touchEvent->timestamp );
256     }
257
258     return ECORE_CALLBACK_PASS_ON;
259   }
260
261   /**
262    * Called when a touch up is received.
263    */
264   static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
265   {
266     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
267     EventHandler* handler( (EventHandler*)data );
268
269     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
270     {
271       Integration::Point point;
272       point.SetDeviceId( touchEvent->multi.device );
273       point.SetState( PointState::UP );
274       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
275       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
276       point.SetPressure( touchEvent->multi.pressure );
277       point.SetAngle( Degree( touchEvent->multi.angle ) );
278       handler->SendEvent( point, touchEvent->timestamp );
279     }
280
281     return ECORE_CALLBACK_PASS_ON;
282   }
283
284   /**
285    * Called when a touch up is received.
286    */
287   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
288   {
289     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
290
291     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);
292
293     EventHandler* handler( (EventHandler*)data );
294     if ( mouseWheelEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
295     {
296       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
297       handler->SendWheelEvent( wheelEvent );
298     }
299     return ECORE_CALLBACK_PASS_ON;
300   }
301
302   /**
303    * Called when a touch motion is received.
304    */
305   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
306   {
307     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
308     EventHandler* handler( (EventHandler*)data );
309
310     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
311     {
312       Integration::Point point;
313       point.SetDeviceId( touchEvent->multi.device );
314       point.SetState( PointState::MOTION );
315       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
316       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
317       point.SetPressure( touchEvent->multi.pressure );
318       point.SetAngle( Degree( touchEvent->multi.angle ) );
319       handler->SendEvent( point, touchEvent->timestamp );
320     }
321
322     return ECORE_CALLBACK_PASS_ON;
323   }
324
325   /////////////////////////////////////////////////////////////////////////////////////////////////
326   // Key Callbacks
327   /////////////////////////////////////////////////////////////////////////////////////////////////
328
329   /**
330    * Called when a key down is received.
331    */
332   static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
333   {
334     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
335
336     EventHandler* handler( (EventHandler*)data );
337     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
338     bool eventHandled( false );
339
340     // If a device key then skip ecore_imf_context_filter_event.
341     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
342     {
343       Ecore_IMF_Context* imfContext = NULL;
344       Dali::ImfManager imfManager( ImfManager::Get() );
345       if ( imfManager )
346       {
347         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
348       }
349
350       if ( imfContext )
351       {
352         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
353         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
354         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
355         ecoreKeyDownEvent.key       = keyEvent->key;
356         ecoreKeyDownEvent.string    = keyEvent->string;
357         ecoreKeyDownEvent.compose   = keyEvent->compose;
358         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
359         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
360         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
361
362         eventHandled = ecore_imf_context_filter_event( imfContext,
363                                                        ECORE_IMF_EVENT_KEY_DOWN,
364                                                        (Ecore_IMF_Event *) &ecoreKeyDownEvent );
365
366         // If the event has not been handled by IMF then check if we should reset our IMF context
367         if( !eventHandled )
368         {
369           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
370                !strcmp( keyEvent->keyname, "Return"   ) ||
371                !strcmp( keyEvent->keyname, "KP_Enter" ) )
372           {
373             ecore_imf_context_reset( imfContext );
374           }
375         }
376       }
377     }
378
379     // If the event wasn't handled then we should send a key event.
380     if ( !eventHandled )
381     {
382       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
383       {
384         std::string keyName( keyEvent->keyname );
385         std::string keyString( "" );
386         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
387         keyCode = (keyCode == -1) ? 0 : keyCode;
388         int modifier( keyEvent->modifiers );
389         unsigned long time = keyEvent->timestamp;
390         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
391           keyCode = atoi(keyEvent->keyname + 8);
392
393         // Ensure key event string is not NULL as keys like SHIFT have a null string.
394         if ( keyEvent->string )
395         {
396           keyString = keyEvent->string;
397         }
398
399         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Down);
400         handler->SendEvent( keyEvent );
401       }
402     }
403
404     return ECORE_CALLBACK_PASS_ON;
405   }
406
407   /**
408    * Called when a key up is received.
409    */
410   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
411   {
412     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp\n" );
413
414     EventHandler* handler( (EventHandler*)data );
415     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
416     bool eventHandled( false );
417
418     // Device keys like Menu, home, back button must skip ecore_imf_context_filter_event.
419     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
420     {
421       Ecore_IMF_Context* imfContext = NULL;
422       Dali::ImfManager imfManager( ImfManager::Get() );
423       if ( imfManager )
424       {
425         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
426       }
427
428       if ( imfContext )
429       {
430         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
431         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
432         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
433         ecoreKeyUpEvent.key       = keyEvent->key;
434         ecoreKeyUpEvent.string    = keyEvent->string;
435         ecoreKeyUpEvent.compose   = keyEvent->compose;
436         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
437         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
438         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
439
440         eventHandled = ecore_imf_context_filter_event( imfContext,
441                                                        ECORE_IMF_EVENT_KEY_UP,
442                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
443       }
444     }
445
446     // If the event wasn't handled then we should send a key event.
447     if ( !eventHandled )
448     {
449       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
450       {
451         std::string keyName( keyEvent->keyname );
452         std::string keyString( "" );
453         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
454         keyCode = (keyCode == -1) ? 0 : keyCode;
455         int modifier( keyEvent->modifiers );
456         unsigned long time = keyEvent->timestamp;
457         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
458           keyCode = atoi(keyEvent->keyname + 8);
459
460         // Ensure key event string is not NULL as keys like SHIFT have a null string.
461         if ( keyEvent->string )
462         {
463           keyString = keyEvent->string;
464         }
465
466         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Up);
467         handler->SendEvent( keyEvent );
468       }
469     }
470
471     return ECORE_CALLBACK_PASS_ON;
472   }
473
474   /////////////////////////////////////////////////////////////////////////////////////////////////
475   // Window Callbacks
476   /////////////////////////////////////////////////////////////////////////////////////////////////
477
478   /**
479    * Called when the window gains focus.
480    */
481   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
482   {
483     Ecore_Wl_Event_Focus_In* focusInEvent( (Ecore_Wl_Event_Focus_In*)event );
484     EventHandler* handler( (EventHandler*)data );
485
486     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
487
488     // If the window gains focus and we hid the keyboard then show it again.
489     if ( focusInEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
490     {
491       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
492
493       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
494       {
495         Dali::ImfManager imfManager( ImfManager::Get() );
496         if ( imfManager )
497         {
498           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
499           if( imfManagerImpl.RestoreAfterFocusLost() )
500           {
501             imfManagerImpl.Activate();
502           }
503         }
504       }
505       // No need to connect callbacks as KeyboardStatusChanged will be called.
506     }
507
508     return ECORE_CALLBACK_PASS_ON;
509   }
510
511   /**
512    * Called when the window loses focus.
513    */
514   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
515   {
516     Ecore_Wl_Event_Focus_Out* focusOutEvent( (Ecore_Wl_Event_Focus_Out*)event );
517     EventHandler* handler( (EventHandler*)data );
518
519     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
520
521     // If the window loses focus then hide the keyboard.
522     if ( focusOutEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
523     {
524       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
525       {
526         Dali::ImfManager imfManager( ImfManager::Get() );
527         if ( imfManager )
528         {
529           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
530           if( imfManagerImpl.RestoreAfterFocusLost() )
531           {
532             imfManagerImpl.Deactivate();
533           }
534         }
535       }
536
537       // Clipboard don't support that whether clipboard is shown or not. Hide clipboard.
538       Dali::Clipboard clipboard = Clipboard::Get();
539       clipboard.HideClipboard();
540     }
541
542     return ECORE_CALLBACK_PASS_ON;
543   }
544
545   /**
546    * Called when the window is damaged.
547    */
548   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
549   {
550     return ECORE_CALLBACK_PASS_ON;
551   }
552
553   /**
554    * Called when the window properties are changed.
555    * We are only interested in the font change.
556    */
557
558
559   /////////////////////////////////////////////////////////////////////////////////////////////////
560   // Drag & Drop Callbacks
561   /////////////////////////////////////////////////////////////////////////////////////////////////
562
563   /**
564    * Called when a dragged item enters our window's bounds.
565    * This is when items are dragged INTO our window.
566    */
567   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
568   {
569     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
570
571     return ECORE_CALLBACK_PASS_ON;
572   }
573
574   /**
575    * Called when a dragged item is moved within our window.
576    * This is when items are dragged INTO our window.
577    */
578   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
579   {
580     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
581
582     return ECORE_CALLBACK_PASS_ON;
583   }
584
585   /**
586    * Called when a dragged item leaves our window's bounds.
587    * This is when items are dragged INTO our window.
588    */
589   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
590   {
591     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
592
593     return ECORE_CALLBACK_PASS_ON;
594   }
595
596   /**
597    * Called when the dragged item is dropped within our window's bounds.
598    * This is when items are dragged INTO our window.
599    */
600   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
601   {
602     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
603
604     return ECORE_CALLBACK_PASS_ON;
605   }
606
607   /**
608    * Called when a dragged item is moved from our window and the target window has done processing it.
609    * This is when items are dragged FROM our window.
610    */
611   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
612   {
613     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
614     return ECORE_CALLBACK_PASS_ON;
615   }
616
617   /**
618    * Called when a dragged item is moved from our window and the target window has sent us a status.
619    * This is when items are dragged FROM our window.
620    */
621   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
622   {
623     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
624     return ECORE_CALLBACK_PASS_ON;
625   }
626
627   /**
628    * Called when the client messages (i.e. the accessibility events) are received.
629    */
630   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
631   {
632     return ECORE_CALLBACK_PASS_ON;
633   }
634
635   /**
636    * Called when the source window notifies us the content in clipboard is selected.
637    */
638   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
639   {
640     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
641     return ECORE_CALLBACK_PASS_ON;
642   }
643
644   /**
645    * Called when the source window sends us about the selected content.
646    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
647    */
648   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
649   {
650     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
651     return ECORE_CALLBACK_PASS_ON;
652   }
653
654   /**
655    * Called when detent event is recevied
656    */
657   static Eina_Bool EcoreEventDetent( void* data, int type, void* event )
658   {
659     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDetent\n" );
660     EventHandler* handler( (EventHandler*)data );
661     Ecore_Event_Detent_Rotate *e((Ecore_Event_Detent_Rotate *)event);
662     int direction = (e->direction == ECORE_DETENT_DIRECTION_CLOCKWISE) ? 1 : -1;
663     int timeStamp = e->timestamp;
664
665     WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), direction, timeStamp );
666     handler->SendWheelEvent( wheelEvent );
667     return ECORE_CALLBACK_PASS_ON;
668   }
669
670   /////////////////////////////////////////////////////////////////////////////////////////////////
671   // Font Callbacks
672   /////////////////////////////////////////////////////////////////////////////////////////////////
673   /**
674    * Called when a font name is changed.
675    */
676   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
677   {
678     EventHandler* handler = static_cast<EventHandler*>( data );
679     handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
680   }
681
682   /**
683    * Called when a font size is changed.
684    */
685   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
686   {
687     EventHandler* handler = static_cast<EventHandler*>( data );
688     handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
689   }
690
691   // Data
692   EventHandler* mHandler;
693   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
694   Ecore_Wl_Window* mWindow;
695 };
696
697 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
698 : mCoreEventInterface(coreEventInterface),
699   mGestureManager( gestureManager ),
700   mStyleMonitor( StyleMonitor::Get() ),
701   mDamageObserver( damageObserver ),
702   mRotationObserver( NULL ),
703   mDragAndDropDetector( dndDetector ),
704   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
705   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
706   mClipboard(Clipboard::Get()),
707   mImpl( NULL )
708 {
709   Ecore_Wl_Window* window = 0;
710
711   // this code only works with the Ecore RenderSurface so need to downcast
712   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
713   if( ecoreSurface )
714   {
715     window = ecoreSurface->GetWlWindow();
716   }
717
718   mImpl = new Impl(this, window);
719 }
720
721 EventHandler::~EventHandler()
722 {
723   if(mImpl)
724   {
725     delete mImpl;
726   }
727
728   mGestureManager.Stop();
729 }
730
731 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)
732 {
733   if(timeStamp < 1)
734   {
735     timeStamp = GetCurrentMilliSeconds();
736   }
737
738   Integration::TouchEvent touchEvent;
739   Integration::HoverEvent hoverEvent;
740   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
741   if(type != Integration::TouchEventCombiner::DispatchNone )
742   {
743     DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.deviceId, point.state, point.local.x, point.local.y);
744
745     // First the touch and/or hover event & related gesture events are queued
746     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
747     {
748       mCoreEventInterface.QueueCoreEvent( touchEvent );
749       mGestureManager.SendEvent(touchEvent);
750     }
751
752     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
753     {
754       mCoreEventInterface.QueueCoreEvent( hoverEvent );
755     }
756
757     // Next the events are processed with a single call into Core
758     mCoreEventInterface.ProcessCoreEvents();
759   }
760 }
761
762 void EventHandler::SendEvent(KeyEvent& keyEvent)
763 {
764   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
765   if ( physicalKeyboard )
766   {
767     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
768     {
769       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
770     }
771   }
772
773   // Create KeyEvent and send to Core.
774   Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
775   keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
776   mCoreEventInterface.QueueCoreEvent( event );
777   mCoreEventInterface.ProcessCoreEvents();
778 }
779
780 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
781 {
782   // Create WheelEvent and send to Core.
783   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
784   mCoreEventInterface.QueueCoreEvent( event );
785   mCoreEventInterface.ProcessCoreEvents();
786 }
787
788 void EventHandler::SendEvent( StyleChange::Type styleChange )
789 {
790   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
791   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
792 }
793
794 void EventHandler::SendEvent( const DamageArea& area )
795 {
796   mDamageObserver.OnDamaged( area );
797 }
798
799 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
800 {
801   if( mRotationObserver != NULL )
802   {
803     mRotationObserver->OnRotationPrepare( event );
804   }
805 }
806
807 void EventHandler::SendRotationRequestEvent( )
808 {
809   if( mRotationObserver != NULL )
810   {
811     mRotationObserver->OnRotationRequest( );
812   }
813 }
814
815 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
816 {
817   Integration::Point convertedPoint( point );
818   SendEvent(convertedPoint, timeStamp);
819 }
820
821 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
822 {
823   SendWheelEvent( wheelEvent );
824 }
825
826 void EventHandler::FeedKeyEvent( KeyEvent& event )
827 {
828   SendEvent( event );
829 }
830
831 void EventHandler::FeedEvent( Integration::Event& event )
832 {
833   mCoreEventInterface.QueueCoreEvent( event );
834   mCoreEventInterface.ProcessCoreEvents();
835 }
836
837 void EventHandler::Reset()
838 {
839   mCombiner.Reset();
840
841   // Any touch listeners should be told of the interruption.
842   Integration::TouchEvent event;
843   Integration::Point point;
844   point.SetState( PointState::INTERRUPTED );
845   event.AddPoint( point );
846
847   // First the touch event & related gesture events are queued
848   mCoreEventInterface.QueueCoreEvent( event );
849   mGestureManager.SendEvent( event );
850
851   // Next the events are processed with a single call into Core
852   mCoreEventInterface.ProcessCoreEvents();
853 }
854
855 void EventHandler::Pause()
856 {
857   mPaused = true;
858   Reset();
859 }
860
861 void EventHandler::Resume()
862 {
863   mPaused = false;
864   Reset();
865 }
866
867 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
868 {
869   mDragAndDropDetector = detector;
870 }
871
872 void EventHandler::SetRotationObserver( RotationObserver* observer )
873 {
874   mRotationObserver = observer;
875 }
876
877 } // namespace Adaptor
878
879 } // namespace Internal
880
881 } // namespace Dali