HomeScreen is now visible independent of the Layout set.
[staging/HomeScreen.git] / WindowManager / src / windowmanager.cpp
index d35db9b..26d650f 100644 (file)
 // DO NOT JUDGE THE SOURCE CODE :)
 //////////////////////////////////////////
 
+// three layers will be defined. The HomeScreen will be placed
+// full screen in the background.
+// On top all applications in one layer.
+// On top of that, the popup layer.
+#define WINDOWMANAGER_LAYER_POPUP 100
+#define WINDOWMANAGER_LAYER_APPLICATIONS 101
+#define WINDOWMANAGER_LAYER_HOMESCREEN 102
+
+#define WINDOWMANAGER_LAYER_NUM 3
+
 void* WindowManager::myThis = 0;
 
 WindowManager::WindowManager(QObject *parent) :
     QObject(parent),
     m_layouts(),
-    m_layoutNames(),
-    m_currentLayout(-1)
+    m_surfaces(),
+    mp_layoutAreaToSurfaceIdAssignment(0),
+    m_currentLayout(-1),
+    m_homeScreenPid(-1)
 {
-    qDebug("WindowManager");
+    qDebug("-=[WindowManager]=-");
     // publish windowmanager interface
     mp_windowManagerAdaptor = new WindowmanagerAdaptor((QObject*)this);
 
     QDBusConnection dbus = QDBusConnection::sessionBus();
     dbus.registerObject("/windowmanager", this);
     dbus.registerService("org.agl.windowmanager");
+}
 
+void WindowManager::start()
+{
+    qDebug("-=[start]=-");
+    mp_layoutAreaToSurfaceIdAssignment = new QMap<int, unsigned int>;
 #ifdef __arm__
-    mp_processLayers = new QList<int>;
-    mp_surfaces = new QMap<t_ilm_uint, SurfaceInfo>;
-
     ilmErrorTypes err;
 
     err = ilm_init();
@@ -51,18 +65,20 @@ WindowManager::WindowManager(QObject *parent) :
     myThis = this;
     err =  ilm_registerNotification(WindowManager::notificationFunc_static, this);
 
-
+    createNewLayer(WINDOWMANAGER_LAYER_POPUP);
+    createNewLayer(WINDOWMANAGER_LAYER_APPLICATIONS);
+    createNewLayer(WINDOWMANAGER_LAYER_HOMESCREEN);
 #endif
 }
 
 WindowManager::~WindowManager()
 {
+    qDebug("-=[~WindowManager]=-");
     delete mp_windowManagerAdaptor;
 #ifdef __arm__
-    delete mp_surfaces;
-
     ilm_destroy();
 #endif
+    delete mp_layoutAreaToSurfaceIdAssignment;
 }
 
 void WindowManager::dumpScene()
@@ -70,92 +86,191 @@ void WindowManager::dumpScene()
     qDebug("\n");
     qDebug("current layout   : %d", m_currentLayout);
     qDebug("available layouts: %d", m_layouts.size());
-    QMap<int, QList<SimpleRect> >::iterator i = m_layouts.begin();
+    QList<Layout>::const_iterator i = m_layouts.begin();
 
-    QList<int> result;
     while (i != m_layouts.constEnd())
     {
-        qDebug("--[id: %d]--[%s]--", i.key(), m_layoutNames.find(i.key()).value().toStdString().c_str());
-        qDebug("  %d surface areas", i.value().size());
-        for (int j = 0; j < i.value().size(); ++j)
+        qDebug("--[id: %d]--[%s]--", i->id, i->name.toStdString().c_str());
+        qDebug("  %d surface areas", i->layoutAreas.size());
+        for (int j = 0; j < i->layoutAreas.size(); ++j)
         {
             qDebug("  -area %d", j);
-            qDebug("    -x     : %d", i.value().at(j).x);
-            qDebug("    -y     : %d", i.value().at(j).y);
-            qDebug("    -width : %d", i.value().at(j).width);
-            qDebug("    -height: %d", i.value().at(j).height);
+            qDebug("    -x     : %d", i->layoutAreas.at(j).x);
+            qDebug("    -y     : %d", i->layoutAreas.at(j).y);
+            qDebug("    -width : %d", i->layoutAreas.at(j).width);
+            qDebug("    -height: %d", i->layoutAreas.at(j).height);
         }
 
         ++i;
     }
