3af703e1d5b09b460f1cec58bffbaf1eb02c34fb
[platform/core/uifw/libds.git] / src / DSZone / DSZone.cpp
1 /*
2 * Copyright © 2020 Samsung Electronics co., Ltd. All Rights Reserved.
3 *
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:
10 *
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
13 * Software.
14 *
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.
22 */
23
24 #include "DSZone.h"
25 #include "DSWaylandCompositor.h"
26 #include "DSWaylandSurface.h"
27 #include "IDSWaylandShell.h"
28 #include "DSWaylandZxdgShellV6.h"
29 #include "DSDebugLog.h"
30
31 namespace display_server
32 {
33
34 DSZone::DSZone()
35         : __position{0, 0},
36           __size{0, 0},
37           __waylandCompositor(nullptr),
38           __wm(nullptr),
39           __eventLoop(nullptr),
40           __waylandShell(nullptr),
41           __stackChanged(false)
42 {
43         __waylandCompositor = DSWaylandCompositor::getInstance();
44         if (__waylandCompositor)
45         {
46                 __waylandCompositor->registerCallbackSurfaceCreated(this, std::bind(&DSZone::__onSurfaceCreated, this, std::placeholders::_1));
47                 __waylandCompositor->registerCallbackSurfaceDestroy(this, std::bind(&DSZone::__onSurfaceDestroy, this, std::placeholders::_1));
48
49                 __wm = DSWindowManager::getInstance();
50                 if (__wm)
51                         __wm->registerZone(this);
52
53                 __eventLoop = DSEventLoop::getInstance();
54                 if (__eventLoop)
55                         __eventLoop->registerCallbackIdleEnterer(this, std::bind(&DSZone::__onEventIdleEnterer, this, std::placeholders::_1));
56
57
58                 __waylandShell = __waylandCompositor->getShell();
59                 if (__waylandShell)
60                         __waylandShell->registerCallbackShellSurfaceCreated(this, std::bind(&DSZone::__onShellSurfaceCreated, this, std::placeholders::_1));
61         }
62
63         __setSupportAuxHints();
64 }
65
66 DSZone::~DSZone()
67 {
68         if (__wm)
69                 __wm->unregisterZone(this);
70         if (__eventLoop)
71                 DSEventLoop::releaseInstance();
72         if (__wm)
73                 DSWindowManager::releaseInstance();
74         if (__waylandCompositor)
75                 DSWaylandCompositor::releaseInstance();
76 }
77
78 void DSZone::__setSupportAuxHints(void)
79 {
80         __supportedAuxHints.push_back("wm.policy.win.user.geometry");
81 }
82
83 void DSZone::setPosition(stPosition &position)
84 {
85         __position.x = position.x;
86         __position.y = position.y;
87 }
88
89 void DSZone::setSize(stSize &size)
90 {
91         __size.w = size.w;
92         __size.h = size.h;
93 }
94
95 stPosition DSZone::getPosition()
96 {
97         stPosition position;
98         position.x = __position.x;
99         position.y = __position.y;
100
101         return position;
102 }
103
104 stSize DSZone::getSize()
105 {
106         stSize size;
107         size.w = __size.w;
108         size.h = __size.h;
109
110         return size;
111 }
112
113 void DSZone::registerCallbackWindowCreated(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
114 {
115         __windowCreatedSignal.connect(slot, func);
116 }
117
118 void DSZone::registerCallbackWindowShellCreated(DSObject *slot, std::function<void(std::shared_ptr<DSWindowShell>)> func)
119 {
120         __windowShellCreatedSignal.connect(slot, func);
121 }
122
123 void DSZone::registerCallbackWindowStackChanged(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
124 {
125         __windowStackChangedSignal.connect(slot, func);
126 }
127
128 void DSZone::registerCallbackWindowDestroy(DSObject *slot, std::function<void(std::shared_ptr<DSWindow>)> func)
129 {
130         __windowDestroySignal.connect(slot, func);
131 }
132
133 void DSZone::callCallbackWindowCreated()
134 {
135         __windowCreatedSignal.emit(nullptr);
136 }
137
138 void DSZone::__onEventIdleEnterer(void *data)
139 {
140         if (__stackChanged)
141         {
142                 DSLOG_DBG("DSZone", "Calculate Visibility...");
143
144                 // calculate visibility?
145                 __stackChanged = false;
146         }
147 }
148
149 void DSZone::__onSurfaceCreated(std::shared_ptr<DSWaylandSurface> waylandSurface)
150 {
151         DSLOG_DBG("DSZone", "waylandSurface:(shared:%p, pure:%p)", waylandSurface, waylandSurface.get());
152
153         if (__wm)
154                 __wm->registerSurface(this, waylandSurface.get());
155
156         // create DSWindow
157         std::shared_ptr<DSWindow> window = __createWindow(waylandSurface);
158
159         // create DSWindowShell
160         std::shared_ptr<DSWindowShell> shell = __createWindowShell(window);
161
162         // set DSWindowShell to DSWindow
163         window->setWindowShell(shell.get());
164 }
165
166 void DSZone::__onSurfaceDestroy(std::shared_ptr<DSWaylandSurface> waylandSurface)
167 {
168         DSWaylandSurface *dswSurfacePtr = waylandSurface.get();
169
170         if (__wm)
171                 __wm->unregisterSurface(this, dswSurfacePtr);
172
173         DSWindowShell *shell = __findWindowShell(dswSurfacePtr);
174         __destroyWindowShell(shell, dswSurfacePtr);
175
176         std::shared_ptr<DSWindow> window = __findWindow(dswSurfacePtr);
177         __destroyWindow(window);
178 }
179
180 void DSZone::__onShellSurfaceCreated(IDSWaylandShellSurface *waylandShellSurface)
181 {
182         DSLOG_DBG("DSZone", "waylandShellSurface:(pure:%p)", waylandShellSurface);
183
184         if (waylandShellSurface)
185         {
186                 struct ::wl_resource *wlSurface = waylandShellSurface->getWlSurface();
187                 DSLOG_DBG("DSZone", "get wl_surface:%p", wlSurface);
188
189                 DSWaylandSurface *dsSurface = waylandShellSurface->getSurface();
190                 DSLOG_DBG("DSZone", "get DSWaylandSurface:%p", dsSurface);
191
192                 if (dsSurface)
193                 {
194                         // find DSWindowShell associated with DSWaylandSurface
195                         DSWindowShell *dsWinShell = __findWindowShell(dsSurface);
196                         if (dsWinShell)
197                         {
198                                 DSLOG_DBG("DSZONE", "Find DSWindowShell (%p)... setShellSurface!", dsWinShell);
199                                 dsWinShell->setShellSurface(waylandShellSurface);
200                         }
201                 }
202         }
203 }
204
205 // for Test
206 void DSZone::callCallbackWindowShellCreated(std::shared_ptr<DSWindowShell> winShell)
207 {
208         __windowShellCreatedSignal.emit(winShell);
209 }
210
211 bool DSZone::testCreateWindow(std::shared_ptr<DSWaylandSurface> waylandSurface)
212 {
213         std::shared_ptr<DSWindow> window = __createWindow(waylandSurface);
214         if (!window) return false;
215
216         return true;
217 }
218
219 std::list<std::shared_ptr<DSWindow>> DSZone::getWindowList()
220 {
221         return __windowList;
222 }
223
224 std::list<std::shared_ptr<DSWindowShell>> DSZone::getWindowShellList()
225 {
226         return __windowShellList;
227 }
228
229 void DSZone::__prependWindowList(std::shared_ptr<DSWindow> window)
230 {
231         __windowList.remove(window);
232         __windowList.push_front(window);
233
234         __stackChanged = true;
235         __updateWindowOrder();
236
237         std::shared_ptr<DSWindow> wTop(__windowList.front());
238         wTop->raiseToTop();
239         __windowStackChangedSignal.emit(wTop);
240 }
241
242 void DSZone::__appendWindowList(std::shared_ptr<DSWindow> window)
243 {
244         __windowList.remove(window);
245         __windowList.push_back(window);
246
247         __stackChanged = true;
248         __updateWindowOrder();
249
250         std::shared_ptr<DSWindow> wTop(__windowList.front());
251         wTop->raiseToTop();
252         __windowStackChangedSignal.emit(wTop);
253 }
254
255 std::shared_ptr<DSWindow> DSZone::__findWindow(DSWaylandSurface *dswlSurface)
256 {
257         std::list<std::shared_ptr<DSWindow>> wList = getWindowList();
258         for (auto w : wList)
259         {
260                 if (w->surface() == dswlSurface)
261                 {
262                         DSLOG_INF("DSZone", "Window found (win=%p, surface=%p)", w, dswlSurface);
263                         return w;
264                 }
265         }
266
267         return nullptr;
268 }
269
270 DSWindowShell *DSZone::__findWindowShell(DSWaylandSurface *dswlSurface)
271 {
272         DSWindowShell *dsWinShell = nullptr;
273
274         std::map<DSWaylandSurface*, DSWindowShell*>::iterator iter;
275         iter = __windowShellMap.find(dswlSurface);
276         if(iter == __windowShellMap.end())
277         {
278                 DSLOG_DBG("DSZone", "Doesn't Exist DSWindowShell... DSWaylandSurface(%p)", dswlSurface);
279                 return nullptr;
280         }
281
282         dsWinShell = iter->second;
283         DSLOG_DBG("DSZone", "Find DSWindowShell(%p)... DSWaylandSurface(%p)", dsWinShell, dswlSurface);
284
285         return dsWinShell;
286 }
287
288 std::shared_ptr<DSWindow> DSZone::__createWindow(std::shared_ptr<DSWaylandSurface> waylandSurface)
289 {
290         std::shared_ptr<DSWindow> window = std::make_shared<DSWindow>(waylandSurface);
291         __prependWindowList(window);
292
293         // emit a signal of the surface committed
294         __windowCreatedSignal.emit(window);
295
296         return window;
297 }
298
299 void DSZone::__destroyWindow(std::shared_ptr<DSWindow> window)
300 {
301         __windowDestroySignal.emit(window);
302         __windowList.remove(window);
303
304         __stackChanged = true;
305         __updateWindowOrder();
306
307         std::shared_ptr<DSWindow> wTop(__windowList.front());
308         wTop->raiseToTop();
309         __windowStackChangedSignal.emit(wTop);
310 }
311
312 void DSZone::__updateWindowOrder(void)
313 {
314         uint32_t zOrder  = 0;
315         std::list<std::shared_ptr<DSWindow>> wList = getWindowList();
316         for (auto w : wList)
317         {
318                 /* TODO : check if the w is in its visible state */
319                 w->setZOrder(zOrder++);
320         }
321 }
322
323 std::shared_ptr<DSWindowShell> DSZone::__createWindowShell(std::shared_ptr<DSWindow> window)
324 {
325         DSWindow *ptrWindow = window.get();
326
327         std::shared_ptr<DSWindowShell> shell = std::make_shared<DSWindowShell>(ptrWindow);
328         __windowShellList.push_front(shell);
329
330         __windowShellMap.insert(std::make_pair(ptrWindow->surface(), shell.get()));
331
332         // emit a signal of the shell created
333         __windowShellCreatedSignal.emit(shell);
334
335         return shell;
336 }
337
338 void DSZone::__destroyWindowShell(DSWindowShell* windowShell, DSWaylandSurface *surface)
339 {
340         // remove from map
341         __windowShellMap.erase(surface);
342
343         // remove from __windowShellList
344         std::list<std::shared_ptr<DSWindowShell>> wsList = getWindowShellList();
345         for (auto ws : wsList)
346         {
347                 if (ws.get() == windowShell)
348                 {
349                         __windowShellDestroySignal.emit(ws);
350                         __windowShellList.remove(ws);
351                         break;
352                 }
353         }
354 }
355
356 bool DSZone::setWindowParent(DSWaylandSurface *dswlSurface, DSWaylandSurface *dswlParentSurface)
357 {
358         DSWindowShell *wShell = __findWindowShell(dswlSurface);
359         if (!wShell) return false;
360
361         DSWindowShell *pwShell = __findWindowShell(dswlParentSurface);
362
363         return wShell->setParent(pwShell);
364 }
365
366 bool DSZone::setWindowTitle(DSWaylandSurface *dswSurface, const std::string &title)
367 {
368         DSWindowShell *wShell = __findWindowShell(dswSurface);
369         if (!wShell) return false;
370
371         return wShell->setTitle(title);
372
373 /*
374         std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
375         if (!window) return false;
376
377         return window->setTitle(title);
378 */
379 }
380
381 bool DSZone::setWindowType(DSWaylandSurface *dswSurface, int type)
382 {
383         DSWindowShell *wShell = __findWindowShell(dswSurface);
384         if (!wShell) return false;
385
386         return wShell->setType(type);
387
388 /*
389         std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
390         if (!window) return false;
391
392         return window->setType(type);
393 */
394 }
395
396 bool DSZone::setWindowGeometry(DSWaylandSurface *dswSurface, int x, int y, unsigned int w, unsigned h)
397 {
398         DSWindowShell *wShell = __findWindowShell(dswSurface);
399         if (!wShell) return false;
400
401         return wShell->setGeometry(x, y, w, h);
402
403 /*
404         std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
405         if (!window) return false;
406
407         return window->setGeometry(x, y, w, h);
408 */
409 }
410
411 bool DSZone::setWindowPosition(DSWaylandSurface *dswSurface, int x, int y)
412 {
413         DSWindowShell *wShell = __findWindowShell(dswSurface);
414         if (!wShell) return false;
415
416         return wShell->setPosition(x, y);
417
418 /*
419         std::shared_ptr<DSWindow> window = __findWindow(dswSurface);
420         if (!window) return false;
421
422         return window->setPosition(x, y);
423 */
424 }
425
426 stGeometry DSZone::getWindowGeometry(DSWaylandSurface *dswSurface)
427 {
428         stGeometry geometry = {0, };
429         DSWindowShell *wShell = __findWindowShell(dswSurface);
430         if (!wShell) return geometry;
431
432         return wShell->getGeometry();
433 }
434
435 void DSZone::addWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id, const std::string &name, const std::string &value)
436 {
437         DSWindowShell *wShell = __findWindowShell(dswlSurface);
438         if (!wShell) return;
439
440         wShell->addAuxHint(id, name, value);
441 }
442
443 void DSZone::changeWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id, const std::string &value)
444 {
445         DSWindowShell *wShell = __findWindowShell(dswlSurface);
446         if (!wShell) return;
447
448         wShell->changeAuxHint(id, value);
449 }
450
451 void DSZone::removeWindowAuxHint(DSWaylandSurface *dswlSurface, int32_t id)
452 {
453         DSWindowShell *wShell = __findWindowShell(dswlSurface);
454         if (!wShell) return;
455
456         wShell->removeAuxHint(id);
457 }
458
459 std::list<std::string> DSZone::getWindowSupportedAuxHints(DSWaylandSurface *dswlSurface)
460 {
461         // TODO: we have to change code to use DSPolicy instead of DSZone
462         return __supportedAuxHints;
463 }
464
465 void DSZone::activateWindow(DSWaylandSurface *dswlSurface)
466 {
467         if (!dswlSurface) return;
468
469         std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
470         __prependWindowList(window);
471
472         DSWindowShell *wShell = __findWindowShell(dswlSurface);
473         if (!wShell) return;
474
475         wShell->activate();
476 }
477
478 void DSZone::raiseWindow(DSWaylandSurface* dswlSurface)
479 {
480         if (!dswlSurface) return;
481
482         std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
483         __prependWindowList(window);
484
485         DSWindowShell *wShell = __findWindowShell(dswlSurface);
486         if (!wShell) return;
487
488         wShell->raise();
489 }
490
491 void DSZone::lowerWindow(DSWaylandSurface* dswlSurface)
492 {
493         if (!dswlSurface) return;
494
495         std::shared_ptr<DSWindow> window = __findWindow(dswlSurface);
496         __appendWindowList(window);
497
498         DSWindowShell *wShell = __findWindowShell(dswlSurface);
499         if (!wShell) return;
500
501         wShell->lower();
502 }
503
504 void DSZone::setWindowSkipFocus(DSWaylandSurface *dswlSurface, bool set)
505 {
506         DSWindowShell *wShell = __findWindowShell(dswlSurface);
507         if (!wShell) return;
508
509         wShell->setSkipFocus(set);
510 }
511
512 bool DSZone::setWindowVkbdFloating(DSWaylandSurface *dswlsurface, bool set)
513 {
514         DSWindowShell *wShell = __findWindowShell(dswlsurface);
515         if (!wShell) return false;
516
517         return wShell->setVkbdFloating(set);
518 }
519
520 bool DSZone::getWindowVkbdFloating(DSWaylandSurface *dswlsurface)
521 {
522         DSWindowShell *wShell = __findWindowShell(dswlsurface);
523         if (!wShell) return false;
524
525         return wShell->getVkbdFloating();
526 }
527 } //  namespace display_server