Hi,
after reading some stuff about xlib and XKBLib, I finally find a way to input my thai.
Here is what I have done but I think it’s ugly and he needs to be rewritten carefully, it may be a help to input other languages similar to thai.
The first thing I have done is in juce_linux_Windowing.cpp :
- in handleWindowMessage, for the case KeyPress,
I replace
KeySym sym = XKeycodeToKeysym (display, keyEvent->keycode, index);
by
char asci[64]; // Must not be above 64.
KeySym sym;
XLookupString(keyEvent, asci, sizeof(asci), &sym, 0);
(Found this in yudit source code)
(XLookupString seems to be powerful and take care of group(language map: french and thai in my case) and level (shift, ctl, …))
if sym represent a thai caractere his value range vary from
XK_Thai_kokai 0x0da1 to XK_Thai_lekkao 0x0df9
asci is a 3 bytes array if printed with printf from a utf-8 console it will display my thai caracter.
The problem I had is that i couldn’t give sym to handlePressKey because of the function
insertTextAtCursor (String::keyCodeToString (key.getKeyCode()));
here keyCodeToString expect a keyCode that is coded only in one byte.
The problem is that I didn’t know how to convert the sym into the asci array. If I knew I had rewritten this function.
So I realised that if I pass asci to the function
insertTextAtCursor (); in TextEditor, it will display my charactere well.
Now the ugly thing happens :
- I modified the Class KeyPress to have a string member.
(First I wanted to create a class KeyPressExt with inheritance from KeyPress it didn’t work)
- So I had function like getStr, setStr and a couple of constructor that take a String as a parameter.
So in the file juce_linux_Windowing following the above addition I added
String str = String(asci);
KeyPress kpe = KeyPress((int) sym, 0, str);
Then I added a test to call handleKeyPressExt only of my charactere typed is thai
if( (sym >= XK_Thai_kokai) && (sym <= XK_Thai_lekkao) ){
keyPressed = false; //make sure the other things don’t happen
printf(“sym is a thai char!\n”); // This for debug.
// Use our own KeyPress handling
handleKeyPressExt(kpe);
}
Then I also added the function handleKeyPressExt which is as following :
void handleKeyPressExt (const KeyPress keyPress){
updateCurrentModifiers();
if (Component::currentlyFocusedComponent->isValidComponent())
Component::currentlyFocusedComponent->keyPressed(keyPress);
else
component->keyPressed(keyPress);
}
The aim of that function was to skip the call to internalPressKey since I had already created my KeyPress object.
Then in TextEditor I added to the function keyPressed :
if (! isReadOnly())
if ( (key.getKeyCode() >= XK_Thai_kokai)
&& (key.getKeyCode() <= XK_Thai_lekkao))
insertTextAtCursor (key.getStr());
else{
insertTextAtCursor (String::keyCodeToString (key.getKeyCode()));
}
lastTransactionTime = Time::getApproximateMillisecondCounter();
I did that to be careful, but i think I just could call getStr whatever is the keyCode.
To conclude what should be done :
- use XLookupString instead of XKeyCodeToKeysym
- Modify the keyCodeToString Function to handle value of keycode above 255.
- I think this would make it works for many languages similar to thai (thai, lao, indic, khmer, …)
To go further maybe we should use XIM method to really get a multilanguage capable library.