WindowSystems: Added support for DirectFB
authorMarek Pikarski <mass@directfb.org>
Tue, 1 Oct 2013 07:38:23 +0000 (09:38 +0200)
committerTimo Lotterbach <timo.lotterbach@bmw-carit.de>
Tue, 1 Oct 2013 14:19:00 +0000 (16:19 +0200)
Added DirectFB window system which manages all windows/surfaces as used by LM running on DirectFB.

Signed-off-by: Marek Pikarski <mass@directfb.org>
LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/DFBWindowSystem.h [new file with mode: 0644]
LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/DFBWindowSystem.cpp [new file with mode: 0644]

diff --git a/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/DFBWindowSystem.h b/LayerManagerPlugins/Renderers/Graphic/include/WindowSystems/DFBWindowSystem.h
new file mode 100644 (file)
index 0000000..3d28256
--- /dev/null
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *
+ * Copyright (c) 2013 DirectFB integrated media GmbH
+ * Copyright (c) 2013 Renesas Solutions Corp.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#ifndef _DFBWINDOWSYSTEM_H_
+#define _DFBWINDOWSYSTEM_H_
+
+#include "GraphicSystems/DFBGraphicSystem.h"
+#include "GraphicSystems/GLESGraphicSystem.h"
+#include "WindowSystems/BaseWindowSystem.h"
+#include "Surface.h"
+#include "PlatformSurfaces/EglDFBPlatformSurface.h"
+#include "ScreenShotType.h"
+
+extern "C" {
+#include <direct/hash.h>
+}
+
+class DFBWindowSystem: public BaseWindowSystem {
+public:
+     DFBWindowSystem(int width, int height, Scene* pScene, InputManager* pInputManager, IDirectFB *dfb, IDirectFBDisplayLayer *layer);
+     virtual ~DFBWindowSystem();
+     bool init(BaseGraphicSystem<DFBDisplay, DFBWindow>* base, bool dfb_mode_hw);
+     bool start(int maxIterationDurationInMS);
+     void stop();
+     void signalRedrawEvent();
+     virtual void allocatePlatformSurface(Surface *surface);
+     virtual void deallocatePlatformSurface(Surface *surface);
+     void doScreenShot(std::string fileName, const uint screen_id);
+     void doScreenShotOfLayer(std::string fileName, const uint id);
+     void doScreenShotOfSurface(std::string fileName, const uint id, const uint layer_id);
+     DFBDisplay getNativeDisplayHandle();
+     int getIterationCounter();
+private:
+     ScreenShotType takeScreenshot;
+     std::string screenShotFile;
+     uint screenShotSurfaceID;
+     uint screenShotLayerID;
+     uint screenShotScreenID;
+     int resolutionWidth;
+     int resolutionHeight;
+     bool m_running;
+     bool m_initialized;
+     bool m_checkWindows;
+     int m_primary_width;
+     int m_primary_height;
+     int m_mouse_x;
+     int m_mouse_y;
+     int m_mouse_x_min;
+     int m_mouse_y_min;
+     int m_mouse_x_max;
+     int m_mouse_y_max;
+     int m_adjusted_mouse_x;
+     int m_adjusted_mouse_y;
+     int m_iterationCounter;
+     int m_maxIterationDurationInMS;
+     std::list<int> *m_sceneLayers;
+protected:
+     IDirectFB *m_dfb;
+     IDirectFBDisplayLayer *m_layer;
+     DFBDisplay dfbDisplay;
+     IDirectFBSurface *m_primary;
+     DirectHash window_map;
+     DirectHash surface_map;
+     pthread_t renderThread;
+     int windowWidth;
+     int windowHeight;
+     bool m_dfb_mode_hw;
+     bool m_ignore_surface_updates;
+     DFBSurfaceID CompositorSurface;
+     IDirectFBEventBuffer *m_events;
+     pthread_mutex_t run_lock;
+     pthread_mutex_t init_lock;
+     pthread_cond_t init_condition;
+     BaseGraphicSystem<DFBDisplay, DFBWindow>* m_gfx;
+     virtual void RedrawAllLayers(bool clear, bool swap);
+     virtual void renderSWLayers(LayerList layers, bool clear, bool swap);
+     virtual void renderHWLayer(Layer* layer, bool clear);
+private:
+     void cleanup();
+     void Screenshot();
+     void Redraw(bool clear);
+     void createSurfaceForWindow(DFBWindow w);
+     void configureSurfaceWindow(DFBWindow w);
+     Surface* getSurfaceForWindow(DFBWindow w);
+     void checkForNewSurfaceNativeContent();
+     void destroy_surface(DFBWindow w);
+     void updateSurface(Surface* s, DFBWindow w, DFBPlatformSurface* dfbsurf);
+     void MapWindow(DFBWindow w);
+     void UnMapWindow(DFBWindow w);
+     bool NewWindow(Surface* s, DFBWindow w);
+     void DestroyWindow(DFBWindow w);
+     bool isWindowValid(DFBWindow w);
+     void EventLoop();
+     void ManageDFBInputEvent(InputDevice type, InputEventState state, DFBEvent *pevent);
+     bool deleteOrphanWindow(void *win);
+     int selectOutput(DFBGraphicSystem *gfx, int id);
+     friend void *startEventLoop(void *);
+     friend bool checkOrphanWindow(DirectHash *hash, unsigned long key, void *value, void *ctx);
+
+     friend class DFBGraphicSystem;
+};
+
+#endif
+
diff --git a/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/DFBWindowSystem.cpp b/LayerManagerPlugins/Renderers/Graphic/src/WindowSystems/DFBWindowSystem.cpp
new file mode 100644 (file)
index 0000000..661b102
--- /dev/null
@@ -0,0 +1,1116 @@
+/***************************************************************************
+ *
+ * Copyright (c) 2013 DirectFB integrated media GmbH
+ * Copyright (c) 2013 Renesas Solutions Corp.
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ****************************************************************************/
+
+#include "DFBRenderer.h"
+#include "WindowSystems/DFBWindowSystem.h"
+#include "config.h"
+#include "Layer.h"
+#include <time.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <iomanip>
+
+typedef struct sManagedWindow
+{
+     DFBPlatformSurface *platform;
+     DFBWindowID winID;
+     IDirectFBWindow *win;
+     DFBSurfaceID surfID;
+     IDirectFBSurface *surf;
+     int x;
+     int y;
+     int w;
+     int h;
+} sManagedWindow;
+
+DFBWindowSystem::DFBWindowSystem(int width, int height, Scene* pScene, InputManager* pInputManager, IDirectFB *dfb, IDirectFBDisplayLayer *layer)
+: BaseWindowSystem(pScene, pInputManager)
+, takeScreenshot(ScreenShotNone)
+, screenShotFile()
+, screenShotSurfaceID(0)
+, screenShotLayerID()
+, screenShotScreenID(0)
+, resolutionWidth(width)
+, resolutionHeight(height)
+, m_running(false)
+, m_initialized(false)
+, m_checkWindows(false)
+, m_primary_width(width)
+, m_primary_height(height)
+, m_mouse_x(0)
+, m_mouse_y(0)
+, m_mouse_x_min(-1)
+, m_mouse_y_min(-1)
+, m_mouse_x_max(-1)
+, m_mouse_y_max(-1)
+, m_adjusted_mouse_x(0)
+, m_adjusted_mouse_y(0)
+, m_iterationCounter(0)
+, m_maxIterationDurationInMS(0)
+, m_dfb(dfb)
+, m_layer(layer)
+, dfbDisplay(0)
+, m_primary(NULL)
+, renderThread(0)
+, windowWidth(width)
+, windowHeight(height)
+, m_dfb_mode_hw(true)
+, m_ignore_surface_updates(false)
+, CompositorSurface(0)
+, m_events(NULL)
+, m_gfx(NULL)
+{
+     pthread_mutex_init( &run_lock, NULL );
+     pthread_mutex_init( &init_lock, NULL );
+     pthread_cond_init( &init_condition,NULL );
+     direct_hash_init( &window_map, 17 );
+     direct_hash_init( &surface_map, 17 );
+     m_sceneLayers = new std::list<int>;
+}
+
+DFBWindowSystem::~DFBWindowSystem()
+{
+     pthread_mutex_destroy( &run_lock );
+     pthread_mutex_destroy( &init_lock );
+     pthread_cond_destroy( &init_condition );
+     direct_hash_deinit( &window_map );
+     direct_hash_deinit( &surface_map );
+}
+
+bool DFBWindowSystem::isWindowValid(DFBWindow w)
+{
+     sManagedWindow *win = (sManagedWindow *)direct_hash_lookup( &window_map, w );
+     if (!win)
+          return true;
+
+     return (w != 0 && win->surfID != CompositorSurface);
+}
+
+Surface* DFBWindowSystem::getSurfaceForWindow(DFBWindow w)
+{
+     const std::map<unsigned int,Surface*> surfaces = m_pScene->getAllSurfaces();
+     for (std::map<unsigned int, Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); ++currentS) {
+          Surface* currentSurface = (*currentS).second;
+          if (!currentSurface)
+               continue;
+
+          if (currentSurface->getNativeContent() == static_cast<long>(w))
+               return currentSurface;
+     }
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": could not get surface for window " << w );
+
+     return NULL;
+}
+
+bool DFBWindowSystem::deleteOrphanWindow(void *win)
+{
+     sManagedWindow *managed = (sManagedWindow *)win;
+
+     if (!getSurfaceForWindow( managed->winID )) {
+          LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": removing orphan window " << managed->winID );
+
+          direct_hash_remove( &window_map, managed->winID );
+          direct_hash_remove( &surface_map, managed->surfID );
+
+          managed->win->DetachEventBuffer( managed->win, m_events );
+          managed->surf->DetachEventBuffer( managed->surf, m_events );
+
+          delete managed->platform;
+
+          return true;
+     }
+
+     return false;
+}
+
+bool checkOrphanWindow(DirectHash *hash, unsigned long key, void *value, void *ctx)
+{
+     (void)hash;
+     (void)key;
+     DFBWindowSystem *windowsys = static_cast<DFBWindowSystem *>((DFBWindowSystem *)ctx);
+
+     windowsys->deleteOrphanWindow( value );
+
+     return true;
+}
+
+void DFBWindowSystem::checkForNewSurfaceNativeContent()
+{
+     m_pScene->lockScene();
+
+     LayerList layers = m_pScene->getCurrentRenderOrder(0);
+     for (LayerListConstIterator current = layers.begin(); current != layers.end(); current++) {
+          SurfaceList surfaces = (*current)->getAllSurfaces();
+          for (SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++) {
+               if ((*currentS)->getNativeContent())
+                    allocatePlatformSurface( *currentS );
+               else
+                    deallocatePlatformSurface( *currentS );
+          }
+     }
+
+     if (direct_hash_count( &window_map ))
+          direct_hash_iterate( &window_map, checkOrphanWindow, this );
+
+     m_pScene->unlockScene();
+
+     m_checkWindows = false;
+}
+
+void DFBWindowSystem::configureSurfaceWindow(DFBWindow window)
+{
+     if (isWindowValid( window )) {
+          int winWidth = 0;
+          int winHeight = 0;
+
+          UnMapWindow( window );
+          MapWindow( window );
+
+          Surface* surface = getSurfaceForWindow( window );
+          if (!surface) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find surface for window " << window );
+               return;
+          }
+
+          if (!surface->platform) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Platform surface not available for window " << window );
+               return;
+          }
+
+          DFBPlatformSurface* platformSurface = (DFBPlatformSurface*)surface->platform;
+          platformSurface->dfb_surface->GetSize( platformSurface->dfb_surface, &winWidth, &winHeight );
+
+          surface->OriginalSourceHeight = winHeight;
+          surface->OriginalSourceWidth = winWidth;
+
+          LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": successfully updated window " << window );
+     }
+}
+
+void DFBWindowSystem::MapWindow(DFBWindow window)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(window=" << window << ")" );
+
+     if (isWindowValid( window )) {
+          Surface* surface = getSurfaceForWindow( window );
+          if (!surface) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find surface for window " << window );
+               return;
+          }
+
+          if (!surface->platform) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Platform surface not available for window " << window );
+               return;
+          }
+
+          DFBPlatformSurface* dfbsurf = (DFBPlatformSurface*)surface->platform;
+          if (dfbsurf->isMapped) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Platform surface for window " << window << " was already mapped" );
+               return;
+          }
+
+          dfbsurf->isMapped = true;
+
+          sManagedWindow *win = (sManagedWindow *)malloc( sizeof(sManagedWindow) );
+          win->platform = dfbsurf;
+          win->winID = dfbsurf->dfb_window_id;
+          win->win = dfbsurf->dfb_window;
+          win->surfID = dfbsurf->dfb_surface_id;
+          win->surf = dfbsurf->dfb_surface;
+          dfbsurf->dfb_window->GetPosition( dfbsurf->dfb_window, &win->x, &win->y );
+          dfbsurf->dfb_window->GetSize( dfbsurf->dfb_window, &win->w, &win->h );
+
+          direct_hash_insert( &window_map, dfbsurf->dfb_window_id, win );
+          direct_hash_insert( &surface_map, dfbsurf->dfb_surface_id, win );
+
+          surface->OriginalSourceWidth = win->w;
+          surface->OriginalSourceHeight = win->h;
+          surface->renderPropertyChanged = true;
+
+          m_gfx->getTextureBinder()->createClientBuffer( surface );
+          dfbsurf->enableRendering();
+
+          LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": successfully mapped window " << window );
+     }
+}
+
+void DFBWindowSystem::UnMapWindow(DFBWindow window)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(window=" << window << ")" );
+
+     if (isWindowValid( window )) {
+          Surface* surface = getSurfaceForWindow( window );        
+          if (!surface) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find surface for window " << window );
+               return;
+          }
+
+          if (!surface->platform) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Platform surface not available for window " << window );
+               return;
+          }
+
+          DFBPlatformSurface* dfbsurf = (DFBPlatformSurface*)surface->platform;
+          dfbsurf->disableRendering();
+          if (!dfbsurf->isMapped) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Platform surface for window " << window << " was already unmapped" );
+               return;
+          }
+
+          dfbsurf->isMapped = false;
+          m_gfx->getTextureBinder()->destroyClientBuffer( surface );
+
+          if (dfbsurf->dfb_surface) {
+               dfbsurf->dfb_window->DetachEventBuffer( dfbsurf->dfb_window, m_events );
+               dfbsurf->dfb_surface->DetachEventBuffer( dfbsurf->dfb_surface, m_events );
+               direct_hash_remove( &window_map, dfbsurf->dfb_window_id );
+               direct_hash_remove( &surface_map, dfbsurf->dfb_surface_id );
+               dfbsurf->dfb_surface->Release( dfbsurf->dfb_surface );
+               dfbsurf->dfb_window->Release( dfbsurf->dfb_window );
+          }
+
+          surface->renderPropertyChanged = true;
+
+          LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": successfully unmapped window " << window );
+     }
+}
+
+bool DFBWindowSystem::NewWindow(Surface* surface, DFBWindow window)
+{
+     DFBResult ret;
+     int winWidth = 0;
+     int winHeight = 0;
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(surface=" << surface << ", window=" << window << ")" );
+
+     if (isWindowValid( window )) {
+          surface->setNativeContent( window );
+          DFBPlatformSurface *platformSurface = (DFBPlatformSurface*)m_gfx->getTextureBinder()->createPlatformSurface( surface );
+          platformSurface->isMapped = false;
+
+          if (!platformSurface->dfb_surface) {
+               LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": failed to create platform surface for window " << window );
+               delete platformSurface;
+               return false;
+          }
+
+          surface->platform = platformSurface;
+
+          platformSurface->dfb_window->GetSize( platformSurface->dfb_window, &winWidth, &winHeight );
+
+          ret = platformSurface->dfb_window->AttachEventBuffer( platformSurface->dfb_window, m_events );
+          if (ret) {
+               LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": IDirectFBSurface::AttachEventBuffer() failed! (ret=" << ret << ")" );
+               delete platformSurface;
+               surface->platform = NULL;
+               return false;
+          }
+
+          ret = platformSurface->dfb_surface->AttachEventBuffer( platformSurface->dfb_surface, m_events );
+          if (ret) {
+               LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": IDirectFBSurface::AttachEventBuffer() failed! (ret=" << ret << ")" );
+               delete platformSurface;
+               surface->platform = NULL;
+               return false;
+          }
+
+          platformSurface->dfb_surface->MakeClient( platformSurface->dfb_surface );
+          surface->OriginalSourceHeight = winHeight;
+          surface->OriginalSourceWidth = winWidth;
+
+          LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": successfully created new surface " << platformSurface->dfb_surface << " for window " << window << " (w=" << winWidth << " h=" << winHeight << ")" );
+
+          return true;
+     }
+
+     return false;
+}
+
+void DFBWindowSystem::DestroyWindow(DFBWindow window)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(window=" << window << ")" );
+
+     if (isWindowValid( window )) {
+          Surface* surface = getSurfaceForWindow( window );
+          if (!surface) {
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find surface for window " << window );
+               return;
+          }
+
+          m_gfx->getTextureBinder()->destroyClientBuffer( surface );
+          UnMapWindow( window );
+          surface->removeNativeContent();
+
+          surface->renderPropertyChanged = true;
+          delete surface->platform;
+          surface->platform = NULL;
+     }
+}
+
+int DFBWindowSystem::selectOutput(DFBGraphicSystem *gfx, int id)
+{
+     int ret = -1;
+
+     for (int i = 0; i < gfx->m_renderer->m_num_outputs; i++) {
+          if (gfx->m_renderer->m_outputs[i].layer_id == id) {
+               ret = i;
+               break;
+          }
+     }
+
+     return ret;
+}
+
+void DFBWindowSystem::RedrawAllLayers(bool clear, bool swap)
+{
+     DFBGraphicSystem *gfx;
+     DFBDisplayLayerConfig config;
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(clear=" << clear << ", swap=" << swap << ")" );
+
+     LayerList layers = m_pScene->getCurrentRenderOrder( 0 );
+     LayerList swLayers;
+     std::list<int> orphan_ids = list<int>( *m_sceneLayers );
+
+     m_sceneLayers->clear();
+
+     for (LayerListConstIterator current = layers.begin(); current != layers.end(); current++) {
+          m_sceneLayers->push_back( (*current)->getID() );
+          orphan_ids.remove( (*current)->getID() );
+
+          if ((*current)->getLayerType() == Hardware) {
+               if (m_forceComposition || m_gfx->needsRedraw( *current ))
+                    renderHWLayer( *current, clear );
+          }
+          else
+               swLayers.push_back( *current );
+     }
+
+     if (m_dfb_mode_hw) {
+          gfx = (DFBGraphicSystem *)m_gfx;
+
+          for(std::list<int>::iterator list_iter = orphan_ids.begin(); list_iter != orphan_ids.end(); list_iter++) {
+               int output = selectOutput( gfx, *list_iter );
+               if (output >= 0) {
+                    if (!gfx->m_renderer->m_outputs[output].muted) {
+                         LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": turning OFF orphan layer " << gfx->m_renderer->m_outputs[output].layer );
+
+                         if (!gfx->m_renderer->m_outputs[output].layer->GetConfiguration( gfx->m_renderer->m_outputs[output].layer, &config )) {
+                              config.options = DLOP_OPACITY;
+
+                              if (gfx->m_renderer->m_outputs[output].layer->SetConfiguration( gfx->m_renderer->m_outputs[output].layer, &config )) {
+                                   LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set layer configuration on layer " << gfx->m_renderer->m_outputs[output].layer );
+                              }
+                              else {
+                                   if (gfx->m_renderer->m_outputs[output].layer->SetOpacity( gfx->m_renderer->m_outputs[output].layer, 0 )) {
+                                        LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set opacity on layer " << gfx->m_renderer->m_outputs[output].layer );
+                                   }
+                                   else {
+                                        gfx->m_renderer->m_outputs[output].muted = true;
+                                        gfx->m_renderer->m_outputs[output].layer_opacity = 0;
+                                   }
+                              }
+                         }
+                    }
+               }
+          }
+     }
+
+     if (swLayers.size() > 0 && (m_forceComposition || m_gfx->needsRedraw( swLayers ))) {
+          if (m_dfb_mode_hw)
+               renderSWLayers( swLayers, clear, swap );
+          else {
+               m_gfx->renderSWLayers( swLayers, clear );
+
+               if (swap)
+                    m_gfx->swapBuffers();
+          }
+     }
+}
+
+void DFBWindowSystem::renderSWLayers(LayerList layers, bool clear, bool swap)
+{
+     DFBGraphicSystem *gfx = (DFBGraphicSystem *)m_gfx;
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(clear=" << clear << ", swap=" << swap << ")" );
+
+     for (LayerListConstIterator layer = layers.begin(); layer != layers.end(); layer++) {
+          gfx->renderSWLayer( *layer, clear );
+          if (swap) {
+               gfx->beginLayer( *layer );
+               if (gfx->m_renderer_output == -1) {
+                    LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": called with a non-existent layer" );
+                    gfx->endLayer();
+                    continue;
+               }
+               gfx->swapBuffers();
+               gfx->endLayer();
+          }
+     }
+}
+
+static int countVisibleSurfaces(Layer *layer)
+{
+     int ret = 0;
+     FloatRectangle rect;
+
+     SurfaceList surfaces = layer->getAllSurfaces();
+     for (SurfaceListConstIterator currentS = surfaces.begin(); currentS != surfaces.end(); currentS++) {
+          if ((*currentS)->getOpacity() > 0 && (*currentS)->getVisibility()) {
+               rect = (*currentS)->getTargetSourceRegion();
+               if (rect.width > 0 && rect.height > 0) {
+                    rect = (*currentS)->getTargetDestinationRegion();
+                    if (rect.width > 0 && rect.height > 0)
+                         ret++;
+               }
+          }
+     }
+
+     return ret;
+}
+
+static bool isSurfaceVisible(Surface *surface)
+{
+     FloatRectangle rect;
+
+     if (surface->getOpacity() > 0 && surface->getVisibility()) {
+          rect = surface->getTargetSourceRegion();
+          if (rect.width > 0 && rect.height > 0) {
+               rect = surface->getTargetDestinationRegion();
+               if (rect.width > 0 && rect.height > 0)
+                    return true;
+          }
+     }
+
+     return false;
+}
+
+void DFBWindowSystem::renderHWLayer(Layer *layer, bool clear)
+{
+     DFBGraphicSystem *gfx = (DFBGraphicSystem *)m_gfx;
+     DFBDisplayLayerConfig config;
+     int num_surfaces_curr = 0;
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(layer=" << layer << ", clear=" << clear << ")" );
+
+     gfx->beginLayer( layer );
+     if (gfx->m_renderer_output == -1) {
+          LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": called with a non-existent layer" );
+
+          gfx->endLayer();
+          return;
+     }
+
+     if (layer->getLayerType() != Hardware)
+          LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": called with a non-HW layer" );
+
+     if (!m_pScene->isLayerInCurrentRenderOrder( layer->getID() ) || layer->opacity == 0 || layer->visibility == 0) {
+          if (!gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted) {
+               LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": turning OFF layer " << layer);
+
+               if (!gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->GetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                    config.options = DLOP_OPACITY;
+
+                    if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                         LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set layer configuration on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                    }
+                    else {
+                         if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetOpacity( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, 0 )) {
+                              LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set opacity on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                         }
+                         else {
+                              gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted = true;
+                              gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer_opacity = 0;
+                         }
+                    }
+               }
+          }
+     }
+     else if (layer->visibility > 0 && layer->opacity > 0.0f) {
+          num_surfaces_curr = countVisibleSurfaces( layer );
+          if (num_surfaces_curr > 0) {
+               if (layer->getChromaKeyEnabled())
+                    LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": cannot handle chroma key" );
+
+               if (clear)
+                    gfx->clearBackground();
+
+               if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted || gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer_opacity != layer->opacity) {
+                    LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": turning ON layer " << layer << " with opacity=" << (int)(layer->opacity * 0xFF) );
+
+                    if (!gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->GetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                         config.options = layer->opacity == 1 ? DLOP_NONE : (DFBDisplayLayerOptions)(DLOP_OPACITY | DLOP_ALPHACHANNEL);
+
+                         if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                              LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set layer configuration on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                         }
+                         else {
+                              if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetOpacity( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, layer->opacity * 0xFF )) {
+                                   LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set opacity on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                              }
+                              else {
+                                   gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted = false;
+                                   gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer_opacity = layer->opacity;
+                              }
+                         }
+                    }
+               }
+
+               SurfaceList surfaces = layer->getAllSurfaces();
+               for (std::list<Surface*>::const_iterator currentS = surfaces.begin(); currentS != surfaces.end(); ++currentS) {
+                    if ((*currentS)->hasNativeContent() && isSurfaceVisible( (*currentS) ))
+                         gfx->renderSurface( *currentS );
+               }
+          }
+          else if (!gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted) {
+               LOG_INFO( "DFBWindowSystem", __FUNCTION__ << ": tunring OFF layer " << layer);
+
+               if (!gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->GetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                    config.options = DLOP_OPACITY;
+
+                    if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetConfiguration( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, &config )) {
+                         LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set layer configuration on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                    }
+                    else {
+                         if (gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer->SetOpacity( gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer, 0 )) {
+                              LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": failed to set opacity on layer " << gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer );
+                         }
+                         else {
+                              gfx->m_renderer->m_outputs[gfx->m_renderer_output].muted = true;
+                              gfx->m_renderer->m_outputs[gfx->m_renderer_output].layer_opacity = 0;
+                         }
+                    }
+               }
+          }
+
+          gfx->m_renderer->m_outputs[gfx->m_renderer_output].num_surfaces = num_surfaces_curr;
+     }
+
+     gfx->swapBuffers();
+
+     gfx->endLayer();
+}
+
+void DFBWindowSystem::Redraw(bool clear)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "()" );
+
+     m_pScene->lockScene();
+
+     RedrawAllLayers( clear, true );
+     ClearDamage();
+
+     m_pScene->unlockScene();
+}
+
+void DFBWindowSystem::Screenshot()
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "()" );
+
+     m_pScene->lockScene();
+
+     if (takeScreenshot == ScreenshotOfDisplay) {
+          if (!m_dfb_mode_hw) {
+               RedrawAllLayers( true, false );
+               m_gfx->saveScreenShotOfFramebuffer( screenShotFile );
+          }
+          else
+               LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": Screetshot of FrameBuffer currently unsupported!" );
+     }
+     else if (takeScreenshot == ScreenshotOfLayer) {
+          Layer* layer = m_pScene->getLayer( screenShotLayerID );
+          if (layer != NULL) {
+               m_gfx->renderSWLayer( layer, true );
+               if (m_dfb_mode_hw)
+                    m_gfx->beginLayer( layer );
+               m_gfx->saveScreenShotOfFramebuffer( screenShotFile );
+               if (m_dfb_mode_hw)
+                    m_gfx->endLayer();
+          }
+     }
+     else if (takeScreenshot == ScreenshotOfSurface) {
+          Layer* layer = m_pScene->getLayer( screenShotLayerID );
+          Surface* surface = m_pScene->getSurface( screenShotSurfaceID );
+          if (layer != NULL && surface != NULL) {
+               m_gfx->clearBackground();
+               m_gfx->beginLayer( layer );
+               m_gfx->renderSurface( surface );
+               m_gfx->saveScreenShotOfFramebuffer( screenShotFile );
+               m_gfx->endLayer();
+          }
+     }
+
+     takeScreenshot = ScreenShotNone;
+
+     m_pScene->unlockScene();
+}
+
+void *startEventLoop(void *ptr)
+{
+     DFBWindowSystem *windowsys = static_cast<DFBWindowSystem *>((DFBWindowSystem *)ptr);
+     windowsys->EventLoop();
+
+     return NULL;
+}
+
+static void genWindowEventFromInput(const DFBInputEvent *inputEvent, DFBWindowID wid, DFBWindowEventType etype, int x, int y, int cx, int cy, DFBWindowEvent *windowEvent)
+{
+     memset( windowEvent, 0, sizeof(DFBWindowEvent) );
+
+     windowEvent->type = etype;
+     windowEvent->window_id = wid; 
+     windowEvent->flags = DWEF_DEVICE_ID;
+     windowEvent->x = x;
+     windowEvent->y = y;
+     windowEvent->cx = cx;
+     windowEvent->cy = cy;
+     windowEvent->device_id = inputEvent->device_id;
+     windowEvent->timestamp = inputEvent->timestamp;
+     windowEvent->key_code = inputEvent->key_code;
+     windowEvent->key_id = inputEvent->key_id;
+     windowEvent->key_symbol = inputEvent->key_symbol;
+     windowEvent->modifiers = inputEvent->modifiers;
+     windowEvent->locks = inputEvent->locks;
+     windowEvent->button = inputEvent->button;
+     windowEvent->buttons = inputEvent->buttons;
+}
+
+void DFBWindowSystem::EventLoop()
+{
+     Surface *surface;
+     sManagedWindow *win;
+     DFBPlatformSurface *surf;
+     DFBWindowEvent windowEvent;
+     DFBEvent event;
+     bool redraw = false;
+
+     if (m_primary) {
+          LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": using compositor primary " << m_primary << " with id " << CompositorSurface << " (w=" << m_primary_width << " h=" << m_primary_height << ")" );
+
+          m_primary->Clear( m_primary, 0, 0, 0, 0 );
+          m_primary->Flip( m_primary, NULL, DSFLIP_NONE );
+     
+          m_gfx->init( dfbDisplay, (long)m_primary );
+          m_gfx->activateGraphicContext();
+          m_gfx->clearBackground();
+          m_gfx->swapBuffers();
+     }
+
+     pthread_mutex_lock( &init_lock );
+     m_running = true;
+     pthread_cond_signal( &init_condition );
+     pthread_mutex_unlock( &init_lock );
+
+     while (m_running) {
+          if (m_checkWindows) {
+               checkForNewSurfaceNativeContent();
+               Redraw( true );
+               redraw = false;
+          }
+          else if (redraw) {
+               Redraw( true );
+               redraw = false;
+          }
+
+          if (takeScreenshot != ScreenShotNone)
+               Screenshot();
+
+          m_events->WaitForEventWithTimeout( m_events, 0, 300 );
+
+          pthread_mutex_lock( &run_lock );
+
+          while (m_events->GetEvent( m_events, &event ) == DFB_OK) {
+               switch (event.clazz) {
+                    case DFEC_WINDOW:
+                         switch (event.window.type) {
+                              case DWET_POSITION:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": WINDOW POSITION event for window id " << event.window.window_id );
+
+                                   win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                   if (win) {
+                                        win->x = event.window.x;
+                                        win->y = event.window.y;
+                                   }
+                                   else
+                                        LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                   break;
+                              default:
+                                   break;
+                         }
+                         break;
+                    case DFEC_SURFACE:
+                         switch (event.surface.type) {
+                              case DSEVT_UPDATE:
+                                   if (!m_ignore_surface_updates) {
+                                        LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": SURFACE UPDATE event for surface id " << event.surface.surface_id );
+
+                                        win = (sManagedWindow *)direct_hash_lookup( &surface_map, event.surface.surface_id );
+                                        if (win) {
+                                             LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": sending FrameAck for surface id " << event.surface.surface_id << " (frame=" << event.surface.flip_count << ")" );
+                                             win->surf->FrameAck( win->surf, event.surface.flip_count );
+                                             redraw = true;
+                                        }
+                                        else
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find surface for id " << event.surface.surface_id );
+                                   }
+                                   else
+                                        LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": SURFACE UPDATE event for surface id " << event.surface.surface_id << " -- ignoring" );
+                                   break;
+                              default:
+                                   break;
+                         }
+                         break;
+                    case DFEC_INPUT:
+                         Point pos;
+                         pos.x = m_adjusted_mouse_x;
+                         pos.y = m_adjusted_mouse_y;
+                         switch (event.input.type) {
+                              case DIET_KEYPRESS:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> KEYPRESS" );
+
+                                   surface = m_pInputManager->reportKeyboardEvent( INPUT_STATE_PRESSED, event.input.key_code );
+                                   if (surface && surface->platform) {
+                                        surf = (DFBPlatformSurface *)surface->platform;
+                                        win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                        if (!win) {
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                             break;
+                                        }
+                                        genWindowEventFromInput( &event.input, surf->dfb_window_id, DWET_KEYDOWN, m_adjusted_mouse_x, m_adjusted_mouse_y, m_adjusted_mouse_x - win->x, m_adjusted_mouse_y - win->y, &windowEvent );
+                                        win->win->SendEvent( win->win, &windowEvent );
+                                   }
+                                   break;
+                              case DIET_KEYRELEASE:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> KEYRELEASE" );
+
+                                   surface = m_pInputManager->reportKeyboardEvent( INPUT_STATE_RELEASED, event.input.key_code );
+                                   if (surface && surface->platform) {
+                                        surf = (DFBPlatformSurface *)surface->platform;
+                                        win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                        if (!win) {
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                             break;
+                                        }
+                                        genWindowEventFromInput( &event.input, surf->dfb_window_id, DWET_KEYUP, m_adjusted_mouse_x, m_adjusted_mouse_y, m_adjusted_mouse_x - win->x, m_adjusted_mouse_y - win->y, &windowEvent );
+                                        win->win->SendEvent( win->win, &windowEvent );
+                                   }
+                                   break;
+                              case DIET_BUTTONPRESS:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> BUTTONPRESS" );
+
+                                   pos.state = INPUT_STATE_PRESSED;
+                                   surface = m_pInputManager->reportPointerEvent( pos );
+                                   if (surface && surface->platform) {
+                                        surf = (DFBPlatformSurface *)surface->platform;
+                                        win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                        if (!win) {
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                             break;
+                                        }
+                                        genWindowEventFromInput( &event.input, surf->dfb_window_id, DWET_BUTTONDOWN, m_adjusted_mouse_x, m_adjusted_mouse_y, m_adjusted_mouse_x - win->x, m_adjusted_mouse_y - win->y, &windowEvent );
+                                        win->win->SendEvent( win->win, &windowEvent );
+                                   }
+                                   break;
+                              case DIET_BUTTONRELEASE:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> BUTTONRELEASE" );
+
+                                   pos.state = INPUT_STATE_RELEASED;
+                                   surface = m_pInputManager->reportPointerEvent( pos );
+                                   if (surface && surface->platform) {
+                                        surf = (DFBPlatformSurface *)surface->platform;
+                                        win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                        if (!win) {
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                             break;
+                                        }
+                                        genWindowEventFromInput( &event.input, surf->dfb_window_id, DWET_BUTTONUP, m_adjusted_mouse_x, m_adjusted_mouse_y, m_adjusted_mouse_x - win->x, m_adjusted_mouse_y - win->y, &windowEvent );
+                                        win->win->SendEvent( win->win, &windowEvent );
+                                   }
+                                   break;
+                              case DIET_AXISMOTION:
+                                   pos.state = INPUT_STATE_MOTION;
+                                   if (event.input.flags & DIEF_AXISABS) {
+                                        switch (event.input.axis) {
+                                             case DIAI_X:
+                                                  m_mouse_x = event.input.axisabs;
+                                                  m_mouse_x_min = event.input.min;
+                                                  m_mouse_x_max = event.input.max;
+                                                  break;
+                                             case DIAI_Y:
+                                                  m_mouse_y = event.input.axisabs;
+                                                  m_mouse_y_min = event.input.min;
+                                                  m_mouse_y_max = event.input.max;
+                                                  break;
+                                             default:
+                                                  break;
+                                        }
+                                   }
+                                   else if (event.input.flags & DIEF_AXISREL) {
+                                        switch (event.input.axis) {
+                                             case DIAI_X:
+                                                  m_mouse_x += event.input.axisrel;
+                                                  break;
+                                             case DIAI_Y:
+                                                  m_mouse_y += event.input.axisrel;
+                                                  break;
+                                             default:
+                                                  break;
+                                        }
+                                   }
+
+                                   if (m_mouse_y_min < m_mouse_y_max && m_mouse_x_min < m_mouse_x_max) {
+                                        m_adjusted_mouse_x = CLAMP(m_mouse_x, 0, m_mouse_x_max);
+                                        m_adjusted_mouse_y = CLAMP(m_mouse_y, 0, m_mouse_y_max);
+                                        m_adjusted_mouse_x = ((m_primary_width - 1) * m_adjusted_mouse_x) / m_mouse_x_max;
+                                        m_adjusted_mouse_y = ((m_primary_height - 1) * m_adjusted_mouse_y) / m_mouse_y_max;
+                                   }
+                                   else {
+                                        m_adjusted_mouse_x = CLAMP(m_mouse_x, 0, m_primary_width - 1);
+                                        m_adjusted_mouse_y = CLAMP(m_mouse_y, 0, m_primary_height - 1);
+                                   }
+
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> MOTION at " << m_adjusted_mouse_x << "," << m_adjusted_mouse_y );
+
+                                   pos.x = m_adjusted_mouse_x;
+                                   pos.y = m_adjusted_mouse_y;
+
+                                   surface = m_pInputManager->reportPointerEvent( pos );
+                                   if (surface && surface->platform) {
+                                        surf = (DFBPlatformSurface *)surface->platform;
+                                        win = (sManagedWindow *)direct_hash_lookup( &window_map, event.window.window_id );
+                                        if (!win) {
+                                             LOG_WARNING( "DFBWindowSystem", __FUNCTION__ << ": could not find window for id " << event.window.window_id );
+                                             break;
+                                        }
+                                        genWindowEventFromInput( &event.input, surf->dfb_window_id, DWET_MOTION, m_adjusted_mouse_x, m_adjusted_mouse_y, m_adjusted_mouse_x - win->x, m_adjusted_mouse_y - win->y, &windowEvent );
+                                        win->win->SendEvent( win->win, &windowEvent );
+                                   }
+                                   break;
+                              default:
+                                   LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> UNKNOWN INPUT EVENT" );
+                                   break;
+                         }
+                         break;
+                    default:
+                         break;
+               }
+          }
+
+          pthread_mutex_unlock( &run_lock );
+     }
+
+     cleanup();
+
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << " --> finished" );
+}
+
+void DFBWindowSystem::signalRedrawEvent()
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "()" );
+
+     pthread_mutex_lock( &run_lock );
+
+     m_checkWindows = true;
+     m_events->WakeUp( m_events );
+
+     pthread_mutex_unlock( &run_lock );
+}
+
+void DFBWindowSystem::cleanup()
+{
+     pthread_mutex_lock( &run_lock );
+
+     m_running = false;
+     m_initialized = false;
+
+     if (m_events) {
+          m_events->Release( m_events );
+          m_events = NULL;
+     }
+
+     if (m_primary) {
+          m_primary->Release( m_primary );
+          m_primary = NULL;
+     }
+
+     pthread_mutex_unlock( &run_lock );
+}
+
+bool DFBWindowSystem::init(BaseGraphicSystem<DFBDisplay, DFBWindow>* base, bool dfb_mode_hw)
+{
+     DFBResult ret;
+
+     LOG_INFO( "DFBWindowSystem", __FUNCTION__ << "(hw=" << dfb_mode_hw << ")" );
+
+     m_gfx = base;
+     m_dfb_mode_hw = dfb_mode_hw;
+
+     m_forceComposition = true;
+
+     ret = m_dfb->CreateInputEventBuffer( m_dfb, (DFBInputDeviceCapabilities)(DICAPS_KEYS | DICAPS_BUTTONS | DICAPS_AXES), DFB_FALSE, &m_events );
+     if (ret) {
+          LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": IDirectFB::CreateEventBuffer() failed! (ret=" << ret << ")" );
+          return false;
+     }
+
+     if (!m_dfb_mode_hw) {
+          DFBSurfaceID surf_id;
+
+          ret = m_layer->GetSurface( m_layer, &m_primary );
+          if (ret) {
+               LOG_ERROR( "DFBWindowSystem", __FUNCTION__ << ": IDirectFBDisplayLayer::GetSurface() failed! (ret=" << ret << ")" );
+               m_events->Release( m_events );
+               if (m_primary)
+                    m_primary->Release( m_primary );
+     
+               return false;
+          }
+     
+          m_primary->GetSize( m_primary, &m_primary_width, &m_primary_height );
+     
+          LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << ": retrieved layer primary " << m_primary << " (w=" << m_primary_width << " h=" << m_primary_height << ")" );
+     
+          m_primary->GetID( m_primary, &surf_id );
+          CompositorSurface = surf_id;
+     }
+
+     pthread_mutex_lock( &init_lock );
+
+     int status = pthread_create( &renderThread, NULL, startEventLoop, this );
+     if (status) {
+          pthread_mutex_unlock( &init_lock );
+          return false;
+     }
+
+     if (!m_running)
+          pthread_cond_wait( &init_condition, &init_lock );
+
+     pthread_mutex_unlock( &init_lock );
+
+     LOG_INFO( "DFBWindowSystem", __FUNCTION__ << " --> initialized" );
+
+     return true;
+}
+
+bool DFBWindowSystem::start(int maxIterationDurationInMS)
+{
+     LOG_INFO( "DFBWindowSystem", __FUNCTION__ << "(" << maxIterationDurationInMS << ")" );
+
+     pthread_mutex_lock( &run_lock );
+
+     LayerList layers = m_pScene->getCurrentRenderOrder( 0 );
+     for (LayerListConstIterator current = layers.begin(); current != layers.end(); current++)
+          m_sceneLayers->push_back( (*current)->getID() );
+
+     m_maxIterationDurationInMS = maxIterationDurationInMS;
+
+     m_running = true;
+
+     m_checkWindows = true;
+     m_events->WakeUp( m_events );
+
+     pthread_mutex_unlock( &run_lock );
+
+     return true;
+}
+
+void DFBWindowSystem::stop()
+{
+     LOG_INFO( "DFBWindowSystem", __FUNCTION__ << "()" );
+
+     pthread_mutex_lock( &run_lock );
+
+     m_sceneLayers->clear();
+
+     m_running = false;
+     m_events->WakeUp( m_events );
+
+     pthread_mutex_unlock( &run_lock );
+
+     pthread_join( renderThread, NULL );
+}
+
+void DFBWindowSystem::allocatePlatformSurface(Surface* surface)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(" << surface << ")" );
+
+     DFBPlatformSurface* nativeSurface = (DFBPlatformSurface*)surface->platform;
+     if (!nativeSurface) {
+          if (NewWindow( surface, surface->getNativeContent() ))
+               MapWindow( surface->getNativeContent() );
+     }
+}
+
+void DFBWindowSystem::deallocatePlatformSurface(Surface* surface)
+{
+     LOG_DEBUG( "DFBWindowSystem", __FUNCTION__ << "(" << surface << ")" );
+
+     DFBPlatformSurface* nativeSurface = (DFBPlatformSurface*)surface->platform;
+     if (nativeSurface) {
+          m_gfx->getTextureBinder()->destroyClientBuffer( surface );
+
+          if (nativeSurface->dfb_surface)
+               nativeSurface->dfb_surface->Release( nativeSurface->dfb_surface );
+
+          if (nativeSurface->dfb_window)
+               nativeSurface->dfb_window->Release( nativeSurface->dfb_window );
+
+          surface->renderPropertyChanged = true;
+          delete surface->platform;
+          surface->platform = NULL;
+     }
+}
+
+void DFBWindowSystem::doScreenShot(std::string fileName, const uint screen_id)
+{
+     takeScreenshot = ScreenshotOfDisplay;
+     screenShotFile = fileName;
+     screenShotScreenID = screen_id;
+}
+
+void DFBWindowSystem::doScreenShotOfLayer(std::string fileName, const uint id)
+{
+     takeScreenshot = ScreenshotOfLayer;
+     screenShotFile = fileName;
+     screenShotLayerID = id;
+}
+
+void DFBWindowSystem::doScreenShotOfSurface(std::string fileName, const uint id, const uint layer_id)
+{
+     takeScreenshot = ScreenshotOfSurface;
+     screenShotFile = fileName;
+     screenShotSurfaceID = id;
+     screenShotLayerID = layer_id;
+}
+
+DFBDisplay DFBWindowSystem::getNativeDisplayHandle()
+{
+     return dfbDisplay;
+}
+
+int DFBWindowSystem::getIterationCounter()
+{
+     return m_iterationCounter;
+}
+