DSWaylandInputPanel: process wl_input_panel_surface requests 14/241814/1
authorjeon <jhyuni.kang@samsung.com>
Tue, 11 Aug 2020 12:24:50 +0000 (21:24 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Thu, 20 Aug 2020 10:11:36 +0000 (19:11 +0900)
Change-Id: I3b73fb98807dc432af91f80b74b3e7bed90893d0

src/DSWaylandServer/DSWaylandInputPanel.cpp
src/DSWaylandServer/DSWaylandInputPanel.h
src/DSWaylandServer/DSWaylandInputPanelPrivate.h
src/DSWaylandServer/DSWaylandInputPanelSurface.h
src/DSWaylandServer/DSWaylandInputPanelSurfacePrivate.h
tests/DSWaylandInputMethod-test.cpp
tests/DSWaylandInputPanel-test.cpp
tests/DSWaylandInputPanelSurface-test.cpp

index 8a4b87f..8c604d4 100644 (file)
 #include "DSWaylandInputPanelPrivate.h"
 #include "DSWaylandInputPanelSurface.h"
 #include "DSWaylandInputPanelSurfacePrivate.h"
+#include "DSStruct.h"
 
 namespace display_server {
 
-DSWaylandInputPanelPrivate::DSWaylandInputPanelPrivate(DSWaylandInputPanel *p_ptr)
-       : DSObjectPrivate(p_ptr),
-         __p_ptr(p_ptr)
+class DSWaylandInputPanelFloating
 {
+public:
+       DSWaylandInputPanelFloating(DSWaylandInputPanel *inputPanel)
+               : movingRequest(false), mousePressed(false), initPortraitPos(false), initLandscapePos(false),
+                 beforePos({0,0}), startPortraitPos({0,0}), startLandscapePos({0,0}), __inputPanel(inputPanel) {}
+       ~DSWaylandInputPanelFloating() {}
+
+       bool movingRequest;
+       bool mousePressed;
+       bool initPortraitPos;
+       bool initLandscapePos;
+       stPosition beforePos;
+       stPosition startPortraitPos;
+       stPosition startLandscapePos;
+
+private:
+       DSWaylandInputPanel *__inputPanel;
+};
+
+class DSWaylandInputPanelSurfaceData
+{
+public:
+       DSWaylandInputPanelSurfaceData(DSWaylandServer::wl_input_panel_surface::Resource *resource, void *inputPanelResource, void *surfaceResource)
+               : panel(false), showing(false), needShow(false),
+                 __resource(resource), __inputPanelResource(inputPanelResource), __surfaceResource(surfaceResource) {}
+       ~DSWaylandInputPanelSurfaceData() {}
+
+       void *getInputPanelResource() {return __inputPanelResource;}
+       void *getSurfaceResource() {return __surfaceResource;}
+
+       bool panel;
+       bool showing;
+       bool needShow;
+
+private:
+       DSWaylandServer::wl_input_panel_surface::Resource *__resource;
+       void *__inputPanelResource;
+       void *__surfaceResource;
+};
+
+#if 0
+DSWaylandInputPanelSurfaceData::DSWaylandInputPanelSurfaceData(DSWaylandServer::wl_input_panel_surface::Resource *resource, void *inputPanelResource, void *surfaceResource)
+       : __resource(resource),
+         __inputPanelResource(inputPanelResource),
+         __surfaceResource(surfaceResource)
+{
+}
+
+DSWaylandInputPanelSurfaceData::~DSWaylandInputPanelSurfaceData()
+{
+}
+
+void *DSWaylandInputPanelSurfaceData::getInputPanelResource()
+{
+       return __inputPanelResource;
+}
+
+void *DSWaylandInputPanelSurfaceData::getSurfaceResource()
+{
+       return __surfaceResource;
+}
+#endif
+
+DSWaylandInputPanelPrivate::DSWaylandInputPanelPrivate(DSWaylandInputPanel *p_ptr, DSWaylandCompositor *compositor)
+       : DSObjectPrivate(p_ptr), __p_ptr(p_ptr),
+         __compositor(compositor)
+{
+       if (!compositor)
+               return;
+
+       wl_input_panel::init(__compositor->display(), 1);
 }
 
 DSWaylandInputPanelPrivate::~DSWaylandInputPanelPrivate()
 {
 }
 
+void DSWaylandInputPanelPrivate::input_panel_destroy_resource(Resource *resource)
+{
+       DS_GET_PUB(DSWaylandInputPanel);
+
+       pub->clearSurfaces(resource->handle);
+}
+
 void DSWaylandInputPanelPrivate::input_panel_get_input_panel_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface)
 {
+       DS_GET_PUB(DSWaylandInputPanel);
+
+       pub->createSurface((void *)resource->client(), (void *)resource->handle, id, (void *)surface);
 }
 
 
-DSWaylandInputPanel::DSWaylandInputPanel()
-       : DSObject(), _d_ptr(std::make_unique<DSWaylandInputPanelPrivate>(this))
+DSWaylandInputPanel::DSWaylandInputPanel(DSWaylandCompositor *compositor)
+       : DSObject(), _d_ptr(std::make_unique<DSWaylandInputPanelPrivate>(this, compositor)),
+         __compositor(compositor),
+         __eventLoop(nullptr),
+         __waitUpdate(false)
 {
+       __inputPanelSurface = new DSWaylandInputPanelSurface(__compositor, this);
+       __inputPanelFloating = new DSWaylandInputPanelFloating(this);
+
+       __eventLoop = DSEventLoop::getInstance();
+       __eventLoop->registerCallbackIdleEnterer(this, std::bind(&DSWaylandInputPanel::__onEventIdleEnterer, this, std::placeholders::_1));
 }
 
 DSWaylandInputPanel::~DSWaylandInputPanel()
 {
+       DSEventLoop::releaseInstance();
+       delete __inputPanelFloating;
+       delete __inputPanelSurface;
+}
+
+void DSWaylandInputPanel::createSurface(void *client, void *inputPanelResource, unsigned int id, void *surface)
+{
+       __inputPanelSurface->createGlobal(client, inputPanelResource, id, surface);
+
+       /* TODO: Find window from surface and set some data */
+}
+
+void DSWaylandInputPanel::clearSurfaces(void *inputPanelResource)
+{
+       __inputPanelSurface->clearGlobals(inputPanelResource);
+}
+
+bool DSWaylandInputPanel::getWaitUpdate()
+{
+       return __waitUpdate;
+}
+
+void DSWaylandInputPanel::setWaitUpdate(bool waitUpdate)
+{
+       __waitUpdate = waitUpdate;
+}
+
+void DSWaylandInputPanel::updateInputPanelState(bool waitUpdate)
+{
+       __waitUpdate = waitUpdate;
+
+       if (__waitUpdate)
+       {
+               /* TODO: Add Timer */
+               __inputPanelSurface->flushFrame();
+               /* TODO: Add buffer change event handler */
+       }
+       else
+       {
+               /* TODO: remove buffer change event handler */
+       }
 }
 
+void DSWaylandInputPanel::setFloatingMovingRequest(bool enabled)
+{
+       if (!__inputPanelFloating) return;
+
+       __inputPanelFloating->movingRequest = enabled;
+}
 
-DSWaylandInputPanelSurfacePrivate::DSWaylandInputPanelSurfacePrivate(DSWaylandInputPanelSurface *p_ptr)
-       : DSObjectPrivate(p_ptr),
-         __p_ptr(p_ptr)
+void DSWaylandInputPanel::__onEventIdleEnterer(void *data)
+{
+}
+
+
+DSWaylandInputPanelSurfacePrivate::DSWaylandInputPanelSurfacePrivate(DSWaylandInputPanelSurface *p_ptr, DSWaylandCompositor *compositor)
+       : DSObjectPrivate(p_ptr), __p_ptr(p_ptr),
+         __compositor(compositor)
 {
 }
 
@@ -63,29 +202,146 @@ DSWaylandInputPanelSurfacePrivate::~DSWaylandInputPanelSurfacePrivate()
 {
 }
 
+void DSWaylandInputPanelSurfacePrivate::createGlobal(void *client, void *inputPanelResource, unsigned int id, void *surface)
+{
+       Resource *resource = add((struct ::wl_client *)client, id, 1);
+       DSWaylandInputPanelSurfaceData *data = new DSWaylandInputPanelSurfaceData(resource, inputPanelResource, surface);
+       __dataMap.insert(std::pair<Resource*, DSWaylandInputPanelSurfaceData *>(resource, data));
+}
+
+void DSWaylandInputPanelSurfacePrivate::clearGlobals(void *inputPanelResource)
+{
+       for (auto it = __dataMap.begin();  it != __dataMap.end(); it++)
+       {
+               auto tempIt = it;
+               DSWaylandInputPanelSurfaceData *surfaceData = (*it).second;
+               if (surfaceData->getInputPanelResource() == inputPanelResource)
+               {
+                       __dataMap.erase(tempIt);
+                       /* TODO: clear window's data */
+               }
+       }
+}
+
+void DSWaylandInputPanelSurfacePrivate::flushFrame()
+{
+       for (auto it = __dataMap.begin();  it != __dataMap.end(); it++)
+       {
+               DSWaylandInputPanelSurfaceData *_surfaceData = (*it).second;
+               if (_surfaceData->getSurfaceResource())
+               {
+                       /* TODO: clear pixmap image */
+               }
+       }
+}
+
+void DSWaylandInputPanelSurfacePrivate::show(DSWaylandInputPanelSurfaceData *surfaceData)
+{
+       DS_GET_PUB(DSWaylandInputPanelSurface);
+
+       if (!surfaceData)
+       {
+               for (auto it = __dataMap.begin();  it != __dataMap.end(); it++)
+               {
+                       //DSWaylandInputPanelSurfaceData *_surfaceData = (*it).second;
+                       /* TODO:
+                        * surfaceData = _surfaceData->getSurfaceResource();
+                        * if surfaceData is focused
+                        * surfaceData = _surfaceData;
+                        * break;
+                        */
+               }
+       }
+
+       if (!surfaceData) return;
+
+       if (pub->__inputPanel->getWaitUpdate())
+       {
+               /* TODO:
+                * if (getfocus(surfaceData->getSurfaceResource())->parent)
+                * {
+                *   if (getfocus(surfaceData->getSurfaceResource())->parent == focused)
+                *   {
+                *     pub->__inputPanel->updateInputPanelState(true);
+                *   }
+                *   else
+                *     pub->__inputPanel->visibilityChange(false);
+                * }
+                * else
+                *   pub->__inputPanel->visibilityChange(false);
+                */
+       }
+}
+
+void DSWaylandInputPanelSurfacePrivate::input_panel_surface_destroy_resource(Resource *resource)
+{
+       auto it = __dataMap.find(resource);
+       if (it != __dataMap.end())
+       {
+               DSWaylandInputPanelSurfaceData *destroyData = (*it).second;
+               delete destroyData;
+               __dataMap.erase(resource);
+       }
+}
+
 void DSWaylandInputPanelSurfacePrivate::input_panel_surface_set_toplevel(Resource *resource, struct ::wl_resource *output, uint32_t position)
 {
+       /* TODO? If this surface is not included in __dataMap, add this surface */
+
+       auto it = __dataMap.find(resource);
+       if (it != __dataMap.end())
+       {
+               DSWaylandInputPanelSurfaceData *surfaceData = (*it).second;
+               surfaceData->panel = true;
+       }
 }
 
 void DSWaylandInputPanelSurfacePrivate::input_panel_surface_set_overlay_panel(Resource *resource)
 {
+       /* TODO? If this surface is not included in __dataMap, add this surface */
+
+       auto it = __dataMap.find(resource);
+       if (it != __dataMap.end())
+       {
+               DSWaylandInputPanelSurfaceData *surfaceData = (*it).second;
+               surfaceData->panel = true;
+       }
 }
 
 void DSWaylandInputPanelSurfacePrivate::input_panel_surface_set_ready(Resource *resource, uint32_t state)
 {
+       auto it = __dataMap.find(resource);
+       if (it != __dataMap.end())
+       {
+               DSWaylandInputPanelSurfaceData *surfaceData = (*it).second;
+               /* TODO: find Window and update base_output resolution */
+               show(surfaceData);
+       }
 }
 
 void DSWaylandInputPanelSurfacePrivate::input_panel_surface_set_floating_panel(Resource *resource, uint32_t state)
 {
+       /* TODO:
+        * set Window's vkbd.floating = !!state
+        * if true
+        *  policy_conformant_part_del
+        * else
+        *  policy_conformant_part_add
+        */
 }
 
 void DSWaylandInputPanelSurfacePrivate::input_panel_surface_set_floating_drag_enabled(Resource *resource, uint32_t enabled)
 {
+       DS_GET_PUB(DSWaylandInputPanelSurface);
+
+       pub->__inputPanel->setFloatingMovingRequest(!!enabled);
 }
 
 
-DSWaylandInputPanelSurface::DSWaylandInputPanelSurface()
-       : DSObject(), _d_ptr(std::make_unique<DSWaylandInputPanelSurfacePrivate>(this))
+DSWaylandInputPanelSurface::DSWaylandInputPanelSurface(DSWaylandCompositor *compositor, DSWaylandInputPanel *inputPanel)
+       : DSObject(), _d_ptr(std::make_unique<DSWaylandInputPanelSurfacePrivate>(this, compositor)),
+         __compositor(compositor),
+         __inputPanel(inputPanel)
 {
 }
 
@@ -93,4 +349,30 @@ DSWaylandInputPanelSurface::~DSWaylandInputPanelSurface()
 {
 }
 
+void DSWaylandInputPanelSurface::createGlobal(void *client, void *inputPanelResource, unsigned int id, void *surface)
+{
+       DS_GET_PRIV(DSWaylandInputPanelSurface);
+
+       if (!client || !inputPanelResource || !surface) return;
+
+       priv->createGlobal(client, inputPanelResource, id, surface);
+}
+
+void DSWaylandInputPanelSurface::clearGlobals(void *inputPanelResource)
+{
+       DS_GET_PRIV(DSWaylandInputPanelSurface);
+
+       if (!inputPanelResource) return;
+
+       priv->clearGlobals(inputPanelResource);
+}
+
+void DSWaylandInputPanelSurface::flushFrame()
+{
+       DS_GET_PRIV(DSWaylandInputPanelSurface);
+
+       priv->flushFrame();
 }
+
+}
+
index 66b80dc..33de418 100644 (file)
 
 #include "DSCore.h"
 #include "DSObject.h"
