diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0654f84ab754c777308ad2697d75f992432a25c4..dc4af8834d7a10f89877ebadc68fcd9225b2ffb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -136,7 +136,6 @@ IF (${RING_FOUND} MATCHES "true")
    INCLUDE_DIRECTORIES(${ring_INCLUDE_DIRS})
 ENDIF()
 
-
 IF(${ENABLE_VIDEO} MATCHES true)
    MESSAGE("VIDEO enabled")
    SET(ENABLE_VIDEO 1 CACHE BOOLEAN "Enable video")
@@ -246,6 +245,16 @@ SET( libringclient_LIB_SRCS
   src/extensions/presencecollectionextension.cpp
 )
 
+IF(${ENABLE_LIBWRAP} MATCHES true)
+SET(libringclient_LIB_SRCS ${libringclient_LIB_SRCS}
+  src/private/directrenderer.cpp
+)
+ELSE()
+SET(libringclient_LIB_SRCS ${libringclient_LIB_SRCS}
+  src/private/shmrenderer.cpp
+)
+ENDIF(${ENABLE_LIBWRAP} MATCHES true)
+
 # Public API
 SET( libringclient_LIB_HDRS
   src/account.h
@@ -311,6 +320,7 @@ SET(libringclient_video_LIB_HDRS
   src/video/resolution.h
   src/video/channel.h
   src/video/rate.h
+  #The renderer implementations are not exported on purpose
 )
 
 SET(libringclient_audio_LIB_HDRS
@@ -342,22 +352,9 @@ SET( libringclient_extra_LIB_HDRS
   src/typedefs.hpp
 )
 
-# Include the headers for linking directly with libDring (used on platforms
-# that don't have/use dbus.
 IF(${ENABLE_LIBWRAP} MATCHES true)
-   SET_SOURCE_FILES_PROPERTIES(
-      src/qtwrapper/presencemanager_wrap.h
-      PROPERTIES
-      CLASSNAME PresenceManagerInterface
-      INCLUDE "src/qtwrapper/metatypes.h")
-
-   SET_SOURCE_FILES_PROPERTIES(
-      src/qtwrapper/configurationmanager_wrap.h
-      PROPERTIES
-      CLASSNAME PresenceManagerInterface
-      INCLUDE "src/qtwrapper/metatypes.h")
-ELSE() # Use dbus to communicate with libDring
 
+ELSE()
    # presence manager interface
    SET ( presencemanager_xml  ${dbus_xml_introspecs_path}/presencemanager-introspec.xml )
 
@@ -450,6 +447,7 @@ SET(libringclient_PRIVATE_HDRS
    src/private/accountmodel_p.h
    src/private/phonedirectorymodel_p.h
    src/private/instantmessagingmodel_p.h
+   src/private/videorenderer_p.h
 )
 
 IF(${ENABLE_LIBWRAP} MATCHES true)
@@ -467,7 +465,7 @@ ENDIF()
 QT5_WRAP_CPP(LIB_HEADER_MOC ${libringclient_PRIVATE_HDRS})
 
 
-ADD_LIBRARY( ringclient  SHARED ${libringclient_LIB_SRCS} ${LIB_HEADER_MOC} )
+ADD_LIBRARY( ringclient SHARED ${libringclient_LIB_SRCS} ${LIB_HEADER_MOC} )
 
 IF(NOT ${ENABLE_STATIC} MATCHES false)
    ADD_LIBRARY( ringclient_static  STATIC ${libringclient_LIB_SRCS} ${LIB_HEADER_MOC} )
diff --git a/cmake/FindRing.cmake b/cmake/FindRing.cmake
index 522432638787bed4b96d3b5f46ef5345baf02877..f44506a19c30ee2683549b235599a061fc7d23eb 100644
--- a/cmake/FindRing.cmake
+++ b/cmake/FindRing.cmake
@@ -4,21 +4,20 @@
 
 SET(RING_FOUND true)
 
-IF(EXISTS ${RING_BUILD_DIR}/dring/dring.h)
-   SET(ring_INCLUDE_DIRS ${RING_BUILD_DIR}/dring)
-ELSEIF(EXISTS ${CMAKE_INSTALL_PREFIX}/include/dring/dring.h)
+IF(EXISTS ${CMAKE_INSTALL_PREFIX}/include/dring/dring.h)
    SET(ring_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include/dring)
+ELSEIF(EXISTS ${RING_BUILD_DIR}/dring/dring.h)
+   SET(ring_INCLUDE_DIRS ${RING_BUILD_DIR}/dring)
 ELSE()
    MESSAGE("Daemon header not found!
    Add -DRING_BUILD_DIR or -DCMAKE_INSTALL_PREFIX")
    SET(RING_FOUND false)
 ENDIF()
 
-
 SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so;.dll")
 FIND_LIBRARY(ring_BIN NAMES ring 
              PATHS ${RING_BUILD_DIR}/.libs 
              PATHS ${CMAKE_INSTALL_PREFIX}/libexec )
 
-MESSAGE("-- Ring daemon header is " ${ring_INCLUDE_DIRS}/dring.h)
-MESSAGE("-- Ring library path is " ${ring_BIN})
+MESSAGE("Ring daemon header is in " ${ring_INCLUDE_DIRS})
+MESSAGE("Ring library path is " ${ring_BIN})
diff --git a/src/account.cpp b/src/account.cpp
index aa0d7b45e9d9fbe46252be48e57bbce071b7b816..33db2274de6200a53b3d43232a3f14efad198d54 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -122,7 +122,7 @@ Account* AccountPrivate::buildNewAccountFromAlias(const QString& alias)
    }
    a->setHostname(a->d_ptr->m_hAccountDetails[DRing::Account::ConfProperties::HOSTNAME]);
    a->d_ptr->setAccountProperty(DRing::Account::ConfProperties::ALIAS,alias);
-   a->setObjectName(a->id());
+   //a->setObjectName(a->id());
    return a;
 }
 
@@ -929,6 +929,7 @@ bool AccountPrivate::setAccountProperty(const QString& param, const QString& val
    if (param == DRing::Account::ConfProperties::Registration::STATUS) {
       m_hAccountDetails[param] = val;
       if (accChanged) {
+         emit q_ptr->changed(q_ptr);
          emit q_ptr->propertyChanged(q_ptr,param,val,buf);
       }
    }
@@ -937,6 +938,7 @@ bool AccountPrivate::setAccountProperty(const QString& param, const QString& val
       if (m_CurrentState == Account::EditState::MODIFIED || m_CurrentState == Account::EditState::NEW) {
          m_hAccountDetails[param] = val;
          if (accChanged) {
+            emit q_ptr->changed(q_ptr);
             emit q_ptr->propertyChanged(q_ptr,param,val,buf);
          }
       }
@@ -1533,7 +1535,7 @@ void AccountPrivate::save()
       const QVector<uint> codecIdList = configurationManager.getCodecList();
       foreach (const int aCodec, codecIdList) {
          const QMap<QString,QString> codec = configurationManager.getCodecDetails(q_ptr->id(),aCodec);
-         const QModelIndex idx = m_pCodecModel->add();
+         const QModelIndex idx = q_ptr->codecModel()->add();
          /*Ring::Account::ConfProperties::CodecInfo::NAME          ; //TODO move this to CodecModel
          Ring::Account::ConfProperties::CodecInfo::TYPE          ;
          Ring::Account::ConfProperties::CodecInfo::SAMPLE_RATE   ;
diff --git a/src/accountmodel.cpp b/src/accountmodel.cpp
index f6e8ad43e914100dc3c64987bf2ddc6e590679a5..673996c2137b5b810e9d8ae7873bb622e1675286 100644
--- a/src/accountmodel.cpp
+++ b/src/accountmodel.cpp
@@ -337,6 +337,7 @@ void AccountModel::update()
          d_ptr->m_lAccounts.insert(i, a);
          emit dataChanged(index(i,0),index(size()-1,0));
          connect(a,SIGNAL(changed(Account*)),d_ptr,SLOT(slotAccountChanged(Account*)));
+         //connect(a,SIGNAL(propertyChanged(Account*,QString,QString,QString)),d_ptr,SLOT(slotAccountChanged(Account*)));
          connect(a,SIGNAL(presenceEnabledChanged(bool)),d_ptr,SLOT(slotAccountPresenceEnabledChanged(bool)));
          emit layoutChanged();
       }
@@ -354,8 +355,11 @@ void AccountModel::updateAccounts()
       Account* acc = getById(accountIds[i].toLatin1());
       if (!acc) {
          Account* a = AccountPrivate::buildExistingAccountFromId(accountIds[i].toLatin1());
+         beginInsertRows(QModelIndex(),d_ptr->m_lAccounts.size(),d_ptr->m_lAccounts.size());
          d_ptr->m_lAccounts += a;
+         endInsertRows();
          connect(a,SIGNAL(changed(Account*)),d_ptr,SLOT(slotAccountChanged(Account*)));
+         //connect(a,SIGNAL(propertyChanged(Account*,QString,QString,QString)),d_ptr,SLOT(slotAccountChanged(Account*)));
          connect(a,SIGNAL(presenceEnabledChanged(bool)),d_ptr,SLOT(slotAccountPresenceEnabledChanged(bool)));
          emit dataChanged(index(size()-1,0),index(size()-1,0));
       }
@@ -450,7 +454,7 @@ void AccountModel::cancel() {
  * Get an account by its ID
  *
  * @note This method have O(N) complexity, but the average account count is low
- * 
+ *
  * @param id The account identifier
  * @param usePlaceHolder Return a placeholder for a future account instead of nullptr
  * @return an account if it exist, a placeholder if usePlaceHolder==true or nullptr
@@ -578,8 +582,11 @@ Account* AccountModel::add(const QString& alias)
 {
    Account* a = AccountPrivate::buildNewAccountFromAlias(alias);
    connect(a,SIGNAL(changed(Account*)),d_ptr,SLOT(slotAccountChanged(Account*)));
+   beginInsertRows(QModelIndex(),d_ptr->m_lAccounts.size(),d_ptr->m_lAccounts.size());
    d_ptr->m_lAccounts += a;
+   endInsertRows();
    connect(a,SIGNAL(presenceEnabledChanged(bool)),d_ptr,SLOT(slotAccountPresenceEnabledChanged(bool)));
+   //connect(a,SIGNAL(propertyChanged(Account*,QString,QString,QString)),d_ptr,SLOT(slotAccountChanged(Account*)));
 
    emit dataChanged(index(d_ptr->m_lAccounts.size()-1,0), index(d_ptr->m_lAccounts.size()-1,0));
    return a;
@@ -591,9 +598,10 @@ void AccountModel::remove(Account* account)
    if (not account) return;
    qDebug() << "Removing" << account->alias() << account->id();
    const int aindex = d_ptr->m_lAccounts.indexOf(account);
+   beginRemoveRows(QModelIndex(),aindex,aindex);
    d_ptr->m_lAccounts.remove(aindex);
    d_ptr->m_lDeletedAccounts << account->id();
-
+   endRemoveRows();
    emit accountRemoved(account);
    emit dataChanged(index(aindex,0), index(d_ptr->m_lAccounts.size()-1,0));
    emit layoutChanged();
diff --git a/src/accountstatusmodel.cpp b/src/accountstatusmodel.cpp
index 668601d3e6d71205b069f768a99b706adc8a45fb..2f71f0c78867d192ff520380a08154d744046a9f 100644
--- a/src/accountstatusmodel.cpp
+++ b/src/accountstatusmodel.cpp
@@ -22,6 +22,7 @@
 
 //Qt
 #include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
 
 //Ring daemon
 #include <account_const.h>
@@ -137,21 +138,13 @@ static void init_statuscode()
    SET_MESSAGE(703) QObject::tr("Error sending message to destination server");
 
    //This section match to POSIX error codes
+#ifdef Q_OS_LINUX
    SET_MESSAGE(PJ_SYS_ERR + EBFONT          ) QObject::tr("Bad font file format"                             );
-   SET_MESSAGE(PJ_SYS_ERR + ENOSTR          ) QObject::tr("Device not a stream"                              );
-   SET_MESSAGE(PJ_SYS_ERR + ENODATA         ) QObject::tr("No data available"                                );
-   SET_MESSAGE(PJ_SYS_ERR + ETIME           ) QObject::tr("Timer expired"                                    );
-   SET_MESSAGE(PJ_SYS_ERR + ENOSR           ) QObject::tr("Out of streams resources"                         );
    SET_MESSAGE(PJ_SYS_ERR + ENONET          ) QObject::tr("Machine is not on the network"                    );
-   SET_MESSAGE(PJ_SYS_ERR + ENOLINK         ) QObject::tr("Link has been severed"                            );
    SET_MESSAGE(PJ_SYS_ERR + EADV            ) QObject::tr("Advertise error"                                  );
    SET_MESSAGE(PJ_SYS_ERR + ESRMNT          ) QObject::tr("Srmount error"                                    );
    SET_MESSAGE(PJ_SYS_ERR + ECOMM           ) QObject::tr("Communication error on send"                      );
-   SET_MESSAGE(PJ_SYS_ERR + EPROTO          ) QObject::tr("Protocol error"                                   );
-   SET_MESSAGE(PJ_SYS_ERR + EMULTIHOP       ) QObject::tr("Multihop attempted"                               );
    SET_MESSAGE(PJ_SYS_ERR + EDOTDOT         ) QObject::tr("RFS specific error"                               );
-   SET_MESSAGE(PJ_SYS_ERR + EBADMSG         ) QObject::tr("Not a data message"                               );
-   SET_MESSAGE(PJ_SYS_ERR + EOVERFLOW       ) QObject::tr("Value too large for defined data type"            );
    SET_MESSAGE(PJ_SYS_ERR + ENOTUNIQ        ) QObject::tr("Name not unique on network"                       );
    SET_MESSAGE(PJ_SYS_ERR + EBADFD          ) QObject::tr("File descriptor in bad state"                     );
    SET_MESSAGE(PJ_SYS_ERR + EREMCHG         ) QObject::tr("Remote address changed"                           );
@@ -159,9 +152,32 @@ static void init_statuscode()
    SET_MESSAGE(PJ_SYS_ERR + ELIBBAD         ) QObject::tr("Accessing a corrupted shared library"             );
    SET_MESSAGE(PJ_SYS_ERR + ELIBMAX         ) QObject::tr("Attempting to link in too many shared libraries"  );
    SET_MESSAGE(PJ_SYS_ERR + ELIBEXEC        ) QObject::tr("Cannot exec a shared library directly"            );
-   SET_MESSAGE(PJ_SYS_ERR + EILSEQ          ) QObject::tr("Illegal byte sequence"                            );
    SET_MESSAGE(PJ_SYS_ERR + ERESTART        ) QObject::tr("Interrupted system call should be restarted"      );
    SET_MESSAGE(PJ_SYS_ERR + ESTRPIPE        ) QObject::tr("Streams pipe error"                               );
+   SET_MESSAGE(PJ_SYS_ERR + EUCLEAN         ) QObject::tr("Structure needs cleaning"                         );
+   SET_MESSAGE(PJ_SYS_ERR + ENOTNAM         ) QObject::tr("Not a XENIX named type file"                      );
+   SET_MESSAGE(PJ_SYS_ERR + ENAVAIL         ) QObject::tr("No XENIX semaphores available"                    );
+   SET_MESSAGE(PJ_SYS_ERR + EISNAM          ) QObject::tr("Is a named type file"                             );
+   SET_MESSAGE(PJ_SYS_ERR + EREMOTEIO       ) QObject::tr("Remote I/O error"                                 );
+   SET_MESSAGE(PJ_SYS_ERR + ENOMEDIUM       ) QObject::tr("No medium found"                                  );
+   SET_MESSAGE(PJ_SYS_ERR + EMEDIUMTYPE     ) QObject::tr("Wrong medium type"                                );
+   SET_MESSAGE(PJ_SYS_ERR + ENOKEY          ) QObject::tr("Required key not available"                       );
+   SET_MESSAGE(PJ_SYS_ERR + EKEYEXPIRED     ) QObject::tr("Key has expired"                                  );
+   SET_MESSAGE(PJ_SYS_ERR + EKEYREVOKED     ) QObject::tr("Key has been revoked"                             );
+   SET_MESSAGE(PJ_SYS_ERR + EKEYREJECTED    ) QObject::tr("Key was rejected by service"                      );
+   SET_MESSAGE(PJ_SYS_ERR + EDQUOT          ) QObject::tr("Quota exceeded"                                   );
+   SET_MESSAGE(PJ_SYS_ERR + ECANCELED       ) QObject::tr("Operation Canceled"                               );
+#endif
+   SET_MESSAGE(PJ_SYS_ERR + ENOSTR          ) QObject::tr("Device not a stream"                              );
+   SET_MESSAGE(PJ_SYS_ERR + ENODATA         ) QObject::tr("No data available"                                );
+   SET_MESSAGE(PJ_SYS_ERR + ETIME           ) QObject::tr("Timer expired"                                    );
+   SET_MESSAGE(PJ_SYS_ERR + ENOSR           ) QObject::tr("Out of streams resources"                         );
+   SET_MESSAGE(PJ_SYS_ERR + ENOLINK         ) QObject::tr("Link has been severed"                            );
+   SET_MESSAGE(PJ_SYS_ERR + EPROTO          ) QObject::tr("Protocol error"                                   );
+   SET_MESSAGE(PJ_SYS_ERR + EMULTIHOP       ) QObject::tr("Multihop attempted"                               );
+   SET_MESSAGE(PJ_SYS_ERR + EBADMSG         ) QObject::tr("Not a data message"                               );
+   SET_MESSAGE(PJ_SYS_ERR + EOVERFLOW       ) QObject::tr("Value too large for defined data type"            );
+   SET_MESSAGE(PJ_SYS_ERR + EILSEQ          ) QObject::tr("Illegal byte sequence"                            );
    SET_MESSAGE(PJ_SYS_ERR + EUSERS          ) QObject::tr("Too many users"                                   );
    SET_MESSAGE(PJ_SYS_ERR + ENOTSOCK        ) QObject::tr("Socket operation on non-socket"                   );
    SET_MESSAGE(PJ_SYS_ERR + EDESTADDRREQ    ) QObject::tr("Destination address required"                     );
@@ -192,19 +208,6 @@ static void init_statuscode()
    SET_MESSAGE(PJ_SYS_ERR + EALREADY        ) QObject::tr("Operation already in progress"                    );
    SET_MESSAGE(PJ_SYS_ERR + EINPROGRESS     ) QObject::tr("Operation now in progress"                        );
    SET_MESSAGE(PJ_SYS_ERR + ESTALE          ) QObject::tr("Stale file handle"                                );
-   SET_MESSAGE(PJ_SYS_ERR + EUCLEAN         ) QObject::tr("Structure needs cleaning"                         );
-   SET_MESSAGE(PJ_SYS_ERR + ENOTNAM         ) QObject::tr("Not a XENIX named type file"                      );
-   SET_MESSAGE(PJ_SYS_ERR + ENAVAIL         ) QObject::tr("No XENIX semaphores available"                    );
-   SET_MESSAGE(PJ_SYS_ERR + EISNAM          ) QObject::tr("Is a named type file"                             );
-   SET_MESSAGE(PJ_SYS_ERR + EREMOTEIO       ) QObject::tr("Remote I/O error"                                 );
-   SET_MESSAGE(PJ_SYS_ERR + EDQUOT          ) QObject::tr("Quota exceeded"                                   );
-   SET_MESSAGE(PJ_SYS_ERR + ENOMEDIUM       ) QObject::tr("No medium found"                                  );
-   SET_MESSAGE(PJ_SYS_ERR + EMEDIUMTYPE     ) QObject::tr("Wrong medium type"                                );
-   SET_MESSAGE(PJ_SYS_ERR + ECANCELED       ) QObject::tr("Operation Canceled"                               );
-   SET_MESSAGE(PJ_SYS_ERR + ENOKEY          ) QObject::tr("Required key not available"                       );
-   SET_MESSAGE(PJ_SYS_ERR + EKEYEXPIRED     ) QObject::tr("Key has expired"                                  );
-   SET_MESSAGE(PJ_SYS_ERR + EKEYREVOKED     ) QObject::tr("Key has been revoked"                             );
-   SET_MESSAGE(PJ_SYS_ERR + EKEYREJECTED    ) QObject::tr("Key was rejected by service"                      );
 
    //The next sections represent pjproject specific errors
 
diff --git a/src/audio/inputdevicemodel.cpp b/src/audio/inputdevicemodel.cpp
index 4e3f7b9b9040c52401813ad36df2b2ff374703d9..271f579b949f8c4abdfbfe168973e4fca01e87a9 100644
--- a/src/audio/inputdevicemodel.cpp
+++ b/src/audio/inputdevicemodel.cpp
@@ -17,6 +17,9 @@
  ***************************************************************************/
 #include "inputdevicemodel.h"
 
+//Qt
+#include <QtCore/QItemSelectionModel>
+
 //Ring
 #include "dbus/configurationmanager.h"
 #include "settings.h"
@@ -27,12 +30,14 @@ class InputDeviceModelPrivate : public QObject
 public:
    InputDeviceModelPrivate(Audio::InputDeviceModel* parent);
    QStringList m_lDeviceList;
+   mutable QItemSelectionModel* m_pSelectionModel;
 
 private:
    Audio::InputDeviceModel* q_ptr;
 };
 
-InputDeviceModelPrivate::InputDeviceModelPrivate(Audio::InputDeviceModel* parent) : q_ptr(parent)
+InputDeviceModelPrivate::InputDeviceModelPrivate(Audio::InputDeviceModel* parent) : q_ptr(parent),
+    m_pSelectionModel(nullptr)
 {
 
 }
@@ -59,7 +64,7 @@ d_ptr(new InputDeviceModelPrivate(this))
 ///Destructor
 Audio::InputDeviceModel::~InputDeviceModel()
 {
-   
+
 }
 
 ///Re-implement QAbstractListModel data
@@ -98,15 +103,18 @@ bool Audio::InputDeviceModel::setData( const QModelIndex& index, const QVariant
    return false;
 }
 
-///Return the current input device index
-QModelIndex Audio::InputDeviceModel::currentDevice() const
+QItemSelectionModel* Audio::InputDeviceModel::selectionModel() const
 {
-   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
-   const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
-   const int idx = currentDevices[static_cast<int>(Settings::DeviceIndex::INPUT)].toInt();
-   if (idx >= d_ptr->m_lDeviceList.size())
-      return QModelIndex();
-   return index(idx,0);
+   if (!d_ptr->m_pSelectionModel) {
+      d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<Audio::InputDeviceModel*>(this));
+
+      ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
+      const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
+      const int idx = currentDevices[static_cast<int>(Settings::DeviceIndex::INPUT)].toInt();
+      if (!(idx >= d_ptr->m_lDeviceList.size()))
+         d_ptr->m_pSelectionModel->setCurrentIndex(index(idx,0), QItemSelectionModel::ClearAndSelect);
+   }
+   return d_ptr->m_pSelectionModel;
 }
 
 ///Set the current input device
diff --git a/src/audio/inputdevicemodel.h b/src/audio/inputdevicemodel.h
index 91d3adb3a0f8d3eda41ef614ec4b4191eccd44ae..d217675878f5929fdc7b5368d292072bf9831e4b 100644
--- a/src/audio/inputdevicemodel.h
+++ b/src/audio/inputdevicemodel.h
@@ -22,6 +22,7 @@
 
 //Qt
 #include <QtCore/QStringList>
+class QItemSelectionModel;
 
 //Ring
 #include <typedefs.h>
@@ -44,7 +45,7 @@ public:
    virtual QHash<int,QByteArray> roleNames() const override;
 
    //Getters
-   QModelIndex currentDevice() const;
+   QItemSelectionModel* selectionModel() const;
 
    //Setters
    void setCurrentDevice(const QModelIndex& index);
diff --git a/src/audio/outputdevicemodel.cpp b/src/audio/outputdevicemodel.cpp
index 9a4daa8081ee8f88a552f2d8f3c3c91179754d4f..ae8396230e2b7d09bbc5eb6389b9c1f5abe9f9aa 100644
--- a/src/audio/outputdevicemodel.cpp
+++ b/src/audio/outputdevicemodel.cpp
@@ -17,6 +17,9 @@
  ***************************************************************************/
 #include "outputdevicemodel.h"
 
+//Qt
+#include <QtCore/QItemSelectionModel>
+
 //Ring
 #include "dbus/configurationmanager.h"
 #include "dbus/callmanager.h"
@@ -28,13 +31,15 @@ class OutputDeviceModelPrivate : public QObject
 public:
    OutputDeviceModelPrivate(Audio::OutputDeviceModel* parent);
    QStringList m_lDeviceList;
+   mutable QItemSelectionModel* m_pSelectionModel;
 
 private:
    Audio::OutputDeviceModel* q_ptr;
 };
 
 
-OutputDeviceModelPrivate::OutputDeviceModelPrivate(Audio::OutputDeviceModel* parent) : q_ptr(parent)
+OutputDeviceModelPrivate::OutputDeviceModelPrivate(Audio::OutputDeviceModel* parent) : q_ptr(parent),
+    m_pSelectionModel(nullptr)
 {
 
 }
@@ -100,16 +105,17 @@ bool Audio::OutputDeviceModel::setData( const QModelIndex& index, const QVariant
    return false;
 }
 
-///Return the current output device
-QModelIndex Audio::OutputDeviceModel::currentDevice() const
+QItemSelectionModel* Audio::OutputDeviceModel::selectionModel() const
 {
-   ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
-   const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
-   const int         idx            = currentDevices[static_cast<int>(Audio::Settings::DeviceIndex::OUTPUT)].toInt();
-
-   if (idx >= d_ptr->m_lDeviceList.size())
-      return QModelIndex();
-   return index(idx,0);
+   if (!d_ptr->m_pSelectionModel) {
+      d_ptr->m_pSelectionModel = new QItemSelectionModel(const_cast<Audio::OutputDeviceModel*>(this));
+      ConfigurationManagerInterface& configurationManager = DBus::ConfigurationManager::instance();
+      const QStringList currentDevices = configurationManager.getCurrentAudioDevicesIndex();
+      const int idx = currentDevices[static_cast<int>(Audio::Settings::DeviceIndex::OUTPUT)].toInt();
+      if (!(idx >= d_ptr->m_lDeviceList.size()))
+         d_ptr->m_pSelectionModel->setCurrentIndex(index(idx,0), QItemSelectionModel::ClearAndSelect);
+   }
+   return d_ptr->m_pSelectionModel;
 }
 
 ///Set the current output device
diff --git a/src/audio/outputdevicemodel.h b/src/audio/outputdevicemodel.h
index 61fb033d1bf85457dc66c61101e468f6763d4fd7..06c523f0e8ee331639650908e5c20671393da349 100644
--- a/src/audio/outputdevicemodel.h
+++ b/src/audio/outputdevicemodel.h
@@ -22,6 +22,7 @@
 
 //Qt
 #include <QtCore/QStringList>
+class QItemSelectionModel;
 
 //Ring
 #include <typedefs.h>
@@ -44,7 +45,7 @@ public:
    virtual QHash<int,QByteArray> roleNames() const override;
 
    //Getters
-   QModelIndex currentDevice() const;
+   QItemSelectionModel* selectionModel() const;
 
    //Setters
    void setCurrentDevice(const QModelIndex& index);
diff --git a/src/call.cpp b/src/call.cpp
index 1ef09c03a13418d059ae8e6544738ad4b9ab4f4c..25a14585861b1aefd7274c7642b8f9794f22a0a5 100644
--- a/src/call.cpp
+++ b/src/call.cpp
@@ -26,6 +26,7 @@
 //Qt
 #include <QtCore/QFile>
 #include <QtCore/QTimer>
+#include <QtCore/QDateTime>
 
 //DRing
 #include <account_const.h>
@@ -1311,7 +1312,7 @@ void CallPrivate::call()
       m_pDialNumber = nullptr;
    }
    else {
-      qDebug() << "Trying to call " << (m_pTransferNumber?QString(m_pTransferNumber->uri()):"ERROR") 
+      qDebug() << "Trying to call " << (m_pTransferNumber?QString(m_pTransferNumber->uri()):"ERROR")
          << " with no account registered . callId : " << q_ptr  << "ConfId:" << q_ptr;
       this->m_HistoryState = Call::LegacyHistoryState::NONE;
       throw tr("No account registered!");
diff --git a/src/call.h b/src/call.h
index 2410a3d2eecd83b7fa5bd7e2884441727fd1a18a..87ea78d7ca99faddb7ffcd812db1d4cd17fc35bf 100644
--- a/src/call.h
+++ b/src/call.h
@@ -38,8 +38,8 @@ class ContactMethod;
 class TemporaryContactMethod;
 class CollectionInterface;
 namespace Video {
-   class Renderer;
    class Manager;
+   class Renderer;
 }
 
 class Call;
@@ -241,7 +241,7 @@ public:
    Q_PROPERTY( uint               stopTimeStamp    READ stopTimeStamp                             )
    Q_PROPERTY( uint               startTimeStamp   READ startTimeStamp                            )
    Q_PROPERTY( bool               isSecure         READ isSecure                                  )
-   Q_PROPERTY( Video::Renderer*   videoRenderer    READ videoRenderer                             )
+   Q_PROPERTY( Video::Renderer* videoRenderer READ videoRenderer                          )
    Q_PROPERTY( QString            formattedName    READ formattedName                             )
    Q_PROPERTY( QString            length           READ length                                    )
    Q_PROPERTY( bool               hasRecording     READ hasRecording                              )
diff --git a/src/certificate.cpp b/src/certificate.cpp
index 7f688c9c2ae76f2764f63d658488d4a584a020d6..3b11201ffcd30a0f41a55e45ea03626abb93f001 100644
--- a/src/certificate.cpp
+++ b/src/certificate.cpp
@@ -19,6 +19,7 @@
 
 //Qt
 #include <QtCore/QFile>
+#include <QtCore/QDateTime>
 
 //Ring daemon
 #include <security_const.h>
diff --git a/src/codecmodel.cpp b/src/codecmodel.cpp
index 918c653c6a8363e05ec4311bfc01039e295f425b..d66ea0a200d4b225a295069c72a1871a85f3aef5 100644
--- a/src/codecmodel.cpp
+++ b/src/codecmodel.cpp
@@ -20,6 +20,7 @@
 //Qt
 #include <QtCore/QDebug>
 #include <QtCore/QCoreApplication>
+#include <QtCore/QSortFilterProxyModel>
 
 //DRing
 #include <account_const.h>
@@ -39,12 +40,15 @@ public:
       QString          name      ;
       QString          bitrate   ;
       QString          samplerate;
+      QString          type      ;
    };
 
    //Attributes
    QList<AudioCodecData*> m_lAudioCodecs  ;
    QMap<int,bool>         m_lEnabledCodecs;
    Account*               m_pAccount      ;
