diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp
index edd0dead11..0bfd97c5dc 100644
--- a/apps/openmw/engine.cpp
+++ b/apps/openmw/engine.cpp
@@ -272,9 +272,7 @@ void OMW::Engine::go()
 
     // Get the path for the keybinder xml file
     std::string keybinderUser = (mCfgMgr.getUserPath() / "input.xml").string();
-
-    if (!boost::filesystem::exists(keybinderUser))
-        keybinderUser = "";
+    bool keybinderUserExists = boost::filesystem::exists(keybinderUser);
 
     mFpsLevel = settings.getInt("fps", "HUD");
 
@@ -374,7 +372,7 @@ void OMW::Engine::go()
 
     mEnvironment.setInputManager (new MWInput::InputManager (*mOgre,
         MWBase::Environment::get().getWorld()->getPlayer(),
-         *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser));
+         *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists));
 
     std::cout << "\nPress Q/ESC or close window to exit.\n";
 
diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp
index 5d73025a7d..bf1d8e45f6 100644
--- a/apps/openmw/mwbase/inputmanager.hpp
+++ b/apps/openmw/mwbase/inputmanager.hpp
@@ -31,6 +31,12 @@ namespace MWBase
             virtual void setDragDrop(bool dragDrop) = 0;
 
             virtual void toggleControlSwitch (const std::string& sw, bool value) = 0;
+
+            virtual std::string getActionDescription (int action) = 0;
+            virtual std::string getActionBindingName (int action) = 0;
+            virtual std::vector<int> getActionSorting () = 0;
+            virtual int getNumActions() = 0;
+            virtual void enableDetectingBindingMode (int action) = 0;
     };
 }
 
diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp
index 931353a900..fde965256c 100644
--- a/apps/openmw/mwbase/windowmanager.hpp
+++ b/apps/openmw/mwbase/windowmanager.hpp
@@ -177,6 +177,10 @@ namespace MWBase
             virtual void unsetSelectedSpell() = 0;
             virtual void unsetSelectedWeapon() = 0;
 
+            virtual void disallowMouse() = 0;
+            virtual void allowMouse() = 0;
+            virtual void notifyInputActionBound() = 0;
+
             virtual void removeDialog(OEngine::GUI::Layout* dialog) = 0;
             ///< Hides dialog and schedules dialog to be deleted.
 
diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp
index bdbb316b05..92dc4e495f 100644
--- a/apps/openmw/mwgui/hud.cpp
+++ b/apps/openmw/mwgui/hud.cpp
@@ -237,6 +237,9 @@ void HUD::setBottomRightVisibility(bool effectBoxVisible, bool minimapBoxVisible
 
 void HUD::onWorldClicked(MyGUI::Widget* _sender)
 {
+    if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ())
+        return;
+
     if (mDragAndDrop->mIsOnDragAndDrop)
     {
         // drop item into the gameworld
diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp
index 485c788fc3..baa350a10c 100644
--- a/apps/openmw/mwgui/hud.hpp
+++ b/apps/openmw/mwgui/hud.hpp
@@ -48,6 +48,8 @@ namespace MWGui
         MyGUI::TextBox* mCellNameBox;
         MyGUI::TextBox* mWeaponSpellBox;
 
+        MyGUI::Widget* mDummy;
+
         MyGUI::WidgetPtr fpsbox;
         MyGUI::TextBox* fpscounter;
         MyGUI::TextBox* trianglecounter;
diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp
index f6597a64ef..477ffe0e24 100644
--- a/apps/openmw/mwgui/settingswindow.cpp
+++ b/apps/openmw/mwgui/settingswindow.cpp
@@ -115,6 +115,7 @@ namespace MWGui
         getWidget(mMiscShadows, "MiscShadows");
         getWidget(mShadowsDebug, "ShadowsDebug");
         getWidget(mUnderwaterButton, "UnderwaterButton");
+        getWidget(mControlsBox, "ControlsBox");
 
         mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked);
         mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled);
@@ -511,4 +512,54 @@ namespace MWGui
         MWBase::Environment::get().getWindowManager()->processChangedSettings(changed);
         MWBase::Environment::get().getInputManager()->processChangedSettings(changed);
     }
