d35db9bce35e557afab0a8f9d8642c1691181d34
[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 #include <wayland-client.h>
19 #include <QFile>
20
21 //////////////////////////////////////////
22 // THIS IS STILL UNDER HEAVY DEVELOPMENT!
23 // DO NOT JUDGE THE SOURCE CODE :)
24 //////////////////////////////////////////
25
26 void* WindowManager::myThis = 0;
27
28 WindowManager::WindowManager(QObject *parent) :
29     QObject(parent),
30     m_layouts(),
31     m_layoutNames(),
32     m_currentLayout(-1)
33 {
34     qDebug("WindowManager");
35     // publish windowmanager interface
36     mp_windowManagerAdaptor = new WindowmanagerAdaptor((QObject*)this);
37
38     QDBusConnection dbus = QDBusConnection::sessionBus();
39     dbus.registerObject("/windowmanager", this);
40     dbus.registerService("org.agl.windowmanager");
41
42 #ifdef __arm__
43     mp_processLayers = new QList<int>;
44     mp_surfaces = new QMap<t_ilm_uint, SurfaceInfo>;
45
46     ilmErrorTypes err;
47
48     err = ilm_init();
49     qDebug("ilm_init = %d", err);
50
51     myThis = this;
52     err =  ilm_registerNotification(WindowManager::notificationFunc_static, this);
53
54
55 #endif
56 }
57
58 WindowManager::~WindowManager()
59 {
60     delete mp_windowManagerAdaptor;
61 #ifdef __arm__
62     delete mp_surfaces;
63
64     ilm_destroy();
65 #endif
66 }
67
68 void WindowManager::dumpScene()
69 {
70     qDebug("\n");
71     qDebug("current layout   : %d", m_currentLayout);
72     qDebug("available layouts: %d", m_layouts.size());
73     QMap<int, QList<SimpleRect> >::iterator i = m_layouts.begin();
74
75     QList<int> result;
76     while (i != m_layouts.constEnd())
77     {
78         qDebug("--[id: %d]--[%s]--", i.key(), m_layoutNames.find(i.key()).value().toStdString().c_str());
79         qDebug("  %d surface areas", i.value().size());
80         for (int j = 0; j < i.value().size(); ++j)
81         {
82             qDebug("  -area %d", j);
83             qDebug("    -x     : %d", i.value().at(j).x);
84             qDebug("    -y     : %d", i.value().at(j).y);
85             qDebug("    -width : %d", i.value().at(j).width);
86             qDebug("    -height: %d", i.value().at(j).height);
87         }
88
89         ++i;
90     }
91
92 }
93
94 #ifdef __arm__
95
96 void WindowManager::createNewLayer(int layerId)
97 {
98     ilmErrorTypes err;
99
100     t_ilm_uint screenID = 0;
101     t_ilm_uint width;
102     t_ilm_uint height;
103
104     err = ilm_getScreenResolution(screenID, &width, &height);
105
106     t_ilm_layer newLayerId = layerId;
107     err = ilm_layerCreateWithDimension(&newLayerId, width, height);
108     qDebug("ilm_layerCreateWithDimension = %d", err);
109     qDebug("layerIdWallpaper = %d", newLayerId);
110
111     err = ilm_layerSetVisibility(newLayerId, true);
112     qDebug("ilm_layerSetVisibility = %d", err);
113
114     t_ilm_float opacity = 1.0;
115     err =  ilm_layerSetOpacity(newLayerId, opacity);
116
117     ilm_commitChanges();
118 }
119
120 void WindowManager::addSurfaceToLayer(int surfaceId, int layerId)
121 {
122     t_ilm_int length;
123     t_ilm_layer* pArray;
124
125     ilm_getLayerIDs(&length, &pArray);
126     bool layerFound(false);
127     for (int i = 0; i< length; ++i)
128     {
129         if (layerId == pArray[i])
130         {
131             layerFound = true;
132         }
133     }
134
135     if (!layerFound)
136     {
137         createNewLayer(layerId);
138     }
139
140     struct ilmSurfaceProperties surfaceProperties;
141     ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
142     qDebug("  origSourceWidth : %d", surfaceProperties.origSourceWidth);
143     qDebug("  origSourceHeight: %d", surfaceProperties.origSourceHeight);
144
145     ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
146     ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
147     ilm_surfaceSetOpacity(surfaceId, 1.0);
148     ilm_surfaceSetVisibility(surfaceId, true);
149
150     ilm_layerAddSurface(layerId, surfaceId);
151
152     ilm_commitChanges();
153 }
154
155 void WindowManager::notificationFunc_non_static(ilmObjectType object,
156                                     t_ilm_uint id,
157                                     t_ilm_bool created)
158 {
159     if (ILM_SURFACE == object)
160     {
161         struct ilmSurfaceProperties surfaceProperties;
162
163         if (created)
164         {
165             qDebug("Surface created, ID: %d", id);
166             ilm_getPropertiesOfSurface(id, &surfaceProperties);
167             qDebug("  origSourceWidth : %d", surfaceProperties.origSourceWidth);
168             qDebug("  origSourceHeight: %d", surfaceProperties.origSourceHeight);
169
170             addSurfaceToLayer(id, surfaceProperties.creatorPid);
171
172             t_ilm_int length;
173             t_ilm_surface* pArray;
174             ilm_getSurfaceIDs(&length, &pArray);
175             ilm_layerSetRenderOrder(42, pArray, length);
176
177             ilm_commitChanges();
178
179             SurfaceInfo surfaceInfo;
180             surfaceInfo.pid = surfaceProperties.creatorPid;
181             QString procInfoFileName = QString("/proc/") + QString::number(surfaceInfo.pid) + QString("/comm");
182             QFile procInfo(procInfoFileName);
183             if (procInfo.open(QIODevice::ReadOnly))
184             {
185                 QTextStream in(&procInfo);
186                 surfaceInfo.processName = in.readLine();
187                 qDebug("surface id %d, pid %d: %s", id, surfaceInfo.pid, surfaceInfo.processName.toStdString().c_str());
188             }
189
190             mp_surfaces->insert(id, surfaceInfo);
191             ilm_surfaceAddNotification(id, surfaceCallbackFunction_static);
192         }
193         else
194         {
195             qDebug("Surface destroyed, ID: %d", id);
196             mp_surfaces->erase(mp_surfaces->find(id));
197             ilm_surfaceRemoveNotification(id);
198         }
199
200         // rearrange surfaces on screen
201         t_ilm_uint screenID = 0;
202         t_ilm_uint width;
203         t_ilm_uint height;
204         ilm_getScreenResolution(screenID, &width, &height);
205
206         qDebug("%d surfaces to show", mp_surfaces->count());
207
208         QMap<t_ilm_uint, SurfaceInfo>::const_iterator i = mp_surfaces->constBegin();
209         int counter(0);
210         while (i != mp_surfaces->constEnd())
211         {
212             qDebug("place surface %d at x: %f, y: %d, width: %f, height: %d",
213                    i.key(),
214                    counter * (width / (1.0 * mp_surfaces->count())),
215                    0,
216                    width / (1.0 * mp_surfaces->count()),
217                    height);
218             ilm_surfaceSetDestinationRectangle(i.key(),
219                     counter * (width / (1.0 * mp_surfaces->count())),
220                     0,
221                     width / (1.0 * mp_surfaces->count()),
222                     height);
223
224             ++i;
225             ++counter;
226         }
227
228
229         ilm_commitChanges();
230     }
231     if (ILM_LAYER == object)
232     {
233         //qDebug("Layer.. we don't care...");
234     }
235 }
236
237 void WindowManager::notificationFunc_static(ilmObjectType object,
238                                             t_ilm_uint id,
239                                             t_ilm_bool created,
240                                             void* user_data)
241 {
242     static_cast<WindowManager*>(WindowManager::myThis)->notificationFunc_non_static(object, id, created);
243 }
244
245
246
247
248 void WindowManager::surfaceCallbackFunction_non_static(t_ilm_surface surface,
249                                     struct ilmSurfaceProperties* surfaceProperties,
250                                     t_ilm_notification_mask mask)
251 {
252     qDebug("surfaceCallbackFunction_non_static changes for surface %d", surface);
253     if (ILM_NOTIFICATION_VISIBILITY & mask)
254     {
255         qDebug("ILM_NOTIFICATION_VISIBILITY");
256     }
257
258     if (ILM_NOTIFICATION_OPACITY & mask)
259     {
260         qDebug("ILM_NOTIFICATION_OPACITY");
261     }
262
263     if (ILM_NOTIFICATION_ORIENTATION & mask)
264     {
265         qDebug("ILM_NOTIFICATION_ORIENTATION");
266     }
267
268     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
269     {
270         qDebug("ILM_NOTIFICATION_SOURCE_RECT");
271     }
272
273     if (ILM_NOTIFICATION_DEST_RECT & mask)
274     {
275         qDebug("ILM_NOTIFICATION_DEST_RECT");
276     }
277 }
278
279 void WindowManager::surfaceCallbackFunction_static(t_ilm_surface surface,
280                                     struct ilmSurfaceProperties* surfaceProperties,
281                                     t_ilm_notification_mask mask)
282
283 {
284     static_cast<WindowManager*>(WindowManager::myThis)->surfaceCallbackFunction_non_static(surface, surfaceProperties, mask);
285 }
286 #endif
287
288 int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<SimpleRect> &surfaceAreas)
289 {
290     m_layouts.insert(layoutId, surfaceAreas);
291     m_layoutNames.insert(layoutId, layoutName);
292     qDebug("addLayout %d %s, size %d", layoutId, layoutName.toStdString().c_str(), surfaceAreas.size());
293
294     dumpScene();
295
296     return true;
297 }
298
299 QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
300 {
301     QMap<int, QList<SimpleRect> >::iterator i = m_layouts.begin();
302
303     QList<int> result;
304     while (i != m_layouts.constEnd())
305     {
306         if (i.value().size() == numberOfAppSurfaces)
307         {
308             result.append(i.key());
309         }
310
311         ++i;
312     }
313
314     return result;
315 }
316
317 // maybe not needed anymore
318 QList<SimplePoint> WindowManager::getAvailableSurfaces()
319 {
320     QList<SimplePoint> points;
321     SimplePoint point;
322     point.x = 1;
323     point.y = 2;
324     points.append(point);
325     point.x = 11;
326     point.y = 22;
327     points.append(point);
328     point.x = 111;
329     point.y = 222;
330     points.append(point);
331
332     return points;
333 }
334
335 int WindowManager::getLayout()
336 {
337     return m_currentLayout;
338 }
339
340 QString WindowManager::getLayoutName(int layoutId)
341 {
342     return m_layoutNames.find(layoutId).value();
343 }
344
345 void WindowManager::setLayoutById(int layoutId)
346 {
347     m_currentLayout = layoutId;
348
349     dumpScene();
350 }
351
352 void WindowManager::setLayoutByName(const QString &layoutName)
353 {
354     QMap<int, QString>::iterator i = m_layoutNames.begin();
355     while (i != m_layoutNames.constEnd())
356     {
357         if (i.value() == layoutName)
358         {
359             m_currentLayout = i.key();
360         }
361         ++i;
362     }
363
364     dumpScene();
365 }
366
367 void WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
368 {
369     dumpScene();
370 }