LWJGL/lwjgl — pull request #62 by momokan (2014-01-26 04:56:50+00:00)
Title: support multibytes input from Input method on Linux (Xlib)

Hi.

I am a big fan of LWJGL in japan.

Currently, LWJGL seems to not support input of multibytes long sentense.
I modified org.lwjgl.input.Keyboard to recieve long sentense from Input method on Linux(XIM).

Mainly modification is the following.

- To be able to specify any argument to Xlib's XSetLocaleModifiers().
It is fixed to "@im=none" so far,
but to use the Input method of local environment,
the argument must be empty string.
I enhanced org.lwjgl.input.Keyboard.setImLocaleModifiers(String)
and the argument is set to XSetLocaleModifiers().

- After XNextEvent() is called, XFilterEvent() must be called to filter all events.
When event occured window and LWJGL created window are not matched, XFilterEvent() has not been called.
But, Input method creates some other window for transformation of mutlibytes inputs (That window has the other window id.)
and events caused at the window also should be filtered by XFilterEvent().

Quoted from: ftp://ftp.x.org/pub/X11R7.0/doc/XIMTransport.txt,
> 1m4.1.	X Transport0m
>
> At the beginning of the X Transport connection for the XIM
> transport mechanism, two different windows must be created
> either in an Xlib XIM or in an IM Server, with which the
> Xlib and the IM Server exchange the XIM transports by using
> the ClientMessage events and Window Properties.	In the fol-
> lowing, the window created by the Xlib is referred as the
> "client communication window", and on the other hand, the
> window created by the IM Server is referred as the "IMS com-
> munication window".

In addition to the above,
when focus in/out events are caused, XSetICFocus()/XUnsetICFocus() must be called.
These functions notify that the receiver of Input method changed.

I modified it on org.lwjgl.opengl.LinuxDisplay.processEvents(),
org.lwjgl.opengl.LinuxEvent.filterEvent(long, LinuxKeyboard).

- I modified org.lwjgl.opengl.LinuxKeyboard.lookupStringUnicode(long, int[])
to translate lookuped string into multibyte characters.
Until now, lookupStringUnicode() make a multibytes character
to each single bytes on the multibytes character.
But, a multibytes character should be translated to single character.

I’m sorry that I couldn’t explain as English well.
Explain it in 2 lines,
Before: lookupStringUnicode() translates 'あ' into char[] {0x??, 0x??, 0x??}
After: lookupStringUnicode() translates 'あ' into char[] {'あ'}

- To be able to allocate large keyboard buffer for Input method.
When Input method sends long text, the text is stored to org.lwjgl.opengl.LinuxKeyboard.temp_translation_buffer at one time.
For Japanease long text (e.g. 20 characters, it was 60 bytes), current temp_translation_buffer may be small.
So to specify any buffer size to org.lwjgl.input.Keyboard.setImKeyboardBufferSize().

These modification are confirmed by this code.

String	text = "";
while (!Display.isCloseRequested()) {

// render OpenGL here

Display.update();

// fetch keyboard input.
while (Keyboard.next()) {
char	c = Keyboard.getEventCharacter();

if ((Keyboard.getEventKey() != Keyboard.KEY_RETURN) && (Character.isIdentifierIgnorable(c))) {
continue;
}

text = text + String.valueOf(c);
if (Keyboard.getEventKey() == Keyboard.KEY_RETURN) {
System.out.println("Input> " + text);
text = "";
}
}
}

If multibytes characters are inputed,
Keyboard.getEventCharacter() returns each　as multibytes characters.

Best regards,
momokan