Revert "[3.0] Change key names according to changes of utilX"
[platform/core/uifw/dali-adaptor.git] / adaptors / x11 / event-handler-x.cpp
index bd89e51..090cd0f 100644 (file)
 #include <Ecore_Input.h>
 #include <Ecore_X.h>
 
+#include <X11/Xlib.h>
+#include <X11/extensions/XInput2.h>
+#include <X11/extensions/XI2.h>
+
 #include <cstring>
 
 #include <sys/time.h>
 
+#ifndef DALI_PROFILE_UBUNTU
 #include <vconf.h>
 #include <vconf-keys.h>
+#endif // DALI_PROFILE_UBUNTU
 
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/events/touch-point.h>
 #include <dali/public-api/events/key-event.h>
-#include <dali/public-api/events/mouse-wheel-event.h>
+#include <dali/public-api/events/wheel-event.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/events/key-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
-#include <dali/integration-api/events/mouse-wheel-event-integ.h>
+#include <dali/integration-api/events/hover-event-integ.h>
+#include <dali/integration-api/events/wheel-event-integ.h>
 
 // INTERNAL INCLUDES
 #include <events/gesture-manager.h>
@@ -48,8 +55,6 @@
 #include <style-monitor-impl.h>
 #include <base/core-event-interface.h>
 
