Add new input event framework
authorFrédéric Blain <frederic.blain@valeo.com>
Fri, 6 Jul 2012 13:30:35 +0000 (15:30 +0200)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Fri, 20 Jul 2012 07:07:16 +0000 (00:07 -0700)
This patch adds the new input event framework to LayerManager:
 + InputManager : New class created to centralized all input management.
 + Irenderer: New method getInputManager() has been added. Will be used later on by LM commands to access to InputManager
 + BaseRenderer: Instanciate automatically the InputManager to be used by concrete renderer.
 + BaseWindowSystem: New attribute to hold a pointer to the InputManager. This pointer is filled at construct time. Concrete WindowSystems will receive the InputManager from their concrete renderer.
 + GraphicalSurface: DestToSourceCoordinates() now takes int instead of unsigned int as in/out coordinates. If the coordinates are outside the surface, negative values are returned.
 + Surface: New thread safe methods updateInputEventAcceptanceFrom() & isInputEventAcceptedFrom() to control which input events are accepted by the Surface

13 files changed:
CMakeLists.txt
LayerManagerPlugins/Renderers/Base/include/BaseRenderer.h
LayerManagerPlugins/Renderers/Base/src/BaseRenderer.cpp
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/BaseWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/NullWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/X11WindowSystem.cpp
LayerManagerService/include/GraphicalSurface.h
LayerManagerService/include/IRenderer.h
LayerManagerService/include/InputManager.h [new file with mode: 0644]
LayerManagerService/include/Surface.h
LayerManagerService/src/GraphicalSurface.cpp
LayerManagerService/src/InputManager.cpp [new file with mode: 0644]

index aefa202..6898aaa 100644 (file)
@@ -94,6 +94,7 @@ add_subdirectory(cmake/optionalFeatures)
 
 add_subdirectory(config)
 
+include_directories ("${PROJECT_SOURCE_DIR}/config")
 include_directories ("${PROJECT_SOURCE_DIR}/3rdParty/")
 # ilm_types are used internally to LM, so we can include them by default
 include_directories ("${PROJECT_SOURCE_DIR}/LayerManagerClient/ilmClient/include")
index 177ed4f..9560b95 100644 (file)
@@ -37,10 +37,12 @@ public:
 
     virtual void doScreenShot(std::string fileToSave) = 0;
     virtual uint getLayerTypeCapabilities(LayerType layerType);
+    virtual InputManager* getInputManager() const {return m_pInputManager;}
     virtual Shader* createShader(const string* vertexName, const string* fragmentName); 
 
 protected:
     Scene* m_pScene;
+    InputManager* m_pInputManager;
 
 private:
     static bool debugMode;
index 1bdceee..bd75c14 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "LayerCapabilities.h"
 #include "BaseRenderer.h"
+#include "InputManager.h"
 #include "Log.h"
 
 bool BaseRenderer::debugMode = true;
@@ -26,6 +27,7 @@ bool BaseRenderer::debugMode = true;
 BaseRenderer::BaseRenderer(Scene* pScene) : m_pScene(pScene)
 {
     LOG_DEBUG("BaseRenderer", "Creating Renderer");
+    m_pInputManager = new InputManager(pScene);
 }
 
 BaseRenderer::~BaseRenderer()
