diff --git a/mythtv/libs/libmythbase/mythdirs.cpp b/mythtv/libs/libmythbase/mythdirs.cpp
index 9e43148..305a4e1 100644
--- a/mythtv/libs/libmythbase/mythdirs.cpp
+++ b/mythtv/libs/libmythbase/mythdirs.cpp
@@ -16,6 +16,8 @@ static QString themedir = QString::null;
 static QString pluginsdir = QString::null;
 static QString translationsdir = QString::null;
 static QString filtersdir = QString::null;
+static QString inputsdir = QString::null;
+
 
 void InitializeMythDirs(void)
 {
@@ -69,6 +71,7 @@ void InitializeMythDirs(void)
     pluginsdir = libdir + "plugins/";
     translationsdir = sharedir + "i18n/";
     filtersdir = libdir + "filters/";
+    inputsdir = libdir + "inputevents/";
 }
 
 QString GetInstallPrefix(void) { return installprefix; }
@@ -79,6 +82,7 @@ QString GetThemesParentDir(void) { return themedir; }
 QString GetPluginsDir(void) { return pluginsdir; }
 QString GetTranslationsDir(void) { return translationsdir; }
 QString GetFiltersDir(void) { return filtersdir; }
+QString GetInputsDir(void) { return inputsdir; }
 
 // These defines provide portability for different
 // plugin file names.
diff --git a/mythtv/libs/libmythbase/mythdirs.h b/mythtv/libs/libmythbase/mythdirs.h
index 34b1047..855b69d 100644
--- a/mythtv/libs/libmythbase/mythdirs.h
+++ b/mythtv/libs/libmythbase/mythdirs.h
@@ -14,6 +14,7 @@
  MBASE_PUBLIC  QString GetPluginsDir(void);
  MBASE_PUBLIC  QString GetTranslationsDir(void);
  MBASE_PUBLIC  QString GetFiltersDir(void);
+ MBASE_PUBLIC  QString GetInputsDir(void);
 
  MBASE_PUBLIC  QString GetPluginsNameFilter(void);
  MBASE_PUBLIC  QString FindPluginName(const QString &plugname);
diff --git a/mythtv/libs/libmythui/libmythui.pro b/mythtv/libs/libmythui/libmythui.pro
index 32b839e..92f3965 100644
--- a/mythtv/libs/libmythui/libmythui.pro
+++ b/mythtv/libs/libmythui/libmythui.pro
@@ -30,7 +30,7 @@ HEADERS += mythgenerictree.h mythuibuttontree.h mythuiutils.h
 HEADERS += mythvirtualkeyboard.h mythuishape.h mythuiguidegrid.h
 HEADERS += mythrender_base.h mythfontmanager.h mythuieditbar.h
 HEADERS += mythdisplay.h mythuivideo.h mythudplistener.h
-HEADERS += mythuiexp.h
+HEADERS += mythuiexp.h mythinputmanager.h mythinputinterface.h
 
 SOURCES  = mythmainwindow.cpp mythpainter.cpp mythimage.cpp mythrect.cpp
 SOURCES += myththemebase.cpp  mythpainter_qimage.cpp mythpainter_yuva.cpp
@@ -48,6 +48,7 @@ SOURCES += mythgenerictree.cpp mythuibuttontree.cpp mythuiutils.cpp
 SOURCES += mythvirtualkeyboard.cpp mythuishape.cpp mythuiguidegrid.cpp
 SOURCES += mythfontmanager.cpp mythuieditbar.cpp
 SOURCES += mythdisplay.cpp mythuivideo.cpp mythudplistener.cpp
+SOURCES += mythinputmanager.cpp
 
 
 inc.path = $${PREFIX}/include/mythtv/libmythui/