-using namespace std;
-
 namespace Dali
 {
 
@@ -73,41 +78,19 @@ Integration::Log::Filter* gSelectionEventLogFilter = Integration::Log::Filter::N
 
 namespace
 {
-const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced.
-
-// Currently this code is internal to dali/dali/internal/event/text/utf8.h but should be made Public and used from there instead.
-size_t Utf8SequenceLength(const unsigned char leadByte)
-{
-  size_t length = 0;
 
-  if ((leadByte & 0x80) == 0 )          //ASCII character (lead bit zero)
-  {
-    length = 1;
-  }
-  else if (( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
-  {
-    length = 2;
-  }
-  else if (( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
-  {
-    length = 3;
-  }
-  else if (( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
-  {
-    length = 4;
-  }
-  else
-  {
-    DALI_LOG_WARNING("Unrecognized lead byte  %c\n", leadByte);
-  }
+const char * DETENT_DEVICE_NAME = "tizen_detent";
 
-  return length;
-}
+#ifndef DALI_PROFILE_UBUNTU
+const char * DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME = "db/setting/accessibility/font_name"; // It will be update at vconf-key.h and replaced.
+#endif // DALI_PROFILE_UBUNTU
 
 const unsigned int PRIMARY_TOUCH_BUTTON_ID( 1 );
 
+#ifndef DALI_PROFILE_UBUNTU
 const char * CLIPBOARD_ATOM                = "CBHM_MSG";
 const char * CLIPBOARD_SET_OWNER_MESSAGE   = "SET_OWNER";
+#endif // DALI_PROFILE_UBUNTU
 
 /// The atoms required by Ecore for Drag & Drop behaviour.
 Ecore_X_Atom DRAG_AND_DROP_ATOMS[] =
@@ -215,7 +198,8 @@ struct EventHandler::Impl
   Impl( EventHandler* handler, Ecore_X_Window window )
   : mHandler( handler ),
     mEcoreEventHandler(),
-    mWindow( window )
+    mWindow( window ),
+    mXiDeviceId( 0 )
   {
     // Only register for touch and key events if we have a window
     if ( window != 0 )
@@ -256,12 +240,75 @@ struct EventHandler::Impl
       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_CLEAR, EcoreEventSelectionClear, handler ) );
       mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_SELECTION_NOTIFY, EcoreEventSelectionNotify, handler ) );
 
+      // Initialize Xi2 system
+      Display* display = static_cast< Display* >(ecore_x_display_get());
+      Ecore_X_Window rootWindow = ecore_x_window_root_first_get();
+      int opcode = 0, event = 0, error = 0;
+      int major = XI_2_Major;
+      int minor = XI_2_Minor;
+      int deviceCount = 0;
+      XIEventMask xiEventMask;
+
+      // Check if X input extension available
+      if( XQueryExtension( display, "XInputExtension", &opcode, &event, &error ) )
+      {
+        // We support version 2.0
+        if( XIQueryVersion( display, &major, &minor ) != BadRequest )
+        {
+          xiEventMask.deviceid = XIAllDevices;
+
+          // Check device id
+          bool match = false;
+          XIDeviceInfo* deviceInfo = NULL;
+          deviceInfo = XIQueryDevice( display, XIAllDevices, &deviceCount );
+
+          for( int i = 0; i < deviceCount; i++ )
+          {
+            if( !strncmp( deviceInfo[i].name, DETENT_DEVICE_NAME, strlen( DETENT_DEVICE_NAME ) ) )
+            {
+              xiEventMask.deviceid = deviceInfo[i].deviceid;
+              match = true;
+              break;
+            }
+          }
+
+          if( match )
+          {
+            mXiDeviceId = xiEventMask.deviceid;
+
+            // SelectXi2Event
+            xiEventMask.mask = (unsigned char*)(calloc( 1, XIMaskLen( XI_LASTEVENT ) ) );
+            XISetMask( xiEventMask.mask, XI_RawMotion );
+
+            xiEventMask.mask_len = sizeof( xiEventMask.mask );
+
+            int ret = XISelectEvents( display, rootWindow, &xiEventMask, 1 );
+            if( ret == 0 )
+            {
+              // Register custom wheel events
+              mEcoreEventHandler.push_back( ecore_event_handler_add( ECORE_X_EVENT_GENERIC, EcoreEventCustomWheel, handler ) );
+            }
+            else
+            {
+              DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to Select Events\n" );
+            }
+          }
+        }
+        else
+        {
+          DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XI Version\n" );
+        }
+      }
+      else
+      {
+        DALI_LOG_INFO( gImfLogging, Debug::General, "Failed to query XInputExtension\n" );
+      }
+
+#ifndef DALI_PROFILE_UBUNTU
       // Register Vconf notify - font name, font size and style
       vconf_notify_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, handler );
       vconf_notify_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, handler );
-#if defined(DALI_PROFILE_MOBILE)
-      vconf_notify_key_changed( VCONFKEY_SETAPPL_CHANGE_UI_THEME_INT, VconfNotifyThemeChanged, handler );
-#endif
+#endif // DALI_PROFILE_UBUNTU
     }
   }
 
@@ -270,11 +317,10 @@ struct EventHandler::Impl
    */
   ~Impl()
   {
-#if defined(DALI_PROFILE_MOBILE)
-    vconf_ignore_key_changed( VCONFKEY_SETAPPL_CHANGE_UI_THEME_INT, VconfNotifyThemeChanged );
-#endif
+#ifndef DALI_PROFILE_UBUNTU
     vconf_ignore_key_changed( VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged );
     vconf_ignore_key_changed( DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged );
+#endif // DALI_PROFILE_UBUNTU
 
     for( std::vector<Ecore_Event_Handler*>::iterator iter = mEcoreEventHandler.begin(), endIter = mEcoreEventHandler.end(); iter != endIter; ++iter )
     {
@@ -333,35 +379,98 @@ struct EventHandler::Impl
   }
 
   /**
-   * Called when a touch up is received.
+   * Called when a touch motion is received.
+   */
+  static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
+  {
+    Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
+    EventHandler* handler( (EventHandler*)data );
+
+    if ( touchEvent->window == handler->mImpl->mWindow )
+    {
+      TouchPoint point( touchEvent->multi.device, TouchPoint::Motion, touchEvent->x, touchEvent->y );
+      handler->SendEvent( point, touchEvent->timestamp );
+    }
+
+    return ECORE_CALLBACK_PASS_ON;
+  }
+
+  /////////////////////////////////////////////////////////////////////////////////////////////////
+  // Wheel Callbacks
+  /////////////////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Called when a mouse wheel is received.
    */
   static Eina_Bool EcoreEventMouseWheel( void* data, int type, void* event )
   {
     Ecore_Event_Mouse_Wheel *mouseWheelEvent( (Ecore_Event_Mouse_Wheel*)event );
 
-    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);
+    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 );
 
     EventHandler* handler( (EventHandler*)data );
     if ( mouseWheelEvent->window == handler->mImpl->mWindow )
     {
-      MouseWheelEvent wheelEvent(mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp);
-      handler->SendMouseWheelEvent( wheelEvent );
+      WheelEvent wheelEvent( WheelEvent::MOUSE_WHEEL, mouseWheelEvent->direction, mouseWheelEvent->modifiers, Vector2(mouseWheelEvent->x, mouseWheelEvent->y), mouseWheelEvent->z, mouseWheelEvent->timestamp );
+      handler->SendWheelEvent( wheelEvent );
     }
     return ECORE_CALLBACK_PASS_ON;
   }
 
   /**
-   * Called when a touch motion is received.
+   * Called when a custom wheel is received.
    */