+#include "DSWaylandCompositor.h"
+#include "DSEventLoop.h"
 
 namespace display_server
 {
 
 class DSWaylandInputPanelPrivate;
+class DSWaylandInputPanelSurface;
+class DSWaylandInputPanelFloating;
 
 class DS_DECL_EXPORT DSWaylandInputPanel : public DSObject
 {
 DS_PIMPL_USE_PRIVATE(DSWaylandInputPanel);
 public:
-       DSWaylandInputPanel();
+       DSWaylandInputPanel(DSWaylandCompositor *compositor);
        ~DSWaylandInputPanel() override;
 
+       void createSurface(void *client, void *inputPanelResource, unsigned int id, void *surface);
+       void clearSurfaces(void *inputPanelResource);
+       bool getWaitUpdate();
+       void setWaitUpdate(bool waitUpdate);
+       void updateInputPanelState(bool waitUpdate);
+
+       void setFloatingMovingRequest(bool enabled);
+
 protected:
 
 private:
+       DSWaylandCompositor *__compositor;
+       DSEventLoop *__eventLoop;
+       DSWaylandInputPanelSurface *__inputPanelSurface;
+       DSWaylandInputPanelFloating *__inputPanelFloating;
+       bool __waitUpdate;
 
+       void __onEventIdleEnterer(void *data);
 };
 
 }