+   QSortFilterProxyModel* m_pAudioProxy   ;
+   QSortFilterProxyModel* m_pVideoProxy   ;
 
    //Helpers
    bool findCodec(int id);
@@ -53,9 +57,10 @@ private:
    CodecModel* q_ptr;
 };
 
-CodecModelPrivate::CodecModelPrivate(CodecModel* parent) : q_ptr(parent)
+CodecModelPrivate::CodecModelPrivate(CodecModel* parent) : q_ptr(parent),
+m_pAudioProxy(nullptr),m_pVideoProxy(nullptr)
 {
-   
+
 }
 
 ///Constructor
@@ -85,6 +90,7 @@ QHash<int,QByteArray> CodecModel::roleNames() const
       roles.insert(CodecModel::Role::NAME      ,QByteArray("name"));
       roles.insert(CodecModel::Role::BITRATE   ,QByteArray("bitrate"));
       roles.insert(CodecModel::Role::SAMPLERATE,QByteArray("samplerate"));
+      roles.insert(CodecModel::Role::TYPE      ,QByteArray("type"));
    }
    return roles;
 }
@@ -109,6 +115,9 @@ QVariant CodecModel::data(const QModelIndex& idx, int role) const {
    else if (idx.column() == 0 && role == CodecModel::Role::ID         ) {
       return d_ptr->m_lAudioCodecs[idx.row()]->id;
    }
+   else if (idx.column() == 0 && role == CodecModel::Role::TYPE         ) {
+      return d_ptr->m_lAudioCodecs[idx.row()]->type;
+   }
    return QVariant();
 }
 
@@ -152,6 +161,11 @@ bool CodecModel::setData( const QModelIndex& idx, const QVariant &value, int rol
       emit dataChanged(idx, idx);
       return true;
    }
+   else if (idx.column() == 0 && role == CodecModel::TYPE) {
+      d_ptr->m_lAudioCodecs[idx.row()]->type = value.toString();
+      emit dataChanged(idx, idx);
+      return true;
+   }
    return false;
 }
 
@@ -224,11 +238,14 @@ void CodecModel::reload()
 
       foreach (const int aCodec, activeCodecList) {
          if (!d_ptr->findCodec(aCodec)) {
+
             const QMap<QString,QString> codec = configurationManager.getCodecDetails(d_ptr->m_pAccount->id(),aCodec);
+
             QModelIndex idx = add();
             setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
             setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
             setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
+            setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
             setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
             setData(idx, Qt::Checked ,Qt::CheckStateRole               );
 
@@ -245,6 +262,7 @@ void CodecModel::reload()
          setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::NAME        ] ,CodecModel::Role::NAME       );
          setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::SAMPLE_RATE ] ,CodecModel::Role::SAMPLERATE );
          setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::BITRATE     ] ,CodecModel::Role::BITRATE    );
+         setData(idx,codec[ DRing::Account::ConfProperties::CodecInfo::TYPE        ] ,CodecModel::Role::TYPE       );
          setData(idx,QString::number(aCodec)  ,CodecModel::Role::ID         );
          setData(idx, Qt::Unchecked ,Qt::CheckStateRole);
       }
@@ -276,4 +294,27 @@ bool CodecModelPrivate::findCodec(int id)
    return false;
 }
 
+
+QSortFilterProxyModel* CodecModel::audioCodecs() const
+{
+    if (!d_ptr->m_pAudioProxy) {
+        d_ptr->m_pAudioProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
+        d_ptr->m_pAudioProxy->setSourceModel(const_cast<CodecModel*>(this));
+        d_ptr->m_pAudioProxy->setFilterRole(CodecModel::Role::TYPE);
+        d_ptr->m_pAudioProxy->setFilterFixedString("AUDIO");
+    }
+    return d_ptr->m_pAudioProxy;
+}
+
+QSortFilterProxyModel* CodecModel::videoCodecs() const
+{
+    if (!d_ptr->m_pVideoProxy) {
+        d_ptr->m_pVideoProxy = new QSortFilterProxyModel(const_cast<CodecModel*>(this));
+        d_ptr->m_pVideoProxy->setSourceModel(const_cast<CodecModel*>(this));
+        d_ptr->m_pVideoProxy->setFilterRole(CodecModel::Role::TYPE);
+        d_ptr->m_pVideoProxy->setFilterFixedString("VIDEO");
+    }
+    return d_ptr->m_pVideoProxy;
+}
+
 #include <codecmodel.moc>
diff --git a/src/codecmodel.h b/src/codecmodel.h
index 7e361f2d6b58fa0218ea962c6658e137eb92bec3..7413ebdaf26b973a575ee545d1b78e2a1d410ac3 100644
--- a/src/codecmodel.h
+++ b/src/codecmodel.h
@@ -22,6 +22,7 @@
 
 //Qt
 #include <QtCore/QString>
+class QSortFilterProxyModel;
 
 //Ring
 #include <typedefs.h>
@@ -46,6 +47,7 @@ public:
       NAME       = 100,
       BITRATE    = 101,
       SAMPLERATE = 102,
+      TYPE       = 104,
    };
 
    //Abstract model member
@@ -55,6 +57,10 @@ public:
    virtual bool setData         (const QModelIndex& index, const QVariant &value, int role )       override;
    virtual QHash<int,QByteArray> roleNames() const override;
 
+   //Proxies
+   QSortFilterProxyModel* audioCodecs() const;
+   QSortFilterProxyModel* videoCodecs() const;
+
    //Mutator
    QModelIndex add();
    Q_INVOKABLE void remove   ( const QModelIndex& idx );
diff --git a/src/collectionmanagerinterface.h b/src/collectionmanagerinterface.h
index 7611d2cd03f8be47061c78f8dc74966853ecbb52..7ead6bc40f9c2a4bdc1464781979907e49192e22 100644
--- a/src/collectionmanagerinterface.h
+++ b/src/collectionmanagerinterface.h
@@ -80,6 +80,13 @@ public:
    explicit CollectionManagerInterface(QAbstractItemModel* self);
    virtual ~CollectionManagerInterface() {};
 
+#ifdef Q_OS_DARWIN
+   /*
+    * Issue with LLVM 3.5svn shipped in Mac OSX with variadic template
+    */
+   template <class T2>
+   T2* addBackend(const LoadOptions options = LoadOptions::NONE);
+#else
    /**
     * This method is used to add a collection to a model. The LoadOptions
     * can be used to enforce some parameters. Please note this function is
@@ -93,6 +100,7 @@ public:
     */
    template <class T2, typename ...Ts>
    T2* addBackend(Ts... args, const LoadOptions options = LoadOptions::NONE);
