2 * Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 #include "DSWaylandCompositor.h"
26 #include "DSWaylandSurface.h"
27 #include "IDSWaylandShell.h"
28 #include "DSWaylandZxdgShellV6.h"
29 #include "DSDebugLog.h"
31 namespace display_server
37 __waylandCompositor(nullptr),
40 __waylandShell(nullptr),
43 __waylandCompositor = DSWaylandCompositor::getInstance();
44 if (__waylandCompositor)
46 __waylandCompositor->registerCallbackSurfaceCreated(this, std::bind(&DSZone::__onSurfaceCreated, this, std::placeholders::_1));
47 __waylandCompositor->registerCallbackSurfaceDestroy(this, std::bind(&DSZone::__onSurfaceDestroy, this, std::placeholders::_1));
49 __wm = DSWindowManager::getInstance();
51 __wm->registerZone(this);
53 __eventLoop = DSEventLoop::getInstance();
55 __eventLoop->registerCallbackIdleEnterer(this, std::bind(&DSZone::__onEventIdleEnterer, this, std::placeholders::_1));
58 __waylandShell = __waylandCompositor->getShell();
60 __waylandShell->registerCallbackShellSurfaceCreated(this, std::bind(&DSZone::__onShellSurfaceCreated, this, std::placeholders::_1));
63 __setSupportAuxHints();
69 __wm->unregisterZone(this);
71 DSEventLoop::releaseInstance();
73 DSWindowManager::releaseInstance();
74 if (__waylandCompositor)
75 DSWaylandCompositor::releaseInstance();
78 void DSZone::__setSupportAuxHints(void)
80 __supportedAuxHints.push_back("wm.policy.win.user.geometry");
83 void DSZone::setPosition(stPosition &position)
85 __position.x = position.x;
86 __position.y = position.y;
89 void DSZone::setSize(stSize &size)
95 stPosition DSZone::getPosition()
98 position.x = __position.x;
99 position.y = __position.y;
104 stSize DSZone::getSize()
113 void DSZone::registerCallbackWindowCreated(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
115 __windowCreatedSignal.connect(slot, func);
118 void DSZone::registerCallbackWindowShellCreated(DSObject *slot, std::function<void(std::shared_ptr<DSWindowShell>)> func)
120 __windowShellCreatedSignal.connect(slot, func);
123 void DSZone::registerCallbackWindowStackChanged(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
125 __windowStackChangedSignal.connect(slot, func);
128 void DSZone::registerCallbackWindowDestroy(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
130 __windowDestroySignal.connect(slot, func);
133 void DSZone::callCallbackWindowCreated()
135 __windowCreatedSignal.emit(nullptr);
138 void DSZone::__onEventIdleEnterer(void *data)
142 DSLOG_DBG("DSZone", "Calculate Visibility...");
144 // calculate visibility?
145 __stackChanged = false;
149 void DSZone::__onSurfaceCreated(std::shared_ptr<DSWaylandSurface> waylandSurface)
151 DSLOG_DBG("DSZone", "waylandSurface:(shared:%p, pure:%p)", waylandSurface, waylandSurface.get());
154 __wm->registerSurface(this, waylandSurface.get());
157 std::shared_ptr<DSWindow> window = __createWindow(waylandSurface);
159 // create DSWindowShell
160 std::shared_ptr<DSWindowShell> shell = __createWindowShell(window);
162 // set DSWindowShell to DSWindow
163 window->setWindowShell(shell.get());
166 void DSZone::__onSurfaceDestroy(std::shared_ptr<DSWaylandSurface> waylandSurface)
168 DSWaylandSurface *dswSurfacePtr = waylandSurface.get();
171 __wm->unregisterSurface(this, dswSurfacePtr);
173 DSWindowShell *shell = __findWindowShell(dswSurfacePtr);
174 __destroyWindowShell(shell, dswSurfacePtr);
176 std::shared_ptr<DSWindow> window = __findWindow(dswSurfacePtr);
177 __destroyWindow(window);
180 void DSZone::__onShellSurfaceCreated(IDSWaylandShellSurface *waylandShellSurface)
182 DSLOG_DBG("DSZone", "waylandShellSurface:(pure:%p)", waylandShellSurface);
184 if (waylandShellSurface)
186 struct ::wl_resource *wlSurface = waylandShellSurface->getWlSurface();
187 DSLOG_DBG("DSZone", "get wl_surface:%p", wlSurface);
189 DSWaylandSurface *dsSurface = waylandShellSurface->getSurface();
190 DSLOG_DBG("DSZone", "get DSWaylandSurface:%p", dsSurface);
194 // find DSWindowShell associated with DSWaylandSurface
195 DSWindowShell *dsWinShell = __findWindowShell(dsSurface);
198 DSLOG_DBG("DSZONE", "Find DSWindowShell (%p)... setShellSurface!", dsWinShell);
199 dsWinShell->setShellSurface(waylandShellSurface);
206 void DSZone::callCallbackWindowShellCreated(std::shared_ptr<DSWindowShell> winShell)
208 __windowShellCreatedSignal.emit(winShell);
211 bool DSZone::testCreateWindow(std::shared_ptr<DSWaylandSurface> waylandSurface)
213 std::shared_ptr<DSWindow> window = __createWindow(waylandSurface);
214 if (!window) return false;
219 std::list<std::shared_ptr<DSWindow>> DSZone::getWindowList()
224 std::list<std::shared_ptr<DSWindowShell>> DSZone::getWindowShellList()
226 return __windowShellList;
229 void DSZone::__prependWindowList(std::shared_ptr<DSWindow> window)
231 __windowList.remove(window);
232 __windowList.push_front(window);
234 __stackChanged = true;
235 __updateWindowOrder();
237 std::shared_ptr<DSWindow> wTop(__windowList.front());
239 __windowStackChangedSignal.emit(wTop);
242 void DSZone::__appendWindowList(std::shared_ptr<DSWindow> window)
244 __windowList.remove(window);
245 __windowList.push_back(window);
247 __stackChanged = true;
248 __updateWindowOrder();
250 std::shared_ptr<DSWindow> wTop(__windowList.front());
252 __windowStackChangedSignal.emit(wTop);
255 std::shared_ptr<DSWindow> DSZone::__findWindow(DSWaylandSurface *dswlSurface)
257 std::list<std::shared_ptr<DSWindow>> wList = getWindowList();
260 if (w->surface() == dswlSurface)
262 DSLOG_INF("DSZone", "Window found (win=%p, surface=%p)", w, dswlSurface);
270 DSWindowShell *DSZone::__findWindowShell(DSWaylandSurface *dswlSurface)
272 DSWindowShell *dsWinShell = nullptr;
274 std::map<DSWaylandSurface*, DSWindowShell*>::iterator iter;
275 iter = __windowShellMap.find(dswlSurface);
276 if(iter == __windowShellMap.end())
278 DSLOG_DBG("DSZone", "Doesn't Exist DSWindowShell... DSWaylandSurface(%p)", dswlSurface);
282 dsWinShell = iter->second;
283 DSLOG_DBG("DSZone", "Find DSWindowShell(%p)... DSWaylandSurface(%p)", dsWinShell, dswlSurface);
288 std::shared_ptr<DSWindow> DSZone::__createWindow(std::shared_ptr<DSWaylandSurface> waylandSurface)
290 std::shared_ptr<DSWindow> window = std::make_shared<DSWindow>(waylandSurface);
291 __prependWindowList(window);
293 // emit a signal of the surface committed
294 __windowCreatedSignal.emit(window);
299 void DSZone::__destroyWindow(std::shared_ptr<DSWindow> window)
301 __windowDestroySignal.emit(window);
302 __windowList.remove(window);
304 __stackChanged = true;
305 __updateWindowOrder();
307 std::shared_ptr<DSWindow> wTop(__windowList.front());
309 __windowStackChangedSignal.emit(wTop);
312 void DSZone::__updateWindowOrder(void)
315 std::list<std::shared_ptr<DSWindow>> wList = getWindowList();
318 /* TODO : check if the w is in its visible state */
319 w->setZOrder(zOrder++);
323 std::shared_ptr<DSWindowShell> DSZone::__createWindowShell(std::shared_ptr<DSWindow> window)
325 DSWindow *ptrWindow = window.get();
327 std::shared_ptr<DSWindowShell> shell = std::make_shared<DSWindowShell>(ptrWindow);
328 __windowShellList.push_front(shell);
330 __windowShellMap.insert(std::make_pair(ptrWindow->surface(), shell.get()));
332 // emit a signal of the shell created
333 __windowShellCreatedSignal.emit(shell);
338 void DSZone::__destroyWindowShell(DSWindowShell* windowShell, DSWaylandSurface *surface)
341 __windowShellMap.erase(surface);
343 // remove from __windowShellList
344 std::list<std::shared_ptr<DSWindowShell>> wsList = getWindowShellList();
345 for (auto ws : wsList)
347 if (ws.get() == windowShell)
349 __windowShellDestroySignal.emit(ws);
350 __windowShellList.remove(ws);
356 bool DSZone::setWindowParent(DSWaylandSurface *dswlSurface, DSWaylandSurface *dswlParentSurface)
358 DSWindowShell *wShell = __findWindowShell(dswlSurface);
359 if (!wShell) return false;
361 DSWindowShell *pwShell = __findWindowShell(dswlParentSurface);
363 return wShell->setParent(pwShell);
366 bool DSZone::setWindowTitle(DSWaylandSurface *dswSurface, const std::string &title)
368 DSWindowShell *wShell = __findWindowShell(dswSurface);
369 if (!wShell) return false;
371 return wShell->setTitle(title);
374 std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
375 if (!window) return false;
377 return window->setTitle(title);
381 bool DSZone::setWindowType(DSWaylandSurface *dswSurface, int type)
383 DSWindowShell *wShell = __findWindowShell(dswSurface);
384 if (!wShell) return false;
386 return wShell->setType(type);
389 std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
390 if (!window) return false;
392 return window->setType(type);
396 bool DSZone::setWindowGeometry(DSWaylandSurface *dswSurface, int x, int y, unsigned int w, unsigned h)
398 DSWindowShell *wShell = __findWindowShell(dswSurface);
399 if (!wShell) return false;
401 return wShell->setGeometry(x, y, w, h);
404 std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
405 if (!window) return false;
407 return window->setGeometry(x, y, w, h);
411 bool DSZone::setWindowPosition(DSWaylandSurface *dswSurface, int x, int y)
413 DSWindowShell *wShell = __findWindowShell(dswSurface);
414 if (!wShell) return false;
416 return wShell->setPosition(x, y);
419 std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
420 if (!window) return false;
422 return window->setPosition(x, y);
426 stGeometry DSZone::getWindowGeometry(DSWaylandSurface *dswSurface)
428 stGeometry geometry = {0, };
429 DSWindowShell *wShell = __findWindowShell(dswSurface);
430 if (!wShell) return geometry;
432 return wShell->getGeometry();
435 void DSZone::addWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id, const std::string &name, const std::string &value)
437 DSWindowShell *wShell = __findWindowShell(dswlSurface);
440 wShell->addAuxHint(id, name, value);
443 void DSZone::changeWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id, const std::string &value)
445 DSWindowShell *wShell = __findWindowShell(dswlSurface);
448 wShell->changeAuxHint(id, value);
451 void DSZone::removeWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id)
453 DSWindowShell *wShell = __findWindowShell(dswlSurface);
456 wShell->removeAuxHint(id);
459 std::list<std::string> DSZone::getWindowSupportedAuxHints(DSWaylandSurface *dswlSurface)
461 // TODO: we have to change code to use DSPolicy instead of DSZone
462 return __supportedAuxHints;
465 void DSZone::activateWindow(DSWaylandSurface *dswlSurface)
467 if (!dswlSurface) return;
469 std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
470 __prependWindowList(window);
472 DSWindowShell *wShell = __findWindowShell(dswlSurface);
478 void DSZone::raiseWindow(DSWaylandSurface* dswlSurface)
480 if (!dswlSurface) return;
482 std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
483 __prependWindowList(window);
485 DSWindowShell *wShell = __findWindowShell(dswlSurface);
491 void DSZone::lowerWindow(DSWaylandSurface* dswlSurface)
493 if (!dswlSurface) return;
495 std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
496 __appendWindowList(window);
498 DSWindowShell *wShell = __findWindowShell(dswlSurface);
504 void DSZone::setWindowSkipFocus(DSWaylandSurface *dswlSurface, bool set)
506 DSWindowShell *wShell = __findWindowShell(dswlSurface);
509 wShell->setSkipFocus(set);
512 bool DSZone::setWindowVkbdFloating(DSWaylandSurface *dswlsurface, bool set)
514 DSWindowShell *wShell = __findWindowShell(dswlsurface);
515 if (!wShell) return false;
517 return wShell->setVkbdFloating(set);
520 bool DSZone::getWindowVkbdFloating(DSWaylandSurface *dswlsurface)
522 DSWindowShell *wShell = __findWindowShell(dswlsurface);
523 if (!wShell) return false;
525 return wShell->getVkbdFloating();
527 } // namespace display_server