From 13ec618d269eca7122629fd48c8fd526477ee47a Mon Sep 17 00:00:00 2001 From: jeon Date: Tue, 11 Aug 2020 21:24:50 +0900 Subject: [PATCH] DSWaylandInputPanel: process wl_input_panel_surface requests Change-Id: I3b73fb98807dc432af91f80b74b3e7bed90893d0 --- src/DSWaylandServer/DSWaylandInputPanel.cpp | 302 ++++++++++++++++++++- src/DSWaylandServer/DSWaylandInputPanel.h | 20 +- src/DSWaylandServer/DSWaylandInputPanelPrivate.h | 5 +- src/DSWaylandServer/DSWaylandInputPanelSurface.h | 10 +- .../DSWaylandInputPanelSurfacePrivate.h | 15 +- tests/DSWaylandInputMethod-test.cpp | 3 +- tests/DSWaylandInputPanel-test.cpp | 55 +++- tests/DSWaylandInputPanelSurface-test.cpp | 34 ++- 8 files changed, 426 insertions(+), 18 deletions(-) diff --git a/src/DSWaylandServer/DSWaylandInputPanel.cpp b/src/DSWaylandServer/DSWaylandInputPanel.cpp index 8a4b87f..8c604d4 100644 --- a/src/DSWaylandServer/DSWaylandInputPanel.cpp +++ b/src/DSWaylandServer/DSWaylandInputPanel.cpp @@ -25,37 +25,176 @@ #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(this)) +DSWaylandInputPanel::DSWaylandInputPanel(DSWaylandCompositor *compositor) + : DSObject(), _d_ptr(std::make_unique(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, 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(this)) +DSWaylandInputPanelSurface::DSWaylandInputPanelSurface(DSWaylandCompositor *compositor, DSWaylandInputPanel *inputPanel) + : DSObject(), _d_ptr(std::make_unique(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(); } + +} + diff --git a/src/DSWaylandServer/DSWaylandInputPanel.h b/src/DSWaylandServer/DSWaylandInputPanel.h index 66b80dc..33de418 100644 --- a/src/DSWaylandServer/DSWaylandInputPanel.h +++ b/src/DSWaylandServer/DSWaylandInputPanel.h @@ -26,23 +26,41 @@ #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); }; } diff --git a/src/DSWaylandServer/DSWaylandInputPanelPrivate.h b/src/DSWaylandServer/DSWaylandInputPanelPrivate.h index 69cbc8b..7de9465 100644 --- a/src/DSWaylandServer/DSWaylandInputPanelPrivate.h +++ b/src/DSWaylandServer/DSWaylandInputPanelPrivate.h @@ -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; }; } diff --git a/src/DSWaylandServer/DSWaylandInputPanelSurface.h b/src/DSWaylandServer/DSWaylandInputPanelSurface.h index 94d3ab3..594f3a9 100644 --- a/src/DSWaylandServer/DSWaylandInputPanelSurface.h +++ b/src/DSWaylandServer/DSWaylandInputPanelSurface.h @@ -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; }; } diff --git a/src/DSWaylandServer/DSWaylandInputPanelSurfacePrivate.h b/src/DSWaylandServer/DSWaylandInputPanelSurfacePrivate.h index 6a53974..a3cd8c9 100644 --- a/src/DSWaylandServer/DSWaylandInputPanelSurfacePrivate.h +++ b/src/DSWaylandServer/DSWaylandInputPanelSurfacePrivate.h @@ -33,20 +33,33 @@ 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 __dataMap; }; } diff --git a/tests/DSWaylandInputMethod-test.cpp b/tests/DSWaylandInputMethod-test.cpp index b74c09a..f3de95b 100644 --- a/tests/DSWaylandInputMethod-test.cpp +++ b/tests/DSWaylandInputMethod-test.cpp @@ -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(); diff --git a/tests/DSWaylandInputPanel-test.cpp b/tests/DSWaylandInputPanel-test.cpp index 77c693b..ead57a2 100644 --- a/tests/DSWaylandInputPanel-test.cpp +++ b/tests/DSWaylandInputPanel-test.cpp @@ -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(); +} diff --git a/tests/DSWaylandInputPanelSurface-test.cpp b/tests/DSWaylandInputPanelSurface-test.cpp index cbe3da5..f3c8e4a 100644 --- a/tests/DSWaylandInputPanelSurface-test.cpp +++ b/tests/DSWaylandInputPanelSurface-test.cpp @@ -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(); +} -- 2.7.4