index 69cbc8b..7de9465 100644 (file)
@@ -37,12 +37,15 @@ class DS_DECL_EXPORT DSWaylandInputPanelPrivate : public DSObjectPrivate, public
 {
 DS_PIMPL_USE_PUBLIC(DSWaylandInputPanel);
 public:
-       DSWaylandInputPanelPrivate(DSWaylandInputPanel *p_ptr);
+       DSWaylandInputPanelPrivate(DSWaylandInputPanel *p_ptr, DSWaylandCompositor *compositor);
        ~DSWaylandInputPanelPrivate() override;
 
 protected:
+       void input_panel_destroy_resource(Resource *resource);
        void input_panel_get_input_panel_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface);
 
+private:
+       DSWaylandCompositor *__compositor;
 };
 
 }
index 94d3ab3..594f3a9 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "DSCore.h"
 #include "DSObject.h"
+#include "DSWaylandInputPanel.h"
 
 namespace display_server
 {
@@ -36,13 +37,18 @@ class DS_DECL_EXPORT DSWaylandInputPanelSurface : public DSObject
 {
 DS_PIMPL_USE_PRIVATE(DSWaylandInputPanelSurface);
 public:
-       DSWaylandInputPanelSurface();
+       DSWaylandInputPanelSurface(DSWaylandCompositor *compositor, DSWaylandInputPanel *inputPanel);
        ~DSWaylandInputPanelSurface() override;
 
+       void createGlobal(void *client, void *inputPanelResource, unsigned int id, void *surface);
+       void clearGlobals(void *inputPanelResource);
+       void flushFrame();
+
 protected:
 
 private:
-
+       DSWaylandCompositor *__compositor;
+       DSWaylandInputPanel *__inputPanel;
 };
 
 }