-  static Eina_Bool EcoreEventMouseButtonMove( void* data, int type, void* event )
+  static Eina_Bool EcoreEventCustomWheel( void* data, int type, void* event )
   {
-    Ecore_Event_Mouse_Move *touchEvent( (Ecore_Event_Mouse_Move*)event );
+    Ecore_X_Event_Generic *genericEvent( (Ecore_X_Event_Generic*)event );
     EventHandler* handler( (EventHandler*)data );
 
-    if ( touchEvent->window == handler->mImpl->mWindow )
+    switch( genericEvent->evtype )
     {
-      TouchPoint point( touchEvent->multi.device, TouchPoint::Motion, touchEvent->x, touchEvent->y );
-      handler->SendEvent( point, touchEvent->timestamp );
+      case XI_RawMotion:
+      {
+        XIRawEvent* xiRawEvent = static_cast< XIRawEvent* >( genericEvent->data );
+        unsigned int timeStamp = 0;
+
+        if( xiRawEvent->deviceid != handler->mImpl->mXiDeviceId )
+        {
+          return ECORE_CALLBACK_PASS_ON;
+        }
+
+        // X(0): rotate: NOT USED
+        // Y(1): timestamp
+        // Z(2): direction
+
+        double* value = xiRawEvent->raw_values;
+
+        if( XIMaskIsSet( xiRawEvent->valuators.mask, 1) )
+        {
+          timeStamp = static_cast< unsigned int >( *(value + 1) );
+        }
+
+        if( XIMaskIsSet( xiRawEvent->valuators.mask, 2) )
+        {
+          // if z == 1, clockwise
+          // otherwise counter-clockwise
+          int z = static_cast< int >( *(value + 2) );
+
+          // In DALi, positive value means clockwise, and negative value means counter-clockwise
+          if( z == 0 )
+          {
+            z = -1;
+          }
+
+          DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventCustomWheel: z: %d\n", z );
+
+          WheelEvent wheelEvent( WheelEvent::CUSTOM_WHEEL, 0, 0, Vector2(0.0f, 0.0f), z, timeStamp );
+          handler->SendWheelEvent( wheelEvent );
+        }
+        break;
+      }
+      default:
+      {
+        break;
+      }
     }
 
     return ECORE_CALLBACK_PASS_ON;
@@ -382,37 +491,41 @@ struct EventHandler::Impl
     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
     bool eventHandled( false );
 
-    Ecore_IMF_Context* imfContext = NULL;
-    if ( Dali::Adaptor::IsAvailable() && handler->mImfManager )
-    {
-      imfContext = reinterpret_cast<Ecore_IMF_Context*>( handler->mImfManager.GetContext() );
-    }
-
     // If a device key then skip ecore_imf_context_filter_event.
-    if ( imfContext && !( KeyLookup::IsDeviceButton( keyEvent->keyname ) ) )
+    if ( ! KeyLookup::IsDeviceButton( keyEvent->keyname ) )
     {
-      // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
-      Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
-      ecoreKeyDownEvent.keyname   = keyEvent->keyname;
-      ecoreKeyDownEvent.key       = keyEvent->key;
-      ecoreKeyDownEvent.string    = keyEvent->string;
-      ecoreKeyDownEvent.compose   = keyEvent->compose;
-      ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
-      ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
-      ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
-
-      eventHandled = ecore_imf_context_filter_event( imfContext,
-                                                     ECORE_IMF_EVENT_KEY_DOWN,
-                                                     (Ecore_IMF_Event *) &ecoreKeyDownEvent );
-
-      // If the event has not been handled by IMF then check if we should reset our IMF context
-      if( !eventHandled )
+      Ecore_IMF_Context* imfContext = NULL;
+      Dali::ImfManager imfManager( ImfManager::Get() );
+      if ( imfManager )
       {
-        if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
-             !strcmp( keyEvent->keyname, "Return"   ) ||
-             !strcmp( keyEvent->keyname, "KP_Enter" ) )
+        imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
+      }
+
+      if ( imfContext )
+      {
+        // We're consuming key down event so we have to pass to IMF so that it can parse it as well.
+        Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
+        ecoreKeyDownEvent.keyname   = keyEvent->keyname;
+        ecoreKeyDownEvent.key       = keyEvent->key;
+        ecoreKeyDownEvent.string    = keyEvent->string;
+        ecoreKeyDownEvent.compose   = keyEvent->compose;
+        ecoreKeyDownEvent.timestamp = keyEvent->timestamp;
+        ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
+        ecoreKeyDownEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
+
+        eventHandled = ecore_imf_context_filter_event( imfContext,
+                                                       ECORE_IMF_EVENT_KEY_DOWN,
+                                                       (Ecore_IMF_Event *) &ecoreKeyDownEvent );
+
+        // If the event has not been handled by IMF then check if we should reset our IMF context
+        if( !eventHandled )
         {
-          ecore_imf_context_reset( imfContext );
+          if ( !strcmp( keyEvent->keyname, "Escape"   ) ||
+               !strcmp( keyEvent->keyname, "Return"   ) ||
+               !strcmp( keyEvent->keyname, "KP_Enter" ) )
+          {
+            ecore_imf_context_reset( imfContext );
+          }
         }
       }
     }
