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