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"
18 #include <wayland-client.h>
21 //////////////////////////////////////////
22 // THIS IS STILL UNDER HEAVY DEVELOPMENT!
23 // DO NOT JUDGE THE SOURCE CODE :)
24 //////////////////////////////////////////
26 // three layers will be defined. The HomeScreen will be placed
27 // full screen in the background.
28 // On top all applications in one layer.
29 // On top of that, the popup layer.
30 #define WINDOWMANAGER_LAYER_POPUP 100
31 #define WINDOWMANAGER_LAYER_APPLICATIONS 101
32 #define WINDOWMANAGER_LAYER_HOMESCREEN 102
34 #define WINDOWMANAGER_LAYER_NUM 3
36 void* WindowManager::myThis = 0;
38 WindowManager::WindowManager(QObject *parent) :
42 mp_layoutAreaToSurfaceIdAssignment(0),
46 qDebug("-=[WindowManager]=-");
47 // publish windowmanager interface
48 mp_windowManagerAdaptor = new WindowmanagerAdaptor((QObject*)this);
50 QDBusConnection dbus = QDBusConnection::sessionBus();
51 dbus.registerObject("/windowmanager", this);
52 dbus.registerService("org.agl.windowmanager");
55 void WindowManager::start()
57 qDebug("-=[start]=-");
58 mp_layoutAreaToSurfaceIdAssignment = new QMap<int, unsigned int>;
63 qDebug("ilm_init = %d", err);
66 err = ilm_registerNotification(WindowManager::notificationFunc_static, this);
68 createNewLayer(WINDOWMANAGER_LAYER_POPUP);
69 createNewLayer(WINDOWMANAGER_LAYER_APPLICATIONS);
70 createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN);
74 WindowManager::~WindowManager()
76 qDebug("-=[~WindowManager]=-");
77 delete mp_windowManagerAdaptor;
81 delete mp_layoutAreaToSurfaceIdAssignment;
84 void WindowManager::dumpScene()
87 qDebug("current layout : %d", m_currentLayout);
88 qDebug("available layouts: %d", m_layouts.size());
89 QList<Layout>::const_iterator i = m_layouts.begin();
91 while (i != m_layouts.constEnd())
93 qDebug("--[id: %d]--[%s]--", i->id, i->name.toStdString().c_str());
94 qDebug(" %d surface areas", i->layoutAreas.size());
95 for (int j = 0; j < i->layoutAreas.size(); ++j)
97 qDebug(" -area %d", j);
98 qDebug(" -x : %d", i->layoutAreas.at(j).x);
99 qDebug(" -y : %d", i->layoutAreas.at(j).y);
100 qDebug(" -width : %d", i->layoutAreas.at(j).width);
101 qDebug(" -height: %d", i->layoutAreas.at(j).height);
110 void WindowManager::createNewLayer(int layerId)
112 qDebug("-=[createNewLayer]=-");
113 qDebug("layerId %d", layerId);
115 t_ilm_uint screenID = 0;
119 ilm_getScreenResolution(screenID, &width, &height);
121 t_ilm_layer newLayerId = layerId;
122 ilm_layerCreateWithDimension(&newLayerId, width, height);
123 ilm_layerSetOpacity(newLayerId, 1.0);
124 ilm_layerSetVisibility(newLayerId, ILM_TRUE);
125 ilm_layerSetSourceRectangle(newLayerId,
130 ilm_layerSetDestinationRectangle(newLayerId,
139 void WindowManager::addSurfaceToLayer(int surfaceId, int layerId)
141 qDebug("-=[addSurfaceToLayer]=-");
142 qDebug("surfaceId %d", surfaceId);
143 qDebug("layerId %d", layerId);
145 if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN)
147 struct ilmSurfaceProperties surfaceProperties;
148 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
150 // homescreen app always fullscreen in the back
151 t_ilm_uint screenID = 0;
155 ilm_getScreenResolution(screenID, &width, &height);
157 ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, width, height);
158 ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
159 ilm_surfaceSetOpacity(surfaceId, 1.0);
160 ilm_surfaceSetVisibility(surfaceId, ILM_TRUE);
162 ilm_layerAddSurface(layerId, surfaceId);
165 if (layerId == WINDOWMANAGER_LAYER_APPLICATIONS)
167 struct ilmSurfaceProperties surfaceProperties;
168 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
170 ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
171 ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
172 ilm_surfaceSetOpacity(surfaceId, 0.0);
173 ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
175 ilm_layerAddSurface(layerId, surfaceId);
178 if (layerId == WINDOWMANAGER_LAYER_POPUP)
180 struct ilmSurfaceProperties surfaceProperties;
181 ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
183 ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
184 ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
185 ilm_surfaceSetOpacity(surfaceId, 0.0);
186 ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
188 ilm_layerAddSurface(layerId, surfaceId);
196 void WindowManager::updateScreen()
198 qDebug("-=[updateScreen]=-");
200 if (-1 != m_currentLayout)
204 t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
205 renderOrder[0] = WINDOWMANAGER_LAYER_HOMESCREEN;
206 renderOrder[1] = WINDOWMANAGER_LAYER_APPLICATIONS;
207 renderOrder[2] = WINDOWMANAGER_LAYER_POPUP;
210 for (int i = 0; i < m_surfaces.size(); ++i)
212 ilm_surfaceSetVisibility(m_surfaces.at(i), ILM_FALSE);
213 ilm_surfaceSetOpacity(m_surfaces.at(i), 0.0);
216 // find the current used layout
217 QList<Layout>::const_iterator ci = m_layouts.begin();
219 Layout currentLayout;
220 while (ci != m_layouts.constEnd())
222 if (ci->id == m_currentLayout)
230 qDebug("show %d apps", mp_layoutAreaToSurfaceIdAssignment->size());
231 for (int j = 0; j < mp_layoutAreaToSurfaceIdAssignment->size(); ++j)
233 int surfaceToShow = mp_layoutAreaToSurfaceIdAssignment->find(j).value();
234 qDebug(" surface no. %d: %d", j, surfaceToShow);
236 ilm_surfaceSetVisibility(surfaceToShow, ILM_TRUE);
237 ilm_surfaceSetOpacity(surfaceToShow, 1.0);
239 qDebug(" layout area %d", j);
240 qDebug(" x: %d", currentLayout.layoutAreas[j].x);
241 qDebug(" y: %d", currentLayout.layoutAreas[j].y);
242 qDebug(" w: %d", currentLayout.layoutAreas[j].width);
243 qDebug(" h: %d", currentLayout.layoutAreas[j].height);
245 ilm_surfaceSetDestinationRectangle(surfaceToShow,
246 currentLayout.layoutAreas[j].x,
247 currentLayout.layoutAreas[j].y,
248 currentLayout.layoutAreas[j].width,
249 currentLayout.layoutAreas[j].height);
252 ilm_displaySetRenderOrder(0, renderOrder, WINDOWMANAGER_LAYER_NUM);
260 void WindowManager::notificationFunc_non_static(ilmObjectType object,
264 qDebug("-=[notificationFunc_non_static]=-");
265 qDebug("Notification from weston!");
266 if (ILM_SURFACE == object)
268 struct ilmSurfaceProperties surfaceProperties;
272 qDebug("Surface created, ID: %d", id);
273 ilm_getPropertiesOfSurface(id, &surfaceProperties);
274 qDebug(" origSourceWidth : %d", surfaceProperties.origSourceWidth);
275 qDebug(" origSourceHeight: %d", surfaceProperties.origSourceHeight);
277 if (m_homeScreenPid == surfaceProperties.creatorPid)
279 if (m_homeScreenSurfaceId != id)
281 qDebug("HomeScreen app detected");
282 m_homeScreenSurfaceId = id;
283 addSurfaceToLayer(id, WINDOWMANAGER_LAYER_HOMESCREEN);
289 addSurfaceToLayer(id, WINDOWMANAGER_LAYER_APPLICATIONS);
291 m_surfaces.append(id);
293 ilm_surfaceAddNotification(id, surfaceCallbackFunction_static);
299 qDebug("Surface destroyed, ID: %d", id);
300 m_surfaces.removeAt(m_surfaces.indexOf(id));
301 ilm_surfaceRemoveNotification(id);
306 if (ILM_LAYER == object)
308 //qDebug("Layer.. we don't care...");
312 void WindowManager::notificationFunc_static(ilmObjectType object,
317 static_cast<WindowManager*>(WindowManager::myThis)->notificationFunc_non_static(object, id, created);
320 void WindowManager::surfaceCallbackFunction_non_static(t_ilm_surface surface,
321 struct ilmSurfaceProperties* surfaceProperties,
322 t_ilm_notification_mask mask)
324 qDebug("-=[surfaceCallbackFunction_non_static]=-");
325 qDebug("surfaceCallbackFunction_non_static changes for surface %d", surface);
326 if (ILM_NOTIFICATION_VISIBILITY & mask)
328 qDebug("ILM_NOTIFICATION_VISIBILITY");
331 if (ILM_NOTIFICATION_OPACITY & mask)
333 qDebug("ILM_NOTIFICATION_OPACITY");
336 if (ILM_NOTIFICATION_ORIENTATION & mask)
338 qDebug("ILM_NOTIFICATION_ORIENTATION");
341 if (ILM_NOTIFICATION_SOURCE_RECT & mask)
343 qDebug("ILM_NOTIFICATION_SOURCE_RECT");
346 if (ILM_NOTIFICATION_DEST_RECT & mask)
348 qDebug("ILM_NOTIFICATION_DEST_RECT");
352 void WindowManager::surfaceCallbackFunction_static(t_ilm_surface surface,
353 struct ilmSurfaceProperties* surfaceProperties,
354 t_ilm_notification_mask mask)
357 static_cast<WindowManager*>(WindowManager::myThis)->surfaceCallbackFunction_non_static(surface, surfaceProperties, mask);
362 int WindowManager::homeScreenPid() const
364 return m_homeScreenPid;
367 void WindowManager::setHomeScreenPid(int value)
369 m_homeScreenPid = value;
371 // maybe the HomeSceen app has already provided its surface.
372 // if so, shift it to the correct layer
373 // find the current used layout
374 QList<int>::iterator ci = m_surfaces.begin();
376 struct ilmSurfaceProperties surfaceProperties;
378 while ((!found) && (ci != m_surfaces.constEnd()))
380 ilm_getPropertiesOfSurface(*ci, &surfaceProperties);
381 if (m_homeScreenPid == surfaceProperties.creatorPid)
383 qDebug("HomeScreen app detected");
384 m_homeScreenSurfaceId = *ci;
385 addSurfaceToLayer(*ci, WINDOWMANAGER_LAYER_HOMESCREEN);
386 m_surfaces.erase(ci);
399 int WindowManager::layoutId() const
401 return m_currentLayout;
404 QString WindowManager::layoutName() const
406 QList<Layout>::const_iterator i = m_layouts.begin();
408 QString result = "not found";
409 while (i != m_layouts.constEnd())
411 if (i->id == m_currentLayout)
423 int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<LayoutArea> &surfaceAreas)
425 qDebug("-=[addLayout]=-");
426 m_layouts.append(Layout(layoutId, layoutName, surfaceAreas));
428 qDebug("addLayout %d %s, size %d",
430 layoutName.toStdString().c_str(),
431 surfaceAreas.size());
435 return WINDOWMANAGER_NO_ERROR;
438 QList<Layout> WindowManager::getAllLayouts()
440 qDebug("-=[getAllLayouts]=-");
445 QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
447 qDebug("-=[getAvailableLayouts]=-");
448 QList<Layout>::const_iterator i = m_layouts.begin();
451 while (i != m_layouts.constEnd())
453 if (i->layoutAreas.size() == numberOfAppSurfaces)
455 result.append(i->id);
464 QList<int> WindowManager::getAvailableSurfaces()
466 qDebug("-=[getAvailableSurfaces]=-");
471 QString WindowManager::getLayoutName(int layoutId)
473 qDebug("-=[getLayoutName]=-");
474 QList<Layout>::const_iterator i = m_layouts.begin();
476 QString result = "not found";
477 while (i != m_layouts.constEnd())
479 if (i->id == layoutId)
491 int WindowManager::setLayoutById(int layoutId)
493 qDebug("-=[setLayoutById]=-");
494 int result = WINDOWMANAGER_NO_ERROR;
495 m_currentLayout = layoutId;
497 mp_layoutAreaToSurfaceIdAssignment->clear();
504 int WindowManager::setLayoutByName(const QString &layoutName)
506 qDebug("-=[setLayoutByName]=-");
507 int result = WINDOWMANAGER_NO_ERROR;
509 QList<Layout>::const_iterator i = m_layouts.begin();
511 while (i != m_layouts.constEnd())
513 if (i->name == layoutName)
515 m_currentLayout = i->id;
517 mp_layoutAreaToSurfaceIdAssignment->clear();
528 int WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
530 qDebug("-=[setSurfaceToLayoutArea]=-");
531 int result = WINDOWMANAGER_NO_ERROR;
533 qDebug("surfaceId %d", surfaceId);
534 qDebug("layoutAreaId %d", layoutAreaId);
535 mp_layoutAreaToSurfaceIdAssignment->insert(layoutAreaId, surfaceId);