+#endif // Q_OS_DARWIN
 
    /// Do this manager have active collections
    virtual bool hasEnabledCollections (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
diff --git a/src/collectionmanagerinterface.hpp b/src/collectionmanagerinterface.hpp
index d9e0831492e0aec49784cec9d0876413b632fbcd..d196fce8bcd974833062d0b65fadb22ab2bcbe5c 100644
--- a/src/collectionmanagerinterface.hpp
+++ b/src/collectionmanagerinterface.hpp
@@ -53,6 +53,28 @@ CollectionManagerInterfacePrivate<T>::~CollectionManagerInterfacePrivate()
 }
 
 template<class T>
+#ifdef Q_OS_DARWIN
+template <class T2>
+T2* CollectionManagerInterface<T>::addBackend(const LoadOptions options)
+{
+   T2* backend = new T2(d_ptr->itemMediator());
+
+   //This will force the T2 to be a CollectionInterface subclass
+   CollectionInterface* b = backend;
+   d_ptr->m_lCollections << b;
+
+   if (options & LoadOptions::FORCE_ENABLED) { //TODO check is the backend is checked
+
+      //Some backends can fail to load directly
+      //eventually it will necessary to add an async version of this
+      //to load the backend only when it is loaded
+      if (backend->load())
+         d_ptr->m_lEnabledCollections << backend;
+   }
+
+   return backend;
+}
+#else
 template <class T2, typename ...Ts>
 T2* CollectionManagerInterface<T>::addBackend(Ts... args, const LoadOptions options)
 {
@@ -73,6 +95,7 @@ T2* CollectionManagerInterface<T>::addBackend(Ts... args, const LoadOptions opti
 
    return collection;
 }
+#endif //Q_OS_DARWIN
 
 template<class T>
 CollectionManagerInterface<T>::CollectionManagerInterface(QAbstractItemModel* self) : d_ptr(new CollectionManagerInterfacePrivate<T>(self,this))
diff --git a/src/dbus/configurationmanager.cpp b/src/dbus/configurationmanager.cpp
index bf51e1da227687753329414c1099352c505b9830..348321f5a058adcc86146d792dd383ac35ef929d 100644
--- a/src/dbus/configurationmanager.cpp
+++ b/src/dbus/configurationmanager.cpp
@@ -18,10 +18,6 @@
  ***************************************************************************/
 #include "configurationmanager.h"
 
-#ifdef ENABLE_LIBWRAP
-#include "callbacks.h"
-#endif
-
 ConfigurationManagerInterface* DBus::ConfigurationManager::interface = nullptr;
 
 ConfigurationManagerInterface& DBus::ConfigurationManager::instance()
diff --git a/src/dbus/metatypes.h b/src/dbus/metatypes.h
index f49f956e70096c30ee5a6420ce1eead108faf341..5afb03e5b586671468196e064c259232c49aa178 100644
--- a/src/dbus/metatypes.h
+++ b/src/dbus/metatypes.h
@@ -24,24 +24,18 @@
 #include <QVector>
 #include <QtCore/QString>
 
+#include "../typedefs.h"
+
 #ifndef ENABLE_LIBWRAP
 #include <QtDBus/QtDBus>
 #endif
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-typedef QMap<QString, QString> MapStringString;
-typedef QMap<QString, int> MapStringInt;
-typedef QVector<int> VectorInt;
-typedef QVector<uint> VectorUInt;
-typedef QVector< QMap<QString, QString> > VectorMapStringString;
-typedef QVector< QString > VectorString;
-typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString;
-typedef QMap< QString, QVector<QString> > MapStringVectorString;
 
 Q_DECLARE_METATYPE(MapStringString)
 Q_DECLARE_METATYPE(MapStringInt)
 Q_DECLARE_METATYPE(VectorMapStringString)
-Q_DECLARE_METATYPE(MapStringMapStringVectorString)
+Q_DECLARE_METATYPE(MapStringMapStringStringList)
 Q_DECLARE_METATYPE(VectorInt)
 Q_DECLARE_METATYPE(VectorUInt)
 Q_DECLARE_METATYPE(VectorString)
@@ -50,14 +44,14 @@ Q_DECLARE_METATYPE(MapStringVectorString)
 #ifndef ENABLE_LIBWRAP
 static bool dbus_metaTypeInit = false;
 inline void registerCommTypes() {
-	qDBusRegisterMetaType<MapStringString>();
-	qDBusRegisterMetaType<MapStringInt>();
-	qDBusRegisterMetaType<VectorMapStringString>();
-        qDBusRegisterMetaType<MapStringMapStringVectorString>();
-        qDBusRegisterMetaType<VectorInt>();
-        qDBusRegisterMetaType<VectorUInt>();
-	qDBusRegisterMetaType<VectorString>();
-        qDBusRegisterMetaType<MapStringVectorString>();
+   qDBusRegisterMetaType<MapStringString>               ();
+   qDBusRegisterMetaType<MapStringInt>                  ();
+   qDBusRegisterMetaType<VectorMapStringString>         ();
+   qDBusRegisterMetaType<MapStringMapStringVectorString>();
+   qDBusRegisterMetaType<VectorInt>                     ();
+   qDBusRegisterMetaType<VectorUInt>                    ();
+   qDBusRegisterMetaType<VectorString>                  ();
+   qDBusRegisterMetaType<MapStringVectorString>         ();
    dbus_metaTypeInit = true;
 }
 #else
diff --git a/src/private/directrenderer.cpp b/src/private/directrenderer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5611ccac020a7d0f90ff410122b9221c1793036
--- /dev/null
+++ b/src/private/directrenderer.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>      *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "directrenderer.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QMutex>
+#include <QtCore/QThread>
+#include <QtCore/QTime>
+
+
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+#endif
+
+#include "video/manager.h"
+#include "video/resolution.h"
+#include "private/videorenderer_p.h"
+
+namespace Video {
+
+class DirectRendererPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   DirectRendererPrivate(Video::DirectRenderer* parent);
+
+   //Attributes
+
+private:
+   Video::DirectRenderer* q_ptr;
+
+};
+
+}
+
+
+
+Video::DirectRendererPrivate::DirectRendererPrivate(Video::DirectRenderer* parent) : QObject(parent), q_ptr(parent)
+{
+}
+
+///Constructor
+Video::DirectRenderer::DirectRenderer(const QByteArray& id, const QSize& res): Renderer(id, res), d_ptr(new DirectRendererPrivate(this))
+{
+   setObjectName("Video::DirectRenderer:"+id);
+
+
+   //DBusVideoManager::instance().registerFrameListener("local", [this] {
+//       qDebug() << "RECEIVED FRAME";
+  // });
+
+}
+
+///Destructor
+Video::DirectRenderer::~DirectRenderer()
+{
+}
+
+void Video::DirectRenderer::startRendering()
+{
+
+}
+void Video::DirectRenderer::stopRendering ()
+{
+
+}
+
+#include <directrenderer.moc>
diff --git a/src/private/directrenderer.h b/src/private/directrenderer.h
new file mode 100644
index 0000000000000000000000000000000000000000..c59d5d21f33799a36637fc61782d70cf1aecf802
--- /dev/null
+++ b/src/private/directrenderer.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>      *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEO_DIRECT_RENDERER_H
+#define VIDEO_DIRECT_RENDERER_H
+
+//Base
+#include <QtCore/QObject>
+#include "typedefs.h"
+#include "video/renderer.h"
+
+//Qt
+class QMutex;
+
+//Ring
+#include "video/device.h"
+
+
+namespace Video {
+class DirectRendererPrivate;
+
+///Manage shared memory and convert it to QByteArray
+class LIB_EXPORT DirectRenderer : public Renderer {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+   public:
+      //Constructor
+      DirectRenderer (const QByteArray& id, const QSize& res);
+      virtual ~DirectRenderer();
+
+      virtual void startRendering() override;
+      virtual void stopRendering () override;
+
+  private:
+     QScopedPointer<DirectRendererPrivate> d_ptr;
+     Q_DECLARE_PRIVATE(DirectRenderer)
+
+};
+
+}
+
+#endif
diff --git a/src/private/shmrenderer.cpp b/src/private/shmrenderer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44e4ef10696d72fc55eb8183a84341f6a330e4de
--- /dev/null
+++ b/src/private/shmrenderer.cpp
@@ -0,0 +1,369 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#include "shmrenderer.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QMutex>
+#include <QtCore/QThread>
+#include <QtCore/QTime>
+
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+#include <errno.h>
+
+
+#ifndef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+#endif
+
+#include <QtCore/QTimer>
+#include "video/manager.h"
+#include "video/resolution.h"
+#include "private/videorenderer_p.h"
+
+///Shared memory object
+struct SHMHeader{
+   sem_t notification;
+   sem_t mutex;
+
+   unsigned m_BufferGen;
+   int m_BufferSize;
+   /* The header will be aligned on 16-byte boundaries */
+   char padding[8];
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-pedantic"
+   char m_Data[];
+#pragma GCC diagnostic pop
+};
+
+namespace Video {
+
+class ShmRendererPrivate : public QObject
+{
+   Q_OBJECT
+public:
+   ShmRendererPrivate(Video::ShmRenderer* parent);
+
+   //Attributes
+   QString           m_ShmPath    ;
+   int               fd           ;
+   SHMHeader*        m_pShmArea   ;
+   signed int        m_ShmAreaLen ;
+   uint              m_BufferGen  ;
+   QTimer*           m_pTimer     ;
+   QMutex*           m_pSSMutex   ;
+   int               m_fpsC       ;
+   int               m_Fps        ;
+   QTime             m_CurrentTime;
+
+   //Constants
+   static const int TIMEOUT_SEC = 1; // 1 second
+
+   //Helpers
+   timespec createTimeout();
+   bool     shmLock      ();
+   void     shmUnlock    ();
+   bool     renderToBitmap();
+
+private:
+   Video::ShmRenderer* q_ptr;
+
+private Q_SLOTS:
+   void timedEvents();
+};
+
+}
+
+Video::ShmRendererPrivate::ShmRendererPrivate(Video::ShmRenderer* parent) : QObject(parent), q_ptr(parent),
+   fd(-1),m_fpsC(0),m_Fps(0),
+   m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0),
+   m_pTimer(nullptr),m_pSSMutex(new QMutex())
+{
+}
+
+///Constructor
+Video::ShmRenderer::ShmRenderer(const QByteArray& id, const QString& shmPath, const QSize& res): Renderer(id, res), d_ptr(new ShmRendererPrivate(this))
+{
+   d_ptr->m_ShmPath = shmPath;
+   setObjectName("Video::Renderer:"+id);
+}
+
+///Destructor
+Video::ShmRenderer::~ShmRenderer()
+{
+   stopShm();
+   //delete m_pShmArea;
+}
+
+///Get the data from shared memory and transform it into a QByteArray
+bool Video::ShmRendererPrivate::renderToBitmap()
+{
+#ifdef Q_OS_LINUX
+   if (!q_ptr->isRendering()) {
+      return false;
+   }
+
+   if (!shmLock()) {
+      return false;
+   }
+
+   if(!Video::Manager::instance()->startStopMutex()->tryLock())
+      return false;
+
+   // wait for a new buffer
+   while (m_BufferGen == m_pShmArea->m_BufferGen) {
+      shmUnlock();
+
+      int err = sem_trywait(&m_pShmArea->notification);
+      // Useful for debugging
+//       switch (errno ) {
+//          case EINTR:
+//             qDebug() << "Unlock failed: Interrupted function call (POSIX.1); see signal(7)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case EINVAL:
+//             qDebug() << "Unlock failed: Invalid argument (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case EAGAIN:
+//             qDebug() << "Unlock failed: Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//          case ETIMEDOUT:
+//             qDebug() << "Unlock failed: Connection timed out (POSIX.1)";
+//             ok = false;
+//             return QByteArray();
+//             break;
+//       }
+      if ((err < 0) || (!shmLock())) {
+         Video::Manager::instance()->startStopMutex()->unlock();
+         return false;
+      }
+      usleep((1/60.0)*100);
+   }
+
+   if (!q_ptr->resizeShm()) {
+      qDebug() << "Could not resize shared memory";
+      Video::Manager::instance()->startStopMutex()->unlock();
+      return false;
+   }
+
+   if (static_cast<Video::Renderer*>(q_ptr)->d_ptr->otherFrame().size() != m_pShmArea->m_BufferSize)
+      static_cast<Video::Renderer*>(q_ptr)->d_ptr->otherFrame().resize(m_pShmArea->m_BufferSize);
+   memcpy(static_cast<Video::Renderer*>(q_ptr)->d_ptr->otherFrame().data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
+   m_BufferGen = m_pShmArea->m_BufferGen;
+   shmUnlock();
+   static_cast<Video::Renderer*>(q_ptr)->d_ptr->updateFrameIndex();
+
+   Video::Manager::instance()->startStopMutex()->unlock();
+   return true;
+#else
+   return false;
+#endif
+}
+
+///Connect to the shared memory
+bool Video::ShmRenderer::startShm()
+{
+   if (d_ptr->fd != -1) {
+      qDebug() << "fd must be -1";
+      return false;
+   }
+
+   d_ptr->fd = shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0);
+   if (d_ptr->fd < 0) {
+      qDebug() << "could not open shm area " << d_ptr->m_ShmPath << ", shm_open failed:" << strerror(errno);
+      return false;
+   }
+   d_ptr->m_ShmAreaLen = sizeof(SHMHeader);
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   d_ptr->m_pShmArea = (SHMHeader*) mmap(NULL, d_ptr->m_ShmAreaLen, PROT_READ | PROT_WRITE, MAP_SHARED, d_ptr->fd, 0);
+   #pragma GCC diagnostic pop
+   if (d_ptr->m_pShmArea == MAP_FAILED) {
+      qDebug() << "Could not map shm area, mmap failed";
+      return false;
+   }
+   emit started();
+   return true;
+}
+
+///Disconnect from the shared memory
+void Video::ShmRenderer::stopShm()
+{
+   if (d_ptr->fd >= 0)
+      close(d_ptr->fd);
+   d_ptr->fd = -1;
+
+   if (d_ptr->m_pShmArea != MAP_FAILED)
+      munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen);
+   d_ptr->m_ShmAreaLen = 0;
+   d_ptr->m_pShmArea = (SHMHeader*) MAP_FAILED;
+}
+
+///Resize the shared memory
+bool Video::ShmRenderer::resizeShm()
+{
+   while (( (unsigned int) sizeof(SHMHeader) + (unsigned int) d_ptr->m_pShmArea->m_BufferSize) > (unsigned int) d_ptr->m_ShmAreaLen) {
+      const size_t new_size = sizeof(SHMHeader) + d_ptr->m_pShmArea->m_BufferSize;
+
+      d_ptr->shmUnlock();
+      if (munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen)) {
+            qDebug() << "Could not unmap shared area:" << strerror(errno);
+            return false;
+      }
+
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+      d_ptr->m_pShmArea = (SHMHeader*) mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, d_ptr->fd, 0);
+      #pragma GCC diagnostic pop
+      d_ptr->m_ShmAreaLen = new_size;
+
+      if (!d_ptr->m_pShmArea) {
+            d_ptr->m_pShmArea = nullptr;
+            qDebug() << "Could not remap shared area";
+            return false;
+      }
+
+      d_ptr->m_ShmAreaLen = new_size;
+      if (!d_ptr->shmLock())
+            return true;
+   }
+   return true;
+}
+
+///Lock the memory while the copy is being made
+bool Video::ShmRendererPrivate::shmLock()
+{
+#ifdef Q_OS_LINUX
+   return sem_trywait(&m_pShmArea->mutex) >= 0;
+#else
+   return false;
+#endif
+}
+
+///Remove the lock, allow a new frame to be drawn
+void Video::ShmRendererPrivate::shmUnlock()
+{
+   sem_post(&m_pShmArea->mutex);
+}
+
+
+/*****************************************************************************
+ *                                                                           *
+ *                                   Slots                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+///Update the buffer
+void Video::ShmRendererPrivate::timedEvents()
+{
+
+   bool ok = renderToBitmap();
+
+   if (ok) {
+
+      //Compute the FPS shown to the client
+      if (m_CurrentTime.second() != QTime::currentTime().second()) {
+         m_Fps = m_fpsC;
+         m_fpsC=0;
+         m_CurrentTime = QTime::currentTime();
+      }
+      m_fpsC++;
+
+      emit q_ptr->frameUpdated();
+   }
+   /*else {
+      qDebug() << "Frame dropped";
+      usleep(rand()%1000); //Be sure it can come back in sync
+   }*/
+}
+
+///Start the rendering loop
+void Video::ShmRenderer::startRendering()
+{
+   Video::Manager::instance()->startStopMutex()->lock();
+   QMutexLocker locker(mutex());
+   startShm();
+   if (!d_ptr->m_pTimer) {
+      d_ptr->m_pTimer = new QTimer(nullptr);
+
+//       m_pTimer->moveToThread(thread());
+      connect(d_ptr->m_pTimer,SIGNAL(timeout()),d_ptr.data(),SLOT(timedEvents()));
+      d_ptr->m_pTimer->setInterval(30);
+   }
+
+   if (!d_ptr->m_pTimer->isActive()) {
+      qDebug() << "Is running" << thread()->isRunning();
+      d_ptr->m_pTimer->start();
+   }
+   else
+      qDebug() << "Timer already started!";
+
+   setRendering(true);
+   Video::Manager::instance()->startStopMutex()->unlock();
+}
+
+///Stop the rendering loop
+void Video::ShmRenderer::stopRendering()
+{
+   Video::Manager::instance()->startStopMutex()->lock();
+   QMutexLocker locker(mutex());
+   setRendering(false);
+   qDebug() << "Stopping rendering on" << id();
+   if (d_ptr->m_pTimer)
+      d_ptr->m_pTimer->stop();
+   emit stopped();
+   stopShm();
+   Video::Manager::instance()->startStopMutex()->unlock();
+}
+
+
+/*****************************************************************************
+ *                                                                           *
+ *                                 Getters                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+///Get the current frame rate of this renderer
+int Video::ShmRenderer::fps() const
+{
+   return d_ptr->m_Fps;
+}
+
+/*****************************************************************************
+ *                                                                           *
+ *                                 Setters                                   *
+ *                                                                           *
+ ****************************************************************************/
+
+void Video::ShmRenderer::setShmPath(const QString& path)
+{
+   d_ptr->m_ShmPath = path;
+}
+
+#include <shmrenderer.moc>
diff --git a/src/private/shmrenderer.h b/src/private/shmrenderer.h
new file mode 100644
index 0000000000000000000000000000000000000000..39bb2669c44a6ca3eb662471a107c779bfb928da
--- /dev/null
+++ b/src/private/shmrenderer.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+ *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef VIDEO_SHM_RENDERER_H
+#define VIDEO_SHM_RENDERER_H
+
+//Base
+#include "video/renderer.h"
+#include "typedefs.h"
+
+//Qt
+class QMutex;
+
+//Ring
+#include "video/device.h"
+
+//Private
+struct SHMHeader;
+
+
+namespace Video {
+class ShmRendererPrivate;
+
+///Manage shared memory and convert it to QByteArray
+class LIB_EXPORT ShmRenderer : public Renderer {
+   #pragma GCC diagnostic push
+   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+   Q_OBJECT
+   #pragma GCC diagnostic pop
+
+   public:
+      //Constructor
+      ShmRenderer (const QByteArray& id, const QString& shmPath, const QSize& res);
+      virtual ~ShmRenderer();
+
+      //Mutators
+      bool resizeShm();
+      void stopShm  ();
+      bool startShm ();
+
+      //Getters
+      virtual int fps             () const         ;
+
+      //Setters
+      void setShmPath   (const QString& path);
+
+   private:
+      QScopedPointer<ShmRendererPrivate> d_ptr;
+      Q_DECLARE_PRIVATE(ShmRenderer)
+
+   public Q_SLOTS:
+      void startRendering();
+      void stopRendering ();
+
+
+
+};
+
+}
+
+#endif
diff --git a/src/private/videorenderer_p.h b/src/private/videorenderer_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..f28e1438207dfad5f0e65fa6ca3546cb32ad52eb
--- /dev/null
+++ b/src/private/videorenderer_p.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ *   Copyright (C) 2013-2015 by Savoir-Faire Linux                          *
+ *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *                                                                          *
+ *   This library is free software; you can redistribute it and/or          *
+ *   modify it under the terms of the GNU Lesser General Public             *
+ *   License as published by the Free Software Foundation; either           *
+ *   version 2.1 of the License, or (at your option) any later version.     *
+ *                                                                          *
+ *   This library is distributed in the hope that it will be useful,        *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
+ *   Lesser General Public License for more details.                        *
+ *                                                                          *
+ *   You should have received a copy of the GNU General Public License      *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
+ ***************************************************************************/
+#ifndef RENDERERPRIVATE_H
+#define RENDERERPRIVATE_H
+
+//Qt
+#include <QtCore/QObject>
+#include <QtCore/QSize>
+class QMutex;
+
+namespace Video {
+
+class Renderer;
+
+class RendererPrivate : public QObject
+{
+Q_OBJECT
+public:
+   RendererPrivate(Video::Renderer* parent);
+
+   //Attributes
+   bool              m_isRendering;
+   QByteArray        m_Frame[2]   ;
+   bool              m_FrameIdx   ;
+   QMutex*           m_pMutex     ;
+   QString           m_Id         ;
+   QSize             m_pSize      ;
+
+   //Helpers
+   QByteArray& otherFrame       () const;
+   void        updateFrameIndex ()      ;
+
+private:
+   Video::Renderer* q_ptr;
+
+};
+
+}
+
+#endif
diff --git a/src/qtwrapper/CMakeLists.txt b/src/qtwrapper/CMakeLists.txt
index 2b128dd52f8368e00c1e4dd4357893bb79a47682..4e4d3ca635d93f7fa654f926388fc3015e5e648e 100644
--- a/src/qtwrapper/CMakeLists.txt
+++ b/src/qtwrapper/CMakeLists.txt
@@ -22,6 +22,7 @@ set(libqtwrapper_LIB_SRCS
 INCLUDE_DIRECTORIES(SYSTEM ${Qt5Core_INCLUDE_DIRS} )
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
 INCLUDE_DIRECTORIES(${ring_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../dbus)
 
 ADD_LIBRARY( qtwrapper STATIC ${libqtwrapper_LIB_SRCS})
diff --git a/src/qtwrapper/callbacks.h b/src/qtwrapper/callbacks.h
deleted file mode 100644
index d5d292e6132497fab9538a1d4d4c4ec7ec2aa9aa..0000000000000000000000000000000000000000
--- a/src/qtwrapper/callbacks.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/******************************************************************************
- *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
- *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
- *                                                                            *
- *   This library is free software; you can redistribute it and/or            *
- *   modify it under the terms of the GNU Lesser General Public               *
- *   License as published by the Free Software Foundation; either             *
- *   version 2.1 of the License, or (at your option) any later version.       *
- *                                                                            *
- *   This library is distributed in the hope that it will be useful,          *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
- *   Lesser General Public License for more details.                          *
- *                                                                            *
- *   You should have received a copy of the Lesser GNU General Public License *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
- *****************************************************************************/
-#pragma once
-
-#include <QtCore/Qstring>
-
-#include "../dbus/callmanager.h"
-#include "../dbus/configurationmanager.h"
-#include "../dbus/instancemanager.h"
-#include "../dbus/presencemanager.h"
-#include "../dbus/videomanager.h"
diff --git a/src/qtwrapper/callmanager_wrap.h b/src/qtwrapper/callmanager_wrap.h
index fd3aa955c24570c55a903236dbc7369b0df0fc9d..8926f5d200a419e6beeaed11f0a157184600fb67 100644
--- a/src/qtwrapper/callmanager_wrap.h
+++ b/src/qtwrapper/callmanager_wrap.h
@@ -1,6 +1,7 @@
 /******************************************************************************
  *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
  *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>        *
  *                                                                            *
  *   This library is free software; you can redistribute it and/or            *
  *   modify it under the terms of the GNU Lesser General Public               *
@@ -27,8 +28,8 @@
 #include <QtCore/QVariant>
 #include <QtCore/QTimer>
 
-#include <dring.h>
-#include "../dbus/metatypes.h"
+#include <callmanager_interface.h>
+#include "typedefs.h"
 #include "conversions_wrap.hpp"
 
 /*
@@ -40,222 +41,245 @@ class CallManagerInterface: public QObject
 
 public:
 
+    std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> callHandlers;
+
     CallManagerInterface()
     {
-        call_ev_handlers = ring_call_ev_handlers {
-            .on_state_change = [this] (const std::string &callID, const std::string &state) {
-                      QTimer::singleShot(0, [this,callID, state] {
-                            printf("EMIT ONSTATECHANGE\n");
-                            emit this->callStateChanged(QString(callID.c_str()), QString(state.c_str()));
-                      });
-            },
-
-            .on_transfer_fail = [this] () {
-                      QTimer::singleShot(0, [this] {
-                            emit this->transferFailed();
-                      });
-            },
-            .on_transfer_success = [this] () {
-                      QTimer::singleShot(0, [this] {
-                            emit this->transferSucceeded();
-                      });
-            },
-            .on_record_playback_stopped = [this] (const std::string &filepath) {
-                      QTimer::singleShot(0, [this,filepath] {
-                            emit this->recordPlaybackStopped(QString(filepath.c_str()));
-                      });
-            },
-
-            .on_voice_mail_notify = [this] (const std::string &accountID, int count) {
-                      QTimer::singleShot(0, [this,accountID, count] {
-                            emit this->voiceMailNotify(QString(accountID.c_str()), count);
-                      });
-            },
-            .on_incoming_message = [this] (const std::string &callID, const std::string &from, const std::string &message) {
-                      QTimer::singleShot(0, [this,callID, from, message] {
-                            emit this->incomingMessage(QString(callID.c_str()), QString(from.c_str()), QString(message.c_str()));
-                      });
-            },
-            .on_incoming_call = [this] (const std::string &accountID, const std::string &callID, const std::string &from) {
-                      QTimer::singleShot(0, [this,accountID, callID, from] {
-                            emit this->incomingCall(QString(accountID.c_str()), QString(callID.c_str()), QString(from.c_str()));
-                      });
-            },
-            .on_record_playback_filepath = [this] (const std::string &callID, const std::string &filepath) {
-                      QTimer::singleShot(0, [this,callID, filepath] {
-                            emit this->recordPlaybackFilepath(QString(callID.c_str()), QString(filepath.c_str()));
-                      });
-            },
-            .on_conference_created = [this] (const std::string &confID) {
-                      QTimer::singleShot(0, [this,confID] {
-                            emit this->conferenceCreated(QString(confID.c_str()));
-                      });
-            },
-            .on_conference_changed = [this] (const std::string &confID, const std::string &state) {
-                      QTimer::singleShot(0, [this,confID, state] {
-                            emit this->conferenceChanged(QString(confID.c_str()), QString(state.c_str()));
-                      });
-            },
-            .on_update_playback_scale = [this] (const std::string &filepath, int position, int size) {
-                      QTimer::singleShot(0, [this,filepath, position, size] {
-                            emit this->updatePlaybackScale(QString(filepath.c_str()), position, size);
-                      });
-            },
-            .on_conference_remove = [this] (const std::string &confID) {
-                      QTimer::singleShot(0, [this,confID] {
-                            emit this->conferenceRemoved(QString(confID.c_str()));
-                      });
-            },
-            .on_new_call = [this] (const std::string &accountID, const std::string &callID, const std::string &to) {
-                      QTimer::singleShot(0, [this,accountID, callID, to] {
-                            printf("EMIT ONNEWCALL\n");
-                            emit this->newCallCreated(QString(accountID.c_str()), QString(callID.c_str()), QString(to.c_str()));
-                      });
-            },
-            .on_sip_call_state_change = [this] (const std::string &callID, const std::string &state, int code) {
-                      QTimer::singleShot(0, [this,callID, state, code] {
-                            emit this->sipCallStateChanged(QString(callID.c_str()), QString(state.c_str()), code);
-                      });
-            },
-            .on_record_state_change = [this] (const std::string &callID, bool recordingState) {
-                      QTimer::singleShot(0, [this,callID, recordingState] {
-                            emit this->recordingStateChanged(QString(callID.c_str()), recordingState);
-                      });
-            },
-            .on_secure_sdes_on = [this] (const std::string &callID) {
-                      QTimer::singleShot(0, [this,callID] {
-                            emit this->secureSdesOn(QString(callID.c_str()));
-                      });
-            },
-            .on_secure_sdes_off = [this] (const std::string &callID) {
-                      QTimer::singleShot(0, [this,callID] {
-                            emit this->secureSdesOff(QString(callID.c_str()));
-                      });
-            },
-            .on_secure_zrtp_on = [this] (const std::string &callID, const std::string &cipher) {
-                      QTimer::singleShot(0, [this,callID,cipher] {
-                            emit this->secureZrtpOn(QString(callID.c_str()), QString(cipher.c_str()));
-                      });
-            },
-            .on_secure_zrtp_off = [this] (const std::string &callID) {
-                      QTimer::singleShot(0, [this,callID] {
-                            emit this->secureZrtpOff(QString(callID.c_str()));
-                      });
-            },
-            .on_show_sas = [this] (const std::string &callID, const std::string &sas, bool verified) {
-                      QTimer::singleShot(0, [this,callID, sas, verified] {
-                            emit this->showSAS(QString(callID.c_str()), QString(sas.c_str()), verified);
-                      });
-            },
-            .on_zrtp_not_supp_other = [this] (const std::string &callID) {
-                      QTimer::singleShot(0, [this,callID] {
-                            emit this->zrtpNotSuppOther(QString(callID.c_str()));
-                      });
-            },
-            .on_zrtp_negotiation_fail = [this] (const std::string &callID, const std::string &reason, const std::string &severity) {
-                      QTimer::singleShot(0, [this,callID, reason, severity] {
-                            emit this->zrtpNegotiationFailed(QString(callID.c_str()), QString(reason.c_str()), QString(severity.c_str()));
-                      });
-            },
-            .on_rtcp_receive_report = [this] (const std::string &callID, const std::map<std::string, int>& report) {
-                      QTimer::singleShot(0, [this,callID, report] {
-                            emit this->onRtcpReportReceived(QString(callID.c_str()), convertStringInt(report));
-                      });
-            }
-        };
-    }
+        using DRing::exportable_callback;
+        using DRing::CallSignal;
+
+         callHandlers = {
+            exportable_callback<CallSignal::StateChange>(
+                [this] (const std::string &callID, const std::string &state) {
+                    QTimer::singleShot(0, [this,callID, state] {
+                        emit this->callStateChanged(QString(callID.c_str()), QString(state.c_str()));
+                    });
+            }),
+            exportable_callback<CallSignal::TransferFailed>(
+                [this] () {
+                       QTimer::singleShot(0, [this] {
+                             emit this->transferFailed();
+                       });
+            }),
+            exportable_callback<CallSignal::TransferSucceeded>(
+                [this] () {
+                       QTimer::singleShot(0, [this] {
+                             emit this->transferSucceeded();
+                       });
+            }),
+            exportable_callback<CallSignal::RecordPlaybackStopped>(
+                [this] (const std::string &filepath) {
+                       QTimer::singleShot(0, [this,filepath] {
+                             emit this->recordPlaybackStopped(QString(filepath.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::VoiceMailNotify>(
+                [this] (const std::string &accountID, int count) {
+                       QTimer::singleShot(0, [this,accountID, count] {
+                             emit this->voiceMailNotify(QString(accountID.c_str()), count);
+                       });
+            }),
+            exportable_callback<CallSignal::IncomingMessage>(
+                [this] (const std::string &callID, const std::string &from, const std::string &message) {
+                       QTimer::singleShot(0, [this,callID, from, message] {
+                             emit this->incomingMessage(QString(callID.c_str()), QString(from.c_str()), QString(message.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::IncomingCall>(
+                [this] (const std::string &accountID, const std::string &callID, const std::string &from) {
+                       QTimer::singleShot(0, [this,accountID, callID, from] {
+                             emit this->incomingCall(QString(accountID.c_str()), QString(callID.c_str()), QString(from.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::RecordPlaybackFilepath>(
+                [this] (const std::string &callID, const std::string &filepath) {
+                       QTimer::singleShot(0, [this,callID, filepath] {
+                             emit this->recordPlaybackFilepath(QString(callID.c_str()), QString(filepath.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::ConferenceCreated>(
+                [this] (const std::string &confID) {
+                       QTimer::singleShot(0, [this,confID] {
+                             emit this->conferenceCreated(QString(confID.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::ConferenceChanged>(
+                [this] (const std::string &confID, const std::string &state) {
+                       QTimer::singleShot(0, [this,confID, state] {
+                             emit this->conferenceChanged(QString(confID.c_str()), QString(state.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::UpdatePlaybackScale>(
+                [this] (const std::string &filepath, int position, int size) {
+                       QTimer::singleShot(0, [this,filepath, position, size] {
+                             emit this->updatePlaybackScale(QString(filepath.c_str()), position, size);
+                       });
+            }),
+            exportable_callback<CallSignal::ConferenceRemoved>(
+                [this] (const std::string &confID) {
+                       QTimer::singleShot(0, [this,confID] {
+                             emit this->conferenceRemoved(QString(confID.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::NewCallCreated>(
+                [this] (const std::string &accountID, const std::string &callID, const std::string &to) {
+                       QTimer::singleShot(0, [this,accountID, callID, to] {
+                             printf("EMIT ONNEWCALL\n");
+                             emit this->newCallCreated(QString(accountID.c_str()), QString(callID.c_str()), QString(to.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::SipCallStateChanged>(
+                [this] (const std::string &callID, const std::string &state, int code) {
+                       QTimer::singleShot(0, [this,callID, state, code] {
+                             emit this->sipCallStateChanged(QString(callID.c_str()), QString(state.c_str()), code);
+                       });
+            }),
+            exportable_callback<CallSignal::RecordingStateChanged>(
+                [this] (const std::string &callID, bool recordingState) {
+                       QTimer::singleShot(0, [this,callID, recordingState] {
+                             emit this->recordingStateChanged(QString(callID.c_str()), recordingState);
+                       });
+            }),
+            exportable_callback<CallSignal::SecureSdesOn>(
+                [this] (const std::string &callID) {
+                       QTimer::singleShot(0, [this,callID] {
+                             emit this->secureSdesOn(QString(callID.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::SecureSdesOff>(
+                [this] (const std::string &callID) {
+                       QTimer::singleShot(0, [this,callID] {
+                             emit this->secureSdesOff(QString(callID.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::SecureZrtpOn>(
+                [this] (const std::string &callID, const std::string &cipher) {
+                       QTimer::singleShot(0, [this,callID,cipher] {
+                             emit this->secureZrtpOn(QString(callID.c_str()), QString(cipher.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::SecureZrtpOff>(
+                [this] (const std::string &callID) {
+                       QTimer::singleShot(0, [this,callID] {
+                             emit this->secureZrtpOff(QString(callID.c_str()));
+                       });
+            }),
+            exportable_callback<CallSignal::ShowSAS>(
+                [this] (const std::string &callID, const std::string &sas, bool verified) {
+                       QTimer::singleShot(0, [this,callID, sas, verified] {
+                             emit this->showSAS(QString(callID.c_str()), QString(sas.c_str()), verified);
+                       });
+            }),
+            exportable_callback<CallSignal::ZrtpNotSuppOther>(
+                [this] (const std::string &callID) {
+                       QTimer::singleShot(0, [this,callID] {
+                             emit this->zrtpNotSuppOther(QString(callID.c_str()));
+                       });
+             }),
+             exportable_callback<CallSignal::ZrtpNegotiationFailed>(
+                 [this] (const std::string &callID, const std::string &reason, const std::string &severity) {
+                       QTimer::singleShot(0, [this,callID, reason, severity] {
+                             emit this->zrtpNegotiationFailed(QString(callID.c_str()), QString(reason.c_str()), QString(severity.c_str()));
+                       });
+             }),
+             exportable_callback<CallSignal::RtcpReportReceived>(
+                 [this] (const std::string &callID, const std::map<std::string, int>& report) {
+                       QTimer::singleShot(0, [this,callID, report] {
+                             emit this->onRtcpReportReceived(QString(callID.c_str()), convertStringInt(report));
+                       });
+             })
+         };
+     }
 
     ~CallManagerInterface() {}
 
     bool isValid() { return true; }
 
-    ring_call_ev_handlers call_ev_handlers;
-
 public Q_SLOTS: // METHODS
     bool accept(const QString &callID)
     {
-        return ring_call_accept(callID.toStdString());
+        return DRing::accept(callID.toStdString());
     }
 
     void acceptEnrollment(const QString &callID, bool accepted)
     {
-        ring_call_accept_enrollment(callID.toStdString(), accepted);
+        DRing::acceptEnrollment(callID.toStdString(), accepted);
     }
 
     bool addMainParticipant(const QString &confID)
     {
-        return ring_call_add_main_participant(confID.toStdString());
+        return DRing::addMainParticipant(confID.toStdString());
     }
 
     bool addParticipant(const QString &callID, const QString &confID)
     {
-        return ring_call_add_participant(
-            callID.toStdString(), confID.toStdString());
+        return DRing::addParticipant(
+                        callID.toStdString(), confID.toStdString());
     }
 
     bool attendedTransfer(const QString &transferID, const QString &targetID)
     {
-        return ring_call_attended_transfer(
-            transferID.toStdString(), targetID.toStdString());
+        return DRing::attendedTransfer(
+                        transferID.toStdString(), targetID.toStdString());
     }
 
     void createConfFromParticipantList(const QStringList &participants)
     {
-        ring_call_create_conf_from_participant_list(
-            convertStringList(participants));
+        DRing::createConfFromParticipantList(
+                        convertStringList(participants));
     }
 
     bool detachParticipant(const QString &callID)
     {
-        return ring_call_detach_participant(callID.toStdString());
+        return DRing::detachParticipant(callID.toStdString());
     }
 
     MapStringString getCallDetails(const QString &callID)
     {
         MapStringString temp =
-            convertMap(ring_call_get_call_details(callID.toStdString()));
+            convertMap(DRing::getCallDetails(callID.toStdString()));
         return temp;
     }
 
     QStringList getCallList()
     {
         QStringList temp =
-            convertStringList(ring_call_get_call_list());
+            convertStringList(DRing::getCallList());
         return temp;
     }
 
     MapStringString getConferenceDetails(const QString &callID)
     {
         MapStringString temp =
-            convertMap(ring_call_get_conference_details(
+            convertMap(DRing::getConferenceDetails(
                 callID.toStdString()));
         return temp;
     }
 
     QString getConferenceId(const QString &callID)
     {
-        QString temp(ring_call_get_conference_id(callID.toStdString()).c_str());
+        QString temp(DRing::getConferenceId(callID.toStdString()).c_str());
         return temp;
     }
 
     QStringList getConferenceList()
     {
         QStringList temp =
-            convertStringList(ring_call_get_conference_list());
+            convertStringList(DRing::getConferenceList());
         return temp;
     }
 
     Q_DECL_DEPRECATED QString getCurrentAudioCodecName(const QString &callID)
     {
         QString temp(
-            ring_call_get_current_audio_codec_name(callID.toStdString()).c_str());
+            DRing::getCurrentAudioCodecName(callID.toStdString()).c_str());
         return temp;
     }
 
     QStringList getDisplayNames(const QString &confID)
     {
         QStringList temp =
-            convertStringList(ring_call_get_display_names(
+            convertStringList(DRing::getDisplayNames(
                 confID.toStdString()));
         return temp;
     }
@@ -263,142 +287,136 @@ public Q_SLOTS: // METHODS
     bool getIsRecording(const QString &callID)
     {
         //TODO: match API
-        return ring_call_is_recording(callID.toStdString());
+        return DRing::getIsRecording(callID.toStdString());
     }
 
     QStringList getParticipantList(const QString &confID)
     {
         QStringList temp =
-            convertStringList(ring_call_get_participant_list(
+            convertStringList(DRing::getParticipantList(
                 confID.toStdString()));
         return temp;
     }
 
     bool hangUp(const QString &callID)
     {
-        return ring_call_hang_up(callID.toStdString());
+        return DRing::hangUp(callID.toStdString());
     }
 
     bool hangUpConference(const QString &confID)
     {
-        return ring_call_hang_up_conference(confID.toStdString());
+        return DRing::hangUpConference(confID.toStdString());
     }
 
     bool hold(const QString &callID)
     {
-        return ring_call_hold(callID.toStdString());
+        return DRing::hold(callID.toStdString());
     }
 
     bool holdConference(const QString &confID)
     {
-        return ring_call_hold_conference(confID.toStdString());
+        return DRing::holdConference(confID.toStdString());
     }
 
     bool isConferenceParticipant(const QString &callID)
     {
-        return ring_call_is_conference_participant(callID.toStdString());
+        return DRing::isConferenceParticipant(callID.toStdString());
     }
 
     bool joinConference(const QString &sel_confID, const QString &drag_confID)
     {
-        return ring_call_join_conference(
+        return DRing::joinConference(
             sel_confID.toStdString(), drag_confID.toStdString());
     }
 
     bool joinParticipant(const QString &sel_callID, const QString &drag_callID)
     {
-        return ring_call_join_participant(
+        return DRing::joinParticipant(
             sel_callID.toStdString(), drag_callID.toStdString());
     }
 
-    bool placeCall(const QString &accountID, const QString &callID, const QString &to)
+    QString placeCall(const QString &accountID, const QString &to)
     {
-        //TODO: match API
-        return ring_call_place(
-            accountID.toStdString(), callID.toStdString(), to.toStdString());
+        QString temp(DRing::placeCall(accountID.toStdString(), to.toStdString()).c_str());
+        return temp;
     }
 
     void playDTMF(const QString &key)
     {
-        ring_call_play_dtmf(key.toStdString());
+        DRing::playDTMF(key.toStdString());
     }
 
     void recordPlaybackSeek(double value)
     {
-        ring_call_record_playback_seek(value);
+        DRing::recordPlaybackSeek(value);
     }
 
     bool refuse(const QString &callID)
     {
-        return ring_call_refuse(callID.toStdString());
+        return DRing::refuse(callID.toStdString());
     }
 
     void requestGoClear(const QString &callID)
     {
-        ring_call_request_go_clear(callID.toStdString());
+        DRing::requestGoClear(callID.toStdString());
     }
 
     void resetSASVerified(const QString &callID)
     {
-        ring_call_reset_sas_verified(callID.toStdString());
+        DRing::resetSASVerified(callID.toStdString());
     }
 
     void sendTextMessage(const QString &callID, const QString &message)
     {
-        ring_call_send_text_message(
+        DRing::sendTextMessage(
             callID.toStdString(), message.toStdString());
     }
 
     void setConfirmGoClear(const QString &callID)
     {
-        ring_call_set_confirm_go_clear(callID.toStdString());
-    }
-
-    Q_DECL_DEPRECATED void setRecording(const QString &callID)
-    {
-        ring_call_set_recording(callID.toStdString());
+        DRing::setConfirmGoClear(callID.toStdString());
     }
 
     void setSASVerified(const QString &callID)
     {
-        ring_call_set_sas_verified(callID.toStdString());
+        DRing::setSASVerified(callID.toStdString());
     }
 
     bool startRecordedFilePlayback(const QString &filepath)
     {
         // TODO: Change method name to match API
-        return ring_call_play_recorded_file(filepath.toStdString());
+        return DRing::startRecordedFilePlayback(filepath.toStdString());
     }
 
     void startTone(int start, int type)
     {
-        ring_call_start_tone(start, type);
+        DRing::startTone(start, type);
     }
 
     void stopRecordedFilePlayback(const QString &filepath)
     {
-        ring_call_stop_recorded_file(filepath.toStdString());
+        DRing::stopRecordedFilePlayback(filepath.toStdString());
     }
 
     bool toggleRecording(const QString &callID)
     {
-        return ring_call_toggle_recording(callID.toStdString());
+        return DRing::toggleRecording(callID.toStdString());
     }
 
     bool transfer(const QString &callID, const QString &to)
     {
-        return ring_call_transfer(
+        return DRing::transfer(
             callID.toStdString(), to.toStdString());
     }
 
     bool unhold(const QString &callID)
     {
-        return ring_call_unhold(callID.toStdString());
+        return DRing::unhold(callID.toStdString());
     }
 
     bool unholdConference(const QString &confID)
     {
-        return ring_call_unhold_conference(confID.toStdString());
+        return DRing::unholdConference(confID.toStdString());
     }
 
 Q_SIGNALS: // SIGNALS
diff --git a/src/qtwrapper/configurationmanager_wrap.h b/src/qtwrapper/configurationmanager_wrap.h
index 0cfb73f13732c377541c7ef7b5d05c88dfea2809..4de404a5a2fe28ce742c2e79a6c265d39aab9845 100644
--- a/src/qtwrapper/configurationmanager_wrap.h
+++ b/src/qtwrapper/configurationmanager_wrap.h
@@ -1,22 +1,23 @@
 /******************************************************************************
- *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
- *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
- *                                                                            *
- *   This library is free software; you can redistribute it and/or            *
- *   modify it under the terms of the GNU Lesser General Public               *
- *   License as published by the Free Software Foundation; either             *
- *   version 2.1 of the License, or (at your option) any later version.       *
- *                                                                            *
- *   This library is distributed in the hope that it will be useful,          *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
- *   Lesser General Public License for more details.                          *
- *                                                                            *
- *   You should have received a copy of the Lesser GNU General Public License *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
- *****************************************************************************/
-#ifndef CONFIGURATIONMANAGER_DBUS_INTERFACE_H
-#define CONFIGURATIONMANAGER_DBUS_INTERFACE_H
+*   Copyright (C) 2014 by Savoir-Faire Linux                                 *
+*   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
+*   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>        *
+*                                                                            *
+*   This library is free software; you can redistribute it and/or            *
+*   modify it under the terms of the GNU Lesser General Public               *
+*   License as published by the Free Software Foundation; either             *
+*   version 2.1 of the License, or (at your option) any later version.       *
+*                                                                            *
+*   This library is distributed in the hope that it will be useful,          *
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
+*   Lesser General Public License for more details.                          *
+*                                                                            *
+*   You should have received a copy of the Lesser GNU General Public License *
+*   along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
+*****************************************************************************/
+#ifndef CONFIGURATIONMANAGER_STATIC_INTERFACE_H
+#define CONFIGURATIONMANAGER_STATIC_INTERFACE_H
 
 #include <QtCore/QObject>
 #include <QtCore/QByteArray>
@@ -29,8 +30,9 @@
 
 #include <future>
 
-#include <dring.h>
-#include "../dbus/metatypes.h"
+#include <configurationmanager_interface.h>
+
+#include "typedefs.h"
 #include "conversions_wrap.hpp"
 
 // TEMPORARY
@@ -45,192 +47,182 @@ class ConfigurationManagerInterface: public QObject
     Q_OBJECT
 
 public:
+
+    std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers;
+
     ConfigurationManagerInterface()
     {
         setObjectName("ConfigurationManagerInterface");
-        config_ev_handlers = {
-            .on_volume_change = [this] (const std::string &device, double value) {
-                      QTimer::singleShot(0, [this,device,value] {
-                            emit this->volumeChanged(QString(device.c_str()), value);
-                      });
-            },
-            .on_accounts_change = [this] () {
-                      QTimer::singleShot(0, [this] {
-                            emit this->accountsChanged();
-                      });
-             },
-            .on_history_change = [this] () {
-                      QTimer::singleShot(0, [this] {
-                            emit this->historyChanged();
-                      });
-            },
-             .on_stun_status_fail = [this] (const std::string &reason) {
-                      QTimer::singleShot(0, [this, reason] {
-                            emit this->stunStatusFailure(QString(reason.c_str()));
-                      });
-            },
-            .on_registration_state_change = [this] (const std::string &accountID, int registration_state) {
-                      QTimer::singleShot(0, [this, accountID, registration_state] {
-                            emit this->registrationStateChanged(QString(accountID.c_str()), registration_state);
-                      });
-            },
-            .on_sip_registration_state_change = [this] (const std::string &accountID, const std::string &state, int code) {
-                      QTimer::singleShot(0, [this,accountID, state, code] {
-                            emit this->sipRegistrationStateChanged(QString(accountID.c_str()), QString(state.c_str()), code);
-                      });
-            },
-
-            //TODO: .on_volatile_details_change = [this] (const QString &message.c_str()) { emit this->volatileAccountDetailsChanged(); },
-            .on_error = [this] (int code) {
-                      QTimer::singleShot(0, [this,code] {
-                        emit this->errorAlert(code);
-                      });
-            }
+        using DRing::exportable_callback;
+        using DRing::ConfigurationSignal;
+
+        setObjectName("ConfigurationManagerInterface");
+        confHandlers = {
+            exportable_callback<ConfigurationSignal::VolumeChanged>(
+                [this] (const std::string &device, double value) {
+                       QTimer::singleShot(0, [this,device,value] {
+                             emit this->volumeChanged(QString(device.c_str()), value);
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::AccountsChanged>(
+                [this] () {
+                       QTimer::singleShot(0, [this] {
+                             emit this->accountsChanged();
+                       });
+             }),
+             exportable_callback<ConfigurationSignal::HistoryChanged>(
+                [this] () {
+                       QTimer::singleShot(0, [this] {
+                             emit this->historyChanged();
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::StunStatusFailed>(
+                [this] (const std::string &reason) {
+                       QTimer::singleShot(0, [this, reason] {
+                             emit this->stunStatusFailure(QString(reason.c_str()));
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::RegistrationStateChanged>(
+                [this] (const std::string &accountID, int registration_state) {
+                       QTimer::singleShot(0, [this, accountID, registration_state] {
+                             emit this->registrationStateChanged(QString(accountID.c_str()), registration_state);
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::SipRegistrationStateChanged>(
+                [this] (const std::string &accountID, const std::string &state, int code) {
+                       QTimer::singleShot(0, [this,accountID, state, code] {
+                             emit this->sipRegistrationStateChanged(QString(accountID.c_str()), QString(state.c_str()), code);
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::VolatileDetailsChanged>(
+                [this] (const std::string &accountID, const std::map<std::string, std::string>& details) {
+                       QTimer::singleShot(0, [this, accountID, details] {
+                         emit this->volatileAccountDetailsChanged(QString(accountID.c_str()), convertMap(details));
+                       });
+            }),
+            exportable_callback<ConfigurationSignal::Error>(
+                [this] (int code) {
+                       QTimer::singleShot(0, [this,code] {
+                         emit this->errorAlert(code);
+                       });
+            })
         };
     }
 
     ~ConfigurationManagerInterface() {}
 
-    ring_config_ev_handlers config_ev_handlers;
-
 public Q_SLOTS: // METHODS
     QString addAccount(MapStringString details)
     {
         QString temp(
-            ring_config_add_account(convertMap(details)).c_str());
+            DRing::addAccount(convertMap(details)).c_str());
         return temp;
     }
 
-    bool checkCertificateValidity(const QString &caPath, const QString &pemPath)
-    {
-        return ring_config_check_certificate_validity(
-            caPath.toStdString(), pemPath.toStdString());
-    }
-
-    bool checkForPrivateKey(const QString &pemPath)
-    {
-        return ring_config_check_for_private_key(pemPath.toStdString());
-    }
-
-    bool checkHostnameCertificate(const QString &host, const QString &port)
-    {
-        return ring_config_check_hostname_certificate(
-            host.toStdString(), port.toStdString());
-    }
-
-    void clearHistory()
-    {
-        ring_config_clear_history();
-    }
-
     MapStringString getAccountDetails(const QString &accountID)
     {
         MapStringString temp =
-            convertMap(ring_config_get_account_details(accountID.toStdString()));
+            convertMap(DRing::getAccountDetails(accountID.toStdString()));
         return temp;
     }
 
     QStringList getAccountList()
     {
-        std::cout << "AccountList:" << std::endl;
-        for (auto x : ring_config_get_account_list())
-            std::cout << x << std::endl;
-
         QStringList temp =
-            convertStringList(ring_config_get_account_list());
+            convertStringList(DRing::getAccountList());
         return temp;
     }
 
     MapStringString getAccountTemplate()
     {
         MapStringString temp =
-            convertMap(ring_config_get_account_template());
+            convertMap(DRing::getAccountTemplate());
         return temp;
     }
 
-// TODO: works?
-    VectorInt getActiveAudioCodecList(const QString &accountID)
+    // TODO: works?
+    VectorUInt getActiveCodecList(const QString &accountID)
     {
-        return QVector<int>::fromStdVector(
-            ring_config_get_active_audio_codec_list(accountID.toStdString()));
+        return QVector<unsigned int>::fromStdVector(
+            DRing::getActiveCodecList(accountID.toStdString()));
     }
 
     QString getAddrFromInterfaceName(const QString &interface)
     {
         QString temp(
-            ring_config_get_addr_from_interface_name(interface.toStdString()).c_str());
+            DRing::getAddrFromInterfaceName(interface.toStdString()).c_str());
         return temp;
     }
 
     QStringList getAllIpInterface()
     {
         QStringList temp =
-            convertStringList(ring_config_get_all_ip_interface());
+            convertStringList(DRing::getAllIpInterface());
         return temp;
     }
 
     QStringList getAllIpInterfaceByName()
     {
         QStringList temp =
-            convertStringList(ring_config_get_all_ip_interface_by_name());
+            convertStringList(DRing::getAllIpInterfaceByName());
         return temp;
     }
 
-    QStringList getAudioCodecDetails(int payload)
+    MapStringString getCodecDetails(const QString accountID, int payload)
     {
-        QStringList temp =
-            convertStringList(ring_config_get_audio_codec_details(payload));
+        MapStringString temp =
+            convertMap(DRing::getCodecDetails(
+                accountID.toStdString().c_str(), payload));
         return temp;
     }
 
-// TODO: works?
-    VectorInt getAudioCodecList()
+    VectorUInt getCodecList()
     {
-        return QVector<int>::fromStdVector(ring_config_get_audio_codec_list());
+        return QVector<unsigned int>::fromStdVector(DRing::getCodecList());
     }
 
     int getAudioInputDeviceIndex(const QString &devname)
     {
-        return ring_config_get_audio_input_device_index(devname.toStdString());
+        return DRing::getAudioInputDeviceIndex(devname.toStdString());
     }
 
     QStringList getAudioInputDeviceList()
     {
         QStringList temp =
-            convertStringList(ring_config_get_audio_input_device_list());
+            convertStringList(DRing::getAudioInputDeviceList());
         return temp;
     }
 
     QString getAudioManager()
     {
         QString temp(
-            ring_config_get_audio_manager().c_str());
+            DRing::getAudioManager().c_str());
         return temp;
     }
 
     int getAudioOutputDeviceIndex(const QString &devname)
     {
-        return ring_config_get_audio_output_device_index(devname.toStdString());
+        return DRing::getAudioOutputDeviceIndex(devname.toStdString());
     }
 
     QStringList getAudioOutputDeviceList()
     {
         QStringList temp =
-            convertStringList(ring_config_get_audio_output_device_list());
+            convertStringList(DRing::getAudioOutputDeviceList());
         return temp;
     }
 
     QStringList getAudioPluginList()
     {
         QStringList temp =
-            convertStringList(ring_config_get_audio_plugin_list());
+            convertStringList(DRing::getAudioPluginList());
         return temp;
     }
 
     VectorMapStringString getCredentials(const QString &accountID)
     {
         VectorMapStringString temp;
-        for(auto x : ring_config_get_credentials(accountID.toStdString())) {
+        for(auto x : DRing::getCredentials(accountID.toStdString())) {
             temp.push_back(convertMap(x));
         }
         return temp;
@@ -239,212 +231,216 @@ public Q_SLOTS: // METHODS
     QStringList getCurrentAudioDevicesIndex()
     {
         QStringList temp =
-            convertStringList(ring_config_get_current_audio_devices_index());
+            convertStringList(DRing::getCurrentAudioDevicesIndex());
         return temp;
     }
 
     QString getCurrentAudioOutputPlugin()
     {
         QString temp(
-            ring_config_get_current_audio_output_plugin().c_str());
-        return temp;
-    }
-
-    VectorMapStringString getHistory()
-    {
-        VectorMapStringString temp;
-        for (auto x : ring_config_get_history()) {
-            temp.push_back(convertMap(x));
-        }
+            DRing::getCurrentAudioOutputPlugin().c_str());
         return temp;
     }
 
     int getHistoryLimit()
     {
-        return ring_config_get_history_limit();
+        return DRing::getHistoryLimit();
     }
 
     MapStringString getHookSettings()
     {
         MapStringString temp =
-            convertMap(ring_config_get_hook_settings());
+            convertMap(DRing::getHookSettings());
         return temp;
     }
 
     MapStringString getIp2IpDetails()
     {
         MapStringString temp =
-            convertMap(ring_config_get_ip2ip_details());
+            convertMap(DRing::getIp2IpDetails());
         return temp;
     }
 
     bool getIsAlwaysRecording()
     {
-        // TODO: update API
-        return ring_config_is_always_recording();
+        return DRing::getIsAlwaysRecording();
     }
 
     bool getNoiseSuppressState()
     {
-        return ring_config_get_noise_suppress_state();
+        return DRing::getNoiseSuppressState();
     }
 
     QString getRecordPath()
     {
         QString temp(
-            ring_config_get_record_path().c_str());
+            DRing::getRecordPath().c_str());
         return temp;
     }
 
-    MapStringString getRingtoneList()
+    QStringList getSupportedAudioManagers()
     {
-        MapStringString temp =
-            convertMap(ring_config_get_ringtone_list());
+        QStringList temp;
         return temp;
     }
 
     MapStringString getShortcuts()
     {
         MapStringString temp =
-            convertMap(ring_config_get_shortcuts());
+            convertMap(DRing::getShortcuts());
         return temp;
     }
 
-    QStringList getSupportedAudioManagers()
+    QStringList getSupportedTlsMethod()
     {
         QStringList temp =
-            convertStringList(ring_config_get_supported_audio_managers());
+            convertStringList(DRing::getSupportedTlsMethod());
         return temp;
     }
 
-    QStringList getSupportedTlsMethod()
+    MapStringString getTlsSettings()
     {
-        QStringList temp =
-            convertStringList(ring_config_get_supported_tls_method());
+        MapStringString temp =
+            convertMap(DRing::getTlsSettings());
         return temp;
     }
 
-    MapStringString getTlsSettings()
+    MapStringString validateCertificate(const QString& unused, const QString certificate, const QString& privateKey)
     {
         MapStringString temp =
-            convertMap(ring_config_get_tls_settings());
+            convertMap(DRing::validateCertificate(unused.toStdString(),
+                                                certificate.toStdString(),
+                                                privateKey.toStdString()));
         return temp;
     }
 
-    MapStringString getTlsSettingsDefault()
+    MapStringString getCertificateDetails(const QString &certificate)
     {
-        // TODO: update API
         MapStringString temp =
-            convertMap(ring_config_get_tls_default_settings());
+            convertMap(DRing::getCertificateDetails(certificate.toStdString()));
+        return temp;
+    }
+
+    QStringList getSupportedCiphers(const QString &accountID)
+    {
+        QStringList temp =
+            convertStringList(DRing::getSupportedCiphers(accountID.toStdString()));
+        return temp;
+    }
+
+    MapStringString getTlsDefaultSettings()
+    {
+        MapStringString temp =
+            convertMap(DRing::getTlsDefaultSettings());
         return temp;
     }
 
     double getVolume(const QString &device)
     {
-        return ring_config_get_volume(device.toStdString());
+        return DRing::getVolume(device.toStdString());
     }
 
     bool isAgcEnabled()
     {
-        return ring_config_is_agc_enabled();
+        return DRing::isAgcEnabled();
     }
 
     bool isCaptureMuted()
     {
-        return ring_config_is_capture_muted();
+        return DRing::isCaptureMuted();
     }
 
     bool isDtmfMuted()
     {
-        return ring_config_is_dtmf_muted();
+        return DRing::isDtmfMuted();
     }
 
     int isIax2Enabled()
     {
-        return ring_config_is_iax2_enabled();
+        return DRing::isIax2Enabled();
     }
 
     bool isPlaybackMuted()
     {
-        return ring_config_is_playback_muted();
+        return DRing::isPlaybackMuted();
     }
 
     void muteCapture(bool mute)
     {
-        ring_config_mute_capture(mute);
+        DRing::muteCapture(mute);
     }
 
     void muteDtmf(bool mute)
     {
-        ring_config_mute_dtmf(mute);
+        DRing::muteDtmf(mute);
     }
 
     void mutePlayback(bool mute)
     {
-        ring_config_mute_playback(mute);
+        DRing::mutePlayback(mute);
     }
 
     void registerAllAccounts()
     {
-        ring_config_register_all_accounts();
+        DRing::registerAllAccounts();
     }
 
     void removeAccount(const QString &accountID)
     {
-        ring_config_remove_account(accountID.toStdString());
+        DRing::removeAccount(accountID.toStdString());
     }
 
     void sendRegister(const QString &accountID, bool enable)
     {
-        ring_config_send_register(accountID.toStdString(), enable);
+        DRing::sendRegister(accountID.toStdString(), enable);
     }
 
     void setAccountDetails(const QString &accountID, MapStringString details)
     {
-        ring_config_set_account_details(accountID.toStdString(),
+        DRing::setAccountDetails(accountID.toStdString(),
             convertMap(details));
     }
 
     void setAccountsOrder(const QString &order)
     {
-        ring_config_set_accounts_order(order.toStdString());
+        DRing::setAccountsOrder(order.toStdString());
     }
 
-    void setActiveAudioCodecList(const QStringList &list, const QString &accountID)
+    void setActiveCodecList(const QString &accountID, VectorUInt &list)
     {
-        ring_config_set_active_audio_codec_list(
-            convertStringList(list), accountID.toStdString());
+        //const std::vector<unsigned int> converted = convertStringList(list);
+        DRing::setActiveCodecList(accountID.toStdString(),
+        list.toStdVector());
     }
 
     void setAgcState(bool enabled)
     {
-        //TODO: update API
-        ring_config_enable_agc(enabled);
+        DRing::setAgcState(enabled);
     }
 
     void setAudioInputDevice(int index)
     {
-        ring_config_set_audio_input_device(index);
+        DRing::setAudioInputDevice(index);
     }
 
     bool setAudioManager(const QString &api)
     {
-        return ring_config_set_audio_manager(api.toStdString());
+        return DRing::setAudioManager(api.toStdString());
     }
 
     void setAudioOutputDevice(int index)
     {
-        ring_config_set_audio_output_device(index);
+        DRing::setAudioOutputDevice(index);
     }
 
     void setAudioPlugin(const QString &audioPlugin)
     {
-        ring_config_set_audio_plugin(audioPlugin.toStdString());
+        DRing::setAudioPlugin(audioPlugin.toStdString());
     }
 
     void setAudioRingtoneDevice(int index)
     {
-        ring_config_set_audio_ringtone_device(index);
+        DRing::setAudioRingtoneDevice(index);
     }
 
     void setCredentials(const QString &accountID, VectorMapStringString credentialInformation)
@@ -453,48 +449,53 @@ public Q_SLOTS: // METHODS
         for (auto x : credentialInformation) {
             temp.push_back(convertMap(x));
         }
-        ring_config_set_credentials(accountID.toStdString(), temp);
+        DRing::setCredentials(accountID.toStdString(), temp);
     }
 
     void setHistoryLimit(int days)
     {
-        ring_config_set_history_limit(days);
+        DRing::setHistoryLimit(days);
     }
 
     void setHookSettings(MapStringString settings)
     {
-        ring_config_set_hook_settings(convertMap(settings));
+        DRing::setHookSettings(convertMap(settings));
     }
 
     void setIsAlwaysRecording(bool enabled)
     {
-        //TODO: update API
-        ring_config_set_always_recording(enabled);
+        DRing::setIsAlwaysRecording(enabled);
     }
 
     void setNoiseSuppressState(bool state)
     {
-        ring_config_set_noise_suppress_state(state);
+        DRing::setNoiseSuppressState(state);
     }
 
     void setRecordPath(const QString &rec)
     {
-        ring_config_set_record_path(rec.toStdString());
+        DRing::setRecordPath(rec.toStdString());
     }
 
     void setShortcuts(MapStringString shortcutsMap)
     {
-        ring_config_set_shortcuts(convertMap(shortcutsMap));
+        DRing::setShortcuts(convertMap(shortcutsMap));
     }
 
     void setTlsSettings(MapStringString details)
     {
-        ring_config_set_tls_settings(convertMap(details));
+        DRing::setTlsSettings(convertMap(details));
     }
 
     void setVolume(const QString &device, double value)
     {
-        ring_config_set_volume(device.toStdString(), value);
+        DRing::setVolume(device.toStdString(), value);
+    }
+
+    MapStringString getVolatileAccountDetails(const QString &accountID)
+    {
+        MapStringString temp = convertMap(DRing::getVolatileAccountDetails(accountID.toStdString()));
+        return temp;
     }
 
 Q_SIGNALS: // SIGNALS
@@ -506,6 +507,7 @@ Q_SIGNALS: // SIGNALS
     void sipRegistrationStateChanged(const QString &accountID, const QString &state, int code);
     void stunStatusSuccess(const QString &message);
     void errorAlert(int code);
+    void volatileAccountDetailsChanged(const QString &accountID, MapStringString details);
 
 };
 
diff --git a/src/qtwrapper/conversions_wrap.hpp b/src/qtwrapper/conversions_wrap.hpp
index 39cf326ece65886731d3feabe66225e75ebfb01a..c65c4d2d3339a27b931192eafd6552dde83c5ea6 100644
--- a/src/qtwrapper/conversions_wrap.hpp
+++ b/src/qtwrapper/conversions_wrap.hpp
@@ -22,7 +22,7 @@
 #include <string>
 #include <vector>
 
-#include "../dbus/metatypes.h"
+#include "../typedefs.h"
 
 #define Q_NOREPLY
 
@@ -50,6 +50,14 @@ inline QStringList convertStringList(const std::vector<std::string>& v) {
     return temp;
 }
 
+inline VectorString convertVectorString(const std::vector<std::string>& v) {
+    VectorString temp;
+    for (const auto& x : v) {
+        temp.push_back(QString(x.c_str()));
+    }
+    return temp;
+}
+
 inline std::vector<std::string> convertStringList(const QStringList& v) {
     std::vector<std::string> temp;
     for (const auto& x : v) {
diff --git a/src/qtwrapper/instancemanager.cpp b/src/qtwrapper/instancemanager.cpp
index 1feb9f3e9a6eb27ccd23e2eb933c157f2a1a6f79..f6c4661074cdd3afee2cf43178ef0a70b42db10b 100644
--- a/src/qtwrapper/instancemanager.cpp
+++ b/src/qtwrapper/instancemanager.cpp
@@ -1,6 +1,7 @@
 /****************************************************************************
  *   Copyright (C) 2009-2014 by Savoir-Faire Linux                          *
  *   Authors : Alexandre Lision alexandre.lision@savoirfairelinux.com       *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>      *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -30,25 +31,45 @@ void pollEvents();
 
 InstanceInterface::InstanceInterface() : m_pTimer(nullptr)
 {
+    using namespace std::placeholders;
+
+    using std::bind;
+    using DRing::exportable_callback;
+    using DRing::CallSignal;
+    using DRing::ConfigurationSignal;
+    using DRing::PresenceSignal;
+
+    #ifdef ENABLE_VIDEO
+    using DRing::VideoSignal;
+    #endif
+
    m_pTimer = new QTimer(this);
    m_pTimer->setInterval(50);
    connect(m_pTimer,&QTimer::timeout,this,&pollEvents);
    m_pTimer->start();
-   ringFlags |= RING_FLAG_DEBUG;
-   ringFlags |= RING_FLAG_CONSOLE_LOG;
+   ringFlags |= DRing::DRING_FLAG_DEBUG;
+   ringFlags |= DRing::DRING_FLAG_CONSOLE_LOG;
 
-   evHandlers = {
-       .call_ev_handlers = DBus::CallManager::instance().call_ev_handlers,
-       .config_ev_handlers = DBus::ConfigurationManager::instance().config_ev_handlers,
-       .pres_ev_handlers = DBus::PresenceManager::instance().pres_ev_handlers,
-   #ifdef ENABLE_VIDEO
-      .video_ev_handler = DBus::VideoManager::instance().video_ev_handlers
-   #endif /* ENABLE_VIDEO */
-   };
+   const std::map<DRing::EventHandlerKey, std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>> evHandlers = {
+        { // Call event handlers
+            DRing::EventHandlerKey::CALL, DBus::CallManager::instance().callHandlers
+        },
+        { // Configuration event handlers
+            DRing::EventHandlerKey::CONFIG, DBus::ConfigurationManager::instance().confHandlers
+        },
+        { // Presence event handlers
+            DRing::EventHandlerKey::PRESENCE, DBus::PresenceManager::instance().presHandlers
+        }
+#ifdef ENABLE_VIDEO
+        ,{ // Video event handlers
+            DRing::EventHandlerKey::VIDEO, DBus::VideoManager::instance().videoHandlers
+        }
+#endif
+    };
 
-   ring_init(&evHandlers, static_cast<ring_init_flag>(ringFlags));
+    DRing::init(evHandlers, static_cast<DRing::InitFlag>(ringFlags));
 
-   printf("INITIATED DAEMON\n");
+    printf("INITIATED DAEMON\n");
 }
 
 InstanceInterface::~InstanceInterface()
@@ -58,12 +79,10 @@ InstanceInterface::~InstanceInterface()
 
 void pollEvents()
 {
-   ring_poll_events();
+    DRing::poll_events();
 }
 
 bool InstanceInterface::isConnected()
 {
    return true;
 }
-
-
diff --git a/src/qtwrapper/instancemanager_wrap.h b/src/qtwrapper/instancemanager_wrap.h
index 2defef3ee0846938384a8a11815d14623a8aa943..a4dc60471a983f802bf880fc1ba51620e35571db 100644
--- a/src/qtwrapper/instancemanager_wrap.h
+++ b/src/qtwrapper/instancemanager_wrap.h
@@ -1,6 +1,7 @@
 /******************************************************************************
  *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
  *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>        *
  *                                                                            *
  *   This library is free software; you can redistribute it and/or            *
  *   modify it under the terms of the GNU Lesser General Public               *
@@ -28,7 +29,7 @@
 #include <QTimer>
 
 #include "dring.h"
-#include "../dbus/metatypes.h"
+#include "../typedefs.h"
 #include "conversions_wrap.hpp"
 
 /*
@@ -55,7 +56,6 @@ public Q_SLOTS: // METHODS
 
 private:
    QTimer* m_pTimer;
-   ring_ev_handlers evHandlers;
 
 Q_SIGNALS: // SIGNALS
    void started();
diff --git a/src/qtwrapper/presencemanager_wrap.h b/src/qtwrapper/presencemanager_wrap.h
index f95fc321a6ddd2a3b2c61cf6d6a47b8eb8694276..14cbba02ee15395b5fcce7625c978ce99dd0ffa5 100644
--- a/src/qtwrapper/presencemanager_wrap.h
+++ b/src/qtwrapper/presencemanager_wrap.h
@@ -1,6 +1,7 @@
 /******************************************************************************
  *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
  *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>        *
  *                                                                            *
  *   This library is free software; you can redistribute it and/or            *
  *   modify it under the terms of the GNU Lesser General Public               *
@@ -27,9 +28,8 @@
 #include <QtCore/QVariant>
 #include <QtCore/QTimer>
 
-#include <dring.h>
-
-#include "../dbus/metatypes.h"
+#include "typedefs.h"
+#include <presencemanager_interface.h>
 #include "conversions_wrap.hpp"
 
 
@@ -40,46 +40,54 @@ class PresenceManagerInterface: public QObject
 {
     Q_OBJECT
 public:
+
+    std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> presHandlers;
+
     PresenceManagerInterface()
     {
-        pres_ev_handlers = {
-            .on_new_server_subscription_request = [this] (const std::string &buddyUri) {
-                      QTimer::singleShot(0, [this,buddyUri] {
-                            emit this->newServerSubscriptionRequest(QString(buddyUri.c_str()));
-                      });
-            },
-            .on_server_error = [this] (const std::string &accountID, const std::string &error, const std::string &msg) {
-                      QTimer::singleShot(0, [this,accountID, error, msg] {
-                            emit this->serverError(QString(accountID.c_str()), QString(error.c_str()), QString(msg.c_str()));
-                      });
-            },
-            .on_new_buddy_notification = [this] (const std::string &accountID, const std::string &buddyUri, bool status, const std::string &lineStatus) {
-                      QTimer::singleShot(0, [this,accountID, buddyUri, status, lineStatus] {
-                            emit this->newBuddyNotification(QString(accountID.c_str()), QString(buddyUri.c_str()), status, QString(lineStatus.c_str()));
-                      });
-            },
-            .on_subscription_state_change = [this] (const std::string &accountID, const std::string &buddyUri, bool state) {
-                      QTimer::singleShot(0, [this,accountID, buddyUri, state] {
-                            emit this->subscriptionStateChanged(QString(accountID.c_str()), QString(buddyUri.c_str()), state);
-                      });
-            }
-        };
+        using DRing::exportable_callback;
+        using DRing::PresenceSignal;
+
+        presHandlers = {
+            exportable_callback<PresenceSignal::NewServerSubscriptionRequest>(
+                [this] (const std::string &buddyUri) {
+                       QTimer::singleShot(0, [this,buddyUri] {
+                             emit this->newServerSubscriptionRequest(QString(buddyUri.c_str()));
+                       });
+            }),
+            exportable_callback<PresenceSignal::ServerError>(
+                [this] (const std::string &accountID, const std::string &error, const std::string &msg) {
+                       QTimer::singleShot(0, [this,accountID, error, msg] {
+                             emit this->serverError(QString(accountID.c_str()), QString(error.c_str()), QString(msg.c_str()));
+                       });
+            }),
+            exportable_callback<PresenceSignal::NewBuddyNotification>(
+                [this] (const std::string &accountID, const std::string &buddyUri, bool status, const std::string &lineStatus) {
+                       QTimer::singleShot(0, [this,accountID, buddyUri, status, lineStatus] {
+                             emit this->newBuddyNotification(QString(accountID.c_str()), QString(buddyUri.c_str()), status, QString(lineStatus.c_str()));
+                       });
+            }),
+            exportable_callback<PresenceSignal::SubscriptionStateChanged>(
+                [this] (const std::string &accountID, const std::string &buddyUri, bool state) {
+                       QTimer::singleShot(0, [this,accountID, buddyUri, state] {
+                             emit this->subscriptionStateChanged(QString(accountID.c_str()), QString(buddyUri.c_str()), state);
+                       });
+            })
+         };
     }
 
     ~PresenceManagerInterface() {}
 
-    ring_pres_ev_handlers pres_ev_handlers;
-
 public Q_SLOTS: // METHODS
     void answerServerRequest(const QString &uri, bool flag)
     {
-        ring_pres_answer_server_request(uri.toStdString(), flag);
+        DRing::answerServerRequest(uri.toStdString(), flag);
     }
 
     VectorMapStringString getSubscriptions(const QString &accountID)
     {
         VectorMapStringString temp;
-        for (auto x : ring_pres_get_subscriptions(accountID.toStdString())) {
+        for (auto x : DRing::getSubscriptions(accountID.toStdString())) {
             temp.push_back(convertMap(x));
         }
         return temp;
@@ -87,17 +95,17 @@ public Q_SLOTS: // METHODS
 
     void publish(const QString &accountID, bool status, const QString &note)
     {
-        ring_pres_publish(accountID.toStdString(), status, note.toStdString());
+        DRing::publish(accountID.toStdString(), status, note.toStdString());
     }
 
     void setSubscriptions(const QString &accountID, const QStringList &uriList)
     {
-        ring_pres_set_subscriptions(accountID.toStdString(), convertStringList(uriList));
+        DRing::setSubscriptions(accountID.toStdString(), convertStringList(uriList));
     }
 
     void subscribeBuddy(const QString &accountID, const QString &uri, bool flag)
     {
-        ring_pres_subscribe_buddy(accountID.toStdString(), uri.toStdString(), flag);
+        DRing::subscribeBuddy(accountID.toStdString(), uri.toStdString(), flag);
     }
 
 Q_SIGNALS: // SIGNALS
diff --git a/src/qtwrapper/videomanager_wrap.h b/src/qtwrapper/videomanager_wrap.h
index 4006600d456668689f2dac6ab4176f1400ee58cc..b9312fbd7f53c25e7e1f809c3e9169ba80fc00de 100644
--- a/src/qtwrapper/videomanager_wrap.h
+++ b/src/qtwrapper/videomanager_wrap.h
@@ -1,6 +1,7 @@
 /******************************************************************************
  *   Copyright (C) 2014 by Savoir-Faire Linux                                 *
  *   Author : Philippe Groarke <philippe.groarke@savoirfairelinux.com>        *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>        *
  *                                                                            *
  *   This library is free software; you can redistribute it and/or            *
  *   modify it under the terms of the GNU Lesser General Public               *
@@ -25,9 +26,11 @@
 #include <QtCore/QString>
 #include <QtCore/QStringList>
 #include <QtCore/QVariant>
+#include <QtCore/QTimer>
 
-#include <dring.h>
-#include "../dbus/metatypes.h"
+#include <videomanager_interface.h>
+
+#include "typedefs.h"
 #include "conversions_wrap.hpp"
 
 /*
@@ -41,22 +44,27 @@ public:
     VideoManagerInterface()
     {
 #ifdef ENABLE_VIDEO
-        video_ev_handlers = {
-            .on_device_event = [this] () { 
-                  QTimer::singleShot(0, [this] {
-                      emit this->deviceEvent();
-                  });
-            },
-            .on_start_decoding = [this] (const std::string &id, const std::string &shmPath, int width, int height, bool isMixer) {
-                  QTimer::singleShot(0, [this,id, shmPath, width, height, isMixer] {
-                     emit this->startedDecoding(QString(id.c_str()), QString(shmPath.c_str()), width, height, isMixer);
-                  });
-            },
-            .on_stop_decoding = [this] (const std::string &id, const std::string &shmPath, bool isMixer) {
-                  QTimer::singleShot(0, [this,id, shmPath, isMixer] {
-                     emit this->stoppedDecoding(QString(id.c_str()), QString(shmPath.c_str()), isMixer);
-                  });
-            }
+        using DRing::exportable_callback;
+        using DRing::VideoSignal;
+        videoHandlers = {
+            exportable_callback<VideoSignal::DeviceEvent>(
+                [this] () {
+                   QTimer::singleShot(0, [this] {
+                       emit this->deviceEvent();
+                   });
+            }),
+            exportable_callback<VideoSignal::DecodingStarted>(
+                [this] (const std::string &id, const std::string &shmPath, int width, int height, bool isMixer) {
+                   QTimer::singleShot(0, [this,id, shmPath, width, height, isMixer] {
+                      emit this->startedDecoding(QString(id.c_str()), QString(shmPath.c_str()), width, height, isMixer);
+                   });
+            }),
+            exportable_callback<VideoSignal::DecodingStopped>(
+                [this] (const std::string &id, const std::string &shmPath, bool isMixer) {
+                   QTimer::singleShot(0, [this,id, shmPath, isMixer] {
+                      emit this->stoppedDecoding(QString(id.c_str()), QString(shmPath.c_str()), isMixer);
+                   });
+            })
         };
 #endif
     }
@@ -64,14 +72,14 @@ public:
     ~VideoManagerInterface() {}
 
 #ifdef ENABLE_VIDEO
-    ring_video_ev_handlers video_ev_handlers;
+    std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> videoHandlers;
 #endif
 
 public Q_SLOTS: // METHODS
     void applySettings(const QString &name, MapStringString settings)
     {
 #ifdef ENABLE_VIDEO
-        ring_video_apply_settings(
+        DRing::applySettings(
             name.toStdString(), convertMap(settings));
 #endif
     }
@@ -82,12 +90,12 @@ public Q_SLOTS: // METHODS
         MapStringMapStringVectorString ret;
 #ifdef ENABLE_VIDEO
         std::map<std::string, std::map<std::string, std::vector<std::string>>> temp;
-        temp = ring_video_get_capabilities(name.toStdString());
+        temp = DRing::getCapabilities(name.toStdString());
 
         for (auto& x : temp) {
-                map<QString, QStringList> ytemp;
-            for (auto& y : x) {
-                ytemp[QString(y.first.c_str())] = convertStringList(y.second);
+                QMap<QString, VectorString> ytemp;
+            for (auto& y : x.second) {
+                ytemp[QString(y.first.c_str())] = convertVectorString(y.second);
             }
             ret[QString(x.first.c_str())] = ytemp;
         }
@@ -95,33 +103,11 @@ public Q_SLOTS: // METHODS
         return ret;
     }
 
-    VectorMapStringString getCodecs(const QString &accountID)
-    {
-        VectorMapStringString temp;
-#ifdef ENABLE_VIDEO
-        for (auto x : ring_video_get_codecs(accountID.toStdString())) {
-            temp.push_back(convertMap(x));
-        }
-#endif
-        return temp;
-    }
-
-    Q_DECL_DEPRECATED QString getCurrentCodecName(const QString &callID)
-    {
-#ifdef ENABLE_VIDEO
-        QString temp(
-            ring_video_get_current_codec_name(callID.toStdString()).c_str());
-#else
-        QString temp;
-#endif
-        return temp;
-    }
-
     QString getDefaultDevice()
     {
 #ifdef ENABLE_VIDEO
         QString temp(
-            ring_video_get_default_device().c_str());
+            DRing::getDefaultDevice().c_str());
 #else
         QString temp;
 #endif
@@ -132,7 +118,7 @@ public Q_SLOTS: // METHODS
     {
 #ifdef ENABLE_VIDEO
         QStringList temp =
-            convertStringList(ring_video_get_device_list());
+            convertStringList(DRing::getDeviceList());
 #else
         QStringList temp;
 #endif
@@ -143,7 +129,7 @@ public Q_SLOTS: // METHODS
     {
 #ifdef ENABLE_VIDEO
         MapStringString temp =
-            convertMap(ring_video_get_settings(device.toStdString()));
+            convertMap(DRing::getSettings(device.toStdString()));
 #else
         MapStringString temp;
 #endif
@@ -153,48 +139,37 @@ public Q_SLOTS: // METHODS
     bool hasCameraStarted()
     {
 #ifdef ENABLE_VIDEO
-        return ring_video_has_camera_started();
+        return DRing::hasCameraStarted();
 #else
         return false;
 #endif
     }
 
-    void setCodecs(const QString &accountID, VectorMapStringString details)
-    {
-#ifdef ENABLE_VIDEO
-        std::vector<std::map<std::string, std::string> > temp;
-        for (auto x : details) {
-            temp.push_back(convertMap(x));
-        }
-        ring_video_set_codecs(accountID.toStdString(), temp);
-#endif
-    }
-
     void setDefaultDevice(const QString &name)
     {
 #ifdef ENABLE_VIDEO
-        ring_video_set_default_device(name.toStdString());
+        DRing::setDefaultDevice(name.toStdString());
 #endif
     }
 
     void startCamera()
     {
 #ifdef ENABLE_VIDEO
-        ring_video_start_camera();
+        DRing::startCamera();
 #endif
     }
 
     void stopCamera()
     {
 #ifdef ENABLE_VIDEO
-        ring_video_stop_camera();
+        DRing::stopCamera();
 #endif
     }
 
     bool switchInput(const QString &resource)
     {
 #ifdef ENABLE_VIDEO
-        return ring_video_switch_input(resource.toStdString());
+        return DRing::switchInput(resource.toStdString());
 #else
         return false;
 #endif
diff --git a/src/typedefs.h b/src/typedefs.h
index f53d49d961af4a83badc1d527b3b8baddc1cbb2d..c41ca8fb924abd777444e015159bbac5dece23d8 100644
--- a/src/typedefs.h
+++ b/src/typedefs.h
@@ -23,7 +23,7 @@
 //Qt
 #include <QtCore/QMetaType>
 #include <QtCore/QMap>
-#include <QVector>
+#include <QtCore/QVector>
 #include <QtCore/QString>
 #include <QtCore/QDebug>
 
@@ -32,10 +32,16 @@
 #include <type_traits>
 
 //Typedefs (required to avoid '<' and '>' in the DBus XML)
-typedef QMap<QString, QString> MapStringString;
-typedef QVector< QMap<QString, QString> > VectorMapStringString;
-typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString;
-typedef QMap<QString, int> MapStringInt;
+typedef QMap<QString, QString>                              MapStringString               ;
+typedef QMap<QString, int>                                  MapStringInt                  ;
+typedef QVector<int>                                        VectorInt                     ;
+typedef QVector<uint>                                       VectorUInt                    ;
+typedef QVector< QMap<QString, QString> >                   VectorMapStringString         ;
+typedef QVector< QString >                                  VectorString                  ;
+typedef QMap< QString, QMap< QString, QVector<QString> > >  MapStringMapStringVectorString;
+typedef QMap< QString, QVector<QString> >                   MapStringVectorString         ;
+typedef QMap< QString, QMap< QString, QStringList > >       MapStringMapStringStringList  ;
+typedef QMap< QString, QStringList >                        MapStringStringList           ;
 
 template<class T, class E>
 struct TypedStateMachine
diff --git a/src/video/device.cpp b/src/video/device.cpp
index 23e9791d7548de4ea6ccb894bd412872c8e00302..6ac6c65048579e1517ec1c415c0e9c32ce28ed89 100644
--- a/src/video/device.cpp
+++ b/src/video/device.cpp
@@ -23,6 +23,7 @@
 #include "resolution.h"
 #include "rate.h"
 #include "channel.h"
+#include "renderer.h"
 
 //Ring private
 #include "../private/videochannel_p.h"
diff --git a/src/video/devicemodel.cpp b/src/video/devicemodel.cpp
index 45e55ee4c25bc83065d856ed2d1d9d6b9a0f28c1..db84231bae2d080c8178eeb0ecbba6d41a9a2607 100644
--- a/src/video/devicemodel.cpp
+++ b/src/video/devicemodel.cpp
@@ -22,6 +22,7 @@
 #include "../dbus/videomanager.h"
 
 #include <QtCore/QCoreApplication>
+#include <QtCore/QTimer>
 
 Video::DeviceModel* Video::DeviceModel::m_spInstance = nullptr;
 
diff --git a/src/video/manager.cpp b/src/video/manager.cpp
index 6c6ee4edc8d1514f84faaccafd023fd7a65c99b9..6212b77921f7893836eb5ee2ae36133224b1cbb9 100644
--- a/src/video/manager.cpp
+++ b/src/video/manager.cpp
@@ -1,6 +1,7 @@
 /****************************************************************************
  *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
- *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *   Authors : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
+ *             Alexandre Lision <alexandre.lision@savoirfairelinux.com>     *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -30,7 +31,13 @@
 #include "channel.h"
 #include "rate.h"
 #include "resolution.h"
-#include "../private/videorate_p.h"
+#include "private/videorate_p.h"
+#if defined(Q_OS_DARWIN)
+#include "private/directrenderer.h"
+#else
+#include "private/shmrenderer.h"
+#endif
+
 
 //Static member
 Video::Manager* Video::Manager::m_spInstance = nullptr;
@@ -46,10 +53,8 @@ public:
    //Attributes
    bool           m_PreviewState;
    uint           m_BufferSize  ;
-   uint           m_ShmKey      ;
-   uint           m_SemKey      ;
    QMutex*        m_SSMutex     ;
-   QHash<QString,Video::Renderer*> m_lRenderers;
+   QHash<QByteArray,Video::Renderer*> m_lRenderers;
 
 private:
    Video::Manager* q_ptr;
@@ -63,9 +68,9 @@ private Q_SLOTS:
 }
 
 Video::ManagerPrivate::ManagerPrivate(Video::Manager* parent) : QObject(parent), q_ptr(parent),
-m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex())
+m_BufferSize(0),m_PreviewState(false),m_SSMutex(new QMutex())
 {
-   
+
 }
 
 ///Constructor
@@ -92,14 +97,14 @@ Video::Manager* Video::Manager::instance()
    return m_spInstance;
 }
 
-///Return the call renderer or nullptr
+///Return the call Renderer or nullptr
 Video::Renderer* Video::Manager::getRenderer(const Call* call) const
 {
    if (!call) return nullptr;
-   return d_ptr->m_lRenderers[call->dringId()];
+   return d_ptr->m_lRenderers[call->dringId().toLatin1()];
 }
 
-///Get the video preview renderer
+///Get the video preview Renderer
 Video::Renderer* Video::Manager::previewRenderer()
 {
    if (!d_ptr->m_lRenderers["local"]) {
@@ -108,7 +113,12 @@ Video::Renderer* Video::Manager::previewRenderer()
          qWarning() << "Misconfigured video device";
          return nullptr;
       }
-      d_ptr->m_lRenderers["local"] = new Video::Renderer("local","",res->size());
+#if defined(Q_OS_DARWIN)
+      d_ptr->m_lRenderers["local"] = new Video::DirectRenderer("local", res->size());
+
+#else
+      d_ptr->m_lRenderers["local"] = new Video::ShmRenderer("local","",res->size());
+#endif
    }
    return d_ptr->m_lRenderers["local"];
 }
@@ -151,43 +161,41 @@ void Video::ManagerPrivate::deviceEvent()
 ///A video is not being rendered
 void Video::ManagerPrivate::startedDecoding(const QString& id, const QString& shmPath, int width, int height)
 {
-   Q_UNUSED(id)
 
    QSize res = QSize(width,height);
-//    if (Video::DeviceModel::instance()->activeDevice()
-//       && Video::DeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->width() == width) {
-//       //FIXME flawed logic
-//       res = Video::DeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->size();
-//    }
-//    else {
-//       res =  QSize(width,height);
-//    }
-
-   if (m_lRenderers[id] == nullptr ) {
-      m_lRenderers[id] = new Video::Renderer(id,shmPath,res);
-      m_lRenderers[id]->moveToThread(q_ptr);
+
+   if (m_lRenderers[id.toLatin1()] == nullptr ) {
+       #if defined(Q_OS_DARWIN)
+             m_lRenderers["local"] = new Video::DirectRenderer("local", res);
+       #else
+             m_lRenderers["local"] = new Video::ShmRenderer("local",shmPath,res);
+       #endif
+      m_lRenderers[id.toLatin1()]->moveToThread(q_ptr);
       if (!q_ptr->isRunning())
          q_ptr->start();
    }
    else {
-      Video::Renderer* renderer = m_lRenderers[id];
-      renderer->setShmPath(shmPath);
-      renderer->setSize(res);
+      Video::Renderer* Renderer = m_lRenderers[id.toLatin1()];
+      //TODO: do direct renderer stuff here
+      m_lRenderers[id.toLatin1()]->setSize(res);
+#if !defined(Q_OS_DARWIN)
+      static_cast<ShmRenderer*>(m_lRenderers[id.toLatin1()])->setShmPath(shmPath);
+#endif
    }
 
-   m_lRenderers[id]->startRendering();
+   m_lRenderers[id.toLatin1()]->startRendering();
    Video::Device* dev = Video::DeviceModel::instance()->getDevice(id);
    if (dev) {
-      emit dev->renderingStarted(m_lRenderers[id]);
+      emit dev->renderingStarted(m_lRenderers[id.toLatin1()]);
    }
    if (id != "local") {
       qDebug() << "Starting video for call" << id;
-      emit q_ptr->videoCallInitiated(m_lRenderers[id]);
+      emit q_ptr->videoCallInitiated(m_lRenderers[id.toLatin1()]);
    }
    else {
       m_PreviewState = true;
       emit q_ptr->previewStateChanged(true);
-      emit q_ptr->previewStarted(m_lRenderers[id]);
+      emit q_ptr->previewStarted(m_lRenderers[id.toLatin1()]);
    }
 }
 
@@ -195,11 +203,11 @@ void Video::ManagerPrivate::startedDecoding(const QString& id, const QString& sh
 void Video::ManagerPrivate::stoppedDecoding(const QString& id, const QString& shmPath)
 {
    Q_UNUSED(shmPath)
-   Video::Renderer* r = m_lRenderers[id];
+   Video::Renderer* r = m_lRenderers[id.toLatin1()];
    if ( r ) {
       r->stopRendering();
    }
-   qDebug() << "Video stopped for call" << id <<  "Renderer found:" << (m_lRenderers[id] != nullptr);
+   qDebug() << "Video stopped for call" << id <<  "Renderer found:" << (m_lRenderers[id.toLatin1()] != nullptr);
 //    emit videoStopped();
 
    Video::Device* dev = Video::DeviceModel::instance()->getDevice(id);
@@ -212,7 +220,7 @@ void Video::ManagerPrivate::stoppedDecoding(const QString& id, const QString& sh
       emit q_ptr->previewStopped(r);
    }
 //    r->mutex()->lock();
-   m_lRenderers[id] = nullptr;
+   m_lRenderers[id.toLatin1()] = nullptr;
    delete r;
 }
 
diff --git a/src/video/manager.h b/src/video/manager.h
index 634fc898f87c8024d8f574b39f3c1a59e918f0c8..9e127bc3a4c1c70a27e8017cdfe784c5ce75a3b8 100644
--- a/src/video/manager.h
+++ b/src/video/manager.h
@@ -84,8 +84,8 @@ Q_SIGNALS:
    void videoCallInitiated(Video::Renderer*);
    ///The preview started/stopped
    void previewStateChanged(bool startStop);
-   void previewStarted(Video::Renderer* renderer);
-   void previewStopped(Video::Renderer* renderer);
+   void previewStarted(Video::Renderer* Renderer);
+   void previewStopped(Video::Renderer* Renderer);
 
 };
 
diff --git a/src/video/renderer.cpp b/src/video/renderer.cpp
index f54cc4ff0a0828678ef994e77bcff6cf997339d3..384978767c609894c7d4c18cc9b49025217a7933 100644
--- a/src/video/renderer.cpp
+++ b/src/video/renderer.cpp
@@ -1,6 +1,6 @@
 /****************************************************************************
  *   Copyright (C) 2012-2015 by Savoir-Faire Linux                          *
- *   Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
+ *   Author : Alexandre Lision <alexandre.lision@savoirfairelinux.com>      *
  *                                                                          *
  *   This library is free software; you can redistribute it and/or          *
  *   modify it under the terms of the GNU Lesser General Public             *
@@ -17,399 +17,88 @@
  ***************************************************************************/
 #include "renderer.h"
 
-#include <QtCore/QDebug>
-#include <QtCore/QMutex>
-#include <QtCore/QThread>
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <semaphore.h>
-#include <errno.h>
-
-
-#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME 0
-#endif
-
-#include <QtCore/QTimer>
-#include "manager.h"
-#include "resolution.h"
-
-///Shared memory object
-struct SHMHeader{
-   sem_t notification;
-   sem_t mutex;
-
-   unsigned m_BufferGen;
-   int m_BufferSize;
-   /* The header will be aligned on 16-byte boundaries */
-   char padding[8];
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-pedantic"
-   char m_Data[];
-#pragma GCC diagnostic pop
-};
-
-namespace Video {
-
-class RendererPrivate : public QObject
-{
-   Q_OBJECT
-public:
-   RendererPrivate(Video::Renderer* parent);
+//Ring
+#include "private/videorenderer_p.h"
 
-   //Attributes
-   QString           m_ShmPath    ;
-   int               fd           ;
-   SHMHeader*        m_pShmArea   ;
-   signed int        m_ShmAreaLen ;
-   uint              m_BufferGen  ;
-   bool              m_isRendering;
-   QTimer*           m_pTimer     ;
-   QByteArray        m_Frame[2]   ;
-   bool              m_FrameIdx   ;
-   QSize             m_pSize      ;
-   QMutex*           m_pMutex     ;
-   QMutex*           m_pSSMutex   ;
-   QString           m_Id         ;
-   int               m_fpsC       ;
-   int               m_Fps        ;
-   QTime             m_CurrentTime;
-
-   //Constants
-   static const int TIMEOUT_SEC = 1; // 1 second
-
-   //Helpers
-   timespec createTimeout();
-   bool     shmLock      ();
-   void     shmUnlock    ();
-   bool     renderToBitmap();
-
-private:
-   Video::Renderer* q_ptr;
-
-private Q_SLOTS:
-   void timedEvents();
-};
-
-}
+//Qt
+#include <QtCore/QMutex>
 
 Video::RendererPrivate::RendererPrivate(Video::Renderer* parent) : QObject(parent), q_ptr(parent),
-   fd(-1),m_fpsC(0),m_Fps(0),
-   m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0),
-   m_isRendering(false),m_pTimer(nullptr),m_pMutex(new QMutex()),
-   m_FrameIdx(false),m_pSSMutex(new QMutex())
+m_pMutex(new QMutex()), m_FrameIdx(false)
 {
 }
 
-///Constructor
-Video::Renderer::Renderer(const QString& id, const QString& shmPath, const QSize& res): QObject(nullptr), d_ptr(new RendererPrivate(this))
+Video::Renderer::Renderer(const QByteArray& id, const QSize& res)
 {
-   d_ptr->m_ShmPath = shmPath;
-   d_ptr->m_Id      = id;
-   d_ptr->m_pSize   = res;
-   setObjectName("Video::Renderer:"+id);
+  d_ptr->m_pSize = res;
+  d_ptr->m_Id = id;
 }
 
-///Destructor
 Video::Renderer::~Renderer()
-{
-   stopShm();
-   //delete m_pShmArea;
-}
-
-///Get the data from shared memory and transform it into a QByteArray
-bool Video::RendererPrivate::renderToBitmap()
-{
-#ifdef Q_OS_LINUX
-   if (!m_isRendering) {
-      return false;
-   }
-
-   if (!shmLock()) {
-      return false;
-   }
-
-   if(!Video::Manager::instance()->startStopMutex()->tryLock())
-      return false;
-
-   // wait for a new buffer
-   while (m_BufferGen == m_pShmArea->m_BufferGen) {
-      shmUnlock();
-
-      int err = sem_trywait(&m_pShmArea->notification);
-      // Useful for debugging
-//       switch (errno ) {
-//          case EINTR:
-//             qDebug() << "Unlock failed: Interrupted function call (POSIX.1); see signal(7)";
-//             ok = false;
-//             return QByteArray();
-//             break;
-//          case EINVAL:
-//             qDebug() << "Unlock failed: Invalid argument (POSIX.1)";
-//             ok = false;
-//             return QByteArray();
-//             break;
-//          case EAGAIN:
-//             qDebug() << "Unlock failed: Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1)";
-//             ok = false;
-//             return QByteArray();
-//             break;
-//          case ETIMEDOUT:
-//             qDebug() << "Unlock failed: Connection timed out (POSIX.1)";
-//             ok = false;
-//             return QByteArray();
-//             break;
-//       }
-      if ((err < 0) || (!shmLock())) {
-         Video::Manager::instance()->startStopMutex()->unlock();
-         return false;
-      }
-      usleep((1/60.0)*100);
-   }
-
-   if (!q_ptr->resizeShm()) {
-      qDebug() << "Could not resize shared memory";
-      Video::Manager::instance()->startStopMutex()->unlock();
-      return false;
-   }
-
-   bool otherFrame = ! m_FrameIdx;
-   if (m_Frame[otherFrame].size() != m_pShmArea->m_BufferSize)
-      m_Frame[otherFrame].resize(m_pShmArea->m_BufferSize);
-   memcpy(m_Frame[otherFrame].data(),m_pShmArea->m_Data,m_pShmArea->m_BufferSize);
-   m_BufferGen = m_pShmArea->m_BufferGen;
-   shmUnlock();
-   m_FrameIdx = !m_FrameIdx;
-
-   Video::Manager::instance()->startStopMutex()->unlock();
-   return true;
-#else
-   return false;
-#endif
-}
-
-///Connect to the shared memory
-bool Video::Renderer::startShm()
-{
-   if (d_ptr->fd != -1) {
-      qDebug() << "fd must be -1";
-      return false;
-   }
-
-   d_ptr->fd = shm_open(d_ptr->m_ShmPath.toLatin1(), O_RDWR, 0);
-   if (d_ptr->fd < 0) {
-      qDebug() << "could not open shm area " << d_ptr->m_ShmPath << ", shm_open failed:" << strerror(errno);
-      return false;
-   }
-   d_ptr->m_ShmAreaLen = sizeof(SHMHeader);
-   #pragma GCC diagnostic push
-   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-   d_ptr->m_pShmArea = (SHMHeader*) mmap(NULL, d_ptr->m_ShmAreaLen, PROT_READ | PROT_WRITE, MAP_SHARED, d_ptr->fd, 0);
-   #pragma GCC diagnostic pop
-   if (d_ptr->m_pShmArea == MAP_FAILED) {
-      qDebug() << "Could not map shm area, mmap failed";
-      return false;
-   }
-   emit started();
-   return true;
-}
-
-///Disconnect from the shared memory
-void Video::Renderer::stopShm()
-{
-   if (d_ptr->fd >= 0)
-      close(d_ptr->fd);
-   d_ptr->fd = -1;
-
-   if (d_ptr->m_pShmArea != MAP_FAILED)
-      munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen);
-   d_ptr->m_ShmAreaLen = 0;
-   d_ptr->m_pShmArea = (SHMHeader*) MAP_FAILED;
-}
-
-///Resize the shared memory
-bool Video::Renderer::resizeShm()
-{
-   while (( (unsigned int) sizeof(SHMHeader) + (unsigned int) d_ptr->m_pShmArea->m_BufferSize) > (unsigned int) d_ptr->m_ShmAreaLen) {
-      const size_t new_size = sizeof(SHMHeader) + d_ptr->m_pShmArea->m_BufferSize;
-
-      d_ptr->shmUnlock();
-      if (munmap(d_ptr->m_pShmArea, d_ptr->m_ShmAreaLen)) {
-            qDebug() << "Could not unmap shared area:" << strerror(errno);
-            return false;
-      }
-
-      #pragma GCC diagnostic push
-      #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-      d_ptr->m_pShmArea = (SHMHeader*) mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, d_ptr->fd, 0);
-      #pragma GCC diagnostic pop
-      d_ptr->m_ShmAreaLen = new_size;
-
-      if (!d_ptr->m_pShmArea) {
-            d_ptr->m_pShmArea = nullptr;
-            qDebug() << "Could not remap shared area";
-            return false;
-      }
-
-      d_ptr->m_ShmAreaLen = new_size;
-      if (!d_ptr->shmLock())
-            return true;
-   }
-   return true;
-}
-
-///Lock the memory while the copy is being made
-bool Video::RendererPrivate::shmLock()
-{
-#ifdef Q_OS_LINUX
-   return sem_trywait(&m_pShmArea->mutex) >= 0;
-#else
-   return false;
-#endif
-}
-
-///Remove the lock, allow a new frame to be drawn
-void Video::RendererPrivate::shmUnlock()
-{
-   sem_post(&m_pShmArea->mutex);
-}
-
+{}
 
 /*****************************************************************************
- *                                                                           *
- *                                   Slots                                   *
- *                                                                           *
- ****************************************************************************/
+*                                                                           *
+*                                 Getters                                   *
+*                                                                           *
+****************************************************************************/
 
-///Update the buffer
-void Video::RendererPrivate::timedEvents()
+bool Video::Renderer::isRendering() const
 {
-
-   bool ok = renderToBitmap();
-
-   if (ok) {
-
-      //Compute the FPS shown to the client
-      if (m_CurrentTime.second() != QTime::currentTime().second()) {
-         m_Fps = m_fpsC;
-         m_fpsC=0;
-         m_CurrentTime = QTime::currentTime();
-      }
-      m_fpsC++;
-
-      emit q_ptr->frameUpdated();
-   }
-   /*else {
-      qDebug() << "Frame dropped";
-      usleep(rand()%1000); //Be sure it can come back in sync
-   }*/
-}
-
-///Start the rendering loop
-void Video::Renderer::startRendering()
-{
-   Video::Manager::instance()->startStopMutex()->lock();
-   QMutexLocker locker(d_ptr->m_pMutex);
-   startShm();
-   if (!d_ptr->m_pTimer) {
-      d_ptr->m_pTimer = new QTimer(nullptr);
-
-//       m_pTimer->moveToThread(thread());
-      connect(d_ptr->m_pTimer,SIGNAL(timeout()),d_ptr.data(),SLOT(timedEvents()));
-      d_ptr->m_pTimer->setInterval(30);
-   }
-
-   if (!d_ptr->m_pTimer->isActive()) {
-      qDebug() << "Is running" << thread()->isRunning();
-      d_ptr->m_pTimer->start();
-   }
-   else
-      qDebug() << "Timer already started!";
-
-   d_ptr->m_isRendering = true;
-   Video::Manager::instance()->startStopMutex()->unlock();
+  return d_ptr->m_isRendering;
 }
 
-///Stop the rendering loop
-void Video::Renderer::stopRendering()
+QByteArray& Video::RendererPrivate::otherFrame() const
 {
-   Video::Manager::instance()->startStopMutex()->lock();
-   QMutexLocker locker(d_ptr->m_pMutex);
-   d_ptr->m_isRendering = false;
-   qDebug() << "Stopping rendering on" << d_ptr->m_Id;
-   if (d_ptr->m_pTimer)
-      d_ptr->m_pTimer->stop();
-   emit stopped();
-   stopShm();
-   Video::Manager::instance()->startStopMutex()->unlock();
-}
-
-
-/*****************************************************************************
- *                                                                           *
- *                                 Getters                                   *
- *                                                                           *
- ****************************************************************************/
-
-///Get the raw bytes directly from the SHM, not recommended, but optimal
-const char* Video::Renderer::rawData()
-{
-   return d_ptr->m_isRendering?d_ptr->m_Frame[d_ptr->m_FrameIdx].data():nullptr;
-}
-
-///Is this redenrer active
-bool Video::Renderer::isRendering()
-{
-   return d_ptr->m_isRendering;
+  static QByteArray empty;
+  return q_ptr->isRendering()?const_cast<Video::RendererPrivate*>(this)->m_Frame[!m_FrameIdx]:empty;
 }
 
 ///Return the current framerate
-const QByteArray& Video::Renderer::currentFrame()
+const QByteArray& Video::Renderer::currentFrame() const
 {
-   static QByteArray empty;
-   return d_ptr->m_isRendering?d_ptr->m_Frame[d_ptr->m_FrameIdx]:empty;
+  static QByteArray empty;
+  return isRendering()?d_ptr->m_Frame[d_ptr->m_FrameIdx]:empty;
 }
 
-///Return the current resolution
-QSize Video::Renderer::size()
+///Get id of this renderer
+QString Video::Renderer::id() const
 {
-   return d_ptr->m_pSize;
+  return d_ptr->m_Id;
 }
 
 ///Get mutex, in case renderer and views are not in the same thread
-QMutex* Video::Renderer::mutex()
+QMutex* Video::Renderer::mutex() const
 {
-   return d_ptr->m_pMutex;
+  return d_ptr->m_pMutex;
 }
 
-///Get the current frame rate of this renderer
-int Video::Renderer::fps() const
+///Return the current resolution
+QSize Video::Renderer::size() const
 {
-   return d_ptr->m_Fps;
+  return d_ptr->m_pSize;
 }
 
-
 /*****************************************************************************
  *                                                                           *
  *                                 Setters                                   *
  *                                                                           *
  ****************************************************************************/
 
-void Video::Renderer::setSize(const QSize& size)
+///Return the current resolution
+void Video::Renderer::setRendering(bool rendering) const
+{
+  d_ptr->m_isRendering = rendering;
+}
+
+void Video::Renderer::setSize(const QSize& size) const
 {
-   d_ptr->m_pSize = size;
+  d_ptr->m_pSize = size;
 }
 
-void Video::Renderer::setShmPath(const QString& path)
+void Video::RendererPrivate::updateFrameIndex()
 {
-   d_ptr->m_ShmPath = path;
+   m_FrameIdx = !m_FrameIdx;
 }
 
 #include <renderer.moc>
-
diff --git a/src/video/renderer.h b/src/video/renderer.h
index ed895255b0aa9a93032d49c1eaaef90cc46dc351..9374ca43d45e47649281167cda5e8541f1cda242 100644
--- a/src/video/renderer.h
+++ b/src/video/renderer.h
@@ -15,71 +15,72 @@
  *   You should have received a copy of the GNU General Public License      *
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
  ***************************************************************************/
-#ifndef VIDEO_RENDERER_H
-#define VIDEO_RENDERER_H
+#ifndef VIDEO_ABSTRACT_RENDERER_H
+#define VIDEO_ABSTRACT_RENDERER_H
 
 //Base
 #include <QtCore/QObject>
-#include <QtCore/QTime>
 #include <typedefs.h>
-#include <time.h>
 
 //Qt
-class QTimer;
 class QMutex;
 
 //Ring
 #include "device.h"
 
-//Private
-struct SHMHeader;
-
 
 namespace Video {
-class RendererPrivate;
 
-///Manage shared memory and convert it to QByteArray
+class RendererPrivate;
+class ShmRendererPrivate;
+class DirectRendererPrivate;
+
+/**
+ * This class provide a rendering object to be used by clients
+ * to get the video content. This object is not intended to be
+ * extended outside of the LibRingClient.
+ * 
+ * Each platform transparently provide its own implementation.
+ */
 class LIB_EXPORT Renderer : public QObject {
-   #pragma GCC diagnostic push
-   #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
-   Q_OBJECT
-   #pragma GCC diagnostic pop
-
-   public:
-      //Constructor
-      Renderer (const QString& id, const QString& shmPath, const QSize& res);
-      virtual ~Renderer();
-
-      //Mutators
-      bool resizeShm();
-      void stopShm  ();
-      bool startShm ();
-
-      //Getters
-      const char*       rawData         ()      ;
-      bool              isRendering     ()      ;
-      const QByteArray& currentFrame    ()      ;
-      QSize             size            ()      ;
-      QMutex*           mutex           ()      ;
-      int               fps             () const;
-
-      //Setters
-      void setSize(const QSize& res);
-      void setShmPath   (const QString& path);
-
-private:
-   QScopedPointer<RendererPrivate> d_ptr;
-   Q_DECLARE_PRIVATE(Renderer)
-
-public Q_SLOTS:
-   void startRendering();
-   void stopRendering ();
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+Q_OBJECT
+#pragma GCC diagnostic pop
+
+friend class Video::ShmRendererPrivate;
+friend class Video::DirectRendererPrivate;
+
+public:
+   //Constructor
+   Renderer (const QByteArray& id,  const QSize& res);
+   virtual ~Renderer();
+
+   //Getters
+   virtual bool              isRendering     () const;
+   virtual const QByteArray& currentFrame    () const;
+   virtual QSize             size            () const;
+   virtual QMutex*           mutex           () const;
+   virtual QString           id              () const;
+
+   //Setters
+   void setRendering(bool rendering)            const;
+   void setSize(const QSize& size)              const;
 
 Q_SIGNALS:
    ///Emitted when a new frame is ready
    void frameUpdated();
-   void stopped();
-   void started();
+   void stopped     ();
+   void started     ();
+
+public Q_SLOTS:
+   virtual void startRendering() = 0;
+   virtual void stopRendering () = 0;
+
+
+private:
+   QScopedPointer<RendererPrivate> d_ptr;
+   Q_DECLARE_PRIVATE(Renderer)
 
 };