Using OIS         Using the Object-oriented Input System Library with OGRE

Introduction

This page contains two parts. The first section shows the bare minimum amount of code required in order to get input events from OIS. The second section contains a more complete example - an InputManager class that you can use in your applications with very little modification.

The choice is yours; either roll your own, or use the provided class.

Minimal OIS code

OIS is an object oriented input library. It supports many different devices, in three basic device categories (keyboards, mice, and joysticks). OIS is an open source library, so you can make changes & alterations as you see fit. The OIS homepage is here

Initialisation

OIS needs to be initialised. Here's the basic code to do this:

OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;
m_win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
m_InputManager = OIS::InputManager::createInputSystem( pl );


Let's go through that example line-by-line.

  1. Line 1 creates a ParamList object. This is basically a typedef for a std::map. It is used to pass parameters to classes (similar to the Ogre::NameValuePairList).
  2. Line 2 creates a size_t object that we will use to retrieve a window handle from our render window.
  3. Line 3 creates a std::ostringstream - we use this to "stringify" the size_t object created in line 2.
  4. Line 4 populates the size_t object with the window handle. 'm_win' in this example is a pointer to an initialised Ogre::RenderWindow
  5. Line 5 performs the stringification - we need a string representation of the window handle.
  6. Line 6 inserts into our parameter list the string "WINDOW", and the string object we created above.
  7. Line 7 actually creates the OIS input system. Note: m_InputManager is a pointer to an OIS::InputManager object.


An alternative method for initializing OIS:

size_t hWnd = 0;
m_win->getCustomAttribute("WINDOW", &hWnd);
m_InputManager = OIS::InputManager::createInputSystem(hWnd);


Phew! That's a lot of work just to create the input system!
Unfortunately, that's not all we have to do. We need to create OIS::Mouse and OIS::Keyboard objects (I'll leave joystick support as an exercise for the reader). The code to do this is fairly simple:

m_Mouse = static_cast<OIS::Mouse*>(m_InputManager->createInputObject(OIS::OISMouse, false));
m_Keyboard = static_cast<OIS::Keyboard*>(m_InputManager->createInputObject(OIS::OISKeyboard, false));


Here, m_Mouse is a pointer to an OIS::Mouse object, and m_Keyboard is a pointer to an OIS::Keyboard object. We need the static cast since the OIS::InputManager returns an OIS::Object (see the OIS API docs for more information). The second parameter to the OIS::InputManager::createInputObject is a hint on whether the input objects should be buffered, or unbuffered. This is an implementation decision that the programmer needs to make. I have chosen to go with unbuffered input.

Nearly there! The last thing we need to do is to tell OIS about the dimensions of the window. This is used in conjunction with mouse events (for example, OIS can trap the mouse inside your display window). The code is fairly simple:

unsigned int width, height, depth;
int top, left;
m_win->getMetrics(width, height, depth, left, top);
const OIS::MouseState &ms = m_Mouse->getMouseState();
ms.width = width;
ms.height = height;


Lines one and two create local variables that will store the window width & height, colour depth, and top and left coordinates. Line 3 gets these values from an Ogre::RenderWindow (m_win is a pointer to an initialised RenderWindow). Line 4 gets a mouse state object, and sets the width and height properties accordingly. Again, consult the OIS API docs for more information.

That's it for initialisation. Keep reading to find out how to use OIS to capture keycodes and mouse events!

Usage

Each time you want to get input device events (probably once per frame), you follow these simple steps:

  1. call the capture() method on the device in question.
  2. Interrogate the device directly.




For example:

m_Keyboard->capture();
if (m_Keyboard->isKeyDown(OIS::KC_ESCAPE))
     return false;


This code might go inside the Ogre::FrameListener::frameStarted event, to tell Ogre to stop rendering when the escape key is pressed. Similar interrogations can be performed on the OIS::Mouse object.

Summary