-
 }
 
 #ifdef __arm__
 
 void WindowManager::createNewLayer(int layerId)
 {
-    ilmErrorTypes err;
+    qDebug("-=[createNewLayer]=-");
+    qDebug("layerId %d", layerId);
 
     t_ilm_uint screenID = 0;
     t_ilm_uint width;
     t_ilm_uint height;
 
-    err = ilm_getScreenResolution(screenID, &width, &height);
+    ilm_getScreenResolution(screenID, &width, &height);
 
     t_ilm_layer newLayerId = layerId;
-    err = ilm_layerCreateWithDimension(&newLayerId, width, height);
-    qDebug("ilm_layerCreateWithDimension = %d", err);
-    qDebug("layerIdWallpaper = %d", newLayerId);
-
-    err = ilm_layerSetVisibility(newLayerId, true);
-    qDebug("ilm_layerSetVisibility = %d", err);
-
-    t_ilm_float opacity = 1.0;
-    err =  ilm_layerSetOpacity(newLayerId, opacity);
+    ilm_layerCreateWithDimension(&newLayerId, width, height);
+    ilm_layerSetOpacity(newLayerId, 1.0);
+    ilm_layerSetVisibility(newLayerId, ILM_TRUE);
+    ilm_layerSetSourceRectangle(newLayerId,
+                                    0,
+                                    0,
+                                    width,
+                                    height);
+    ilm_layerSetDestinationRectangle(newLayerId,
+                                    0,
+                                    0,
+                                    width,
+                                    height);
 
     ilm_commitChanges();
 }
 
 void WindowManager::addSurfaceToLayer(int surfaceId, int layerId)
 {
-    t_ilm_int length;
-    t_ilm_layer* pArray;
+    qDebug("-=[addSurfaceToLayer]=-");
+    qDebug("surfaceId %d", surfaceId);
+    qDebug("layerId %d", layerId);
 
-    ilm_getLayerIDs(&length, &pArray);
-    bool layerFound(false);
-    for (int i = 0; i< length; ++i)
+    if (layerId == WINDOWMANAGER_LAYER_HOMESCREEN)
     {
-        if (layerId == pArray[i])
-        {
-            layerFound = true;
-        }
+        struct ilmSurfaceProperties surfaceProperties;
+        ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
+
+        qDebug("sourceX %d", surfaceProperties.sourceX);
+        qDebug("sourceY %d", surfaceProperties.sourceY);
+        qDebug("sourceWidth %d", surfaceProperties.sourceWidth);
+        qDebug("sourceHeight %d", surfaceProperties.sourceHeight);
+
+        // homescreen app always fullscreen in the back
+        t_ilm_uint screenID = 0;
+        t_ilm_uint width;
+        t_ilm_uint height;
+
+        ilm_getScreenResolution(screenID, &width, &height);
+
+        ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, width, height);
+        ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
+        ilm_surfaceSetOpacity(surfaceId, 1.0);
+        ilm_surfaceSetVisibility(surfaceId, ILM_TRUE);
+
+        ilm_layerAddSurface(layerId, surfaceId);
     }
 
-    if (!layerFound)
+    if (layerId == WINDOWMANAGER_LAYER_APPLICATIONS)
     {
-        createNewLayer(layerId);
+        struct ilmSurfaceProperties surfaceProperties;
+        ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
+
+        ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
+        ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
+        ilm_surfaceSetOpacity(surfaceId, 0.0);
+        ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
+
+        ilm_layerAddSurface(layerId, surfaceId);
     }
 
