-Make the SampleNav app yellow.
[staging/HomeScreen.git] / HomeScreen / src / layouthandler.cpp
1 #include "layouthandler.h"
2 #include <QTimerEvent>
3
4 LayoutHandler::LayoutHandler(QObject *parent) :
5     QObject(parent),
6     m_secondsTimerId(-1),
7     mp_dBusWindowManagerProxy(0),
8     mp_dBusPopupProxy(0),
9     m_visibleSurfaces(),
10     m_invisibleSurfaces(),
11     m_requestsToBeVisibleSurfaces()
12 {
13     qDBusRegisterMetaType<SimplePoint>();
14     qDBusRegisterMetaType<QList<SimplePoint> >();
15     qDBusRegisterMetaType<LayoutArea>();
16     qDBusRegisterMetaType<QList<LayoutArea> >();
17     qDBusRegisterMetaType<Layout>();
18     qDBusRegisterMetaType<QList<Layout> >();
19
20     qDebug("D-Bus: connect to org.agl.windowmanager /windowmanager");
21     mp_dBusWindowManagerProxy = new org::agl::windowmanager("org.agl.windowmanager",
22                                               "/windowmanager",
23                                               QDBusConnection::sessionBus(),
24                                               0);
25     qDebug("D-Bus: connect to org.agl.homescreen /Popup");
26     mp_dBusPopupProxy = new org::agl::popup("org.agl.homescreen",
27                                               "/Popup",
28                                               QDBusConnection::sessionBus(),
29                                               0);
30 }
31
32 LayoutHandler::~LayoutHandler()
33 {
34     delete mp_dBusPopupProxy;
35     delete mp_dBusWindowManagerProxy;
36 }
37
38 void LayoutHandler::setUpLayouts()
39 {
40     qDebug("setUpLayouts");
41     QList<LayoutArea> surfaceAreas;
42     LayoutArea surfaceArea;
43
44     const int SCREEN_WIDTH = 1080;
45     const int SCREEN_HEIGHT = 1920;
46
47     const int STATUSBAR_HEIGHT = 60;
48     const int STATUSBAR_WIDTH = SCREEN_WIDTH;
49     const int STATUSBAR_X = 0;
50     const int STATUSBAR_Y = 0;
51     const int CONTROLBAR_HEIGHT = 60;
52     const int CONTROLBAR_WIDTH = SCREEN_WIDTH;
53     const int CONTROLBAR_X = 0;
54     const int CONTROLBAR_Y = SCREEN_HEIGHT - CONTROLBAR_HEIGHT;
55
56
57     // layout 1:
58     // one app surface, statusbar, control bar
59     surfaceArea.x = 0;
60     surfaceArea.y = STATUSBAR_HEIGHT;
61     surfaceArea.width = SCREEN_WIDTH;
62     surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
63
64     surfaceAreas.append(surfaceArea);
65
66     mp_dBusWindowManagerProxy->addLayout(1, "one app", surfaceAreas);
67
68
69     surfaceAreas.clear();
70
71     // layout 2:
72     // two app surfaces (one on top of the other), statusbar, control bar
73
74     // top surface
75     surfaceArea.x = 0;
76     surfaceArea.y = STATUSBAR_HEIGHT;
77     surfaceArea.width = SCREEN_WIDTH;
78     surfaceArea.height = (SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT) / 2;
79
80     surfaceAreas.append(surfaceArea);
81
82     // bottom surface
83     surfaceArea.x = 0;
84     surfaceArea.y = SCREEN_HEIGHT / 2;
85     surfaceArea.width = SCREEN_WIDTH;
86     surfaceArea.height = (SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT) / 2;
87
88     surfaceAreas.append(surfaceArea);
89
90     mp_dBusWindowManagerProxy->addLayout(2, "top on bottom", surfaceAreas);
91
92
93     surfaceAreas.clear();
94
95     // layout 3:
96     // two app surfaces (one besides the other), statusbar, control bar
97
98     // left surface
99     surfaceArea.x = 0;
100     surfaceArea.y = STATUSBAR_HEIGHT;
101     surfaceArea.width = SCREEN_WIDTH / 2;
102     surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
103
104     surfaceAreas.append(surfaceArea);
105
106     // right surface
107     surfaceArea.x = SCREEN_WIDTH / 2;
108     surfaceArea.y = STATUSBAR_HEIGHT;
109     surfaceArea.width = SCREEN_WIDTH / 2;
110     surfaceArea.height = SCREEN_HEIGHT - STATUSBAR_HEIGHT - CONTROLBAR_HEIGHT;
111
112     surfaceAreas.append(surfaceArea);
113
114     mp_dBusWindowManagerProxy->addLayout(3, "side by side", surfaceAreas);
115 }
116
117 void LayoutHandler::showAppLayer()
118 {
119     mp_dBusWindowManagerProxy->showLayer(1); //1==app layer
120 }
121
122 void LayoutHandler::hideAppLayer()
123 {
124     mp_dBusWindowManagerProxy->hideLayer(1); //1==app layer
125 }
126
127 void LayoutHandler::makeMeVisible(int pid)
128 {
129     qDebug("makeMeVisible %d", pid);
130
131     m_requestsToBeVisiblePids.append(pid);
132
133     // callback every second
134     if (-1 != m_secondsTimerId)
135     {
136         killTimer(m_secondsTimerId);
137         m_secondsTimerId = -1;
138     }
139     m_secondsTimerId = startTimer(1000);
140 }
141
142 void LayoutHandler::checkToDoQueue()
143 {
144     if ((-1 != m_secondsTimerId) && (0 == m_requestsToBeVisiblePids.size()))
145     {
146         killTimer(m_secondsTimerId);
147         m_secondsTimerId = -1;
148     }
149
150     if (0 != m_requestsToBeVisiblePids.size())
151     {
152         int pid = m_requestsToBeVisiblePids.at(0);
153         qDebug("pid %d wants to be visible", pid);
154
155         QList<int> allSurfaces;
156         allSurfaces = mp_dBusWindowManagerProxy->getAllSurfacesOfProcess(pid);
157         if (0 == allSurfaces.size())
158         {
159             qDebug("no surfaces for pid %d. retrying!", pid);
160         }
161         else
162         {
163             m_requestsToBeVisiblePids.removeAt(0);
164             qSort(allSurfaces);
165
166             if (0 != allSurfaces.size())
167             {
168                 m_requestsToBeVisibleSurfaces.append(allSurfaces.at(0));
169
170                 qDebug("m_visibleSurfaces %d", m_visibleSurfaces.size());
171                 qDebug("m_invisibleSurfaces %d", m_invisibleSurfaces.size());
172                 qDebug("m_requestsToBeVisibleSurfaces %d", m_requestsToBeVisibleSurfaces.size());
173
174                 QList<int> availableLayouts = mp_dBusWindowManagerProxy->getAvailableLayouts(m_visibleSurfaces.size() + m_requestsToBeVisibleSurfaces.size());
175                 if (0 == availableLayouts.size())
176                 {
177                     // no layout fits the need!
178                     // replace the last app
179                     qDebug("no layout fits the need!");
180                     qDebug("replace the last surface");
181
182                     m_invisibleSurfaces.append(m_visibleSurfaces.last());
183                     m_visibleSurfaces.removeLast();
184
185                     m_visibleSurfaces.append(m_requestsToBeVisibleSurfaces);
186                     m_requestsToBeVisibleSurfaces.clear();
187
188                     for (int i = 0; i < m_visibleSurfaces.size(); ++i)
189                     {
190                         mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(m_visibleSurfaces.at(i), i);
191                     }
192                 }
193                 if (1 == availableLayouts.size())
194                 {
195                     // switch to new layout
196                     qDebug("switch to new layout %d", availableLayouts.at(0));
197                     m_visibleSurfaces.append(m_requestsToBeVisibleSurfaces);
198                     m_requestsToBeVisibleSurfaces.clear();
199
200                     mp_dBusWindowManagerProxy->setLayoutById(availableLayouts.at(0));
201                     for (int i = 0; i < m_visibleSurfaces.size(); ++i)
202                     {
203                         mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(m_visibleSurfaces.at(i), i);
204                     }
205                 }
206                 if (1 < availableLayouts.size())
207                 {
208                     // more than one layout possible! Ask user.
209                     qDebug("more than one layout possible! Ask user.");
210
211                     QStringList choices;
212                     for (int i = 0; i < availableLayouts.size(); ++i)
213                     {
214                         choices.append(mp_dBusWindowManagerProxy->getLayoutName(availableLayouts.at(i)));
215                     }
216
217                     mp_dBusPopupProxy->showPopupComboBox("Select Layout", choices);
218                 }
219             }
220         }
221     }
222 }
223
224 QList<int> LayoutHandler::requestGetAllSurfacesOfProcess(int pid)
225 {
226     qDebug("requestGetAllSurfacesOfProcess %d", pid);
227
228     return mp_dBusWindowManagerProxy->getAllSurfacesOfProcess(pid);
229 }
230
231 int LayoutHandler::requestGetSurfaceStatus(int surfaceId)
232 {
233     int result = -1;
234
235     if (-1 != m_visibleSurfaces.indexOf(surfaceId))
236     {
237         result = 0;
238     }
239     if (-1 != m_invisibleSurfaces.indexOf(surfaceId))
240     {
241         result = 1;
242     }
243     if (-1 != m_requestsToBeVisibleSurfaces.indexOf(surfaceId))
244     {
245         result = 1;
246     }
247
248     return result;
249 }
250
251 void LayoutHandler::requestRenderSurfaceToArea(int surfaceId, const QRect &renderArea)
252 {
253     qDebug("requestRenderSurfaceToArea %d %d,%d,%d,%d", surfaceId, renderArea.x(), renderArea.y(), renderArea.width(), renderArea.height());
254 }
255
256 void LayoutHandler::requestSurfaceIdToFullScreen(int surfaceId)
257 {
258     qDebug("requestSurfaceIdToFullScreen %d", surfaceId);
259 }
260
261 void LayoutHandler::setLayoutByName(QString layoutName)
262 {
263     // switch to new layout
264     qDebug("setLayout: switch to new layout %s", layoutName.toStdString().c_str());
265     m_visibleSurfaces.append(m_requestsToBeVisibleSurfaces);
266     m_requestsToBeVisibleSurfaces.clear();
267
268     mp_dBusWindowManagerProxy->setLayoutByName(layoutName);
269     for (int i = 0; i < m_visibleSurfaces.size(); ++i)
270     {
271         mp_dBusWindowManagerProxy->setSurfaceToLayoutArea(i, i);
272     }
273 }
274
275 void LayoutHandler::timerEvent(QTimerEvent *e)
276 {
277     if (e->timerId() == m_secondsTimerId)
278     {
279         checkToDoQueue();
280     }
281 }
282