That's it! OIS is pretty easy to use, but the available documentation doesn't make it easy to get started. Hopefully I have made it a bit easier by providing some sample code. Please feel free to edit the code above, and add any suggestions / comments.

Thanks.

InputManager Class

With this code, I'm trying to make a simple InputManager that uses OIS as input library. I basically used the input managers from Practical Application - Let's Get Started and Managing Game States with OGRE as templates for this one. I hope you can use it.

I tried to keep OGRE out of it as much as possible so you can also use it for other projects. That's why I used another method for getting a singleton pointer. I did keep the Ogre::Renderwindow because I like to keep the initialisation as easy and clean as possible.

InputManager.h

#ifndef InputManager_H
#define InputManager_H

#include <OISMouse.h>
#include <OISKeyboard.h>
#include <OISJoyStick.h>
#include <OISInputManager.h>

#include <OgreRenderWindow.h>

class InputManager : public OIS::KeyListener, public OIS::MouseListener, public OIS::JoyStickListener {
public:
    virtual ~InputManager( void );

    void initialise( Ogre::RenderWindow *renderWindow );
    void capture( void );

    void addKeyListener( OIS::KeyListener *keyListener, const std::string& instanceName );
    void addMouseListener( OIS::MouseListener *mouseListener, const std::string& instanceName );
    void addJoystickListener( OIS::JoyStickListener *joystickListener, const std::string& instanceName );

    void removeKeyListener( const std::string& instanceName );
    void removeMouseListener( const std::string& instanceName );
    void removeJoystickListener( const std::string& instanceName );

    void removeKeyListener( OIS::KeyListener *keyListener );
    void removeMouseListener( OIS::MouseListener *mouseListener );
    void removeJoystickListener( OIS::JoyStickListener *joystickListener );

    void removeAllListeners( void );
    void removeAllKeyListeners( void );
    void removeAllMouseListeners( void );
    void removeAllJoystickListeners( void );

    void setWindowExtents( int width, int height );

    OIS::Mouse*    getMouse( void );
    OIS::Keyboard* getKeyboard( void );
    OIS::JoyStick* getJoystick( unsigned int index );

    int getNumOfJoysticks( void );

    static InputManager* getSingletonPtr( void );
private:
    InputManager( void );
    InputManager( const InputManager& ) { }
    InputManager & operator = ( const InputManager& );

    bool keyPressed( const OIS::KeyEvent &e );
    bool keyReleased( const OIS::KeyEvent &e );

    bool mouseMoved( const OIS::MouseEvent &e );
    bool mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id );
    bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id );

    bool povMoved( const OIS::JoyStickEvent &e, int pov );
    bool axisMoved( const OIS::JoyStickEvent &e, int axis );
    bool sliderMoved( const OIS::JoyStickEvent &e, int sliderID );
    bool buttonPressed( const OIS::JoyStickEvent &e, int button );
    bool buttonReleased( const OIS::JoyStickEvent &e, int button );

    OIS::Mouse        *mMouse;
    OIS::Keyboard     *mKeyboard;
    OIS::InputManager *mInputSystem;

    std::vector<OIS::JoyStick*> mJoysticks;
    std::vector<OIS::JoyStick*>::iterator itJoystick;
    std::vector<OIS::JoyStick*>::iterator itJoystickEnd;

    std::map<std::string, OIS::KeyListener*> mKeyListeners;
    std::map<std::string, OIS::MouseListener*> mMouseListeners;
    std::map<std::string, OIS::JoyStickListener*> mJoystickListeners;

    std::map<std::string, OIS::KeyListener*>::iterator itKeyListener;
    std::map<std::string, OIS::MouseListener*>::iterator itMouseListener;
    std::map<std::string, OIS::JoyStickListener*>::iterator itJoystickListener;

    std::map<std::string, OIS::KeyListener*>::iterator itKeyListenerEnd;
    std::map<std::string, OIS::MouseListener*>::iterator itMouseListenerEnd;
    std::map<std::string, OIS::JoyStickListener*>::iterator itJoystickListenerEnd;

    static InputManager *mInputManager;
};
#endif

