mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	Move SDL helpers to their own package in extern/, allow conversion from sdl to ois keycodes, (maybe) fix unicode handling
This commit is contained in:
		
							parent
							
								
									cb01df49c0
								
							
						
					
					
						commit
						ed644259ce
					
				
					 14 changed files with 733 additions and 408 deletions
				
			
		| 
						 | 
				
			
			@ -474,6 +474,7 @@ endif(WIN32)
 | 
			
		|||
# Extern
 | 
			
		||||
add_subdirectory (extern/shiny)
 | 
			
		||||
add_subdirectory (extern/oics)
 | 
			
		||||
add_subdirectory (extern/sdl4ogre)
 | 
			
		||||
 | 
			
		||||
# Components
 | 
			
		||||
add_subdirectory (components)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@ add_openmw_dir (mwrender
 | 
			
		|||
    )
 | 
			
		||||
 | 
			
		||||
add_openmw_dir (mwinput
 | 
			
		||||
    inputmanagerimp sdlinputwrapper
 | 
			
		||||
    inputmanagerimp
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
add_openmw_dir (mwgui
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +108,7 @@ target_link_libraries(openmw
 | 
			
		|||
    "shiny"
 | 
			
		||||
    "shiny.OgrePlatform"
 | 
			
		||||
    "oics"
 | 
			
		||||
    "sdl4ogre"
 | 
			
		||||
    components
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,13 +62,13 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
        Ogre::RenderWindow* window = ogre.getWindow ();
 | 
			
		||||
 | 
			
		||||
        mInputManager = new MWSDLInputWrapper(window);
 | 
			
		||||
        mInputManager = new SFO::InputWrapper(window);
 | 
			
		||||
        mInputManager->setMouseEventCallback (this);
 | 
			
		||||
        mInputManager->setKeyboardEventCallback (this);
 | 
			
		||||
        mInputManager->setWindowEventCallback(this);
 | 
			
		||||
 | 
			
		||||
        std::string file = userFileExists ? userFile : "";
 | 
			
		||||
        mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
 | 
			
		||||
        mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
 | 
			
		||||
 | 
			
		||||
        adjustMouseRegion (window->getWidth(), window->getHeight());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
        for (int i = 0; i < A_Last; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            mInputCtrl->getChannel (i)->addListener (this);
 | 
			
		||||
            mInputBinder->getChannel (i)->addListener (this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mControlSwitch["playercontrols"]      = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -94,9 +94,9 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    InputManager::~InputManager()
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->save (mUserFile);
 | 
			
		||||
        mInputBinder->save (mUserFile);
 | 
			
		||||
 | 
			
		||||
        delete mInputCtrl;
 | 
			
		||||
        delete mInputBinder;
 | 
			
		||||
 | 
			
		||||
        delete mInputManager;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +206,7 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
        // update values of channels (as a result of pressed keys)
 | 
			
		||||
        if (!loading)
 | 
			
		||||
            mInputCtrl->update(dt);
 | 
			
		||||
            mInputBinder->update(dt);
 | 
			
		||||
 | 
			
		||||
        // Update windows/gui as a result of input events
 | 
			
		||||
        // For instance this could mean opening a new window/dialog,
 | 
			
		||||
| 
						 | 
				
			
			@ -396,12 +396,12 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    void InputManager::adjustMouseRegion(int width, int height)
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->adjustMouseRegion(width, height);
 | 
			
		||||
        mInputBinder->adjustMouseRegion(width, height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->keyPressed (arg);
 | 
			
		||||
        mInputBinder->keyPressed (arg);
 | 
			
		||||
        unsigned int text = arg.keysym.unicode;
 | 
			
		||||
 | 
			
		||||
        //TODO: Check if we need this with SDL
 | 
			
		||||
| 
						 | 
				
			
			@ -414,23 +414,27 @@ namespace MWInput
 | 
			
		|||
#endif
 | 
			
		||||
        */
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text);
 | 
			
		||||
        OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputManager::keyReleased(const SDL_KeyboardEvent &arg )
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->keyReleased (arg);
 | 
			
		||||
        mInputBinder->keyReleased (arg);
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.keysym.sym));
 | 
			
		||||
        OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->mousePressed (arg, id);
 | 
			
		||||
        mInputBinder->mousePressed (arg, id);
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -448,16 +452,16 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->mouseReleased (arg, id);
 | 
			
		||||
        mInputBinder->mouseReleased (arg, id);
 | 
			
		||||
 | 
			
		||||
        MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id));
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputManager::mouseMoved( const ICS::MWSDLMouseMotionEvent &arg )
 | 
			
		||||
    bool InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
 | 
			
		||||
    {
 | 
			
		||||
        mInputCtrl->mouseMoved (arg);
 | 
			
		||||
        mInputBinder->mouseMoved (arg);
 | 
			
		||||
 | 
			
		||||
        resetIdleTime ();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -683,7 +687,7 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    bool InputManager::actionIsActive (int id)
 | 
			
		||||
    {
 | 
			
		||||
        return mInputCtrl->getChannel (id)->getValue () == 1;
 | 
			
		||||
        return mInputBinder->getChannel (id)->getValue () == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputManager::loadKeyDefaults (bool force)
 | 
			
		||||
| 
						 | 
				
			
			@ -728,29 +732,29 @@ namespace MWInput
 | 
			
		|||
        for (int i = 0; i < A_Last; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            ICS::Control* control;
 | 
			
		||||
            bool controlExists = mInputCtrl->getChannel(i)->getControlsCount () != 0;
 | 
			
		||||
            bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0;
 | 
			
		||||
            if (!controlExists)
 | 
			
		||||
            {
 | 
			
		||||
                control = new ICS::Control(boost::lexical_cast<std::string>(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX);
 | 
			
		||||
                mInputCtrl->addControl(control);
 | 
			
		||||
                control->attachChannel(mInputCtrl->getChannel(i), ICS::Channel::DIRECT);
 | 
			
		||||
                mInputBinder->addControl(control);
 | 
			
		||||
                control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                control = mInputCtrl->getChannel(i)->getAttachedControls ().front().control;
 | 
			
		||||
                control = mInputBinder->getChannel(i)->getAttachedControls ().front().control;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!controlExists || force ||
 | 
			
		||||
                    ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN
 | 
			
		||||
                      && mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
 | 
			
		||||
                    ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN
 | 
			
		||||
                      && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
 | 
			
		||||
                      ))
 | 
			
		||||
            {
 | 
			
		||||
                clearAllBindings (control);
 | 
			
		||||
 | 
			
		||||
                if (defaultKeyBindings.find(i) != defaultKeyBindings.end())
 | 
			
		||||
                    mInputCtrl->addKeyBinding(control, static_cast<SDL_Keycode>(defaultKeyBindings[i]), ICS::Control::INCREASE);
 | 
			
		||||
                    mInputBinder->addKeyBinding(control, static_cast<SDL_Keycode>(defaultKeyBindings[i]), ICS::Control::INCREASE);
 | 
			
		||||
                else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end())
 | 
			
		||||
                    mInputCtrl->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
 | 
			
		||||
                    mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -794,15 +798,15 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    std::string InputManager::getActionBindingName (int action)
 | 
			
		||||
    {
 | 
			
		||||
        if (mInputCtrl->getChannel (action)->getControlsCount () == 0)
 | 
			
		||||
        if (mInputBinder->getChannel (action)->getControlsCount () == 0)
 | 
			
		||||
            return "#{sNone}";
 | 
			
		||||
 | 
			
		||||
        ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
 | 
			
		||||
        ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
 | 
			
		||||
 | 
			
		||||
        if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN)
 | 
			
		||||
            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));
 | 
			
		||||
        if (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN)
 | 
			
		||||
            return mInputBinder->keyCodeToString (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE));
 | 
			
		||||
        else if (mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
 | 
			
		||||
            return "#{sMouse} " + boost::lexical_cast<std::string>(mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE));
 | 
			
		||||
        else
 | 
			
		||||
            return "#{sNone}";
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -842,9 +846,9 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
    void InputManager::enableDetectingBindingMode (int action)
 | 
			
		||||
    {
 | 
			
		||||
        ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
 | 
			
		||||
        ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
 | 
			
		||||
 | 
			
		||||
        mInputCtrl->enableDetectingBindingState (c, ICS::Control::INCREASE);
 | 
			
		||||
        mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
 | 
			
		||||
| 
						 | 
				
			
			@ -905,10 +909,10 @@ namespace MWInput
 | 
			
		|||
    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) != SDLK_UNKNOWN)
 | 
			
		||||
            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));
 | 
			
		||||
        if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN)
 | 
			
		||||
            mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE));
 | 
			
		||||
        if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
 | 
			
		||||
            mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE));
 | 
			
		||||
 | 
			
		||||
        /// \todo add joysticks here once they are added
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
#include <components/settings/settings.hpp>
 | 
			
		||||
 | 
			
		||||