index 59ca6e2..12d8207 100644 (file)
 class BaseWindowSystem
 {
 public:
-    BaseWindowSystem(Scene* pScene)
+    BaseWindowSystem(Scene* pScene, InputManager* pInputManager )
     : m_pScene(pScene)
-       , m_damaged(false)
+    , m_pInputManager(pInputManager)
+    , m_damaged(false)
     {
     }
 
@@ -44,6 +45,7 @@ public:
 
 protected:
     Scene* m_pScene;
+    InputManager* m_pInputManager;
 
 public:
     bool m_damaged;
index 6c57f39..e592691 100644 (file)
@@ -28,7 +28,7 @@ class NullWindowSystem: public BaseWindowSystem
 {
 public:
     NullWindowSystem(Scene* pScene, int width, int height)
-    : BaseWindowSystem(pScene)
+    : BaseWindowSystem(pScene, NULL)
     , windowWidth(width)
     , windowHeight(height)
     , resolutionWidth(width)
index aa31f48..42edf4f 100644 (file)
@@ -114,7 +114,7 @@ extern "C" {
 }
 
 WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene)
-: BaseWindowSystem(pScene)
+: BaseWindowSystem(pScene, NULL)
 , m_wlDisplay(NULL)
 , m_wlDisplayClient(NULL)
 , m_wlCompositorClient(NULL)
index 6aecbc3..75dd136 100644 (file)
@@ -40,7 +40,7 @@ const char X11WindowSystem::CompositorWindowTitle[] = "LayerManager";
 bool    X11WindowSystem::m_xerror = false;
 
 X11WindowSystem::X11WindowSystem(const char* displayname, int width, int height, Scene* pScene,GetVisualInfoFunction func)
-: BaseWindowSystem(pScene)
+: BaseWindowSystem(pScene, NULL)
 , takeScreenshot(ScreenShotNone)
 , screenShotFile()
 , screenShotSurfaceID(0)
index 2392f14..83e1b50 100644 (file)
@@ -98,7 +98,7 @@ public:
      * @return TRUE if the coordinates have been translated
      *         FALSE if an error occured, exp: The position is not in the destination region
      */
-    bool DestToSourceCoordinates(unsigned int *x, unsigned int *y, bool check) const;
+    bool DestToSourceCoordinates(int *x, int *y, bool check) const;
 
     int OriginalSourceWidth;
     int OriginalSourceHeight;    
index a07197f..d6d3b00 100644 (file)
 #include "LayerType.h"
 #include "Shader.h"
 
+
+class InputManager;
+
+
 /**
  * Abstract Base of all CompositingControllers, ie Renderers.
  * \defgroup RendererAPI Layer Management Renderer API
@@ -138,6 +142,13 @@ public:
      * \ingroup    RendererAPI
      */
     virtual void forceCompositionWindowSystem() = 0;
+
+    /**
+      * \brief      Get the InputManager associated to the Scene
+      * \ingroup    RendererAPI
+      */
+    virtual InputManager* getInputManager() const = 0;
 };
 
 #endif /* _IRENDERER_H_ */
