Added Application::New(..., stylesheet)
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / event-handler-x.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_X.h>
25
26 #include <cstring>
27
28 #include <sys/time.h>
29
30 #ifndef DALI_PROFILE_UBUNTU
31 #include <vconf.h>
32 #include <vconf-keys.h>
33 #endif // DALI_PROFILE_UBUNTU
34
35 #include <dali/public-api/common/vector-wrapper.h>
36 #include <dali/public-api/events/touch-point.h>
37 #include <dali/public-api/events/key-event.h>
38 #include <dali/public-api/events/mouse-wheel-event.h>
39 #include <dali/integration-api/debug.h>
40 #include <dali/integration-api/events/key-event-integ.h>
41 #include <dali/integration-api/events/touch-event-integ.h>
42 #include <dali/integration-api/events/hover-event-integ.h>
43 #include <dali/integration-api/events/mouse-wheel-event-integ.h>
44
45 // INTERNAL INCLUDES
46 #include <events/gesture-manager.h>
47 #include <window-render-surface.h>
48 #include <clipboard-impl.h>
49 #include <key-impl.h>
50 #include <physical-keyboard-impl.h>
51 #include <style-monitor-impl.h>
52 #include <base/core-event-interface.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 #ifndef DALI_PROFILE_UBUNTU
78 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced.
79 #endif // DALI_PROFILE_UBUNTU
80
81 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
82
83 #ifndef DALI_PROFILE_UBUNTU
84 const char * CLIPBOARD_ATOM                = "CBHM_MSG";
85 const char * CLIPBOARD_SET_OWNER_MESSAGE   = "SET_OWNER";
86 #endif // DALI_PROFILE_UBUNTU
87
88 /// The atoms required by Ecore for Drag & Drop behaviour.
89 Ecore_X_Atom DRAG_AND_DROP_ATOMS[] =
90 {
91   ECORE_X_ATOM_XDND_ACTION_COPY,
92 };
93
94 /// The types that we support.
95 const char * DRAG_AND_DROP_TYPES[] =
96 {
97   ECORE_X_SELECTION_TARGET_UTF8_STRING,
98 };
99
100 const unsigned int DRAG_AND_DROP_ATOMS_NUMBER = sizeof( DRAG_AND_DROP_ATOMS ) / sizeof( Ecore_X_Atom );
101 const unsigned int DRAG_AND_DROP_TYPES_NUMBER = sizeof( DRAG_AND_DROP_TYPES ) / sizeof( const char * );
102
103 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
104
105 /**
106  * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.
107  * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.
108  * @param[in] ecoreModifier the Ecore_Event_Modifier input.
109  * @return the Ecore_IMF_Keyboard_Modifiers output.
110  */
111 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)
112 {
113    int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.
114
115
116    if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h
117    {
118      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h
119    }
120
121    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
122    {
123      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
124    }
125
126    if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
127    {
128      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
129    }
130
131    if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
132    {
133      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
134    }
135
136    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
137    {
138      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
139    }
140
141    return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
142 }
143
144
145 // Copied from x server
146 static unsigned int GetCurrentMilliSeconds(void)
147 {
148   struct timeval tv;
149
150   struct timespec tp;
151   static clockid_t clockid;
152
153   if (!clockid)
154   {
155 #ifdef CLOCK_MONOTONIC_COARSE
156     if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
157       (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
158     {
159       clockid = CLOCK_MONOTONIC_COARSE;
160     }
161     else
162 #endif
163     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
164     {
165       clockid = CLOCK_MONOTONIC;
166     }
167     else
168     {
169       clockid = ~0L;
170     }
171   }
172   if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
173   {
174     return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
175   }
176
177   gettimeofday(&tv, NULL);
178   return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
179 }
180
181 } // unnamed namespace
182
183 // Impl to hide EFL implementation.
184 struct EventHandler::Impl
185 {
186   // Construction & Destruction
187
188   /**
189    * Constructor
190    */
191   Impl( EventHandler* handler, Ecore_X_Window window )
192   : mHandler( handler ),
193     mEcoreEventHandler(),
194     mWindow( window )
195   {
196     // Only register for touch and key events if we have a window
197     if ( window != 0 )
198     {
199       // Register Touch events
200       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,  EcoreEventMouseButtonDown, handler ) );
201       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,    EcoreEventMouseButtonUp,   handler ) );
202       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,         EcoreEventMouseButtonMove, handler ) );
203       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT,          EcoreEventMouseButtonUp,   handler ) ); // process mouse out event like up event
204
205       // Register Mouse wheel events
206       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,        EcoreEventMouseWheel,      handler ) );
207
208       // Register Key events
209       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
210       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
211
212       // Register Focus events
213       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );
214       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );
215
216       // Register Window damage events
217       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE,    EcoreEventWindowDamaged, handler ) );
218
219       // Enable Drag & Drop and register DnD events
220       ecore_x_dnd_aware_set( window, EINA_TRUE );
221       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_ENTER,       EcoreEventDndEnter,            handler) );
222       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_POSITION,    EcoreEventDndPosition,         handler) );
223       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_LEAVE,       EcoreEventDndLeave,            handler) );
224       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_DROP,        EcoreEventDndDrop,             handler) );
225       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_FINISHED,    EcoreEventDndFinished,         handler) );
226       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_STATUS,      EcoreEventDndStatus,           handler) );
227
228       // Register Client message events - accessibility etc.
229       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, handler ) );
230
231       // Register Selection event - clipboard selection, Drag & Drop selection etc.
232       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) );
233       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) );
234
235 #ifndef DALI_PROFILE_UBUNTU
236       // Register Vconf notify - font name, font size and style
237       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, handler );
238       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
239 #endif // DALI_PROFILE_UBUNTU
240     }
241   }
242
243   /**
244    * Destructor
245    */
246   ~Impl()
247   {
248 #ifndef DALI_PROFILE_UBUNTU
249     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
250     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged );
251 #endif // DALI_PROFILE_UBUNTU
252
253     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
254     {
255       ecore_event_handler_del( *iter );
256     }
257   }
258
259   // Static methods
260
261   /////////////////////////////////////////////////////////////////////////////////////////////////
262   // Touch Callbacks
263   /////////////////////////////////////////////////////////////////////////////////////////////////
264
265   /**
266    * Called when a touch down is received.
267    */
268   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
269   {
270     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
271     EventHandler* handler( (EventHandler*)data );
272
273     if ( touchEvent->window == handler->mImpl->mWindow )
274     {
275       TouchPoint::State state ( TouchPoint::Down );
276
277       // Check if the buttons field is set and ensure it's the primary touch button.
278       // If this event was triggered by buttons other than the primary button (used for touch), then
279       // just send an interrupted event to Core.
280       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
281       {
282         state = TouchPoint::Interrupted;
283       }
284
285       TouchPoint point( touchEvent->multi.device, state, touchEvent->x, touchEvent->y );
286       handler->SendEvent( point, touchEvent->timestamp );
287     }
288
289     return ECORE_CALLBACK_PASS_ON;
290   }
291
292   /**
293    * Called when a touch up is received.
294    */
295   static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
296   {
297     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
298     EventHandler* handler( (EventHandler*)data );
299
300     if ( touchEvent->window == handler->mImpl->mWindow )
301     {
302       TouchPoint point( touchEvent->multi.device, TouchPoint::Up, touchEvent->x, touchEvent->y );
303       handler->SendEvent( point, touchEvent->timestamp );
304     }
305
306     return ECORE_CALLBACK_PASS_ON;
307   }
308
309   /**
310    * Called when a touch up is received.
311    */
312   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
313   {
314     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
315
316     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);
317
318     EventHandler* handler( (EventHandler*)data );
319     if ( mouseWheelEvent->window == handler->mImpl->mWindow )
320     {
321       MouseWheelEvent wheelEvent(mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp);
322       handler->SendMouseWheelEvent( wheelEvent );
323     }
324     return ECORE_CALLBACK_PASS_ON;
325   }
326
327   /**
328    * Called when a touch motion is received.
329    */
330   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
331   {
332     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
333     EventHandler* handler( (EventHandler*)data );
334
335     if ( touchEvent->window == handler->mImpl->mWindow )
336     {
337       TouchPoint point( touchEvent->multi.device, TouchPoint::Motion, touchEvent->x, touchEvent->y );
338       handler->SendEvent( point, touchEvent->timestamp );
339     }
340
341     return ECORE_CALLBACK_PASS_ON;
342   }
343
344   /////////////////////////////////////////////////////////////////////////////////////////////////
345   // Key Callbacks
346   /////////////////////////////////////////////////////////////////////////////////////////////////
347
348   /**
349    * Called when a key down is received.
350    */
351   static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
352   {
353     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
354
355     EventHandler* handler( (EventHandler*)data );
356     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
357     bool eventHandled( false );
358
359     // If a device key then skip ecore_imf_context_filter_event.
360     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
361     {
362       Ecore_IMF_Context* imfContext = NULL;
363       Dali::ImfManager imfManager( ImfManager::Get() );
364       if ( imfManager )
365       {
366         imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
367       }
368
369       if ( imfContext )
370       {
371         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
372         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
373         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
374         ecoreKeyDownEvent.key       = keyEvent->key;
375         ecoreKeyDownEvent.string    = keyEvent->string;
376         ecoreKeyDownEvent.compose   = keyEvent->compose;
377         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
378         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
379         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
380
381         eventHandled = ecore_imf_context_filter_event( imfContext,
382                                                        ECORE_IMF_EVENT_KEY_DOWN,
383                                                        (Ecore_IMF_Event *) &ecoreKeyDownEvent );
384
385         // If the event has not been handled by IMF then check if we should reset our IMF context
386         if( !eventHandled )
387         {
388           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
389                !strcmp( keyEvent->keyname, "Return"   ) ||
390                !strcmp( keyEvent->keyname, "KP_Enter" ) )
391           {
392             ecore_imf_context_reset( imfContext );
393           }
394         }
395       }
396     }
397
398     // If the event wasn't handled then we should send a key event.
399     if ( !eventHandled )
400     {
401       if ( keyEvent->window == handler->mImpl->mWindow )
402       {
403         std::string keyName( keyEvent->keyname );
404         std::string keyString( "" );
405         int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
406         int modifier( keyEvent->modifiers );
407         unsigned long time = keyEvent->timestamp;
408
409         // Ensure key event string is not NULL as keys like SHIFT have a null string.
410         if ( keyEvent->string )
411         {
412           keyString = keyEvent->string;
413         }
414
415         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Down);
416         handler->SendEvent( keyEvent );
417       }
418     }
419
420     return ECORE_CALLBACK_PASS_ON;
421   }
422
423   /**
424    * Called when a key up is received.
425    */
426   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
427   {
428     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp \n" );
429
430     EventHandler* handler( (EventHandler*)data );
431     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
432     bool eventHandled( false );
433
434     // XF86Stop and XF86Send must skip ecore_imf_context_filter_event.
435     if ( strcmp( keyEvent->keyname, "XF86Send"  ) &&
436          strcmp( keyEvent->keyname, "XF86Phone" ) &&
437          strcmp( keyEvent->keyname, "XF86Stop"  ) )
438     {
439       Ecore_IMF_Context* imfContext = NULL;
440       Dali::ImfManager imfManager( ImfManager::Get() );
441       if ( imfManager )
442       {
443         imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
444       }
445
446       if ( imfContext )
447       {
448         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
449         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
450         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
451         ecoreKeyUpEvent.key       = keyEvent->key;
452         ecoreKeyUpEvent.string    = keyEvent->string;
453         ecoreKeyUpEvent.compose   = keyEvent->compose;
454         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
455         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
456         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
457
458         eventHandled = ecore_imf_context_filter_event( imfContext,
459                                                        ECORE_IMF_EVENT_KEY_UP,
460                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
461       }
462     }
463
464     // If the event wasn't handled then we should send a key event.
465     if ( !eventHandled )
466     {
467       if ( keyEvent->window == handler->mImpl->mWindow )
468       {
469         std::string keyName( keyEvent->keyname );
470         std::string keyString( "" );
471         int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
472         int modifier( keyEvent->modifiers );
473         unsigned long time( keyEvent->timestamp );
474
475         // Ensure key event string is not NULL as keys like SHIFT have a null string.
476         if ( keyEvent->string )
477         {
478           keyString = keyEvent->string;
479         }
480
481         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Up);
482         handler->SendEvent( keyEvent );
483
484       }
485     }
486
487     return ECORE_CALLBACK_PASS_ON;
488   }
489
490   /////////////////////////////////////////////////////////////////////////////////////////////////
491   // Window Callbacks
492   /////////////////////////////////////////////////////////////////////////////////////////////////
493
494   /**
495    * Called when the window gains focus.
496    */
497   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
498   {
499     Ecore_X_Event_Window_Focus_In* focusInEvent( (Ecore_X_Event_Window_Focus_In*)event );
500     EventHandler* handler( (EventHandler*)data );
501
502     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
503
504     // If the window gains focus and we hid the keyboard then show it again.
505     if ( focusInEvent->win == handler->mImpl->mWindow )
506     {
507       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
508
509       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
510       {
511         Dali::ImfManager imfManager( ImfManager::Get() );
512         if ( imfManager )
513         {
514           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
515           if( imfManagerImpl.RestoreAfterFocusLost() )
516           {
517             imfManagerImpl.Activate();
518           }
519         }
520       }
521       // No need to connect callbacks as KeyboardStatusChanged will be called.
522     }
523
524     return ECORE_CALLBACK_PASS_ON;
525   }
526
527   /**
528    * Called when the window loses focus.
529    */
530   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
531   {
532     Ecore_X_Event_Window_Focus_Out* focusOutEvent( (Ecore_X_Event_Window_Focus_Out*)event );
533     EventHandler* handler( (EventHandler*)data );
534
535     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
536
537     // If the window loses focus then hide the keyboard.
538     if ( focusOutEvent->win == handler->mImpl->mWindow )
539     {
540       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
541       {
542         Dali::ImfManager imfManager( ImfManager::Get() );
543         if ( imfManager )
544         {
545           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
546           if( imfManagerImpl.RestoreAfterFocusLost() )
547           {
548             imfManagerImpl.Deactivate();
549           }
550         }
551       }
552
553       // Clipboard don't support that whether clipboard is shown or not. Hide clipboard.
554       Dali::Clipboard clipboard = Clipboard::Get();
555       clipboard.HideClipboard();
556     }
557
558     return ECORE_CALLBACK_PASS_ON;
559   }
560
561   /**
562    * Called when the window is damaged.
563    */
564   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
565   {
566     Ecore_X_Event_Window_Damage* windowDamagedEvent( (Ecore_X_Event_Window_Damage*)event );
567     EventHandler* handler( (EventHandler*)data );
568
569     if( windowDamagedEvent->win == handler->mImpl->mWindow )
570     {
571       DamageArea area;
572       area.x = windowDamagedEvent->x;
573       area.y = windowDamagedEvent->y;
574       area.width = windowDamagedEvent->w;
575       area.height = windowDamagedEvent->h;
576
577       handler->SendEvent( area );
578     }
579
580     return ECORE_CALLBACK_PASS_ON;
581   }
582
583   /**
584    * Called when the window properties are changed.
585    * We are only interested in the font change.
586    */
587
588
589   /////////////////////////////////////////////////////////////////////////////////////////////////
590   // Drag & Drop Callbacks
591   /////////////////////////////////////////////////////////////////////////////////////////////////
592
593   /**
594    * Called when a dragged item enters our window's bounds.
595    * This is when items are dragged INTO our window.
596    */
597   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
598   {
599     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
600
601     Ecore_X_Event_Xdnd_Enter* enterEvent( (Ecore_X_Event_Xdnd_Enter*) event );
602     EventHandler* handler( (EventHandler*)data );
603     Ecore_X_Window window ( handler->mImpl->mWindow );
604
605     if ( enterEvent->win == window )
606     {
607       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
608
609       // Check whether the Drag & Drop detector has Drag & Drop behaviour enabled before we accept.
610       if ( dndDetector && dndDetector->IsEnabled() )
611       {
612         // Tell Ecore that we want to enable drop in the entire window.
613         Ecore_X_Rectangle rect;
614         rect.x = rect.y = 0;
615         ecore_x_window_geometry_get( window, NULL, NULL, (int*)&rect.width, (int*)&rect.height );
616
617         // Tell Ecore that we are able to process a drop.
618         ecore_x_dnd_send_status( EINA_TRUE, EINA_FALSE, rect, ECORE_X_ATOM_XDND_DROP );
619
620         // Register the required atoms and types.
621         ecore_x_dnd_actions_set( window, DRAG_AND_DROP_ATOMS, DRAG_AND_DROP_ATOMS_NUMBER );
622         ecore_x_dnd_types_set(   window, DRAG_AND_DROP_TYPES, DRAG_AND_DROP_TYPES_NUMBER );
623
624         // Request to get the content from Ecore.
625         ecore_x_selection_xdnd_request( window, ECORE_X_SELECTION_TARGET_UTF8_STRING );
626
627         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndEnter: Requesting Drag & Drop\n" );
628
629         // Clear the previous content
630         dndDetector->ClearContent();
631
632         // Emit the entered signal
633         dndDetector->EmitEnteredSignal();
634       }
635     }
636
637     return ECORE_CALLBACK_PASS_ON;
638   }
639
640   /**
641    * Called when a dragged item is moved within our window.
642    * This is when items are dragged INTO our window.
643    */
644   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
645   {
646     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
647
648     Ecore_X_Event_Xdnd_Position* positionEvent( (Ecore_X_Event_Xdnd_Position*) event );
649     EventHandler* handler( (EventHandler*)data );
650
651     if ( positionEvent->win == handler->mImpl->mWindow )
652     {
653       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
654
655       // If we have a detector then update its latest position.
656       if ( dndDetector )
657       {
658         DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndPosition: position ( %d x %d )\n", positionEvent->position.x, positionEvent->position.y );
659         dndDetector->SetPosition( Vector2( positionEvent->position.x, positionEvent->position.y ));
660         dndDetector->EmitMovedSignal();
661       }
662     }
663
664     return ECORE_CALLBACK_PASS_ON;
665   }
666
667   /**
668    * Called when a dragged item leaves our window's bounds.
669    * This is when items are dragged INTO our window.
670    */
671   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
672   {
673     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
674
675     Ecore_X_Event_Xdnd_Leave* leaveEvent( (Ecore_X_Event_Xdnd_Leave*) event );
676     EventHandler* handler( (EventHandler*)data );
677
678     if ( leaveEvent->win == handler->mImpl->mWindow )
679     {
680       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
681
682       // If we have a detector then clear its content and emit the exited-signal. Also tell Ecore that we have finished.
683       if ( dndDetector )
684       {
685         dndDetector->ClearContent();
686         dndDetector->EmitExitedSignal();
687
688         ecore_x_dnd_send_finished();
689
690         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndLeave: Finished\n" );
691       }
692     }
693
694     return ECORE_CALLBACK_PASS_ON;
695   }
696
697   /**
698    * Called when the dragged item is dropped within our window's bounds.
699    * This is when items are dragged INTO our window.
700    */
701   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
702   {
703     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
704
705     Ecore_X_Event_Xdnd_Drop* dropEvent ( (Ecore_X_Event_Xdnd_Drop*) event);
706     EventHandler* handler( (EventHandler*)data );
707
708     if ( dropEvent->win == handler->mImpl->mWindow )
709     {
710       DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
711
712       // Something has been dropped, inform the detector (if we have one) and tell Ecore that we have finished.
713       if ( dndDetector )
714       {
715         DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: position ( %d x %d )\n", dropEvent->position.x, dropEvent->position.y );
716
717         dndDetector->SetPosition( Vector2( dropEvent->position.x, dropEvent->position.y ) );
718         dndDetector->EmitDroppedSignal();
719         ecore_x_dnd_send_finished();
720
721         DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: Finished\n" );
722       }
723     }
724
725     return ECORE_CALLBACK_PASS_ON;
726   }
727
728   /**
729    * Called when a dragged item is moved from our window and the target window has done processing it.
730    * This is when items are dragged FROM our window.
731    */
732   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
733   {
734     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
735     return ECORE_CALLBACK_PASS_ON;
736   }
737
738   /**
739    * Called when a dragged item is moved from our window and the target window has sent us a status.
740    * This is when items are dragged FROM our window.
741    */
742   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
743   {
744     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
745     return ECORE_CALLBACK_PASS_ON;
746   }
747
748   /**
749    * Called when the client messages (i.e. the accessibility events) are received.
750    */
751   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
752   {
753 #ifndef DALI_PROFILE_UBUNTU
754     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
755     EventHandler* handler( (EventHandler*)data );
756
757     if (clientMessageEvent->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
758     {
759       if ( ( (unsigned int)clientMessageEvent->data.l[0] == handler->mImpl->mWindow ) && handler->mAccessibilityManager )
760       {
761         AccessibilityManager* accessibilityManager( &AccessibilityManager::GetImplementation( handler->mAccessibilityManager ) );
762
763         if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL)
764         {
765           // 2 finger touch & move, 2 finger flick
766
767           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
768           // x : e->data.l[3]
769           // y : e->data.l[4]
770           TouchPoint::State state(TouchPoint::Down);
771
772           if ((unsigned int)clientMessageEvent->data.l[2] == 0)
773           {
774             state = TouchPoint::Down; // mouse down
775           }
776           else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
777           {
778             state = TouchPoint::Motion; // mouse move
779           }
780           else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
781           {
782             state = TouchPoint::Up; // mouse up
783           }
784           else
785           {
786             state = TouchPoint::Interrupted; // error
787           }
788
789           DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
790             "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
791             (unsigned int)clientMessageEvent->data.l[2],
792             (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
793
794           // Send touch event to accessibility manager.
795           TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
796
797           // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
798           accessibilityManager->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
799         }
800         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE)
801         {
802           // 1 finger double tap and hold
803
804           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
805           // x : e->data.l[3]
806           // y : e->data.l[4]
807           TouchPoint::State state(TouchPoint::Down);
808
809           if ((unsigned int)clientMessageEvent->data.l[2] == 0)
810           {
811             state = TouchPoint::Down; // mouse down
812           }
813           else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
814           {
815             state = TouchPoint::Motion; // mouse move
816           }
817           else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
818           {
819             state = TouchPoint::Up; // mouse up
820           }
821           else
822           {
823             state = TouchPoint::Interrupted; // error
824           }
825
826           DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
827             "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
828             (unsigned int)clientMessageEvent->data.l[2],
829             (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
830
831           // Send touch event to accessibility manager.
832           TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
833
834           // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
835           accessibilityManager->HandleActionTouchEvent( point, GetCurrentMilliSeconds() );
836         }
837         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK)
838         {
839           // 2 finger circle draw, do back
840           accessibilityManager->HandleActionBackEvent();
841         }
842         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
843         {
844           // one finger flick down
845           // focus next object
846           if(accessibilityManager)
847           {
848             accessibilityManager->HandleActionNextEvent();
849           }
850         }
851         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
852         {
853           // one finger flick up
854           // focus previous object
855           if(accessibilityManager)
856           {
857             accessibilityManager->HandleActionPreviousEvent();
858           }
859         }
860         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
861         {
862           // one finger double tap
863           // same as one finger tap in normal mode (i.e. execute focused actor)
864           if(accessibilityManager)
865           {
866             accessibilityManager->HandleActionActivateEvent();
867           }
868         }
869         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
870         {
871           // one finger tap
872           // focus & read an actor at ( e->data.l[2], e->data.l[3] ) position according to finger
873           if(accessibilityManager)
874           {
875             accessibilityManager->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[2], (unsigned int)clientMessageEvent->data.l[3], true /* allow read again*/);
876           }
877         }
878 #if defined(DALI_PROFILE_MOBILE)
879         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER)
880         {
881           // one finger tap & move
882           // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
883           // x : e->data.l[3]
884           // y : e->data.l[4]
885           // focus & read an actor at (x, y) position according to finger
886           if(accessibilityManager && (unsigned int)clientMessageEvent->data.l[2] == 1 /*only work for move event*/)
887           {
888             accessibilityManager->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4], false /* not allow read again*/);
889           }
890         }
891 #endif
892         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
893         {
894           // one finger flick right
895           // focus next object
896            if(accessibilityManager)
897           {
898             accessibilityManager->HandleActionReadNextEvent();
899           }
900         }
901         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
902         {
903           // one finger flick left
904           // focus previous object
905           if(accessibilityManager)
906           {
907             accessibilityManager->HandleActionReadPreviousEvent();
908           }
909         }
910         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
911         {
912           // double down and move (right, up)
913           // change slider value
914           if(accessibilityManager)
915           {
916             accessibilityManager->HandleActionUpEvent();
917           }
918         }
919         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
920         {
921           // double down and move (left, down)
922           // change slider value
923           if(accessibilityManager)
924           {
925             accessibilityManager->HandleActionDownEvent();
926           }
927         }
928         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE)
929         {
930            if(accessibilityManager)
931           {
932             accessibilityManager->HandleActionEnableEvent();
933           }
934         }
935         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE)
936         {
937           if(accessibilityManager)
938           {
939             accessibilityManager->HandleActionDisableEvent();
940           }
941         }
942         // TODO: some more actions could be added later
943       }
944     }
945     else if(clientMessageEvent->message_type == ecore_x_atom_get(CLIPBOARD_ATOM))
946     {
947       std::string message(clientMessageEvent->data.b);
948       if( message == CLIPBOARD_SET_OWNER_MESSAGE)
949       {
950         // Claim the ownership of the SECONDARY selection.
951         ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
952
953         // Show the clipboard window
954         Dali::Clipboard clipboard = Dali::Clipboard::Get();
955         clipboard.ShowClipboard();
956       }
957     }
958     else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE )
959     {
960       RotationEvent rotationEvent;
961       rotationEvent.angle      = static_cast<int>(clientMessageEvent->data.l[1]);
962       rotationEvent.winResize  = static_cast<int>(clientMessageEvent->data.l[2]);
963       rotationEvent.width      = static_cast<int>(clientMessageEvent->data.l[3]);
964       rotationEvent.height     = static_cast<int>(clientMessageEvent->data.l[4]);
965       handler->SendRotationPrepareEvent( rotationEvent );
966     }
967     else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST )
968     {
969       handler->SendRotationRequestEvent();
970     }
971
972 #endif // DALI_PROFILE_UBUNTU
973     return ECORE_CALLBACK_PASS_ON;
974   }
975
976   /**
977    * Called when the source window notifies us the content in clipboard is selected.
978    */
979   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
980   {
981     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
982     Ecore_X_Event_Selection_Clear* selectionClearEvent( (Ecore_X_Event_Selection_Clear*) event );
983     EventHandler* handler( (EventHandler*)data );
984
985     if ( selectionClearEvent->win == handler->mImpl->mWindow )
986     {
987       if ( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY )
988       {
989         // Request to get the content from Ecore.
990         ecore_x_selection_secondary_request(selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT);
991       }
992     }
993     return ECORE_CALLBACK_PASS_ON;
994   }
995
996   /**
997    * Called when the source window sends us about the selected content.
998    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
999    */
1000   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
1001   {
1002     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
1003
1004     Ecore_X_Event_Selection_Notify* selectionNotifyEvent( (Ecore_X_Event_Selection_Notify*) event );
1005     EventHandler* handler( (EventHandler*)data );
1006
1007     if ( selectionNotifyEvent->win == handler->mImpl->mWindow )
1008     {
1009       Ecore_X_Selection_Data* selectionData( (Ecore_X_Selection_Data*) selectionNotifyEvent->data );
1010       if ( selectionData->data )
1011       {
1012         if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_XDND )
1013         {
1014           DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
1015
1016           // We have got the content that is to be dropped, inform the DndListener (if we have one).
1017           if ( dndDetector )
1018           {
1019             std::string content( (char*) selectionData->data, selectionData->length );
1020             dndDetector->SetContent( content );
1021
1022             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1023             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1024             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1025             DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1026           }
1027         }
1028         else if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY )
1029         {
1030           // We have got the selected content, inform the clipboard event listener (if we have one).
1031           if ( handler->mClipboardEventNotifier )
1032           {
1033             ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) );
1034             std::string content( (char*) selectionData->data, selectionData->length );
1035             clipboardEventNotifier.SetContent( content );
1036             clipboardEventNotifier.EmitContentSelectedSignal();
1037           }
1038
1039           // Claim the ownership of the SECONDARY selection.
1040           ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
1041
1042           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1043           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1044           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1045           DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1046         }
1047       }
1048     }
1049     return ECORE_CALLBACK_PASS_ON;
1050   }
1051
1052
1053 #ifndef DALI_PROFILE_UBUNTU
1054   /////////////////////////////////////////////////////////////////////////////////////////////////
1055   // Font Callbacks
1056   /////////////////////////////////////////////////////////////////////////////////////////////////
1057   /**
1058    * Called when a font name is changed.
1059    */
1060   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
1061   {
1062     EventHandler* handler = static_cast<EventHandler*>( data );
1063
1064     StyleChange fontChange;
1065     fontChange.defaultFontChange = true;
1066
1067     handler->SendEvent( fontChange );
1068   }
1069
1070   /**
1071    * Called when a font size is changed.
1072    */
1073   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
1074   {
1075     EventHandler* handler = static_cast<EventHandler*>( data );
1076
1077     StyleChange fontChange;
1078     fontChange.defaultFontSizeChange = true;
1079
1080     handler->SendEvent( fontChange );
1081   }
1082 #endif // DALI_PROFILE_UBUNTU
1083
1084   // Data
1085   EventHandler* mHandler;
1086   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
1087   Ecore_X_Window mWindow;
1088 };
1089
1090 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
1091 : mCoreEventInterface(coreEventInterface),
1092   mGestureManager( gestureManager ),
1093   mStyleMonitor( StyleMonitor::Get() ),
1094   mDamageObserver( damageObserver ),
1095   mRotationObserver( NULL ),
1096   mDragAndDropDetector( dndDetector ),
1097   mAccessibilityManager( AccessibilityManager::Get() ),
1098   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
1099   mClipboard(Clipboard::Get()),
1100   mImpl( NULL )
1101 {
1102   Ecore_X_Window window = 0;
1103
1104   // this code only works with the EcoreX11 RenderSurface so need to downcast
1105   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
1106   if( ecoreSurface )
1107   {
1108     // enable multi touch
1109     window = ecoreSurface->GetXWindow();
1110   }
1111
1112   mImpl = new Impl(this, window);
1113 }
1114
1115 EventHandler::~EventHandler()
1116 {
1117   if(mImpl)
1118   {
1119     delete mImpl;
1120   }
1121
1122   mGestureManager.Stop();
1123 }
1124
1125 void EventHandler::SendEvent(TouchPoint& point, unsigned long timeStamp)
1126 {
1127   if(timeStamp < 1)
1128   {
1129     timeStamp = GetCurrentMilliSeconds();
1130   }
1131
1132   Integration::TouchEvent touchEvent;
1133   Integration::HoverEvent hoverEvent;
1134   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
1135   if(type != Integration::TouchEventCombiner::DispatchNone )
1136   {
1137     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);
1138
1139     // First the touch and/or hover event & related gesture events are queued
1140     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
1141     {
1142       mCoreEventInterface.QueueCoreEvent( touchEvent );
1143       mGestureManager.SendEvent(touchEvent);
1144     }
1145
1146     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
1147     {
1148       mCoreEventInterface.QueueCoreEvent( hoverEvent );
1149     }
1150
1151     // Next the events are processed with a single call into Core
1152     mCoreEventInterface.ProcessCoreEvents();
1153   }
1154 }
1155
1156 void EventHandler::SendEvent(KeyEvent& keyEvent)
1157 {
1158   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
1159   if ( physicalKeyboard )
1160   {
1161     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
1162     {
1163       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
1164     }
1165   }
1166
1167   // Create KeyEvent and send to Core.
1168   Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
1169   keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
1170   mCoreEventInterface.QueueCoreEvent( event );
1171   mCoreEventInterface.ProcessCoreEvents();
1172 }
1173
1174 void EventHandler::SendMouseWheelEvent( MouseWheelEvent& wheelEvent )
1175 {
1176   // Create MouseWheelEvent and send to Core.
1177   Integration::MouseWheelEvent event(wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp);
1178   mCoreEventInterface.QueueCoreEvent( event );
1179   mCoreEventInterface.ProcessCoreEvents();
1180 }
1181
1182 void EventHandler::SendEvent(StyleChange styleChange)
1183 {
1184   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
1185   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
1186 }
1187
1188 void EventHandler::SendEvent( const DamageArea& area )
1189 {
1190   mDamageObserver.OnDamaged( area );
1191 }
1192
1193 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
1194 {
1195   if( mRotationObserver != NULL )
1196   {
1197     mRotationObserver->OnRotationPrepare( event );
1198   }
1199 }
1200
1201 void EventHandler::SendRotationRequestEvent( )
1202 {
1203   if( mRotationObserver != NULL )
1204   {
1205     mRotationObserver->OnRotationRequest( );
1206   }
1207 }
1208
1209 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
1210 {
1211   SendEvent(point, timeStamp);
1212 }
1213
1214 void EventHandler::FeedWheelEvent( MouseWheelEvent& wheelEvent )
1215 {
1216   SendMouseWheelEvent( wheelEvent );
1217 }
1218
1219 void EventHandler::FeedKeyEvent( KeyEvent& event )
1220 {
1221   SendEvent( event );
1222 }
1223
1224 void EventHandler::FeedEvent( Integration::Event& event )
1225 {
1226   mCoreEventInterface.QueueCoreEvent( event );
1227   mCoreEventInterface.ProcessCoreEvents();
1228 }
1229
1230 void EventHandler::Reset()
1231 {
1232   mCombiner.Reset();
1233
1234   // Any touch listeners should be told of the interruption.
1235   Integration::TouchEvent event;
1236   TouchPoint point(0, TouchPoint::Interrupted, 0, 0);
1237   event.AddPoint( point );
1238
1239   // First the touch event & related gesture events are queued
1240   mCoreEventInterface.QueueCoreEvent( event );
1241   mGestureManager.SendEvent( event );
1242
1243   // Next the events are processed with a single call into Core
1244   mCoreEventInterface.ProcessCoreEvents();
1245 }
1246
1247 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
1248 {
1249   mDragAndDropDetector = detector;
1250 }
1251
1252 void EventHandler::SetRotationObserver( RotationObserver* observer )
1253 {
1254   mRotationObserver = observer;
1255 }
1256
1257 } // namespace Adaptor
1258
1259 } // namespace Internal
1260
1261 } // namespace Dali