#include "../mwbase/inputmanager.hpp"
 | 
			
		||||
#include "sdlinputwrapper.hpp"
 | 
			
		||||
#include <extern/sdl4ogre/sdlinputwrapper.hpp>
 | 
			
		||||
 | 
			
		||||
namespace OEngine
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,6 @@ namespace MyGUI
 | 
			
		|||
 | 
			
		||||
#include <extern/oics/ICSChannelListener.h>
 | 
			
		||||
#include <extern/oics/ICSInputControlSystem.h>
 | 
			
		||||
#include <extern/oics/OISCompat.h>
 | 
			
		||||
 | 
			
		||||
namespace MWInput
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -53,9 +52,9 @@ namespace MWInput
 | 
			
		|||
    */
 | 
			
		||||
    class InputManager :
 | 
			
		||||
            public MWBase::InputManager,
 | 
			
		||||
            public ICS::MWSDLKeyListener,
 | 
			
		||||
            public ICS::MWSDLMouseListener,
 | 
			
		||||
            public ICS::MWSDLWindowListener,
 | 
			
		||||
            public SFO::KeyListener,
 | 
			
		||||
            public SFO::MouseListener,
 | 
			
		||||
            public SFO::WindowListener,
 | 
			
		||||
            public ICS::ChannelListener,
 | 
			
		||||
            public ICS::DetectingBindingListener
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +92,7 @@ namespace MWInput
 | 
			
		|||
 | 
			
		||||
        virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
 | 
			
		||||
        virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
 | 
			
		||||
        virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg );
 | 
			
		||||
        virtual bool mouseMoved( const SFO::MouseMotionEvent &arg );
 | 
			
		||||
 | 
			
		||||
        virtual bool windowVisibilityChange( bool visible );
 | 
			
		||||
        virtual bool windowFocusChange( bool have_focus );
 | 
			
		||||
| 
						 | 
				
			
			@ -129,10 +128,10 @@ namespace MWInput
 | 
			
		|||
        MWBase::WindowManager &mWindows;
 | 
			
		||||
        OMW::Engine& mEngine;
 | 
			
		||||
 | 
			
		||||
        ICS::InputControlSystem* mInputCtrl;
 | 
			
		||||
        ICS::InputControlSystem* mInputBinder;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        MWSDLInputWrapper* mInputManager;
 | 
			
		||||
        SFO::InputWrapper* mInputManager;
 | 
			
		||||
 | 
			
		||||
        std::string mUserFile;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,254 +0,0 @@
 | 
			
		|||
#include "sdlinputwrapper.hpp"
 | 
			
		||||
#include <SDL2/SDL.h>
 | 
			
		||||
#include <SDL2/SDL_syswm.h>
 | 
			
		||||
 | 
			
		||||
#include <OgrePlatform.h>
 | 
			
		||||
#include <OgreRoot.h>
 | 
			
		||||
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
 | 
			
		||||
#   include <X11/Xlib.h>
 | 
			
		||||
#   include <X11/Xutil.h>
 | 
			
		||||