InputManager.cpp

#include "InputManager.h"

InputManager *InputManager::mInputManager;

InputManager::InputManager( void ) :
    mMouse( 0 ),
    mKeyboard( 0 ),
    mInputSystem( 0 ) {
}

InputManager::~InputManager( void ) {
    if( mInputSystem ) {
        if( mMouse ) {
            mInputSystem->destroyInputObject( mMouse );
            mMouse = 0;
        }

        if( mKeyboard ) {
            mInputSystem->destroyInputObject( mKeyboard );
            mKeyboard = 0;
        }

        if( mJoysticks.size() > 0 ) {
            itJoystick    = mJoysticks.begin();
            itJoystickEnd = mJoysticks.end();
            for(; itJoystick != itJoystickEnd; ++itJoystick ) {
                mInputSystem->destroyInputObject( *itJoystick );
            }

            mJoysticks.clear();
        }

        // If you use OIS1.0RC1 or above, uncomment this line
        // and comment the line below it
        mInputSystem->destroyInputSystem( mInputSystem );
        //mInputSystem->destroyInputSystem();
        mInputSystem = 0;

        // Clear Listeners
        mKeyListeners.clear();
        mMouseListeners.clear();
        mJoystickListeners.clear();
    }
}

void InputManager::initialise( Ogre::RenderWindow *renderWindow ) {
    if( !mInputSystem ) {
        // Setup basic variables
        OIS::ParamList paramList;    
        size_t windowHnd = 0;
        std::ostringstream windowHndStr;

        // Get window handle
        renderWindow->getCustomAttribute( "WINDOW", &windowHnd );

        // Fill parameter list
        windowHndStr << (unsigned int) windowHnd;
        paramList.insert( std::make_pair( std::string( "WINDOW" ), windowHndStr.str() ) );

        // Create inputsystem
        mInputSystem = OIS::InputManager::createInputSystem( paramList );

        // If possible create a buffered keyboard
        // (note: if below line doesn't compile, try:  if (mInputSystem->getNumberOfDevices(OIS::OISKeyboard) > 0) {
        //if( mInputSystem->numKeyboards() > 0 ) {
        if (mInputSystem->getNumberOfDevices(OIS::OISKeyboard) > 0) {
            mKeyboard = static_cast<OIS::Keyboard*>( mInputSystem->createInputObject( OIS::OISKeyboard, true ) );
            mKeyboard->setEventCallback( this );
        }

        // If possible create a buffered mouse
        // (note: if below line doesn't compile, try:  if (mInputSystem->getNumberOfDevices(OIS::OISMouse) > 0) {
        //if( mInputSystem->numMice() > 0 ) {
        if (mInputSystem->getNumberOfDevices(OIS::OISMouse) > 0) {
            mMouse = static_cast<OIS::Mouse*>( mInputSystem->createInputObject( OIS::OISMouse, true ) );
            mMouse->setEventCallback( this );

            // Get window size
            unsigned int width, height, depth;
            int left, top;
            renderWindow->getMetrics( width, height, depth, left, top );

            // Set mouse region
            this->setWindowExtents( width, height );
        }

        // If possible create all joysticks in buffered mode
        // (note: if below line doesn't compile, try:  if (mInputSystem->getNumberOfDevices(OIS::OISJoyStick) > 0) {
        //if( mInputSystem->numJoySticks() > 0 ) {
        if (mInputSystem->getNumberOfDevices(OIS::OISJoyStick) > 0) {
            //mJoysticks.resize( mInputSystem->numJoySticks() );
            mJoysticks.resize( mInputSystem->getNumberOfDevices(OIS::OISJoyStick) );

            itJoystick    = mJoysticks.begin();
            itJoystickEnd = mJoysticks.end();
            for(; itJoystick != itJoystickEnd; ++itJoystick ) {
                (*itJoystick) = static_cast<OIS::JoyStick*>( mInputSystem->createInputObject( OIS::OISJoyStick, true ) );
                (*itJoystick)->setEventCallback( this );
            }
        }
    }
}

