forked from Mirrorlandia_minetest/irrlicht
Add support for IMEs on Linux
This commit is contained in:
parent
32004b9c5f
commit
3ef5902815
@ -13,6 +13,7 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include "IEventReceiver.h"
|
#include "IEventReceiver.h"
|
||||||
#include "ISceneManager.h"
|
#include "ISceneManager.h"
|
||||||
|
#include "IGUIElement.h"
|
||||||
#include "IGUIEnvironment.h"
|
#include "IGUIEnvironment.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "CTimer.h"
|
#include "CTimer.h"
|
||||||
@ -705,6 +706,14 @@ bool CIrrDeviceLinux::createInputContext()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load XMODIFIERS (e.g. for IMEs)
|
||||||
|
if (!XSetLocaleModifiers(""))
|
||||||
|
{
|
||||||
|
setlocale(LC_CTYPE, oldLocale.c_str());
|
||||||
|
os::Printer::log("XSetLocaleModifiers failed. Falling back to non-i18n input.", ELL_WARNING);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
XInputMethod = XOpenIM(XDisplay, NULL, NULL, NULL);
|
XInputMethod = XOpenIM(XDisplay, NULL, NULL, NULL);
|
||||||
if ( !XInputMethod )
|
if ( !XInputMethod )
|
||||||
{
|
{
|
||||||
@ -820,7 +829,7 @@ bool CIrrDeviceLinux::run()
|
|||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
XNextEvent(XDisplay, &event);
|
XNextEvent(XDisplay, &event);
|
||||||
if (XFilterEvent(&event, XWindow))
|
if (acceptsIME() && XFilterEvent(&event, None))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
@ -998,19 +1007,30 @@ bool CIrrDeviceLinux::run()
|
|||||||
SKeyMap mp;
|
SKeyMap mp;
|
||||||
if ( XInputContext )
|
if ( XInputContext )
|
||||||
{
|
{
|
||||||
wchar_t buf[8]={0};
|
wchar_t buf[64]={0};
|
||||||
Status status;
|
Status status;
|
||||||
int strLen = XwcLookupString(XInputContext, &event.xkey, buf, sizeof(buf), &mp.X11Key, &status);
|
int strLen = XwcLookupString(XInputContext, &event.xkey, buf, sizeof(buf)/sizeof(wchar_t)-1, &mp.X11Key, &status);
|
||||||
if ( status == XBufferOverflow )
|
if ( status == XBufferOverflow )
|
||||||
{
|
{
|
||||||
os::Printer::log("XwcLookupString needs a larger buffer", ELL_INFORMATION);
|
os::Printer::log("XwcLookupString needs a larger buffer", ELL_INFORMATION);
|
||||||
}
|
}
|
||||||
if ( strLen > 0 && (status == XLookupChars || status == XLookupBoth) )
|
if ( strLen > 0 && (status == XLookupChars || status == XLookupBoth) )
|
||||||
{
|
{
|
||||||
if ( strLen > 1 )
|
if (strLen > 1)
|
||||||
os::Printer::log("Additional returned characters dropped", ELL_INFORMATION);
|
{
|
||||||
|
// Multiple characters: send string event
|
||||||
|
irrevent.EventType = irr::EET_STRING_INPUT_EVENT;
|
||||||
|
irrevent.StringInput.Str = new core::stringw(buf);
|
||||||
|
postEventFromUser(irrevent);
|
||||||
|
delete irrevent.StringInput.Str;
|
||||||
|
irrevent.StringInput.Str = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
irrevent.KeyInput.Char = buf[0];
|
irrevent.KeyInput.Char = buf[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if 0 // Most of those are fine - but useful to have the info when debugging Irrlicht itself.
|
#if 0 // Most of those are fine - but useful to have the info when debugging Irrlicht itself.
|
||||||
@ -1044,7 +1064,6 @@ bool CIrrDeviceLinux::run()
|
|||||||
irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0;
|
irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0;
|
||||||
irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0;
|
irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0;
|
||||||
irrevent.KeyInput.Key = getKeyCode(event);
|
irrevent.KeyInput.Key = getKeyCode(event);
|
||||||
|
|
||||||
postEventFromUser(irrevent);
|
postEventFromUser(irrevent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1138,6 +1157,22 @@ bool CIrrDeviceLinux::run()
|
|||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
} // end while
|
} // end while
|
||||||
|
|
||||||
|
// Update IME information
|
||||||
|
if (GUIEnvironment)
|
||||||
|
{
|
||||||
|
gui::IGUIElement *elem = GUIEnvironment->getFocus();
|
||||||
|
if (elem && elem->acceptsIME())
|
||||||
|
{
|
||||||
|
core::rect<s32> r = elem->getAbsolutePosition();
|
||||||
|
XPoint p;
|
||||||
|
p.x = (short)r.UpperLeftCorner.X;
|
||||||
|
p.y = (short)r.LowerRightCorner.Y;
|
||||||
|
XVaNestedList l = XVaCreateNestedList(0, XNSpotLocation, &p, NULL);
|
||||||
|
XSetICValues(XInputContext, XNPreeditAttributes, l, NULL);
|
||||||
|
XFree(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif //_IRR_COMPILE_WITH_X11_
|
#endif //_IRR_COMPILE_WITH_X11_
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user