Revert "[Tizen] Do not call ProcessCoreEventsFromIdle repeatedly"
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / windows / event-handler-ecore-win.cpp
1 /*\r
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  *\r
16  */\r
17 \r
18 // CLASS HEADER\r
19 #include <dali/internal/window-system/common/event-handler.h>\r
20 \r
21 // EXTERNAL INCLUDES\r
22 #include <cstring>\r
23 #include <dali/public-api/adaptor-framework/window.h>\r
24 \r
25 #include <dali/public-api/common/vector-wrapper.h>\r
26 #include <dali/public-api/events/touch-point.h>\r
27 #include <dali/public-api/events/key-event.h>\r
28 #include <dali/public-api/events/wheel-event.h>\r
29 #include <dali/integration-api/debug.h>\r
30 #include <dali/integration-api/events/key-event-integ.h>\r
31 #include <dali/integration-api/events/touch-event-integ.h>\r
32 #include <dali/integration-api/events/hover-event-integ.h>\r
33 #include <dali/integration-api/events/wheel-event-integ.h>\r
34 #include <WindowsEventSystem.h>\r
35 \r
36 // INTERNAL INCLUDES\r
37 #include <dali/internal/input/common/gesture-manager.h>\r
38 #include <dali/internal/window-system/windows/window-render-surface-ecore-win.h>\r
39 #include <dali/internal/clipboard/common/clipboard-impl.h>\r
40 #include <dali/internal/input/common/key-impl.h>\r
41 #include <dali/internal/input/common/physical-keyboard-impl.h>\r
42 #include <dali/internal/styling/common/style-monitor-impl.h>\r
43 #include <dali/internal/system/common/core-event-interface.h>\r
44 \r
45 #include <Windows.h>\r
46 \r
47 namespace Dali\r
48 {\r
49 \r
50 namespace Internal\r
51 {\r
52 \r
53 using namespace Win32System;\r
54 \r
55 namespace Adaptor\r
56 {\r
57 \r
58 #if defined(DEBUG_ENABLED)\r
59 namespace\r
60 {\r
61 Integration::Log::Filter* gTouchEventLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_TOUCH");\r
62 Integration::Log::Filter* gClientMessageLogFilter  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_CLIENT_MESSAGE");\r
63 Integration::Log::Filter* gDragAndDropLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DND");\r
64 Integration::Log::Filter* gImfLogging  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_IMF");\r
65 Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_SELECTION");\r
66 } // unnamed namespace\r
67 #endif\r
68 \r
69 namespace\r
70 {\r
71 \r
72 const std::string DEFAULT_DEVICE_NAME = "";\r
73 const Device::Class::Type DEFAULT_DEVICE_CLASS = Device::Class::NONE;\r
74 const Device::Subclass::Type DEFAULT_DEVICE_SUBCLASS = Device::Subclass::NONE;\r
75 \r
76 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );\r
77 \r
78 #ifndef DALI_PROFILE_UBUNTU\r
79 const char * CLIPBOARD_ATOM                = "CBHM_MSG";\r
80 const char * CLIPBOARD_SET_OWNER_MESSAGE   = "SET_OWNER";\r
81 #endif // DALI_PROFILE_UBUNTU\r
82 \r
83 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;\r
84 \r
85 /**\r
86  * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.\r
87  * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.\r
88  * @param[in] ecoreModifier the Ecore_Event_Modifier input.\r
89  * @return the Ecore_IMF_Keyboard_Modifiers output.\r
90  */\r
91 \r
92 static bool IsDeviceButton(int keyCode)\r
93 {\r
94     bool ret = false;\r
95     switch (keyCode)\r
96     {\r
97     case VK_BACK:\r
98     case VK_ESCAPE:\r
99     case VK_LEFT:\r
100     case VK_RIGHT:\r
101     case VK_SHIFT:\r
102         ret = true;\r
103         break;\r
104 \r
105     default:\r
106         break;\r
107     }\r
108 \r
109     return ret;\r
110 }\r
111 \r
112 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)\r
113 {\r
114    int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.\r
115 \r
116    if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h\r
117    {\r
118      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h\r
119    }\r
120 \r
121    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )\r
122    {\r
123      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;\r
124    }\r
125 \r
126    if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )\r
127    {\r
128      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;\r
129    }\r
130 \r
131    if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )\r
132    {\r
133      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;\r
134    }\r
135 \r
136    if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )\r
137    {\r
138      modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;\r
139    }\r
140 \r
141    return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );\r
142 }\r
143 \r
144 \r
145 // Copied from x server\r
146 // Copied from x server\r
147 \r
148 void GetNanoseconds(uint64_t& timeInNanoseconds)\r
149 {\r
150     Win32WindowSystem::GetNanoseconds(timeInNanoseconds);\r
151 }\r
152 \r
153 // Copied from x server\r
154 unsigned int GetCurrentMilliSeconds(void)\r
155 {\r
156     return Win32WindowSystem::GetCurrentMilliSeconds();\r
157 }\r
158 } // unnamed namespace\r
159 \r
160 // Impl to hide EFL implementation.\r
161 struct EventHandler::Impl\r
162 {\r
163   // Construction & Destruction\r
164 \r
165   /**\r
166    * Constructor\r
167    */\r
168   Impl( EventHandler* handler, Ecore_Win_Window window )\r
169   : mHandler( handler ),\r
170     mEcoreEventHandler(),\r
171     mWindow( window ),\r
172     mXiDeviceId( 0 )\r
173 #ifdef DALI_ELDBUS_AVAILABLE\r
174   , mSessionConnection( NULL ),\r
175     mA11yConnection( NULL )\r
176 #endif\r
177   {\r
178     // Only register for touch and key events if we have a window\r
179     if ( window != 0 )\r
180     {\r
181       // Register Touch events\r
182       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN,  EcoreEventMouseButtonDown, handler ) );\r
183       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP,    EcoreEventMouseButtonUp,   handler ) );\r
184       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE,         EcoreEventMouseButtonMove, handler ) );\r
185       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT,          EcoreEventMouseOut,   handler ) ); // process mouse out event like up event\r
186 \r
187       // Register Mouse wheel events\r
188       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL,        EcoreEventMouseWheel,      handler ) );\r
189 \r
190       // Register Key events\r
191       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN,           EcoreEventKeyDown,         handler ) );\r
192       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP,             EcoreEventKeyUp,           handler ) );\r
193 \r
194       // Register Focus events\r
195       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_WINDOW_FOCUS_IN,  EcoreEventWindowFocusIn,   handler ) );\r
196       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut,  handler ) );\r
197 \r
198       // Register Window damage events\r
199       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_WINDOW_DAMAGE,    EcoreEventWindowDamaged, handler ) );\r
200 \r
201       // Enable Drag & Drop and register DnD events\r
202       //ecore_win_dnd_aware_set( window, EINA_TRUE );\r
203       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_ENTER,       EcoreEventDndEnter,            handler) );\r
204       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_POSITION,    EcoreEventDndPosition,         handler) );\r
205       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_LEAVE,       EcoreEventDndLeave,            handler) );\r
206       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_DROP,        EcoreEventDndDrop,             handler) );\r
207       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_FINISHED,    EcoreEventDndFinished,         handler) );\r
208       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_XDND_STATUS,      EcoreEventDndStatus,           handler) );\r
209 \r
210       // Register Client message events - accessibility etc.\r
211       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_CLIENT_MESSAGE,  EcoreEventClientMessage, handler ) );\r
212 \r
213       // Register Selection event - clipboard selection, Drag & Drop selection etc.\r
214       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) );\r
215       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_WIN_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) );\r
216 \r
217       Win32WindowSystem::AddListener(EventEntry);\r
218     }\r
219   }\r
220 \r
221   /**\r
222    * Destructor\r
223    */\r
224   ~Impl()\r
225   {\r
226 #ifndef DALI_PROFILE_UBUNTU\r
227     //vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );\r
228     //vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged );\r
229 #endif // DALI_PROFILE_UBUNTU\r
230 \r
231     for( std::vector<Ecore_Event_Handler>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )\r
232     {\r
233       ecore_event_handler_del( *iter );\r
234     }\r
235 \r
236 #ifdef DALI_ELDBUS_AVAILABLE\r
237     // Close down ElDBus\r
238     if( mA11yConnection )\r
239     {\r
240       eldbus_connection_unref( mA11yConnection );\r
241     }\r
242 \r
243     if( mSessionConnection )\r
244     {\r
245       eldbus_connection_unref( mSessionConnection );\r
246     }\r
247 \r
248     eldbus_shutdown();\r
249 #endif // DALI_ELDBUS_AVAILABLE\r
250   }\r
251 \r
252   // Static methods\r
253 \r
254   /////////////////////////////////////////////////////////////////////////////////////////////////\r
255   // Touch Callbacks\r
256   /////////////////////////////////////////////////////////////////////////////////////////////////\r
257   static void EventEntry(long hWnd, unsigned int uMsg, long wParam, long lParam)\r
258   {\r
259       EventCallback callback = GetCallback(uMsg);\r
260       EventHandler *handler = ( EventHandler* )GetEventHandler(uMsg);\r
261 \r
262       if (NULL != callback)\r
263       {\r
264           //EventHandler *handler = new EventHandler();\r
265           TWinEventInfo eventInfo(hWnd, uMsg, wParam, lParam);\r
266           callback(handler, uMsg, &eventInfo);\r
267       }\r
268   }\r
269   /**\r
270    * Called when a touch down is received.\r
271    */\r
272   static bool EcoreEventMouseButtonDown( void* data, int type, TWinEventInfo *event )\r
273   {\r
274     Ecore_Event_Mouse_Button touchEvent = *((Ecore_Event_Mouse_Button*)event);\r
275     EventHandler* handler( (EventHandler*)data );\r
276 \r
277     touchEvent.x = LOWORD(event->lParam);\r
278     touchEvent.y = HIWORD(event->lParam);\r
279     touchEvent.multi.device = DEVICE_MOUSE;\r
280 \r
281     if ( touchEvent.window == handler->mImpl->mWindow )\r
282     {\r
283       PointState::Type state ( PointState::DOWN );\r
284 \r
285       // Check if the buttons field is set and ensure it's the primary touch button.\r
286       // If this event was triggered by buttons other than the primary button (used for touch), then\r
287       // just send an interrupted event to Core.\r
288       if ( touchEvent.buttons && (touchEvent.buttons != PRIMARY_TOUCH_BUTTON_ID ) )\r
289       {\r
290         state = PointState::INTERRUPTED;\r
291       }\r
292 \r
293       Integration::Point point;\r
294       point.SetDeviceId( touchEvent.multi.device );\r
295       point.SetState( state );\r
296       point.SetScreenPosition( Vector2( touchEvent.x, touchEvent.y + Win32WindowSystem::GetEdgeHeight() ) );\r
297       point.SetRadius( touchEvent.multi.radius, Vector2( touchEvent.multi.radius_x, touchEvent.multi.radius_y ) );\r
298       point.SetPressure( touchEvent.multi.pressure );\r
299       point.SetAngle( Degree( touchEvent.multi.angle ) );\r
300       handler->SendEvent( point, touchEvent.timestamp );\r
301     }\r
302 \r
303     return ECORE_CALLBACK_PASS_ON;\r
304   }\r
305 \r
306   /**\r
307    * Called when a touch up is received.\r
308    */\r
309   static bool EcoreEventMouseButtonUp( void* data, int type, TWinEventInfo *event )\r
310   {\r
311     Ecore_Event_Mouse_Button touchEvent = *((Ecore_Event_Mouse_Button*)event);\r
312     EventHandler* handler( (EventHandler*)data );\r
313 \r
314     touchEvent.x = LOWORD(event->lParam);\r
315     touchEvent.y = HIWORD(event->lParam);\r
316     touchEvent.multi.device = DEVICE_MOUSE;\r
317 \r
318     if ( touchEvent.window == handler->mImpl->mWindow )\r
319     {\r
320       Integration::Point point;\r
321       point.SetDeviceId(touchEvent.multi.device );\r
322       point.SetState( PointState::UP );\r
323       point.SetScreenPosition( Vector2(touchEvent.x, touchEvent.y + Win32WindowSystem::GetEdgeHeight() ) );\r
324       point.SetRadius(touchEvent.multi.radius, Vector2(touchEvent.multi.radius_x, touchEvent.multi.radius_y ) );\r
325       point.SetPressure(touchEvent.multi.pressure );\r
326       point.SetAngle( Degree(touchEvent.multi.angle ) );\r
327       handler->SendEvent( point, touchEvent.timestamp );\r
328     }\r
329 \r
330     return ECORE_CALLBACK_PASS_ON;\r
331   }\r
332 \r
333   /**\r
334    * Called when a touch motion is received.\r
335    */\r
336   static bool EcoreEventMouseButtonMove( void* data, int type, TWinEventInfo *event )\r
337   {\r
338     Ecore_Event_Mouse_Button touchEvent = *((Ecore_Event_Mouse_Button*)event);\r
339     touchEvent.timestamp = GetTickCount();\r
340 \r
341     EventHandler* handler( (EventHandler*)data );\r
342 \r
343     touchEvent.x = LOWORD(event->lParam);\r
344     touchEvent.y = HIWORD(event->lParam);\r
345     touchEvent.multi.device = DEVICE_MOUSE;\r
346 \r
347     if (touchEvent.window == handler->mImpl->mWindow )\r
348     {\r
349       Integration::Point point;\r
350       point.SetDeviceId(touchEvent.multi.device );\r
351       point.SetState( PointState::MOTION );\r
352       point.SetScreenPosition( Vector2(touchEvent.x, touchEvent.y + Win32WindowSystem::GetEdgeHeight() ) );\r
353       point.SetRadius(touchEvent.multi.radius, Vector2(touchEvent.multi.radius_x, touchEvent.multi.radius_y ) );\r
354       point.SetPressure(touchEvent.multi.pressure );\r
355       point.SetAngle( Degree(touchEvent.multi.angle ) );\r
356       handler->SendEvent( point, touchEvent.timestamp );\r
357     }\r
358 \r
359     return ECORE_CALLBACK_PASS_ON;\r
360   }\r
361 \r
362   static bool EcoreEventMouseOut( void* data, int type, TWinEventInfo *event )\r
363   {\r
364     return ECORE_CALLBACK_PASS_ON;\r
365   }\r
366 \r
367   /////////////////////////////////////////////////////////////////////////////////////////////////\r
368   // Wheel Callbacks\r
369   /////////////////////////////////////////////////////////////////////////////////////////////////\r
370 \r
371   /**\r
372    * Called when a mouse wheel is received.\r
373    */\r
374   static bool EcoreEventMouseWheel( void* data, int type, TWinEventInfo *event )\r
375   {\r
376     Ecore_Event_Mouse_Wheel mouseWheelEvent = *((Ecore_Event_Mouse_Wheel*)event);\r
377     mouseWheelEvent.x = LOWORD(event->lParam);\r
378     mouseWheelEvent.y = HIWORD(event->lParam);\r
379 \r
380     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 );\r
381 \r
382     EventHandler* handler( (EventHandler*)data );\r
383     if ( mouseWheelEvent.window == handler->mImpl->mWindow )\r
384     {\r
385       WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent.direction, mouseWheelEvent.modifiers, Vector2(mouseWheelEvent.x, mouseWheelEvent.y), mouseWheelEvent.z, mouseWheelEvent.timestamp );\r
386       handler->SendWheelEvent( wheelEvent );\r
387     }\r
388     return ECORE_CALLBACK_PASS_ON;\r
389   }\r
390 \r
391   /**\r
392    * Called when a custom wheel is received.\r
393    */\r
394   static bool EcoreEventCustomWheel( void* data, int type, TWinEventInfo *event )\r
395   {\r
396     return ECORE_CALLBACK_PASS_ON;\r
397   }\r
398 \r
399   /////////////////////////////////////////////////////////////////////////////////////////////////\r
400   // Key Callbacks\r
401   /////////////////////////////////////////////////////////////////////////////////////////////////\r
402 \r
403   /**\r
404    * Called when a key down is received.\r
405    */\r
406 \r
407   static bool EcoreEventKeyDown( void* data, int type, TWinEventInfo *event )\r
408   {\r
409     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );\r
410 \r
411     EventHandler* handler( (EventHandler*)data );\r
412 \r
413     if( event->mWindow == handler->mImpl->mWindow )\r
414     {\r
415       int keyCode = event->wParam;\r
416       std::string keyName( Win32WindowSystem::GetKeyName( keyCode ) );\r
417       std::string keyString( "" );\r
418       std::string compose ( "" );\r
419 \r
420       int modifier( 0 );\r
421       unsigned long time( 0 );\r
422 \r
423       // Ensure key event string is not NULL as keys like SHIFT have a null string.\r
424       keyString.push_back( event->wParam );\r
425 \r
426       Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Down, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );\r
427       handler->SendEvent( keyEvent );\r
428     }\r
429 \r
430     return ECORE_CALLBACK_PASS_ON;\r
431   }\r
432 \r
433   /**\r
434    * Called when a key up is received.\r
435    */\r
436   static bool EcoreEventKeyUp( void* data, int type, TWinEventInfo *event )\r
437   {\r
438     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp \n" );\r
439 \r
440     EventHandler* handler( (EventHandler*)data );\r
441 \r
442     if( event->mWindow == handler->mImpl->mWindow )\r
443     {\r
444       int keyCode = event->wParam;\r
445       std::string keyName( Win32WindowSystem::GetKeyName( keyCode ) );\r
446       std::string keyString( "" );\r
447       std::string compose( "" );\r
448 \r
449       int modifier( 0/*keyEvent->modifiers*/ );\r
450       unsigned long time( 0 );\r
451 \r
452       // Ensure key event string is not NULL as keys like SHIFT have a null string.\r
453       keyString.push_back( event->wParam );\r
454 \r
455       Integration::KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, Integration::KeyEvent::Up, compose, DEFAULT_DEVICE_NAME, DEFAULT_DEVICE_CLASS, DEFAULT_DEVICE_SUBCLASS );\r
456 \r
457       handler->SendEvent( keyEvent );\r
458     }\r
459 \r
460     return ECORE_CALLBACK_PASS_ON;\r
461   }\r
462 \r
463   /////////////////////////////////////////////////////////////////////////////////////////////////\r
464   // Window Callbacks\r
465   /////////////////////////////////////////////////////////////////////////////////////////////////\r
466 \r
467   /**\r
468    * Called when the window gains focus.\r
469    */\r
470   static bool EcoreEventWindowFocusIn( void* data, int type, TWinEventInfo *event )\r
471   {\r
472     EventHandler* handler( (EventHandler*)data );\r
473 \r
474     DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );\r
475 \r
476     // If the window gains focus and we hid the keyboard then show it again.\r
477     if (event->mWindow == handler->mImpl->mWindow )\r
478     {\r
479       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );\r
480     }\r
481 \r
482     return ECORE_CALLBACK_PASS_ON;\r
483   }\r
484 \r
485   /**\r
486    * Called when the window loses focus.\r
487    */\r
488   static bool EcoreEventWindowFocusOut( void* data, int type, TWinEventInfo *event )\r
489   {\r
490     return ECORE_CALLBACK_PASS_ON;\r
491   }\r
492 \r
493   /**\r
494    * Called when the window is damaged.\r
495    */\r
496   static bool EcoreEventWindowDamaged(void *data, int type, TWinEventInfo *event)\r
497   {\r
498       Ecore_Event_Mouse_Button* windowDamagedEvent( (Ecore_Event_Mouse_Button*)event );\r
499     EventHandler* handler( (EventHandler*)data );\r
500 \r
501     if( windowDamagedEvent->window == handler->mImpl->mWindow )\r
502     {\r
503       DamageArea area;\r
504       area.x = 0;\r
505       area.y = 0;\r
506       area.width = 480;\r
507       area.height = 800;\r
508 \r
509       handler->SendEvent( area );\r
510     }\r
511 \r
512     return ECORE_CALLBACK_PASS_ON;\r
513   }\r
514 \r
515   /**\r
516    * Called when the window properties are changed.\r
517    * We are only interested in the font change.\r
518    */\r
519 \r
520 \r
521   /////////////////////////////////////////////////////////////////////////////////////////////////\r
522   // Drag & Drop Callbacks\r
523   /////////////////////////////////////////////////////////////////////////////////////////////////\r
524 \r
525   /**\r
526    * Called when a dragged item enters our window's bounds.\r
527    * This is when items are dragged INTO our window.\r
528    */\r
529   static bool EcoreEventDndEnter( void* data, int type, TWinEventInfo *event )\r
530   {\r
531     DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );\r
532     return ECORE_CALLBACK_PASS_ON;\r
533   }\r
534 \r
535   /**\r
536    * Called when a dragged item is moved within our window.\r
537    * This is when items are dragged INTO our window.\r
538    */\r
539   static bool EcoreEventDndPosition( void* data, int type, TWinEventInfo *event )\r
540   {\r
541     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );\r
542     return ECORE_CALLBACK_PASS_ON;\r
543   }\r
544 \r
545   /**\r
546    * Called when a dragged item leaves our window's bounds.\r
547    * This is when items are dragged INTO our window.\r
548    */\r
549   static bool EcoreEventDndLeave( void* data, int type, TWinEventInfo *event )\r
550   {\r
551     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );\r
552     return ECORE_CALLBACK_PASS_ON;\r
553   }\r
554 \r
555   /**\r
556    * Called when the dragged item is dropped within our window's bounds.\r
557    * This is when items are dragged INTO our window.\r
558    */\r
559   static bool EcoreEventDndDrop( void* data, int type, TWinEventInfo *event )\r
560   {\r
561     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );\r
562     return ECORE_CALLBACK_PASS_ON;\r
563   }\r
564 \r
565   /**\r
566    * Called when a dragged item is moved from our window and the target window has done processing it.\r
567    * This is when items are dragged FROM our window.\r
568    */\r
569   static bool EcoreEventDndFinished( void* data, int type, TWinEventInfo *event )\r
570   {\r
571     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );\r
572     return ECORE_CALLBACK_PASS_ON;\r
573   }\r
574 \r
575   /**\r
576    * Called when a dragged item is moved from our window and the target window has sent us a status.\r
577    * This is when items are dragged FROM our window.\r
578    */\r
579   static bool EcoreEventDndStatus( void* data, int type, TWinEventInfo *event )\r
580   {\r
581     DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );\r
582     return ECORE_CALLBACK_PASS_ON;\r
583   }\r
584 \r
585   /**\r
586    * Called when the client messages (i.e. the accessibility events) are received.\r
587    */\r
588   static bool EcoreEventClientMessage( void* data, int type, TWinEventInfo *event )\r
589   {\r
590     return ECORE_CALLBACK_PASS_ON;\r
591   }\r
592 \r
593 \r
594   /////////////////////////////////////////////////////////////////////////////////////////////////\r
595   // ElDBus Accessibility Callbacks\r
596   /////////////////////////////////////////////////////////////////////////////////////////////////\r
597 \r
598   /**\r
599    * Called when the source window notifies us the content in clipboard is selected.\r
600    */\r
601   static bool EcoreEventSelectionClear( void* data, int type, TWinEventInfo *event )\r
602   {\r
603     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );\r
604     return ECORE_CALLBACK_PASS_ON;\r
605   }\r
606 \r
607   /**\r
608    * Called when the source window sends us about the selected content.\r
609    * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.\r
610    */\r
611   static bool EcoreEventSelectionNotify( void* data, int type, TWinEventInfo *event )\r
612   {\r
613     DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );\r
614     return ECORE_CALLBACK_PASS_ON;\r
615   }\r
616 \r
617   // Data\r
618   EventHandler* mHandler;\r
619   std::vector<Ecore_Event_Handler> mEcoreEventHandler;\r
620   Ecore_Win_Window mWindow;\r
621   int mXiDeviceId;\r
622 \r
623 #ifdef DALI_ELDBUS_AVAILABLE\r
624   Eldbus_Connection* mSessionConnection;\r
625   Eldbus_Connection* mA11yConnection;\r
626 #endif\r
627 };\r
628 \r
629 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )\r
630 : mCoreEventInterface( coreEventInterface ),\r
631   mGestureManager( gestureManager ),\r
632   mStyleMonitor( StyleMonitor::Get() ),\r
633   mDamageObserver( damageObserver ),\r
634   mRotationObserver( NULL ),\r
635   mDragAndDropDetector( dndDetector ),\r
636   mAccessibilityAdaptor( AccessibilityAdaptor::Get() ),\r
637   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),\r
638   mClipboard( Clipboard::Get() ),\r
639   mImpl( NULL ),\r
640   mPaused( false )\r
641 {\r
642   Ecore_Win_Window window = 0;\r
643 \r
644   // this code only works with the WindowRenderSurface so need to downcast\r
645   WindowRenderSurfaceEcoreWin* ecoreSurface = static_cast< WindowRenderSurfaceEcoreWin* >( surface );\r
646   if( ecoreSurface )\r
647   {\r
648     // enable multi touch\r
649     window = ecoreSurface->GetWinWindow();\r
650   }\r
651 \r
652   mImpl = new Impl(this, window);\r
653 }\r
654 \r
655 EventHandler::~EventHandler()\r
656 {\r
657   delete mImpl;\r
658 \r
659   mGestureManager.Stop();\r
660 }\r
661 \r
662 void EventHandler::SendEvent(Integration::Point& point, unsigned long timeStamp)\r
663 {\r
664   if(timeStamp < 1)\r
665   {\r
666     timeStamp = GetCurrentMilliSeconds();\r
667   }\r
668 \r
669   Integration::TouchEvent touchEvent;\r
670   Integration::HoverEvent hoverEvent;\r
671   Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);\r
672   if(type != Integration::TouchEventCombiner::DispatchNone )\r
673   {\r
674     DALI_LOG_INFO(gTouchEventLogFilter, Debug::General, "%d: Device %d: Button state %d (%.2f, %.2f)\n", timeStamp, point.GetDeviceId(), point.GetState(), point.GetScreenPosition().x, point.GetScreenPosition().y);\r
675 \r
676     // First the touch and/or hover event & related gesture events are queued\r
677     if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)\r
678     {\r
679       mCoreEventInterface.QueueCoreEvent( touchEvent );\r
680       mGestureManager.SendEvent(touchEvent);\r
681     }\r
682 \r
683     if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)\r
684     {\r
685       mCoreEventInterface.QueueCoreEvent( hoverEvent );\r
686     }\r
687 \r
688     // Next the events are processed with a single call into Core\r
689     mCoreEventInterface.ProcessCoreEvents();\r
690   }\r
691 }\r
692 \r
693 void EventHandler::SendEvent(Integration::KeyEvent& keyEvent)\r
694 {\r
695   Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();\r
696   if ( physicalKeyboard )\r
697   {\r
698     if ( ! KeyLookup::IsDeviceButton( keyEvent.keyName.c_str() ) )\r
699     {\r
700       GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );\r
701     }\r
702   }\r
703 \r
704   // Send to KeyEvent Core.\r
705   mCoreEventInterface.QueueCoreEvent( keyEvent );\r
706   mCoreEventInterface.ProcessCoreEvents();\r
707 }\r
708 \r
709 void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )\r
710 {\r
711   // Create WheelEvent and send to Core.\r
712   Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );\r
713   mCoreEventInterface.QueueCoreEvent( event );\r
714   mCoreEventInterface.ProcessCoreEvents();\r
715 }\r
716 \r
717 void EventHandler::SendEvent( StyleChange::Type styleChange )\r
718 {\r
719   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );\r
720   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);\r
721 }\r
722 \r
723 void EventHandler::SendEvent( const DamageArea& area )\r
724 {\r
725   mDamageObserver.OnDamaged( area );\r
726 }\r
727 \r
728 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )\r
729 {\r
730   if( mRotationObserver != NULL )\r
731   {\r
732     mRotationObserver->OnRotationPrepare( event );\r
733   }\r
734 }\r
735 \r
736 void EventHandler::SendRotationRequestEvent( )\r
737 {\r
738   if( mRotationObserver != NULL )\r
739   {\r
740     mRotationObserver->OnRotationRequest( );\r
741   }\r
742 }\r
743 \r
744 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)\r
745 {\r
746   Integration::Point convertedPoint( point );\r
747 \r
748   SendEvent(convertedPoint, timeStamp);\r
749 }\r
750 \r
751 void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )\r
752 {\r
753   SendWheelEvent( wheelEvent );\r
754 }\r
755 \r
756 void EventHandler::FeedKeyEvent( KeyEvent& event )\r
757 {\r
758   Integration::KeyEvent convertedEvent( event );\r
759   SendEvent( convertedEvent );\r
760 }\r
761 \r
762 void EventHandler::FeedEvent( Integration::Event& event )\r
763 {\r
764   mCoreEventInterface.QueueCoreEvent( event );\r
765   mCoreEventInterface.ProcessCoreEvents();\r
766 }\r
767 \r
768 void EventHandler::Reset()\r
769 {\r
770   mCombiner.Reset();\r
771 \r
772   // Any touch listeners should be told of the interruption.\r
773   Integration::TouchEvent event;\r
774   Integration::Point point;\r
775   point.SetState( PointState::INTERRUPTED );\r
776   event.AddPoint( point );\r
777 \r
778   // First the touch event & related gesture events are queued\r
779   mCoreEventInterface.QueueCoreEvent( event );\r
780   mGestureManager.SendEvent( event );\r
781 \r
782   // Next the events are processed with a single call into Core\r
783   mCoreEventInterface.ProcessCoreEvents();\r
784 }\r
785 \r
786 void EventHandler::Pause()\r
787 {\r
788   mPaused = true;\r
789   Reset();\r
790 }\r
791 \r
792 void EventHandler::Resume()\r
793 {\r
794   mPaused = false;\r
795   Reset();\r
796 }\r
797 \r
798 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )\r
799 {\r
800   mDragAndDropDetector = detector;\r
801 }\r
802 \r
803 void EventHandler::SetRotationObserver( RotationObserver* observer )\r
804 {\r
805   mRotationObserver = observer;\r
806 }\r
807 \r
808 } // namespace Adaptor\r
809 \r
810 } // namespace Internal\r
811 \r
812 } // namespace Dali\r
813 \r