index 6a53974..a3cd8c9 100644 (file)
 namespace display_server
 {
 
+class DSWaylandInputPanelSurfaceData;
+
 class DS_DECL_EXPORT DSWaylandInputPanelSurfacePrivate : public DSObjectPrivate, public DSWaylandServer::wl_input_panel_surface
 {
 DS_PIMPL_USE_PUBLIC(DSWaylandInputPanelSurface);
 public:
-       DSWaylandInputPanelSurfacePrivate(DSWaylandInputPanelSurface *p_ptr);
+       DSWaylandInputPanelSurfacePrivate(DSWaylandInputPanelSurface *p_ptr, DSWaylandCompositor *compositor);
        ~DSWaylandInputPanelSurfacePrivate() override;
 
+       void createGlobal(void *client, void *inputPanelResource, unsigned int id, void *surface);
+       void clearGlobals(void *inputPanelResource);
+
+       void show(DSWaylandInputPanelSurfaceData *surfaceData);
+       void flushFrame();
+
 protected:
+       void input_panel_surface_destroy_resource(Resource *resource);
+
        void input_panel_surface_set_toplevel(Resource *resource, struct ::wl_resource *output, uint32_t position);
     void input_panel_surface_set_overlay_panel(Resource *resource);
     void input_panel_surface_set_ready(Resource *resource, uint32_t state);
     void input_panel_surface_set_floating_panel(Resource *resource, uint32_t state);
     void input_panel_surface_set_floating_drag_enabled(Resource *resource, uint32_t enabled);
 
+private:
+       DSWaylandCompositor *__compositor;
+       std::multimap<Resource*, DSWaylandInputPanelSurfaceData *> __dataMap;
 };
 
 }
