WaylandX11WindowSystem: input event support based on InputManager
authorNobuhiko Tanibata <ntanibata@jp.adit-jv.com>
Wed, 19 Sep 2012 02:34:02 +0000 (11:34 +0900)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Thu, 22 Nov 2012 10:01:27 +0000 (02:01 -0800)
-Pointer & keyboard events support
-Receive Input events and report them to InputManager
-Forword local events of corresponding surface from InputManager to Wayland protocol

LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandBaseWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandDrmWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandFbdevWindowSystem.h
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/WaylandX11WindowSystem.h
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandBaseWindowSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandDrmWindowSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandFbdevWindowSystem.cpp
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/WaylandX11WindowSystem.cpp
LayerManagerPlugins/Renderers/Platform/WaylandGLESRenderer/src/WaylandGLESRenderer.cpp

index c438489..532d244 100644 (file)
@@ -38,6 +38,8 @@
 #include "Log.h"
 #include "ScreenShotType.h"
 #include "config.h"
+#include "InputManager.h"
+#include "WindowSystems/WaylandInputEvent.h"
 
 extern "C" {
 // TODO:to abstract
@@ -49,6 +51,17 @@ typedef enum waylandWindowSystemStates
     UNKOWN_STATE
 } WaylandWindowSystemStates;
 
+typedef struct _wlevent {
+    int        x, y;
+    int32_t    button;
+    enum wl_pointer_button_state buttonState;
+    long       keyCode;
+    enum wl_keyboard_key_state   keyState;
+    uint32_t   serial;
+    int        touchId;
+    int        touchType;
+} WLEvent;
+
 } // extern "C"
 
 struct native_surface;
@@ -56,7 +69,7 @@ struct native_surface;
 class WaylandBaseWindowSystem: public BaseWindowSystem
 {
 public:
-    WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene);
+    WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager);
     virtual ~WaylandBaseWindowSystem();
     bool init(BaseGraphicSystem<void*, void*>* sys);
     bool start();
@@ -106,6 +119,7 @@ protected:
     int m_height;
 
     struct wl_list m_listFrameCallback;
+    struct wl_list m_nativeSurfaceList;
 
     void createServerinfo(WaylandBaseWindowSystem* windowSystem);
     struct native_surface* createNativeSurface();
@@ -117,6 +131,7 @@ protected:
     void Redraw();
     void shutdownCompositor();
     Surface* getSurfaceFromNativeSurface(struct native_surface* nativeSurface);
+    struct native_surface* getNativeSurfaceFromSurface(Surface* surface);
     void checkForNewSurfaceNativeContent();
     void calculateFps();
     void calculateSurfaceFps(Surface *currentSurface, float time) ;
@@ -130,6 +145,9 @@ protected:
     bool createWaylandClient();
     void releaseWaylandClient();
 
+    WaylandInputEvent* m_inputEvent;
+    virtual bool createInputEvent();
+
 public:
     static void serverinfoIFCreateConnection(struct wl_client *client, struct wl_resource *resource);
     static void bindServerinfo(struct wl_client *client, void *data, uint32_t version, uint32_t id);
@@ -150,6 +168,9 @@ public:
     static void compositorIFCreateSurface(struct wl_client *client, struct wl_resource* resource, uint32_t id);
 
     struct wl_list m_connectionList;
+
+    // Input event
+    void manageWLInputEvent(const InputDevice type, const InputEventState state, const WLEvent *wlEvent);
 };
 
 inline void WaylandBaseWindowSystem::setSystemState (WaylandWindowSystemStates state)
@@ -167,6 +188,11 @@ inline struct wl_display* WaylandBaseWindowSystem::getNativeDisplayHandle()
     return m_wlDisplay;
 }
 
