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