2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <events/event-handler.h>
23 #include <Ecore_Input.h>
30 #ifndef DALI_PROFILE_UBUNTU
32 #include <vconf-keys.h>
33 #endif // DALI_PROFILE_UBUNTU
35 #include <dali/public-api/common/vector-wrapper.h>
36 #include <dali/public-api/events/touch-point.h>
37 #include <dali/public-api/events/key-event.h>
38 #include <dali/public-api/events/mouse-wheel-event.h>
39 #include <dali/integration-api/debug.h>
40 #include <dali/integration-api/events/key-event-integ.h>
41 #include <dali/integration-api/events/touch-event-integ.h>
42 #include <dali/integration-api/events/hover-event-integ.h>
43 #include <dali/integration-api/events/mouse-wheel-event-integ.h>
46 #include <events/gesture-manager.h>
47 #include <window-render-surface.h>
48 #include <clipboard-impl.h>
50 #include <physical-keyboard-impl.h>
51 #include <style-monitor-impl.h>
52 #include <base/core-event-interface.h>
63 #if defined(DEBUG_ENABLED)
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
77 #ifndef DALI_PROFILE_UBUNTU
78 const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced.
79 #endif // DALI_PROFILE_UBUNTU
81 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
83 #ifndef DALI_PROFILE_UBUNTU
84 const char * CLIPBOARD_ATOM = "CBHM_MSG";
85 const char * CLIPBOARD_SET_OWNER_MESSAGE = "SET_OWNER";
86 #endif // DALI_PROFILE_UBUNTU
88 /// The atoms required by Ecore for Drag & Drop behaviour.
89 Ecore_X_Atom DRAG_AND_DROP_ATOMS[] =
91 ECORE_X_ATOM_XDND_ACTION_COPY,
94 /// The types that we support.
95 const char * DRAG_AND_DROP_TYPES[] =
97 ECORE_X_SELECTION_TARGET_UTF8_STRING,
100 const unsigned int DRAG_AND_DROP_ATOMS_NUMBER = sizeof( DRAG_AND_DROP_ATOMS ) / sizeof( Ecore_X_Atom );
101 const unsigned int DRAG_AND_DROP_TYPES_NUMBER = sizeof( DRAG_AND_DROP_TYPES ) / sizeof( const char * );
103 const unsigned int BYTES_PER_CHARACTER_FOR_ATTRIBUTES = 3;
106 * Ecore_Event_Modifier enums in Ecore_Input.h do not match Ecore_IMF_Keyboard_Modifiers in Ecore_IMF.h.
107 * This function converts from Ecore_Event_Modifier to Ecore_IMF_Keyboard_Modifiers enums.
108 * @param[in] ecoreModifier the Ecore_Event_Modifier input.
109 * @return the Ecore_IMF_Keyboard_Modifiers output.
111 Ecore_IMF_Keyboard_Modifiers EcoreInputModifierToEcoreIMFModifier(unsigned int ecoreModifier)
113 int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE ); // If no other matches returns NONE.
116 if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT ) // enums from ecore_input/Ecore_Input.h
118 modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT; // enums from ecore_imf/ecore_imf.h
121 if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
123 modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
126 if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
128 modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
131 if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
133 modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
136 if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
138 modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
141 return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
145 // Copied from x server
146 static unsigned int GetCurrentMilliSeconds(void)
151 static clockid_t clockid;
155 #ifdef CLOCK_MONOTONIC_COARSE
156 if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
157 (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
159 clockid = CLOCK_MONOTONIC_COARSE;
163 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
165 clockid = CLOCK_MONOTONIC;
172 if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
174 return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
177 gettimeofday(&tv, NULL);
178 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
181 } // unnamed namespace
183 // Impl to hide EFL implementation.
184 struct EventHandler::Impl
186 // Construction & Destruction
191 Impl( EventHandler* handler, Ecore_X_Window window )
192 : mHandler( handler ),
193 mEcoreEventHandler(),
196 // Only register for touch and key events if we have a window
199 // Register Touch events
200 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_DOWN, EcoreEventMouseButtonDown, handler ) );
201 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_BUTTON_UP, EcoreEventMouseButtonUp, handler ) );
202 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_MOVE, EcoreEventMouseButtonMove, handler ) );
203 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_OUT, EcoreEventMouseButtonUp, handler ) ); // process mouse out event like up event
205 // Register Mouse wheel events
206 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_MOUSE_WHEEL, EcoreEventMouseWheel, handler ) );
208 // Register Key events
209 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_DOWN, EcoreEventKeyDown, handler ) );
210 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_EVENT_KEY_UP, EcoreEventKeyUp, handler ) );
212 // Register Focus events
213 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_IN, EcoreEventWindowFocusIn, handler ) );
214 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_FOCUS_OUT, EcoreEventWindowFocusOut, handler ) );
216 // Register Window damage events
217 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_WINDOW_DAMAGE, EcoreEventWindowDamaged, handler ) );
219 // Enable Drag & Drop and register DnD events
220 ecore_x_dnd_aware_set( window, EINA_TRUE );
221 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_ENTER, EcoreEventDndEnter, handler) );
222 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_POSITION, EcoreEventDndPosition, handler) );
223 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_LEAVE, EcoreEventDndLeave, handler) );
224 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_DROP, EcoreEventDndDrop, handler) );
225 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_FINISHED, EcoreEventDndFinished, handler) );
226 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_XDND_STATUS, EcoreEventDndStatus, handler) );
228 // Register Client message events - accessibility etc.
229 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_CLIENT_MESSAGE, EcoreEventClientMessage, handler ) );
231 // Register Selection event - clipboard selection, Drag & Drop selection etc.
232 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) );
233 mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) );
235 #ifndef DALI_PROFILE_UBUNTU
236 // Register Vconf notify - font name, font size and style
237 vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, handler );
238 vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
239 #endif // DALI_PROFILE_UBUNTU
248 #ifndef DALI_PROFILE_UBUNTU
249 vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
250 vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged );
251 #endif // DALI_PROFILE_UBUNTU
253 for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
255 ecore_event_handler_del( *iter );
261 /////////////////////////////////////////////////////////////////////////////////////////////////
263 /////////////////////////////////////////////////////////////////////////////////////////////////
266 * Called when a touch down is received.
268 static Eina_Bool EcoreEventMouseButtonDown( void* data, int type, void* event )
270 Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
271 EventHandler* handler( (EventHandler*)data );
273 if ( touchEvent->window == handler->mImpl->mWindow )
275 TouchPoint::State state ( TouchPoint::Down );
277 // Check if the buttons field is set and ensure it's the primary touch button.
278 // If this event was triggered by buttons other than the primary button (used for touch), then
279 // just send an interrupted event to Core.
280 if ( touchEvent->buttons && (touchEvent->buttons != PRIMARY_TOUCH_BUTTON_ID ) )
282 state = TouchPoint::Interrupted;
285 TouchPoint point( touchEvent->multi.device, state, touchEvent->x, touchEvent->y );
286 handler->SendEvent( point, touchEvent->timestamp );
289 return ECORE_CALLBACK_PASS_ON;
293 * Called when a touch up is received.
295 static Eina_Bool EcoreEventMouseButtonUp( void* data, int type, void* event )
297 Ecore_Event_Mouse_Button *touchEvent( (Ecore_Event_Mouse_Button*)event );
298 EventHandler* handler( (EventHandler*)data );
300 if ( touchEvent->window == handler->mImpl->mWindow )
302 TouchPoint point( touchEvent->multi.device, TouchPoint::Up, touchEvent->x, touchEvent->y );
303 handler->SendEvent( point, touchEvent->timestamp );
306 return ECORE_CALLBACK_PASS_ON;
310 * Called when a touch up is received.
312 static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
314 Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
316 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);
318 EventHandler* handler( (EventHandler*)data );
319 if ( mouseWheelEvent->window == handler->mImpl->mWindow )
321 MouseWheelEvent wheelEvent(mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp);
322 handler->SendMouseWheelEvent( wheelEvent );
324 return ECORE_CALLBACK_PASS_ON;
328 * Called when a touch motion is received.
330 static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
332 Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
333 EventHandler* handler( (EventHandler*)data );
335 if ( touchEvent->window == handler->mImpl->mWindow )
337 TouchPoint point( touchEvent->multi.device, TouchPoint::Motion, touchEvent->x, touchEvent->y );
338 handler->SendEvent( point, touchEvent->timestamp );
341 return ECORE_CALLBACK_PASS_ON;
344 /////////////////////////////////////////////////////////////////////////////////////////////////
346 /////////////////////////////////////////////////////////////////////////////////////////////////
349 * Called when a key down is received.
351 static Eina_Bool EcoreEventKeyDown( void* data, int type, void* event )
353 DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyDown \n" );
355 EventHandler* handler( (EventHandler*)data );
356 Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
357 bool eventHandled( false );
359 // If a device key then skip ecore_imf_context_filter_event.
360 if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
362 Ecore_IMF_Context* imfContext = NULL;
363 Dali::ImfManager imfManager( ImfManager::Get() );
366 imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
371 // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
372 Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
373 ecoreKeyDownEvent.keyname = keyEvent->keyname;
374 ecoreKeyDownEvent.key = keyEvent->key;
375 ecoreKeyDownEvent.string = keyEvent->string;
376 ecoreKeyDownEvent.compose = keyEvent->compose;
377 ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
378 ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
379 ecoreKeyDownEvent.locks = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
381 eventHandled = ecore_imf_context_filter_event( imfContext,
382 ECORE_IMF_EVENT_KEY_DOWN,
383 (Ecore_IMF_Event *) &ecoreKeyDownEvent );
385 // If the event has not been handled by IMF then check if we should reset our IMF context
388 if ( !strcmp( keyEvent->keyname, "Escape" ) ||
389 !strcmp( keyEvent->keyname, "Return" ) ||
390 !strcmp( keyEvent->keyname, "KP_Enter" ) )
392 ecore_imf_context_reset( imfContext );
398 // If the event wasn't handled then we should send a key event.
401 if ( keyEvent->window == handler->mImpl->mWindow )
403 std::string keyName( keyEvent->keyname );
404 std::string keyString( "" );
405 int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
406 int modifier( keyEvent->modifiers );
407 unsigned long time = keyEvent->timestamp;
409 // Ensure key event string is not NULL as keys like SHIFT have a null string.
410 if ( keyEvent->string )
412 keyString = keyEvent->string;
415 KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Down);
416 handler->SendEvent( keyEvent );
420 return ECORE_CALLBACK_PASS_ON;
424 * Called when a key up is received.
426 static Eina_Bool EcoreEventKeyUp( void* data, int type, void* event )
428 DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventKeyUp \n" );
430 EventHandler* handler( (EventHandler*)data );
431 Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
432 bool eventHandled( false );
434 // XF86Stop and XF86Send must skip ecore_imf_context_filter_event.
435 if ( strcmp( keyEvent->keyname, "XF86Send" ) &&
436 strcmp( keyEvent->keyname, "XF86Phone" ) &&
437 strcmp( keyEvent->keyname, "XF86Stop" ) )
439 Ecore_IMF_Context* imfContext = NULL;
440 Dali::ImfManager imfManager( ImfManager::Get() );
443 imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
448 // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
449 Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
450 ecoreKeyUpEvent.keyname = keyEvent->keyname;
451 ecoreKeyUpEvent.key = keyEvent->key;
452 ecoreKeyUpEvent.string = keyEvent->string;
453 ecoreKeyUpEvent.compose = keyEvent->compose;
454 ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
455 ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
456 ecoreKeyUpEvent.locks = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
458 eventHandled = ecore_imf_context_filter_event( imfContext,
459 ECORE_IMF_EVENT_KEY_UP,
460 (Ecore_IMF_Event *) &ecoreKeyUpEvent );
464 // If the event wasn't handled then we should send a key event.
467 if ( keyEvent->window == handler->mImpl->mWindow )
469 std::string keyName( keyEvent->keyname );
470 std::string keyString( "" );
471 int keyCode = ecore_x_keysym_keycode_get(keyEvent->keyname);
472 int modifier( keyEvent->modifiers );
473 unsigned long time( keyEvent->timestamp );
475 // Ensure key event string is not NULL as keys like SHIFT have a null string.
476 if ( keyEvent->string )
478 keyString = keyEvent->string;
481 KeyEvent keyEvent(keyName, keyString, keyCode, modifier, time, KeyEvent::Up);
482 handler->SendEvent( keyEvent );
487 return ECORE_CALLBACK_PASS_ON;
490 /////////////////////////////////////////////////////////////////////////////////////////////////
492 /////////////////////////////////////////////////////////////////////////////////////////////////
495 * Called when the window gains focus.
497 static Eina_Bool EcoreEventWindowFocusIn( void* data, int type, void* event )
499 Ecore_X_Event_Window_Focus_In* focusInEvent( (Ecore_X_Event_Window_Focus_In*)event );
500 EventHandler* handler( (EventHandler*)data );
502 DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusIn \n" );
504 // If the window gains focus and we hid the keyboard then show it again.
505 if ( focusInEvent->win == handler->mImpl->mWindow )
507 DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
509 if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
511 Dali::ImfManager imfManager( ImfManager::Get() );
514 ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
515 if( imfManagerImpl.RestoreAfterFocusLost() )
517 imfManagerImpl.Activate();
521 // No need to connect callbacks as KeyboardStatusChanged will be called.
524 return ECORE_CALLBACK_PASS_ON;
528 * Called when the window loses focus.
530 static Eina_Bool EcoreEventWindowFocusOut( void* data, int type, void* event )
532 Ecore_X_Event_Window_Focus_Out* focusOutEvent( (Ecore_X_Event_Window_Focus_Out*)event );
533 EventHandler* handler( (EventHandler*)data );
535 DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT >>EcoreEventWindowFocusOut \n" );
537 // If the window loses focus then hide the keyboard.
538 if ( focusOutEvent->win == handler->mImpl->mWindow )
540 if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
542 Dali::ImfManager imfManager( ImfManager::Get() );
545 ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
546 if( imfManagerImpl.RestoreAfterFocusLost() )
548 imfManagerImpl.Deactivate();
553 // Clipboard don't support that whether clipboard is shown or not. Hide clipboard.
554 Dali::Clipboard clipboard = Clipboard::Get();
555 clipboard.HideClipboard();
558 return ECORE_CALLBACK_PASS_ON;
562 * Called when the window is damaged.
564 static Eina_Bool EcoreEventWindowDamaged(void *data, int type, void *event)
566 Ecore_X_Event_Window_Damage* windowDamagedEvent( (Ecore_X_Event_Window_Damage*)event );
567 EventHandler* handler( (EventHandler*)data );
569 if( windowDamagedEvent->win == handler->mImpl->mWindow )
572 area.x = windowDamagedEvent->x;
573 area.y = windowDamagedEvent->y;
574 area.width = windowDamagedEvent->w;
575 area.height = windowDamagedEvent->h;
577 handler->SendEvent( area );
580 return ECORE_CALLBACK_PASS_ON;
584 * Called when the window properties are changed.
585 * We are only interested in the font change.
589 /////////////////////////////////////////////////////////////////////////////////////////////////
590 // Drag & Drop Callbacks
591 /////////////////////////////////////////////////////////////////////////////////////////////////
594 * Called when a dragged item enters our window's bounds.
595 * This is when items are dragged INTO our window.
597 static Eina_Bool EcoreEventDndEnter( void* data, int type, void* event )
599 DALI_LOG_INFO( gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndEnter\n" );
601 Ecore_X_Event_Xdnd_Enter* enterEvent( (Ecore_X_Event_Xdnd_Enter*) event );
602 EventHandler* handler( (EventHandler*)data );
603 Ecore_X_Window window ( handler->mImpl->mWindow );
605 if ( enterEvent->win == window )
607 DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
609 // Check whether the Drag & Drop detector has Drag & Drop behaviour enabled before we accept.
610 if ( dndDetector && dndDetector->IsEnabled() )
612 // Tell Ecore that we want to enable drop in the entire window.
613 Ecore_X_Rectangle rect;
615 ecore_x_window_geometry_get( window, NULL, NULL, (int*)&rect.width, (int*)&rect.height );
617 // Tell Ecore that we are able to process a drop.
618 ecore_x_dnd_send_status( EINA_TRUE, EINA_FALSE, rect, ECORE_X_ATOM_XDND_DROP );
620 // Register the required atoms and types.
621 ecore_x_dnd_actions_set( window, DRAG_AND_DROP_ATOMS, DRAG_AND_DROP_ATOMS_NUMBER );
622 ecore_x_dnd_types_set( window, DRAG_AND_DROP_TYPES, DRAG_AND_DROP_TYPES_NUMBER );
624 // Request to get the content from Ecore.
625 ecore_x_selection_xdnd_request( window, ECORE_X_SELECTION_TARGET_UTF8_STRING );
627 DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndEnter: Requesting Drag & Drop\n" );
629 // Clear the previous content
630 dndDetector->ClearContent();
632 // Emit the entered signal
633 dndDetector->EmitEnteredSignal();
637 return ECORE_CALLBACK_PASS_ON;
641 * Called when a dragged item is moved within our window.
642 * This is when items are dragged INTO our window.
644 static Eina_Bool EcoreEventDndPosition( void* data, int type, void* event )
646 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndPosition\n" );
648 Ecore_X_Event_Xdnd_Position* positionEvent( (Ecore_X_Event_Xdnd_Position*) event );
649 EventHandler* handler( (EventHandler*)data );
651 if ( positionEvent->win == handler->mImpl->mWindow )
653 DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
655 // If we have a detector then update its latest position.
658 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndPosition: position ( %d x %d )\n", positionEvent->position.x, positionEvent->position.y );
659 dndDetector->SetPosition( Vector2( positionEvent->position.x, positionEvent->position.y ));
660 dndDetector->EmitMovedSignal();
664 return ECORE_CALLBACK_PASS_ON;
668 * Called when a dragged item leaves our window's bounds.
669 * This is when items are dragged INTO our window.
671 static Eina_Bool EcoreEventDndLeave( void* data, int type, void* event )
673 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndLeave\n" );
675 Ecore_X_Event_Xdnd_Leave* leaveEvent( (Ecore_X_Event_Xdnd_Leave*) event );
676 EventHandler* handler( (EventHandler*)data );
678 if ( leaveEvent->win == handler->mImpl->mWindow )
680 DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
682 // If we have a detector then clear its content and emit the exited-signal. Also tell Ecore that we have finished.
685 dndDetector->ClearContent();
686 dndDetector->EmitExitedSignal();
688 ecore_x_dnd_send_finished();
690 DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndLeave: Finished\n" );
694 return ECORE_CALLBACK_PASS_ON;
698 * Called when the dragged item is dropped within our window's bounds.
699 * This is when items are dragged INTO our window.
701 static Eina_Bool EcoreEventDndDrop( void* data, int type, void* event )
703 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndDrop\n" );
705 Ecore_X_Event_Xdnd_Drop* dropEvent ( (Ecore_X_Event_Xdnd_Drop*) event);
706 EventHandler* handler( (EventHandler*)data );
708 if ( dropEvent->win == handler->mImpl->mWindow )
710 DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
712 // Something has been dropped, inform the detector (if we have one) and tell Ecore that we have finished.
715 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: position ( %d x %d )\n", dropEvent->position.x, dropEvent->position.y );
717 dndDetector->SetPosition( Vector2( dropEvent->position.x, dropEvent->position.y ) );
718 dndDetector->EmitDroppedSignal();
719 ecore_x_dnd_send_finished();
721 DALI_LOG_INFO( gDragAndDropLogFilter, Debug::General, "EcoreEventDndDrop: Finished\n" );
725 return ECORE_CALLBACK_PASS_ON;
729 * Called when a dragged item is moved from our window and the target window has done processing it.
730 * This is when items are dragged FROM our window.
732 static Eina_Bool EcoreEventDndFinished( void* data, int type, void* event )
734 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndFinished\n" );
735 return ECORE_CALLBACK_PASS_ON;
739 * Called when a dragged item is moved from our window and the target window has sent us a status.
740 * This is when items are dragged FROM our window.
742 static Eina_Bool EcoreEventDndStatus( void* data, int type, void* event )
744 DALI_LOG_INFO(gDragAndDropLogFilter, Debug::Concise, "EcoreEventDndStatus\n" );
745 return ECORE_CALLBACK_PASS_ON;
749 * Called when the client messages (i.e. the accessibility events) are received.
751 static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
753 #ifndef DALI_PROFILE_UBUNTU
754 Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
755 EventHandler* handler( (EventHandler*)data );
757 if (clientMessageEvent->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL)
759 if ( ( (unsigned int)clientMessageEvent->data.l[0] == handler->mImpl->mWindow ) && handler->mAccessibilityManager )
761 AccessibilityManager* accessibilityManager( &AccessibilityManager::GetImplementation( handler->mAccessibilityManager ) );
763 if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_SCROLL)
765 // 2 finger touch & move, 2 finger flick
767 // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
770 TouchPoint::State state(TouchPoint::Down);
772 if ((unsigned int)clientMessageEvent->data.l[2] == 0)
774 state = TouchPoint::Down; // mouse down
776 else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
778 state = TouchPoint::Motion; // mouse move
780 else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
782 state = TouchPoint::Up; // mouse up
786 state = TouchPoint::Interrupted; // error
789 DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
790 "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
791 (unsigned int)clientMessageEvent->data.l[2],
792 (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
794 // Send touch event to accessibility manager.
795 TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
797 // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
798 accessibilityManager->HandleActionScrollEvent( point, GetCurrentMilliSeconds() );
800 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_MOUSE)
802 // 1 finger double tap and hold
804 // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
807 TouchPoint::State state(TouchPoint::Down);
809 if ((unsigned int)clientMessageEvent->data.l[2] == 0)
811 state = TouchPoint::Down; // mouse down
813 else if ((unsigned int)clientMessageEvent->data.l[2] == 1)
815 state = TouchPoint::Motion; // mouse move
817 else if ((unsigned int)clientMessageEvent->data.l[2] == 2)
819 state = TouchPoint::Up; // mouse up
823 state = TouchPoint::Interrupted; // error
826 DALI_LOG_INFO(gClientMessageLogFilter, Debug::General,
827 "[%s:%d] [%d] %d, %d\n", __FUNCTION__, __LINE__,
828 (unsigned int)clientMessageEvent->data.l[2],
829 (unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4]);
831 // Send touch event to accessibility manager.
832 TouchPoint point( 0, state, (float)clientMessageEvent->data.l[3], (float)clientMessageEvent->data.l[4] );
834 // In accessibility mode, scroll action should be handled when the currently focused actor is contained in scrollable control
835 accessibilityManager->HandleActionTouchEvent( point, GetCurrentMilliSeconds() );
837 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_BACK)
839 // 2 finger circle draw, do back
840 accessibilityManager->HandleActionBackEvent();
842 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_NEXT)
844 // one finger flick down
846 if(accessibilityManager)
848 accessibilityManager->HandleActionNextEvent();
851 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_PREV)
853 // one finger flick up
854 // focus previous object
855 if(accessibilityManager)
857 accessibilityManager->HandleActionPreviousEvent();
860 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE)
862 // one finger double tap
863 // same as one finger tap in normal mode (i.e. execute focused actor)
864 if(accessibilityManager)
866 accessibilityManager->HandleActionActivateEvent();
869 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ)
872 // focus & read an actor at ( e->data.l[2], e->data.l[3] ) position according to finger
873 if(accessibilityManager)
875 accessibilityManager->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[2], (unsigned int)clientMessageEvent->data.l[3], true /* allow read again*/);
878 #if defined(DALI_PROFILE_MOBILE)
879 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER)
881 // one finger tap & move
882 // mouse state : e->data.l[2] (0: mouse down, 1: mouse move, 2: mouse up)
885 // focus & read an actor at (x, y) position according to finger
886 if(accessibilityManager && (unsigned int)clientMessageEvent->data.l[2] == 1 /*only work for move event*/)
888 accessibilityManager->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[3], (unsigned int)clientMessageEvent->data.l[4], false /* not allow read again*/);
892 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_NEXT)
894 // one finger flick right
896 if(accessibilityManager)
898 accessibilityManager->HandleActionReadNextEvent();
901 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ_PREV)
903 // one finger flick left
904 // focus previous object
905 if(accessibilityManager)
907 accessibilityManager->HandleActionReadPreviousEvent();
910 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_UP)
912 // double down and move (right, up)
913 // change slider value
914 if(accessibilityManager)
916 accessibilityManager->HandleActionUpEvent();
919 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DOWN)
921 // double down and move (left, down)
922 // change slider value
923 if(accessibilityManager)
925 accessibilityManager->HandleActionDownEvent();
928 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ENABLE)
930 if(accessibilityManager)
932 accessibilityManager->HandleActionEnableEvent();
935 else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_DISABLE)
937 if(accessibilityManager)
939 accessibilityManager->HandleActionDisableEvent();
942 // TODO: some more actions could be added later
945 else if(clientMessageEvent->message_type == ecore_x_atom_get(CLIPBOARD_ATOM))
947 std::string message(clientMessageEvent->data.b);
948 if( message == CLIPBOARD_SET_OWNER_MESSAGE)
950 // Claim the ownership of the SECONDARY selection.
951 ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
953 // Show the clipboard window
954 Dali::Clipboard clipboard = Dali::Clipboard::Get();
955 clipboard.ShowClipboard();
958 else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE )
960 RotationEvent rotationEvent;
961 rotationEvent.angle = static_cast<int>(clientMessageEvent->data.l[1]);
962 rotationEvent.winResize = static_cast<int>(clientMessageEvent->data.l[2]);
963 rotationEvent.width = static_cast<int>(clientMessageEvent->data.l[3]);
964 rotationEvent.height = static_cast<int>(clientMessageEvent->data.l[4]);
965 handler->SendRotationPrepareEvent( rotationEvent );
967 else if( clientMessageEvent->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_REQUEST )
969 handler->SendRotationRequestEvent();
972 #endif // DALI_PROFILE_UBUNTU
973 return ECORE_CALLBACK_PASS_ON;
977 * Called when the source window notifies us the content in clipboard is selected.
979 static Eina_Bool EcoreEventSelectionClear( void* data, int type, void* event )
981 DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionClear\n" );
982 Ecore_X_Event_Selection_Clear* selectionClearEvent( (Ecore_X_Event_Selection_Clear*) event );
983 EventHandler* handler( (EventHandler*)data );
985 if ( selectionClearEvent->win == handler->mImpl->mWindow )
987 if ( selectionClearEvent->selection == ECORE_X_SELECTION_SECONDARY )
989 // Request to get the content from Ecore.
990 ecore_x_selection_secondary_request(selectionClearEvent->win, ECORE_X_SELECTION_TARGET_TEXT);
993 return ECORE_CALLBACK_PASS_ON;
997 * Called when the source window sends us about the selected content.
998 * For example, when dragged items are dragged INTO our window or when items are selected in the clipboard.
1000 static Eina_Bool EcoreEventSelectionNotify( void* data, int type, void* event )
1002 DALI_LOG_INFO(gSelectionEventLogFilter, Debug::Concise, "EcoreEventSelectionNotify\n" );
1004 Ecore_X_Event_Selection_Notify* selectionNotifyEvent( (Ecore_X_Event_Selection_Notify*) event );
1005 EventHandler* handler( (EventHandler*)data );
1007 if ( selectionNotifyEvent->win == handler->mImpl->mWindow )
1009 Ecore_X_Selection_Data* selectionData( (Ecore_X_Selection_Data*) selectionNotifyEvent->data );
1010 if ( selectionData->data )
1012 if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_XDND )
1014 DragAndDropDetectorPtr dndDetector( handler->mDragAndDropDetector );
1016 // We have got the content that is to be dropped, inform the DndListener (if we have one).
1019 std::string content( (char*) selectionData->data, selectionData->length );
1020 dndDetector->SetContent( content );
1022 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1023 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1024 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1025 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1028 else if ( selectionNotifyEvent->selection == ECORE_X_SELECTION_SECONDARY )
1030 // We have got the selected content, inform the clipboard event listener (if we have one).
1031 if ( handler->mClipboardEventNotifier )
1033 ClipboardEventNotifier& clipboardEventNotifier( ClipboardEventNotifier::GetImplementation( handler->mClipboardEventNotifier ) );
1034 std::string content( (char*) selectionData->data, selectionData->length );
1035 clipboardEventNotifier.SetContent( content );
1036 clipboardEventNotifier.EmitContentSelectedSignal();
1039 // Claim the ownership of the SECONDARY selection.
1040 ecore_x_selection_secondary_set(handler->mImpl->mWindow, "", 1);
1042 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "EcoreEventSelectionNotify: Content(%d):\n" , selectionData->length );
1043 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1044 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "%s\n", selectionData->data );
1045 DALI_LOG_INFO( gSelectionEventLogFilter, Debug::General, "======================================\n" );
1049 return ECORE_CALLBACK_PASS_ON;
1053 #ifndef DALI_PROFILE_UBUNTU
1054 /////////////////////////////////////////////////////////////////////////////////////////////////
1056 /////////////////////////////////////////////////////////////////////////////////////////////////
1058 * Called when a font name is changed.
1060 static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
1062 EventHandler* handler = static_cast<EventHandler*>( data );
1064 StyleChange fontChange;
1065 fontChange.defaultFontChange = true;
1067 handler->SendEvent( fontChange );
1071 * Called when a font size is changed.
1073 static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
1075 EventHandler* handler = static_cast<EventHandler*>( data );
1077 StyleChange fontChange;
1078 fontChange.defaultFontSizeChange = true;
1080 handler->SendEvent( fontChange );
1082 #endif // DALI_PROFILE_UBUNTU
1085 EventHandler* mHandler;
1086 std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
1087 Ecore_X_Window mWindow;
1090 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
1091 : mCoreEventInterface(coreEventInterface),
1092 mGestureManager( gestureManager ),
1093 mStyleMonitor( StyleMonitor::Get() ),
1094 mDamageObserver( damageObserver ),
1095 mRotationObserver( NULL ),
1096 mDragAndDropDetector( dndDetector ),
1097 mAccessibilityManager( AccessibilityManager::Get() ),
1098 mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
1099 mClipboard(Clipboard::Get()),
1102 Ecore_X_Window window = 0;
1104 // this code only works with the EcoreX11 RenderSurface so need to downcast
1105 ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
1108 // enable multi touch
1109 window = ecoreSurface->GetXWindow();
1112 mImpl = new Impl(this, window);
1115 EventHandler::~EventHandler()
1122 mGestureManager.Stop();
1125 void EventHandler::SendEvent(TouchPoint& point, unsigned long timeStamp)
1129 timeStamp = GetCurrentMilliSeconds();
1132 Integration::TouchEvent touchEvent;
1133 Integration::HoverEvent hoverEvent;
1134 Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
1135 if(type != Integration::TouchEventCombiner::DispatchNone )
1137 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);
1139 // First the touch and/or hover event & related gesture events are queued
1140 if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
1142 mCoreEventInterface.QueueCoreEvent( touchEvent );
1143 mGestureManager.SendEvent(touchEvent);
1146 if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
1148 mCoreEventInterface.QueueCoreEvent( hoverEvent );
1151 // Next the events are processed with a single call into Core
1152 mCoreEventInterface.ProcessCoreEvents();
1156 void EventHandler::SendEvent(KeyEvent& keyEvent)
1158 Dali::PhysicalKeyboard physicalKeyboard = PhysicalKeyboard::Get();
1159 if ( physicalKeyboard )
1161 if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ) )
1163 GetImplementation( physicalKeyboard ).KeyReceived( keyEvent.time > 1 );
1167 // Create KeyEvent and send to Core.
1168 Integration::KeyEvent event(keyEvent.keyPressedName, keyEvent.keyPressed, keyEvent.keyCode,
1169 keyEvent.keyModifier, keyEvent.time, static_cast<Integration::KeyEvent::State>(keyEvent.state));
1170 mCoreEventInterface.QueueCoreEvent( event );
1171 mCoreEventInterface.ProcessCoreEvents();
1174 void EventHandler::SendMouseWheelEvent( MouseWheelEvent& wheelEvent )
1176 // Create MouseWheelEvent and send to Core.
1177 Integration::MouseWheelEvent event(wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp);
1178 mCoreEventInterface.QueueCoreEvent( event );
1179 mCoreEventInterface.ProcessCoreEvents();
1182 void EventHandler::SendEvent(StyleChange styleChange)
1184 DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
1185 GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
1188 void EventHandler::SendEvent( const DamageArea& area )
1190 mDamageObserver.OnDamaged( area );
1193 void EventHandler::SendRotationPrepareEvent( const RotationEvent& event )
1195 if( mRotationObserver != NULL )
1197 mRotationObserver->OnRotationPrepare( event );
1201 void EventHandler::SendRotationRequestEvent( )
1203 if( mRotationObserver != NULL )
1205 mRotationObserver->OnRotationRequest( );
1209 void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
1211 SendEvent(point, timeStamp);
1214 void EventHandler::FeedWheelEvent( MouseWheelEvent& wheelEvent )
1216 SendMouseWheelEvent( wheelEvent );
1219 void EventHandler::FeedKeyEvent( KeyEvent& event )
1224 void EventHandler::FeedEvent( Integration::Event& event )
1226 mCoreEventInterface.QueueCoreEvent( event );
1227 mCoreEventInterface.ProcessCoreEvents();
1230 void EventHandler::Reset()
1234 // Any touch listeners should be told of the interruption.
1235 Integration::TouchEvent event;
1236 TouchPoint point(0, TouchPoint::Interrupted, 0, 0);
1237 event.AddPoint( point );
1239 // First the touch event & related gesture events are queued
1240 mCoreEventInterface.QueueCoreEvent( event );
1241 mGestureManager.SendEvent( event );
1243 // Next the events are processed with a single call into Core
1244 mCoreEventInterface.ProcessCoreEvents();
1247 void EventHandler::SetDragAndDropDetector( DragAndDropDetectorPtr detector )
1249 mDragAndDropDetector = detector;
1252 void EventHandler::SetRotationObserver( RotationObserver* observer )
1254 mRotationObserver = observer;
1257 } // namespace Adaptor
1259 } // namespace Internal