#   include <X11/Xos.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace MWInput
 | 
			
		||||
{
 | 
			
		||||
    MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) :
 | 
			
		||||
        mWindow(window),
 | 
			
		||||
        mSDLWindow(NULL),
 | 
			
		||||
        mWarpCompensate(false),
 | 
			
		||||
        mMouseRelative(false),
 | 
			
		||||
        mGrabPointer(false),
 | 
			
		||||
        mWrapPointer(false)
 | 
			
		||||
    {
 | 
			
		||||
        _start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MWSDLInputWrapper::~MWSDLInputWrapper()
 | 
			
		||||
    {
 | 
			
		||||
        if(mSDLWindow != NULL)
 | 
			
		||||
            SDL_DestroyWindow(mSDLWindow);
 | 
			
		||||
        mSDLWindow = NULL;
 | 
			
		||||
        SDL_StopTextInput();
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MWSDLInputWrapper::_start()
 | 
			
		||||
    {
 | 
			
		||||
        Uint32 flags = SDL_INIT_VIDEO;
 | 
			
		||||
        if(SDL_WasInit(flags) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            //get the HWND from ogre's renderwindow
 | 
			
		||||
            size_t windowHnd;
 | 
			
		||||
            mWindow->getCustomAttribute("WINDOW", &windowHnd);
 | 
			
		||||
 | 
			
		||||
            //kindly ask SDL not to trash our OGL context
 | 
			
		||||
            SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
 | 
			
		||||
            if(SDL_Init(SDL_INIT_VIDEO) != 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            //wrap our own event handler around ogre's
 | 
			
		||||
            mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd);
 | 
			
		||||
 | 
			
		||||
            if(mSDLWindow == NULL)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            SDL_StartTextInput();
 | 
			
		||||
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
 | 
			
		||||
            //linux-specific event-handling fixups
 | 
			
		||||
            SDL_SysWMinfo wm_info;
 | 
			
		||||
            SDL_VERSION(&wm_info.version);
 | 
			
		||||
 | 
			
		||||
            if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info))
 | 
			
		||||
            {
 | 
			
		||||
                Display* display = wm_info.info.x11.display;
 | 
			
		||||
                Window w = wm_info.info.x11.window;
 | 
			
		||||
 | 
			
		||||
                // Set the input hints so we get keyboard input
 | 
			
		||||
                XWMHints *wmhints = XAllocWMHints();
 | 
			
		||||
                if (wmhints) {
 | 
			
		||||
                    wmhints->input = True;
 | 
			
		||||
                    wmhints->flags = InputHint;
 | 
			
		||||
                    XSetWMHints(display, w, wmhints);
 | 
			
		||||
                    XFree(wmhints);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //make sure to subscribe to XLib's events
 | 
			
		||||
                XSelectInput(display, w,
 | 
			
		||||
                             (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
 | 
			
		||||
                             ExposureMask | ButtonPressMask | ButtonReleaseMask |
 | 
			
		||||
                             PointerMotionMask | KeyPressMask | KeyReleaseMask |
 | 
			
		||||
                             PropertyChangeMask | StructureNotifyMask |
 | 
			
		||||
                             KeymapStateMask));
 | 
			
		||||
 | 
			
		||||
                XFlush(display);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            SDL_ShowCursor(SDL_FALSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::capture()
 | 
			
		||||
    {
 | 
			
		||||
        if(!_start())
 | 
			
		||||
            throw std::runtime_error(SDL_GetError());
 | 
			
		||||
 | 
			
		||||
        SDL_Event evt;
 | 
			
		||||
        while(SDL_PollEvent(&evt))
 | 
			
		||||
        {
 | 
			
		||||
            switch(evt.type)
 | 
			
		||||
            {
 | 
			
		||||
                case SDL_MOUSEMOTION:
 | 
			
		||||
                    //ignore this if it happened due to a warp
 | 
			
		||||
                    if(!_handleWarpMotion(evt.motion))
 | 
			
		||||
                    {
 | 
			
		||||
                        mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion));
 | 
			
		||||
 | 
			
		||||
                        //try to keep the mouse inside the window
 | 
			
		||||
                        _wrapMousePointer(evt.motion);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEWHEEL:
 | 
			
		||||
                    mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel));
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
                    mMouseListener->mousePressed(evt.button, evt.button.button);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEBUTTONUP:
 | 
			
		||||
                    mMouseListener->mouseReleased(evt.button, evt.button.button);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case SDL_KEYDOWN:
 | 
			
		||||
                    _handleKeyPress(evt.key);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_KEYUP:
 | 
			
		||||
                    mKeyboardListener->keyReleased(evt.key);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case SDL_WINDOWEVENT_FOCUS_GAINED:
 | 
			
		||||
                    mWindowListener->windowFocusChange(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_FOCUS_LOST:
 | 
			
		||||
                    mWindowListener->windowFocusChange(false);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_EXPOSED:
 | 
			
		||||
                    mWindowListener->windowVisibilityChange(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_HIDDEN:
 | 
			
		||||
                    mWindowListener->windowVisibilityChange(false);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                //SDL traps ^C signals, pass it to OGRE.
 | 
			
		||||
                case SDL_QUIT:
 | 
			
		||||
                    Ogre::Root::getSingleton().queueEndRendering();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MWSDLInputWrapper::isModifierHeld(int mod)
 | 
			
		||||
    {
 | 
			
		||||
        return SDL_GetModState() & mod;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::warpMouse(int x, int y)
 | 
			
		||||
    {
 | 
			
		||||
        SDL_WarpMouseInWindow(mSDLWindow, x, y);
 | 
			
		||||
        mWarpCompensate = true;
 | 
			
		||||
        mWarpX = x;
 | 
			
		||||
        mWarpY = y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::setGrabPointer(bool grab)
 | 
			
		||||
    {
 | 
			
		||||
        SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE;
 | 
			
		||||
 | 
			
		||||
        mGrabPointer = grab;
 | 
			
		||||
        SDL_SetWindowGrab(mSDLWindow, sdlGrab);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::setMouseRelative(bool relative)
 | 
			
		||||
    {
 | 
			
		||||
        if(mMouseRelative == relative)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        mMouseRelative = relative;
 | 
			
		||||
 | 
			
		||||
        mWrapPointer = false;
 | 
			
		||||
 | 
			
		||||
        //eep, wrap the pointer manually if the input driver doesn't support
 | 
			
		||||
        //relative positioning natively
 | 
			
		||||
        if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1)
 | 
			
		||||
        {
 | 
			
		||||
            if(relative)
 | 
			
		||||
                mWrapPointer = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //now remove all mouse events using the old setting from the queue
 | 
			
		||||
        SDL_PumpEvents();
 | 
			
		||||
 | 
			
		||||
        SDL_Event dummy[20];
 | 
			
		||||
        SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool MWSDLInputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        if(!mWarpCompensate)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        //this was a warp event, signal the caller to eat it.
 | 
			
		||||
        if(evt.x == mWarpX && evt.y == mWarpY)
 | 
			
		||||
        {
 | 
			
		||||
            mWarpCompensate = false;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        //don't wrap if we don't want relative movements, support relative
 | 
			
		||||
        //movements natively, or aren't grabbing anyways
 | 
			
		||||
        if(!mMouseRelative || !mWrapPointer || !mGrabPointer)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        int width = 0;
 | 
			
		||||
        int height = 0;
 | 
			
		||||
 | 
			
		||||
        SDL_GetWindowSize(mSDLWindow, &width, &height);
 | 
			
		||||
 | 
			
		||||
        const int FUDGE_FACTOR_X = width / 4;
 | 
			
		||||
        const int FUDGE_FACTOR_Y = height / 4;
 | 
			
		||||
 | 
			
		||||
        //warp the mouse if it's about to go outside the window
 | 
			
		||||
        if(evt.x - FUDGE_FACTOR_X < 0  || evt.x + FUDGE_FACTOR_X > width
 | 
			
		||||
                || evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height)
 | 
			
		||||
        {
 | 
			
		||||
            warpMouse(width / 2, height / 2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void MWSDLInputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt)
 | 
			
		||||
    {
 | 
			
		||||
        //SDL keyboard events are followed by the actual text those keys would generate
 | 
			
		||||
        //to account for languages that require multiple keystrokes to produce a key.
 | 
			
		||||
        //Look for an event immediately following ours, assuming each key produces exactly
 | 
			
		||||
        //one character.
 | 
			
		||||
 | 
			
		||||
        //TODO: This won't work for multibyte characters, but MyGUI is the only consumer
 | 
			
		||||
        //of these, does it even support multibyte characters?
 | 
			
		||||
 | 
			
		||||
        SDL_Event text_evts[1];
 | 
			
		||||
        if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            evt.keysym.unicode = text_evts[0].text.text[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mKeyboardListener->keyPressed(evt);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,53 +0,0 @@
 | 
			
		|||
#ifndef _MWINPUT_SDLINPUTWRAPPER_H
 | 
			
		||||
#define _MWINPUT_SDLINPUTWRAPPER_H
 | 
			
		||||
 | 
			
		||||
#include "SDL2/SDL_events.h"
 | 
			
		||||
#include <extern/oics/OISCompat.h>
 | 
			
		||||
#include <OGRE/OgreRenderWindow.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace MWInput
 | 
			
		||||
{
 | 
			
		||||
    class MWSDLInputWrapper
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        MWSDLInputWrapper(Ogre::RenderWindow* window);
 | 
			
		||||
        ~MWSDLInputWrapper();
 | 
			
		||||
 | 
			
		||||
        void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; }
 | 
			
		||||
        void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; }
 | 
			
		||||
        void setWindowEventCallback(ICS::MWSDLWindowListener* listen) { mWindowListener = listen; }
 | 
			
		||||
 | 
			
		||||
        void capture();
 | 
			
		||||
        bool isModifierHeld(int mod);
 | 
			
		||||
 | 
			
		||||
        void setMouseRelative(bool relative);
 | 
			
		||||
        bool getMouseRelative() { return mMouseRelative; }
 | 
			
		||||
        void setGrabPointer(bool grab);
 | 
			
		||||
 | 
			
		||||
        void warpMouse(int x, int y);
 | 
			
		||||
    private:
 | 
			
		||||
        bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
 | 
			
		||||
        void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
 | 
			
		||||
 | 
			
		||||
        void _handleKeyPress(SDL_KeyboardEvent& evt);
 | 
			
		||||
 | 
			
		||||
        bool _start();
 | 
			
		||||
 | 
			
		||||
        ICS::MWSDLMouseListener* mMouseListener;
 | 
			
		||||
        ICS::MWSDLKeyListener* mKeyboardListener;
 | 
			
		||||
        ICS::MWSDLWindowListener* mWindowListener;
 | 
			
		||||
 | 
			
		||||
        Uint16 mWarpX;
 | 
			
		||||
        Uint16 mWarpY;
 | 
			
		||||
        bool mWarpCompensate;
 | 
			
		||||
        bool mMouseRelative;
 | 
			
		||||
        bool mWrapPointer;
 | 
			
		||||
        bool mGrabPointer;
 | 
			
		||||
 | 
			
		||||
        Ogre::RenderWindow* mWindow;
 | 
			
		||||
        SDL_Window* mSDLWindow;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1
									
								
								extern/oics/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								extern/oics/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -9,7 +9,6 @@ set(OICS_SOURCE_FILES
 | 
			
		|||
	ICSInputControlSystem_keyboard.cpp
 | 
			
		||||
	ICSInputControlSystem_mouse.cpp
 | 
			
		||||
	ICSInputControlSystem_joystick.cpp
 | 
			
		||||
	OISCompat.h
 | 
			
		||||
	tinyxml.cpp
 | 
			
		||||
	tinyxmlparser.cpp
 | 
			
		||||
	tinyxmlerror.cpp
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								extern/oics/ICSInputControlSystem.h
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -32,7 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		|||
#include "ICSControl.h"
 | 
			
		||||
#include "ICSChannel.h"
 | 
			
		||||
 | 
			
		||||
#include "OISCompat.h"
 | 
			
		||||
#include "../sdl4ogre/events.h"
 | 
			
		||||
 | 
			
		||||
#define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() );
 | 
			
		||||
#define ICS_MAX_JOYSTICK_AXIS 16
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +50,9 @@ namespace ICS
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
	class DllExport InputControlSystem : 
 | 
			
		||||
		public MWSDLMouseListener,
 | 
			
		||||
		public MWSDLKeyListener,
 | 
			
		||||
        public MWSDLJoyStickListener
 | 
			
		||||
		public SFO::MouseListener,
 | 
			
		||||
		public SFO::KeyListener,
 | 
			
		||||
        public SFO::JoyListener
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ namespace ICS
 | 
			
		|||
		JoystickIDList& getJoystickIdList(){ return mJoystickIDList; };
 | 
			
		||||
		
 | 
			
		||||
		// MouseListener
 | 
			
		||||
		bool mouseMoved(const MWSDLMouseMotionEvent &evt);
 | 
			
		||||
		bool mouseMoved(const SFO::MouseMotionEvent &evt);
 | 
			
		||||
		bool mousePressed(const SDL_MouseButtonEvent &evt, Uint8);
 | 
			
		||||
		bool mouseReleased(const SDL_MouseButtonEvent &evt, Uint8);
 | 
			
		||||
		
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								extern/oics/ICSInputControlSystem_mouse.cpp
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -219,7 +219,7 @@ namespace ICS
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// mouse Listeners
 | 
			
		||||
	bool InputControlSystem::mouseMoved(const MWSDLMouseMotionEvent& evt)
 | 
			
		||||
	bool InputControlSystem::mouseMoved(const SFO::MouseMotionEvent& evt)
 | 
			
		||||
	{
 | 
			
		||||
		if(mActive)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								extern/sdl4ogre/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								extern/sdl4ogre/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
set(SDL4OGRE_LIBRARY "sdl4ogre")
 | 
			
		||||
 | 
			
		||||
# Sources
 | 
			
		||||
 | 
			
		||||
set(SDL4OGRE_SOURCE_FILES
 | 
			
		||||
	sdlinputwrapper.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(${SDL4OGRE_LIBRARY} STATIC ${SDL4OGRE_SOURCE_FILES})
 | 
			
		||||
 | 
			
		||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
target_link_libraries(${SDL4OGRE_LIBRARY} ${SDL2_LIBRARY})
 | 
			
		||||
							
								
								
									
										159
									
								
								extern/sdl4ogre/OISCompat.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								extern/sdl4ogre/OISCompat.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,159 @@
 | 
			
		|||
#ifndef _OIS_SDL_COMPAT_H
 | 
			
		||||
#define _OIS_SDL_COMPAT_H
 | 
			
		||||
 | 
			
		||||
#include <SDL2/SDL_events.h>
 | 
			
		||||
#include <SDL2/SDL_types.h>
 | 
			
		||||
 | 
			
		||||
namespace OIS
 | 
			
		||||
{
 | 
			
		||||
//! Keyboard scan codes
 | 
			
		||||
enum KeyCode
 | 
			
		||||
{
 | 
			
		||||
    KC_UNASSIGNED  = 0x00,
 | 
			
		||||
    KC_ESCAPE      = 0x01,
 | 
			
		||||
    KC_1           = 0x02,
 | 
			
		||||
    KC_2           = 0x03,
 | 
			
		||||
    KC_3           = 0x04,
 | 
			
		||||
    KC_4           = 0x05,
 | 
			
		||||
    KC_5           = 0x06,
 | 
			
		||||
    KC_6           = 0x07,
 | 
			
		||||
    KC_7           = 0x08,
 | 
			
		||||
    KC_8           = 0x09,
 | 
			
		||||
    KC_9           = 0x0A,
 | 
			
		||||
    KC_0           = 0x0B,
 | 
			
		||||
    KC_MINUS       = 0x0C,    // - on main keyboard
 | 
			
		||||
    KC_EQUALS      = 0x0D,
 | 
			
		||||
    KC_BACK        = 0x0E,    // backspace
 | 
			
		||||
    KC_TAB         = 0x0F,
 | 
			
		||||
    KC_Q           = 0x10,
 | 
			
		||||
    KC_W           = 0x11,
 | 
			
		||||
    KC_E           = 0x12,
 | 
			
		||||
    KC_R           = 0x13,
 | 
			
		||||
    KC_T           = 0x14,
 | 
			
		||||
    KC_Y           = 0x15,
 | 
			
		||||
    KC_U           = 0x16,
 | 
			
		||||
    KC_I           = 0x17,
 | 
			
		||||
    KC_O           = 0x18,
 | 
			
		||||
    KC_P           = 0x19,
 | 
			
		||||
    KC_LBRACKET    = 0x1A,
 | 
			
		||||
    KC_RBRACKET    = 0x1B,
 | 
			
		||||
    KC_RETURN      = 0x1C,    // Enter on main keyboard
 | 
			
		||||
    KC_LCONTROL    = 0x1D,
 | 
			
		||||
    KC_A           = 0x1E,
 | 
			
		||||
    KC_S           = 0x1F,
 | 
			
		||||
    KC_D           = 0x20,
 | 
			
		||||
    KC_F           = 0x21,
 | 
			
		||||
    KC_G           = 0x22,
 | 
			
		||||
    KC_H           = 0x23,
 | 
			
		||||
    KC_J           = 0x24,
 | 
			
		||||
    KC_K           = 0x25,
 | 
			
		||||
    KC_L           = 0x26,
 | 
			
		||||
    KC_SEMICOLON   = 0x27,
 | 
			
		||||
    KC_APOSTROPHE  = 0x28,
 | 
			
		||||
    KC_GRAVE       = 0x29,    // accent
 | 
			
		||||
    KC_LSHIFT      = 0x2A,
 | 
			
		||||
    KC_BACKSLASH   = 0x2B,
 | 
			
		||||
    KC_Z           = 0x2C,
 | 
			
		||||
    KC_X           = 0x2D,
 | 
			
		||||
    KC_C           = 0x2E,
 | 
			
		||||
    KC_V           = 0x2F,
 | 
			
		||||
    KC_B           = 0x30,
 | 
			
		||||
    KC_N           = 0x31,
 | 
			
		||||
    KC_M           = 0x32,
 | 
			
		||||
    KC_COMMA       = 0x33,
 | 
			
		||||
    KC_PERIOD      = 0x34,    // . on main keyboard
 | 
			
		||||
    KC_SLASH       = 0x35,    // / on main keyboard
 | 
			
		||||
    KC_RSHIFT      = 0x36,
 | 
			
		||||
    KC_MULTIPLY    = 0x37,    // * on numeric keypad
 | 
			
		||||
    KC_LMENU       = 0x38,    // left Alt
 | 
			
		||||
    KC_SPACE       = 0x39,
 | 
			
		||||
    KC_CAPITAL     = 0x3A,
 | 
			
		||||
    KC_F1          = 0x3B,
 | 
			
		||||
    KC_F2          = 0x3C,
 | 
			
		||||
    KC_F3          = 0x3D,
 | 
			
		||||
    KC_F4          = 0x3E,
 | 
			
		||||
    KC_F5          = 0x3F,
 | 
			
		||||
    KC_F6          = 0x40,
 | 
			
		||||
    KC_F7          = 0x41,
 | 
			
		||||
    KC_F8          = 0x42,
 | 
			
		||||
    KC_F9          = 0x43,
 | 
			
		||||
    KC_F10         = 0x44,
 | 
			
		||||
    KC_NUMLOCK     = 0x45,
 | 
			
		||||
    KC_SCROLL      = 0x46,    // Scroll Lock
 | 
			
		||||
    KC_NUMPAD7     = 0x47,
 | 
			
		||||
    KC_NUMPAD8     = 0x48,
 | 
			
		||||
    KC_NUMPAD9     = 0x49,
 | 
			
		||||
    KC_SUBTRACT    = 0x4A,    // - on numeric keypad
 | 
			
		||||
    KC_NUMPAD4     = 0x4B,
 | 
			
		||||
    KC_NUMPAD5     = 0x4C,
 | 
			
		||||
    KC_NUMPAD6     = 0x4D,
 | 
			
		||||
    KC_ADD         = 0x4E,    // + on numeric keypad
 | 
			
		||||
    KC_NUMPAD1     = 0x4F,
 | 
			
		||||
    KC_NUMPAD2     = 0x50,
 | 
			
		||||
    KC_NUMPAD3     = 0x51,
 | 
			
		||||
    KC_NUMPAD0     = 0x52,
 | 
			
		||||
    KC_DECIMAL     = 0x53,    // . on numeric keypad
 | 
			
		||||
    KC_OEM_102     = 0x56,    // < > | on UK/Germany keyboards
 | 
			
		||||
    KC_F11         = 0x57,
 | 
			
		||||
    KC_F12         = 0x58,
 | 
			
		||||
    KC_F13         = 0x64,    //                     (NEC PC98)
 | 
			
		||||
    KC_F14         = 0x65,    //                     (NEC PC98)
 | 
			
		||||
    KC_F15         = 0x66,    //                     (NEC PC98)
 | 
			
		||||
    KC_KANA        = 0x70,    // (Japanese keyboard)
 | 
			
		||||
    KC_ABNT_C1     = 0x73,    // / ? on Portugese (Brazilian) keyboards
 | 
			
		||||
    KC_CONVERT     = 0x79,    // (Japanese keyboard)
 | 
			
		||||
    KC_NOCONVERT   = 0x7B,    // (Japanese keyboard)
 | 
			
		||||
    KC_YEN         = 0x7D,    // (Japanese keyboard)
 | 
			
		||||
    KC_ABNT_C2     = 0x7E,    // Numpad . on Portugese (Brazilian) keyboards
 | 
			
		||||
    KC_NUMPADEQUALS= 0x8D,    // = on numeric keypad (NEC PC98)
 | 
			
		||||
    KC_PREVTRACK   = 0x90,    // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
 | 
			
		||||
    KC_AT          = 0x91,    //                     (NEC PC98)
 | 
			
		||||
    KC_COLON       = 0x92,    //                     (NEC PC98)
 | 
			
		||||
    KC_UNDERLINE   = 0x93,    //                     (NEC PC98)
 | 
			
		||||
    KC_KANJI       = 0x94,    // (Japanese keyboard)
 | 
			
		||||
    KC_STOP        = 0x95,    //                     (NEC PC98)
 | 
			
		||||
    KC_AX          = 0x96,    //                     (Japan AX)
 | 
			
		||||
    KC_UNLABELED   = 0x97,    //                        (J3100)
 | 
			
		||||
    KC_NEXTTRACK   = 0x99,    // Next Track
 | 
			
		||||
    KC_NUMPADENTER = 0x9C,    // Enter on numeric keypad
 | 
			
		||||
    KC_RCONTROL    = 0x9D,
 | 
			
		||||
    KC_MUTE        = 0xA0,    // Mute
 | 
			
		||||
    KC_CALCULATOR  = 0xA1,    // Calculator
 | 
			
		||||
    KC_PLAYPAUSE   = 0xA2,    // Play / Pause
 | 
			
		||||
    KC_MEDIASTOP   = 0xA4,    // Media Stop
 | 
			
		||||
    KC_VOLUMEDOWN  = 0xAE,    // Volume -
 | 
			
		||||
    KC_VOLUMEUP    = 0xB0,    // Volume +
 | 
			
		||||
    KC_WEBHOME     = 0xB2,    // Web home
 | 
			
		||||
    KC_NUMPADCOMMA = 0xB3,    // , on numeric keypad (NEC PC98)
 | 
			
		||||
    KC_DIVIDE      = 0xB5,    // / on numeric keypad
 | 
			
		||||
    KC_SYSRQ       = 0xB7,
 | 
			
		||||
    KC_RMENU       = 0xB8,    // right Alt
 | 
			
		||||
    KC_PAUSE       = 0xC5,    // Pause
 | 
			
		||||
    KC_HOME        = 0xC7,    // Home on arrow keypad
 | 
			
		||||
    KC_UP          = 0xC8,    // UpArrow on arrow keypad
 | 
			
		||||
    KC_PGUP        = 0xC9,    // PgUp on arrow keypad
 | 
			
		||||
    KC_LEFT        = 0xCB,    // LeftArrow on arrow keypad
 | 
			
		||||
    KC_RIGHT       = 0xCD,    // RightArrow on arrow keypad
 | 
			
		||||
    KC_END         = 0xCF,    // End on arrow keypad
 | 
			
		||||
    KC_DOWN        = 0xD0,    // DownArrow on arrow keypad
 | 
			
		||||
    KC_PGDOWN      = 0xD1,    // PgDn on arrow keypad
 | 
			
		||||
    KC_INSERT      = 0xD2,    // Insert on arrow keypad
 | 
			
		||||
    KC_DELETE      = 0xD3,    // Delete on arrow keypad
 | 
			
		||||
    KC_LWIN        = 0xDB,    // Left Windows key
 | 
			
		||||
    KC_RWIN        = 0xDC,    // Right Windows key
 | 
			
		||||
    KC_APPS        = 0xDD,    // AppMenu key
 | 
			
		||||
    KC_POWER       = 0xDE,    // System Power
 | 
			
		||||
    KC_SLEEP       = 0xDF,    // System Sleep
 | 
			
		||||
    KC_WAKE        = 0xE3,    // System Wake
 | 
			
		||||
    KC_WEBSEARCH   = 0xE5,    // Web Search
 | 
			
		||||
    KC_WEBFAVORITES= 0xE6,    // Web Favorites
 | 
			
		||||
    KC_WEBREFRESH  = 0xE7,    // Web Refresh
 | 
			
		||||
    KC_WEBSTOP     = 0xE8,    // Web Stop
 | 
			
		||||
    KC_WEBFORWARD  = 0xE9,    // Web Forward
 | 
			
		||||
    KC_WEBBACK     = 0xEA,    // Web Back
 | 
			
		||||
    KC_MYCOMPUTER  = 0xEB,    // My Computer
 | 
			
		||||
    KC_MAIL        = 0xEC,    // Mail
 | 
			
		||||
    KC_MEDIASELECT = 0xED     // Media Select
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,53 +1,20 @@
 | 
			
		|||
#ifndef _OIS_SDL_COMPAT_H
 | 
			
		||||
#define _OIS_SDL_COMPAT_H
 | 
			
		||||
#ifndef _SFO_EVENTS_H
 | 
			
		||||
#define _SFO_EVENTS_H
 | 
			
		||||
 | 
			
		||||
#include <SDL2/SDL_events.h>
 | 
			
		||||
#include <SDL2/SDL_types.h>
 | 
			
		||||
#include <SDL2/SDL.h>
 | 
			
		||||
 | 
			
		||||
//TODO: Remove this. Right now we want to remain as close to OIS as possible
 | 
			
		||||
//So we can easily test the SDL backend
 | 
			
		||||
 | 
			
		||||
////////////
 | 
			
		||||
// Events //
 | 
			
		||||
////////////
 | 
			
		||||
 | 
			
		||||
namespace ICS {
 | 
			
		||||
namespace SFO {
 | 
			
		||||
 | 
			
		||||
/** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */
 | 
			
		||||
struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent {
 | 
			
		||||
struct MouseMotionEvent : SDL_MouseMotionEvent {
 | 
			
		||||
 | 
			
		||||
    Sint16 zrel;
 | 
			
		||||
 | 
			
		||||
    MWSDLMouseMotionEvent()
 | 
			
		||||
    {
 | 
			
		||||
        _init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        _init();
 | 
			
		||||
        x = evt.x;
 | 
			
		||||
        y = evt.y;
 | 
			
		||||
        xrel = evt.xrel;
 | 
			
		||||
        yrel = evt.yrel;
 | 
			
		||||
        state = evt.state;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        _init();
 | 
			
		||||
        zrel = evt.y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void _init()
 | 
			
		||||
    {
 | 
			
		||||
        x = 0;
 | 
			
		||||
        y = 0;
 | 
			
		||||
        xrel = 0;
 | 
			
		||||
        yrel = 0;
 | 
			
		||||
        state = 0;
 | 
			
		||||
        zrel = 0;
 | 
			
		||||
    }
 | 
			
		||||
    Sint32 zrel;
 | 
			
		||||
    Sint32 z;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,27 +22,27 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent {
 | 
			
		|||
// Listeners //
 | 
			
		||||
///////////////
 | 
			
		||||
 | 
			
		||||
class MWSDLMouseListener
 | 
			
		||||
class MouseListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~MWSDLMouseListener() {}
 | 
			
		||||
    virtual bool mouseMoved( const MWSDLMouseMotionEvent &arg ) = 0;
 | 
			
		||||
    virtual ~MouseListener() {}
 | 
			
		||||
    virtual bool mouseMoved( const MouseMotionEvent &arg ) = 0;
 | 
			
		||||
    virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
 | 
			
		||||
    virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MWSDLKeyListener
 | 
			
		||||
class KeyListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~MWSDLKeyListener() {}
 | 
			
		||||
    virtual ~KeyListener() {}
 | 
			
		||||
    virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0;
 | 
			
		||||
    virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MWSDLJoyStickListener
 | 
			
		||||
class JoyListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~MWSDLJoyStickListener() {}
 | 
			
		||||
    virtual ~JoyListener() {}
 | 
			
		||||
    /** @remarks Joystick button down event */
 | 
			
		||||
    virtual bool buttonPressed( const SDL_JoyButtonEvent &evt, int button ) = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,10 +58,10 @@ public:
 | 
			
		|||
    virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MWSDLWindowListener
 | 
			
		||||
class WindowListener
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~MWSDLWindowListener() {}
 | 
			
		||||
    virtual ~WindowListener() {}
 | 
			
		||||
 | 
			
		||||
    /** @remarks The window's visibility changed */
 | 
			
		||||
    virtual bool windowVisibilityChange( bool visible ) = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -104,4 +71,5 @@ public:
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										420
									
								
								extern/sdl4ogre/sdlinputwrapper.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										420
									
								
								extern/sdl4ogre/sdlinputwrapper.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,420 @@
 | 
			
		|||
#include "sdlinputwrapper.hpp"
 | 
			
		||||
#include <SDL2/SDL_syswm.h>
 | 
			
		||||
 | 
			
		||||
#include <OgrePlatform.h>
 | 
			
		||||
#include <OgreRoot.h>
 | 
			
		||||
#include <boost/locale.hpp>
 | 
			
		||||
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
 | 
			
		||||
#   include <X11/Xlib.h>
 | 
			
		||||
#   include <X11/Xutil.h>
 | 
			
		||||
#   include <X11/Xos.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace SFO
 | 
			
		||||
{
 | 
			
		||||
    InputWrapper::InputWrapper(Ogre::RenderWindow *window) :
 | 
			
		||||
        mWindow(window),
 | 
			
		||||
        mSDLWindow(NULL),
 | 
			
		||||
        mWarpCompensate(false),
 | 
			
		||||
        mMouseRelative(false),
 | 
			
		||||
        mGrabPointer(false),
 | 
			
		||||
        mWrapPointer(false),
 | 
			
		||||
        mMouseZ(0),
 | 
			
		||||
        mMouseY(0),
 | 
			
		||||
        mMouseX(0)
 | 
			
		||||
    {
 | 
			
		||||
        _start();
 | 
			
		||||
        _setupOISKeys();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    InputWrapper::~InputWrapper()
 | 
			
		||||
    {
 | 
			
		||||
        if(mSDLWindow != NULL)
 | 
			
		||||
            SDL_DestroyWindow(mSDLWindow);
 | 
			
		||||
        mSDLWindow = NULL;
 | 
			
		||||
        SDL_StopTextInput();
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputWrapper::_start()
 | 
			
		||||
    {
 | 
			
		||||
        Uint32 flags = SDL_INIT_VIDEO;
 | 
			
		||||
        if(SDL_WasInit(flags) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            //get the HWND from ogre's renderwindow
 | 
			
		||||
            size_t windowHnd;
 | 
			
		||||
            mWindow->getCustomAttribute("WINDOW", &windowHnd);
 | 
			
		||||
 | 
			
		||||
            //kindly ask SDL not to trash our OGL context
 | 
			
		||||
            //might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
 | 
			
		||||
            SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
 | 
			
		||||
            if(SDL_Init(SDL_INIT_VIDEO) != 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            //wrap our own event handler around ogre's
 | 
			
		||||
            mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd);
 | 
			
		||||
 | 
			
		||||
            if(mSDLWindow == NULL)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            SDL_StartTextInput();
 | 
			
		||||
 | 
			
		||||
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
 | 
			
		||||
            //linux-specific event-handling fixups
 | 
			
		||||
            //see http://bugzilla.libsdl.org/show_bug.cgi?id=730
 | 
			
		||||
            SDL_SysWMinfo wm_info;
 | 
			
		||||
            SDL_VERSION(&wm_info.version);
 | 
			
		||||
 | 
			
		||||
            if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info))
 | 
			
		||||
            {
 | 
			
		||||
                Display* display = wm_info.info.x11.display;
 | 
			
		||||
                Window w = wm_info.info.x11.window;
 | 
			
		||||
 | 
			
		||||
                // Set the input hints so we get keyboard input
 | 
			
		||||
                XWMHints *wmhints = XAllocWMHints();
 | 
			
		||||
                if (wmhints) {
 | 
			
		||||
                    wmhints->input = True;
 | 
			
		||||
                    wmhints->flags = InputHint;
 | 
			
		||||
                    XSetWMHints(display, w, wmhints);
 | 
			
		||||
                    XFree(wmhints);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //make sure to subscribe to XLib's events
 | 
			
		||||
                XSelectInput(display, w,
 | 
			
		||||
                             (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
 | 
			
		||||
                             ExposureMask | ButtonPressMask | ButtonReleaseMask |
 | 
			
		||||
                             PointerMotionMask | KeyPressMask | KeyReleaseMask |
 | 
			
		||||
                             PropertyChangeMask | StructureNotifyMask |
 | 
			
		||||
                             KeymapStateMask));
 | 
			
		||||
 | 
			
		||||
                XFlush(display);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
            SDL_ShowCursor(SDL_FALSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::capture()
 | 
			
		||||
    {
 | 
			
		||||
        if(!_start())
 | 
			
		||||
            throw std::runtime_error(SDL_GetError());
 | 
			
		||||
 | 
			
		||||
        SDL_Event evt;
 | 
			
		||||
        while(SDL_PollEvent(&evt))
 | 
			
		||||
        {
 | 
			
		||||
            switch(evt.type)
 | 
			
		||||
            {
 | 
			
		||||
                case SDL_MOUSEMOTION:
 | 
			
		||||
                    //ignore this if it happened due to a warp
 | 
			
		||||
                    if(!_handleWarpMotion(evt.motion))
 | 
			
		||||
                    {
 | 
			
		||||
                        mMouseListener->mouseMoved(_packageMouseMotion(evt));
 | 
			
		||||
 | 
			
		||||
                        //try to keep the mouse inside the window
 | 
			
		||||
                        _wrapMousePointer(evt.motion);
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEWHEEL:
 | 
			
		||||
                    mMouseListener->mouseMoved(_packageMouseMotion(evt));
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEBUTTONDOWN:
 | 
			
		||||
                    mMouseListener->mousePressed(evt.button, evt.button.button);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_MOUSEBUTTONUP:
 | 
			
		||||
                    mMouseListener->mouseReleased(evt.button, evt.button.button);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case SDL_KEYDOWN:
 | 
			
		||||
                    _handleKeyPress(evt.key);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_KEYUP:
 | 
			
		||||
                    mKeyboardListener->keyReleased(evt.key);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case SDL_WINDOWEVENT_FOCUS_GAINED:
 | 
			
		||||
                    mWindowListener->windowFocusChange(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_FOCUS_LOST:
 | 
			
		||||
                    mWindowListener->windowFocusChange(false);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_EXPOSED:
 | 
			
		||||
                    mWindowListener->windowVisibilityChange(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                case SDL_WINDOWEVENT_HIDDEN:
 | 
			
		||||
                    mWindowListener->windowVisibilityChange(false);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                //SDL traps ^C signals, pass it to OGRE.
 | 
			
		||||
                case SDL_QUIT:
 | 
			
		||||
                    Ogre::Root::getSingleton().queueEndRendering();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputWrapper::isModifierHeld(int mod)
 | 
			
		||||
    {
 | 
			
		||||
        return SDL_GetModState() & mod;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::warpMouse(int x, int y)
 | 
			
		||||
    {
 | 
			
		||||
        SDL_WarpMouseInWindow(mSDLWindow, x, y);
 | 
			
		||||
        mWarpCompensate = true;
 | 
			
		||||
        mWarpX = x;
 | 
			
		||||
        mWarpY = y;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::setGrabPointer(bool grab)
 | 
			
		||||
    {
 | 
			
		||||
        SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE;
 | 
			
		||||
 | 
			
		||||
        mGrabPointer = grab;
 | 
			
		||||
        SDL_SetWindowGrab(mSDLWindow, sdlGrab);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::setMouseRelative(bool relative)
 | 
			
		||||
    {
 | 
			
		||||
        if(mMouseRelative == relative)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        mMouseRelative = relative;
 | 
			
		||||
 | 
			
		||||
        mWrapPointer = false;
 | 
			
		||||
 | 
			
		||||
        //eep, wrap the pointer manually if the input driver doesn't support
 | 
			
		||||
        //relative positioning natively
 | 
			
		||||
        if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1)
 | 
			
		||||
        {
 | 
			
		||||
            if(relative)
 | 
			
		||||
                mWrapPointer = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //now remove all mouse events using the old setting from the queue
 | 
			
		||||
        SDL_PumpEvents();
 | 
			
		||||
 | 
			
		||||
        SDL_Event dummy[20];
 | 
			
		||||
        SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        if(!mWarpCompensate)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        //this was a warp event, signal the caller to eat it.
 | 
			
		||||
        if(evt.x == mWarpX && evt.y == mWarpY)
 | 
			
		||||
        {
 | 
			
		||||
            mWarpCompensate = false;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
 | 
			
		||||
    {
 | 
			
		||||
        //don't wrap if we don't want relative movements, support relative
 | 
			
		||||
        //movements natively, or aren't grabbing anyways
 | 
			
		||||
        if(!mMouseRelative || !mWrapPointer || !mGrabPointer)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        int width = 0;
 | 
			
		||||
        int height = 0;
 | 
			
		||||
 | 
			
		||||
        SDL_GetWindowSize(mSDLWindow, &width, &height);
 | 
			
		||||
 | 
			
		||||
        const int FUDGE_FACTOR_X = width / 4;
 | 
			
		||||
        const int FUDGE_FACTOR_Y = height / 4;
 | 
			
		||||
 | 
			
		||||
        //warp the mouse if it's about to go outside the window
 | 
			
		||||
        if(evt.x - FUDGE_FACTOR_X < 0  || evt.x + FUDGE_FACTOR_X > width
 | 
			
		||||
                || evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height)
 | 
			
		||||
        {
 | 
			
		||||
            warpMouse(width / 2, height / 2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt)
 | 
			
		||||
    {
 | 
			
		||||
        //SDL keyboard events are followed by the actual text those keys would generate
 | 
			
		||||
        //to account for languages that require multiple keystrokes to produce a key.
 | 
			
		||||
        //Look for an event immediately following ours, assuming each key produces exactly
 | 
			
		||||
        //one character or none at all.
 | 
			
		||||
 | 
			
		||||
        //TODO: Check if this works properly for multibyte symbols
 | 
			
		||||
        //do we have to worry about endian-ness?
 | 
			
		||||
        //for that matter, check if we even need to do any of this.
 | 
			
		||||
 | 
			
		||||
        SDL_Event text_evts[1];
 | 
			
		||||
        if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            const char* symbol = text_evts[0].text.text;
 | 
			
		||||
 | 
			
		||||
            Uint32 num_bytes = strlen(symbol);
 | 
			
		||||
 | 
			
		||||
            //no valid character is more than 4 bytes
 | 
			
		||||
            if(num_bytes > 0 && num_bytes <= 4)
 | 
			
		||||
            {
 | 
			
		||||
                Uint32 u32_symbol = boost::locale::conv::utf_to_utf<Uint32>(symbol)[0];
 | 
			
		||||
 | 
			
		||||
                evt.keysym.unicode = u32_symbol;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mKeyboardListener->keyPressed(evt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt)
 | 
			
		||||
    {
 | 
			
		||||
        MouseMotionEvent pack_evt;
 | 
			
		||||
        pack_evt.x = mMouseX;
 | 
			
		||||
        pack_evt.xrel = 0;
 | 
			
		||||
        pack_evt.y = mMouseY;
 | 
			
		||||
        pack_evt.yrel = 0;
 | 
			
		||||
        pack_evt.z = mMouseZ;
 | 
			
		||||
        pack_evt.zrel = 0;
 | 
			
		||||
 | 
			
		||||
        if(evt.type == SDL_MOUSEMOTION)
 | 
			
		||||
        {
 | 
			
		||||
            pack_evt.x = mMouseX = evt.motion.x;
 | 
			
		||||
            pack_evt.y = mMouseY = evt.motion.y;
 | 
			
		||||
            pack_evt.xrel = evt.motion.xrel;
 | 
			
		||||
            pack_evt.yrel = evt.motion.yrel;
 | 
			
		||||
        }
 | 
			
		||||
        else if(evt.type == SDL_MOUSEWHEEL)
 | 
			
		||||
        {
 | 
			
		||||
            mMouseZ += pack_evt.zrel = evt.wheel.y;
 | 
			
		||||
            pack_evt.z = mMouseZ;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw new std::runtime_error("Tried to package non-motion event!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return pack_evt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code)
 | 
			
		||||
    {
 | 
			
		||||
        OIS::KeyCode kc = OIS::KC_UNASSIGNED;
 | 
			
		||||
 | 
			
		||||
        KeyMap::const_iterator ois_equiv = mKeyMap.find(code);
 | 
			
		||||
 | 
			
		||||
        if(ois_equiv != mKeyMap.end())
 | 
			
		||||
            kc = ois_equiv->second;
 | 
			
		||||
 | 
			
		||||
        return kc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InputWrapper::_setupOISKeys()
 | 
			
		||||
    {
 | 
			
		||||
        //lifted from OIS's SDLKeyboard.cpp
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_2, OIS::KC_2) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_3, OIS::KC_3) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_4, OIS::KC_4) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_5, OIS::KC_5) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_6, OIS::KC_6) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_7, OIS::KC_7) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_8, OIS::KC_8) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_9, OIS::KC_9) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_0, OIS::KC_0) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, OIS::KC_MINUS) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, OIS::KC_EQUALS) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, OIS::KC_BACK) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_TAB, OIS::KC_TAB) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_q, OIS::KC_Q) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_w, OIS::KC_W) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_e, OIS::KC_E) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_r, OIS::KC_R) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_t, OIS::KC_T) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_y, OIS::KC_Y) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_u, OIS::KC_U) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_i, OIS::KC_I) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_o, OIS::KC_O) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_p, OIS::KC_P) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, OIS::KC_RETURN) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LCONTROL));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_a, OIS::KC_A) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_s, OIS::KC_S) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_d, OIS::KC_D) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_f, OIS::KC_F) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_g, OIS::KC_G) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_h, OIS::KC_H) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_j, OIS::KC_J) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_k, OIS::KC_K) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_l, OIS::KC_L) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, OIS::KC_SEMICOLON) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_COLON, OIS::KC_COLON) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, OIS::KC_APOSTROPHE) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, OIS::KC_GRAVE)  );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, OIS::KC_LSHIFT) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, OIS::KC_BACKSLASH) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, OIS::KC_SLASH) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_z, OIS::KC_Z) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_x, OIS::KC_X) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_c, OIS::KC_C) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_v, OIS::KC_V) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_b, OIS::KC_B) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_n, OIS::KC_N) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_m, OIS::KC_M) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, OIS::KC_COMMA)  );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, OIS::KC_PERIOD));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, OIS::KC_RSHIFT));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, OIS::KC_MULTIPLY) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_LALT, OIS::KC_LMENU) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, OIS::KC_SPACE));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, OIS::KC_CAPITAL) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F1, OIS::KC_F1) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F2, OIS::KC_F2) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F3, OIS::KC_F3) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F4, OIS::KC_F4) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F5, OIS::KC_F5) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F6, OIS::KC_F6) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F7, OIS::KC_F7) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F8, OIS::KC_F8) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F9, OIS::KC_F9) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F10, OIS::KC_F10) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCKCLEAR, OIS::KC_NUMLOCK) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLLOCK, OIS::KC_SCROLL));
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_7, OIS::KC_NUMPAD7) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_8, OIS::KC_NUMPAD8) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_9, OIS::KC_NUMPAD9) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, OIS::KC_SUBTRACT) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_4, OIS::KC_NUMPAD4) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_5, OIS::KC_NUMPAD5) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_6, OIS::KC_NUMPAD6) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, OIS::KC_ADD) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_1, OIS::KC_NUMPAD1) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_2, OIS::KC_NUMPAD2) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_3, OIS::KC_NUMPAD3) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_0, OIS::KC_NUMPAD0) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, OIS::KC_DECIMAL) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F11, OIS::KC_F11) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F12, OIS::KC_F12) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F13, OIS::KC_F13) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F14, OIS::KC_F14) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_F15, OIS::KC_F15) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, OIS::KC_NUMPADEQUALS) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, OIS::KC_DIVIDE) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, OIS::KC_SYSRQ) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_RALT, OIS::KC_RMENU) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_HOME, OIS::KC_HOME) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_UP, OIS::KC_UP) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, OIS::KC_PGUP) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, OIS::KC_LEFT) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, OIS::KC_RIGHT) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_END, OIS::KC_END) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, OIS::KC_DOWN) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, OIS::KC_PGDOWN) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, OIS::KC_INSERT) );
 | 
			
		||||
        mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, OIS::KC_DELETE) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								extern/sdl4ogre/sdlinputwrapper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								extern/sdl4ogre/sdlinputwrapper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,67 @@
 | 
			
		|||