+
diff --git a/LayerManagerService/include/InputManager.h b/LayerManagerService/include/InputManager.h
new file mode 100644 (file)
index 0000000..640032e
--- /dev/null
@@ -0,0 +1,218 @@
+/***************************************************************************
+*
+* Copyright 2012 Valeo
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+****************************************************************************/
+
+#include "config.h"
+
+#ifndef _INPUTMANAGER_H_
+#define _INPUTMANAGER_H_
+
+
+#include <map>
+#include <vector>
+#include <pthread.h>
+
+
+class IScene;
+class Surface;
+
+#include "ilm_types.h"
+
+/**
+ * @brief Identifier for the different type of input devices supported by LayerManager.
+ *        Fields can be used as a bit mask
+ */
+typedef unsigned int InputDevice;
+#define INPUT_DEVICE_KEYBOARD   ((InputDevice) 1 << 0)
+#define INPUT_DEVICE_POINTER    ((InputDevice) 1 << 1)
+#define INPUT_DEVICE_TOUCH      ((InputDevice) 1 << 2)
+#define INPUT_DEVICE_ALL        ((InputDevice) ~0)
+
+
+/**
+ * @brief List the different states an input can be.
+ */
+typedef enum
+{
+    INPUT_STATE_PRESSED,    /*!< input is pressed    */
+    INPUT_STATE_MOTION,     /*!< input is in motion  */
+    INPUT_STATE_RELEASED,   /*!< input is released   */
+    INPUT_STATE_OTHER       /*!< input is in an other, not listed, state  */
+} InputEventState;
+
+
+/**
+ * @brief Type that describe a point.
+ * Keep it POD (Plain Old Datatype) for performance reasons when dealing with touch event
+ */
+typedef struct
+{
+    InputEventState state;  /*<! State of the point       */
+    int x;                  /*<! X position of the point  */
+    int y;                  /*<! Y position of the point  */
+}  Point;
+
+
+/**
+ * @brief Type to hold list of points
+ */
+typedef std::vector<Point> PointVect;
+typedef PointVect::iterator PointVectIterator;
+
+
+class InputManager
+{
+    public:
+        /** Ctor / Dtor
+         */
+        InputManager(IScene* s);
+        ~InputManager();
+
+
+        /** Methods to report input events
+         *  They all return the surface to transfer the event to, or NULL if the event should not be dispatched
+         */
+        Surface * reportKeyboardEvent(InputEventState state, long keyId);
+        Surface * reportTouchEvent(PointVect& pv);
+        Surface * reportPointerEvent(Point& p);
+
+
+        /** Methods to control the focus
+         */
+        bool setKeyboardFocusOn(unsigned int surfId);
+        bool updateInputEventAcceptanceOn(unsigned int surfId, InputDevice devices, bool accept);
+
+        /** Few getters
+         */
+        unsigned int getKeyboardFocusSurfaceId();
+
+    private:
+        Surface * electSurfaceForPointerEvent(int& x, int& y);
+        void transformGlobalToLocalCoordinates(Surface* surf, int& x, int& y);
+
+
+        /*
+         * Private Getters / Setters
+         * Needed because access to their associated member requires exclusive area
+         */
+
+        /** \brief Set the keyboard focus on a particular surface */
+        void _setKbdFocus(Surface * s);
+        /** \brief Get the surface which has keyboard focus */
+        Surface * _getKbdFocus();
+        /** \brief Set the pointer focus on a particular surface */
+        void _setPointerFocus(Surface * s);
+        /** \brief Get the surface which has pointer focus */
+        Surface * _getPointerFocus();
+        /** \brief Set the touch focus on a particular surface */
+        void _setTouchFocus(Surface * s);
+        /** \brief Get the surface which has touch focus */
+        Surface * _getTouchFocus();
+
+
+    private:
+        IScene * m_pScene;                  /*!< Pointer to the scene */
+        std::map<long, Surface*> m_KeyMap;  /*!< Map that associate keypressed event to the surface it has been forward to. See @ref<InputManager-KeypressedMap>. */
+        pthread_mutex_t m_mutex;            /*!< Mutex to avoid concurrent access to shared variables */
+
+        /* Access to the below members must be protected by mutex to avoid concurrent accesses */
+        Surface * m_KbdFocus;               /*!< Pointer to the surface which has the focus for keyboard event.
+                                                 Should only be accessed via its getter / setter */
+        Surface * m_PointerFocus;           /*!< Pointer to the surface which has the focus for pointer event.
+                                                 Should only be accessed via its getter / setter */
+        Surface * m_TouchFocus;             /*!< Pointer to the surface which has the focus for touch event.
+                                                 Should only be accessed via its getter / setter */
+
+};
+
+
+/**
+ * @section <InputManager-extra-documentation> (InputManager extra documentation)
+ *
+ * @subsection <InputManager-Requirements> (InputManager Requirements)
+ *  <ul>
+ *  \anchor<LM_INPUT_REQ_01>
+ *    <li>
+ *      LM_INPUT_REQ_01:
+ *      LM should support input events dispatching to the relevant surface.
+ *      Input devices can be keyboard, mouse or (multi)touch foil.
+ *    </li>
+ *
+ *  \anchor<LM_INPUT_REQ_02>
+ *    <li>
+ *      LM_INPUT_REQ_02:
+ *      Keyboard pressed events will be dispatched to the surface elected as being
+ *      the "keyboard focused" surface.
+ *      Keyboard released events will be dispatched to the surface which received
+ *      the same key pressed event.
+ *    </li>
+ *
+ *  \anchor<LM_INPUT_REQ_03>
+ *    <li>
+ *      LM_INPUT_REQ_03:
+ *      A surface gain the Keyboard focus if the LM command "surfaceSetKeyboardFocus"
+ *      is called on that surface. The elected surface can be changed at any time.
+ *    </li>
+ *
+ *  \anchor<LM_INPUT_REQ_04>
+ *  <li>
+ *    LM_INPUT_REQ_04:
+ *    Mouse & touch events will be dispatched to the surface elected as being the "Pointed" surface,
+ *    even if theses events are outside of the surface. Coordinates will be adjusted relatively to the surface.
+ *  </li>
+ *
+ *  \anchor<LM_INPUT_REQ_05>
+ *  <li>
+ *    LM_INPUT_REQ_05:
+ *    A surface gain the "Pointed surface" status as soon as a Pointer event in "Pressed"
+ *    state is reported under it.
+ *    The conditions to gain this status is that the surface or its containing layer should:
+ *     + be visible
+ *     + be opaque (opacity != 0).
+ *     + has a native content
+ *  </li>
+ *
+ *  \anchor<LM_INPUT_REQ_06>
+ *  <li>
+ *    LM_INPUT_REQ_06:
+ *    A surface can request to not receive particular input events. In this case, the surface should not be considered for focus election & the events
+ *    must be dispatched to an other surface, if relevant.
+ *  </li>
+ *
+ *  </ul>
+ *
+ *
+ *
+ *
+ * @subsection <InputManager-KeypressedMap> (InputManager KeyPressed map)
+ *
+ * Note that reportKeyboardEvent() method takes a long as 2nd argument.
+ * This is actually an identifier of the key being reported. It's purpose is to avoid a race in the following scenario :
+ * 1- Surface S1 is the keyboard elected surface
+ * 2- Key X is pressed, so we indicate the renderer to forward to S1
+ * 3- The command "surfaceSetKeyboardFocus" is called on S2, so the surface S2 is now the keyboard elected one
+ * 4- Key X is released.
+ * We should then forward the KeyRelased event to S1 since we have reported the pressed event to it.
+ * So we need a map that associate keyPressed  -> Surface. When the same key is released, we must forward that event to the original surface, and not to the elected one.
+ *
+ *
+ */
+
+
+#endif /* ! #ifndef _INPUTMANAGER_H_ */
+
index c7bad92..e131a0f 100644 (file)
 #ifndef _SURFACE_H_
 #define _SURFACE_H_
 