+
+    void SettingsWindow::updateControlsBox()
+    {
+        while (mControlsBox->getChildCount())
+            MyGUI::Gui::getInstance().destroyWidget(mControlsBox->getChildAt(0));
+
+        std::vector<int> actions = MWBase::Environment::get().getInputManager()->getActionSorting ();
+
+        const int h = 18;
+        const int w = mControlsBox->getWidth() - 34;
+        int curH = 6;
+        for (std::vector<int>::const_iterator it = actions.begin(); it != actions.end(); ++it)
+        {
+            std::string desc = MWBase::Environment::get().getInputManager()->getActionDescription (*it);
+            if (desc == "")
+                continue;
+
+            std::string binding = MWBase::Environment::get().getInputManager()->getActionBindingName (*it);
+
+            MyGUI::TextBox* leftText = mControlsBox->createWidget<MyGUI::TextBox>("SandText", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
+            leftText->setCaptionWithReplacing(desc);
+
+            MyGUI::Button* rightText = mControlsBox->createWidget<MyGUI::Button>("SandTextButton", MyGUI::IntCoord(0,curH,w,h), MyGUI::Align::Default);
+            rightText->setCaptionWithReplacing(binding);
+            rightText->setTextAlign (MyGUI::Align::Right);
+            rightText->setUserData(*it); // save the action id for callbacks
+            rightText->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onRebindAction);
+            curH += h;
+        }
+
+        mControlsBox->setCanvasSize (mControlsBox->getWidth(), std::max(curH, mControlsBox->getHeight()));
+    }
+
+    void SettingsWindow::onRebindAction(MyGUI::Widget* _sender)
+    {
+        int actionId = *_sender->getUserData<int>();
+
+        static_cast<MyGUI::Button*>(_sender)->setCaptionWithReplacing("#{sNone}");
+
+        MWBase::Environment::get().getWindowManager ()->messageBox ("#{sControlsMenu3}", std::vector<std::string>());
+        MWBase::Environment::get().getWindowManager ()->disallowMouse();
+
+        MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId);
+
+    }
+
+    void SettingsWindow::open()
+    {
+        updateControlsBox ();
+    }
 }
diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp
index ca11b6f9c2..61614da014 100644
--- a/apps/openmw/mwgui/settingswindow.hpp
+++ b/apps/openmw/mwgui/settingswindow.hpp
@@ -15,6 +15,10 @@ namespace MWGui
         public:
             SettingsWindow(MWBase::WindowManager& parWindowManager);
 
+            virtual void open();
+
+            void updateControlsBox();
+
         private:
             static int const sFovMin = 30;
             static int const sFovMax = 140;
@@ -60,6 +64,9 @@ namespace MWGui
             MyGUI::ScrollBar* mFootstepsVolumeSlider;
             MyGUI::ScrollBar* mMusicVolumeSlider;
 
+            // controls
+            MyGUI::ScrollView* mControlsBox;
+
             void onOkButtonClicked(MyGUI::Widget* _sender);
             void onFpsToggled(MyGUI::Widget* _sender);
             void onTextureFilteringToggled(MyGUI::Widget* _sender);
@@ -72,6 +79,8 @@ namespace MWGui
             void onShadersToggled(MyGUI::Widget* _sender);
             void onShadowTextureSize(MyGUI::Widget* _sender);
 
+            void onRebindAction(MyGUI::Widget* _sender);
+
             void apply();
     };
 }
diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp
index 183c435fdf..676eb2046e 100644
--- a/apps/openmw/mwgui/windowmanagerimp.cpp
+++ b/apps/openmw/mwgui/windowmanagerimp.cpp
@@ -134,6 +134,8 @@ WindowManager::WindowManager(
     mAlchemyWindow = new AlchemyWindow(*this);
     mSpellWindow = new SpellWindow(*this);
 
+    mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Windows","");
+
     // The HUD is always on
     mHud->setVisible(true);
 
@@ -230,11 +232,16 @@ void WindowManager::updateVisible()
 
     bool gameMode = !isGuiMode();
 
+    mInputBlocker->setVisible (gameMode);
+
     if (gameMode)
         mToolTips->enterGameMode();
     else
         mToolTips->enterGuiMode();
 
+    if (gameMode)
+        MyGUI::InputManager::getInstance ().setKeyFocusWidget (NULL);
+
     setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned());
     setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned());
     setSpellVisibility((mAllowed & GW_Magic) && !mSpellWindow->pinned());