#ifndef _MWINPUT_SDLINPUTWRAPPER_H
 | 
			
		||||
#define _MWINPUT_SDLINPUTWRAPPER_H
 | 
			
		||||
 | 
			
		||||
#include "SDL2/SDL_events.h"
 | 
			
		||||
#include <OGRE/OgreRenderWindow.h>
 | 
			
		||||
#include <boost/unordered_map.hpp>
 | 
			
		||||
 | 
			
		||||
#include "OISCompat.h"
 | 
			
		||||
#include "events.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace SFO
 | 
			
		||||
{
 | 
			
		||||
    class InputWrapper
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        InputWrapper(Ogre::RenderWindow* window);
 | 
			
		||||
        ~InputWrapper();
 | 
			
		||||
 | 
			
		||||
        void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
 | 
			
		||||
        void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; }
 | 
			
		||||
        void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; }
 | 
			
		||||
 | 
			
		||||
        void capture();
 | 
			
		||||
        bool isModifierHeld(int mod);
 | 
			
		||||
 | 
			
		||||
        void setMouseRelative(bool relative);
 | 
			
		||||
        bool getMouseRelative() { return mMouseRelative; }
 | 
			
		||||
        void setGrabPointer(bool grab);
 | 
			
		||||
 | 
			
		||||
        OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code);
 | 
			
		||||
 | 
			
		||||
        void warpMouse(int x, int y);
 | 
			
		||||
    private:
 | 
			
		||||
        bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
 | 
			
		||||
        void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
 | 
			
		||||
 | 
			
		||||
        MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
 | 
			
		||||
        void _handleKeyPress(SDL_KeyboardEvent& evt);
 | 
			
		||||
 | 
			
		||||
        bool _start();
 | 
			
		||||
        void _setupOISKeys();
 | 
			
		||||
 | 
			
		||||
        SFO::MouseListener* mMouseListener;
 | 
			
		||||
        SFO::KeyListener* mKeyboardListener;
 | 
			
		||||
        SFO::WindowListener* mWindowListener;
 | 
			
		||||
 | 
			
		||||
        typedef boost::unordered::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
 | 
			
		||||
        KeyMap mKeyMap;
 | 
			
		||||
 | 
			
		||||
        Uint16 mWarpX;
 | 
			
		||||
        Uint16 mWarpY;
 | 
			
		||||
        bool mWarpCompensate;
 | 
			
		||||
        bool mMouseRelative;
 | 
			
		||||
        bool mWrapPointer;
 | 
			
		||||
        bool mGrabPointer;
 | 
			
		||||
 | 
			
		||||
        Sint32 mMouseZ;
 | 
			
		||||
        Sint32 mMouseX;
 | 
			
		||||
        Sint32 mMouseY;
 | 
			
		||||
 | 
			
		||||
        Ogre::RenderWindow* mWindow;
 | 
			
		||||
        SDL_Window* mSDLWindow;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
		Reference in a new issue