-#include "GraphicalSurface.h"
 #include <stdlib.h>
+#include <pthread.h>
+
+#include "GraphicalSurface.h"
 #include "PlatformSurface.h"
 #include "PixelFormat.h"
+#include "InputManager.h"
 
 /**
  * Represents a graphical surface generated by an application. Always contained in layers.
@@ -77,6 +80,57 @@ public:
     }
 
     /**
+     * Indicate from which input devices the Surface can accept events.
+     *
+     * \param[in] devices Bit masks of supported devices
+     * \param[in] accept Indicate if the surface should accept or reject input events from the specified list of devices
+     */
+    void updateInputEventAcceptanceFrom(InputDevice devices, bool accept)
+    {
+        if (accept)
+        {
+            pthread_mutex_lock(&m_inputAcceptMutex);
+            m_acceptInputFrom = (InputDevice) (m_acceptInputFrom | devices);
+            pthread_mutex_unlock(&m_inputAcceptMutex);
+        }
+        else
+        {
+            pthread_mutex_lock(&m_inputAcceptMutex);
+            m_acceptInputFrom = (InputDevice) (m_acceptInputFrom  & ~devices);
+            pthread_mutex_unlock(&m_inputAcceptMutex);
+        }
+    }
+
+
+    /**
+     * Indicate if the surface accepts input events from the specified list of devices.
+     *
+     * \param[in] devices Bit masks of devices
+     * \return true if input events are accepted for ALL of the specified devices
+     * \return false if input events are not accepted for at least ONE of the specified devices
+     */
+    bool isInputEventAcceptedFrom(InputDevice devices)
+    {
+        bool ret;
+
+        pthread_mutex_lock(&m_inputAcceptMutex);
+        ret = ((m_acceptInputFrom & devices) == devices);
+        pthread_mutex_unlock(&m_inputAcceptMutex);
+
+        return ret;
+    }
+    
+    /**
+     * Get the set of devices from which the surface can accept input events
+     *
+     * \return Bitmask of InputDevice
+     */
+    InputDevice getInputEventAcceptanceOnDevices() const
+    {
+        return m_acceptInputFrom;
+    }
+    
+    /**
      * Platform specific Object containing surface information specific to a used platform.
      * This typically contains a native window handle/surface handle or information only used
      * by a specific renderer.unsigned
@@ -97,7 +151,9 @@ public:
     , m_pixformat(PIXELFORMAT_UNKNOWN)
     , m_layerId(INVALID_ID)
     , m_hasNativeContent(false)
+    , m_acceptInputFrom(INPUT_DEVICE_ALL)
     {
+        pthread_mutex_init(&m_inputAcceptMutex, NULL);
     }
 
     Surface(int id)
@@ -110,15 +166,28 @@ public:
     , m_pixformat(PIXELFORMAT_UNKNOWN)
     , m_layerId(INVALID_ID)
     , m_hasNativeContent(false)
+    , m_acceptInputFrom(INPUT_DEVICE_ALL)
     {
+        pthread_mutex_init(&m_inputAcceptMutex, NULL);
     }
 
+    ~Surface()
+    {
+        pthread_mutex_destroy(&m_inputAcceptMutex);
+    }
+    
 
 private:
     long m_nativeHandle;
     PixelFormat m_pixformat;
     unsigned int m_layerId;
     bool m_hasNativeContent;
+    /** \brief Bitmask to represent from which kind of devices the surface can accept
+      * input events. By default, all devices are accepted. */
+    InputDevice m_acceptInputFrom;
+    /** \brief m_acceptInputFrom can be accessed concurently. To make it thread safe, we need a mutex */
+    pthread_mutex_t m_inputAcceptMutex;
 };
 
 #endif /* _SURFACE_H_ */