index b74c09a..f3de95b 100644 (file)
@@ -58,7 +58,8 @@ TEST_F(DSWaylandInputMethodTest, ActivateDeactivate)
 
        inputMethod->activate(0);
        bool activated = inputMethod->contextActivated();
-       inputMethod->deactivate();
+       if (activated)
+               inputMethod->deactivate();
 
        delete inputMethod;
        DSWaylandCompositor::releaseInstance();
index 77c693b..ead57a2 100644 (file)
@@ -42,10 +42,63 @@ public:
 /* Test cases */
 TEST_F(DSWaylandInputPanelTest, NewDSWaylandInputPanel)
 {
-       DSWaylandInputPanel *inputPanel = new  DSWaylandInputPanel();
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
        EXPECT_TRUE(inputPanel != nullptr);
 
        delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
 }
 
+TEST_F(DSWaylandInputPanelTest, CreateClearSurface)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       EXPECT_TRUE(inputPanel != nullptr);
+
+       inputPanel->createSurface(nullptr, nullptr, 0, nullptr);
+       inputPanel->clearSurfaces(nullptr);
+
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}
+
+TEST_F(DSWaylandInputPanelTest, GetSetWaitUpdate)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       EXPECT_TRUE(inputPanel != nullptr);
+
+       inputPanel->setWaitUpdate(true);
+       bool waitUpdate = inputPanel->getWaitUpdate();
+
+       EXPECT_TRUE(waitUpdate == true);
+
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}
+
+TEST_F(DSWaylandInputPanelTest, UpdateInputPanelState)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       EXPECT_TRUE(inputPanel != nullptr);
+
+       inputPanel->updateInputPanelState(true);
+
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}
+
+TEST_F(DSWaylandInputPanelTest, SetFloatingMovingRequest)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       EXPECT_TRUE(inputPanel != nullptr);
+
+       inputPanel->setFloatingMovingRequest(true);
+
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}
 
