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