void InputManager::capture( void ) {
    // Need to capture / update each device every frame
    if( mMouse ) {
        mMouse->capture();
    }

    if( mKeyboard ) {
        mKeyboard->capture();
    }

    if( mJoysticks.size() > 0 ) {
        itJoystick    = mJoysticks.begin();
        itJoystickEnd = mJoysticks.end();
        for(; itJoystick != itJoystickEnd; ++itJoystick ) {
            (*itJoystick)->capture();
        }
    }
}

void InputManager::addKeyListener( OIS::KeyListener *keyListener, const std::string& instanceName ) {
    if( mKeyboard ) {
        // Check for duplicate items
        itKeyListener = mKeyListeners.find( instanceName );
        if( itKeyListener == mKeyListeners.end() ) {
            mKeyListeners[ instanceName ] = keyListener;
        }
        else {
            // Duplicate Item
        }
    }
}

void InputManager::addMouseListener( OIS::MouseListener *mouseListener, const std::string& instanceName ) {
    if( mMouse ) {
        // Check for duplicate items
        itMouseListener = mMouseListeners.find( instanceName );
        if( itMouseListener == mMouseListeners.end() ) {
            mMouseListeners[ instanceName ] = mouseListener;
        }
        else {
            // Duplicate Item
        }
    }
}

void InputManager::addJoystickListener( OIS::JoyStickListener *joystickListener, const std::string& instanceName ) {
    if( mJoysticks.size() > 0 ) {
        // Check for duplicate items
        itJoystickListener = mJoystickListeners.find( instanceName );
        if( itJoystickListener == mJoystickListeners.end() ) {
            mJoystickListeners[ instanceName ] = joystickListener;
        }
        else {
            // Duplicate Item
        }
    }
}

void InputManager::removeKeyListener( const std::string& instanceName ) {
    // Check if item exists
    itKeyListener = mKeyListeners.find( instanceName );
    if( itKeyListener != mKeyListeners.end() ) {
        mKeyListeners.erase( itKeyListener );
    }
    else {
        // Doesn't Exist
    }
}

void InputManager::removeMouseListener( const std::string& instanceName ) {
    // Check if item exists
    itMouseListener = mMouseListeners.find( instanceName );
    if( itMouseListener != mMouseListeners.end() ) {
        mMouseListeners.erase( itMouseListener );
    }
    else {
        // Doesn't Exist
    }
}

void InputManager::removeJoystickListener( const std::string& instanceName ) {
    // Check if item exists
    itJoystickListener = mJoystickListeners.find( instanceName );
    if( itJoystickListener != mJoystickListeners.end() ) {
        mJoystickListeners.erase( itJoystickListener );
    }
    else {
        // Doesn't Exist
    }
}

void InputManager::removeKeyListener( OIS::KeyListener *keyListener ) {
    itKeyListener    = mKeyListeners.begin();
    itKeyListenerEnd = mKeyListeners.end();
    for(; itKeyListener != itKeyListenerEnd; ++itKeyListener ) {
        if( itKeyListener->second == keyListener ) {
            mKeyListeners.erase( itKeyListener );
            break;
        }
    }
}

void InputManager::removeMouseListener( OIS::MouseListener *mouseListener ) {
    itMouseListener    = mMouseListeners.begin();
    itMouseListenerEnd = mMouseListeners.end();
    for(; itMouseListener != itMouseListenerEnd; ++itMouseListener ) {
        if( itMouseListener->second == mouseListener ) {
            mMouseListeners.erase( itMouseListener );
            break;
        }
    }
}