+inline bool WaylandBaseWindowSystem::createInputEvent()
+{
+    return false;
+}
+
 extern "C" {
     struct native_surface {
         struct wl_surface surface;
index 3abb454..f64a4fa 100644 (file)
@@ -36,7 +36,7 @@ struct gbm_device;
 class WaylandDrmWindowSystem: public WaylandBaseWindowSystem
 {
 public:
-    WaylandDrmWindowSystem(const char* displayname, int width, int height, Scene* pScene);
+    WaylandDrmWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager);
     virtual ~WaylandDrmWindowSystem();
 
 protected:
index 8a5c9f7..9d2ce2a 100644 (file)
@@ -34,7 +34,7 @@
 class WaylandFbdevWindowSystem: public WaylandBaseWindowSystem
 {
 public:
-    WaylandFbdevWindowSystem(const char* displayname, int width, int height, Scene* pScene);
+    WaylandFbdevWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager);
 
 protected:
     virtual bool createNativeContext();
index 60e34d0..4023166 100644 (file)
 class WaylandX11WindowSystem: public WaylandBaseWindowSystem
 {
 public:
-    WaylandX11WindowSystem(const char* displayname, int width, int height, Scene* pScene);
+    WaylandX11WindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager);
 #if 0
     virtual bool init(BaseGraphicSystem<EGLNativeDisplayType, EGLNativeWindowType>* sys);
 #endif
+    Display* x11Display() const;
 
 protected:
     virtual bool createNativeContext();
     virtual bool initGraphicSystem();
+    virtual bool createInputEvent();
 
 private:
 #if 0
@@ -59,4 +61,6 @@ private:
     Colormap m_x11Colormap;
 };
 
+inline Display* WaylandX11WindowSystem::x11Display() const { return m_x11Display; }
+
 #endif /* _WAYLANDX11WINDOWSYSTEM_H_ */
index cf0b908..7538cc8 100644 (file)
@@ -41,6 +41,7 @@
 #include <unistd.h>
 #include <iomanip>
 #include "WindowSystems/WaylandServerinfoServerProtocol.h"
+#include "InputManager.h"
 
 extern "C" {
     struct serverinfo {
@@ -112,8 +113,8 @@ extern "C" {
     };
 }
 
-WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene)
-: BaseWindowSystem(pScene, NULL)
+WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager)
+: BaseWindowSystem(pScene, pInputManager)
 , m_wlDisplay(NULL)
 , m_wlDisplayClient(NULL)
 , m_wlCompositorClient(NULL)
@@ -139,6 +140,7 @@ WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int wi
 , m_width(width)
 , m_height(height)
 , m_listFrameCallback()