index cbe3da5..f3c8e4a 100644 (file)
@@ -42,10 +42,42 @@ public:
 /* Test cases */
 TEST_F(DSWaylandInputPanelSurfaceTest, NewDSWaylandInputPanelSurface)
 {
-       DSWaylandInputPanelSurface *inputPanelSurface = new  DSWaylandInputPanelSurface();
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       DSWaylandInputPanelSurface *inputPanelSurface = new DSWaylandInputPanelSurface(comp, inputPanel);
        EXPECT_TRUE(inputPanelSurface != nullptr);
 
        delete inputPanelSurface;
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
 }
 
+TEST_F(DSWaylandInputPanelSurfaceTest, CreateClearGlobal)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       DSWaylandInputPanelSurface *inputPanelSurface = new DSWaylandInputPanelSurface(comp, inputPanel);
+       EXPECT_TRUE(inputPanelSurface != nullptr);
+
+       inputPanelSurface->createGlobal(nullptr, nullptr, 0, nullptr);
+       inputPanelSurface->clearGlobals(nullptr);
+
+       delete inputPanelSurface;
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}
+
+TEST_F(DSWaylandInputPanelSurfaceTest, FlushFrame)
+{
+       DSWaylandCompositor *comp = DSWaylandCompositor::getInstance();
+       DSWaylandInputPanel *inputPanel = new DSWaylandInputPanel(comp);
+       DSWaylandInputPanelSurface *inputPanelSurface = new DSWaylandInputPanelSurface(comp, inputPanel);
+       EXPECT_TRUE(inputPanelSurface != nullptr);
+
+       inputPanelSurface->flushFrame();
+
+       delete inputPanelSurface;
+       delete inputPanel;
+       DSWaylandCompositor::releaseInstance();
+}