void InputManager::removeJoystickListener( OIS::JoyStickListener *joystickListener ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if( itJoystickListener->second == joystickListener ) {
            mJoystickListeners.erase( itJoystickListener );
            break;
        }
    }
}

void InputManager::removeAllListeners( void ) {
    mKeyListeners.clear();
    mMouseListeners.clear();
    mJoystickListeners.clear();
}

void InputManager::removeAllKeyListeners( void ) {
    mKeyListeners.clear();
}

void InputManager::removeAllMouseListeners( void ) {
    mMouseListeners.clear();
}

void InputManager::removeAllJoystickListeners( void ) {
    mJoystickListeners.clear();
}

void InputManager::setWindowExtents( int width, int height ) {
    // Set mouse region (if window resizes, we should alter this to reflect as well)
    const OIS::MouseState &mouseState = mMouse->getMouseState();
    mouseState.width  = width;
    mouseState.height = height;
}

OIS::Mouse* InputManager::getMouse( void ) {
    return mMouse;
}

OIS::Keyboard* InputManager::getKeyboard( void ) {
    return mKeyboard;
}

OIS::JoyStick* InputManager::getJoystick( unsigned int index ) {
    // Make sure it's a valid index
    if( index < mJoysticks.size() ) {
        return mJoysticks[ index ];
    }

    return 0;
}

int InputManager::getNumOfJoysticks( void ) {
    // Cast to keep compiler happy ^^
    return (int) mJoysticks.size();
}

bool InputManager::keyPressed( const OIS::KeyEvent &e ) {
    itKeyListener    = mKeyListeners.begin();
    itKeyListenerEnd = mKeyListeners.end();
    for(; itKeyListener != itKeyListenerEnd; ++itKeyListener ) {
        if(!itKeyListener->second->keyPressed( e ))
            break;
    }

    return true;
}

bool InputManager::keyReleased( const OIS::KeyEvent &e ) {
    itKeyListener    = mKeyListeners.begin();
    itKeyListenerEnd = mKeyListeners.end();
    for(; itKeyListener != itKeyListenerEnd; ++itKeyListener ) {
        if(!itKeyListener->second->keyReleased( e ))
            break;
    }

    return true;
}

bool InputManager::mouseMoved( const OIS::MouseEvent &e ) {
    itMouseListener    = mMouseListeners.begin();
    itMouseListenerEnd = mMouseListeners.end();
    for(; itMouseListener != itMouseListenerEnd; ++itMouseListener ) {
        if(!itMouseListener->second->mouseMoved( e ))
            break;
    }

    return true;
}

bool InputManager::mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id ) {
    itMouseListener    = mMouseListeners.begin();
    itMouseListenerEnd = mMouseListeners.end();
    for(; itMouseListener != itMouseListenerEnd; ++itMouseListener ) {
        if(!itMouseListener->second->mousePressed( e, id ))
            break;
    }

    return true;
}

bool InputManager::mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ) {
    itMouseListener    = mMouseListeners.begin();
    itMouseListenerEnd = mMouseListeners.end();
    for(; itMouseListener != itMouseListenerEnd; ++itMouseListener ) {
        if(!itMouseListener->second->mouseReleased( e, id ))
            break;
    }

    return true;
}

bool InputManager::povMoved( const OIS::JoyStickEvent &e, int pov ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if(!itJoystickListener->second->povMoved( e, pov ))
            break;
    }

    return true;
}

bool InputManager::axisMoved( const OIS::JoyStickEvent &e, int axis ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if(!itJoystickListener->second->axisMoved( e, axis ))
            break;
    }

    return true;
}

bool InputManager::sliderMoved( const OIS::JoyStickEvent &e, int sliderID ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if(!itJoystickListener->second->sliderMoved( e, sliderID ))
            break;
    }

    return true;
}

bool InputManager::buttonPressed( const OIS::JoyStickEvent &e, int button ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if(!itJoystickListener->second->buttonPressed( e, button ))
            break;
    }

    return true;
}