+, m_inputEvent(NULL)
 , m_connectionList()
 {
     LOG_DEBUG("WaylandBaseWindowSystem", "creating WaylandBaseWindowSystem width:" << width << " height:" << height);
@@ -150,6 +152,8 @@ WaylandBaseWindowSystem::WaylandBaseWindowSystem(const char* displayname, int wi
 
 WaylandBaseWindowSystem::~WaylandBaseWindowSystem()
 {
+    if (m_inputEvent)
+        delete m_inputEvent;
 }
 
 void WaylandBaseWindowSystem::printDebug()
@@ -216,6 +220,29 @@ Surface* WaylandBaseWindowSystem::getSurfaceFromNativeSurface(struct native_surf
     return NULL;
 }
 
+struct native_surface*
+WaylandBaseWindowSystem::getNativeSurfaceFromSurface(Surface* surface)
+{
+    struct native_surface *nativeSurface = NULL;
+
+    WaylandPlatformSurface* platformSurface = static_cast<WaylandPlatformSurface*>(surface->platform);
+    if (!platformSurface)
+    {
+        return NULL;
+    }
+
+    wl_list_for_each(nativeSurface, &m_nativeSurfaceList, link)
+    {
+        if ((nativeSurface->connectionId == platformSurface->connectionId) &&
+            (nativeSurface->surface.resource.object.id == platformSurface->surfaceId))
+        {
+            break; // FOUND
+        }
+    }
+
+    return nativeSurface;
+}
+
 void WaylandBaseWindowSystem::checkForNewSurfaceNativeContent()
 {
     m_pScene->lockScene();
@@ -711,6 +738,7 @@ extern "C" void WaylandBaseWindowSystem::compositorIFCreateSurface
 
     windowSystem->checkForNewSurfaceNativeContent();
     wl_client_add_resource(client, &surface->surface.resource);
+    wl_list_insert(windowSystem->m_nativeSurfaceList.prev, &surface->link);
     LOG_DEBUG("WaylandBaseWindowSystem", "compositorIFCreateSurface OUT");
 }
 
@@ -774,8 +802,8 @@ bool WaylandBaseWindowSystem::initCompositor()
     wl_display_init_shm(m_wlDisplay);
 
     wl_list_init(&m_listFrameCallback);
-
     wl_list_init(&m_connectionList);
+    wl_list_init(&m_nativeSurfaceList);
     createServerinfo(this);
 
     LOG_DEBUG("WaylandBaseWindowSystem", "initCompositor END");
@@ -870,6 +898,15 @@ void* WaylandBaseWindowSystem::eventLoop()
         }
         LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:init GraphicSystem");
 
+        // create input event
+        status = createInputEvent();
+        if (false == status)
+        {
+            LOG_ERROR("WaylandBaseWindowSystem", "failed to create input event");
+            break;
+        }
+        LOG_DEBUG("WaylandBaseWindowSystem", "SUCCESS:create InputEvent");
+
         this->m_success = status;
         this->m_initialized = true;
 
@@ -1139,3 +1176,117 @@ void WaylandBaseWindowSystem::doScreenShotOfSurface(std::string fileName, const
     m_screenShotSurfaceID = id;
     m_screenShotLayerID = layer_id;
 }
+
+void WaylandBaseWindowSystem::manageWLInputEvent(const InputDevice type,
+                                                 const InputEventState state,
+                                                 const WLEvent *wlEvent)
+{
+    if (!m_inputEvent){
+        LOG_WARNING("WaylandBaseWindowSystem", "InputEvent not available");
+        return;
+    }
+    Surface *surface = NULL;
+    native_surface *nativeSurface = NULL;
+    uint32_t time = getTime();
+
+    switch (type){
+    case INPUT_DEVICE_KEYBOARD:
+        {
+            LOG_DEBUG("WaylandBaseWindowSystem",
+                      "INPUT_DEVICE_KEYBOARD: state = " << state <<
+                      ", keyCode = " << wlEvent->keyCode);
+            surface = m_pInputManager->reportKeyboardEvent(state, wlEvent->keyCode);
+            if (!surface){
+                m_inputEvent->inputDevice().setKeyboardFocus(NULL);
+                break;
+            }
+
+            nativeSurface = getNativeSurfaceFromSurface(surface);
+            if (!nativeSurface)
+                break;
+
+            switch (state){
+            case INPUT_STATE_PRESSED:
+                m_inputEvent->inputDevice().sendKeyPressEvent(
+                    &nativeSurface->surface, time, wlEvent->keyCode);
+                break;
+            case INPUT_STATE_RELEASED:
+                m_inputEvent->inputDevice().sendKeyReleaseEvent(
+                    &nativeSurface->surface, time, wlEvent->keyCode);
+                break;
+            case INPUT_STATE_OTHER:
+            default:
+                // nothing to do
+                break;
+            }
+        }
+        break;
+    case INPUT_DEVICE_POINTER:
+        {
+            LOG_DEBUG("WaylandBaseWindowSystem",
+                      "INPUT_DEVICE_POINTER: state = " << state <<
+                      ", x = " << wlEvent->x <<
+                      ", y = " << wlEvent->y);
+            Point globalPos = {state, wlEvent->x, wlEvent->y};
+            Point localPos  = globalPos;
+            surface = m_pInputManager->reportPointerEvent(localPos);
+            if (!surface){
+                LOG_WARNING("WaylandBaseWindowSystem", "NO FOUND SURFACE!");
+                break;
+            }
+            LOG_DEBUG("WaylandBaseWindowSystem",
+                      "Local coordinates: x = " << localPos.x <<
+                      ", y = " << localPos.y);
+
+            nativeSurface = getNativeSurfaceFromSurface(surface);
+            if (!nativeSurface)
+                break;
+
+            switch (state){
+            case INPUT_STATE_PRESSED:
+                m_inputEvent->inputDevice().sendMousePressEvent(
+                    globalPos, localPos, wlEvent->button, time);
+                break;
+            case INPUT_STATE_RELEASED:
+                m_inputEvent->inputDevice().sendMouseReleaseEvent(
+                    globalPos, localPos, wlEvent->button, time);
+                break;
+            case INPUT_STATE_MOTION:
+                m_inputEvent->inputDevice().sendMouseMotionEvent(
+                    &nativeSurface->surface, globalPos, localPos, time);
+                break;
+            case INPUT_STATE_OTHER:
+            default:
+                break;
+            }
+        }
+        break;
+    case INPUT_DEVICE_TOUCH:
+        {
+            LOG_DEBUG("WaylandBaseWindowSystem",
+                      "INPUT_DEVICE_TOUCH: state = " << state <<
+                      ", x = " << wlEvent->x <<
+                      ", y = " << wlEvent->y);
+            Point pt = {state, wlEvent->x, wlEvent->y};
+            PointVect ptVec(1, pt);
+            surface = m_pInputManager->reportTouchEvent(ptVec);
+            if (!surface)
+                break;
+
+            switch (state){
+            case INPUT_STATE_PRESSED:
+                m_inputEvent->inputDevice().sendTouchPointEvent();
+                break;
+            case INPUT_STATE_MOTION:
+            case INPUT_STATE_RELEASED:
+            case INPUT_STATE_OTHER:
+            default:
+                break;
+            }
+        }
+        break;
+    case INPUT_DEVICE_ALL:
+    default:
+        break;
+    }
+}
index 0e612de..af4181e 100644 (file)
@@ -40,8 +40,8 @@
 
 static const char default_seat[] = "seat0";
 
-WaylandDrmWindowSystem::WaylandDrmWindowSystem(const char* displayname, int width, int height, Scene* pScene)
-: WaylandBaseWindowSystem(displayname, width, height, pScene)
+WaylandDrmWindowSystem::WaylandDrmWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager)
+: WaylandBaseWindowSystem(displayname, width, height, pScene, pInputManager)
 , m_fdDev(-1), m_gbm(NULL)
 {
     LOG_DEBUG("WaylandDrmWindowSystem", "creating WaylandDrmWindowSystem width:" << width << " height:" << height);
index f3ee75f..93bb466 100644 (file)
@@ -45,8 +45,8 @@
 #endif
 #include <iomanip>
 
-WaylandFbdevWindowSystem::WaylandFbdevWindowSystem(const char* displayname, int width, int height, Scene* pScene)
-: WaylandBaseWindowSystem(displayname, width, height, pScene)
+WaylandFbdevWindowSystem::WaylandFbdevWindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager)
+: WaylandBaseWindowSystem(displayname, width, height, pScene, pInputManager)
 , m_fdFB(-1)
 {
     LOG_DEBUG("WaylandFbdevWindowSystem", "creating WaylandFbdevWindowSystem width:" << width << " height:" << height);
index 5c4fe92..0f681da 100644 (file)
 #include "GraphicSystems/GLESGraphicSystem.h"
 
 #include "WindowSystems/WaylandServerinfoServerProtocol.h"
+#include "WindowSystems/WaylandX11InputEvent.h"
 
-WaylandX11WindowSystem::WaylandX11WindowSystem(const char* displayname, int width, int height, Scene* pScene)
-: WaylandBaseWindowSystem(displayname, width, height, pScene)
+WaylandX11WindowSystem::WaylandX11WindowSystem(const char* displayname, int width, int height, Scene* pScene, InputManager* pInputManager)
+: WaylandBaseWindowSystem(displayname, width, height, pScene, pInputManager)
 , m_x11Window(0)
 , m_x11Display(0)
 , m_x11Screen(0)
@@ -138,7 +139,7 @@ bool WaylandX11WindowSystem::createNativeContext()
     // Add to these for handling other events
     windowAttributes.event_mask = StructureNotifyMask | ExposureMask
             | ButtonPressMask | ButtonReleaseMask | KeyPressMask
-            | KeyReleaseMask;
+            | KeyReleaseMask | Button1MotionMask | PointerMotionMask | FocusChangeMask;
     windowAttributes.backing_store = Always;
 
     // Set the window mask attributes
@@ -171,3 +172,10 @@ bool WaylandX11WindowSystem::createNativeContext()
 
     return result;
 }