-    struct ilmSurfaceProperties surfaceProperties;
-    ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
-    qDebug("  origSourceWidth : %d", surfaceProperties.origSourceWidth);
-    qDebug("  origSourceHeight: %d", surfaceProperties.origSourceHeight);
+    if (layerId == WINDOWMANAGER_LAYER_POPUP)
+    {
+        struct ilmSurfaceProperties surfaceProperties;
+        ilm_getPropertiesOfSurface(surfaceId, &surfaceProperties);
+
+        ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
+        ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
+        ilm_surfaceSetOpacity(surfaceId, 0.0);
+        ilm_surfaceSetVisibility(surfaceId, ILM_FALSE);
+
+        ilm_layerAddSurface(layerId, surfaceId);
+    }
+
+    ilm_commitChanges();
+}
+
+#endif
+
+void WindowManager::updateScreen()
+{
+    qDebug("-=[updateScreen]=-");
+
+#ifdef __arm__
+    if (-1 != m_currentLayout)
+    {
+
+        // hide all surfaces
+        for (int i = 0; i < m_surfaces.size(); ++i)
+        {
+            ilm_surfaceSetVisibility(m_surfaces.at(i), ILM_FALSE);
+            ilm_surfaceSetOpacity(m_surfaces.at(i), 0.0);
+        }
+
+        // find the current used layout
+        QList<Layout>::const_iterator ci = m_layouts.begin();
+
+        Layout currentLayout;
+        while (ci != m_layouts.constEnd())
+        {
+            if (ci->id == m_currentLayout)
+            {
+                currentLayout = *ci;
+            }
+
+            ++ci;
+        }
+
+        qDebug("show %d apps", mp_layoutAreaToSurfaceIdAssignment->size());
+        for (int j = 0; j < mp_layoutAreaToSurfaceIdAssignment->size(); ++j)
+        {
+            int surfaceToShow = mp_layoutAreaToSurfaceIdAssignment->find(j).value();
+            qDebug("  surface no. %d: %d", j, surfaceToShow);
+
+            ilm_surfaceSetVisibility(surfaceToShow, ILM_TRUE);
+            ilm_surfaceSetOpacity(surfaceToShow, 1.0);
+
+            qDebug("  layout area %d", j);
+            qDebug("    x: %d", currentLayout.layoutAreas[j].x);
+            qDebug("    y: %d", currentLayout.layoutAreas[j].y);
+            qDebug("    w: %d", currentLayout.layoutAreas[j].width);
+            qDebug("    h: %d", currentLayout.layoutAreas[j].height);
+
+            ilm_surfaceSetDestinationRectangle(surfaceToShow,
+                                             currentLayout.layoutAreas[j].x,
+                                             currentLayout.layoutAreas[j].y,
+                                             currentLayout.layoutAreas[j].width,
+                                             currentLayout.layoutAreas[j].height);
+        }
+
+        ilm_commitChanges();
+    }
 
-    ilm_surfaceSetDestinationRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
-    ilm_surfaceSetSourceRectangle(surfaceId, 0, 0, surfaceProperties.origSourceWidth, surfaceProperties.origSourceHeight);
-    ilm_surfaceSetOpacity(surfaceId, 1.0);
-    ilm_surfaceSetVisibility(surfaceId, true);
+    t_ilm_layer renderOrder[WINDOWMANAGER_LAYER_NUM];
+    renderOrder[0] = WINDOWMANAGER_LAYER_HOMESCREEN;
+    renderOrder[1] = WINDOWMANAGER_LAYER_APPLICATIONS;
+    renderOrder[2] = WINDOWMANAGER_LAYER_POPUP;
 
-    ilm_layerAddSurface(layerId, surfaceId);
+    ilm_displaySetRenderOrder(0, renderOrder, WINDOWMANAGER_LAYER_NUM);
 
     ilm_commitChanges();
+
+#endif
 }
 