+
index ba2d6fa..311e0f7 100644 (file)
@@ -61,7 +61,7 @@ bool GraphicalSurface::isInside(unsigned int x_DestCoordinateSyst, unsigned int
  *  - rotation (not yet implemented)
  *
  */
-bool GraphicalSurface::DestToSourceCoordinates(unsigned int *x, unsigned int *y, bool check) const
+bool GraphicalSurface::DestToSourceCoordinates(int *x, int *y, bool check) const
 {
        bool    ret;
        int     TVxD, TVyD;  /* Translation vector x,y in destination system */ 
diff --git a/LayerManagerService/src/InputManager.cpp b/LayerManagerService/src/InputManager.cpp
new file mode 100644 (file)
index 0000000..cfcf0f1
--- /dev/null
@@ -0,0 +1,340 @@
+/***************************************************************************
+*
+* Copyright 2012 Valeo
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*        http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+****************************************************************************/
+
+
+#include <cassert>
+
+#include "Log.h"
+#include "config.h"
+#include "IScene.h"
+#include "InputManager.h"
+
+
+InputManager::InputManager(IScene* s) :
+    m_pScene(s),
+    m_KbdFocus(NULL),
+    m_PointerFocus(NULL),
+    m_TouchFocus(NULL)
+{
+    assert(s != NULL);
+    pthread_mutex_init(&m_mutex, NULL);
+}
+
+
+InputManager::~InputManager()
+{
+    m_pScene = NULL;
+    pthread_mutex_destroy(&m_mutex);
+}
+
+
+/**
+ * @brief Set the keyboard focus on a specific surface.
+ */
+bool InputManager::setKeyboardFocusOn(unsigned int surfId)
+{
+    bool ret;
+    Surface * surf;
+
+    surf = m_pScene->getSurface(surfId);
+    if (surf == NULL)
+    {
+        LOG_ERROR("InputManager", "setKeyboardFocusOn() called on an unknown surface id: " << surfId);
+        ret = false;
+    }
+    else
+    {
+        if (surf->isInputEventAcceptedFrom(INPUT_DEVICE_KEYBOARD))
+        {
+            _setKbdFocus(surf);
+            ret = true;
+        }
+        else
+        {
+            // Hum, the surface does not accept kbd events but we've been asked to set the focus on it
+            _setKbdFocus(NULL);
+            ret = false;
+            LOG_ERROR("InputManager", "setKeyboardFocusOn() called on surface " << surfId << ". This surface does not accept keyboard event !");
+        }
+    }
+
+
+    return ret;
+}
+
+/**
+ * @brief Get the identifier of the surface which has the keyboard focus
+ */
+unsigned int InputManager::getKeyboardFocusSurfaceId()
+{
+    Surface *surf;
+    unsigned int surfId;
+
+    surf = _getKbdFocus();
+    if (!surf)
+    {
+        surfId = GraphicalObject::INVALID_ID;
+    }
+    else
+    {
+        surfId = surf->getID();
+    }
+
+    return surfId;
+}
+
+
+bool InputManager::updateInputEventAcceptanceOn(unsigned int surfId, InputDevice devices, bool accept)
+{
+    bool ret;
+    Surface * surf;
+
+    surf = m_pScene->getSurface(surfId);
+    if (surf == NULL)
+    {
+        LOG_ERROR("InputManager", "setInputAcceptanceOn() called on an unknown surface id: " << surfId);
+        ret = false;
+    }
+    else
+    {
+        surf->updateInputEventAcceptanceFrom(devices, accept);
+        ret = true;
+    }
+
+    return ret;
+}
+
+
+
+/**
+ * @brief Report keyboard event.
+ * @param[in] state The state of the key. Can be either INPUT_STATE_PRESSED or INPUT_STATE_RELEASED
+ * @param[in] keyId A uniq identifier for the key being reported. See @ref<InputManager-KeypressedMap>.
+ * @return The Surface to which to report the event, or NULL
+ */
+Surface * InputManager::reportKeyboardEvent(InputEventState state, long keyId)
+{
+    Surface * elected;
+
+    switch (state)
+    {
+        case INPUT_STATE_PRESSED:
+            elected = _getKbdFocus();
+            m_KeyMap[keyId] = elected;
+            break;
+
+        case INPUT_STATE_RELEASED:
+            elected = m_KeyMap[keyId];
+            break;
+
+        default:
+            elected = NULL;
+            LOG_WARNING("InputManager", "Invalid input state reported for reportKeyboardEvent() : " << state);
+            break;
+    }
+
+    return elected;
+}
+
+
+/**
+ * @return The Surface to which to report the event, or NULL
+ */
+Surface * InputManager::reportPointerEvent(Point& p)
+{
+    Surface * elected;
+
+    switch (p.state)
+    {
+        case INPUT_STATE_PRESSED:
+            elected = electSurfaceForPointerEvent(p.x, p.y);
+            _setPointerFocus(elected);
+            /* Pointer pressed also assigns the focus for touch events */
+            _setTouchFocus(elected);
+            break;
+
+        case INPUT_STATE_OTHER:
+        case INPUT_STATE_MOTION:
+        case INPUT_STATE_RELEASED:
+            elected = _getPointerFocus();
+            if (elected != NULL)
+            {
+                transformGlobalToLocalCoordinates(elected, p.x, p.y);
+            }
+            break;
+
+        default:
+            elected = NULL;
+            LOG_WARNING("InputManager", "Invalid input state reported for reportPointerEvent() : " << p.state);
+    }
+
+    return elected;
+}
+
+
+Surface * InputManager::reportTouchEvent(PointVect& pv)
+{
+    Surface * elected;
+
+    elected = _getTouchFocus();
+    if (elected != NULL)
+    {
+        PointVectIterator it;
+        for (it = pv.begin(); it != pv.end(); it++)
+        {
+            transformGlobalToLocalCoordinates(elected, it->x, it->y);
+        }
+    }
+
+    return elected;
+}
+
+
+Surface * InputManager::electSurfaceForPointerEvent(int& x, int& y)
+{
+    Surface* surf;
+    LayerList &ll = m_pScene->getCurrentRenderOrder();
+    LayerListConstReverseIterator currentLayer;
+    SurfaceListConstReverseIterator currentSurf;
+    int x_SurfCoordinate, y_SurfCoordinate;
+
+    surf = NULL;
+    /* Need to browse for all layers. 1st layer of m_currentRenderOrder is rendered
+     * on bottom, last one is rendrered on top. So we have to reverse iterate */
+    for (currentLayer = ll.rbegin();
+         currentLayer != ll.rend() && surf == NULL;
+         currentLayer++)
+    {
+        if ( ((*currentLayer)->visibility) && ((*currentLayer)->getOpacity() != 0) )
+        {
+            if ((*currentLayer)->isInside(x, y))
+            {
+                x_SurfCoordinate = x;
+                y_SurfCoordinate = y;
+                (*currentLayer)->DestToSourceCoordinates(&x_SurfCoordinate, &y_SurfCoordinate, false);
+                /* Need to browse for all surfaces */
+                for (currentSurf = (*currentLayer)->getAllSurfaces().rbegin();
+                     currentSurf != (*currentLayer)->getAllSurfaces().rend() && surf == NULL;
+                     currentSurf++)
+                {
+                    if ( ((*currentSurf)->hasNativeContent()) && ((*currentSurf)->visibility) && ((*currentSurf)->getOpacity() != 0) )
+                    {
+                        if ((*currentSurf)->isInside(x_SurfCoordinate, y_SurfCoordinate))
+                        {
+                            if ((*currentSurf)->isInputEventAcceptedFrom(INPUT_DEVICE_POINTER))
+                            {
+                                surf = *currentSurf;
+                                (*currentSurf)->DestToSourceCoordinates(&x_SurfCoordinate, &y_SurfCoordinate, false);
+                                x = x_SurfCoordinate;
+                                y = y_SurfCoordinate;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return surf;
+}
+
+
+void InputManager::transformGlobalToLocalCoordinates(Surface* surf, int& x, int& y)
+{
+    Layer* layer;
+
+    assert(surf != NULL);
+
+    layer = m_pScene->getLayer(surf->getContainingLayerId());
+    if (layer != NULL)
+    {
+        layer->DestToSourceCoordinates(&x,&y, false);
+        surf->DestToSourceCoordinates(&x,&y, false);
+    }
+}
+
+
+//@{
+/*
+ * m_KbdFocus can be concurrently accessed by :
+ *   - reportKeyboardEvent(), called in the renderer thread context
+ *   - setKeyboardFocusOn(), called in the IPC mechanism context
+ *
+ *   So read & Write to this variable must be protected by exclusive to avoid
+ *   race conditions
+ */
+
+void InputManager::_setKbdFocus(Surface * s)
+{
+    pthread_mutex_lock(&m_mutex);
+    m_KbdFocus = s;
+    pthread_mutex_unlock(&m_mutex);
+}
+
+Surface * InputManager::_getKbdFocus()
+{
+    Surface * s;
+    pthread_mutex_lock(&m_mutex);
+    s = m_KbdFocus;
+    pthread_mutex_unlock(&m_mutex);
+
+    return s;
+}
+//@}
+
+
+
+//@{
+/*
+ * m_PointerFocus can NOT be concurrently accessed as of today :
+ * It is only accessed by reportPointerEvent(), called in the renderer thread context
+ *
+ * But it's cheap to add getter / setter if needed in the future & at least to have
+ * a similar access mechanism than m_KbdFocus
+ */
+void InputManager::_setPointerFocus(Surface * s)
+{
+    m_PointerFocus = s;
+}
+
+Surface * InputManager::_getPointerFocus()
+{
+    return m_PointerFocus;
+}
+//@}
+
+
+//@{
+/*
+ * m_TouchFocus can NOT be concurrently accessed as of today.
+ * It is only accessed by reportPointerEvent() & reportTouchEvent(), both called in the renderer thread context.
+ *
+ * But it's cheap to add getter / setter if needed in the future & at least to have
+ * a similar access mechanism than m_KbdFocus
+ */
+void InputManager::_setTouchFocus(Surface * s)
+{
+    m_TouchFocus = s;
+}
+
+Surface * InputManager::_getTouchFocus()
+{
+    return m_TouchFocus;
+}
+
+