@@ -646,6 +653,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector
         mScrollWindow->center();
         mBookWindow->center();
         mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
+        mInputBlocker->setSize(MyGUI::IntSize(x,y));
     }
 }
 
@@ -823,3 +831,19 @@ WindowManager::SkillList WindowManager::getPlayerMajorSkills()
 {
     return mPlayerMajorSkills;
 }
+
+void WindowManager::disallowMouse()
+{
+    mInputBlocker->setVisible (true);
+}
+
+void WindowManager::allowMouse()
+{
+    mInputBlocker->setVisible (!isGuiMode ());
+}
+
+void WindowManager::notifyInputActionBound ()
+{
+    mSettingsWindow->updateControlsBox ();
+    allowMouse();
+}
diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp
index eaa6a16832..3913055942 100644
--- a/apps/openmw/mwgui/windowmanagerimp.hpp
+++ b/apps/openmw/mwgui/windowmanagerimp.hpp
@@ -157,6 +157,10 @@ namespace MWGui
     virtual void unsetSelectedSpell();
     virtual void unsetSelectedWeapon();
 
+    virtual void disallowMouse();
+    virtual void allowMouse();
+    virtual void notifyInputActionBound();
+
     virtual void removeDialog(OEngine::GUI::Layout* dialog); ///< Hides dialog and schedules dialog to be deleted.
 
     virtual void messageBox (const std::string& message, const std::vector<std::string>& buttons);
@@ -208,6 +212,8 @@ namespace MWGui
 
     CharacterCreation* mCharGen;
 
+    MyGUI::Widget* mInputBlocker;
+
     /// \todo get rid of this stuff. Move it to the respective UI element classes, if needed.
     // Various stats about player as needed by window manager
     ESM::Class mPlayerClass;
diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp
index 0318995389..09ed50944c 100644
--- a/apps/openmw/mwinput/inputmanagerimp.cpp
+++ b/apps/openmw/mwinput/inputmanagerimp.cpp
@@ -14,8 +14,6 @@
 #include <MyGUI_InputManager.h>
 #include <MyGUI_RenderManager.h>
 
-#include <extern/oics/ICSInputControlSystem.h>
-
 #include <openengine/ogre/renderer.hpp>
 
 #include "../engine.hpp"
@@ -31,7 +29,7 @@ namespace MWInput
             MWBase::WindowManager &windows,
             bool debug,
             OMW::Engine& engine,
-            const std::string& userFile)
+            const std::string& userFile, bool userFileExists)
         : mOgre(ogre)
         , mPlayer(player)
         , mWindows(windows)
@@ -101,11 +99,12 @@ namespace MWInput
 
         MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs);
 
-        mInputCtrl = new ICS::InputControlSystem(userFile, true, NULL, NULL, A_LAST);
+        std::string file = userFileExists ? userFile : "";
+        mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
 
         loadKeyDefaults();
 
-        for (int i = 0; i < A_LAST; ++i)
+        for (int i = 0; i < A_Last; ++i)
         {
             mInputCtrl->getChannel (i)->addListener (this);
         }
@@ -322,8 +321,7 @@ namespace MWInput
     {
         mInputCtrl->keyPressed (arg);
 
-        if (mGuiCursorEnabled)
-            MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.key), arg.text);
+        MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.key), arg.text);
 
         return true;
     }
@@ -341,8 +339,7 @@ namespace MWInput
     {
         mInputCtrl->mousePressed (arg, id);
 
-        if (mGuiCursorEnabled)
-            MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, MyGUI::MouseButton::Enum(id));
+        MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, MyGUI::MouseButton::Enum(id));
 
         return true;
     }