@@ -453,29 +566,34 @@ struct EventHandler::Impl
     Ecore_Event_Key *keyEvent( (Ecore_Event_Key*)event );
     bool eventHandled( false );
 
-    Ecore_IMF_Context* imfContext = NULL;
-    if ( Dali::Adaptor::IsAvailable() && handler->mImfManager )
-    {
-      imfContext = reinterpret_cast<Ecore_IMF_Context*>( handler->mImfManager.GetContext() );
-    }
-
     // XF86Stop and XF86Send must skip ecore_imf_context_filter_event.
-    if ( imfContext && strcmp( keyEvent->keyname, "XF86Send" ) && strcmp( keyEvent->keyname, "XF86Phone" ) && strcmp( keyEvent->keyname, "XF86Stop" ) )
-
+    if ( strcmp( keyEvent->keyname, "XF86Send"  ) &&
+         strcmp( keyEvent->keyname, "XF86Phone" ) &&
+         strcmp( keyEvent->keyname, "XF86Stop"  ) )
     {
-      // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
-      Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
-      ecoreKeyUpEvent.keyname   = keyEvent->keyname;
-      ecoreKeyUpEvent.key       = keyEvent->key;
-      ecoreKeyUpEvent.string    = keyEvent->string;
-      ecoreKeyUpEvent.compose   = keyEvent->compose;
-      ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
-      ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
-      ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
-
-      eventHandled = ecore_imf_context_filter_event( imfContext,
-                                                     ECORE_IMF_EVENT_KEY_UP,
-                                                     (Ecore_IMF_Event *) &ecoreKeyUpEvent );
+      Ecore_IMF_Context* imfContext = NULL;
+      Dali::ImfManager imfManager( ImfManager::Get() );
+      if ( imfManager )
+      {
+        imfContext = reinterpret_cast<Ecore_IMF_Context*>( imfManager.GetContext() );
+      }
+
+      if ( imfContext )
+      {
+        // We're consuming key up event so we have to pass to IMF so that it can parse it as well.
+        Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
+        ecoreKeyUpEvent.keyname   = keyEvent->keyname;
+        ecoreKeyUpEvent.key       = keyEvent->key;
+        ecoreKeyUpEvent.string    = keyEvent->string;
+        ecoreKeyUpEvent.compose   = keyEvent->compose;
+        ecoreKeyUpEvent.timestamp = keyEvent->timestamp;
+        ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier ( keyEvent->modifiers );
+        ecoreKeyUpEvent.locks     = (Ecore_IMF_Keyboard_Locks) ECORE_IMF_KEYBOARD_LOCK_NONE;
+
+        eventHandled = ecore_imf_context_filter_event( imfContext,
+                                                       ECORE_IMF_EVENT_KEY_UP,
+                                                       (Ecore_IMF_Event *) &ecoreKeyUpEvent );
+      }
     }
 
     // If the event wasn't handled then we should send a key event.
