Reworking layer/surface management
[staging/HomeScreen.git] / WindowManager / src / windowmanager.cpp
1 /*
2  * Copyright (C) 2016 Mentor Graphics Development (Deutschland) GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "windowmanager.hpp"
18
19
20 //////////////////////////////////////////
21 // THIS IS STILL UNDER HEAVY DEVELOPMENT!
22 // DO NOT JUDGE THE SOURCE CODE :)
23 //////////////////////////////////////////
24
25 // three layers will be defined. The HomeScreen will be placed
26 // full screen in the background.
27 // On top all applications in one layer.
28 // On top of that, the popup layer.
29 #define WINDOWMANAGER_LAYER_POPUP 100
30 #define WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY 101
31 #define WINDOWMANAGER_LAYER_APPLICATIONS 102
32 #define WINDOWMANAGER_LAYER_HOMESCREEN 103
33
34 #define WINDOWMANAGER_LAYER_NUM 4
35
36 #define WINDOWMANAGER_SURFACE_ID_SHIFT 22
37
38 // the HomeScreen app has to have the surface id 4194304
39 #define WINDOWMANAGER_HOMESCREEN_MAIN_SURFACE_ID (1 << WINDOWMANAGER_SURFACE_ID_SHIFT)
40
41 // Quick hack for scaling layer to fit non-FHD(1920x1080) screen
42 //  * source rect of layer should be 1920x1080
43 //  * destination rect of layer should fit physical display resolution
44 //  * source rect of surface shoud be based on 1920x1080
45 //  * destination rect of surface should be based on 1920x1080
46 #define WINDOWMANAGER_HOMESCREEN_WIDTH  1080
47 #define WINDOWMANAGER_HOMESCREEN_HEIGHT 1920
48
49 void* WindowManager::myThis = 0;
50
51 WindowManager::WindowManager(int displayId, QObject *parent) :
52     QObject(parent),
53     m_layouts(),
54     mp_layoutAreaToSurfaceIdAssignment(0),
55     m_currentLayout(-1),
56     m_screenId(displayId),
57     m_screenWidth(0),
58     m_screenHeight(0)
59 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
60     ,
61     m_appSurfaces(),
62     m_appLayers(),
63     m_pending_to_show(-1)
64 #endif
65 {
66 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
67     m_showLayers = new t_ilm_layer[WINDOWMANAGER_LAYER_NUM];
68
69     m_showLayers[0] = 0; /* POPUP is not shown by default */
70     m_showLayers[1] = 0; /* HOMESCREEN_OVERLAY is not shown by default */
71     m_showLayers[2] = 0; /* APPLICATIONS is not shown by default */
72     m_showLayers[3] = WINDOWMANAGER_LAYER_HOMESCREEN; /* HOMESCREEN is shwon by default */
73
74 #endif
75     qDebug("-=[WindowManager]=-");
76 }
77
78 void WindowManager::start()
79 {
80     qDebug("-=[start]=-");
81     mp_layoutAreaToSurfaceIdAssignment = new QMap<int, unsigned int>;
82 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
83     ilmErrorTypes err;
84
85     err = ilm_init();
86     qDebug("ilm_init = %d", err);
87     if(ILM_SUCCESS != err)
88     {
89         qDebug("failed! Exiting!");
90         exit(-1);
91     }
92
93     myThis = this;
94
95     ilm_getScreenResolution(m_screenId, &m_screenWidth, &m_screenHeight);
96
97     createNewLayer(WINDOWMANAGER_LAYER_POPUP);
98     createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY);
99     createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN);
100
101     ilm_registerNotification(WindowManager::notificationFunc_static, this);
102 #endif
103
104     QDBusConnection dbus = QDBusConnection::sessionBus();
105     dbus.registerObject("/windowmanager", this);
106     dbus.registerService("org.agl.windowmanager");
107
108     // publish windowmanager interface
109     mp_windowManagerAdaptor = new WindowmanagerAdaptor((QObject*)this);
110 }
111
112 WindowManager::~WindowManager()
113 {
114     qDebug("-=[~WindowManager]=-");
115     delete mp_windowManagerAdaptor;
116 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
117     ilm_destroy();
118 #endif
119     delete mp_layoutAreaToSurfaceIdAssignment;
120 }
121
122 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
123 int WindowManager::getLayerRenderOrder(t_ilm_layer id_array[])
124 {
125     int i, j;
126
127     for (i = WINDOWMANAGER_LAYER_NUM - 1, j = 0; i >= 0; i--) {
128         if (m_showLayers[i] != 0) {
129             id_array[j++] = m_showLayers[i];
130         }
131     }
132
133     return j;
134 }
135 #endif
136
137 void WindowManager::dumpScene()
138 {
139     qDebug("\n");
140     qDebug("current layout   : %d", m_currentLayout);
141     qDebug("available layouts: %d", m_layouts.size());
142     QList<Layout>::const_iterator i = m_layouts.begin();
143
144     while (i != m_layouts.constEnd())
145     {
146         qDebug("--[id: %d]--[%s]--", i->id, i->name.toStdString().c_str());
147         qDebug("  %d surface areas", i->layoutAreas.size());
148         for (int j = 0; j < i->layoutAreas.size(); ++j)
149         {
150             qDebug("  -area %d", j);
151             qDebug("    -x     : %d", i->layoutAreas.at(j).x);
152             qDebug("    -y     : %d", i->layoutAreas.at(j).y);
153             qDebug("    -width : %d", i->layoutAreas.at(j).width);
154             qDebug("    -height: %d", i->layoutAreas.at(j).height);
155         }
156
157         ++i;
158     }
159 }
160
161 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
162
163 void WindowManager::createNewLayer(int layerId)
164 {
165     qDebug("-=[createNewLayer]=-");
166     qDebug("  layerId %d", layerId);
167
168     t_ilm_layer newLayerId = layerId;
169     ilm_layerCreateWithDimension(&newLayerId,
170                                     WINDOWMANAGER_HOMESCREEN_WIDTH,
171                                     WINDOWMANAGER_HOMESCREEN_HEIGHT);
172     ilm_commitChanges();
173     ilm_layerSetSourceRectangle(newLayerId,
174                                     0,
175                                     0,
176                                     WINDOWMANAGER_HOMESCREEN_WIDTH,
177                                     WINDOWMANAGER_HOMESCREEN_HEIGHT);
178     ilm_layerSetDestinationRectangle(newLayerId,
179                                     0,
180                                     0,
181                                     m_screenWidth,
182                                     m_screenHeight);
183     ilm_commitChanges();
184     ilm_layerSetOpacity(newLayerId, 1.0);
185     ilm_layerSetVisibility(newLayerId, ILM_TRUE);
186     ilm_commitChanges();
187 }
188
189 t_ilm_layer WindowManager::getAppLayerID(pid_t pid)
190 {
191     t_ilm_layer layer_id;
192
193 //    layer_id = pid + (WINDOWMANAGER_LAYER_APPLICATIONS << WINDOWMANAGER_LAYER_ID_SHIFT);
194     layer_id = pid + (WINDOWMANAGER_LAYER_APPLICATIONS * 100000); /* for debug */
195
196     return layer_id;
197 }
198
199 void WindowManager::addSurface(t_ilm_surface surfaceId)
200 {
201     struct ilmSurfaceProperties surfaceProperties;
202     pid_t pid;
203
204     ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
205     pid = surfaceProperties.creatorPid;
206
207     QMap<pid_t, t_ilm_surface>::const_iterator i = m_appSurfaces.find(pid);
208     if (i != m_appSurfaces.end() && i.value() == 0) {
209         /* Only the 1st surface is handled by Window Manager */
210         qDebug("This surface (%d) is 1st one for app (%d)", surfaceId, pid);
211         /* update surface id */
212         m_appSurfaces.insert(pid, surfaceId);
213
214         /* this surface should be handled by WindowManager */
215         ilm_surfaceAddNotification(surfaceId, surfaceCallbackFunction_static);
216         ilm_commitChanges();
217     }
218 }
219
220 t_ilm_layer WindowManager::addSurfaceToAppLayer(pid_t pid, int surfaceId)
221 {
222     struct ilmSurfaceProperties surfaceProperties;
223     t_ilm_layer layer_id;
224     int found = 0;
225
226     qDebug("-=[addSurfaceToAppLayer]=-");
227     qDebug("  surfaceId %d", surfaceId);
228
229     if (pid < 0)
230         return 0;
231
232     QMap<pid_t, t_ilm_layer>::const_iterator i = m_appLayers.find(pid);
233     if (i == m_appLayers.end()) {
234         qDebug("No layer found, create new for app(pid=%d)", pid);
235
236         /* not found, create new one */
237         layer_id = getAppLayerID(pid);
238
239         createNewLayer(layer_id);
240         m_appLayers.insert(pid, layer_id);
241     } else {
242         layer_id = i.value();
243     }
244
245     return layer_id;
246 }
247
248 void WindowManager::addSurfaceToLayer(int surfaceId, int layerId)
249 {
250     qDebug("-=[addSurfaceToLayer]=-");
251     qDebug("  surfaceId %d", surfaceId);
252     qDebug("  layerId %d", layerId);
253
254     if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN)
255     {
256       ilm_layerAddSurface(layerId, surfaceId);
257     }
258     else if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY)
259     {
260         struct ilmSurfaceProperties surfaceProperties;
261         ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
262
263         //ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
264         //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
265         //ilm_surfaceSetOpacity(surfaceId, 0.5);
266         //ilm_surfaceSetVisibility(surfaceId, ILM_TRUE);
267
268         ilm_layerAddSurface(layerId, surfaceId);
269     }
270     else if (layerId == WINDOWMANAGER_LAYER_POPUP)
271     {
272         struct ilmSurfaceProperties surfaceProperties;
273         ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
274
275         //ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
276         //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
277         //ilm_surfaceSetOpacity(surfaceId, 0.0);
278         //ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
279
280         ilm_layerAddSurface(layerId, surfaceId);
281     } else {
282         return;
283     }
284
285     ilm_commitChanges();
286 }
287
288 void WindowManager::configureHomeScreenMainSurface(t_ilm_surface surface, t_ilm_int width, t_ilm_int height)
289 {
290     // homescreen app always fullscreen in the back
291     ilm_surfaceSetDestinationRectangle(surface, 0, 0,
292                                        WINDOWMANAGER_HOMESCREEN_WIDTH,
293                                        WINDOWMANAGER_HOMESCREEN_HEIGHT);
294     ilm_surfaceSetSourceRectangle(surface, 0, 0, width, height);
295     ilm_surfaceSetOpacity(surface, 1.0);
296     ilm_surfaceSetVisibility(surface, ILM_TRUE);
297
298     ilm_commitChanges();
299 }
300
301 void WindowManager::configureAppSurface(pid_t pid, t_ilm_surface surface, t_ilm_int width, t_ilm_int height)
302 {
303     /* Dirty hack! cut & paste from HomeScreen/src/layouthandler.cpp */
304     const int SCREEN_WIDTH = 1080;
305     const int SCREEN_HEIGHT = 1920;
306
307     const int TOPAREA_HEIGHT = 218;
308     const int TOPAREA_WIDTH = SCREEN_WIDTH;
309     const int TOPAREA_X = 0;
310     const int TOPAREA_Y = 0;
311     const int MEDIAAREA_HEIGHT = 215;
312     const int MEDIAAREA_WIDTH = SCREEN_WIDTH;
313     const int MEDIAAREA_X = 0;
314     const int MEDIAAREA_Y = SCREEN_HEIGHT - MEDIAAREA_HEIGHT;
315
316     ilm_surfaceSetDestinationRectangle(surface,
317                                        0,
318                                        TOPAREA_HEIGHT,
319                                        SCREEN_WIDTH,
320                                        SCREEN_HEIGHT - TOPAREA_HEIGHT - MEDIAAREA_HEIGHT);
321     ilm_surfaceSetSourceRectangle(surface, 0, 0, width, height);
322     ilm_surfaceSetOpacity(surface, 1.0);
323     ilm_surfaceSetVisibility(surface, ILM_TRUE); /* Hack to avoid blank screen when switch apps */
324
325     ilm_commitChanges();
326 }
327 #endif
328
329 void WindowManager::updateScreen()
330 {
331     qDebug("-=[updateScreen]=-");
332
333 #if 0
334 //#ifdef HAVE_IVI_LAYERMANAGEMENT_API
335     if (-1 != m_currentLayout)
336     {
337         // hide all surfaces
338         for (int i = 0; i < m_appSurfaces.size(); ++i)
339         {
340             ilm_layerRemoveSurface(WINDOWMANAGER_LAYER_APPLICATIONS, m_appSurfaces.at(i));
341             //ilm_surfaceSetVisibility(m_appSurfaces.at(i), ILM_FALSE);
342             //ilm_surfaceSetOpacity(m_appSurfaces.at(i), 0.0);
343             ilm_commitChanges();
344         }
345
346         // find the current used layout
347         QList<Layout>::const_iterator ci = m_layouts.begin();
348
349         Layout currentLayout;
350         while (ci != m_layouts.constEnd())
351         {
352             if (ci->id == m_currentLayout)
353             {
354                 currentLayout = *ci;
355             }
356
357             ++ci;
358         }
359
360         qDebug("show %d apps", mp_layoutAreaToSurfaceIdAssignment->size());
361         for (int j = 0; j < mp_layoutAreaToSurfaceIdAssignment->size(); ++j)
362         {
363             int surfaceToShow = mp_layoutAreaToSurfaceIdAssignment->find(j).value();
364             qDebug("  surface no. %d: %d", j, surfaceToShow);
365
366             addSurfaceToLayer(surfaceToShow, WINDOWMANAGER_LAYER_APPLICATIONS);
367
368             ilm_surfaceSetVisibility(surfaceToShow, ILM_TRUE);
369             ilm_surfaceSetOpacity(surfaceToShow, 1.0);
370
371             qDebug("  layout area %d", j);
372             qDebug("    x: %d", currentLayout.layoutAreas[j].x);
373             qDebug("    y: %d", currentLayout.layoutAreas[j].y);
374             qDebug("    w: %d", currentLayout.layoutAreas[j].width);
375             qDebug("    h: %d", currentLayout.layoutAreas[j].height);
376
377             ilm_surfaceSetDestinationRectangle(surfaceToShow,
378                                              currentLayout.layoutAreas[j].x,
379                                              currentLayout.layoutAreas[j].y,
380                                              currentLayout.layoutAreas[j].width,
381                                              currentLayout.layoutAreas[j].height);
382             ilm_commitChanges();
383         }
384     }
385
386     // layer surface render order
387     t_ilm_int length;
388     t_ilm_surface* pArray;
389     ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_HOMESCREEN, &length, &pArray);
390     ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_HOMESCREEN, pArray, length);
391     ilm_commitChanges();
392     ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_APPLICATIONS, &length, &pArray);
393     ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_APPLICATIONS, pArray, length);
394     ilm_commitChanges();
395     ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY, &length, &pArray);
396     ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY, pArray, length);
397     ilm_commitChanges();
398     ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_POPUP, &length, &pArray);
399     ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_POPUP, pArray, length);
400     ilm_commitChanges();
401 #endif
402 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
403     if (m_pending_to_show != -1) {
404         qDebug("show pending app (%d)", m_pending_to_show);
405         showAppLayer(m_pending_to_show);
406     } else {
407         // display layer render order
408         t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
409         int num_layers = getLayerRenderOrder(renderOrder);
410
411         qDebug("Screen render order %d, %d layers", m_screenId, num_layers);
412         ilm_displaySetRenderOrder(m_screenId, renderOrder, num_layers);
413         ilm_commitChanges();
414     }
415 #endif
416 }
417
418 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
419 void WindowManager::notificationFunc_non_static(ilmObjectType object,
420                                     t_ilm_uint id,
421                                     t_ilm_bool created)
422 {
423     qDebug("-=[notificationFunc_non_static]=-");
424     qDebug("Notification from weston!");
425     if (ILM_SURFACE == object)
426     {
427         struct ilmSurfaceProperties surfaceProperties;
428
429         if (created)
430         {
431             if (WINDOWMANAGER_HOMESCREEN_MAIN_SURFACE_ID == id)
432             {
433                 ilm_surfaceAddNotification(id, surfaceCallbackFunction_static);
434                 ilm_commitChanges();
435             }
436             else
437             {
438                 addSurface(id);
439             }
440         }
441         else
442         {
443             qDebug("Surface destroyed, ID: %d", id);
444 #if 0
445             m_appSurfaces.removeAt(m_appSurfaces.indexOf(id));
446             ilm_surfaceRemoveNotification(id);
447
448             ilm_commitChanges();
449 #endif
450         }
451     }
452     if (ILM_LAYER == object)
453     {
454         //qDebug("Layer.. we don't care...");
455     }
456 }
457
458 void WindowManager::notificationFunc_static(ilmObjectType object,
459                                             t_ilm_uint id,
460                                             t_ilm_bool created,
461                                             void* user_data)
462 {
463     static_cast<WindowManager*>(WindowManager::myThis)->notificationFunc_non_static(object, id, created);
464 }
465
466 void WindowManager::surfaceCallbackFunction_non_static(t_ilm_surface surface,
467                                     struct ilmSurfaceProperties* surfaceProperties,
468                                     t_ilm_notification_mask mask)
469 {
470     qDebug("-=[surfaceCallbackFunction_non_static]=-");
471     qDebug("surfaceCallbackFunction_non_static changes for surface %d", surface);
472     if (ILM_NOTIFICATION_VISIBILITY & mask)
473     {
474         qDebug("ILM_NOTIFICATION_VISIBILITY");
475         surfaceVisibilityChanged(surface, surfaceProperties->visibility);
476         updateScreen();
477     }
478     if (ILM_NOTIFICATION_OPACITY & mask)
479     {
480         qDebug("ILM_NOTIFICATION_OPACITY");
481     }
482     if (ILM_NOTIFICATION_ORIENTATION & mask)
483     {
484         qDebug("ILM_NOTIFICATION_ORIENTATION");
485     }
486     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
487     {
488         qDebug("ILM_NOTIFICATION_SOURCE_RECT");
489     }
490     if (ILM_NOTIFICATION_DEST_RECT & mask)
491     {
492         qDebug("ILM_NOTIFICATION_DEST_RECT");
493     }
494     if (ILM_NOTIFICATION_CONTENT_AVAILABLE & mask)
495     {
496         qDebug("ILM_NOTIFICATION_CONTENT_AVAILABLE");
497     }
498     if (ILM_NOTIFICATION_CONTENT_REMOVED & mask)
499     {
500         qDebug("ILM_NOTIFICATION_CONTENT_REMOVED");
501
502         /* application being down */
503         m_appLayers.remove(surfaceProperties->creatorPid);
504     }
505     if (ILM_NOTIFICATION_CONFIGURED & mask)
506     {
507         qDebug("ILM_NOTIFICATION_CONFIGURED");
508         qDebug("  surfaceProperties %d", surface);
509         qDebug("    surfaceProperties.origSourceWidth: %d", surfaceProperties->origSourceWidth);
510         qDebug("    surfaceProperties.origSourceHeight: %d", surfaceProperties->origSourceHeight);
511
512         if (surface == WINDOWMANAGER_HOMESCREEN_MAIN_SURFACE_ID) {
513             addSurfaceToLayer(surface, WINDOWMANAGER_LAYER_HOMESCREEN);
514             configureHomeScreenMainSurface(surface, surfaceProperties->origSourceWidth, surfaceProperties->origSourceHeight);
515         } else {
516             ilmErrorTypes result;
517             pid_t pid = surfaceProperties->creatorPid;
518             t_ilm_layer layer = addSurfaceToAppLayer(pid, surface);
519
520             if (layer != 0) {
521                 configureAppSurface(pid, surface,
522                                     surfaceProperties->origSourceWidth,
523                                     surfaceProperties->origSourceHeight);
524
525                 result = ilm_layerAddSurface(layer, surface);
526                 if (result != ILM_SUCCESS) {
527                     qDebug("ilm_layerAddSurface(%d,%d) failed.", layer, surface);
528                 }
529                 ilm_commitChanges();
530             }
531         }
532         updateScreen();
533     }
534 }
535
536 void WindowManager::surfaceCallbackFunction_static(t_ilm_surface surface,
537                                     struct ilmSurfaceProperties* surfaceProperties,
538                                     t_ilm_notification_mask mask)
539
540 {
541     static_cast<WindowManager*>(WindowManager::myThis)->surfaceCallbackFunction_non_static(surface, surfaceProperties, mask);
542 }
543 #endif
544
545 int WindowManager::layoutId() const
546 {
547     return m_currentLayout;
548 }
549
550 QString WindowManager::layoutName() const
551 {
552     QList<Layout>::const_iterator i = m_layouts.begin();
553
554     QString result = "not found";
555     while (i != m_layouts.constEnd())
556     {
557         if (i->id == m_currentLayout)
558         {
559             result = i->name;
560         }
561
562         ++i;
563     }
564
565     return result;
566 }
567
568
569 int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<LayoutArea> &surfaceAreas)
570 {
571     qDebug("-=[addLayout]=-");
572     m_layouts.append(Layout(layoutId, layoutName, surfaceAreas));
573
574     qDebug("addLayout %d %s, size %d",
575            layoutId,
576            layoutName.toStdString().c_str(),
577            surfaceAreas.size());
578
579     dumpScene();
580
581     return WINDOWMANAGER_NO_ERROR;
582 }
583
584 int WindowManager::deleteLayoutById(int layoutId)
585 {
586     qDebug("-=[deleteLayoutById]=-");
587     qDebug("layoutId: %d", layoutId);
588     int result = WINDOWMANAGER_NO_ERROR;
589
590     if (m_currentLayout == layoutId)
591     {
592         result = WINDOWMANAGER_ERROR_ID_IN_USE;
593     }
594     else
595     {
596         QList<Layout>::iterator i = m_layouts.begin();
597         result = WINDOWMANAGER_ERROR_ID_IN_USE;
598         while (i != m_layouts.constEnd())
599         {
600             if (i->id == layoutId)
601             {
602                 m_layouts.erase(i);
603                 result = WINDOWMANAGER_NO_ERROR;
604                 break;
605             }
606
607             ++i;
608         }
609     }
610
611     return result;
612 }
613
614
615 QList<Layout> WindowManager::getAllLayouts()
616 {
617     qDebug("-=[getAllLayouts]=-");
618
619     return m_layouts;
620 }
621
622 #if 0
623 QList<int> WindowManager::getAllSurfacesOfProcess(int pid)
624 {
625     QList<int> result;
626 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
627     struct ilmSurfaceProperties surfaceProperties;
628
629     for (int i = 0; i < m_appSurfaces.size(); ++i)
630     {
631         ilm_getPropertiesOfSurface(m_appSurfaces.at(i), &surfaceProperties);
632         if (pid == surfaceProperties.creatorPid)
633         {
634             result.append(m_appSurfaces.at(i));
635         }
636     }
637 #endif
638     return result;
639 }
640 #endif
641
642 QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
643 {
644     qDebug("-=[getAvailableLayouts]=-");
645     QList<Layout>::const_iterator i = m_layouts.begin();
646
647     QList<int> result;
648     while (i != m_layouts.constEnd())
649     {
650         if (i->layoutAreas.size() == numberOfAppSurfaces)
651         {
652             result.append(i->id);
653         }
654
655         ++i;
656     }
657
658     return result;
659 }
660
661 #if 0
662 QList<int> WindowManager::getAvailableSurfaces()
663 {
664     qDebug("-=[getAvailableSurfaces]=-");
665
666     return m_appSurfaces;
667 }
668 #endif
669
670 QString WindowManager::getLayoutName(int layoutId)
671 {
672     qDebug("-=[getLayoutName]=-");
673     QList<Layout>::const_iterator i = m_layouts.begin();
674
675     QString result = "not found";
676     while (i != m_layouts.constEnd())
677     {
678         if (i->id == layoutId)
679         {
680             result = i->name;
681         }
682
683         ++i;
684     }
685
686     return result;
687 }
688
689 void WindowManager::hideLayer(int layer)
690 {
691     qDebug("-=[hideLayer]=-");
692     qDebug("layer %d", layer);
693
694 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
695     // POPUP=0, HOMESCREEN_OVERLAY=1, APPS=2, HOMESCREEN=3
696     if (layer >= 0 && layer < WINDOWMANAGER_LAYER_NUM) {
697         /* hide target layer */
698         m_showLayers[layer] = 0;
699         if (layer == 2) {
700             /* clear pending flag */
701             m_pending_to_show = -1;
702         }
703
704         t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
705         int num_layers = getLayerRenderOrder(renderOrder);
706         ilm_displaySetRenderOrder(m_screenId, renderOrder, num_layers);
707         ilm_commitChanges();
708     }
709 #endif
710 }
711
712 int WindowManager::setLayoutById(int layoutId)
713 {
714     qDebug("-=[setLayoutById]=-");
715     int result = WINDOWMANAGER_NO_ERROR;
716     m_currentLayout = layoutId;
717
718     mp_layoutAreaToSurfaceIdAssignment->clear();
719
720     dumpScene();
721
722     return result;
723 }
724
725 int WindowManager::setLayoutByName(const QString &layoutName)
726 {
727     qDebug("-=[setLayoutByName]=-");
728     int result = WINDOWMANAGER_NO_ERROR;
729
730     QList<Layout>::const_iterator i = m_layouts.begin();
731
732     while (i != m_layouts.constEnd())
733     {
734         if (i->name == layoutName)
735         {
736             m_currentLayout = i->id;
737
738             mp_layoutAreaToSurfaceIdAssignment->clear();
739
740             dumpScene();
741         }
742
743         ++i;
744     }
745
746     return result;
747 }
748
749 int WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
750 {
751     qDebug("-=[setSurfaceToLayoutArea]=-");
752     int result = WINDOWMANAGER_NO_ERROR;
753
754     qDebug("surfaceId %d", surfaceId);
755     qDebug("layoutAreaId %d", layoutAreaId);
756     mp_layoutAreaToSurfaceIdAssignment->insert(layoutAreaId, surfaceId);
757
758     updateScreen();
759
760     dumpScene();
761
762     return result;
763 }
764
765 void WindowManager::showLayer(int layer)
766 {
767     qDebug("-=[showLayer]=-");
768     qDebug("layer %d", layer);
769
770 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
771     // POPUP=0, HOMESCREEN_OVERLAY=1, APPS=2, HOMESCREEN=3
772     if (layer >= 0 && layer < WINDOWMANAGER_LAYER_NUM) {
773         static const int layer_id_array[] = {
774             WINDOWMANAGER_LAYER_POPUP,
775             WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY,
776             WINDOWMANAGER_LAYER_APPLICATIONS,
777             WINDOWMANAGER_LAYER_HOMESCREEN,
778         };
779
780         m_showLayers[layer] = layer_id_array[layer];
781
782         t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
783         int num_layers = getLayerRenderOrder(renderOrder);
784         ilm_displaySetRenderOrder(m_screenId, renderOrder, num_layers);
785         ilm_commitChanges();
786     }
787 #endif
788 }
789
790 void WindowManager::showAppLayer(int pid)
791 {
792     qDebug("-=[showAppLayer]=-");
793     qDebug("pid %d", pid);
794
795     if (pid == -1) {
796         /* nothing to show */
797         return;
798     }
799 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
800     /* clear pending flag */
801     m_pending_to_show = -1;
802
803     /* search layer id for application to show */
804     QMap<pid_t, t_ilm_layer>::const_iterator i = m_appLayers.find(pid);
805     QMap<pid_t, t_ilm_surface>::const_iterator j = m_appSurfaces.find(pid);
806
807     if (i != m_appLayers.end()) {
808         m_showLayers[2] = i.value();
809         qDebug("Found layer(%d) to show for app(pid=%d)", m_showLayers[2], pid);
810     } else {
811         /* check if this app is registered */
812         if (j == m_appSurfaces.end()) {
813             qDebug("New app %d", pid);
814             m_appSurfaces.insert(pid, 0); /* register pid only so far */
815         }
816
817         /* Probably app layer hasn't been made yet */
818         m_pending_to_show = pid;
819         /* hide current app once, back to default screen */
820         m_showLayers[2] = 0;
821         qDebug("No layer to show for app(pid=%d)", pid);
822     }
823     t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
824
825     int num_layers = getLayerRenderOrder(renderOrder);
826     ilm_displaySetRenderOrder(m_screenId, renderOrder, num_layers);
827     ilm_commitChanges();
828 #endif
829 }