LayerManagement: fixed issues detected by valgrind
[profile/ivi/layer-management.git] / LayerManagerPlugins / Communicators / GenericCommunicator / src / GenericCommunicator.cpp
index d8ab2c4..8386cd1 100644 (file)
@@ -1,5 +1,6 @@
 /***************************************************************************
  * Copyright 2012 BMW Car IT GmbH
+ * Copyright (C) 2012 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
 
 #include "GenericCommunicator.h"
 #include "ilm_types.h"
+#include "LmScreen.h"
 #include "Log.h"
-
+#include "Configuration.h"
+
+#include "ICommandExecutor.h"
+#include "CommitCommand.h"
+#include "LayerCreateCommand.h"
+#include "SurfaceCreateCommand.h"
+#include "SurfaceGetDimensionCommand.h"
+#include "LayerGetDimensionCommand.h"
+#include "SurfaceGetOpacityCommand.h"
+#include "LayerGetOpacityCommand.h"
+#include "SurfaceGetPixelformatCommand.h"
+#include "LayerGetVisibilityCommand.h"
+#include "SurfaceGetVisibilityCommand.h"
+#include "LayerAddSurfaceCommand.h"
+#include "LayerRemoveSurfaceCommand.h"
+#include "LayerRemoveCommand.h"
+#include "SurfaceRemoveCommand.h"
+#include "SurfaceGetOrientationCommand.h"
+#include "LayerGetOrientationCommand.h"
+#include "LayerSetDestinationRectangleCommand.h"
+#include "SurfaceSetDestinationRectangleCommand.h"
+#include "LayerSetOpacityCommand.h"
+#include "SurfaceSetOpacityCommand.h"
+#include "LayerSetSourceRectangleCommand.h"
+#include "SurfaceSetSourceRectangleCommand.h"
+#include "LayerSetOrientationCommand.h"
+#include "SurfaceSetOrientationCommand.h"
+#include "LayerSetVisibilityCommand.h"
+#include "SurfaceSetVisibilityCommand.h"
+#include "DebugCommand.h"
+#include "ExitCommand.h"
+#include "ScreenSetRenderOrderCommand.h"
+#include "LayerSetRenderOrderCommand.h"
+#include "LayerSetDimensionCommand.h"
+#include "SurfaceSetDimensionCommand.h"
+#include "LayerSetPositionCommand.h"
+#include "SurfaceSetPositionCommand.h"
+#include "LayerGetPositionCommand.h"
+#include "SurfaceGetPositionCommand.h"
+#include "ShaderCreateCommand.h"
+#include "ShaderDestroyCommand.h"
+#include "SurfaceSetShaderCommand.h"
+#include "ShaderSetUniformsCommand.h"
+#include "ScreenDumpCommand.h"
+#include "LayerDumpCommand.h"
+#include "SurfaceDumpCommand.h"
+#include "SurfaceSetNativeContentCommand.h"
+#include "SurfaceRemoveNativeContentCommand.h"
+#include "SurfaceSetKeyboardFocusCommand.h"
+#include "SurfaceGetKeyboardFocusCommand.h"
+#include "SurfaceUpdateInputEventAcceptance.h"
+#include "SurfaceSetChromaKeyCommand.h"
+#include "LayerSetChromaKeyCommand.h"
+#include "SetOptimizationModeCommand.h"
+#include "GetOptimizationModeCommand.h"
+#include "SetSynchronizedSurfacesCommand.h"
+#include "RemoveSynchronizedSurfacesCommand.h"
 #include <stdbool.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <string>
+#include <pthread.h>
+#include <signal.h>
+#include <vector>
 
 #define DEFAULT_SCREEN 0
 
-const char* RESSOURCE_ALREADY_INUSE = "Ressource already in use";
-const char* INVALID_ARGUMENT = "Invalid argument";
-const char* RESSOURCE_NOT_FOUND = "Ressource not found";
-
-
-//=============================================================================
-// logging
-//=============================================================================
-#define LOG_ENTER_FUNCTION printf("      --> GenericCommunicator::%s()\n", __FUNCTION__)
-//#define LOG_ENTER_FUNCTION
-
-#include <sstream>
-using std::stringstream;
-
-#include <string>
-using std::string;
-
-GenericCommunicator::GenericCommunicator(ICommandExecutor* executor)
-: ICommunicator(executor)
+GenericCommunicator::GenericCommunicator(ICommandExecutor& executor, Configuration& config)
+: ICommunicator(&executor)
+, PluginBase(executor, config, Communicator_Api_v1)
 , m_running(ILM_FALSE)
 {
-    LOG_ENTER_FUNCTION;
-
     MethodTable manager_methods[] =
     {
-        { "ServiceConnect",                   &GenericCommunicator::ServiceConnect },
-        { "ServiceDisconnect",                &GenericCommunicator::ServiceDisconnect },
-        { "Debug",                            &GenericCommunicator::Debug },
-        { "ScreenShot",                       &GenericCommunicator::ScreenShot },
-        { "ScreenShotOfLayer",                &GenericCommunicator::ScreenShotOfLayer },
-        { "ScreenShotOfSurface",              &GenericCommunicator::ScreenShotOfSurface },
-        { "GetScreenResolution",              &GenericCommunicator::GetScreenResolution },
-        { "GetNumberOfHardwareLayers",        &GenericCommunicator::GetNumberOfHardwareLayers },
-        { "GetScreenIDs",                     &GenericCommunicator::GetScreenIDs },
-        { "ListAllLayerIDS",                  &GenericCommunicator::ListAllLayerIDS },
-        { "ListAllLayerIDsOnScreen",          &GenericCommunicator::ListAllLayerIDsOnScreen },
-        { "ListAllSurfaceIDS",                &GenericCommunicator::ListAllSurfaceIDS },
-        { "ListAllLayerGroupIDS",             &GenericCommunicator::ListAllLayerGroupIDS },
-        { "ListAllSurfaceGroupIDS",           &GenericCommunicator::ListAllSurfaceGroupIDS },
-        { "ListSurfacesOfSurfacegroup",       &GenericCommunicator::ListSurfacesOfSurfacegroup },
-        { "ListLayersOfLayergroup",           &GenericCommunicator::ListLayersOfLayergroup },
-        { "ListSurfaceofLayer",               &GenericCommunicator::ListSurfaceofLayer },
-        { "GetPropertiesOfSurface",           &GenericCommunicator::GetPropertiesOfSurface },
-        { "GetPropertiesOfLayer",             &GenericCommunicator::GetPropertiesOfLayer },
-        { "CreateSurface",                    &GenericCommunicator::CreateSurface },
-        { "CreateSurfaceFromId",              &GenericCommunicator::CreateSurfaceFromId },
-        { "InitializeSurface",                &GenericCommunicator::InitializeSurface },
-        { "InitializeSurfaceFromId",          &GenericCommunicator::InitializeSurfaceFromId },
-        { "SetSurfaceNativeContent",          &GenericCommunicator::SetSurfaceNativeContent },
-        { "RemoveSurfaceNativeContent",       &GenericCommunicator::RemoveSurfaceNativeContent },
-        { "RemoveSurface",                    &GenericCommunicator::RemoveSurface },
-        { "CreateLayer",                      &GenericCommunicator::CreateLayer },
-        { "CreateLayerFromId",                &GenericCommunicator::CreateLayerFromId },
-        { "CreateLayerWithDimension",         &GenericCommunicator::CreateLayerWithDimension },
-        { "CreateLayerFromIdWithDimension",   &GenericCommunicator::CreateLayerFromIdWithDimension },
-        { "RemoveLayer",                      &GenericCommunicator::RemoveLayer },
-        { "AddSurfaceToSurfaceGroup",         &GenericCommunicator::AddSurfaceToSurfaceGroup },
-        { "RemoveSurfaceFromSurfaceGroup",    &GenericCommunicator::RemoveSurfaceFromSurfaceGroup },
-        { "AddLayerToLayerGroup",             &GenericCommunicator::AddLayerToLayerGroup },
-        { "RemoveLayerFromLayerGroup",        &GenericCommunicator::RemoveLayerFromLayerGroup },
-        { "AddSurfaceToLayer",                &GenericCommunicator::AddSurfaceToLayer },
-        { "RemoveSurfaceFromLayer",           &GenericCommunicator::RemoveSurfaceFromLayer },
-        { "CreateSurfaceGroup",               &GenericCommunicator::CreateSurfaceGroup },
-        { "CreateSurfaceGroupFromId",         &GenericCommunicator::CreateSurfaceGroupFromId },
-        { "RemoveSurfaceGroup",               &GenericCommunicator::RemoveSurfaceGroup },
-        { "CreateLayerGroup",                 &GenericCommunicator::CreateLayerGroup },
-        { "CreateLayerGroupFromId",           &GenericCommunicator::CreateLayerGroupFromId },
-        { "RemoveLayerGroup",                 &GenericCommunicator::RemoveLayerGroup },
-        { "SetSurfaceSourceRegion",           &GenericCommunicator::SetSurfaceSourceRegion },
-        { "SetLayerSourceRegion",             &GenericCommunicator::SetLayerSourceRegion },
-        { "SetSurfaceDestinationRegion",      &GenericCommunicator::SetSurfaceDestinationRegion },
-        { "SetSurfacePosition",               &GenericCommunicator::SetSurfacePosition },
-        { "GetSurfacePosition",               &GenericCommunicator::GetSurfacePosition },
-        { "SetSurfaceDimension",              &GenericCommunicator::SetSurfaceDimension },
-        { "SetLayerDestinationRegion",        &GenericCommunicator::SetLayerDestinationRegion },
-        { "SetLayerPosition",                 &GenericCommunicator::SetLayerPosition },
-        { "GetLayerPosition",                 &GenericCommunicator::GetLayerPosition },
-        { "SetLayerDimension",                &GenericCommunicator::SetLayerDimension },
-        { "GetLayerDimension",                &GenericCommunicator::GetLayerDimension },
-        { "GetSurfaceDimension",              &GenericCommunicator::GetSurfaceDimension },
-        { "SetSurfaceOpacity",                &GenericCommunicator::SetSurfaceOpacity },
-        { "SetLayerOpacity",                  &GenericCommunicator::SetLayerOpacity },
-        { "SetSurfacegroupOpacity",           &GenericCommunicator::SetSurfacegroupOpacity },
-        { "SetLayergroupOpacity",             &GenericCommunicator::SetLayergroupOpacity },
-        { "GetSurfaceOpacity",                &GenericCommunicator::GetSurfaceOpacity },
-        { "GetLayerOpacity",                  &GenericCommunicator::GetLayerOpacity },
-        { "SetSurfaceOrientation",            &GenericCommunicator::SetSurfaceOrientation },
-        { "GetSurfaceOrientation",            &GenericCommunicator::GetSurfaceOrientation },
-        { "SetLayerOrientation",              &GenericCommunicator::SetLayerOrientation },
-        { "GetLayerOrientation",              &GenericCommunicator::GetLayerOrientation },
-        { "GetSurfacePixelformat",            &GenericCommunicator::GetSurfacePixelformat },
-        { "SetSurfaceVisibility",             &GenericCommunicator::SetSurfaceVisibility },
-        { "SetLayerVisibility",               &GenericCommunicator::SetLayerVisibility },
-        { "GetSurfaceVisibility",             &GenericCommunicator::GetSurfaceVisibility },
-        { "GetLayerVisibility",               &GenericCommunicator::GetLayerVisibility },
-        { "SetSurfacegroupVisibility",        &GenericCommunicator::SetSurfacegroupVisibility },
-        { "SetLayergroupVisibility",          &GenericCommunicator::SetLayergroupVisibility },
-        { "SetRenderOrderOfLayers",           &GenericCommunicator::SetRenderOrderOfLayers },
+        { "ServiceConnect", &GenericCommunicator::ServiceConnect },
+        { "ServiceDisconnect", &GenericCommunicator::ServiceDisconnect },
+        { "Debug", &GenericCommunicator::Debug },
+        { "ScreenShot", &GenericCommunicator::ScreenShot },
+        { "ScreenShotOfLayer", &GenericCommunicator::ScreenShotOfLayer },
+        { "ScreenShotOfSurface", &GenericCommunicator::ScreenShotOfSurface },
+        { "GetScreenResolution", &GenericCommunicator::GetScreenResolution },
+        { "GetNumberOfHardwareLayers", &GenericCommunicator::GetNumberOfHardwareLayers },
+        { "GetScreenIDs", &GenericCommunicator::GetScreenIDs },
+        { "ListAllLayerIDS", &GenericCommunicator::ListAllLayerIDS },
+        { "ListAllLayerIDsOnScreen", &GenericCommunicator::ListAllLayerIDsOnScreen },
+        { "ListAllSurfaceIDS", &GenericCommunicator::ListAllSurfaceIDS },
+        { "ListSurfaceofLayer", &GenericCommunicator::ListSurfaceofLayer },
+        { "GetPropertiesOfSurface", &GenericCommunicator::GetPropertiesOfSurface },
+        { "GetPropertiesOfLayer", &GenericCommunicator::GetPropertiesOfLayer },
+        { "CreateSurface", &GenericCommunicator::CreateSurface },
+        { "CreateSurfaceFromId", &GenericCommunicator::CreateSurfaceFromId },
+        { "InitializeSurface", &GenericCommunicator::InitializeSurface },
+        { "InitializeSurfaceFromId", &GenericCommunicator::InitializeSurfaceFromId },
+        { "SetSurfaceNativeContent", &GenericCommunicator::SetSurfaceNativeContent },
+        { "RemoveSurfaceNativeContent", &GenericCommunicator::RemoveSurfaceNativeContent },
+        { "RemoveSurface", &GenericCommunicator::RemoveSurface },
+        { "CreateLayer", &GenericCommunicator::CreateLayer },
+        { "CreateLayerFromId", &GenericCommunicator::CreateLayerFromId },
+        { "CreateLayerWithDimension", &GenericCommunicator::CreateLayerWithDimension },
+        { "CreateLayerFromIdWithDimension", &GenericCommunicator::CreateLayerFromIdWithDimension },
+        { "RemoveLayer", &GenericCommunicator::RemoveLayer },
+        { "AddSurfaceToLayer", &GenericCommunicator::AddSurfaceToLayer },
+        { "RemoveSurfaceFromLayer", &GenericCommunicator::RemoveSurfaceFromLayer },
+        { "SetSurfaceSourceRegion", &GenericCommunicator::SetSurfaceSourceRegion },
+        { "SetLayerSourceRegion", &GenericCommunicator::SetLayerSourceRegion },
+        { "SetSurfaceDestinationRegion", &GenericCommunicator::SetSurfaceDestinationRegion },
+        { "SetSurfacePosition", &GenericCommunicator::SetSurfacePosition },
+        { "GetSurfacePosition", &GenericCommunicator::GetSurfacePosition },
+        { "SetSurfaceDimension", &GenericCommunicator::SetSurfaceDimension },
+        { "SetLayerDestinationRegion", &GenericCommunicator::SetLayerDestinationRegion },
+        { "SetLayerPosition", &GenericCommunicator::SetLayerPosition },
+        { "GetLayerPosition", &GenericCommunicator::GetLayerPosition },
+        { "SetLayerDimension", &GenericCommunicator::SetLayerDimension },
+        { "GetLayerDimension", &GenericCommunicator::GetLayerDimension },
+        { "GetSurfaceDimension", &GenericCommunicator::GetSurfaceDimension },
+        { "SetSurfaceOpacity", &GenericCommunicator::SetSurfaceOpacity },
+        { "SetLayerOpacity", &GenericCommunicator::SetLayerOpacity },
+        { "GetSurfaceOpacity", &GenericCommunicator::GetSurfaceOpacity },
+        { "GetLayerOpacity", &GenericCommunicator::GetLayerOpacity },
+        { "SetSurfaceOrientation", &GenericCommunicator::SetSurfaceOrientation },
+        { "GetSurfaceOrientation", &GenericCommunicator::GetSurfaceOrientation },
+        { "SetLayerOrientation", &GenericCommunicator::SetLayerOrientation },
+        { "GetLayerOrientation", &GenericCommunicator::GetLayerOrientation },
+        { "GetSurfacePixelformat", &GenericCommunicator::GetSurfacePixelformat },
+        { "SetSurfaceVisibility", &GenericCommunicator::SetSurfaceVisibility },
+        { "SetLayerVisibility", &GenericCommunicator::SetLayerVisibility },
+        { "GetSurfaceVisibility", &GenericCommunicator::GetSurfaceVisibility },
+        { "GetLayerVisibility", &GenericCommunicator::GetLayerVisibility },
+        { "SetRenderOrderOfLayers", &GenericCommunicator::SetRenderOrderOfLayers },
         { "SetSurfaceRenderOrderWithinLayer", &GenericCommunicator::SetSurfaceRenderOrderWithinLayer },
-        { "GetLayerType",                     &GenericCommunicator::GetLayerType },
-        { "GetLayertypeCapabilities",         &GenericCommunicator::GetLayertypeCapabilities },
-        { "GetLayerCapabilities",             &GenericCommunicator::GetLayerCapabilities },
-        { "Exit",                             &GenericCommunicator::Exit },
-        { "CommitChanges",                    &GenericCommunicator::CommitChanges },
-        { "CreateShader",                     &GenericCommunicator::CreateShader },
-        { "DestroyShader",                    &GenericCommunicator::DestroyShader },
-        { "SetShader",                        &GenericCommunicator::SetShader },
-        { "SetUniforms",                      &GenericCommunicator::SetUniforms },
+        { "GetLayerType", &GenericCommunicator::GetLayerType },
+        { "GetLayertypeCapabilities", &GenericCommunicator::GetLayertypeCapabilities },
+        { "GetLayerCapabilities", &GenericCommunicator::GetLayerCapabilities },
+        { "Exit", &GenericCommunicator::Exit },
+        { "CommitChanges", &GenericCommunicator::CommitChanges },
+        { "CreateShader", &GenericCommunicator::CreateShader },
+        { "DestroyShader", &GenericCommunicator::DestroyShader },
+        { "SetShader", &GenericCommunicator::SetShader },
+        { "SetUniforms", &GenericCommunicator::SetUniforms },
+        { "SetKeyboardFocusOn", &GenericCommunicator::SetKeyboardFocusOn },
+        { "GetKeyboardFocusSurfaceId", &GenericCommunicator::GetKeyboardFocusSurfaceId },
+        { "UpdateInputEventAcceptanceOn", &GenericCommunicator::UpdateInputEventAcceptanceOn },
+        { "SetSurfaceChromaKey", &GenericCommunicator::SetSurfaceChromaKey },
+        { "SetLayerChromaKey", &GenericCommunicator::SetLayerChromaKey },
+        { "LayerAddNotification", &GenericCommunicator::LayerAddNotification },
+        { "SurfaceAddNotification", &GenericCommunicator::SurfaceAddNotification },
+        { "LayerRemoveNotification", &GenericCommunicator::LayerRemoveNotification },
+        { "SurfaceRemoveNotification", &GenericCommunicator::SurfaceRemoveNotification },
+        { "SetOptimizationMode", &GenericCommunicator::SetOptimizationMode },
+        { "GetOptimizationMode", &GenericCommunicator::GetOptimizationMode },
+        { "GetPropertiesOfScreen", &GenericCommunicator::GetPropertiesOfScreen },
+        { "SetSynchronizedSurfaces", &GenericCommunicator::SetSynchronizedSurfaces },
+        { "RemoveSynchronizedSurfaces", &GenericCommunicator::RemoveSynchronizedSurfaces }
     };
 
     int entryCount = sizeof(manager_methods) / sizeof(MethodTable);
@@ -150,12 +189,15 @@ GenericCommunicator::GenericCommunicator(ICommandExecutor* executor)
             LOG_DEBUG("GenericCommunicator", "registered callback for " << method->name);
         }
     }
+
+    memset(&m_ipcModule, 0, sizeof(m_ipcModule));
+
+    mThreadId = pthread_self();
 }
 
 bool GenericCommunicator::start()
 {
-    LOG_ENTER_FUNCTION;
-    LOG_DEBUG("GenericCommunicator", "Starting up dbus connector");
+    LOG_DEBUG("GenericCommunicator", "Starting up IpcModules.");
 
     if (!loadIpcModule(&m_ipcModule))
     {
@@ -164,72 +206,115 @@ bool GenericCommunicator::start()
     }
     LOG_DEBUG("GenericCommunicator", "Loading IpcModule success.");
 
-    if (!m_ipcModule.init(ILM_FALSE))
+    if (!m_ipcModule.initServiceMode())
     {
         LOG_ERROR("GenericCommunicator", "Initializing IpcModule failed.");
         return ILM_FALSE;
     }
     LOG_DEBUG("GenericCommunicator", "Initializing IpcModule success.");
 
+    m_running = ILM_TRUE;
+    pluginSetHealth(HealthRunning);
+
+    threadCreate();
+    threadInit();
+    threadStart();
+
     return ILM_TRUE;
 }
 
 void GenericCommunicator::stop()
 {
-    LOG_ENTER_FUNCTION;
-    LOG_INFO("GenericCommunicator","stopping");
+    LOG_INFO("GenericCommunicator", "stopping");
 
-    m_ipcModule.destroy();
+    threadStop();
+
+    if (m_running)
+    {
+        m_ipcModule.destroy();
+    }
+    pluginSetHealth(HealthStopped);
 }
 
 void GenericCommunicator::process(int timeout_ms)
 {
-    enum IpcMessageType messageType = m_ipcModule.receiveMessage(timeout_ms);
+    t_ilm_message message = m_ipcModule.receive(timeout_ms);
+    if (!message)
+    {
+        return;
+    }
 
-    t_ilm_const_string name = m_ipcModule.getMessageName();
-    t_ilm_const_string sender = m_ipcModule.getSenderName();
+    t_ilm_message_type messageType = m_ipcModule.getMessageType(message);
+    t_ilm_const_string name = m_ipcModule.getMessageName(message);
+    t_ilm_client_handle senderHandle = m_ipcModule.getSenderHandle(message);
 
-    switch(messageType)
+    switch (messageType)
     {
     case IpcMessageTypeCommand:
-        if (m_callBackTable.count(name))
+        if (m_callBackTable.end() != m_callBackTable.find(name))
         {
-            LOG_DEBUG("GenericCommunicator", "Received message " << name
-                      << " (type=command" << ", sender=" << sender << ")");
+            LOG_DEBUG("GenericCommunicator", "received: " << name << " from "
+                        << m_executor->getSenderName(senderHandle)
+                        << "(" << m_executor->getSenderPid(senderHandle) << ")");
             CallBackMethod method = m_callBackTable[name].function;
-            (this->*method)();
+            (this->*method)(message);
         }
         else
         {
-            LOG_WARNING("GenericCommunicator", "Received unknown message " << name
-                        << " (type=command" << ", sender=" << sender << ")");
+            LOG_WARNING("GenericCommunicator", "Received unknown command " << name
+                    << " from " << m_executor->getSenderName(senderHandle)
+                    << "(pid " << m_executor->getSenderPid(senderHandle) << ")");
         }
+        processNotificationQueue();
         break;
 
-    case IpcMessageTypeDisconnect:
-        LOG_DEBUG("GenericCommunicator", "Received message " << name
-                  << " (type=disconnect" << ", sender=" << sender << ")");
-        ServiceDisconnect();
+    case IpcMessageTypeConnect:
+        LOG_DEBUG("GenericCommunicator", "client " << m_executor->getSenderName(senderHandle)
+                    << "(pid " << m_executor->getSenderPid(senderHandle) << ") connected");
         break;
 
-    case IpcMessageTypeNotification:
-        LOG_DEBUG("GenericCommunicator", "Received message " << name
-                  << " (type=notification" << ", sender=" << sender << ")");
+    case IpcMessageTypeDisconnect:
+        LOG_DEBUG("GenericCommunicator", "client " << m_executor->getSenderName(senderHandle)
+                    << "(pid " << m_executor->getSenderPid(senderHandle) << ") disconnected");
+        {
+            const LayerMap& layers = m_executor->getScene()->getAllLayers();
+            LayerMapConstIterator layerIter = layers.begin();
+            LayerMapConstIterator layerIterEnd = layers.end();
+            for (; layerIter != layerIterEnd; ++layerIter)
+            {
+                Layer* layer = layerIter->second;
+                layer->removeNotification(senderHandle);
+            }
+
+            const SurfaceMap& surfaces = m_executor->getScene()->getAllSurfaces();
+            SurfaceMapConstIterator surfaceIter = surfaces.begin();
+            SurfaceMapConstIterator surfaceIterEnd = surfaces.end();
+            for (; surfaceIter != surfaceIterEnd; ++surfaceIter)
+            {
+                Surface* surface = surfaceIter->second;
+                surface->removeNotification(senderHandle);
+            }
+            m_executor->removeApplicationReference(senderHandle);
+        }
         break;
 
     case IpcMessageTypeError:
-        LOG_DEBUG("GenericCommunicator", "Received message " << name
-                  << " (type=error" << ", sender=" << sender << ")");
+        LOG_DEBUG("GenericCommunicator", "Received error message " << name << " from "
+                    << m_executor->getSenderName(senderHandle)
+                    << "(pid " << m_executor->getSenderPid(senderHandle) << ")");
         break;
 
+    case IpcMessageTypeShutdown:
     case IpcMessageTypeNone:
         break;
 
     default:
-        LOG_DEBUG("GenericCommunicator", "Received message " << name
-                  << " (type=unknown" << ", sender=" << sender << ")");
+        LOG_DEBUG("GenericCommunicator", "Received unknown data from "
+                    << m_executor->getSenderName(senderHandle)
+                    << "(pid " << m_executor->getSenderPid(senderHandle) << "), Message type: " << messageType);
         break;
     }
+    m_ipcModule.destroyMessage(message);
 }
 
 void GenericCommunicator::setdebug(bool onoff)
@@ -237,279 +322,260 @@ void GenericCommunicator::setdebug(bool onoff)
     (void)onoff; // TODO: remove, only prevents warning
 }
 
-void GenericCommunicator::ServiceConnect()
+t_ilm_bool GenericCommunicator::threadMainLoop()
 {
-    LOG_DEBUG("GenericCommunicator", "ServiceConnect called");
-    u_int32_t processId = 0;
-    m_ipcModule.getUint(&processId);
-    char* owner = strdup(m_ipcModule.getSenderName());
-    m_executor->addApplicationReference(new IApplicationReference(owner,processId));
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.sendMessage();
+    process(-1);
+    return ILM_TRUE;
 }
 
-void GenericCommunicator::ServiceDisconnect()
+t_ilm_const_string GenericCommunicator::pluginGetName() const
 {
-    LOG_DEBUG("GenericCommunicator", "ServiceDisconnect called");
-    char* owner = strdup(m_ipcModule.getSenderName());
-    long int ownerHash = IApplicationReference::generateApplicationHash(owner);
-    ApplicationReferenceMap* refmap = m_executor->getApplicationReferenceMap();
+    return "GenericCommunicator";
+}
 
-    ApplicationReferenceMapIterator iter = refmap->find(ownerHash);
-    ApplicationReferenceMapIterator iterEnd = refmap->end();
+void GenericCommunicator::ServiceConnect(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
 
-    for (; iter != iterEnd; ++iter)
-    {
-        IApplicationReference* registeredApp = (*iter).second;
-        m_executor->removeApplicationReference(registeredApp);
-    }
+    unsigned int processId = 0;
+    char processName[1024];
+    m_ipcModule.getUint(message, &processId);
+    m_ipcModule.getString(message, processName);
+
+    m_executor->addApplicationReference(clientHandle, new IApplicationReference(processName, processId));
 
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.sendMessage();
+    LOG_DEBUG("GenericCommunicator", "ServiceConnect called from "
+                << m_executor->getSenderName(clientHandle)
+                << "(" << m_executor->getSenderPid(clientHandle) << ")");
+
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::Debug()
+void GenericCommunicator::ServiceDisconnect(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+
+    LOG_DEBUG("GenericCommunicator", "ServiceDisconnect called from "
+                << m_executor->getSenderName(clientHandle)
+                << "(" << m_executor->getSenderPid(clientHandle) << ")");
+
+    m_executor->removeApplicationReference(clientHandle);
+
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::Debug(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     t_ilm_bool param = ILM_FALSE;
-    m_ipcModule.getBool(&param);
+    m_ipcModule.getBool(message, &param);
 
-    t_ilm_bool status = m_executor->execute(new DebugCommand(param));
+    t_ilm_bool status = m_executor->execute(new DebugCommand(clientPid, param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(INVALID_ARGUMENT);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetScreenResolution()
+void GenericCommunicator::GetScreenResolution(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint screenid = 0;
-    m_ipcModule.getUint(&screenid);
+    m_ipcModule.getUint(message, &screenid);
     uint* resolution = m_executor->getScreenResolution(screenid);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUint(resolution[0]);
-    m_ipcModule.appendUint(resolution[1]);
-    m_ipcModule.sendMessage();
+
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUint(response, resolution[0]);
+    m_ipcModule.appendUint(response, resolution[1]);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+
+    delete [] resolution;
 }
 
-void GenericCommunicator::GetNumberOfHardwareLayers()
+void GenericCommunicator::GetNumberOfHardwareLayers(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint screenid = 0;
-    m_ipcModule.getUint(&screenid);
+    m_ipcModule.getUint(message, &screenid);
     uint numberOfHardwareLayers = m_executor->getNumberOfHardwareLayers(screenid);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUint(numberOfHardwareLayers);
-    m_ipcModule.sendMessage();
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUint(response, numberOfHardwareLayers);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetScreenIDs()
+void GenericCommunicator::GetScreenIDs(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint length = 0;
     uint* IDs = m_executor->getScreenIDs(&length);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUintArray(IDs, length);
-    m_ipcModule.sendMessage();
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUintArray(response, IDs, length);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+    delete [] IDs;
 }
 
-void GenericCommunicator::ScreenShot()
+void GenericCommunicator::ScreenShot(t_ilm_message message)
 {
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    t_ilm_message response;
     uint screenid = 0;
-    m_ipcModule.getUint(&screenid);
-    char filename[256];
-    m_ipcModule.getString(filename);
+    char filename[1024];
+
+    m_ipcModule.getUint(message, &screenid);
+    m_ipcModule.getString(message, filename);
 
-    t_ilm_bool status = m_executor->execute(new ScreenDumpCommand(filename, screenid));
+    t_ilm_bool status = m_executor->execute(new ScreenDumpCommand(clientPid, filename, screenid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(INVALID_ARGUMENT);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::ScreenShotOfLayer()
+void GenericCommunicator::ScreenShotOfLayer(t_ilm_message message)
 {
-    char filename[256];
-    m_ipcModule.getString(filename);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    char filename[1024];
+    m_ipcModule.getString(message, filename);
     uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
+    m_ipcModule.getUint(message, &layerid);
 
-    t_ilm_bool status = m_executor->execute(new LayerDumpCommand(filename, layerid));
+    t_ilm_bool status = m_executor->execute(new LayerDumpCommand(clientPid, filename, layerid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::ScreenShotOfSurface()
+void GenericCommunicator::ScreenShotOfSurface(t_ilm_message message)
 {
-    char filename[256];
-    m_ipcModule.getString(filename);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    char filename[1024];
+    m_ipcModule.getString(message, filename);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    t_ilm_bool status = m_executor->execute(new SurfaceDumpCommand(filename, id));
+    m_ipcModule.getUint(message, &id);
+    t_ilm_bool status = m_executor->execute(new SurfaceDumpCommand(clientPid, filename, id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::ListAllLayerIDS()
+void GenericCommunicator::ListAllLayerIDS(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint* array = NULL;
     uint length = 0;
     m_executor->getScene()->lockScene();
     m_executor->getScene()->getLayerIDs(&length, &array);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUintArray(array, length);
-    m_ipcModule.sendMessage();
     m_executor->getScene()->unlockScene();
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUintArray(response, array, length);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::ListAllLayerIDsOnScreen()
+void GenericCommunicator::ListAllLayerIDsOnScreen(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint screenID = 0;
-    m_ipcModule.getUint(&screenID);
+    m_ipcModule.getUint(message, &screenID);
 
     uint* array = NULL;
     uint length = 0;
     m_executor->getScene()->lockScene();
     t_ilm_bool status = m_executor->getScene()->getLayerIDsOfScreen(screenID, &length, &array);
+    m_executor->getScene()->unlockScene();
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUintArray(array, length);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUintArray(response, array, length);
     }
     else
     {
-        m_ipcModule.sendError(INVALID_ARGUMENT);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
-    m_executor->getScene()->unlockScene();
-}
 
-void GenericCommunicator::ListAllSurfaceIDS()
-{
-    uint* array = NULL;
-    uint length = 0;
-    m_executor->getScene()->lockScene();
-    m_executor->getScene()->getSurfaceIDs(&length, &array);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUintArray(array, length);
-    m_ipcModule.sendMessage();
-    m_executor->getScene()->unlockScene();
-}
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 
-void GenericCommunicator::ListAllLayerGroupIDS()
-{
-    uint* array = NULL;
-    uint length = 0;
-    m_executor->getScene()->lockScene();
-    m_executor->getScene()->getLayerGroupIDs(&length, &array);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUintArray(array, length);
-    m_ipcModule.sendMessage();
-    m_executor->getScene()->unlockScene();
+    delete [] array;
 }
 
-void GenericCommunicator::ListAllSurfaceGroupIDS()
+void GenericCommunicator::ListAllSurfaceIDS(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint* array = NULL;
     uint length = 0;
     m_executor->getScene()->lockScene();
-    m_executor->getScene()->getSurfaceGroupIDs(&length, &array);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUintArray(array, length);
-    m_ipcModule.sendMessage();
+    m_executor->getScene()->getSurfaceIDs(&length, &array);
     m_executor->getScene()->unlockScene();
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUintArray(response, array, length);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::ListSurfacesOfSurfacegroup()
+void GenericCommunicator::ListSurfaceofLayer(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    m_executor->getScene()->lockScene();
-    SurfaceGroup* sg = m_executor->getScene()->getSurfaceGroup(id);
-    if (NULL != sg)
-    {
-        std::list<Surface*> surfaces = sg->getList();
-        uint length = surfaces.size();
-        uint* array = new uint[length];
-        uint arrayPos = 0;
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-
-        for (std::list<Surface*>::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
-        {
-            Surface* s = *it;
-            array[arrayPos] = s->getID();
-            ++arrayPos;
-        }
-
-        m_ipcModule.appendUintArray(array, length);
-
-        m_ipcModule.sendMessage();
-        m_executor->getScene()->unlockScene();
-    }
-    else
-    {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
-    }
-}
-
-void GenericCommunicator::ListLayersOfLayergroup()
-{
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    m_executor->getScene()->lockScene();
-    LayerGroup* sg = m_executor->getScene()->getLayerGroup(id);
-    if (NULL != sg)
-    {
-        std::list<Layer*> layers = sg->getList();
-
-        uint length = layers.size();
-        uint* array = new uint[length];
-        uint arrayPos = 0;
-
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        for (std::list<Layer*>::const_iterator it = layers.begin(); it != layers.end(); ++it)
-        {
-            Layer* l = *it;
-            array[arrayPos] = l->getID();
-            ++arrayPos;
-        }
-
-        m_ipcModule.appendUintArray(array, length);
-
-        m_ipcModule.sendMessage();
-        m_executor->getScene()->unlockScene();
-    }
-    else
-    {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
-    }
-}
-
-void GenericCommunicator::ListSurfaceofLayer()
-{
-    uint id = 0;
-    m_ipcModule.getUint(&id);
+    m_ipcModule.getUint(message, &id);
     m_executor->getScene()->lockScene();
     Layer* layer = m_executor->getScene()->getLayer(id);
     if (layer != NULL)
@@ -520,30 +586,35 @@ void GenericCommunicator::ListSurfaceofLayer()
         uint* array = new uint[length];
         uint arrayPos = 0;
 
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-
         for (std::list<Surface*>::const_iterator it = surfaces.begin(); it != surfaces.end(); ++it)
         {
             Surface* s = *it;
             array[arrayPos] = s->getID();
             ++arrayPos;
         }
+        m_executor->getScene()->unlockScene();
 
-        m_ipcModule.appendUintArray(array, length);
-
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUintArray(response, array, length);
+        delete [] array;
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        m_executor->getScene()->unlockScene();
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
-    m_executor->getScene()->unlockScene();
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetPropertiesOfSurface()
+void GenericCommunicator::GetPropertiesOfSurface(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint id = 0;
-    m_ipcModule.getUint(&id);
+    m_ipcModule.getUint(message, &id);
 
     Surface* surface = m_executor->getScene()->getSurface(id);
     if (surface != NULL)
@@ -551,38 +622,53 @@ void GenericCommunicator::GetPropertiesOfSurface()
         Rectangle dest = surface->getDestinationRegion();
         Rectangle src = surface->getSourceRegion();
         OrientationType orientation = surface->getOrientation();
-
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendDouble(surface->getOpacity());
-        m_ipcModule.appendUint(src.x);
-        m_ipcModule.appendUint(src.y);
-        m_ipcModule.appendUint(src.width);
-        m_ipcModule.appendUint(src.height);
-        m_ipcModule.appendUint(surface->OriginalSourceWidth);
-        m_ipcModule.appendUint(surface->OriginalSourceHeight);
-        m_ipcModule.appendUint(dest.x);
-        m_ipcModule.appendUint(dest.y);
-        m_ipcModule.appendUint(dest.width);
-        m_ipcModule.appendUint(dest.height);
-        m_ipcModule.appendUint(orientation);
-        m_ipcModule.appendBool(surface->getVisibility());
-        m_ipcModule.appendUint(surface->frameCounter);
-        m_ipcModule.appendUint(surface->drawCounter);
-        m_ipcModule.appendUint(surface->updateCounter);
-        m_ipcModule.appendUint(surface->getPixelFormat());
-        m_ipcModule.appendUint(surface->getNativeContent());
-        m_ipcModule.sendMessage();
-    }
-    else
-    {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
-    }
-}
-
-void GenericCommunicator::GetPropertiesOfLayer()
-{
+        unsigned char chromaKeyRed = 0;
+        unsigned char chromaKeyGreen = 0;
+        unsigned char chromaKeyBlue = 0;
+        surface->getChromaKey(chromaKeyRed, chromaKeyGreen, chromaKeyBlue);
+
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendDouble(response, surface->getOpacity());
+        m_ipcModule.appendUint(response, src.x);
+        m_ipcModule.appendUint(response, src.y);
+        m_ipcModule.appendUint(response, src.width);
+        m_ipcModule.appendUint(response, src.height);
+        m_ipcModule.appendUint(response, surface->OriginalSourceWidth);
+        m_ipcModule.appendUint(response, surface->OriginalSourceHeight);
+        m_ipcModule.appendUint(response, dest.x);
+        m_ipcModule.appendUint(response, dest.y);
+        m_ipcModule.appendUint(response, dest.width);
+        m_ipcModule.appendUint(response, dest.height);
+        m_ipcModule.appendUint(response, orientation);
+        m_ipcModule.appendBool(response, surface->getVisibility());
+        m_ipcModule.appendUint(response, surface->frameCounter);
+        m_ipcModule.appendUint(response, surface->drawCounter);
+        m_ipcModule.appendUint(response, surface->updateCounter);
+        m_ipcModule.appendUint(response, surface->getPixelFormat());
+        m_ipcModule.appendUint(response, surface->getNativeContent());
+        m_ipcModule.appendUint(response, surface->getInputEventAcceptanceOnDevices());
+        m_ipcModule.appendBool(response, surface->getChromaKeyEnabled());
+        m_ipcModule.appendUint(response, chromaKeyRed);
+        m_ipcModule.appendUint(response, chromaKeyGreen);
+        m_ipcModule.appendUint(response, chromaKeyBlue);
+        m_ipcModule.appendInt(response, surface->getCreatorPid());
+    }
+    else
+    {
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
+    }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::GetPropertiesOfLayer(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint id = 0;
-    m_ipcModule.getUint(&id);
+    m_ipcModule.getUint(message, &id);
 
     Layer* layer = m_executor->getScene()->getLayer(id);
     if (layer != NULL)
@@ -590,1321 +676,2009 @@ void GenericCommunicator::GetPropertiesOfLayer()
         Rectangle dest = layer->getDestinationRegion();
         Rectangle src = layer->getSourceRegion();
         OrientationType orientation = layer->getOrientation();
-
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendDouble(layer->getOpacity());
-        m_ipcModule.appendUint(src.x);
-        m_ipcModule.appendUint(src.y);
-        m_ipcModule.appendUint(src.width);
-        m_ipcModule.appendUint(src.height);
-        m_ipcModule.appendUint(layer->OriginalSourceWidth);
-        m_ipcModule.appendUint(layer->OriginalSourceHeight);
-        m_ipcModule.appendUint(dest.x);
-        m_ipcModule.appendUint(dest.y);
-        m_ipcModule.appendUint(dest.width);
-        m_ipcModule.appendUint(dest.height);
-        m_ipcModule.appendUint(orientation);
-        m_ipcModule.appendBool(layer->getVisibility());
-        m_ipcModule.appendUint(layer->getLayerType());
-        m_ipcModule.sendMessage();
-    }
-    else
-    {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
-    }
-}
-
-void GenericCommunicator::CreateSurface()
-{
+        unsigned char chromaKeyRed = 0;
+        unsigned char chromaKeyGreen = 0;
+        unsigned char chromaKeyBlue = 0;
+        layer->getChromaKey(chromaKeyRed, chromaKeyGreen, chromaKeyBlue);
+
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendDouble(response, layer->getOpacity());
+        m_ipcModule.appendUint(response, src.x);
+        m_ipcModule.appendUint(response, src.y);
+        m_ipcModule.appendUint(response, src.width);
+        m_ipcModule.appendUint(response, src.height);
+        m_ipcModule.appendUint(response, layer->OriginalSourceWidth);
+        m_ipcModule.appendUint(response, layer->OriginalSourceHeight);
+        m_ipcModule.appendUint(response, dest.x);
+        m_ipcModule.appendUint(response, dest.y);
+        m_ipcModule.appendUint(response, dest.width);
+        m_ipcModule.appendUint(response, dest.height);
+        m_ipcModule.appendUint(response, orientation);
+        m_ipcModule.appendBool(response, layer->getVisibility());
+        m_ipcModule.appendUint(response, layer->getLayerType());
+        m_ipcModule.appendBool(response, layer->getChromaKeyEnabled());
+        m_ipcModule.appendUint(response, chromaKeyRed);
+        m_ipcModule.appendUint(response, chromaKeyGreen);
+        m_ipcModule.appendUint(response, chromaKeyBlue);
+        m_ipcModule.appendInt(response, layer->getCreatorPid());
+    }
+    else
+    {
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
+    }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::CreateSurface(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint handle = 0;
-    m_ipcModule.getUint(&handle);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
     uint pixelformat = 0;
-    m_ipcModule.getUint(&pixelformat);
-    PixelFormat pf = (PixelFormat) pixelformat;
-
-    //LOG_DEBUG("GenericCommunicator::CreateSurface","pixelformat: " << pixelformat);
+    PixelFormat pf = PIXELFORMAT_UNKNOWN;
     uint id = GraphicalObject::INVALID_ID;
-    /* First of all create the surface */
-    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(&id));
-    /* after that apply the native content */
-    status &= m_executor->execute(new SurfaceSetNativeContentCommand(id, handle, pf, width, height));    
+
+    m_ipcModule.getUint(message, &handle);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+    m_ipcModule.getUint(message, &pixelformat);
+
+    pf = (PixelFormat) pixelformat;
+
+    // First of all create the surface
+    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(clientPid, &id));
+
+    // after that apply the native content
+    status &= m_executor->execute(new SurfaceSetNativeContentCommand(clientPid, id, handle, pf, width, height));
+
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateSurfaceFromId()
+void GenericCommunicator::CreateSurfaceFromId(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint handle = 0;
-    m_ipcModule.getUint(&handle);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
     uint pixelformat = 0;
-    m_ipcModule.getUint(&pixelformat);
-    PixelFormat pf = (PixelFormat) pixelformat;
-
-    //LOG_DEBUG("GenericCommunicator::CreateSurface","pixelformat: " << pixelformat);
+    PixelFormat pf = PIXELFORMAT_UNKNOWN;
     uint id = 0;
-    m_ipcModule.getUint(&id);
+
+    m_ipcModule.getUint(message, &handle);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+    m_ipcModule.getUint(message, &pixelformat);
+    m_ipcModule.getUint(message, &id);
+
+    pf = (PixelFormat) pixelformat;
 
     // First of all create the surface
-    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(&id));
+    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(clientPid, &id));
+
     // after that apply the native content