+
+bool WaylandX11WindowSystem::createInputEvent()
+{
+    m_inputEvent = new WaylandX11InputEvent(this);
+    m_inputEvent->setupInputEvent();
+    return true;
+}
index a734dae..0d55477 100644 (file)
@@ -55,13 +55,13 @@ bool WaylandGLESRenderer::start(int width, int height, const char* displayname)
     // create Wayland windows, register as composite manager etc
     m_pWindowSystem = NULL;
 #ifdef WITH_WAYLAND_FBDEV
-    m_pWindowSystem = new WaylandFbdevWindowSystem(displayname, width, height, m_pScene);
+    m_pWindowSystem = new WaylandFbdevWindowSystem(displayname, width, height, m_pScene, m_pInputManager);
 #endif
 #ifdef WITH_WAYLAND_X11
-    m_pWindowSystem = new WaylandX11WindowSystem(displayname, width, height, m_pScene);
+    m_pWindowSystem = new WaylandX11WindowSystem(displayname, width, height, m_pScene, m_pInputManager);
 #endif
 #ifdef WITH_WAYLAND_DRM
-    m_pWindowSystem = new WaylandDrmWindowSystem(displayname, width, height, m_pScene);
+    m_pWindowSystem = new WaylandDrmWindowSystem(displayname, width, height, m_pScene, m_pInputManager);
 #endif
     if( m_pWindowSystem == NULL )
     {