diff --git a/mythtv/libs/libmythui/mythinputinterface.h b/mythtv/libs/libmythui/mythinputinterface.h
new file mode 100755
index 0000000..4ea9b7a
--- /dev/null
+++ b/mythtv/libs/libmythui/mythinputinterface.h
@@ -0,0 +1,129 @@
+#ifndef MYTHINPUTINTERFACE_H
+#define MYTHINPUTINTERFACE_H
+
+#include <QtPlugin>
+#include <QKeyEvent>
+
+/**
+ * \file
+ * This is the only file a plugin need to include, a plugin should normally not be link with libmythui
+ */
+
+class MythInputInterface;
+
+/**
+ * \brief Interface accessible from a input plugin.
+ */
+class MythInputManagerInterface : public QObject
+{
+    Q_OBJECT
+  public:
+    MythInputManagerInterface():QObject(){};
+
+    /**
+     * \brief an event need to be send to MythMainWindow
+     */
+    virtual void onKeyPressed(const QKeyEvent &keyEvent)=0;
+
+
+    /**
+     * \brief get a string setting
+     */
+    virtual QString getSetting(const MythInputInterface * input, const QString &key)=0;
+    /**
+     * \brief get a string setting with a default value
+     */
+    virtual QString getSetting(const MythInputInterface * input, const QString &key, const QString &defaultval)=0;
+    /**
+     * \brief save a string setting
+     */
+    virtual bool saveSetting(const MythInputInterface * input, const QString &key, const QString &newValue)=0;
+
+    /**
+     * \brief get a integer setting
+     */
+    virtual int getNumSetting(const MythInputInterface * input, const QString &key)=0;
+    /**
+     * \brief get a integer setting with a default value
+     */
+    virtual int getNumSetting(const MythInputInterface * input, const QString &key, int defaultval)=0;
+    /**
+     * \brief save an integer setting
+     */
+    virtual bool saveNumSetting(const MythInputInterface * input, const QString &key, int newValue)=0;
+
+    /**
+     * \brief get a float setting
+     */
+    virtual double getFloatSetting(const MythInputInterface * input, const QString &key)=0;
+    /**
+     * \brief get a float setting with a default value
+     */
+    virtual double getFloatSetting(const MythInputInterface * input, const QString &key, double defaultval)=0;
+    /**
+     * \brief save an float setting
+     */
+    virtual bool saveFloatSetting(const MythInputInterface * input, const QString &key, double newValue)=0;
+
+  public slots:
+    /* helper methods so a plugin can log using myth without to link with myth*/
+    virtual void logDebug(const QString &msg)=0;
+    virtual void logInfo(const QString &msg)=0;
+    virtual void logWarning(const QString &msg)=0;
+    virtual void logError(const QString &msg)=0;
+};
+
+/**
+ * \defgroup MythUI_Input_Plugin Input plugins
+ * \ingroup MythUI_Input
+ * \brief Access to a particular user input device.
+ *
+ * Read a device and produce events QKeyEvent and send them to the input manager
+ */
+
+/**
+ * \interface MythInputInterface
+ * \brief This is the interface an input plugin should implement.
+ * \ingroup MythUI_Input
+ */
+class MythInputInterface
+{
+
+  public:
+    virtual ~MythInputInterface(){};
+
+    /**
+     * \brief start the input plugin.
+     */
+    virtual void start()=0;
+
+    /**
+     * \brief stop the input plugin.
+     *
+     * When a input is stopped it should stopped calling onKeyPressed.
+     * Any socket or thread should be stopped too.
+     */
+    virtual void stop()=0;
+
+    /**
+     * \brief name of the plugin
+     */
+    virtual const QString name() const=0;
+
+    /**
+     * \brief human readable description
+     */
+    virtual const QString description() const=0;
+
+    /**
+     * \brief set the input manager
+     * The input manager is where the QKeyEvent need to be sent using \fn MythInputManagerInterface::onKeyPressed
+     */
+    virtual void setInputManager(MythInputManagerInterface * inputManager)=0;
+
+};
+
+Q_DECLARE_INTERFACE(MythInputInterface, "org.mythtv.MythInputInterface/1.0");
+
+#endif // MYTHINPUTINTERFACE_H
+
diff --git a/mythtv/libs/libmythui/mythinputmanager.cpp b/mythtv/libs/libmythui/mythinputmanager.cpp
new file mode 100755
index 0000000..38cbfa4
--- /dev/null
+++ b/mythtv/libs/libmythui/mythinputmanager.cpp
@@ -0,0 +1,226 @@
+#include "mythinputmanager.h"
+
+
+//Qt
+#include <QPluginLoader>
+#include <QString>
+#include <QCoreApplication>
+#include <QDir>
+//Myth
+#include "mythinputinterface.h"
+#include "mythlogging.h"
+#include "mythdb.h"
+#include "mythdirs.h"
+
+
+
+
+
+/**
+ * \class MythInputManager
+ * \brief This class provide a single entry point to access the different Input available.
+ *
+ * The Input Manager is a singleton class which allow to start() and stop() all
+ * the inputs in one go.
+ * We can also reload the configuration at any point by calling the restart() method.
+ * \ingroup MythUI_Input
+ */
+
+MythInputManager * MythInputManager::m_mythInputManager = NULL;
+
+MythInputManager::MythInputManager(QObject * mainWindow)
+    :MythInputManagerInterface(),
+    m_mainWindow(mainWindow),
+    m_lockedInputs(false)
+{
+    QDir FiltDir(GetInputsDir());
+
+    FiltDir.setFilter(QDir::Files | QDir::Readable);
+    if (FiltDir.exists())
+    {
+        QStringList LibList = FiltDir.entryList();
+        for (QStringList::iterator i = LibList.begin(); i != LibList.end();
+             ++i)
+        {
+            QString path = FiltDir.filePath(*i);
+            if (path.length() <= 1)
+                continue;
+
+            LOG(VB_GUI, LOG_INFO, 
+                QString("MythInputManager: Loading input plugin '%1'").arg(path));
+
+            if (!loadPlugin(path))
+            {
+                LOG(VB_GUI, LOG_ERR, 
+                    QString("MythInputManager: Failed to load input plugin: %1").arg(path));
+            }
+        }
+    }
+    else
+        LOG(VB_GUI, LOG_ERR,
+            "MythInputManager: plugin directory '" + FiltDir.absolutePath() + "' doesn't exist?");
+}
+
+const QString MythInputManager::getSettingKey(const MythInputInterface * input, const QString &key)const
+{
+    //to ensure that to plugin does not override other plugin settings
+    if (input==NULL)
+    {
+        LOG(VB_GUI, LOG_ERR,QString("MythInputManager::getSettingKey: an input parameter is NULL"));  
+        return QString("");
+    }
+    return QString("inputmanager.%1.%2").arg(input->name()).arg(key);
+}
+
+
+void MythInputManager::lockInputDevices(bool locked)
+{
+    m_lockedInputs=locked;
+}
+
+bool MythInputManager::loadPlugin(QString fileName)
+{
+    QPluginLoader pluginLoader(fileName);
+    QObject *plugin = pluginLoader.instance();
+    MythInputInterface * inputPlugin;
+    if (plugin) 
+    {
+        inputPlugin = qobject_cast<MythInputInterface *>(plugin);
+        if (inputPlugin)
+        {
+            m_inputs[inputPlugin->name()]=inputPlugin;
+            m_inputs[inputPlugin->name()]->setInputManager(this);
+            LOG(VB_GUI, LOG_INFO, QString("MythInputManager::loadPlugin(%1): success").arg(inputPlugin->name()));
+            return true;
+        }
+        else
+        {
+            LOG(VB_GUI, LOG_ERR, QString("MythInputManager::loadPlugin(%1): wrong interface").arg(fileName));
+        }
+    }
+    else
+    {
+        LOG(VB_GUI, LOG_ERR, pluginLoader.errorString ());
+        LOG(VB_GUI, LOG_ERR, QString("MythInputManager::loadPlugin(%1): can not load").arg(fileName));
+    }
+    return false;
+}
+
+MythInputManager::~MythInputManager()
+{
+    stop();
+}
+
+/**
+ * \brief start all the inputs.
+ *
+ * The input manager will start the input manager which previously register to it.
+ */
+void MythInputManager::start()
+{
+    LOG(VB_GUI, LOG_ERR, "MythInputManager::start()");
+    MythInputInterface *input;
+    foreach (input , m_inputs)
+            input->start();
+}
+
+/**
+ * \brief stop all the inputs
+ */
+void MythInputManager::stop()
+{
+    LOG(VB_GUI, LOG_ERR, "MythInputManager::stop()");
+     MythInputInterface *input;
+     foreach (input , m_inputs)
+             input->stop();
+}
+
+/* The following method are the implementation of MythInputManagerInterface */
+
+QString MythInputManager::getSetting(const MythInputInterface * input, const QString &key)
+{
+    return GetMythDB()->GetSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName());
+}
+QString MythInputManager::getSetting(const MythInputInterface * input, const QString &key, const QString &defaultval)
+{
+    return GetMythDB()->GetSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName(),defaultval);
+}
+
+bool MythInputManager::saveSetting(const MythInputInterface * input, const QString &key, const QString &newValue)
+{
+    return GetMythDB()->SaveSettingOnHost(getSettingKey(input,key),newValue,
+            GetMythDB()->GetHostName());
+}
+
+int MythInputManager::getNumSetting(const MythInputInterface * input, const QString &key)
+{
+    return GetMythDB()->GetNumSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName());
+}
+int MythInputManager::getNumSetting(const MythInputInterface * input, const QString &key, int defaultval)
+{
+    return GetMythDB()->GetNumSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName(), defaultval);
+}
+
+bool MythInputManager::saveNumSetting(const MythInputInterface * input, const QString &key, int newValue)
+{
+    QString val = QString::number(newValue);
+    return saveSetting(input,key,val);
+}
+
+double MythInputManager::getFloatSetting(const MythInputInterface * input, const QString &key)
+{
+    return GetMythDB()->GetFloatSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName());
+}
+
+double MythInputManager::getFloatSetting(const MythInputInterface * input, const QString &key, double defaultval)
+{
+    return GetMythDB()->GetFloatSettingOnHost(getSettingKey(input,key),
+        GetMythDB()->GetHostName(), defaultval);
+}
+
+bool MythInputManager::saveFloatSetting(const MythInputInterface * input, const QString &key, double newValue)
+{
+    QString val = QString::number(newValue);
+    return saveSetting(input,key,val);
+}
+
+void MythInputManager::onKeyPressed(const QKeyEvent &keyEvent)
+{
+    LOG(VB_GUI, LOG_ERR, "MythInputManager::onKeyPressed: receive keyPress");
+    if (!m_lockedInputs)
+    {
+        QKeyEvent * event = new QKeyEvent(keyEvent);
+        QCoreApplication::postEvent(m_mainWindow, event);
+    }
+}
+
+void MythInputManager::logDebug(const QString &msg)
+{
+    LOG(VB_GUI, LOG_DEBUG, QString("MythInputManager: %1").arg(msg));
+}
+
+void MythInputManager::logInfo(const QString &msg)
+{
+    LOG(VB_GUI, LOG_INFO, QString("MythInputManager: %1").arg(msg));
+}
+
+void MythInputManager::logWarning(const QString &msg)
+{
+    LOG(VB_GUI, LOG_WARNING, QString("MythInputManager: %1").arg(msg));
+}
+
+void MythInputManager::logError(const QString &msg)
+{
+    LOG(VB_GUI, LOG_ERR, QString("MythInputManager: %1").arg(msg));
+}
+
+
+
+
+
+
diff --git a/mythtv/libs/libmythui/mythinputmanager.h b/mythtv/libs/libmythui/mythinputmanager.h
new file mode 100755
index 0000000..9201784
--- /dev/null
+++ b/mythtv/libs/libmythui/mythinputmanager.h
@@ -0,0 +1,64 @@
+#ifndef MYTHINPUTMANAGER_H
+#define MYTHINPUTMANAGER_H
+
+#include <QObject>
+#include <QMap>
+#include <QHash>
+#include <QString>
+#include <QMutex>
+#include <QMutexLocker>
+#include <QKeyEvent>
+#include "mythinputinterface.h"
+
+class MythMainWindow;
+
+
+class MythInputManager : public MythInputManagerInterface
+{
+  public:
+    MythInputManager(QObject * mainWindow);
+    ~MythInputManager();
+
+    void start();
+    void restart();
+    void stop();
+
+    const MythInputInterface * getInputByName(const QString &inputName);
+    QList<const MythInputInterface*> inputs();
+
+    void lockInputDevices(bool locked);
+
+    /* MythInputManagerInterface*/
+    QString getSetting(const MythInputInterface * input, const QString &key);
+    QString getSetting(const MythInputInterface * input, const QString &key, const QString &defaultval);
+    bool saveSetting(const MythInputInterface * input, const QString &key, const QString &newValue);
+
+    int getNumSetting(const MythInputInterface * input, const QString &key);
+    int getNumSetting(const MythInputInterface * input, const QString &key, int defaultval);
+    bool saveNumSetting(const MythInputInterface * input, const QString &key, int newValue);
+
+    double getFloatSetting(const MythInputInterface * input, const QString &key);
+    double getFloatSetting(const MythInputInterface * input, const QString &key, double defaultval);
+    bool saveFloatSetting(const MythInputInterface * input, const QString &key, double newValue);
+
+    void onKeyPressed(const QKeyEvent &keyEvent);
+
+    void logDebug(const QString &);
+    void logInfo(const QString &);
+    void logWarning(const QString &);
+    void logError(const QString &);
+    /* MythInputManagerInterface end */
+  private:
+    const QString getSettingKey(const MythInputInterface * input, const QString &key)const;
+    bool loadPlugin(QString filename);
+    static MythInputManager * m_mythInputManager;
+
+    QObject *m_mainWindow;
+    QMap<QString, MythInputInterface*> m_inputs;
+
+    bool m_lockedInputs;
+
+};
+
+
+#endif // MYTHINPUTMANAGER_H
diff --git a/mythtv/libs/libmythui/mythmainwindow.cpp b/mythtv/libs/libmythui/mythmainwindow.cpp
index e69e4fd..fb3ae51 100644
--- a/mythtv/libs/libmythui/mythmainwindow.cpp
+++ b/mythtv/libs/libmythui/mythmainwindow.cpp
@@ -52,6 +52,7 @@ using namespace std;
 #include "lircevent.h"
 #include "mythudplistener.h"
 #include "mythrender_base.h"
