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