Implement wayland clipboard
[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 #include <virtual-keyboard.h>
53
54 namespace Dali
55 {
56
57 namespace Internal
58 {
59
60 namespace Adaptor
61 {
62
63 #if defined(DEBUG_ENABLED)
64 namespace
65 {
66 Integration::Log::Filter* gTouchEventLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");
67 Integration::Log::Filter* gClientMessageLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_CLIENT_MESSAGE");
68 Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND");
69 Integration::Log::Filter* gImfLogging  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF");
70 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");
71 } // unnamed namespace
72 #endif
73
74
75 namespace
76 {
77 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 Focus events
189       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );
190       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );
191
192       // Register Key events
193       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );
194       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );
195
196       // Register Selection event - clipboard selection
197       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_DATA_SOURCE_SEND, EcoreEventDataSend, handler ) );
198       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WL_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, handler ) );
199
200       // Register Detent event
201       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_DETENT_ROTATE, EcoreEventDetent, handler) );
202
203 #ifndef DALI_PROFILE_UBUNTU
204       // Register Vconf notify - font name and size
205       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged, handler );
206       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
207 #endif // DALI_PROFILE_UBUNTU
208     }
209   }
210
211   /**
212    * Destructor
213    */
214   ~Impl()
215   {
216 #ifndef DALI_PROFILE_UBUNTU
217     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
218     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontNameChanged );
219 #endif // DALI_PROFILE_UBUNTU
220
221     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
222     {
223       ecore_event_handler_del( *iter );
224     }
225   }
226
227   // Static methods
228
229   /////////////////////////////////////////////////////////////////////////////////////////////////
230   // Touch Callbacks
231   /////////////////////////////////////////////////////////////////////////////////////////////////
232
233   /**
234    * Called when a touch down is received.
235    */
236   static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
237   {
238     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
239     EventHandler* handler( (EventHandler*)data );
240
241     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
242     {
243       PointState::Type state ( PointState::DOWN );
244
245       // Check if the buttons field is set and ensure it's the primary touch button.
246       // If this event was triggered by buttons other than the primary button (used for touch), then
247       // just send an interrupted event to Core.
248       if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
249       {
250         state = PointState::INTERRUPTED;
251       }
252
253       Integration::Point point;
254       point.SetDeviceId( touchEvent->multi.device );
255       point.SetState( state );
256       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
257       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
258       point.SetPressure( touchEvent->multi.pressure );
259       point.SetAngle( Degree( touchEvent->multi.angle ) );
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 EcoreEventMouseButtonUp( void* data, int type, void* event )
270   {
271     Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
272     EventHandler* handler( (EventHandler*)data );
273
274     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
275     {
276       Integration::Point point;
277       point.SetDeviceId( touchEvent->multi.device );
278       point.SetState( PointState::UP );
279       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
280       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
281       point.SetPressure( touchEvent->multi.pressure );
282       point.SetAngle( Degree( touchEvent->multi.angle ) );
283       handler->SendEvent( point, touchEvent->timestamp );
284     }
285
286     return ECORE_CALLBACK_PASS_ON;
287   }
288
289   /**
290    * Called when a touch up is received.
291    */
292   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
293   {
294     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
295
296     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);
297
298     EventHandler* handler( (EventHandler*)data );
299     if ( mouseWheelEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
300     {
301       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
302       handler->SendWheelEvent( wheelEvent );
303     }
304     return ECORE_CALLBACK_PASS_ON;
305   }
306
307   /**
308    * Called when a touch motion is received.
309    */
310   static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
311   {
312     Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
313     EventHandler* handler( (EventHandler*)data );
314
315     if ( touchEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
316     {
317       Integration::Point point;
318       point.SetDeviceId( touchEvent->multi.device );
319       point.SetState( PointState::MOTION );
320       point.SetScreenPosition( Vector2( touchEvent->x, touchEvent->y ) );
321       point.SetRadius( touchEvent->multi.radius, Vector2( touchEvent->multi.radius_x, touchEvent->multi.radius_y ) );
322       point.SetPressure( touchEvent->multi.pressure );
323       point.SetAngle( Degree( touchEvent->multi.angle ) );
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     // If a device key then skip ecore_imf_context_filter_event.
346     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
347     {
348       Ecore_IMF_Context* imfContext = NULL;
349       Dali::ImfManager imfManager( ImfManager::Get() );
350       if ( imfManager )
351       {
352         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
353       }
354
355       if ( imfContext )
356       {
357         // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
358         Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
359         ecoreKeyDownEvent.keyname   = keyEvent->keyname;
360         ecoreKeyDownEvent.key       = keyEvent->key;
361         ecoreKeyDownEvent.string    = keyEvent->string;
362         ecoreKeyDownEvent.compose   = keyEvent->compose;
363         ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
364         ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
365         ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
366
367         eventHandled = ecore_imf_context_filter_event( imfContext,
368                                                        ECORE_IMF_EVENT_KEY_DOWN,
369                                                        (Ecore_IMF_Event *) &ecoreKeyDownEvent );
370
371         // If the event has not been handled by IMF then check if we should reset our IMF context
372         if( !eventHandled )
373         {
374           if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
375                !strcmp( keyEvent->keyname, "Return"   ) ||
376                !strcmp( keyEvent->keyname, "KP_Enter" ) )
377           {
378             ecore_imf_context_reset( imfContext );
379           }
380         }
381       }
382     }
383
384     // If the event wasn't handled then we should send a key event.
385     if ( !eventHandled )
386     {
387       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
388       {
389         std::string keyName( keyEvent->keyname );
390         std::string keyString( "" );
391         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
392         keyCode = (keyCode == -1) ? 0 : keyCode;
393         int modifier( keyEvent->modifiers );
394         unsigned long time = keyEvent->timestamp;
395         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
396           keyCode = atoi(keyEvent->keyname + 8);
397
398         // Ensure key event string is not NULL as keys like SHIFT have a null string.
399         if ( keyEvent->string )
400         {
401           keyString = keyEvent->string;
402         }
403
404         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Down);
405         handler->SendEvent( keyEvent );
406       }
407     }
408
409     return ECORE_CALLBACK_PASS_ON;
410   }
411
412   /**
413    * Called when a key up is received.
414    */
415   static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
416   {
417     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp\n" );
418
419     EventHandler* handler( (EventHandler*)data );
420     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
421     bool eventHandled( false );
422
423     // Device keys like Menu, home, back button must skip ecore_imf_context_filter_event.
424     if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
425     {
426       Ecore_IMF_Context* imfContext = NULL;
427       Dali::ImfManager imfManager( ImfManager::Get() );
428       if ( imfManager )
429       {
430         imfContext = ImfManager::GetImplementation( imfManager ).GetContext();
431       }
432
433       if ( imfContext )
434       {
435         // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
436         Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
437         ecoreKeyUpEvent.keyname   = keyEvent->keyname;
438         ecoreKeyUpEvent.key       = keyEvent->key;
439         ecoreKeyUpEvent.string    = keyEvent->string;
440         ecoreKeyUpEvent.compose   = keyEvent->compose;
441         ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
442         ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
443         ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
444
445         eventHandled = ecore_imf_context_filter_event( imfContext,
446                                                        ECORE_IMF_EVENT_KEY_UP,
447                                                        (Ecore_IMF_Event *) &ecoreKeyUpEvent );
448       }
449     }
450
451     // If the event wasn't handled then we should send a key event.
452     if ( !eventHandled )
453     {
454       if ( keyEvent->window == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
455       {
456         std::string keyName( keyEvent->keyname );
457         std::string keyString( "" );
458         int keyCode = KeyLookup::GetDaliKeyCode( keyEvent->keyname);
459         keyCode = (keyCode == -1) ? 0 : keyCode;
460         int modifier( keyEvent->modifiers );
461         unsigned long time = keyEvent->timestamp;
462         if (!strncmp(keyEvent->keyname, "Keycode-", 8))
463           keyCode = atoi(keyEvent->keyname + 8);
464
465         // Ensure key event string is not NULL as keys like SHIFT have a null string.
466         if ( keyEvent->string )
467         {
468           keyString = keyEvent->string;
469         }
470
471         KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Up);
472         handler->SendEvent( keyEvent );
473       }
474     }
475
476     return ECORE_CALLBACK_PASS_ON;
477   }
478
479   /////////////////////////////////////////////////////////////////////////////////////////////////
480   // Window Callbacks
481   /////////////////////////////////////////////////////////////////////////////////////////////////
482
483   /**
484    * Called when the window gains focus.
485    */
486   static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
487   {
488     Ecore_Wl_Event_Focus_In* focusInEvent( (Ecore_Wl_Event_Focus_In*)event );
489     EventHandler* handler( (EventHandler*)data );
490
491     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
492
493     // If the window gains focus and we hid the keyboard then show it again.
494     if ( focusInEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
495     {
496       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
497
498       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
499       {
500         Dali::ImfManager imfManager( ImfManager::Get() );
501         if ( imfManager )
502         {
503           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
504           if( imfManagerImpl.RestoreAfterFocusLost() )
505           {
506             imfManagerImpl.Activate();
507           }
508         }
509       }
510       Dali::Clipboard clipboard = Clipboard::Get();
511       clipboard.HideClipboard();
512     }
513
514     return ECORE_CALLBACK_PASS_ON;
515   }
516
517   /**
518    * Called when the window loses focus.
519    */
520   static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
521   {
522     Ecore_Wl_Event_Focus_Out* focusOutEvent( (Ecore_Wl_Event_Focus_Out*)event );
523     EventHandler* handler( (EventHandler*)data );
524
525     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
526
527     // If the window loses focus then hide the keyboard.
528     if ( focusOutEvent->win == (unsigned int)ecore_wl_window_id_get(handler->mImpl->mWindow) )
529     {
530       if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
531       {
532         Dali::ImfManager imfManager( ImfManager::Get() );
533         if ( imfManager )
534         {
535           ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
536           if( imfManagerImpl.RestoreAfterFocusLost() )
537           {
538             imfManagerImpl.Deactivate();
539           }
540         }
541       }
542
543       // Hiding clipboard event will be ignored once because window focus out event is always received on showing clipboard
544       Dali::Clipboard clipboard = Clipboard::Get();
545       if ( clipboard )
546       {
547         Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
548         clipBoardImpl.HideClipboard(true);
549       }
550     }
551
552     return ECORE_CALLBACK_PASS_ON;
553   }
554
555   /**
556    * Called when the window is damaged.
557    */
558   static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
559   {
560     return ECORE_CALLBACK_PASS_ON;
561   }
562
563   /**
564    * Called when the window properties are changed.
565    * We are only interested in the font change.
566    */
567
568
569   /////////////////////////////////////////////////////////////////////////////////////////////////
570   // Drag & Drop Callbacks
571   /////////////////////////////////////////////////////////////////////////////////////////////////
572
573   /**
574    * Called when a dragged item enters our window's bounds.
575    * This is when items are dragged INTO our window.
576    */
577   static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
578   {
579     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
580
581     return ECORE_CALLBACK_PASS_ON;
582   }
583
584   /**
585    * Called when a dragged item is moved within our window.
586    * This is when items are dragged INTO our window.
587    */
588   static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
589   {
590     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
591
592     return ECORE_CALLBACK_PASS_ON;
593   }
594
595   /**
596    * Called when a dragged item leaves our window's bounds.
597    * This is when items are dragged INTO our window.
598    */
599   static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
600   {
601     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
602
603     return ECORE_CALLBACK_PASS_ON;
604   }
605
606   /**
607    * Called when the dragged item is dropped within our window's bounds.
608    * This is when items are dragged INTO our window.
609    */
610   static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
611   {
612     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
613
614     return ECORE_CALLBACK_PASS_ON;
615   }
616
617   /**
618    * Called when a dragged item is moved from our window and the target window has done processing it.
619    * This is when items are dragged FROM our window.
620    */
621   static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
622   {
623     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
624     return ECORE_CALLBACK_PASS_ON;
625   }
626
627   /**
628    * Called when a dragged item is moved from our window and the target window has sent us a status.
629    * This is when items are dragged FROM our window.
630    */
631   static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
632   {
633     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
634     return ECORE_CALLBACK_PASS_ON;
635   }
636
637   /**
638    * Called when the client messages (i.e. the accessibility events) are received.
639    */
640   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
641   {
642     return ECORE_CALLBACK_PASS_ON;
643   }
644
645   /**
646    * Called when the source window notifies us the content in clipboard is selected.
647    */
648   static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
649   {
650     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
651     return ECORE_CALLBACK_PASS_ON;
652   }
653
654   /**
655    * Called when the source window sends us about the selected content.
656    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
657    */
658   static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
659   {
660     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
661     return ECORE_CALLBACK_PASS_ON;
662   }
663
664   /**
665   * Called when the source window notifies us the content in clipboard is selected.
666   */
667   static Eina_Bool EcoreEventDataSend( void* data, int type, void* event )
668   {
669     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataSend\n" );
670
671     Dali::Clipboard clipboard = Clipboard::Get();
672     if ( clipboard )
673     {
674       Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
675       clipBoardImpl.ExcuteBuffered( true, event );
676     }
677     return ECORE_CALLBACK_PASS_ON;
678   }
679
680    /**
681     * Called when the source window sends us about the selected content.
682     * For example, when item is selected in the clipboard.
683     */
684    static Eina_Bool EcoreEventDataReceive( void* data, int type, void* event )
685    {
686      DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDataReceive\n" );
687
688      EventHandler* handler( (EventHandler*)data );
689       Dali::Clipboard clipboard = Clipboard::Get();
690       char *selectionData = NULL;
691       if ( clipboard )
692       {
693         Clipboard& clipBoardImpl( GetImplementation( clipboard ) );
694         selectionData = clipBoardImpl.ExcuteBuffered( false, event );
695       }
696       if ( selectionData && handler->mClipboardEventNotifier )
697       {
698         ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) );
699         std::string content( selectionData, strlen(selectionData) );
700
701         clipboardEventNotifier.SetContent( content );
702         clipboardEventNotifier.EmitContentSelectedSignal();
703       }
704      return ECORE_CALLBACK_PASS_ON;
705    }
706
707   /*
708   * Called when detent event is recevied
709   */
710   static Eina_Bool EcoreEventDetent( void* data, int type, void* event )
711   {
712     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventDetent\n" );
713     EventHandler* handler( (EventHandler*)data );
714     Ecore_Event_Detent_Rotate *e((Ecore_Event_Detent_Rotate *)event);
715     int direction = (e->direction == ECORE_DETENT_DIRECTION_CLOCKWISE) ? 1 : -1;
716     int timeStamp = e->timestamp;
717
718     WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), direction, timeStamp );
719     handler->SendWheelEvent( wheelEvent );
720     return ECORE_CALLBACK_PASS_ON;
721   }
722
723   /////////////////////////////////////////////////////////////////////////////////////////////////
724   // Font Callbacks
725   /////////////////////////////////////////////////////////////////////////////////////////////////
726   /**
727    * Called when a font name is changed.
728    */
729   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
730   {
731     EventHandler* handler = static_cast<EventHandler*>( data );
732     handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
733   }
734
735   /**
736    * Called when a font size is changed.
737    */
738   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
739   {
740     EventHandler* handler = static_cast<EventHandler*>( data );
741     handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
742   }
743
744   // Data
745   EventHandler* mHandler;
746   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
747   Ecore_Wl_Window* mWindow;
748 };
749
750 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
751 : mCoreEventInterface(coreEventInterface),
752   mGestureManager( gestureManager ),
753   mStyleMonitor( StyleMonitor::Get() ),
754   mDamageObserver( damageObserver ),
755   mRotationObserver( NULL ),
756   mDragAndDropDetector( dndDetector ),
757   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),
758   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
759   mClipboard(Clipboard::Get()),
760   mImpl( NULL )
761 {
762   Ecore_Wl_Window* window = 0;
763
764   // this code only works with the Ecore RenderSurface so need to downcast
765   ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
766   if( ecoreSurface )
767   {
768     window = ecoreSurface->GetWlWindow();
769   }
770
771   mImpl = new Impl(this, window);
772 }
773
774 EventHandler::~EventHandler()
775 {
776   if(mImpl)
777   {
778     delete mImpl;
779   }
780
781   mGestureManager.Stop();
782 }
783
784 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)
785 {
786   if(timeStamp < 1)
787   {
788     timeStamp = GetCurrentMilliSeconds();
789   }
790
791   Integration::TouchEvent touchEvent;
792   Integration::HoverEvent hoverEvent;
793   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
794   if(type != Integration::TouchEventCombiner::DispatchNone )
795   {
796     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);
797
798     // First the touch and/or hover event & related gesture events are queued
799     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
800     {
801       mCoreEventInterface.QueueCoreEvent( touchEvent );
802       mGestureManager.SendEvent(touchEvent);
803     }
804
805     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
806     {
807       mCoreEventInterface.QueueCoreEvent( hoverEvent );
808     }
809
810     // Next the events are processed with a single call into Core
811     mCoreEventInterface.ProcessCoreEvents();
812   }
813 }
814
815 void EventHandler::SendEvent(KeyEvent& keyEvent)
816 {
817   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
818   if ( physicalKeyboard )
819   {
820     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
821     {
822       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
823     }
824   }
825
826   // Create KeyEvent and send to Core.
827   Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
828   keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
829   mCoreEventInterface.QueueCoreEvent( event );
830   mCoreEventInterface.ProcessCoreEvents();
831 }
832
833 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
834 {
835   // Create WheelEvent and send to Core.
836   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
837   mCoreEventInterface.QueueCoreEvent( event );
838   mCoreEventInterface.ProcessCoreEvents();
839 }
840
841 void EventHandler::SendEvent( StyleChange::Type styleChange )
842 {
843   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
844   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
845 }
846
847 void EventHandler::SendEvent( const DamageArea& area )
848 {
849   mDamageObserver.OnDamaged( area );
850 }
851
852 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
853 {
854   if( mRotationObserver != NULL )
855   {
856     mRotationObserver->OnRotationPrepare( event );
857   }
858 }
859
860 void EventHandler::SendRotationRequestEvent( )
861 {
862   if( mRotationObserver != NULL )
863   {
864     mRotationObserver->OnRotationRequest( );
865   }
866 }
867
868 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
869 {
870   Integration::Point convertedPoint( point );
871   SendEvent(convertedPoint, timeStamp);
872 }
873
874 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
875 {
876   SendWheelEvent( wheelEvent );
877 }
878
879 void EventHandler::FeedKeyEvent( KeyEvent& event )
880 {
881   SendEvent( event );
882 }
883
884 void EventHandler::FeedEvent( Integration::Event& event )
885 {
886   mCoreEventInterface.QueueCoreEvent( event );
887   mCoreEventInterface.ProcessCoreEvents();
888 }
889
890 void EventHandler::Reset()
891 {
892   mCombiner.Reset();
893
894   // Any touch listeners should be told of the interruption.
895   Integration::TouchEvent event;
896   Integration::Point point;
897   point.SetState( PointState::INTERRUPTED );
898   event.AddPoint( point );
899
900   // First the touch event & related gesture events are queued
901   mCoreEventInterface.QueueCoreEvent( event );
902   mGestureManager.SendEvent( event );
903
904   // Next the events are processed with a single call into Core
905   mCoreEventInterface.ProcessCoreEvents();
906 }
907
908 void EventHandler::Pause()
909 {
910   mPaused = true;
911   Reset();
912 }
913
914 void EventHandler::Resume()
915 {
916   mPaused = false;
917   Reset();
918 }
919
920 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
921 {
922   mDragAndDropDetector = detector;
923 }
924
925 void EventHandler::SetRotationObserver( RotationObserver* observer )
926 {
927   mRotationObserver = observer;
928 }
929
930 } // namespace Adaptor
931
932 } // namespace Internal
933
934 } // namespace Dali