@@ -440,15 +437,11 @@ namespace MWInput
     {
         bool gameMode = !mWindows.isGuiMode();
 
-        std::cout << "gameMode: " << gameMode << std::endl;
-
         // Toggle between game mode and inventory mode
         if(gameMode)
             mWindows.pushGuiMode(MWGui::GM_Inventory);
         else if(mWindows.getMode() == MWGui::GM_Inventory)
             mWindows.popGuiMode();
-        else
-            std::cout << "toggleInv didnt do anything!!!" << std::endl;
 
         // .. but don't touch any other mode.
     }
@@ -535,7 +528,7 @@ namespace MWInput
         std::map<int, int> defaultMouseButtonBindings;
         defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right;
 
-        for (int i = 0; i < A_LAST; ++i)
+        for (int i = 0; i < A_Last; ++i)
         {
             if (mInputCtrl->getChannel(i)->getControlsCount () == 0)
             {
@@ -551,4 +544,141 @@ namespace MWInput
         }
     }
 
+    std::string InputManager::getActionDescription (int action)
+    {
+        std::map<int, std::string> descriptions;
+
+        descriptions[A_Activate] = "sActivate";
+        descriptions[A_MoveBackward] = "sBack";
+        descriptions[A_MoveForward] = "sForward";
+        descriptions[A_MoveLeft] = "sLeft";
+        descriptions[A_MoveRight] = "sRight";
+        descriptions[A_ToggleWeapon] = "sReady_Weapon";
+        descriptions[A_ToggleSpell] = "sReady_Magic";
+        descriptions[A_Console] = "sConsoleTitle";
+        descriptions[A_Crouch] = "sCrouch_Sneak";
+        descriptions[A_AutoMove] = "sAuto_Run";
+        descriptions[A_Jump] = "sJump";
+        descriptions[A_Journal] = "sJournal";
+        descriptions[A_Rest] = "sRestKey";
+        descriptions[A_Inventory] = "sInventory";
+
+        if (action == A_GameMenu)
+            return "Menu"; // not configurable in morrowind so no GMST
+
+        if (descriptions[action] == "")
+            return ""; // not configurable
+
+        return "#{" + descriptions[action] + "}";
+    }
+
+    std::string InputManager::getActionBindingName (int action)
+    {
+        if (mInputCtrl->getChannel (action)->getControlsCount () == 0)
+            return "#{sNone}";
+
+        ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
+
+        if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED)
+            return mInputCtrl->keyCodeToString (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE));
+        else if (mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
+            return "#{sMouse} " + boost::lexical_cast<std::string>(mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE));
+        else
+            return "#{sNone}";
+    }
+
+    std::vector<int> InputManager::getActionSorting()
+    {
+        std::vector<int> ret;
+        ret.push_back(A_MoveForward);
+        ret.push_back(A_MoveBackward);
+        ret.push_back(A_MoveLeft);
+        ret.push_back(A_MoveRight);
+        ret.push_back(A_Crouch);
+        ret.push_back(A_Activate);
+        ret.push_back(A_ToggleWeapon);
+        ret.push_back(A_AutoMove);
+        ret.push_back(A_Jump);
+        ret.push_back(A_Inventory);
+        ret.push_back(A_Journal);
+        ret.push_back(A_Rest);
+        ret.push_back(A_Console);
+        ret.push_back(A_GameMenu);
+
+        return ret;
+    }
+
+    void InputManager::enableDetectingBindingMode (int action)
+    {
+        ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
+
+        mInputCtrl->enableDetectingBindingState (c, ICS::Control::INCREASE);
+    }
+
+    void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction)
+    {
+        // we don't want mouse movement bindings
+        return;
+    }
+
+    void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , unsigned int button, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::mouseButtonBindingDetected (ICS, control, button, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , int deviceId, int axis, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, control, deviceId, axis, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , int deviceId, unsigned int button, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, control, deviceId, button, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::joystickPOVBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , int deviceId, int pov,ICS:: InputControlSystem::POVAxis axis, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::joystickPOVBindingDetected (ICS, control, deviceId, pov, axis, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::joystickSliderBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+        , int deviceId, int slider, ICS::Control::ControlChangingDirection direction)
+    {
+        clearAllBindings(control);
+        ICS::DetectingBindingListener::joystickSliderBindingDetected (ICS, control, deviceId, slider, direction);
+        MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
+    }
+
+    void InputManager::clearAllBindings (ICS::Control* control)
+    {
+        // right now we don't really need multiple bindings for the same action, so remove all others first
+        if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED)
+            mInputCtrl->removeKeyBinding (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE));
+        if (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
+            mInputCtrl->removeMouseButtonBinding (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE));
+
+        /// \todo add joysticks here once they are added
+    }
+
 }
diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp
index 9fc77aeeb4..d3d4d13853 100644
--- a/apps/openmw/mwinput/inputmanagerimp.hpp
+++ b/apps/openmw/mwinput/inputmanagerimp.hpp
@@ -46,6 +46,7 @@ namespace OIS
 #include <OIS/OISMouse.h>
 
 #include <extern/oics/ICSChannelListener.h>
+#include <extern/oics/ICSInputControlSystem.h>
 
 namespace MWInput
 {
@@ -53,7 +54,7 @@ namespace MWInput
     /**
     * @brief Class that handles all input and key bindings for OpenMW.
     */
-    class InputManager : public MWBase::InputManager, public OIS::KeyListener, public OIS::MouseListener, public ICS::ChannelListener
+    class InputManager : public MWBase::InputManager, public OIS::KeyListener, public OIS::MouseListener, public ICS::ChannelListener, public ICS::DetectingBindingListener
     {
     public:
         InputManager(OEngine::Render::OgreRenderer &_ogre,
@@ -61,7 +62,7 @@ namespace MWInput
             MWBase::WindowManager &_windows,
             bool debug,
             OMW::Engine& engine,
-            const std::string& userFile);
+            const std::string& userFile, bool userFileExists);
 
         virtual ~InputManager();
 
@@ -75,6 +76,12 @@ namespace MWInput
 
         virtual void toggleControlSwitch (const std::string& sw, bool value);
 
+        virtual std::string getActionDescription (int action);
+        virtual std::string getActionBindingName (int action);
+        virtual int getNumActions() { return A_Last; }
+        virtual std::vector<int> getActionSorting ();
+        virtual void enableDetectingBindingMode (int action);
+
 
     public:
         virtual bool keyPressed( const OIS::KeyEvent &arg );
@@ -86,6 +93,29 @@ namespace MWInput
 
         virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue);
 
+        virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction);
+
+        virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction);
+
+        virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , unsigned int button, ICS::Control::ControlChangingDirection direction);
+
+        virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , int deviceId, int axis, ICS::Control::ControlChangingDirection direction);
+
+        virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , int deviceId, unsigned int button, ICS::Control::ControlChangingDirection direction);
+
+        virtual void joystickPOVBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , int deviceId, int pov,ICS:: InputControlSystem::POVAxis axis, ICS::Control::ControlChangingDirection direction);
+
+        virtual void joystickSliderBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
+            , int deviceId, int slider, ICS::Control::ControlChangingDirection direction);
+
+        void clearAllBindings (ICS::Control* control);
+
     private:
         OEngine::Render::OgreRenderer &mOgre;
         MWWorld::Player &mPlayer;
@@ -175,7 +205,7 @@ namespace MWInput
             A_ToggleWeapon,
             A_ToggleSpell,
 
-            A_LAST            // Marker for the last item
+            A_Last            // Marker for the last item
         };
 
 
diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout
index a14606ade9..ee4855f381 100644
--- a/files/mygui/openmw_settings_window.layout
+++ b/files/mygui/openmw_settings_window.layout
@@ -82,6 +82,13 @@
             </Widget>
             <Widget type="TabItem" skin="" position="4 28 360 312">
                 <Property key="Caption" value="  #{sControls}  "/>
+
+                <Widget type="Widget" skin="MW_Box" position="8 8 344 180">
+
+                    <Widget type="ScrollView" skin="MW_ScrollView" name="ControlsBox" position="4 4 336 172"/>
+
+                </Widget>
+
             </Widget>
             <Widget type="TabItem" skin="" position="4 28 360 312">
                 <Property key="Caption" value="  #{sVideo}  "/>