-    status &= m_executor->execute(new SurfaceSetNativeContentCommand(id, handle, pf, width, height));    
+    status &= m_executor->execute(new SurfaceSetNativeContentCommand(clientPid, id, handle, pf, width, height));
 
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::InitializeSurface()
+void GenericCommunicator::InitializeSurface(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = GraphicalObject::INVALID_ID;
 
-    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(&id));
+    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(clientPid, &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::InitializeSurfaceFromId()
+void GenericCommunicator::InitializeSurfaceFromId(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(&id));
+    m_ipcModule.getUint(message, &id);
+    t_ilm_bool status = m_executor->execute(new SurfaceCreateCommand(clientPid, &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceNativeContent()
+void GenericCommunicator::SetSurfaceNativeContent(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
     uint handle = 0;
-    m_ipcModule.getUint(&handle);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
     uint pixelformat = 0;
-    m_ipcModule.getUint(&pixelformat);
-    PixelFormat pf = (PixelFormat) pixelformat;
+    PixelFormat pf = PIXELFORMAT_UNKNOWN;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &handle);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+    m_ipcModule.getUint(message, &pixelformat);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetNativeContentCommand(id, handle, pf, width, height));
+    pf = (PixelFormat) pixelformat;
+
+    t_ilm_bool status = m_executor->execute(new SurfaceSetNativeContentCommand(clientPid, id, handle, pf, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveSurfaceNativeContent()
+void GenericCommunicator::RemoveSurfaceNativeContent(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceRemoveNativeContentCommand(id));
+    t_ilm_bool status = m_executor->execute(new SurfaceRemoveNativeContentCommand(clientPid, id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveSurface()
+void GenericCommunicator::RemoveSurface(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint param = 0;
-    m_ipcModule.getUint(&param);
-    t_ilm_bool status = m_executor->execute(new SurfaceRemoveCommand(param));
+    m_ipcModule.getUint(message, &param);
+    t_ilm_bool status = m_executor->execute(new SurfaceRemoveCommand(clientPid, param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateLayer()
+void GenericCommunicator::CreateLayer(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = GraphicalObject::INVALID_ID;
     // use resolution of default screen as default width and height of layers
     uint* resolution = m_executor->getScreenResolution(DEFAULT_SCREEN);
-    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(resolution[0], resolution[1], &id));
+    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(clientPid, resolution[0], resolution[1], &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateLayerFromId()
+void GenericCommunicator::CreateLayerFromId(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = GraphicalObject::INVALID_ID;
 
-    m_ipcModule.getUint(&id);
+    m_ipcModule.getUint(message, &id);
     // use resolution of default screen as default width and height of layers
     uint* resolution = m_executor->getScreenResolution(DEFAULT_SCREEN);
-    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(resolution[0], resolution[1], &id));
+    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(clientPid, resolution[0], resolution[1], &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+
+    delete [] resolution;
 }
 
 
-void GenericCommunicator::CreateLayerWithDimension()
+void GenericCommunicator::CreateLayerWithDimension(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint width = 0;
-    m_ipcModule.getUint(&width);
+    m_ipcModule.getUint(message, &width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
+    m_ipcModule.getUint(message, &height);
 
     uint id = GraphicalObject::INVALID_ID;
-    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(width, height, &id));
+    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(clientPid, width, height, &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateLayerFromIdWithDimension()
+void GenericCommunicator::CreateLayerFromIdWithDimension(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = GraphicalObject::INVALID_ID;
-
-    m_ipcModule.getUint(&id);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
-    t_ilm_bool status = m_executor->execute(new LayerCreateCommand(width, height, &id));
+    t_ilm_bool status = ILM_FALSE;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+
+    status = m_executor->execute(new LayerCreateCommand(clientPid, width, height, &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveLayer()
+void GenericCommunicator::RemoveLayer(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint param = 0;
-    m_ipcModule.getUint(&param);
-    t_ilm_bool status = m_executor->execute(new LayerRemoveCommand(param));
+    m_ipcModule.getUint(message, &param);
+    t_ilm_bool status = m_executor->execute(new LayerRemoveCommand(clientPid, param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::AddSurfaceToSurfaceGroup()
+void GenericCommunicator::AddSurfaceToLayer(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint surfaceid = 0;
-    m_ipcModule.getUint(&surfaceid);
-    uint surfacegroupid = 0;
-    m_ipcModule.getUint(&surfacegroupid);
+    uint layer = 0;
+
+    m_ipcModule.getUint(message, &surfaceid);
+    m_ipcModule.getUint(message, &layer);
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupAddSurfaceCommand(surfacegroupid, surfaceid));
+    t_ilm_bool status = m_executor->execute(new LayerAddSurfaceCommand(clientPid, layer, surfaceid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_ALREADY_INUSE);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveSurfaceFromSurfaceGroup()
+void GenericCommunicator::RemoveSurfaceFromLayer(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint surfaceid = 0;
-    m_ipcModule.getUint(&surfaceid);
-    uint surfacegroupid = 0;
-    m_ipcModule.getUint(&surfacegroupid);
+    uint layerid = 0;
+    m_ipcModule.getUint(message, &surfaceid);
+    m_ipcModule.getUint(message, &layerid);
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupRemoveSurfaceCommand(surfacegroupid, surfaceid));
+    t_ilm_bool status = m_executor->execute(new LayerRemoveSurfaceCommand(clientPid, layerid, surfaceid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::AddLayerToLayerGroup()
+void GenericCommunicator::SetSurfaceSourceRegion(t_ilm_message message)
 {
-    uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
-    uint layergroupid = 0;
-    m_ipcModule.getUint(&layergroupid);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
+    uint width = 0;
+    uint height = 0;
 
-    t_ilm_bool status = m_executor->execute(new LayergroupAddLayerCommand(layergroupid, layerid));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+
+    t_ilm_bool status = m_executor->execute(new SurfaceSetSourceRectangleCommand(clientPid, id, x, y, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveLayerFromLayerGroup()
+void GenericCommunicator::SetLayerSourceRegion(t_ilm_message message)
 {
-    uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
-    uint layergroupid = 0;
-    m_ipcModule.getUint(&layergroupid);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
+    uint width = 0;
+    uint height = 0;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
 
-    t_ilm_bool status = m_executor->execute(new LayergroupRemoveLayerCommand(layergroupid, layerid));
+    t_ilm_bool status = m_executor->execute(new LayerSetSourceRectangleCommand(clientPid, id, x, y, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::AddSurfaceToLayer()
+void GenericCommunicator::SetSurfaceDestinationRegion(t_ilm_message message)
 {
-    uint surfaceid = 0;
-    m_ipcModule.getUint(&surfaceid);
-    uint layer = 0;
-    m_ipcModule.getUint(&layer);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
+    uint width = 0;
+    uint height = 0;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
 
-    t_ilm_bool status = m_executor->execute(new LayerAddSurfaceCommand(layer, surfaceid));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetDestinationRectangleCommand(clientPid, id, x, y, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveSurfaceFromLayer()
+void GenericCommunicator::SetSurfacePosition(t_ilm_message message)
 {
-    uint surfaceid = 0;
-    m_ipcModule.getUint(&surfaceid);
-    uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
 
-    t_ilm_bool status = m_executor->execute(new LayerRemoveSurfaceCommand(layerid, surfaceid));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
+
+    t_ilm_bool status = m_executor->execute(new SurfaceSetPositionCommand(clientPid, id, x, y));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateSurfaceGroup()
+void GenericCommunicator::GetSurfacePosition(t_ilm_message message)
 {
-    uint newID = GraphicalObject::INVALID_ID;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupCreateCommand(&newID));
+    m_ipcModule.getUint(message, &id);
+
+    t_ilm_bool status = m_executor->execute(new SurfaceGetPositionCommand(clientPid, id, &x, &y));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(newID);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, x);
+        m_ipcModule.appendUint(response, y);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateSurfaceGroupFromId()
+void GenericCommunicator::SetSurfaceDimension(t_ilm_message message)
 {
-    uint newID = GraphicalObject::INVALID_ID;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint width = 0;
+    uint height = 0;
 
-    m_ipcModule.getUint(&newID);
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupCreateCommand(&newID));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetDimensionCommand(clientPid, id, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(newID);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveSurfaceGroup()
+void GenericCommunicator::SetLayerDestinationRegion(t_ilm_message message)
 {
-    uint param = 0;
-    m_ipcModule.getUint(&param);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
+    uint width = 0;
+    uint height = 0;
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupRemoveCommand(param));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+
+    t_ilm_bool status = m_executor->execute(new LayerSetDestinationRectangleCommand(clientPid, id, x, y, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateLayerGroup()
+void GenericCommunicator::SetLayerPosition(t_ilm_message message)
 {
-    uint newID = GraphicalObject::INVALID_ID;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &x);
+    m_ipcModule.getUint(message, &y);
 
-    t_ilm_bool status = m_executor->execute(new LayergroupCreateCommand(&newID));
+    t_ilm_bool status = m_executor->execute(new LayerSetPositionCommand(clientPid, id, x, y));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(newID);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateLayerGroupFromId()
+void GenericCommunicator::GetLayerPosition(t_ilm_message message)
 {
-    uint newID = GraphicalObject::INVALID_ID;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint x = 0;
+    uint y = 0;
 
-    m_ipcModule.getUint(&newID);
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new LayergroupCreateCommand(&newID));
+    t_ilm_bool status = m_executor->execute(new LayerGetPositionCommand(clientPid, id, &x, &y));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(newID);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, x);
+        m_ipcModule.appendUint(response, y);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_ALREADY_INUSE);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::RemoveLayerGroup()
+void GenericCommunicator::SetLayerDimension(t_ilm_message message)
 {
-    uint param = 0;
-    m_ipcModule.getUint(&param);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint id = 0;
+    uint width = 0;
+    uint height = 0;
 
-    t_ilm_bool status = m_executor->execute(new LayergroupRemoveCommand(param));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &width);
+    m_ipcModule.getUint(message, &height);
+
+    t_ilm_bool status = m_executor->execute(new LayerSetDimensionCommand(clientPid, id, width, height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceSourceRegion()
+void GenericCommunicator::GetLayerDimension(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetSourceRectangleCommand(id, x, y, width, height));
+    m_ipcModule.getUint(message, &id);
+
+    t_ilm_bool status = m_executor->execute(new LayerGetDimensionCommand(clientPid, id, &width, &height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, width);
+        m_ipcModule.appendUint(response, height);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerSourceRegion()
+void GenericCommunicator::GetSurfaceDimension(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
     uint width = 0;
-    m_ipcModule.getUint(&width);
     uint height = 0;
-    m_ipcModule.getUint(&height);
 
-    //LOG_DEBUG("DBUSC","new SetSourceRectangleCommand with arguments: " <<id <<" " << x <<" "<< y <<" "<< width <<" "<< height );
-    t_ilm_bool status = m_executor->execute(new LayerSetSourceRectangleCommand(id, x, y, width, height));
+    m_ipcModule.getUint(message, &id);
+
+    t_ilm_bool status = m_executor->execute(new SurfaceGetDimensionCommand(clientPid, id, &width, &height));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, width);
+        m_ipcModule.appendUint(response, height);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceDestinationRegion()
+void GenericCommunicator::SetSurfaceOpacity(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
-    uint width = 0;
-    m_ipcModule.getUint(&width);
-    uint height = 0;
-    m_ipcModule.getUint(&height);
+    double param = 0.0;
+
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getDouble(message, &param);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetDestinationRectangleCommand(id, x, y, width, height));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetOpacityCommand(clientPid, id, param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfacePosition()
+void GenericCommunicator::SetLayerOpacity(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
+    double param = 0.0;
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetPositionCommand(id, x, y));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getDouble(message, &param);
+
+    t_ilm_bool status = m_executor->execute(new LayerSetOpacityCommand(clientPid, id, param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfacePosition()
+void GenericCommunicator::GetSurfaceOpacity(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    uint y = 0;
+    double param = 0.0;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetPositionCommand(id, &x, &y));
+    t_ilm_bool status = m_executor->execute(new SurfaceGetOpacityCommand(clientPid, id, &param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(x);
-        m_ipcModule.appendUint(y);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendDouble(response, param);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceDimension()
+void GenericCommunicator::GetLayerOpacity(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint width = 0;
-    m_ipcModule.getUint(&width);
-    uint height = 0;
-    m_ipcModule.getUint(&height);
+    double param = 0.0;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetDimensionCommand(id, width, height));
+    t_ilm_bool status = m_executor->execute(new LayerGetOpacityCommand(clientPid, id, &param));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendDouble(response, param);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerDestinationRegion()
+void GenericCommunicator::SetSurfaceOrientation(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
-    uint width = 0;
-    m_ipcModule.getUint(&width);
-    uint height = 0;
-    m_ipcModule.getUint(&height);
+    uint param = 0;
+    OrientationType o = Zero;
 
-    t_ilm_bool status = m_executor->execute(new LayerSetDestinationRectangleCommand(id, x, y, width, height));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &param);
+
+    o = (OrientationType) param;
+
+    t_ilm_bool status = m_executor->execute(new SurfaceSetOrientationCommand(clientPid, id, o));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerPosition()
+void GenericCommunicator::GetSurfaceOrientation(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    m_ipcModule.getUint(&x);
-    uint y = 0;
-    m_ipcModule.getUint(&y);
+    OrientationType o;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new LayerSetPositionCommand(id, x, y));
+    t_ilm_bool status = m_executor->execute(new SurfaceGetOrientationCommand(clientPid, id, &o));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, o);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerPosition()
+void GenericCommunicator::SetLayerOrientation(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint x = 0;
-    uint y = 0;
+    uint param = 0;
+    OrientationType o = Zero;
 
-    t_ilm_bool status = m_executor->execute(new LayerGetPositionCommand(id, &x, &y));
+    m_ipcModule.getUint(message, &id);
+    m_ipcModule.getUint(message, &param);
+
+    o = (OrientationType) param;
+
+    t_ilm_bool status = m_executor->execute(new LayerSetOrientationCommand(clientPid, id, o));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(x);
-        m_ipcModule.appendUint(y);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerDimension()
+void GenericCommunicator::GetLayerOrientation(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint width = 0;
-    m_ipcModule.getUint(&width);
-    uint height = 0;
-    m_ipcModule.getUint(&height);
+    OrientationType o;
 
-    t_ilm_bool status = m_executor->execute(new LayerSetDimensionCommand(id, width, height));
+    m_ipcModule.getUint(message, &id);
+
+    t_ilm_bool status = m_executor->execute(new LayerGetOrientationCommand(clientPid, id, &o));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, o);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerDimension()
+void GenericCommunicator::GetSurfacePixelformat(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint width = 0;
-    uint height = 0;
+    PixelFormat pixelFormat = (PixelFormat)ILM_PIXEL_FORMAT_UNKNOWN;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new LayerGetDimensionCommand(id, &width, &height));
+    t_ilm_bool status = m_executor->execute(new SurfaceGetPixelformatCommand(clientPid, id, &pixelFormat));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(width);
-        m_ipcModule.appendUint(height);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, pixelFormat);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfaceDimension()
+void GenericCommunicator::SetSurfaceVisibility(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint width = 0;
-    uint height = 0;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint surfaceid = 0;
+    t_ilm_bool newVis = ILM_FALSE;
+
+    m_ipcModule.getUint(message, &surfaceid);
+    m_ipcModule.getBool(message, &newVis);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetDimensionCommand(id, &width, &height));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetVisibilityCommand(clientPid, surfaceid, newVis));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(width);
-        m_ipcModule.appendUint(height);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceOpacity()
+void GenericCommunicator::SetLayerVisibility(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
-    m_ipcModule.getDouble(&param);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint layerid = 0;
+    t_ilm_bool myparam = ILM_FALSE;
+
+    m_ipcModule.getUint(message, &layerid);
+    m_ipcModule.getBool(message, &myparam);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetOpacityCommand(id, param));
+    t_ilm_bool status = m_executor->execute(new LayerSetVisibilityCommand(clientPid, layerid, myparam));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerOpacity()
+void GenericCommunicator::GetSurfaceVisibility(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
-    m_ipcModule.getDouble(&param);
+    bool visibility = false;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new LayerSetOpacityCommand(id, param));
+    t_ilm_bool status = m_executor->execute(new SurfaceGetVisibilityCommand(clientPid, id, &visibility));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendBool(response, visibility);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfacegroupOpacity()
+void GenericCommunicator::GetLayerVisibility(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
-    m_ipcModule.getDouble(&param);
+    bool visibility = false;
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupSetOpacityCommand(id, param));
+    m_ipcModule.getUint(message, &id);
+
+    t_ilm_bool status = m_executor->execute(new LayerGetVisibilityCommand(clientPid, id, &visibility));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendBool(response, visibility);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayergroupOpacity()
+void GenericCommunicator::SetSynchronizedSurfaces(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
-    m_ipcModule.getDouble(&param);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
 
-    t_ilm_bool status = m_executor->execute(new LayergroupSetOpacityCommand(id, param));
+    // ipcArray was created in ipcModule using malloc (it's implemented C)
+    // so we copy it to a buffer created with new() and discard
+    // the ipcArray using free() to avoid memory corruption
+    uint* ipcArray = NULL;
+    uint* array = NULL;
+    int length = 0;
+    m_ipcModule.getUintArray(message, &ipcArray, &length);
+    array = new uint[length];
+    memset(array, 0, length * sizeof(uint));
+    memcpy(array, ipcArray, length * sizeof(uint));
+    free(ipcArray);
+
+    t_ilm_bool status = m_executor->execute(new SetSynchronizedSurfacesCommand(clientPid, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfaceOpacity()
+void GenericCommunicator::RemoveSynchronizedSurfaces(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetOpacityCommand(id, &param));
+    // ipcArray was created in ipcModule using malloc (it's implemented C)
+    // so we copy it to a buffer created with new() and discard
+    // the ipcArray using free() to avoid memory corruption
+    uint* ipcArray = NULL;
+    uint* array = NULL;
+    int length = 0;
+    m_ipcModule.getUintArray(message, &ipcArray, &length);
+    array = new uint[length];
+    memset(array, 0, length * sizeof(uint));
+    memcpy(array, ipcArray, length * sizeof(uint));
+    free(ipcArray);
+
+    t_ilm_bool status = m_executor->execute(new RemoveSynchronizedSurfacesCommand(clientPid, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendDouble(param);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerOpacity()
+void GenericCommunicator::SetRenderOrderOfLayers(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    double param = 0.0;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+
+    // ipcArray was created in ipcModule using malloc (it's implemented C)
+    // so we copy it to a buffer created with new() and discard
+    // the ipcArray using free() to avoid memory corruption
+    uint* ipcArray = NULL;
+    uint* array = NULL;
+    int length = 0;
+    m_ipcModule.getUintArray(message, &ipcArray, &length);
+    array = new uint[length];
+    memset(array, 0, length * sizeof(uint));
+    memcpy(array, ipcArray, length * sizeof(uint));
+    free(ipcArray);
+
+    uint screenID = 0;
+
+    m_ipcModule.getUint(message, &screenID);
 
-    t_ilm_bool status = m_executor->execute(new LayerGetOpacityCommand(id, &param));
+    t_ilm_bool status = m_executor->execute(new ScreenSetRenderOrderCommand(clientPid, screenID, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendDouble(param);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceOrientation()
+void GenericCommunicator::SetSurfaceRenderOrderWithinLayer(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint param = 0;
-    m_ipcModule.getUint(&param);
-    OrientationType o = (OrientationType) param;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetOrientationCommand(id, o));
+    uint layerid = 0;
+    m_ipcModule.getUint(message, &layerid);
+
+    // ipcArray was created in ipcModule using malloc (it's implemented C)
+    // so we copy it to a buffer created with new() and discard
+    // the ipcArray using free() to avoid memory corruption
+    uint* ipcArray = NULL;
+    uint* array = NULL;
+    int length = 0;
+    m_ipcModule.getUintArray(message, &ipcArray, &length);
+    array = new uint[length];
+    memset(array, 0, length * sizeof(uint));
+    memcpy(array, ipcArray, length * sizeof(uint));
+    free(ipcArray);
+
+    t_ilm_bool status = m_executor->execute(new LayerSetRenderOrderCommand(clientPid, layerid, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfaceOrientation()
+void GenericCommunicator::GetLayerType(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    OrientationType o;
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetOrientationCommand(id, &o));
-    if (status)
+    Layer* layer = m_executor->getScene()->getLayer(id);
+    if (layer)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(o);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, layer->getLayerType());
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerOrientation()
+void GenericCommunicator::GetLayertypeCapabilities(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    uint param = 0;
-    m_ipcModule.getUint(&param);
-    OrientationType o = (OrientationType) param;
+    LayerType type = Unknown;
 
-    t_ilm_bool status = m_executor->execute(new LayerSetOrientationCommand(id, o));
-    if (status)
+    m_ipcModule.getUint(message, &id);
+
+    type = (LayerType) id;
+
+    uint capabilities = m_executor->getLayerTypeCapabilities(type);
+    response = m_ipcModule.createResponse(message);
+    m_ipcModule.appendUint(response, capabilities);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::GetLayerCapabilities(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    uint id = 0;
+    m_ipcModule.getUint(message, &id);
+
+    Layer* layer = m_executor->getScene()->getLayer(id);
+    if (layer)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, layer->getCapabilities());
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerOrientation()
+void GenericCommunicator::FadeIn(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    OrientationType o;
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    response = m_ipcModule.createErrorResponse(message);
+    m_ipcModule.appendUint(response, ILM_ERROR_NOT_IMPLEMENTED);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
 
-    t_ilm_bool status = m_executor->execute(new LayerGetOrientationCommand(id, &o));
+void GenericCommunicator::SynchronizedFade(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    response = m_ipcModule.createErrorResponse(message);
+    m_ipcModule.appendUint(response, ILM_ERROR_NOT_IMPLEMENTED);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::FadeOut(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    response = m_ipcModule.createErrorResponse(message);
+    m_ipcModule.appendUint(response, ILM_ERROR_NOT_IMPLEMENTED);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::Exit(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    t_ilm_bool status = m_executor->execute(new ExitCommand(clientPid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(o);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfacePixelformat()
+void GenericCommunicator::CommitChanges(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    t_ilm_bool status = m_executor->execute(new CommitCommand(clientPid));
+    if (status)
+    {
+        response = m_ipcModule.createResponse(message);
+    }
+    else
+    {
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
+    }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
+
+void GenericCommunicator::CreateShader(t_ilm_message message)
+{
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    char vertname[1024];
+    char fragname[1024];
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    PixelFormat param;
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetPixelformatCommand(id, &param));
+    m_ipcModule.getString(message, vertname);
+    m_ipcModule.getString(message, fragname);
+
+    t_ilm_bool status = m_executor->execute(new ShaderCreateCommand(clientPid, vertname, fragname, &id));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(param);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, id);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceVisibility()
+void GenericCommunicator::DestroyShader(t_ilm_message message)
 {
-    uint surfaceid = 0;
-    m_ipcModule.getUint(&surfaceid);
-    t_ilm_bool newVis = ILM_FALSE;
-    m_ipcModule.getBool(&newVis);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint shaderid = 0;
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetVisibilityCommand(surfaceid, newVis));
+    m_ipcModule.getUint(message, &shaderid);
+
+    t_ilm_bool status = m_executor->execute(new ShaderDestroyCommand(clientPid, shaderid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayerVisibility()
+void GenericCommunicator::SetShader(t_ilm_message message)
 {
-    uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
-    t_ilm_bool myparam = ILM_FALSE;
-    m_ipcModule.getBool(&myparam);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint surfaceId = 0;
+    uint shaderid = 0;
+
+    m_ipcModule.getUint(message, &surfaceId);
+    m_ipcModule.getUint(message, &shaderid);
 
-    t_ilm_bool status = m_executor->execute(new LayerSetVisibilityCommand(layerid, myparam));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetShaderCommand(clientPid, surfaceId, shaderid));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetSurfaceVisibility()
+void GenericCommunicator::SetUniforms(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint id = 0;
-    m_ipcModule.getUint(&id);
-    bool param;
+    std::vector<string> uniforms;
+
+    m_ipcModule.getUint(message, &id);
 
-    t_ilm_bool status = m_executor->execute(new SurfaceGetVisibilityCommand(id, &param));
+    // TODO
+    //m_ipcModule.getStringArray(&uniforms);
+
+    t_ilm_bool status = m_executor->execute(new ShaderSetUniformsCommand(clientPid, id, uniforms));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        //LOG_DEBUG("GenericCommunicator", "returning surfacevisibility: " << param);
-        m_ipcModule.appendBool(param);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerVisibility()
+void GenericCommunicator::SetKeyboardFocusOn(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    bool param;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    t_ilm_message response;
+    uint surfaceId = 0;
 
-    t_ilm_bool status = m_executor->execute(new LayerGetVisibilityCommand(id, &param));
+    m_ipcModule.getUint(message, &surfaceId);
+
+    t_ilm_bool status = m_executor->execute(new SurfaceSetKeyboardFocusCommand(clientPid, surfaceId));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendBool(param);
-        //LOG_DEBUG("GenericCommunicator", "returning layervisibility: " << param);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfacegroupVisibility()
+
+void GenericCommunicator::GetKeyboardFocusSurfaceId(t_ilm_message message)
 {
-    uint groupid = 0;
-    m_ipcModule.getUint(&groupid);
-    t_ilm_bool myparam = ILM_FALSE;
-    m_ipcModule.getBool(&myparam);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    uint surfaceId;
 
-    t_ilm_bool status = m_executor->execute(new SurfacegroupSetVisibilityCommand(groupid, myparam));
+    t_ilm_bool status = m_executor->execute(new SurfaceGetKeyboardFocusCommand(clientPid, &surfaceId));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, surfaceId);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetLayergroupVisibility()
+
+void GenericCommunicator::UpdateInputEventAcceptanceOn(t_ilm_message message)
 {
-    uint groupid = 0;
-    m_ipcModule.getUint(&groupid);
-    t_ilm_bool myparam = ILM_FALSE;
-    m_ipcModule.getBool(&myparam);
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    t_ilm_message response;
+    uint surfaceId = 0;
+    uint udevices = 0;
+    InputDevice devices;
+    t_ilm_bool accept;
+
+    m_ipcModule.getUint(message, &surfaceId);
+    m_ipcModule.getUint(message, &udevices);
+    m_ipcModule.getBool(message, &accept);
 
-    t_ilm_bool status = m_executor->execute(new LayergroupSetVisibilityCommand(groupid, myparam));
+    devices = (InputDevice) udevices;
+
+    t_ilm_bool status = m_executor->execute(new SurfaceUpdateInputEventAcceptance(clientPid, surfaceId, devices, accept));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
-}
 
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
+}
 
-void GenericCommunicator::SetRenderOrderOfLayers()
+void GenericCommunicator::SetSurfaceChromaKey(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint* array = NULL;
     int length = 0;
+    uint surfaceid = 0;
 
-    m_ipcModule.getUintArray(&array, &length);
-
-    //LOG_DEBUG("GenericCommunicator","Renderorder: Got " << length << " ids.");
+    m_ipcModule.getUint(message, &surfaceid);
+    m_ipcModule.getUintArray(message, &array, &length);
 
-    t_ilm_bool status = m_executor->execute(new ScreenSetRenderOrderCommand(array, length));
+    t_ilm_bool status = m_executor->execute(new SurfaceSetChromaKeyCommand(clientPid, surfaceid, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetSurfaceRenderOrderWithinLayer()
+void GenericCommunicator::SetLayerChromaKey(t_ilm_message message)
 {
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
     uint* array = NULL;
     int length = 0;
-
     uint layerid = 0;
-    m_ipcModule.getUint(&layerid);
 
-    m_ipcModule.getUintArray(&array, &length);
+    m_ipcModule.getUint(message, &layerid);
+    m_ipcModule.getUintArray(message, &array, &length);
 
-    t_ilm_bool status = m_executor->execute(new LayerSetRenderOrderCommand(layerid, array, length));
+    t_ilm_bool status = m_executor->execute(new LayerSetChromaKeyCommand(clientPid, layerid, array, length));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerType()
+void GenericCommunicator::LayerAddNotification(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    Layer* l = m_executor->getScene()->getLayer(id);
-    if (l != NULL)
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    uint layerid = 0;
+
+    m_ipcModule.getUint(message, &layerid);
+
+    Layer* layer = m_executor->getScene()->getLayer(layerid);
+    if (layer)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(l->getLayerType());
-        m_ipcModule.sendMessage();
+        layer->addNotification(clientHandle);
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
-}
 
-void GenericCommunicator::GetLayertypeCapabilities()
-{
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    LayerType type = (LayerType) id;
-    uint capabilities = m_executor->getLayerTypeCapabilities(type);
-    //LOG_DEBUG("GenericCommunicator", "GetLayertypeCapabilities: returning capabilities:" << capabilities);
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.appendUint(capabilities);
-    m_ipcModule.sendMessage();
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::GetLayerCapabilities()
+void GenericCommunicator::SurfaceAddNotification(t_ilm_message message)
 {
-    uint id = 0;
-    m_ipcModule.getUint(&id);
-    Layer* l = m_executor->getScene()->getLayer(id);
-    if (l != NULL)
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    uint surfaceid = 0;
+
+    m_ipcModule.getUint(message, &surfaceid);
+
+    Surface* surface = m_executor->getScene()->getSurface(surfaceid);
+    if (surface)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(l->getCapabilities());
-        m_ipcModule.sendMessage();
+        surface->addNotification(clientHandle);
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
-}
 
-void GenericCommunicator::FadeIn()
-{
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.sendMessage();
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SynchronizedFade()
+void GenericCommunicator::LayerRemoveNotification(t_ilm_message message)
 {
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.sendMessage();
-}
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    uint layerid = 0;
 
-void GenericCommunicator::FadeOut()
-{
-    m_ipcModule.createMessage((char*)__FUNCTION__);
-    m_ipcModule.sendMessage();
-}
+    m_ipcModule.getUint(message, &layerid);
 
-void GenericCommunicator::Exit()
-{
-    t_ilm_bool status = m_executor->execute(new ExitCommand());
-    if (status)
+    Layer* layer = m_executor->getScene()->getLayer(layerid);
+    if (layer)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        layer->removeNotification(clientHandle);
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(INVALID_ARGUMENT);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CommitChanges()
+void GenericCommunicator::SurfaceRemoveNotification(t_ilm_message message)
 {
-    t_ilm_bool status = m_executor->execute(new CommitCommand());
-    if (status)
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_message response;
+    uint surfaceid = 0;
+
+    m_ipcModule.getUint(message, &surfaceid);
+
+    Surface* surface = m_executor->getScene()->getSurface(surfaceid);
+    if (surface)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        surface->removeNotification(clientHandle);
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(INVALID_ARGUMENT);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_INVALID_ARGUMENTS);
     }
+
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::CreateShader()
+void GenericCommunicator::processNotificationQueue()
 {
-    char* vertname = NULL;
-    m_ipcModule.getString(vertname);
-    char* fragname = NULL;
-    m_ipcModule.getString(fragname);
-    uint id = 0;
+    NotificationQueue& notificationQueue = m_executor->getClientNotificationQueue();
+    NotificationQueue::iterator iter = notificationQueue.begin();
+    NotificationQueue::iterator end = notificationQueue.end();
 
-    t_ilm_bool status = m_executor->execute(new ShaderCreateCommand(vertname, fragname, &id));
-    if (status)
+    for (; iter != end; ++iter)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.appendUint(id);
-        m_ipcModule.sendMessage();
+        GraphicalObject* object = iter->first;
+        t_ilm_notification_mask mask = iter->second;
+        sendNotification(object, mask);
     }
-    else
+    notificationQueue.clear();
+}
+
+void GenericCommunicator::sendNotification(GraphicalObject* object, t_ilm_notification_mask mask)
+{
+    switch (object->type)
+    {
+    case TypeLayer:
+        {
+            Layer* layer = static_cast<Layer*>(object);
+            if (layer)
+            {
+                ApplicationReferenceList& arl = layer->getNotificationClients();
+
+                if (arl.size())
+                {
+                    t_ilm_message notification;
+                    Rectangle dest = layer->getDestinationRegion();
+                    Rectangle src = layer->getSourceRegion();
+                    OrientationType orientation = layer->getOrientation();
+
+                    unsigned char chromaKeyRed = 0;
+                    unsigned char chromaKeyGreen = 0;
+                    unsigned char chromaKeyBlue = 0;
+                    layer->getChromaKey(chromaKeyRed, chromaKeyGreen, chromaKeyBlue);
+
+                    std::stringstream notificationName;
+                    notificationName << "NotificationForLayer" << layer->getID();
+
+                    notification = m_ipcModule.createNotification(notificationName.str().c_str());
+                    m_ipcModule.appendUint(notification, layer->getID());
+                    m_ipcModule.appendUint(notification, mask);
+
+                    m_ipcModule.appendDouble(notification, layer->getOpacity());
+                    m_ipcModule.appendUint(notification, src.x);
+                    m_ipcModule.appendUint(notification, src.y);
+                    m_ipcModule.appendUint(notification, src.width);
+                    m_ipcModule.appendUint(notification, src.height);
+                    m_ipcModule.appendUint(notification, layer->OriginalSourceWidth);
+                    m_ipcModule.appendUint(notification, layer->OriginalSourceHeight);
+                    m_ipcModule.appendUint(notification, dest.x);
+                    m_ipcModule.appendUint(notification, dest.y);
+                    m_ipcModule.appendUint(notification, dest.width);
+                    m_ipcModule.appendUint(notification, dest.height);
+                    m_ipcModule.appendUint(notification, orientation);
+                    m_ipcModule.appendBool(notification, layer->getVisibility());
+                    m_ipcModule.appendUint(notification, layer->getLayerType());
+                    m_ipcModule.appendBool(notification, layer->getChromaKeyEnabled());
+                    m_ipcModule.appendUint(notification, chromaKeyRed);
+                    m_ipcModule.appendUint(notification, chromaKeyGreen);
+                    m_ipcModule.appendUint(notification, chromaKeyBlue);
+                    m_ipcModule.appendInt(notification, layer->getCreatorPid());
+
+                    int clientCount = arl.size();
+                    t_ilm_client_handle clientArray[256];
+
+                    ApplicationReferenceList::iterator iter = arl.begin();
+                    ApplicationReferenceList::iterator end = arl.end();
+
+                    for (int clientNumber = 0;
+                            iter != end, clientNumber < 256;
+                            ++iter, ++clientNumber)
+                    {
+                        t_ilm_client_handle client = *iter;
+                        clientArray[clientNumber] = client;
+                    }
+
+                    LOG_DEBUG("GenericCommunicator", "Sending " << clientCount << " notification(s): layer " << layer->getID() << " was updated.");
+
+                    if (!m_ipcModule.sendToClients(notification, clientArray, clientCount))
+                    {
+                        LOG_ERROR("GenericCommunicator", "Sending notification to clients failed.")
+                    }
+
+                    m_ipcModule.destroyMessage(notification);
+                }
+            }
+        }
+        break;
+    case TypeSurface:
+        {
+            Surface* surface = static_cast<Surface*>(object);
+            if (surface)
+            {
+                ApplicationReferenceList& arl = surface->getNotificationClients();
+
+                if (arl.size())
+                {
+                    t_ilm_message notification;
+                    std::stringstream notificationName;
+                    notificationName << "NotificationForSurface" << surface->getID();
+
+                    unsigned char chromaKeyRed = 0;
+                    unsigned char chromaKeyGreen = 0;
+                    unsigned char chromaKeyBlue = 0;
+                    surface->getChromaKey(chromaKeyRed, chromaKeyGreen, chromaKeyBlue);
+
+                    notification = m_ipcModule.createNotification(notificationName.str().c_str());
+                    m_ipcModule.appendUint(notification, surface->getID());
+                    m_ipcModule.appendUint(notification, mask);
+
+                    m_ipcModule.appendDouble(notification, surface->getOpacity());
+                    m_ipcModule.appendUint(notification, surface->getSourceRegion().x);
+                    m_ipcModule.appendUint(notification, surface->getSourceRegion().y);
+                    m_ipcModule.appendUint(notification, surface->getSourceRegion().width);
+                    m_ipcModule.appendUint(notification, surface->getSourceRegion().height);
+                    m_ipcModule.appendUint(notification, surface->OriginalSourceWidth);
+                    m_ipcModule.appendUint(notification, surface->OriginalSourceHeight);
+                    m_ipcModule.appendUint(notification, surface->getDestinationRegion().x);
+                    m_ipcModule.appendUint(notification, surface->getDestinationRegion().y);
+                    m_ipcModule.appendUint(notification, surface->getDestinationRegion().width);
+                    m_ipcModule.appendUint(notification, surface->getDestinationRegion().height);
+                    m_ipcModule.appendUint(notification, surface->getOrientation());
+                    m_ipcModule.appendBool(notification, surface->getVisibility());
+                    m_ipcModule.appendUint(notification, surface->frameCounter);
+                    m_ipcModule.appendUint(notification, surface->drawCounter);
+                    m_ipcModule.appendUint(notification, surface->updateCounter);
+                    m_ipcModule.appendUint(notification, surface->getPixelFormat());
+                    m_ipcModule.appendUint(notification, surface->getNativeContent());
+                    m_ipcModule.appendUint(notification, surface->getInputEventAcceptanceOnDevices());
+                    m_ipcModule.appendBool(notification, surface->getChromaKeyEnabled());
+                    m_ipcModule.appendUint(notification, chromaKeyRed);
+                    m_ipcModule.appendUint(notification, chromaKeyGreen);
+                    m_ipcModule.appendUint(notification, chromaKeyBlue);
+                    m_ipcModule.appendInt(notification, surface->getCreatorPid());
+
+                    int clientCount = arl.size();
+                    t_ilm_client_handle clients[256];
+
+                    ApplicationReferenceList::iterator iter = arl.begin();
+                    ApplicationReferenceList::iterator end = arl.end();
+
+                    for (int clientNumber = 0;
+                            iter != end, clientNumber < 256;
+                            ++iter, ++clientNumber)
+                    {
+                        clients[clientNumber] = *iter;
+                    }
+
+                    LOG_DEBUG("GenericCommunicator", "Sending " << clientCount << " notification(s): surface " << surface->getID() << " was updated.");
+
+                    if (!m_ipcModule.sendToClients(notification, clients, clientCount))
+                    {
+                        LOG_ERROR("GenericCommunicator", "Sending notification to clients failed.")
+                    }
+
+                    m_ipcModule.destroyMessage(notification);
+                }
+            }
+        }
+        break;
+    default:
+        LOG_INFO("GenericCommunicator", "Unknown notification found in queue.");
+        break;
+    }
+}
+
+HealthCondition GenericCommunicator::pluginGetHealth()
+{
+    HealthCondition health = PluginBase::pluginGetHealth();
+    if (0 != pthread_kill(mThreadId, 0))
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        health = HealthDead;
     }
+    return health;
 }
 
-void GenericCommunicator::DestroyShader()
+void GenericCommunicator::SetOptimizationMode(t_ilm_message message)
 {
-    uint shaderid = 0;
-    m_ipcModule.getUint(&shaderid);
+    t_ilm_message response;
+    OptimizationType optimizationId;
+    OptimizationModeType optimizationMode;
+    unsigned int optMode;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+
+    m_ipcModule.getUint(message, &optMode);
+    optimizationId = (OptimizationType)optMode;
+    m_ipcModule.getUint(message, &optMode);
+    optimizationMode = (OptimizationModeType)optMode;
 
-    t_ilm_bool status = m_executor->execute(new ShaderDestroyCommand(shaderid));
+    t_ilm_bool status = m_executor->execute(new SetOptimizationModeCommand(clientPid, optimizationId, optimizationMode));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetShader()
+void GenericCommunicator::GetOptimizationMode(t_ilm_message message)
 {
-    uint surfaceId = 0;
-    uint shaderid = 0;
-    m_ipcModule.getUint(&surfaceId);
-    m_ipcModule.getUint(&shaderid);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    t_ilm_uint clientPid = m_executor->getSenderPid(clientHandle);
+    OptimizationType optimizationId;
+    OptimizationModeType optimizationMode;
+    unsigned int o;
+
+    m_ipcModule.getUint(message, &o);
+    optimizationId = (OptimizationType)o;
 
-    t_ilm_bool status = m_executor->execute(new SurfaceSetShaderCommand(surfaceId, shaderid));
+    t_ilm_bool status = m_executor->execute(new GetOptimizationModeCommand(clientPid, optimizationId, &optimizationMode));
     if (status)
     {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUint(response, (unsigned int)optimizationMode);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-void GenericCommunicator::SetUniforms()
+void GenericCommunicator::GetPropertiesOfScreen(t_ilm_message message)
 {
-    uint id = 0; m_ipcModule.getUint(&id);
+    t_ilm_message response;
+    t_ilm_client_handle clientHandle = m_ipcModule.getSenderHandle(message);
+    uint id = 0;
+    m_ipcModule.getUint(message, &id);
 
-    std::vector<string> uniforms;
+    LmScreen* screen = m_executor->getScene()->getScreen(id);
+    if (screen != NULL)
+    {
+        LayerList renderOrder = screen->getCurrentRenderOrder();
+        std::vector<t_ilm_layer> layerIdVector;
 
-    // TODO
-    //m_ipcModule.getStringArray(&uniforms);
+        LayerListConstIterator iter = renderOrder.begin();
+        LayerListConstIterator end = renderOrder.end();
+        for (; iter != end; ++iter)
+        {
+            layerIdVector.push_back((*iter)->getID());
+        }
 
-    t_ilm_bool status = m_executor->execute(new ShaderSetUniformsCommand(id, uniforms));
-    if (status)
-    {
-        m_ipcModule.createMessage((char*)__FUNCTION__);
-        m_ipcModule.sendMessage();
+        uint numberOfHardwareLayers = m_executor->getNumberOfHardwareLayers(id);
+        uint* resolution = m_executor->getScreenResolution(id);
+
+        response = m_ipcModule.createResponse(message);
+        m_ipcModule.appendUintArray(response, layerIdVector.data(), layerIdVector.size());
+        m_ipcModule.appendUint(response, numberOfHardwareLayers);
+        m_ipcModule.appendUint(response, resolution[0]);
+        m_ipcModule.appendUint(response, resolution[1]);
     }
     else
     {
-        m_ipcModule.sendError(RESSOURCE_NOT_FOUND);
+        response = m_ipcModule.createErrorResponse(message);
+        m_ipcModule.appendUint(response, ILM_ERROR_RESOURCE_NOT_FOUND);
     }
-}
 
-extern "C" ICommunicator* createGenericCommunicator(ICommandExecutor* executor)
-{
-    return new GenericCommunicator(executor);
+    m_ipcModule.sendToClients(response, &clientHandle, 1);
+    m_ipcModule.destroyMessage(response);
 }
 
-extern "C" void destroyGenericCommunicator(GenericCommunicator* p)
-{
-    delete p;
-}
+DECLARE_LAYERMANAGEMENT_PLUGIN(GenericCommunicator)