@@ -523,12 +641,16 @@ struct EventHandler::Impl
     {
       DALI_LOG_INFO( gImfLogging, Debug::General, "EVENT EcoreEventWindowFocusIn - >>WindowFocusGained \n" );
 
-      if ( handler->mImfManager )
+      if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
       {
-        ImfManager& imfManager( ImfManager::GetImplementation( handler->mImfManager ) );
-        if( imfManager.RestoreAfterFocusLost() )
+        Dali::ImfManager imfManager( ImfManager::Get() );
+        if ( imfManager )
         {
-          imfManager.Activate();
+          ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
+          if( imfManagerImpl.RestoreAfterFocusLost() )
+          {
+            imfManagerImpl.Activate();
+          }
         }
       }
       // No need to connect callbacks as KeyboardStatusChanged will be called.
@@ -550,12 +672,16 @@ struct EventHandler::Impl
     // If the window loses focus then hide the keyboard.
     if ( focusOutEvent->win == handler->mImpl->mWindow )
     {
-      if ( handler->mImfManager )
+      if ( ImfManager::IsAvailable() /* Only get the ImfManager if it's available as we do not want to create it */ )
       {
-        ImfManager& imfManager( ImfManager::GetImplementation( handler->mImfManager ) );
-        if( imfManager.RestoreAfterFocusLost() )
+        Dali::ImfManager imfManager( ImfManager::Get() );
+        if ( imfManager )
         {
-          imfManager.Deactivate();
+          ImfManager& imfManagerImpl( ImfManager::GetImplementation( imfManager ) );
+          if( imfManagerImpl.RestoreAfterFocusLost() )
+          {
+            imfManagerImpl.Deactivate();
+          }
         }
       }
 
@@ -759,6 +885,7 @@ struct EventHandler::Impl
    */
   static Eina_Bool EcoreEventClientMessage( void* data, int type, void* event )
   {
+#ifndef DALI_PROFILE_UBUNTU
     Ecore_X_Event_Client_Message* clientMessageEvent( (Ecore_X_Event_Client_Message*)event );
     EventHandler* handler( (EventHandler*)data );
 
@@ -883,7 +1010,7 @@ struct EventHandler::Impl
             accessibilityManager->HandleActionReadEvent((unsigned int)clientMessageEvent->data.l[2], (unsigned int)clientMessageEvent->data.l[3], true /* allow read again*/);
           }
         }
-#if defined(DALI_PROFILE_MOBILE) || defined(DALI_PROFILE_TV)
+#if defined(DALI_PROFILE_MOBILE)
         else if((unsigned int)clientMessageEvent->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_OVER)
         {
           // one finger tap & move
@@ -977,6 +1104,7 @@ struct EventHandler::Impl
       handler->SendRotationRequestEvent();
     }
 
+#endif // DALI_PROFILE_UBUNTU
     return ECORE_CALLBACK_PASS_ON;
   }
 
@@ -1056,6 +1184,8 @@ struct EventHandler::Impl
     return ECORE_CALLBACK_PASS_ON;
   }
 
+
+#ifndef DALI_PROFILE_UBUNTU
   /////////////////////////////////////////////////////////////////////////////////////////////////
   // Font Callbacks
   /////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1065,11 +1195,7 @@ struct EventHandler::Impl
   static void VconfNotifyFontNameChanged( keynode_t* node, void* data )
   {
     EventHandler* handler = static_cast<EventHandler*>( data );
-
-    StyleChange fontChange;
-    fontChange.defaultFontChange = true;
-
-    handler->SendEvent( fontChange );
+    handler->SendEvent( StyleChange::DEFAULT_FONT_CHANGE );
   }
 
   /**
@@ -1078,30 +1204,15 @@ struct EventHandler::Impl
   static void VconfNotifyFontSizeChanged( keynode_t* node, void* data )
   {
     EventHandler* handler = static_cast<EventHandler*>( data );
-
-    StyleChange fontChange;
-    fontChange.defaultFontSizeChange = true;
-
-    handler->SendEvent( fontChange );
-  }
-
-  /**
-   * Called when style is changed
-   */
-  static void VconfNotifyThemeChanged( keynode_t* node, void* data )
-  {
-    EventHandler* handler( static_cast<EventHandler*>(data) );
-
-    StyleChange themeChange;
-    themeChange.themeChange = true;
-
-    handler->SendEvent( themeChange );
+    handler->SendEvent( StyleChange::DEFAULT_FONT_SIZE_CHANGE );
   }
+#endif // DALI_PROFILE_UBUNTU
 
   // Data
   EventHandler* mHandler;
   std::vector<Ecore_Event_Handler*> mEcoreEventHandler;
   Ecore_X_Window mWindow;
+  int mXiDeviceId;
 };
 
 EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEventInterface, GestureManager& gestureManager, DamageObserver& damageObserver, DragAndDropDetectorPtr dndDetector )
