From 272d3d729fa85b799f907d3185730ca4af9f2072 Mon Sep 17 00:00:00 2001 From: Doyoun Kang Date: Tue, 18 Aug 2020 16:31:35 +0900 Subject: [PATCH] DSWindowManager: add register/unregister zone/surface Change-Id: I0993c30c11572ece50df11c620974f1cb51e8352 --- src/DSWindowManager/DSWindowManager.cpp | 212 ++++++++++++++++++++++++++- src/DSWindowManager/DSWindowManager.h | 15 ++ src/DSWindowManager/DSWindowManagerPrivate.h | 32 +++- src/DSZone/DSZone.cpp | 17 ++- src/DSZone/DSZone.h | 2 + tests/DSWindowManager-test.cpp | 72 ++++++++- 6 files changed, 343 insertions(+), 7 deletions(-) diff --git a/src/DSWindowManager/DSWindowManager.cpp b/src/DSWindowManager/DSWindowManager.cpp index 10dc622..5eaa293 100644 --- a/src/DSWindowManager/DSWindowManager.cpp +++ b/src/DSWindowManager/DSWindowManager.cpp @@ -23,6 +23,9 @@ #include "DSWindowManager.h" #include "DSWindowManagerPrivate.h" +#include "DSZone.h" +#include "DSWindow.h" +#include "DSWaylandSurface.h" #include "DSDebugLog.h" namespace display_server @@ -43,6 +46,163 @@ DSWindowManagerPrivate::~DSWindowManagerPrivate() { } +DSZone *DSWindowManagerPrivate::__getZone(DSWindow *window) +{ + auto it = __zoneWinMap.find(window); + if (it != __zoneWinMap.end()) + return it->second; + + return nullptr; +} + +DSZone *DSWindowManagerPrivate::__getZone(DSWaylandSurface *surface) +{ + auto it = __zoneSurfaceMap.find(surface); + if (it != __zoneSurfaceMap.end()) + return it->second; + + return nullptr; +} + +bool DSWindowManagerPrivate::__checkZone(DSZone *zone) +{ + std::list zList = __zoneList; + for (DSZone *z : zList) + { + if (z == zone) + { + return true; + } + } + + return false; +} + +void DSWindowManagerPrivate::__registerZone(DSZone *zone) +{ + __zoneList.push_front(zone); +} + +bool DSWindowManagerPrivate::registerZone(DSZone *zone) +{ + // find zone in zone List + if (__checkZone(zone)) + { + // Error... Already exist!!! + return false; + } + + DSLOG_DBG("WindowManager", "Register Zone:%p", zone); + // add zone to list + __registerZone(zone); + return true; +} + +void DSWindowManagerPrivate::__unregisterZone(DSZone *zone) +{ + __zoneList.remove(zone); +} + +void DSWindowManagerPrivate::unregisterZone(DSZone *zone) +{ + // find zone in zone list + if (!__checkZone(zone)) return; + + DSLOG_DBG("WindowManager", "Unregister Zone:%p", zone); + // remove zone from list + __unregisterZone(zone); +} + +void DSWindowManagerPrivate::__registerWindow(DSZone *zone, DSWindow *window) +{ + __zoneWinMap.insert(std::make_pair(window, zone)); +} + +bool DSWindowManagerPrivate::registerWindow(DSZone *zone, DSWindow *window) +{ + // find zone in zone list + if (!__checkZone(zone)) + { + // Error.. Zone is not exist + return false; + } + + // map window to zone + __registerWindow(zone, window); + return true; +} + +void DSWindowManagerPrivate::__unregisterWindow(DSWindow *window) +{ + __zoneWinMap.erase(window); +} + +void DSWindowManagerPrivate::unregisterWindow(DSZone *zone, DSWindow *window) +{ + // find zone in zone list + if (!__checkZone(zone)) + { + // Error.. Zone is not exist + return; + } + + // unmap window from zone + __unregisterWindow(window); +} + +DSZone *DSWindowManagerPrivate::getZone(DSWindow *window) +{ + return __getZone(window); +} + +void DSWindowManagerPrivate::__registerSurface(DSZone *zone, DSWaylandSurface *surface) +{ + __zoneSurfaceMap.insert(std::make_pair(surface, zone)); +} + +bool DSWindowManagerPrivate::registerSurface(DSZone *zone, DSWaylandSurface *surface) +{ + // find zone in zone list + if (!__checkZone(zone)) + { + // Error.. Zone is not exist + return false; + } + + DSLOG_DBG("WindowManager", "Register Surface:%p to Zone:%p", surface, zone); + + // map window to zone + __registerSurface(zone, surface); + return true; +} + +void DSWindowManagerPrivate::__unregisterSurface(DSWaylandSurface *surface) +{ + __zoneSurfaceMap.erase(surface); +} + +void DSWindowManagerPrivate::unregisterSurface(DSZone *zone, DSWaylandSurface *surface) +{ + // find zone in zone list + if (!__checkZone(zone)) + { + // Error.. Zone is not exist + return; + } + + DSLOG_DBG("WindowManager", "Unregister Surface:%p from Zone:%p", surface, zone); + + // unmap window from zone + __unregisterSurface(surface); +} + +DSZone *DSWindowManagerPrivate::getZone(DSWaylandSurface *surface) +{ + return __getZone(surface); +} + + + DSWindowManager::DSWindowManager(DSObject *parent) : DS_INIT_PRIVATE_PTR(DSWindowManager) { @@ -53,6 +213,7 @@ DSWindowManager::~DSWindowManager() } /* getInstance for DSWindowManager singleton */ +//static DSWindowManager *DSWindowManager::getInstance() { std::lock_guard tLock(__mutex); @@ -72,6 +233,7 @@ DSWindowManager *DSWindowManager::getInstance() } /* releaseInstance for DSWindowManager singleton */ +// static void DSWindowManager::releaseInstance() { std::lock_guard tLock(__mutex); @@ -91,5 +253,53 @@ void DSWindowManager::releaseInstance() } } +bool DSWindowManager::registerZone(DSZone *zone) +{ + DS_GET_PRIV(DSWindowManager); + return priv->registerZone(zone); +} + +void DSWindowManager::unregisterZone(DSZone *zone) +{ + DS_GET_PRIV(DSWindowManager); + priv->unregisterZone(zone); +} + +bool DSWindowManager::registerWindow(DSZone *zone, DSWindow *window) +{ + DS_GET_PRIV(DSWindowManager); + return priv->registerWindow(zone, window); +} + +void DSWindowManager::unregisterWindow(DSZone *zone, DSWindow *window) +{ + DS_GET_PRIV(DSWindowManager); + priv->unregisterWindow(zone, window); +} + +DSZone *DSWindowManager::getZone(DSWindow *window) +{ + DS_GET_PRIV(DSWindowManager); + return priv->getZone(window); +} + +bool DSWindowManager::registerSurface(DSZone *zone, DSWaylandSurface *surface) +{ + DS_GET_PRIV(DSWindowManager); + return priv->registerSurface(zone, surface); +} + +void DSWindowManager::unregisterSurface(DSZone *zone, DSWaylandSurface *surface) +{ + DS_GET_PRIV(DSWindowManager); + priv->unregisterSurface(zone, surface); +} + +DSZone *DSWindowManager::getZone(DSWaylandSurface *surface) +{ + DS_GET_PRIV(DSWindowManager); + return priv->getZone(surface); +} + -} // namespace display_server \ No newline at end of file +} // namespace display_server diff --git a/src/DSWindowManager/DSWindowManager.h b/src/DSWindowManager/DSWindowManager.h index 0dd3252..7ad2f0d 100644 --- a/src/DSWindowManager/DSWindowManager.h +++ b/src/DSWindowManager/DSWindowManager.h @@ -31,6 +31,9 @@ namespace display_server { class DSWindowManagerPrivate; +class DSZone; +class DSWindow; +class DSWaylandSurface; class DSWindowManager : public DSObject { @@ -40,6 +43,18 @@ public: static DSWindowManager *getInstance(); static void releaseInstance(); + // APIs for DSZone related + bool registerZone(DSZone *zone); + void unregisterZone(DSZone *zone); + + bool registerWindow(DSZone *zone, DSWindow *window); + void unregisterWindow(DSZone *zone, DSWindow *window); + DSZone *getZone(DSWindow *window); + + bool registerSurface(DSZone *zone, DSWaylandSurface *surface); + void unregisterSurface(DSZone *zone, DSWaylandSurface *surface); + DSZone *getZone(DSWaylandSurface *surface); + protected: private: diff --git a/src/DSWindowManager/DSWindowManagerPrivate.h b/src/DSWindowManager/DSWindowManagerPrivate.h index 8538009..f92b0d7 100644 --- a/src/DSWindowManager/DSWindowManagerPrivate.h +++ b/src/DSWindowManager/DSWindowManagerPrivate.h @@ -24,6 +24,7 @@ #ifndef __DS_WINDOW_MANAGER_PRIVATE__ #define __DS_WINDOW_MANAGER_PRIVATE__ +#include #include "DSWindowManager.h" namespace display_server @@ -38,9 +39,38 @@ public: DSWindowManagerPrivate(DSWindowManager *p_ptr); ~DSWindowManagerPrivate(); + bool registerZone(DSZone *zone); + void unregisterZone(DSZone *zone); + + bool registerWindow(DSZone *zone, DSWindow *window); + void unregisterWindow(DSZone *zone, DSWindow *window); + DSZone *getZone(DSWindow *window); + + bool registerSurface(DSZone *zone, DSWaylandSurface *surface); + void unregisterSurface(DSZone *zone, DSWaylandSurface *surface); + DSZone *getZone(DSWaylandSurface *surface); + +private: + DSZone *__getZone(DSWindow *window); + DSZone *__getZone(DSWaylandSurface *surface); + bool __checkZone(DSZone *zone); + + void __registerZone(DSZone *zone); + void __unregisterZone(DSZone *zone); + + void __registerWindow(DSZone *zone, DSWindow *window); + void __unregisterWindow(DSWindow *window); + + void __registerSurface(DSZone *zone, DSWaylandSurface *surface); + void __unregisterSurface(DSWaylandSurface *surface); + + private: + std::list __zoneList; + std::unordered_map __zoneWinMap; + std::unordered_map __zoneSurfaceMap; }; } // namespace display_server -#endif \ No newline at end of file +#endif diff --git a/src/DSZone/DSZone.cpp b/src/DSZone/DSZone.cpp index c1844c3..a838a28 100644 --- a/src/DSZone/DSZone.cpp +++ b/src/DSZone/DSZone.cpp @@ -34,12 +34,17 @@ namespace display_server DSZone::DSZone() : __position{0, 0}, __size{0, 0}, - __waylandCompositor(nullptr) + __waylandCompositor(nullptr), + __wm(nullptr) { __waylandCompositor = DSWaylandCompositor::getInstance(); __waylandCompositor->registerCallbackSurfaceCreated(this, std::bind(&DSZone::__onSurfaceCreated, this, std::placeholders::_1)); __waylandCompositor->registerCallbackSurfaceDestroy(this, std::bind(&DSZone::__onSurfaceDestroy, this, std::placeholders::_1)); + __wm = DSWindowManager::getInstance(); + if (__wm) + __wm->registerZone(this); + __waylandShell = __waylandCompositor->getShell(); if (__waylandShell) __waylandShell->registerCallbackShellSurfaceCreated(this, std::bind(&DSZone::__onShellSurfaceCreated, this, std::placeholders::_1)); @@ -47,6 +52,10 @@ DSZone::DSZone() DSZone::~DSZone() { + if (__wm) + __wm->unregisterZone(this); + + DSWindowManager::releaseInstance(); DSWaylandCompositor::releaseInstance(); } @@ -99,6 +108,9 @@ void DSZone::__onSurfaceCreated(std::shared_ptr waylandSurface { DSLOG_DBG("DSZone", "waylandSurface:(shared:%p, pure:%p)", waylandSurface, waylandSurface.get()); + if (__wm) + __wm->registerSurface(this, waylandSurface.get()); + // create DSWindow std::shared_ptr window = __createWindow(waylandSurface); @@ -113,6 +125,9 @@ void DSZone::__onSurfaceDestroy(std::shared_ptr waylandSurface { DSWaylandSurface *dswSurfacePtr = waylandSurface.get(); + if (__wm) + __wm->unregisterSurface(this, dswSurfacePtr); + DSWindowShell *shell = __findWindowShell(dswSurfacePtr); __destroyWindowShell(shell, dswSurfacePtr); diff --git a/src/DSZone/DSZone.h b/src/DSZone/DSZone.h index e464e31..5bbf38f 100644 --- a/src/DSZone/DSZone.h +++ b/src/DSZone/DSZone.h @@ -25,6 +25,7 @@ #define __DS_ZONE_H__ #include +#include "DSWindowManager.h" #include "DSWindow.h" #include "DSWindowShell.h" #include "DSSignal.h" @@ -80,6 +81,7 @@ private: std::list> __windowList; std::list> __windowShellList; DSWaylandCompositor *__waylandCompositor; + DSWindowManager *__wm; IDSWaylandShell *__waylandShell; std::map __windowShellMap; diff --git a/tests/DSWindowManager-test.cpp b/tests/DSWindowManager-test.cpp index 918651e..319d418 100644 --- a/tests/DSWindowManager-test.cpp +++ b/tests/DSWindowManager-test.cpp @@ -24,24 +24,88 @@ #include "libds-tests.h" #include "DSWaylandCompositor.h" #include "DSWindowManager.h" +#include "DSZone.h" +#include "DSWindow.h" +#include "DSWaylandSurface.h" + using namespace display_server; +DSWindowManager* g_winMgr = nullptr; + class DSWindowManagerTest : public ::testing::Test { public: void SetUp(void) override { - setenv("XDG_RUNTIME_DIR", "/run", 1); + g_winMgr = DSWindowManager::getInstance(); } void TearDown(void) override { - unsetenv("XDG_RUNTIME_DIR"); + DSWindowManager::releaseInstance(); + g_winMgr = nullptr; } }; TEST_F(DSWindowManagerTest, GetWindowManager) { - DSWindowManager* winMgr = DSWindowManager::getInstance(); - EXPECT_TRUE(winMgr != nullptr); + EXPECT_TRUE(g_winMgr != nullptr); +} + +TEST_F(DSWindowManagerTest, RegisterWindow) +{ + bool ret = false; + DSZone *foundZone = nullptr; + + EXPECT_TRUE(g_winMgr != nullptr); + + auto zone = std::make_shared(); + EXPECT_TRUE(zone != nullptr); + + auto window = std::make_shared(); + EXPECT_TRUE(window != nullptr); + + foundZone = g_winMgr->getZone(window.get()); + EXPECT_TRUE(foundZone == nullptr); + + ret = g_winMgr->registerWindow(zone.get(), window.get()); + EXPECT_TRUE(ret == true); + + foundZone = g_winMgr->getZone(window.get()); + EXPECT_TRUE(foundZone == zone.get()); + + g_winMgr->unregisterWindow(zone.get(), window.get()); + + foundZone = g_winMgr->getZone(window.get()); + EXPECT_TRUE(foundZone == nullptr); +} + +TEST_F(DSWindowManagerTest, RegisterSurface) +{ + bool ret = false; + DSZone *foundZone = nullptr; + + EXPECT_TRUE(g_winMgr != nullptr); + + auto zone = std::make_shared(); + EXPECT_TRUE(zone != nullptr); + + auto surface = std::make_shared(); + EXPECT_TRUE(surface != nullptr); + + foundZone = g_winMgr->getZone(surface.get()); + EXPECT_TRUE(foundZone == nullptr); + + ret = g_winMgr->registerSurface(zone.get(), surface.get()); + EXPECT_TRUE(ret == true); + + foundZone = g_winMgr->getZone(surface.get()); + EXPECT_TRUE(foundZone == zone.get()); + + g_winMgr->unregisterSurface(zone.get(), surface.get()); + + foundZone = g_winMgr->getZone(surface.get()); + EXPECT_TRUE(foundZone == nullptr); } + + -- 2.7.4