2 * Copyright (C) 2016 Mentor Graphics Development (Deutschland) GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "windowmanager.hpp"
20 //////////////////////////////////////////
21 // THIS IS STILL UNDER HEAVY DEVELOPMENT!
22 // DO NOT JUDGE THE SOURCE CODE :)
23 //////////////////////////////////////////
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
34 #define WINDOWMANAGER_LAYER_NUM 4
36 // the HomeScreen app has to have the surface id 1000
37 #define WINDOWMANAGER_HOMESCREEN_MAIN_SURFACE_ID 1000
39 void* WindowManager::myThis = 0;
41 static const int layer_id_array[] = {
42 WINDOWMANAGER_LAYER_POPUP,
43 WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY,
44 WINDOWMANAGER_LAYER_APPLICATIONS,
45 WINDOWMANAGER_LAYER_HOMESCREEN,
48 WindowManager::WindowManager(QObject *parent) :
52 mp_layoutAreaToSurfaceIdAssignment(0),
54 m_screenId(0), // use screen "0"
58 m_showLayers = new int[WINDOWMANAGER_LAYER_NUM];
60 m_showLayers[0] = 0; /* POPUP is not shown by default */
61 m_showLayers[1] = 0; /* HOMESCREEN_OVERLAY is not shown by default */
62 m_showLayers[2] = 0; /* APPLICATIONS is not shown by default */
63 m_showLayers[3] = WINDOWMANAGER_LAYER_HOMESCREEN; /* HOMESCREEN is shwon by default */
65 qDebug("-=[WindowManager]=-");
68 void WindowManager::start()
70 qDebug("-=[start]=-");
71 mp_layoutAreaToSurfaceIdAssignment = new QMap<int, unsigned int>;
72 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
76 qDebug("ilm_init = %d", err);
77 if(ILM_SUCCESS != err)
79 qDebug("failed! Exiting!");
85 ilm_getScreenResolution(m_screenId, &m_screenWidth, &m_screenHeight);
87 createNewLayer(WINDOWMANAGER_LAYER_POPUP);
88 createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY);
89 createNewLayer(WINDOWMANAGER_LAYER_APPLICATIONS);
90 createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN);
92 ilm_registerNotification(WindowManager::notificationFunc_static, this);
95 QDBusConnection dbus = QDBusConnection::sessionBus();
96 dbus.registerObject("/windowmanager", this);
97 dbus.registerService("org.agl.windowmanager");
99 // publish windowmanager interface
100 mp_windowManagerAdaptor = new WindowmanagerAdaptor((QObject*)this);
103 WindowManager::~WindowManager()
105 qDebug("-=[~WindowManager]=-");
106 delete mp_windowManagerAdaptor;
107 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
110 delete mp_layoutAreaToSurfaceIdAssignment;
113 int WindowManager::getLayerRenderOrder(t_ilm_layer id_array[])
117 for (i = WINDOWMANAGER_LAYER_NUM - 1, j = 0; i >= 0; i--, j++) {
118 if (m_showLayers[i] != 0) {
119 id_array[j] = m_showLayers[i];
126 void WindowManager::dumpScene()
129 qDebug("current layout : %d", m_currentLayout);
130 qDebug("available layouts: %d", m_layouts.size());
131 QList<Layout>::const_iterator i = m_layouts.begin();
133 while (i != m_layouts.constEnd())
135 qDebug("--[id: %d]--[%s]--", i->id, i->name.toStdString().c_str());
136 qDebug(" %d surface areas", i->layoutAreas.size());
137 for (int j = 0; j < i->layoutAreas.size(); ++j)
139 qDebug(" -area %d", j);
140 qDebug(" -x : %d", i->layoutAreas.at(j).x);
141 qDebug(" -y : %d", i->layoutAreas.at(j).y);
142 qDebug(" -width : %d", i->layoutAreas.at(j).width);
143 qDebug(" -height: %d", i->layoutAreas.at(j).height);
150 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
152 void WindowManager::createNewLayer(int layerId)
154 qDebug("-=[createNewLayer]=-");
155 qDebug(" layerId %d", layerId);
157 t_ilm_layer newLayerId = layerId;
158 ilm_layerCreateWithDimension(&newLayerId, m_screenWidth, m_screenHeight);
159 ilm_layerSetOpacity(newLayerId, 1.0);
160 ilm_layerSetVisibility(newLayerId, ILM_TRUE);
161 ilm_layerSetSourceRectangle(newLayerId,
166 ilm_layerSetDestinationRectangle(newLayerId,
175 void WindowManager::addSurfaceToLayer(int surfaceId, int layerId)
177 qDebug("-=[addSurfaceToLayer]=-");
178 qDebug(" surfaceId %d", surfaceId);
179 qDebug(" layerId %d", layerId);
181 if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN)
183 struct ilmSurfaceProperties surfaceProperties;
184 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
186 // homescreen app always fullscreen in the back
187 ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, m_screenWidth, m_screenHeight);
188 //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, m_screenWidth, m_screenHeight);
189 ilm_surfaceSetOpacity(surfaceId, 1.0);
190 ilm_surfaceSetVisibility(surfaceId, ILM_TRUE);
192 ilm_layerAddSurface(layerId, surfaceId);
195 if (layerId == WINDOWMANAGER_LAYER_APPLICATIONS)
197 struct ilmSurfaceProperties surfaceProperties;
198 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
200 //ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
201 //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
202 //ilm_surfaceSetOpacity(surfaceId, 0.0);
203 //ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
205 ilm_layerAddSurface(layerId, surfaceId);
208 if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY)
210 struct ilmSurfaceProperties surfaceProperties;
211 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
213 //ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
214 //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
215 //ilm_surfaceSetOpacity(surfaceId, 0.5);
216 //ilm_surfaceSetVisibility(surfaceId, ILM_TRUE);
218 ilm_layerAddSurface(layerId, surfaceId);
221 if (layerId == WINDOWMANAGER_LAYER_POPUP)
223 struct ilmSurfaceProperties surfaceProperties;
224 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
226 //ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
227 //ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
228 //ilm_surfaceSetOpacity(surfaceId, 0.0);
229 //ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
231 ilm_layerAddSurface(layerId, surfaceId);
239 void WindowManager::updateScreen()
241 qDebug("-=[updateScreen]=-");
243 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
244 if (-1 != m_currentLayout)
247 for (int i = 0; i < m_appSurfaces.size(); ++i)
249 ilm_layerRemoveSurface(WINDOWMANAGER_LAYER_APPLICATIONS, m_appSurfaces.at(i));
250 //ilm_surfaceSetVisibility(m_appSurfaces.at(i), ILM_FALSE);
251 //ilm_surfaceSetOpacity(m_appSurfaces.at(i), 0.0);
255 // find the current used layout
256 QList<Layout>::const_iterator ci = m_layouts.begin();
258 Layout currentLayout;
259 while (ci != m_layouts.constEnd())
261 if (ci->id == m_currentLayout)
269 qDebug("show %d apps", mp_layoutAreaToSurfaceIdAssignment->size());
270 for (int j = 0; j < mp_layoutAreaToSurfaceIdAssignment->size(); ++j)
272 int surfaceToShow = mp_layoutAreaToSurfaceIdAssignment->find(j).value();
273 qDebug(" surface no. %d: %d", j, surfaceToShow);
275 addSurfaceToLayer(surfaceToShow, WINDOWMANAGER_LAYER_APPLICATIONS);
277 ilm_surfaceSetVisibility(surfaceToShow, ILM_TRUE);
278 ilm_surfaceSetOpacity(surfaceToShow, 1.0);
280 qDebug(" layout area %d", j);
281 qDebug(" x: %d", currentLayout.layoutAreas[j].x);
282 qDebug(" y: %d", currentLayout.layoutAreas[j].y);
283 qDebug(" w: %d", currentLayout.layoutAreas[j].width);
284 qDebug(" h: %d", currentLayout.layoutAreas[j].height);
286 ilm_surfaceSetDestinationRectangle(surfaceToShow,
287 currentLayout.layoutAreas[j].x,
288 currentLayout.layoutAreas[j].y,
289 currentLayout.layoutAreas[j].width,
290 currentLayout.layoutAreas[j].height);
295 // layer surface render order
297 t_ilm_surface* pArray;
298 ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_HOMESCREEN, &length, &pArray);
299 ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_HOMESCREEN, pArray, length);
301 ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_APPLICATIONS, &length, &pArray);
302 ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_APPLICATIONS, pArray, length);
304 ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY, &length, &pArray);
305 ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_HOMESCREEN_OVERLAY, pArray, length);
307 ilm_getSurfaceIDsOnLayer(WINDOWMANAGER_LAYER_POPUP, &length, &pArray);
308 ilm_layerSetRenderOrder(WINDOWMANAGER_LAYER_POPUP, pArray, length);
311 // display layer render order
312 t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
313 int num_layers = getLayerRenderOrder(renderOrder);
314 ilm_displaySetRenderOrder(0, renderOrder, num_layers);
315 ilm_displaySetRenderOrder(1, renderOrder, num_layers);
320 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
321 void WindowManager::notificationFunc_non_static(ilmObjectType object,
325 qDebug("-=[notificationFunc_non_static]=-");
326 qDebug("Notification from weston!");
327 if (ILM_SURFACE == object)
329 struct ilmSurfaceProperties surfaceProperties;
333 qDebug("Surface created, ID: %d", id);
334 ilm_getPropertiesOfSurface(id, &surfaceProperties);
335 qDebug(" origSourceWidth : %d", surfaceProperties.origSourceWidth);
336 qDebug(" origSourceHeight: %d", surfaceProperties.origSourceHeight);
338 if (WINDOWMANAGER_HOMESCREEN_MAIN_SURFACE_ID == id)
340 qDebug("HomeScreen app detected");
341 addSurfaceToLayer(id, WINDOWMANAGER_LAYER_HOMESCREEN);
346 //addSurfaceToLayer(id, WINDOWMANAGER_LAYER_APPLICATIONS);
348 m_appSurfaces.append(id);
350 ilm_surfaceAddNotification(id, surfaceCallbackFunction_static);
356 qDebug("Surface destroyed, ID: %d", id);
357 m_appSurfaces.removeAt(m_appSurfaces.indexOf(id));
358 ilm_surfaceRemoveNotification(id);
363 if (ILM_LAYER == object)
365 //qDebug("Layer.. we don't care...");
369 void WindowManager::notificationFunc_static(ilmObjectType object,
374 static_cast<WindowManager*>(WindowManager::myThis)->notificationFunc_non_static(object, id, created);
377 void WindowManager::surfaceCallbackFunction_non_static(t_ilm_surface surface,
378 struct ilmSurfaceProperties* surfaceProperties,
379 t_ilm_notification_mask mask)
381 qDebug("-=[surfaceCallbackFunction_non_static]=-");
382 qDebug("surfaceCallbackFunction_non_static changes for surface %d", surface);
383 if (ILM_NOTIFICATION_VISIBILITY & mask)
385 qDebug("ILM_NOTIFICATION_VISIBILITY");
386 surfaceVisibilityChanged(surface, surfaceProperties->visibility);
388 if (ILM_NOTIFICATION_OPACITY & mask)
390 qDebug("ILM_NOTIFICATION_OPACITY");
392 if (ILM_NOTIFICATION_ORIENTATION & mask)
394 qDebug("ILM_NOTIFICATION_ORIENTATION");
396 if (ILM_NOTIFICATION_SOURCE_RECT & mask)
398 qDebug("ILM_NOTIFICATION_SOURCE_RECT");
400 if (ILM_NOTIFICATION_DEST_RECT & mask)
402 qDebug("ILM_NOTIFICATION_DEST_RECT");
404 if (ILM_NOTIFICATION_CONTENT_AVAILABLE & mask)
406 qDebug("ILM_NOTIFICATION_CONTENT_AVAILABLE");
409 if (ILM_NOTIFICATION_CONTENT_REMOVED & mask)
411 qDebug("ILM_NOTIFICATION_CONTENT_REMOVED");
413 if (ILM_NOTIFICATION_CONFIGURED & mask)
415 qDebug("ILM_NOTIFICATION_CONFIGURED");
416 qDebug(" surfaceProperties %d", surface);
417 qDebug(" surfaceProperties.origSourceWidth: %d", surfaceProperties->origSourceWidth);
418 qDebug(" surfaceProperties.origSourceHeight: %d", surfaceProperties->origSourceHeight);
420 ilm_surfaceSetSourceRectangle(surface,
423 surfaceProperties->origSourceWidth,
424 surfaceProperties->origSourceHeight);
431 void WindowManager::surfaceCallbackFunction_static(t_ilm_surface surface,
432 struct ilmSurfaceProperties* surfaceProperties,
433 t_ilm_notification_mask mask)
436 static_cast<WindowManager*>(WindowManager::myThis)->surfaceCallbackFunction_non_static(surface, surfaceProperties, mask);
440 int WindowManager::layoutId() const
442 return m_currentLayout;
445 QString WindowManager::layoutName() const
447 QList<Layout>::const_iterator i = m_layouts.begin();
449 QString result = "not found";
450 while (i != m_layouts.constEnd())
452 if (i->id == m_currentLayout)
464 int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<LayoutArea> &surfaceAreas)
466 qDebug("-=[addLayout]=-");
467 m_layouts.append(Layout(layoutId, layoutName, surfaceAreas));
469 qDebug("addLayout %d %s, size %d",
471 layoutName.toStdString().c_str(),
472 surfaceAreas.size());
476 return WINDOWMANAGER_NO_ERROR;
479 int WindowManager::deleteLayoutById(int layoutId)
481 qDebug("-=[deleteLayoutById]=-");
482 qDebug("layoutId: %d", layoutId);
483 int result = WINDOWMANAGER_NO_ERROR;
485 if (m_currentLayout == layoutId)
487 result = WINDOWMANAGER_ERROR_ID_IN_USE;
491 QList<Layout>::iterator i = m_layouts.begin();
492 result = WINDOWMANAGER_ERROR_ID_IN_USE;
493 while (i != m_layouts.constEnd())
495 if (i->id == layoutId)
498 result = WINDOWMANAGER_NO_ERROR;
510 QList<Layout> WindowManager::getAllLayouts()
512 qDebug("-=[getAllLayouts]=-");
517 QList<int> WindowManager::getAllSurfacesOfProcess(int pid)
520 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
521 struct ilmSurfaceProperties surfaceProperties;
523 for (int i = 0; i < m_appSurfaces.size(); ++i)
525 ilm_getPropertiesOfSurface(m_appSurfaces.at(i), &surfaceProperties);
526 if (pid == surfaceProperties.creatorPid)
528 result.append(m_appSurfaces.at(i));
535 QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
537 qDebug("-=[getAvailableLayouts]=-");
538 QList<Layout>::const_iterator i = m_layouts.begin();
541 while (i != m_layouts.constEnd())
543 if (i->layoutAreas.size() == numberOfAppSurfaces)
545 result.append(i->id);
554 QList<int> WindowManager::getAvailableSurfaces()
556 qDebug("-=[getAvailableSurfaces]=-");
558 return m_appSurfaces;
561 QString WindowManager::getLayoutName(int layoutId)
563 qDebug("-=[getLayoutName]=-");
564 QList<Layout>::const_iterator i = m_layouts.begin();
566 QString result = "not found";
567 while (i != m_layouts.constEnd())
569 if (i->id == layoutId)
580 void WindowManager::hideLayer(int layer)
582 qDebug("-=[hideLayer]=-");
583 qDebug("layer %d", layer);
585 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
586 // POPUP=0, HOMESCREEN_OVERLAY=1, APPS=2, HOMESCREEN=3
587 if (layer >= 0 && layer < WINDOWMANAGER_LAYER_NUM) {
588 m_showLayers[layer] = 0;
590 t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
591 int num_layers = getLayerRenderOrder(renderOrder);
592 ilm_displaySetRenderOrder(0, renderOrder, num_layers);
593 ilm_displaySetRenderOrder(1, renderOrder, num_layers);
599 int WindowManager::setLayoutById(int layoutId)
601 qDebug("-=[setLayoutById]=-");
602 int result = WINDOWMANAGER_NO_ERROR;
603 m_currentLayout = layoutId;
605 mp_layoutAreaToSurfaceIdAssignment->clear();
612 int WindowManager::setLayoutByName(const QString &layoutName)
614 qDebug("-=[setLayoutByName]=-");
615 int result = WINDOWMANAGER_NO_ERROR;
617 QList<Layout>::const_iterator i = m_layouts.begin();
619 while (i != m_layouts.constEnd())
621 if (i->name == layoutName)
623 m_currentLayout = i->id;
625 mp_layoutAreaToSurfaceIdAssignment->clear();
636 int WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
638 qDebug("-=[setSurfaceToLayoutArea]=-");
639 int result = WINDOWMANAGER_NO_ERROR;
641 qDebug("surfaceId %d", surfaceId);
642 qDebug("layoutAreaId %d", layoutAreaId);
643 mp_layoutAreaToSurfaceIdAssignment->insert(layoutAreaId, surfaceId);
652 void WindowManager::showLayer(int layer)
654 qDebug("-=[showLayer]=-");
655 qDebug("layer %d", layer);
657 #ifdef HAVE_IVI_LAYERMANAGEMENT_API
658 // POPUP=0, HOMESCREEN_OVERLAY=1, APPS=2, HOMESCREEN=3
659 if (layer >= 0 && layer < WINDOWMANAGER_LAYER_NUM) {
660 m_showLayers[layer] = layer_id_array[layer];
662 t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
663 int num_layers = getLayerRenderOrder(renderOrder);
664 ilm_displaySetRenderOrder(0, renderOrder, num_layers);
665 ilm_displaySetRenderOrder(1, renderOrder, num_layers);