+#include "mythinputmanager.h"
 
 #ifdef USING_APPLEREMOTE
 #include "AppleRemoteListener.h"
@@ -173,8 +174,10 @@ class MythMainWindowPrivate
 
         m_udpListener(NULL),
 
-        m_pendingUpdate(false)
+        m_pendingUpdate(false),
+        m_inputManager(NULL)
     {
+
     }
 
     int TranslateKeyNum(QKeyEvent *e);
@@ -256,6 +259,7 @@ class MythMainWindowPrivate
     MythUDPListener *m_udpListener;
 
     bool m_pendingUpdate;
+    MythInputManager * m_inputManager;
 };
 
 // Make keynum in QKeyEvent be equivalent to what's in QKeySequence
@@ -423,6 +427,10 @@ MythMainWindow::MythMainWindow(const bool useDB)
     d->lircThread = NULL;
     StartLIRC();
 
+    d->m_inputManager = new MythInputManager(this);
+    d->m_inputManager->start();
+
+
 #ifdef USE_JOYSTICK_MENU
     d->ignore_joystick_keys = false;
 
@@ -495,6 +503,11 @@ MythMainWindow::~MythMainWindow()
         d->lircThread = NULL;
     }
 #endif
+    if (d->m_inputManager)
+    {
+        delete d->m_inputManager;
+    }
+
 
 #ifdef USE_JOYSTICK_MENU
     if (d->joystickThread)
@@ -2432,6 +2445,8 @@ void MythMainWindow::LockInputDevices( bool locked )
     else
         LOG(VB_GENERAL, LOG_INFO, "Unlocking input devices");
 
+    d->m_inputManager->lockInputDevices(locked);
+
 #ifdef USE_LIRC
     d->ignore_lirc_keys = locked;
 #endif
