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