bool InputManager::buttonReleased( const OIS::JoyStickEvent &e, int button ) {
    itJoystickListener    = mJoystickListeners.begin();
    itJoystickListenerEnd = mJoystickListeners.end();
    for(; itJoystickListener != itJoystickListenerEnd; ++itJoystickListener ) {
        if(!itJoystickListener->second->buttonReleased( e, button ))
            break;
    }

    return true;
}

InputManager* InputManager::getSingletonPtr( void ) {
    if( !mInputManager ) {
        mInputManager = new InputManager();
    }

    return mInputManager;
}

Sample Usage

Just fire up the inputmanager like that:

// Setup input
    mInputMgr = InputManager::getSingletonPtr();
    mInputMgr->initialise( mRenderWindow );
    mInputMgr->addKeyListener( this, "ListenerName" );
    mInputMgr->addMouseListener( this, "ListenerName" );
    mInputMgr->addJoystickListener( this, "ListenerName" );

Example (Download)

Here you can download an example which uses the OIS InputManager with game states and a custom application loop (instead of using the framelisteners): Download link

Important Notes

  • Very Important: If you are not using Ogre's startRendering() call (e.g using renderOneFrame() or window->update() instead), make sure you pump Win32 messages. This can be done with Ogre's Ogre::WindowEventUtilities::messagePump();. If you forget to do so, you will have weird behavior with regards to text/shift/capslock.
  • The first call to InputManager::getSingletonPtr() creates the input manager. Do not forget to destroy it at the end(OIS::InputManager::destroyInputSystem()).
  • Don't forget to capture incoming input events before every frame!
  • If your render window resizes, you should readjust the Mouse clipping values of the mouse state structure.
  • In buffered mode, the keyboard keys will trigger a call to keyPressed() and keyReleased(). Unbuffered access (or immediate access) to the keyboard keys is obtained via a call of InputManager::getSingletonPtr()->getKeyboard()->isKeyDown(OIS::KC_UP). In this case, it is tested whether the up arrow is pressed. If you are calling capture() outside of FrameStarted(), such as within a main loop, the following hack will trigger a call to keyPressed() with an "unassigned" key. Add the two bold printed lines to the keyboard handling code within InputManager::capture( void ):

if( mKeyboard ) {
   mKeyboard->capture();
   '''OIS::KeyEvent e(mKeyboard, 0, OIS::KC_UNASSIGNED, 0);'''
   '''keyPressed(e);'''
 }

  • When writing your input handler functions such as keyPressed(), keyReleased(), mouseMoved(), etc, it is vitally important to always return true, otherwise (if you return false) you are asking for OIS to discard the remainder of your input buffer. This will have a subtle effect of dropping your character inputs randomly, especially when running at low frame rates and typing quickly (and hence using your input buffer more).
  • Double-clicks Using OIS: Basically, whenever the left mouse button is released, you note the time. Whenever it's pressed, you subtract the last-released time. If it's less than (say) 250 milliseconds, you've got a double click. Otherwise, you've got a single click. This assumes, of course, that you're treating a "click" as a mouse press-and-release (rather than just the press).
  • If you are using Paul Nettle's Memory Manager (OGRE uses it internally for tracking down issues, but it's disabled by default) to tackle memory bugs in your project, don't forget to include any STL headers used by OIS (or any external library for that matter) before you include anything OIS related. I just spent four hours chasing my tail because I didn't take into consideration OIS's dependencies on the STL.
  • If you crash your application using the X11 window system in linux you can go to a console by pressing CTRL+ALT+F2 and there kill your application using "ps -Al" and "killall -s KILL appname". After that your keyboard may stop working correctly and not repeat keys when you hold a key down. To fix that just type "xset r on".

Non-exclusive input

This is useful for non fullscreen mode running applications, especially when debugging.
If you want to see the mouse cursor and be able to move it outside your OGRE window and use the keyboard outside the running application, you might want to try the following:

// insert the following lines right before calling mInputSystem = OIS::InputManager::createInputSystem( paramList );
#if defined OIS_WIN32_PLATFORM
paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
paramList.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
paramList.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
paramList.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
paramList.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
#endif


If you are using ExampleFrameListener, there's an easy way to override it. In your child class constructor, destroy the InputSystem first, then just recreate it with your own parameters, as follows:

mInputManager->destroyInputObject(mMouse);
mInputManager->destroyInputObject(mKeyboard);
mInputManager->destroyInputObject(mJoy);
OIS::InputManager::destroyInputSystem(mInputManager);

// override OIS construction to avoid grabbing mouse
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;

window->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
#if defined OIS_WIN32_PLATFORM
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));
pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
#elif defined OIS_LINUX_PLATFORM
pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
#endif

mInputManager = OIS::InputManager::createInputSystem( pl );

//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, false ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, false ));
try {
	mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, false ));
}
catch(...) {
	mJoy = 0;
}



Warning! This might break absolute mouseposition under win32, but maybe you can correct the error by listening to the windowMoved event in a Ogre::WindowEventListener and substract the left-top coordinates of the window from the "absolute" mouseposition returned by OIS.

Info NOTE: As of 2010-05-04, there are no problems with OIS and non-exclusive input under Windows. All you have to do is tell OIS the size of the render window each time the window is (re)created:

Ogre::RenderWindow::getMetrics(w, h, d, left, top);
const OIS::MouseState &ms = mMouse->getMouseState();
ms.width = w;
ms.height = h;


If you are using a Mac / OSX you have to manually override the cursor visibility. OIS will hide it by default with no option to show it and share it.

First include the Carbon.h header

#ifdef OIS_APPLE_PLATFORM
#include <Carbon/Carbon.h>
#endif

Then, after you create and initialize OIS and create a mouse input execute the appropriate commands.

#ifdef OIS_APPLE_PLATFORM
CGDisplayShowCursor(kCGDirectMainDisplay);
CGAssociateMouseAndMouseCursorPosition(TRUE);
#endif

OIS on OSX in windowed mode

If you run your app in windowed mode you may notice that you receive no mouse input when your app launches. This is because OIS is incorrectly computing the center coords for your window, so the mouse is hidden and outside the bounds of your application window. To fix this you can manually move the mouse to the correct position.

First include the Carbon.h header

#ifdef OIS_APPLE_PLATFORM
#include <Carbon/Carbon.h>
#endif


Next, after initializing OIS and creating a mouse input.

#ifdef OIS_APPLE_PLATFORM
            Ogre::Rect r = getWindowBounds(renderWindow);
            CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, CGPointMake(r.left + r.right / 2, r.top - r.bottom / 2));
#endif


Where renderWindow is a pointer to your Ogre::RenderWindow. You will also need to create a new class to bridge between your objective c code and your c++ code. So create a class called something like OgreInputInterface

OgreInputInterface.h

@interface OgreInputInterface : NSObject
@end


OgreInputInterface.mm <-- the mm ending is IMPORTANT

#import "OgreInputInterface.h"
#include <Ogre.h>
// HAX - this prevents collisions with glew / gl type defines
#define __glew_h__
#include <OgreOSXCocoaWindow.h>
@implementation OgreInputInterface
Ogre::Rect getWindowBounds(Ogre::RenderWindow *renderWindow)
{
    Ogre::OSXCocoaWindow *cw = static_cast<Ogre::OSXCocoaWindow*>(renderWindow);
    NSWindow *win = cw->ogreWindow();
    
    // invert the y value to get the distance from the top of the display. ugh. 
    NSScreen *screen = NSScreen.mainScreen;
    NSRect rect = screen.frame;
    
    return Ogre::Rect(win.frame.origin.x, rect.size.height - win.frame.origin.y, win.frame.size.width, win.frame.size.height);
}

@end

See also


Alias: Using_OIS