LayerManagerControl: fixed handling error in ILM calls
[profile/ivi/layer-management.git] / LayerManagerControl / src / common.cpp
1 /***************************************************************************
2  *
3  * Copyright 2012 BMW Car IT GmbH
4  *
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  ****************************************************************************/
19
20 #include "ilm_client.h"
21 #include "LMControl.h"
22
23 #include <algorithm>
24 using std::find;
25
26 #include <cmath>
27 using std::max;
28 using std::min;
29
30 #include <iterator>
31 using std::iterator;
32
33 #include <iostream>
34 using std::cout;
35 using std::cin;
36 using std::endl;
37
38 #include <vector>
39 using std::vector;
40
41 #include <pthread.h>
42 #include <signal.h>
43 #include <sys/types.h>
44 #include <unistd.h>
45
46
47 tuple4 getSurfaceScreenCoordinates(ilmSurfaceProperties targetSurfaceProperties, ilmLayerProperties targetLayerProperties)
48 {
49     t_ilm_float horizontalScale = targetLayerProperties.sourceWidth ?
50                     1.0 * targetLayerProperties.destWidth / targetLayerProperties.sourceWidth : 0;
51
52     t_ilm_float targetX1 = targetLayerProperties.destX + horizontalScale
53             * (targetSurfaceProperties.destX- targetLayerProperties.sourceX);
54     t_ilm_float targetX2 = targetX1 + horizontalScale * targetSurfaceProperties.destWidth;
55
56     t_ilm_float verticalScale = targetLayerProperties.sourceHeight ?
57             1.0 * targetLayerProperties.destHeight/ targetLayerProperties.sourceHeight : 0;
58
59     t_ilm_float targetY1 = targetLayerProperties.destY + verticalScale
60             * (targetSurfaceProperties.destY - targetLayerProperties.sourceY);
61     t_ilm_float targetY2 = targetY1 + verticalScale * targetSurfaceProperties.destHeight;
62
63     tuple4 targetSurfaceCoordinates(static_cast<t_ilm_int>(targetX1),
64             static_cast<t_ilm_int>(targetY1),
65             max(0, static_cast<t_ilm_int>(targetX2) - 1),
66             max(0, static_cast<t_ilm_int>(targetY2) - 1));
67
68     return targetSurfaceCoordinates;
69 }
70
71 tuple4 getSurfaceScreenCoordinates(t_scene_data* pScene, t_ilm_surface surface)
72 {
73     tuple4 surfaceCoordinates;
74
75     //if surface belongs to a layer make it appear exacrly as it would appear on its current layer
76     if (pScene->surfaceLayer.find(surface) != pScene->surfaceLayer.end())
77     {
78         //set dimensions of the surface to map to the extra layer according to its current placement in the
79         t_ilm_layer layer = pScene->surfaceLayer[surface];
80         ilmLayerProperties layerProperties = pScene->layerProperties[layer];
81         ilmSurfaceProperties surfaceProperties = pScene->surfaceProperties[surface];
82
83         surfaceCoordinates = getSurfaceScreenCoordinates(surfaceProperties, layerProperties);
84     }
85     //if surface does not belong to a layer just assume it belongs to a layer that fills the screen
86     else
87     {
88         ilmSurfaceProperties surfaceProperties = pScene->surfaceProperties[surface];
89
90         surfaceCoordinates.x = surfaceProperties.destX;
91         surfaceCoordinates.y = surfaceProperties.destY;
92         surfaceCoordinates.z = surfaceProperties.destX + surfaceProperties.destWidth;
93         surfaceCoordinates.w = surfaceProperties.destX + surfaceProperties.destHeight;
94     }
95
96     return surfaceCoordinates;
97 }
98
99 t_ilm_bool surfaceRenderedOnScreen(t_scene_data& scene, t_ilm_surface surface)
100 {
101     //if scene belongs to a layer and that layer belongs to a screen
102     if (scene.surfaceLayer.find(surface) != scene.surfaceLayer.end())
103     {
104         t_ilm_layer layer = scene.surfaceLayer[surface];
105         if (scene.layerScreen.find(layer) != scene.layerScreen.end())
106         {
107             return ILM_TRUE;
108         }
109     }
110
111     return ILM_FALSE;
112 }
113
114 vector<t_ilm_surface> getSceneRenderOrder(t_scene_data* pScene)
115 {
116     t_scene_data& scene = *pScene;
117     vector<t_ilm_surface> renderOrder;
118
119     //iterate over screens
120     for (vector<t_ilm_display>::iterator it = scene.screens.begin(); it != scene.screens.end(); ++it)
121     {
122         t_ilm_display screen = *it;
123         vector<t_ilm_layer> layers = scene.screenLayers[screen];
124
125         //iterate over layers
126         for (vector<t_ilm_layer>::iterator layerIterator = layers.begin();
127                 layerIterator != layers.end(); ++layerIterator)
128         {
129             t_ilm_layer layer = (*layerIterator);
130             vector<t_ilm_surface> surfaces = scene.layerSurfaces[layer];
131
132             //iterate over surfaces
133             for (vector<t_ilm_surface>::iterator it = surfaces.begin(); it != surfaces.end(); ++it)
134             {
135                 t_ilm_surface surface = *it;
136
137                 renderOrder.push_back(surface);
138             }
139         }
140     }
141
142     return renderOrder;
143 }
144
145 void captureSceneData(t_scene_data* pScene)
146 {
147     t_scene_data& scene = *pScene;
148
149     //get screen information
150     t_ilm_uint screenWidth = 0, screenHeight = 0;
151
152     ilmErrorTypes callResult = ilm_getScreenResolution(0, &screenWidth, &screenHeight);
153     if (ILM_SUCCESS != callResult)
154     {
155         cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
156         cout << "Failed to get screen resolution for screen with ID " << 0 << "\n";
157         return;
158     }
159
160     scene.screenWidth = screenWidth;
161     scene.screenHeight = screenHeight;
162
163     //extra layer for debugging
164     scene.extraLayer = 0xFFFFFFFF;
165
166     //get screens
167     unsigned int screenCount = 0;
168     t_ilm_display* screenArray = NULL;
169
170     callResult = ilm_getScreenIDs(&screenCount, &screenArray);
171     if (ILM_SUCCESS != callResult)
172     {
173         cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
174         cout << "Failed to get available screen IDs\n";
175         return;
176     }
177
178     scene.screens = vector<t_ilm_display>(screenArray, screenArray + screenCount);
179
180     //layers on each screen
181     for (unsigned int i = 0; i < screenCount; ++i)
182     {
183         t_ilm_display screenId = screenArray[i];
184
185         t_ilm_int layerCount = 0;
186         t_ilm_layer* layerArray = NULL;
187
188         callResult = ilm_getLayerIDsOnScreen(screenId, &layerCount, &layerArray);
189         if (ILM_SUCCESS != callResult)
190         {
191             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
192             cout << "Failed to get layers on screen with ID "<< screenId <<"\n";
193             return;
194         }
195
196         scene.screenLayers[screenId] = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
197
198         //preserve rendering order for layers on each screen
199         for (int j = 0; j < layerCount; ++j)
200         {
201             t_ilm_layer layerId = layerArray[j];
202
203             scene.layerScreen[layerId] = screenId;
204         }
205     }
206
207     //get all layers (rendered and not rendered)
208     t_ilm_int layerCount = 0;
209     t_ilm_layer* layerArray = NULL;
210     ilm_getLayerIDs(&layerCount, &layerArray);
211     scene.layers = vector<t_ilm_layer>(layerArray, layerArray + layerCount);
212
213     for (int j = 0; j < layerCount; ++j)
214     {
215         t_ilm_layer layerId = layerArray[j];
216
217         //layer properties
218         ilmLayerProperties lp;
219
220         callResult = ilm_getPropertiesOfLayer(layerId, &lp);
221         if (ILM_SUCCESS != callResult)
222         {
223             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
224             cout << "Failed to get properties of layer with ID "<< layerId <<"\n";
225             return;
226         }
227
228         scene.layerProperties[layerId] = lp;
229     }
230
231     //surfaces on each layer
232     for (int j = 0; j < layerCount; ++j)
233     {
234         t_ilm_layer layerId = layerArray[j];
235
236         //surfaces on layer (in rendering order)
237         int surfaceCount = 0;
238         t_ilm_surface* surfaceArray = NULL;
239
240         callResult = ilm_getSurfaceIDsOnLayer(layerId, &surfaceCount, &surfaceArray);
241         if (ILM_SUCCESS != callResult)
242         {
243             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
244             cout << "Failed to get surfaces on layer with ID "<< layerId <<"\n";
245             return;
246         }
247
248         //rendering order on layer
249         scene.layerSurfaces[layerId] = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
250
251         //make each surface aware of its layer
252         for (int k = 0; k < surfaceCount; ++k)
253         {
254             t_ilm_surface surfaceId = surfaceArray[k];
255             scene.surfaceLayer[surfaceId] = layerId;
256         }
257     }
258
259     //get all surfaces (on layers and without layers)
260     t_ilm_int surfaceCount = 0;
261     t_ilm_surface* surfaceArray = NULL;
262
263     callResult = ilm_getSurfaceIDs(&surfaceCount, &surfaceArray);
264     if (ILM_SUCCESS != callResult)
265     {
266         cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
267         cout << "Failed to get available surfaces\n";
268         return;
269     }
270
271     scene.surfaces = vector<t_ilm_surface>(surfaceArray, surfaceArray + surfaceCount);
272
273     for (int k = 0; k < surfaceCount; ++k)
274     {
275         t_ilm_surface surfaceId = surfaceArray[k];
276
277         //surface properties
278         ilmSurfaceProperties sp;
279
280         callResult = ilm_getPropertiesOfSurface(surfaceId, &sp);
281         if (ILM_SUCCESS != callResult)
282         {
283             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
284             cout << "Failed to get properties of surface with ID " << surfaceId << "\n";
285             return;
286         }
287
288         scene.surfaceProperties[surfaceId] = sp;
289     }
290 }
291
292 void setScene(t_scene_data* pScene, bool clean)
293 {
294     t_scene_data initialScene;
295     captureSceneData(&initialScene);
296
297     //dismantel current scene
298     for (map<t_ilm_surface, t_ilm_layer>::iterator it = initialScene.surfaceLayer.begin();
299             it != initialScene.surfaceLayer.end(); ++it)
300     {
301         t_ilm_surface surface = it->first;
302         t_ilm_layer layer = it->second;
303
304         ilmErrorTypes callResult = ilm_layerRemoveSurface(layer, surface);
305         if (ILM_SUCCESS != callResult)
306         {
307             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
308             cout << "Failed to remove surface " << surface << " from layer " << layer << "\n";
309             return;
310         }
311     }
312
313     ilm_commitChanges();
314
315     //cleaning scene if needed
316     if (clean)
317     {
318         //remove unneeded surfaces and layers!
319         for (vector<t_ilm_surface>::iterator it = initialScene.surfaces.begin();
320                 it != initialScene.surfaces.end(); ++it)
321         {
322             t_ilm_surface surface = *it;
323             //if surface does not exist (in final scene)
324             if (find(pScene->surfaces.begin(), pScene->surfaces.end(), surface) == pScene->surfaces.end())
325             {
326                 //remove surface !
327                 ilmErrorTypes callResult = ilm_surfaceRemove(surface);
328                 if (ILM_SUCCESS != callResult)
329                 {
330                     cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
331                     cout << "Failed to remove surface " << surface << "\n";
332                     return;
333                 }
334             }
335         }
336
337         ilm_commitChanges();
338
339         for (vector<t_ilm_layer>::iterator it = initialScene.layers.begin();
340                 it != initialScene.layers.end(); ++it)
341         {
342             t_ilm_layer layer = *it;
343             //if layer does not exist (in final scene)
344             if (find(pScene->layers.begin(), pScene->layers.end(), layer) == pScene->layers.end())
345             {
346                 //remove surface !
347                 ilmErrorTypes callResult = ilm_layerRemove(layer);
348                 if (ILM_SUCCESS != callResult)
349                 {
350                     cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
351                     cout << "Failed to remove layer " << layer << "\n";
352                     return;
353                 }
354             }
355         }
356
357         ilm_commitChanges();
358     }
359
360     //make sure all layers and surfaces of the new scene are created
361     for (vector<t_ilm_layer>::iterator it = pScene->layers.begin();
362             it != pScene->layers.end(); ++it)
363     {
364         t_ilm_layer layer = *it;
365         //if layer does not exist (in initial scene)
366         if (find(initialScene.layers.begin(), initialScene.layers.end(), layer) == initialScene.layers.end())
367         {
368             ilmLayerProperties& props = pScene->layerProperties[layer];
369
370             ilmErrorTypes callResult = ilm_layerCreateWithDimension(&layer, props.origSourceWidth, props.origSourceHeight);
371             if (ILM_SUCCESS != callResult)
372             {
373                 cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
374                 cout << "Failed to create layer with ID " << layer << " and dimensions (" << props.origSourceWidth << " ," << props.origSourceHeight << ")\n";
375                 return;
376             }
377         }
378     }
379
380     ilm_commitChanges();
381
382     for (vector<t_ilm_surface>::iterator it = pScene->surfaces.begin();
383             it != pScene->surfaces.end(); ++it)
384     {
385         t_ilm_surface surface = *it;
386         //if surface does not exist (in initial scene)
387         if (find(initialScene.surfaces.begin(), initialScene.surfaces.end(), surface)
388                 == initialScene.surfaces.end())
389         {
390             ilmSurfaceProperties& props = pScene->surfaceProperties[surface];
391
392             ilm_surfaceCreate(props.nativeSurface,
393                     props.origSourceWidth,
394                     props.origSourceHeight,
395                     (e_ilmPixelFormat) props.pixelformat,
396                     &surface);
397         }
398
399         //if surface exists but mapped to different native: remove then recreate it
400         if (initialScene.surfaceProperties[surface].nativeSurface
401                 != pScene->surfaceProperties[surface].nativeSurface)
402         {
403             ilm_surfaceRemove(surface);
404             ilmSurfaceProperties& props = pScene->surfaceProperties[surface];
405             ilm_surfaceCreate(props.nativeSurface,
406                     props.origSourceWidth,
407                     props.origSourceHeight,
408                     (e_ilmPixelFormat) props.pixelformat,
409                     &surface);
410         }
411     }
412
413     ilm_commitChanges();
414
415     //set render order of layers on each screen
416     for (vector<t_ilm_display>::iterator it = pScene->screens.begin();
417             it != pScene->screens.end(); ++it)
418     {
419         t_ilm_display screen = *it;
420         vector<t_ilm_layer>& layers = pScene->screenLayers[screen];
421
422         //if vector data is NULL (no data in vector)
423         if (layers.data() == NULL)
424         {
425             layers.reserve(1);
426         }
427
428         ilm_displaySetRenderOrder(screen, layers.data(), layers.size());
429     }
430
431     ilm_commitChanges();
432
433     //set render order of surfaces on each layer
434     for (map<t_ilm_layer, vector<t_ilm_surface> >::iterator it = pScene->layerSurfaces.begin();
435             it != pScene->layerSurfaces.end(); ++it)
436     {
437         t_ilm_layer layer = it->first;
438         vector<t_ilm_surface>& surfaces = it->second;
439         if(surfaces.data() == NULL)
440         {
441             surfaces.reserve(1);
442         }
443
444         ilm_layerSetRenderOrder(layer, surfaces.data(), surfaces.size());
445     }
446
447     ilm_commitChanges();
448
449     //set properties of layers
450     for (map<t_ilm_layer, ilmLayerProperties>::iterator it = pScene->layerProperties.begin();
451             it != pScene->layerProperties.end(); ++it)
452     {
453         t_ilm_layer layer = it->first;
454         ilmLayerProperties& props = it->second;
455
456         //set layer properties
457         ilm_layerSetDestinationRectangle(layer, props.destX, props.destY, props.destWidth, props.destHeight);
458         ilm_commitChanges();
459
460         ilm_layerSetOpacity(layer, props.opacity);
461         ilm_commitChanges();
462
463         ilm_layerSetOrientation(layer, props.orientation);
464         ilm_commitChanges();
465
466         ilm_layerSetSourceRectangle(layer, props.sourceX, props.sourceY, props.sourceWidth, props.sourceHeight);
467         ilm_commitChanges();
468
469         ilm_layerSetVisibility(layer, props.visibility);
470         ilm_commitChanges();
471     }
472
473     //set properties of surfaces
474     for (map<t_ilm_surface, ilmSurfaceProperties>::iterator it = pScene->surfaceProperties.begin();
475             it != pScene->surfaceProperties.end(); ++it)
476     {
477         t_ilm_surface surface = it->first;
478         ilmSurfaceProperties& props = it->second;
479
480         ilm_surfaceSetNativeContent(props.nativeSurface,
481                 props.origSourceWidth,
482                 props.origSourceHeight,
483                 (e_ilmPixelFormat) props.pixelformat,
484                 surface);
485         ilm_commitChanges();
486
487         ilm_surfaceSetOpacity(surface, props.opacity);
488         ilm_commitChanges();
489
490         ilm_surfaceSetOrientation(surface, props.orientation);
491         ilm_commitChanges();
492
493         ilm_surfaceSetSourceRectangle(surface, props.sourceX, props.sourceY, props.sourceWidth, props.sourceHeight);
494         ilm_commitChanges();
495
496         ilm_surfaceSetDestinationRectangle(surface, props.destX, props.destY, props.destWidth, props.destHeight);
497         ilm_commitChanges();
498
499         ilm_surfaceSetVisibility(surface, props.visibility);
500         ilm_commitChanges();
501     }
502
503     ilm_commitChanges();
504 }
505
506 void emptyScene(t_scene_data* pScene)
507 {
508     pScene->extraLayer = -1;
509     pScene->layerProperties.clear();
510     pScene->layerScreen.clear();
511     pScene->layerSurfaces.clear();
512     pScene->layers.clear();
513     pScene->screenLayers.clear();
514     pScene->screens.clear();
515     pScene->surfaceLayer.clear();
516     pScene->surfaceProperties.clear();
517     pScene->surfaces.clear();
518
519     t_ilm_uint count;
520     t_ilm_display* screenArray;
521     ilm_getScreenIDs(&count, &screenArray);
522     for(t_ilm_uint i = 0 ; i < count ; ++i)
523     {
524         pScene->screens.push_back(screenArray[i]);
525
526         ilmErrorTypes callResult = ilm_getScreenResolution(screenArray[0], & pScene->screenWidth, & pScene->screenHeight);
527         if (ILM_SUCCESS != callResult)
528         {
529             cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
530             cout << "Failed to get screen resolution for screen with ID " << screenArray[0] << "\n";
531             return;
532         }
533     }
534 }
535
536 t_scene_data cloneToUniLayerScene(t_scene_data* pScene)
537 {
538     //prepare values needed for dummy (animation) scene
539     t_ilm_layer extraLayer = -1;
540     //if the scene is already uni layer just reuse same layer
541     if(pScene->layers.size() == 1)
542     {
543         extraLayer = pScene->layers[0];
544     }
545
546     ilmErrorTypes callResult = ilm_layerCreate(&extraLayer);
547     if (ILM_SUCCESS != callResult)
548     {
549         cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
550         cout << "Failed to create layer\n";
551     }
552
553     ilmLayerProperties extraLayerProperties;
554     extraLayerProperties.destHeight = pScene->screenHeight;
555     extraLayerProperties.destWidth = pScene->screenWidth;
556     extraLayerProperties.destX = 0;
557     extraLayerProperties.destY = 0;
558     extraLayerProperties.opacity = 1;
559     extraLayerProperties.orientation = (e_ilmOrientation) 0;
560     extraLayerProperties.origSourceHeight = pScene->screenHeight;
561     extraLayerProperties.origSourceWidth = pScene->screenWidth;
562     extraLayerProperties.sourceHeight = pScene->screenHeight;
563     extraLayerProperties.sourceWidth = pScene->screenWidth;
564     extraLayerProperties.sourceX = 0;
565     extraLayerProperties.sourceY = 0;
566     extraLayerProperties.type = 2;
567     extraLayerProperties.visibility = 1;
568
569     t_ilm_display screen = pScene->screens[0];
570
571     vector<t_ilm_surface> finalRenderOrder = getSceneRenderOrder(pScene);
572
573     //build dummy scene to be used for animation
574     t_scene_data dummyScene;
575     //to avoid destroying and recreating surfaces and layers
576     dummyScene.surfaces = pScene->surfaces;
577
578     //the real deal !
579     dummyScene.screens.push_back(screen);
580     dummyScene.screenLayers[screen] = vector<t_ilm_layer>(&extraLayer, &extraLayer + 1);
581     dummyScene.layerScreen[extraLayer] = screen;
582     dummyScene.layerSurfaces[extraLayer] = finalRenderOrder;
583
584     for (vector<t_ilm_surface>::iterator it = finalRenderOrder.begin();
585             it != finalRenderOrder.end(); ++it)
586     {
587         dummyScene.surfaceProperties[*it] = pScene->surfaceProperties[*it];
588
589         tuple4 coords = getSurfaceScreenCoordinates(pScene, *it);
590
591         dummyScene.surfaceProperties[*it].destX = coords.x;
592         dummyScene.surfaceProperties[*it].destY = coords.y;
593         dummyScene.surfaceProperties[*it].destWidth = coords.z - coords.x;
594         dummyScene.surfaceProperties[*it].destHeight = coords.w - coords.y;
595     }
596
597     dummyScene.layerProperties[extraLayer] = extraLayerProperties;
598
599     dummyScene.layerScreen[extraLayer] = screen;
600
601     for (vector<t_ilm_surface>::iterator it = finalRenderOrder.begin();
602             it != finalRenderOrder.end(); ++it)
603     {
604         dummyScene.surfaceLayer[*it] = extraLayer;
605     }
606
607     dummyScene.surfaces = finalRenderOrder;
608     dummyScene.layers = vector<t_ilm_layer>(&extraLayer, &extraLayer + 1);
609
610     dummyScene.extraLayer = -1;
611     dummyScene.screenWidth = pScene->screenWidth;
612     dummyScene.screenHeight = pScene->screenHeight;
613
614     return dummyScene;
615 }
616
617 tuple4 interpolateCoordinatesHelper(tuple4& start, tuple4& end, float t)
618 {
619     t = static_cast<float>(1 - pow((t - 1), 4));
620     return tuple4(static_cast<int>(start.x * (1 - t) + end.x * t),
621             static_cast<int>(start.y * (1 - t) + end.y * t),
622             static_cast<int>(start.z * (1 - t) + end.z * t),
623             static_cast<int>(start.w * (1 - t) + end.w * t));
624 }
625
626 void transformScene(t_scene_data* pInitialScene, t_scene_data* pFinalScene, t_ilm_long durationMillis, t_ilm_int frameCount)
627 {
628     t_scene_data dummyScene = cloneToUniLayerScene(pFinalScene);
629     //set dummy scene
630     setScene(&dummyScene);
631
632     //animate dummy scene !
633
634     if (durationMillis > 0 && frameCount > 0)
635     {
636         //sleep time
637         long sleepMillis = durationMillis / frameCount;
638         struct timespec sleepTime;
639         sleepTime.tv_nsec = (sleepMillis% 1000) * 1000000;
640         sleepTime.tv_sec = sleepMillis / 1000;
641
642         struct timespec remTime;
643
644         //start and end coordinates of surfaces
645         map<t_ilm_surface, tuple4> start;
646         map<t_ilm_surface, tuple4> end;
647         for(vector<t_ilm_surface>::iterator it = dummyScene.surfaces.begin();
648                 it != dummyScene.surfaces.end(); ++it)
649         {
650             t_ilm_surface surface = *it;
651             start[surface] = getSurfaceScreenCoordinates(pInitialScene, surface);
652
653             end[surface] = getSurfaceScreenCoordinates(pFinalScene, surface);
654         }
655
656         for (int i = 0; i < frameCount; ++i)
657         {
658             float t = 1.0 * i / frameCount;
659
660             //interpolate properties of each surface
661             for(vector<t_ilm_surface>::iterator it = dummyScene.surfaces.begin();
662                     it != dummyScene.surfaces.end(); ++it)
663             {
664                 t_ilm_surface surface = *it;
665                 tuple4 coords = interpolateCoordinatesHelper(start[surface], end[surface], t);
666
667                 ilmErrorTypes callResult = ilm_surfaceSetDestinationRectangle(surface, coords.x, coords.y, coords.z - coords.x, coords.w - coords.y);
668                 if (ILM_SUCCESS != callResult)
669                 {
670                     cout << "LayerManagerService returned: " << ILM_ERROR_STRING(callResult) << "\n";
671                     cout << "Failed to set destination rectangle (" << coords.x << "," << coords.y << ", "<< coords.z - coords.x << ", " << coords.w - coords.y
672                             <<") for surface with ID " << surface << "\n";
673                     return;
674                 }
675
676                 float opacity = t * pFinalScene->surfaceProperties[surface].opacity
677                         + (1-t) * pInitialScene->surfaceProperties[surface].opacity;
678                 ilm_surfaceSetOpacity(surface, opacity);
679             }
680
681             ilm_commitChanges();
682
683             //sleep
684             nanosleep(&sleepTime, &remTime);
685         }
686     }
687
688     //set final scene
689     setScene(pFinalScene);
690 }
691
692 static t_scene_data* global_pOriginalScene = NULL;
693
694 void interruptSignalRestoreScene(int s)
695 {
696     (void) s;
697
698     cout<<"LayerManagerControl :Interrupt signal...\n";
699     if (global_pOriginalScene != NULL)
700     {
701         setScene(global_pOriginalScene, true);
702         sleep(3);
703         exit(0);
704     }
705 }
706
707 void setSceneToRestore(t_scene_data* pScene)
708 {
709     if (global_pOriginalScene == NULL)
710     {
711         global_pOriginalScene = pScene;
712         struct sigaction signalAction;
713
714         signalAction.sa_handler = &interruptSignalRestoreScene;
715         sigemptyset(&signalAction.sa_mask);
716         signalAction.sa_flags = 0;
717
718         sigaction(SIGINT, &signalAction, NULL);
719     }
720 }