Merge "[3.0] Tizen Directory Migration" into tizen
[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 Key events
189       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
190       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
191
192 #ifndef DALI_PROFILE_UBUNTU
193       // Register Vconf notify - font name and size
194       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged, handler );
195       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
196 #endif // DALI_PROFILE_UBUNTU
197     }
198   }
199
200   /**
201    * Destructor
202    */
203   ~Impl()
204   {
205 #ifndef DALI_PROFILE_UBUNTU
206     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
207     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged );
208 #endif // DALI_PROFILE_UBUNTU
209
210     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
211     {
212       ecore_event_handler_del( *iter );
213     }
214   }
215
216   // Static methods
217
218   /////////////////////////////////////////////////////////////////////////////////////////////////
219   // Touch Callbacks
220   /////////////////////////////////////////////////////////////////////////////////////////////////
221
222   /**
223    * Called when a touch down is received.
224    */
225   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
226   {
227     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
228     EventHandler* handler( (EventHandler*)data );
229
230     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
231     {
232       PointState::Type state ( PointState::DOWN );
233
234       // Check if the buttons field is set and ensure it's the primary touch button.
235       // If this event was triggered by buttons other than the primary button (used for touch), then
236       // just send an interrupted event to Core.
237       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
238       {
239         state = PointState::INTERRUPTED;
240       }
241
242       Integration::Point point;
243       point.SetDeviceId( touchEvent->multi.device );
244       point.SetState( state );
245       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
246       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
247       point.SetPressure( touchEvent->multi.pressure );
248       point.SetAngle( Degree( touchEvent->multi.angle ) );
249       handler->SendEvent( point, touchEvent->timestamp );
250     }
251
252     return ECORE_CALLBACK_PASS_ON;
253   }
254
255   /**
256    * Called when a touch up is received.
257    */
258   static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
259   {
260     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
261     EventHandler* handler( (EventHandler*)data );
262
263     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
264     {
265       Integration::Point point;
266       point.SetDeviceId( touchEvent->multi.device );
267       point.SetState( PointState::UP );
268       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
269       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
270       point.SetPressure( touchEvent->multi.pressure );
271       point.SetAngle( Degree( touchEvent->multi.angle ) );
272       handler->SendEvent( point, touchEvent->timestamp );
273     }
274
275     return ECORE_CALLBACK_PASS_ON;
276   }
277
278   /**
279    * Called when a touch up is received.
280    */
281   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
282   {
283     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
284
285     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);
286
287     EventHandler* handler( (EventHandler*)data );
288     if ( mouseWheelEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
289     {
290       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
291       handler->SendWheelEvent( wheelEvent );
292     }
293     return ECORE_CALLBACK_PASS_ON;
294   }
295
296   /**
297    * Called when a touch motion is received.
298    */
299   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
300   {
301     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
302     EventHandler* handler( (EventHandler*)data );
303
304     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
305     {
306       Integration::Point point;
307       point.SetDeviceId( touchEvent->multi.device );
308       point.SetState( PointState::MOTION );
309       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
310       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
311       point.SetPressure( touchEvent->multi.pressure );
312       point.SetAngle( Degree( touchEvent->multi.angle ) );
313       handler->SendEvent( point, touchEvent->timestamp );
314     }
315
316     return ECORE_CALLBACK_PASS_ON;
317   }
318
319   /////////////////////////////////////////////////////////////////////////////////////////////////
320   // Key Callbacks
321   /////////////////////////////////////////////////////////////////////////////////////////////////
322
323   /**
324    * Called when a key down is received.
325    */
326   static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
327   {
328     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
329
330     EventHandler* handler( (EventHandler*)data );
331     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
332     bool eventHandled( false );
333
334     // If a device key then skip ecore_imf_context_filter_event.
335     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
336     {
337       Ecore_IMF_Context* imfContext = NULL;
338       Dali::ImfManager imfManager( ImfManager::Get() );
339       if ( imfManager )
340       {
341         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
342       }
343
344       if ( imfContext )
345       {
346         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
347         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
348         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
349         ecoreKeyDownEvent.key       = keyEvent->key;
350         ecoreKeyDownEvent.string    = keyEvent->string;
351         ecoreKeyDownEvent.compose   = keyEvent->compose;
352         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
353         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
354         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
355
356         eventHandled = ecore_imf_context_filter_event( imfContext,
357                                                        ECORE_IMF_EVENT_KEY_DOWN,
358                                                        (Ecore_IMF_Event *) &ecoreKeyDownEvent );
359
360         // If the event has not been handled by IMF then check if we should reset our IMF context
361         if( !eventHandled )
362         {
363           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
364                !strcmp( keyEvent->keyname, "Return"   ) ||
365                !strcmp( keyEvent->keyname, "KP_Enter" ) )
366           {
367             ecore_imf_context_reset( imfContext );
368           }
369         }
370       }
371     }
372
373     // If the event wasn't handled then we should send a key event.
374     if ( !eventHandled )
375     {
376       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
377       {
378         std::string keyName( keyEvent->keyname );
379         std::string keyString( "" );
380         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
381         keyCode = (keyCode == -1) ? 0 : keyCode;
382         int modifier( keyEvent->modifiers );
383         unsigned long time = keyEvent->timestamp;
384         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
385           keyCode = atoi(keyEvent->keyname + 8);
386
387         // Ensure key event string is not NULL as keys like SHIFT have a null string.
388         if ( keyEvent->string )
389         {
390           keyString = keyEvent->string;
391         }
392
393         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Down);
394         handler->SendEvent( keyEvent );
395       }
396     }
397
398     return ECORE_CALLBACK_PASS_ON;
399   }
400
401   /**
402    * Called when a key up is received.
403    */
404   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
405   {
406     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp\n" );
407
408     EventHandler* handler( (EventHandler*)data );
409     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
410     bool eventHandled( false );
411
412     // Device keys like Menu, home, back button must skip ecore_imf_context_filter_event.
413     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
414     {
415       Ecore_IMF_Context* imfContext = NULL;
416       Dali::ImfManager imfManager( ImfManager::Get() );
417       if ( imfManager )
418       {
419         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
420       }
421
422       if ( imfContext )
423       {
424         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
425         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
426         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
427         ecoreKeyUpEvent.key       = keyEvent->key;
428         ecoreKeyUpEvent.string    = keyEvent->string;
429         ecoreKeyUpEvent.compose   = keyEvent->compose;
430         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
431         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
432         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
433
434         eventHandled = ecore_imf_context_filter_event( imfContext,
435                                                        ECORE_IMF_EVENT_KEY_UP,
436                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
437       }
438     }
439
440     // If the event wasn't handled then we should send a key event.
441     if ( !eventHandled )
442     {
443       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
444       {
445         std::string keyName( keyEvent->keyname );
446         std::string keyString( "" );
447         int keyCode = 0/*ecore_x_keysym_keycode_get(keyEvent->keyname)*/;
448         int modifier( keyEvent->modifiers );
449         unsigned long time( keyEvent->timestamp );
450
451         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
452           keyCode = atoi(keyEvent->keyname + 8);
453
454         // Ensure key event string is not NULL as keys like SHIFT have a null string.
455         if ( keyEvent->string )
456         {
457           keyString = keyEvent->string;
458         }
459
460         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Up);
461         handler->SendEvent( keyEvent );
462       }
463     }
464
465     return ECORE_CALLBACK_PASS_ON;
466   }
467
468   /////////////////////////////////////////////////////////////////////////////////////////////////
469   // Window Callbacks
470   /////////////////////////////////////////////////////////////////////////////////////////////////
471
472   /**
473    * Called when the window gains focus.
474    */
475   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
476   {
477     Ecore_Wl_Event_Focus_In* focusInEvent( (Ecore_Wl_Event_Focus_In*)event );
478     EventHandler* handler( (EventHandler*)data );
479
480     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
481
482     // If the window gains focus and we hid the keyboard then show it again.
483     if ( focusInEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
484     {
485       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
486
487       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
488       {
489         Dali::ImfManager imfManager( ImfManager::Get() );
490         if ( imfManager )
491         {
492           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
493           if( imfManagerImpl.RestoreAfterFocusLost() )
494           {
495             imfManagerImpl.Activate();
496           }
497         }
498       }
499       // No need to connect callbacks as KeyboardStatusChanged will be called.
500     }
501
502     return ECORE_CALLBACK_PASS_ON;
503   }
504
505   /**
506    * Called when the window loses focus.
507    */
508   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
509   {
510     Ecore_Wl_Event_Focus_Out* focusOutEvent( (Ecore_Wl_Event_Focus_Out*)event );
511     EventHandler* handler( (EventHandler*)data );
512
513     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
514
515     // If the window loses focus then hide the keyboard.
516     if ( focusOutEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
517     {
518       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
519       {
520         Dali::ImfManager imfManager( ImfManager::Get() );
521         if ( imfManager )
522         {
523           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
524           if( imfManagerImpl.RestoreAfterFocusLost() )
525           {
526             imfManagerImpl.Deactivate();
527           }
528         }
529       }
530
531       // Clipboard don't support that whether clipboard is shown or not. Hide clipboard.
532       Dali::Clipboard clipboard = Clipboard::Get();
533       clipboard.HideClipboard();
534     }
535
536     return ECORE_CALLBACK_PASS_ON;
537   }
538
539   /**
540    * Called when the window is damaged.
541    */
542   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
543   {
544     return ECORE_CALLBACK_PASS_ON;
545   }
546
547   /**
548    * Called when the window properties are changed.
549    * We are only interested in the font change.
550    */
551
552
553   /////////////////////////////////////////////////////////////////////////////////////////////////
554   // Drag & Drop Callbacks
555   /////////////////////////////////////////////////////////////////////////////////////////////////
556
557   /**
558    * Called when a dragged item enters our window's bounds.
559    * This is when items are dragged INTO our window.
560    */
561   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
562   {
563     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
564
565     return ECORE_CALLBACK_PASS_ON;
566   }
567
568   /**
569    * Called when a dragged item is moved within our window.
570    * This is when items are dragged INTO our window.
571    */
572   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
573   {
574     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
575
576     return ECORE_CALLBACK_PASS_ON;
577   }
578
579   /**
580    * Called when a dragged item leaves our window's bounds.
581    * This is when items are dragged INTO our window.
582    */
583   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
584   {
585     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
586
587     return ECORE_CALLBACK_PASS_ON;
588   }
589
590   /**
591    * Called when the dragged item is dropped within our window's bounds.
592    * This is when items are dragged INTO our window.
593    */
594   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
595   {
596     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
597
598     return ECORE_CALLBACK_PASS_ON;
599   }
600
601   /**
602    * Called when a dragged item is moved from our window and the target window has done processing it.
603    * This is when items are dragged FROM our window.
604    */
605   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
606   {
607     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
608     return ECORE_CALLBACK_PASS_ON;
609   }
610
611   /**
612    * Called when a dragged item is moved from our window and the target window has sent us a status.
613    * This is when items are dragged FROM our window.
614    */
615   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
616   {
617     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
618     return ECORE_CALLBACK_PASS_ON;
619   }
620
621   /**
622    * Called when the client messages (i.e. the accessibility events) are received.
623    */
624   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
625   {
626     return ECORE_CALLBACK_PASS_ON;
627   }
628
629   /**
630    * Called when the source window notifies us the content in clipboard is selected.
631    */
632   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
633   {
634     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
635     return ECORE_CALLBACK_PASS_ON;
636   }
637
638   /**
639    * Called when the source window sends us about the selected content.
640    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
641    */
642   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
643   {
644     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
645     return ECORE_CALLBACK_PASS_ON;
646   }
647
648   /////////////////////////////////////////////////////////////////////////////////////////////////
649   // Font Callbacks
650   /////////////////////////////////////////////////////////////////////////////////////////////////
651   /**
652    * Called when a font name is changed.
653    */
654   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
655   {
656     EventHandler* handler = static_cast<EventHandler*>( data );
657     handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
658   }
659
660   /**
661    * Called when a font size is changed.
662    */
663   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
664   {
665     EventHandler* handler = static_cast<EventHandler*>( data );
666     handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
667   }
668
669   void KeyboardVisibilityOnPause()
670   {
671     mKeyboardVisibilityOnPause = VirtualKeyboard::IsVisible() ? 1 : 0;
672   }
673
674   void KeyboardVisibilityOnResume()
675   {
676     if (mKeyboardVisibilityOnPause)
677     {
678       VirtualKeyboard::Show();
679     }
680   }
681
682   // Data
683   EventHandler* mHandler;
684   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
685   Ecore_Wl_Window* mWindow;
686   bool mKeyboardVisibilityOnPause;
687 };
688
689 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
690 : mCoreEventInterface(coreEventInterface),
691   mGestureManager( gestureManager ),
692   mStyleMonitor( StyleMonitor::Get() ),
693   mDamageObserver( damageObserver ),
694   mRotationObserver( NULL ),
695   mDragAndDropDetector( dndDetector ),
696   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
697   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
698   mClipboard(Clipboard::Get()),
699   mImpl( NULL )
700 {
701   Ecore_Wl_Window* window = 0;
702
703   // this code only works with the Ecore RenderSurface so need to downcast
704   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
705   if( ecoreSurface )
706   {
707     window = ecoreSurface->GetWlWindow();
708   }
709
710   mImpl = new Impl(this, window);
711 }
712
713 EventHandler::~EventHandler()
714 {
715   if(mImpl)
716   {
717     delete mImpl;
718   }
719
720   mGestureManager.Stop();
721 }
722
723 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)
724 {
725   if(timeStamp < 1)
726   {
727     timeStamp = GetCurrentMilliSeconds();
728   }
729
730   Integration::TouchEvent touchEvent;
731   Integration::HoverEvent hoverEvent;
732   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
733   if(type != Integration::TouchEventCombiner::DispatchNone )
734   {
735     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);
736
737     // First the touch and/or hover event & related gesture events are queued
738     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
739     {
740       mCoreEventInterface.QueueCoreEvent( touchEvent );
741       mGestureManager.SendEvent(touchEvent);
742     }
743
744     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
745     {
746       mCoreEventInterface.QueueCoreEvent( hoverEvent );
747     }
748
749     // Next the events are processed with a single call into Core
750     mCoreEventInterface.ProcessCoreEvents();
751   }
752 }
753
754 void EventHandler::SendEvent(KeyEvent& keyEvent)
755 {
756   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
757   if ( physicalKeyboard )
758   {
759     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
760     {
761       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
762     }
763   }
764
765   // Create KeyEvent and send to Core.
766   Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
767   keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
768   mCoreEventInterface.QueueCoreEvent( event );
769   mCoreEventInterface.ProcessCoreEvents();
770 }
771
772 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
773 {
774   // Create WheelEvent and send to Core.
775   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
776   mCoreEventInterface.QueueCoreEvent( event );
777   mCoreEventInterface.ProcessCoreEvents();
778 }
779
780 void EventHandler::SendEvent( StyleChange::Type styleChange )
781 {
782   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
783   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
784 }
785
786 void EventHandler::SendEvent( const DamageArea& area )
787 {
788   mDamageObserver.OnDamaged( area );
789 }
790
791 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
792 {
793   if( mRotationObserver != NULL )
794   {
795     mRotationObserver->OnRotationPrepare( event );
796   }
797 }
798
799 void EventHandler::SendRotationRequestEvent( )
800 {
801   if( mRotationObserver != NULL )
802   {
803     mRotationObserver->OnRotationRequest( );
804   }
805 }
806
807 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
808 {
809   Integration::Point convertedPoint( point );
810   SendEvent(convertedPoint, timeStamp);
811 }
812
813 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
814 {
815   SendWheelEvent( wheelEvent );
816 }
817
818 void EventHandler::FeedKeyEvent( KeyEvent& event )
819 {
820   SendEvent( event );
821 }
822
823 void EventHandler::FeedEvent( Integration::Event& event )
824 {
825   mCoreEventInterface.QueueCoreEvent( event );
826   mCoreEventInterface.ProcessCoreEvents();
827 }
828
829 void EventHandler::Reset()
830 {
831   mCombiner.Reset();
832
833   // Any touch listeners should be told of the interruption.
834   Integration::TouchEvent event;
835   Integration::Point point;
836   point.SetState( PointState::INTERRUPTED );
837   event.AddPoint( point );
838
839   // First the touch event & related gesture events are queued
840   mCoreEventInterface.QueueCoreEvent( event );
841   mGestureManager.SendEvent( event );
842
843   // Next the events are processed with a single call into Core
844   mCoreEventInterface.ProcessCoreEvents();
845 }
846
847 void EventHandler::Pause()
848 {
849   mPaused = true;
850   Reset();
851   mImpl->KeyboardVisibilityOnPause();
852 }
853
854 void EventHandler::Resume()
855 {
856   mPaused = false;
857   Reset();
858   mImpl->KeyboardVisibilityOnResume();
859 }
860
861 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
862 {
863   mDragAndDropDetector = detector;
864 }
865
866 void EventHandler::SetRotationObserver( RotationObserver* observer )
867 {
868   mRotationObserver = observer;
869 }
870
871 } // namespace Adaptor
872
873 } // namespace Internal
874
875 } // namespace Dali