+#ifdef __arm__
 void WindowManager::notificationFunc_non_static(ilmObjectType object,
                                     t_ilm_uint id,
                                     t_ilm_bool created)
 {
+    qDebug("-=[notificationFunc_non_static]=-");
+    qDebug("Notification from weston!");
     if (ILM_SURFACE == object)
     {
         struct ilmSurfaceProperties surfaceProperties;
@@ -167,66 +282,34 @@ void WindowManager::notificationFunc_non_static(ilmObjectType object,
             qDebug("  origSourceWidth : %d", surfaceProperties.origSourceWidth);
             qDebug("  origSourceHeight: %d", surfaceProperties.origSourceHeight);
 
-            addSurfaceToLayer(id, surfaceProperties.creatorPid);
-
-            t_ilm_int length;
-            t_ilm_surface* pArray;
-            ilm_getSurfaceIDs(&length, &pArray);
-            ilm_layerSetRenderOrder(42, pArray, length);
-
-            ilm_commitChanges();
-
-            SurfaceInfo surfaceInfo;
-            surfaceInfo.pid = surfaceProperties.creatorPid;
-            QString procInfoFileName = QString("/proc/") + QString::number(surfaceInfo.pid) + QString("/comm");
-            QFile procInfo(procInfoFileName);
-            if (procInfo.open(QIODevice::ReadOnly))
+            if (m_homeScreenPid == surfaceProperties.creatorPid)
             {
-                QTextStream in(&procInfo);
-                surfaceInfo.processName = in.readLine();
-                qDebug("surface id %d, pid %d: %s", id, surfaceInfo.pid, surfaceInfo.processName.toStdString().c_str());
+                if (m_homeScreenSurfaceId != id)
+                {
+                    qDebug("HomeScreen app detected");
+                    m_homeScreenSurfaceId = id;
+                    addSurfaceToLayer(id, WINDOWMANAGER_LAYER_HOMESCREEN);
+                    updateScreen();
+                }
             }
+            else
+            {
+                addSurfaceToLayer(id, WINDOWMANAGER_LAYER_APPLICATIONS);
 
-            mp_surfaces->insert(id, surfaceInfo);
+                m_surfaces.append(id);
+            }
             ilm_surfaceAddNotification(id, surfaceCallbackFunction_static);
+
+            ilm_commitChanges();
         }
         else
         {
             qDebug("Surface destroyed, ID: %d", id);
-            mp_surfaces->erase(mp_surfaces->find(id));
+            m_surfaces.removeAt(m_surfaces.indexOf(id));
             ilm_surfaceRemoveNotification(id);
-        }
 
-        // rearrange surfaces on screen
-        t_ilm_uint screenID = 0;
-        t_ilm_uint width;
-        t_ilm_uint height;
-        ilm_getScreenResolution(screenID, &width, &height);
-
-        qDebug("%d surfaces to show", mp_surfaces->count());
-
-        QMap<t_ilm_uint, SurfaceInfo>::const_iterator i = mp_surfaces->constBegin();
-        int counter(0);
-        while (i != mp_surfaces->constEnd())
-        {
-            qDebug("place surface %d at x: %f, y: %d, width: %f, height: %d",
-                   i.key(),
-                   counter * (width / (1.0 * mp_surfaces->count())),
-                   0,
-                   width / (1.0 * mp_surfaces->count()),
-                   height);
-            ilm_surfaceSetDestinationRectangle(i.key(),
-                    counter * (width / (1.0 * mp_surfaces->count())),
-                    0,
-                    width / (1.0 * mp_surfaces->count()),
-                    height);
-
-            ++i;
-            ++counter;
+            ilm_commitChanges();
         }
-
-
-        ilm_commitChanges();
     }
     if (ILM_LAYER == object)
     {
@@ -242,13 +325,11 @@ void WindowManager::notificationFunc_static(ilmObjectType object,
     static_cast<WindowManager*>(WindowManager::myThis)->notificationFunc_non_static(object, id, created);
 }
 
-
-
-
 void WindowManager::surfaceCallbackFunction_non_static(t_ilm_surface surface,
                                     struct ilmSurfaceProperties* surfaceProperties,
                                     t_ilm_notification_mask mask)
 {
+    qDebug("-=[surfaceCallbackFunction_non_static]=-");
     qDebug("surfaceCallbackFunction_non_static changes for surface %d", surface);
     if (ILM_NOTIFICATION_VISIBILITY & mask)
     {
@@ -285,27 +366,59 @@ void WindowManager::surfaceCallbackFunction_static(t_ilm_surface surface,
 }
 #endif
 
-int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<SimpleRect> &surfaceAreas)
+
+int WindowManager::homeScreenPid() const
+{
+    return m_homeScreenPid;
+}
+
+void WindowManager::setHomeScreenPid(int value)
 {
-    m_layouts.insert(layoutId, surfaceAreas);
-    m_layoutNames.insert(layoutId, layoutName);
-    qDebug("addLayout %d %s, size %d", layoutId, layoutName.toStdString().c_str(), surfaceAreas.size());
+    m_homeScreenPid = value;
+#ifdef __arm__
+    // maybe the HomeSceen app has already provided its surface.
+    // if so, shift it to the correct layer
+    // find the current used layout
+    QList<int>::iterator ci = m_surfaces.begin();
+
+    struct ilmSurfaceProperties surfaceProperties;
+    bool found = false;
+    while ((!found) && (ci != m_surfaces.constEnd()))
+    {
+        ilm_getPropertiesOfSurface(*ci, &surfaceProperties);
+        if (m_homeScreenPid == surfaceProperties.creatorPid)
+        {
+            qDebug("HomeScreen app detected");
+            m_homeScreenSurfaceId = *ci;
+            addSurfaceToLayer(*ci, WINDOWMANAGER_LAYER_HOMESCREEN);
+            m_surfaces.erase(ci);
+            found = true;
+            updateScreen();
+        }
+
+        ++ci;
+    }
+#endif
 
+    updateScreen();
     dumpScene();
+}
 
-    return true;
+int WindowManager::layoutId() const
+{
+    return m_currentLayout;
 }
 
-QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
+QString WindowManager::layoutName() const
 {
-    QMap<int, QList<SimpleRect> >::iterator i = m_layouts.begin();
+    QList<Layout>::const_iterator i = m_layouts.begin();
 
-    QList<int> result;
+    QString result = "not found";
     while (i != m_layouts.constEnd())
     {
-        if (i.value().size() == numberOfAppSurfaces)
+        if (i->id == m_currentLayout)
         {
-            result.append(i.key());
+            result = i->name;
         }
 
         ++i;
@@ -314,57 +427,124 @@ QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
     return result;
 }
 
-// maybe not needed anymore
-QList<SimplePoint> WindowManager::getAvailableSurfaces()
+
+int WindowManager::addLayout(int layoutId, const QString &layoutName, const QList<LayoutArea> &surfaceAreas)
 {
-    QList<SimplePoint> points;
-    SimplePoint point;
-    point.x = 1;
-    point.y = 2;
-    points.append(point);
-    point.x = 11;
-    point.y = 22;
-    points.append(point);
-    point.x = 111;
-    point.y = 222;
-    points.append(point);
-
-    return points;
+    qDebug("-=[addLayout]=-");
+    m_layouts.append(Layout(layoutId, layoutName, surfaceAreas));
+
+    qDebug("addLayout %d %s, size %d",
+           layoutId,
+           layoutName.toStdString().c_str(),
+           surfaceAreas.size());
+
+    dumpScene();
+
+    return WINDOWMANAGER_NO_ERROR;
 }
 
-int WindowManager::getLayout()
+QList<Layout> WindowManager::getAllLayouts()
 {
-    return m_currentLayout;
+    qDebug("-=[getAllLayouts]=-");
+
+    return m_layouts;
+}
+
+QList<int> WindowManager::getAvailableLayouts(int numberOfAppSurfaces)
+{
+    qDebug("-=[getAvailableLayouts]=-");
+    QList<Layout>::const_iterator i = m_layouts.begin();
+
+    QList<int> result;
+    while (i != m_layouts.constEnd())
+    {
+        if (i->layoutAreas.size() == numberOfAppSurfaces)
+        {
+            result.append(i->id);
+        }
+
+        ++i;
+    }
+
+    return result;
+}
+
+QList<int> WindowManager::getAvailableSurfaces()
+{
+    qDebug("-=[getAvailableSurfaces]=-");
+
+    return m_surfaces;
 }
 
 QString WindowManager::getLayoutName(int layoutId)
 {
-    return m_layoutNames.find(layoutId).value();
+    qDebug("-=[getLayoutName]=-");
+    QList<Layout>::const_iterator i = m_layouts.begin();
+
+    QString result = "not found";
+    while (i != m_layouts.constEnd())
+    {
+        if (i->id == layoutId)
+        {
+            result = i->name;
+        }
+
+        ++i;
+    }
+
+    return result;
 }
 
-void WindowManager::setLayoutById(int layoutId)
+
+int WindowManager::setLayoutById(int layoutId)
 {
+    qDebug("-=[setLayoutById]=-");
+    int result = WINDOWMANAGER_NO_ERROR;
     m_currentLayout = layoutId;
 
+    mp_layoutAreaToSurfaceIdAssignment->clear();
+
     dumpScene();
+
+    return result;
 }
 
-void WindowManager::setLayoutByName(const QString &layoutName)
+int WindowManager::setLayoutByName(const QString &layoutName)
 {
-    QMap<int, QString>::iterator i = m_layoutNames.begin();
-    while (i != m_layoutNames.constEnd())
+    qDebug("-=[setLayoutByName]=-");
+    int result = WINDOWMANAGER_NO_ERROR;
+
+    QList<Layout>::const_iterator i = m_layouts.begin();
+
+    while (i != m_layouts.constEnd())
     {
-        if (i.value() == layoutName)
+        if (i->name == layoutName)
         {
-            m_currentLayout = i.key();
+            m_currentLayout = i->id;
+
+            mp_layoutAreaToSurfaceIdAssignment->clear();
+
+            dumpScene();
         }
+
         ++i;
     }
 
-    dumpScene();
+    return result;
 }
 
-void WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
+int WindowManager::setSurfaceToLayoutArea(int surfaceId, int layoutAreaId)
 {
+    qDebug("-=[setSurfaceToLayoutArea]=-");
+    int result = WINDOWMANAGER_NO_ERROR;
+
+    qDebug("surfaceId %d", surfaceId);
+    qDebug("layoutAreaId %d", layoutAreaId);
+    mp_layoutAreaToSurfaceIdAssignment->insert(layoutAreaId, surfaceId);
+
+    updateScreen();
+
     dumpScene();
+
+    return result;
 }