mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 13:49:40 +00:00
Better handle SDL_TEXTINPUT events
This commit is contained in:
parent
03682184c6
commit
b16c92c2f5
6 changed files with 77 additions and 76 deletions
|
@ -10,6 +10,7 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/inputmanager.hpp"
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
|
@ -126,7 +127,7 @@ namespace MWGui
|
|||
|
||||
// always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before
|
||||
// (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow)
|
||||
//MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
MWBase::Environment::get().getInputManager()->update(0, true);
|
||||
|
||||
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));
|
||||
|
||||
|
|
|
@ -23,6 +23,65 @@
|
|||
|
||||
using namespace ICS;
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<unsigned long> utf8ToUnicode(const std::string& utf8)
|
||||
{
|
||||
std::vector<unsigned long> unicode;
|
||||
size_t i = 0;
|
||||
while (i < utf8.size())
|
||||
{
|
||||
unsigned long uni;
|
||||
size_t todo;
|
||||
unsigned char ch = utf8[i++];
|
||||
if (ch <= 0x7F)
|
||||
{
|
||||
uni = ch;
|
||||
todo = 0;
|
||||
}
|
||||
else if (ch <= 0xBF)
|
||||
{
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
}
|
||||
else if (ch <= 0xDF)
|
||||
{
|
||||
uni = ch&0x1F;
|
||||
todo = 1;
|
||||
}
|
||||
else if (ch <= 0xEF)
|
||||
{
|
||||
uni = ch&0x0F;
|
||||
todo = 2;
|
||||
}
|
||||
else if (ch <= 0xF7)
|
||||
{
|
||||
uni = ch&0x07;
|
||||
todo = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
}
|
||||
for (size_t j = 0; j < todo; ++j)
|
||||
{
|
||||
if (i == utf8.size())
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
unsigned char ch = utf8[i++];
|
||||
if (ch < 0x80 || ch > 0xBF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
uni <<= 6;
|
||||
uni += ch & 0x3F;
|
||||
}
|
||||
if (uni >= 0xD800 && uni <= 0xDFFF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
if (uni > 0x10FFFF)
|
||||
throw std::logic_error("not a UTF-8 string");
|
||||
unicode.push_back(uni);
|
||||
}
|
||||
return unicode;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWInput
|
||||
{
|
||||
InputManager::InputManager(OEngine::Render::OgreRenderer &ogre,
|
||||
|
@ -422,11 +481,19 @@ namespace MWInput
|
|||
|
||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||
|
||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text);
|
||||
|
||||
if (kc != OIS::KC_UNASSIGNED)
|
||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
||||
{
|
||||
const char* text = &arg.text[0];
|
||||
std::vector<unsigned long> unicode = utf8ToUnicode(std::string(text));
|
||||
for (std::vector<unsigned long>::iterator it = unicode.begin(); it != unicode.end(); ++it)
|
||||
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
|
||||
}
|
||||
|
||||
bool InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
||||
{
|
||||
mInputBinder->keyReleased (arg);
|
||||
|
|
|
@ -88,6 +88,7 @@ namespace MWInput
|
|||
public:
|
||||
virtual bool keyPressed(const SDL_KeyboardEvent &arg );
|
||||
virtual bool keyReleased( const SDL_KeyboardEvent &arg );
|
||||
virtual void textInput (const SDL_TextInputEvent &arg);
|
||||
|
||||
virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
|
||||
|
|
1
extern/sdl4ogre/events.h
vendored
1
extern/sdl4ogre/events.h
vendored
|
@ -35,6 +35,7 @@ class KeyListener
|
|||
{
|
||||
public:
|
||||
virtual ~KeyListener() {}
|
||||
virtual void textInput (const SDL_TextInputEvent& arg) {}
|
||||
virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0;
|
||||
virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0;
|
||||
};
|
||||
|
|
75
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
75
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
|
@ -67,12 +67,15 @@ namespace SFO
|
|||
break;
|
||||
case SDL_KEYDOWN:
|
||||
if (!evt.key.repeat)
|
||||
_handleKeyPress(evt.key);
|
||||
mKeyboardListener->keyPressed(evt.key);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
if (!evt.key.repeat)
|
||||
mKeyboardListener->keyReleased(evt.key);
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
mKeyboardListener->textInput(evt.text);
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
handleWindowEvent(evt);
|
||||
break;
|
||||
|
@ -220,74 +223,6 @@ namespace SFO
|
|||
return pack_evt;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(strlen(text_evts[0].text.text) != 0)
|
||||
{
|
||||
const unsigned char* symbol = reinterpret_cast<unsigned char*>(&(text_evts[0].text.text[0]));
|
||||
evt.keysym.unicode = _UTF8ToUTF32(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
mKeyboardListener->keyPressed(evt);
|
||||
}
|
||||
|
||||
//Lifted from OIS' LinuxKeyboard.cpp
|
||||
Uint32 InputWrapper::_UTF8ToUTF32(const unsigned char *buf)
|
||||
{
|
||||
unsigned char FirstChar = buf[0];
|
||||
|
||||
//it's an ascii char, bail out early.
|
||||
if(FirstChar < 128)
|
||||
return FirstChar;
|
||||
|
||||
Uint32 val = 0;
|
||||
Sint32 len = 0;
|
||||
|
||||
if((FirstChar & 0xE0) == 0xC0) //2 Chars
|
||||
{
|
||||
len = 2;
|
||||
val = FirstChar & 0x1F;
|
||||
}
|
||||
else if((FirstChar & 0xF0) == 0xE0) //3 Chars
|
||||
{
|
||||
len = 3;
|
||||
val = FirstChar & 0x0F;
|
||||
}
|
||||
else if((FirstChar & 0xF8) == 0xF0) //4 Chars
|
||||
{
|
||||
len = 4;
|
||||
val = FirstChar & 0x07;
|
||||
}
|
||||
else if((FirstChar & 0xFC) == 0xF8) //5 Chars
|
||||
{
|
||||
len = 5;
|
||||
val = FirstChar & 0x03;
|
||||
}
|
||||
else // if((FirstChar & 0xFE) == 0xFC) //6 Chars
|
||||
{
|
||||
len = 6;
|
||||
val = FirstChar & 0x01;
|
||||
}
|
||||
|
||||
for(int i = 1; i < len; i++)
|
||||
val = (val << 6) | (buf[i] & 0x3F);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code)
|
||||
{
|
||||
OIS::KeyCode kc = OIS::KC_UNASSIGNED;
|
||||
|
@ -296,8 +231,6 @@ namespace SFO
|
|||
|
||||
if(ois_equiv != mKeyMap.end())
|
||||
kc = ois_equiv->second;
|
||||
else
|
||||
std::cerr << "Couldn't find OIS key for " << code << std::endl;
|
||||
|
||||
return kc;
|
||||
}
|
||||
|
|
2
extern/sdl4ogre/sdlinputwrapper.hpp
vendored
2
extern/sdl4ogre/sdlinputwrapper.hpp
vendored
|
@ -42,8 +42,6 @@ namespace SFO
|
|||
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
|
||||
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
|
||||
|
||||
void _handleKeyPress(SDL_KeyboardEvent& evt);
|
||||
Uint32 _UTF8ToUTF32(const unsigned char *buf);
|
||||
void _setupOISKeys();
|
||||
|
||||
SFO::MouseListener* mMouseListener;
|
||||
|
|
Loading…
Reference in a new issue