@@ -1114,21 +1225,16 @@ EventHandler::EventHandler( RenderSurface* surface, CoreEventInterface& coreEven
   mAccessibilityManager( AccessibilityManager::Get() ),
   mClipboardEventNotifier( ClipboardEventNotifier::Get() ),
   mClipboard(Clipboard::Get()),
-  mImfManager( ImfManager::Get() ),
   mImpl( NULL )
 {
   Ecore_X_Window window = 0;
 
-  if( surface->GetType() == Dali::RenderSurface::WINDOW )
+  // this code only works with the EcoreX11 RenderSurface so need to downcast
+  ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
+  if( ecoreSurface )
   {
-    // this code only works with the EcoreX11 RenderSurface so need to downcast
-    ECore::WindowRenderSurface* ecoreSurface = dynamic_cast< ECore::WindowRenderSurface* >( surface );
-    if( ecoreSurface )
-    {
-      // enable multi touch
-      window = ecoreSurface->GetXWindow();
-      ecore_x_input_multi_select( window );
-    }
+    // enable multi touch
+    window = ecoreSurface->GetXWindow();
   }
 
   mImpl = new Impl(this, window);
@@ -1151,14 +1257,24 @@ void EventHandler::SendEvent(TouchPoint& point, unsigned long timeStamp)
     timeStamp = GetCurrentMilliSeconds();
   }
 
-  Integration::TouchEvent event;
-  if (mCombiner.GetNextTouchEvent(point, timeStamp, event))
+  Integration::TouchEvent touchEvent;
+  Integration::HoverEvent hoverEvent;
+  Integration::TouchEventCombiner::EventDispatchType type = mCombiner.GetNextTouchEvent(point, timeStamp, touchEvent, hoverEvent);
+  if(type != Integration::TouchEventCombiner::DispatchNone )
   {
     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);
 
-    // First the touch event & related gesture events are queued
-    mCoreEventInterface.QueueCoreEvent( event );
-    mGestureManager.SendEvent(event);
+    // First the touch and/or hover event & related gesture events are queued
+    if(type == Integration::TouchEventCombiner::DispatchTouch || type == Integration::TouchEventCombiner::DispatchBoth)
+    {
+      mCoreEventInterface.QueueCoreEvent( touchEvent );
+      mGestureManager.SendEvent(touchEvent);
+    }
+
+    if(type == Integration::TouchEventCombiner::DispatchHover || type == Integration::TouchEventCombiner::DispatchBoth)
+    {
+      mCoreEventInterface.QueueCoreEvent( hoverEvent );
+    }
 
     // Next the events are processed with a single call into Core
     mCoreEventInterface.ProcessCoreEvents();
@@ -1183,15 +1299,15 @@ void EventHandler::SendEvent(KeyEvent& keyEvent)
   mCoreEventInterface.ProcessCoreEvents();
 }
 
-void EventHandler::SendMouseWheelEvent( MouseWheelEvent& wheelEvent )
+void EventHandler::SendWheelEvent( WheelEvent& wheelEvent )
 {
-  // Create MouseWheelEvent and send to Core.
-  Integration::MouseWheelEvent event(wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp);
+  // Create WheelEvent and send to Core.
+  Integration::WheelEvent event( static_cast< Integration::WheelEvent::Type >(wheelEvent.type), wheelEvent.direction, wheelEvent.modifiers, wheelEvent.point, wheelEvent.z, wheelEvent.timeStamp );
   mCoreEventInterface.QueueCoreEvent( event );
   mCoreEventInterface.ProcessCoreEvents();
 }
 
-void EventHandler::SendEvent(StyleChange styleChange)
+void EventHandler::SendEvent( StyleChange::Type styleChange )
 {
   DALI_ASSERT_DEBUG( mStyleMonitor && "StyleMonitor Not Available" );
   GetImplementation( mStyleMonitor ).StyleChanged(styleChange);
@@ -1223,9 +1339,9 @@ void EventHandler::FeedTouchPoint( TouchPoint& point, int timeStamp)
   SendEvent(point, timeStamp);
 }
 
-void EventHandler::FeedWheelEvent( MouseWheelEvent& wheelEvent )
+void EventHandler::FeedWheelEvent( WheelEvent& wheelEvent )
 {
-  SendMouseWheelEvent( wheelEvent );
+  SendWheelEvent( wheelEvent );
 }
 
 void EventHandler::FeedKeyEvent( KeyEvent& event )