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