Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » i think i solve the chinese input problem

This thread is locked; no one can reply to it. rss feed Print
i think i solve the chinese input problem
vkensou
Member #15,546
March 2014

i use allegro 5.1.8

change some code:

in file <d3d_disp.cpp>'s method d3d_display_thread_proc()
and file <wgl_disp.c>'s method display_thread_proc() add code:
"TranslateMessage(&msg);"

file <wwindow.c>'s method window_callback() add

case WM_IME_CHAR:
{
int vcode = wParam;
#ifndef _UNICODE
char mbstr[3];
wchar_t wstr[2];
unsigned char hiByte = wParam >> 8;
unsigned char loByte = wParam & 0x000000FF;
if (hiByte == 0)
{
mbstr[0] = loByte;
mbstr[1] = '\0';
}
else
{
mbstr[0] = hiByte;
mbstr[1] = loByte;
mbstr[2] = '\0';
}
//wchar_t wstr[2];
/*int num = */MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, mbstr, -1, wstr, _countof(wstr));
vcode = wstr[0];
#endif
_al_win_kbd_handle_imechar(vcode,win_display);

break;
}

file <wkeyboard.c> add method

void _al_win_kbd_handle_imechar(int code,ALLEGRO_DISPLAY_WIN *win_disp)
{
ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_disp;
ALLEGRO_EVENT event;

if (!_al_event_source_needs_to_generate_event(&the_keyboard.es))
return;

event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN;
event.keyboard.timestamp = al_get_time();
event.keyboard.display = display;
event.keyboard.keycode = 0;
event.keyboard.unichar = code;
event.keyboard.modifiers = 0;
event.keyboard.repeat = false;

_al_event_source_emit_event(&the_keyboard.es, &event);

event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR;
_al_event_source_emit_event(&the_keyboard.es, &event);

_al_event_source_unlock(&the_keyboard.es);

}

file <aintwin.h> add method's declare :

void _al_win_kbd_handle_imechar(int code,ALLEGRO_DISPLAY_WIN *win_disp);

now in the event ALLEGRO_EVENT_KEY_CHAR,event.keyboard.unichar have the char code.

Now we can input Chinese, and perhaps other IME input language can also.
;D

beoran
Member #12,636
March 2011

Not bad, but we'll have to port this to Linux, Android, OSX and iOS too, though...

Elias
Member #358
May 2000

Linux already should work.

--
"Either help out or stop whining" - Evert

SiegeLord
Member #7,827
October 2006
avatar

I think 'solve' is pretty strong here. In my testing this:

  • Generates an unpaired KEY_DOWN event

  • Breaks US International keyboard layout:

Log from ex_keyboard_events with this patch:

KEY_DOWN  code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_CHAR  code=069, char='"' (  34), modifiers=00000001, [KEY69]
KEY_CHAR  code=069, char='"' (  34), modifiers=00000001, [KEY69]
KEY_UP    code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_UP    code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=005, char=' ' (   0), modifiers=00000000, [E]
KEY_CHAR  code=005, char='e' ( 101), modifiers=00000000, [E]
KEY_UP    code=005, char=' ' (   0), modifiers=00000000, [E]

And without:

KEY_DOWN  code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_UP    code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_UP    code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=005, char=' ' (   0), modifiers=00000000, [E]
KEY_CHAR  code=005, char='ë' ( 235), modifiers=00000000, [E]
KEY_UP    code=005, char=' ' (   0), modifiers=00000000, [E]

  • Doesn't work with the Chinese IME I was using (the one built into Windows)

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

torhu
Member #2,727
September 2002
avatar

By the way, MSDN says this about WM_IME_CHAR: "For a Unicode window, this message is the same as WM_CHAR." One less thing to fix, then.

vkensou
Member #15,546
March 2014

to torhu

in my patch i have handled both ANICODE window and UNICODE window

to SiegeLord
i only add handle the WM_IME_CHAR message. if you do not use ime to input, it should be no effect.
and i do not have a us layout keyboard, so i cant test that.

this patch only effect windows, have no effect to other os.

Elias
Member #358
May 2000

The allegro window already is Unicode (in the version in git) so that's all we need.

And it definitely would be good to fix this, but I think SiegeLord ran into some issues when he tried.

--
"Either help out or stop whining" - Evert

SiegeLord
Member #7,827
October 2006
avatar

vkensou said:

if you do not use ime to input, it should be no effect.

The TranslateMessage call breaks some other input types.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

I guess at some point we will need TranslateMessage. Worst case it would have to be some platform specific configuration option with which to turn it on.

But for many applications having correct text input is rather crucial (but I have no idea what exactly breaks with it).

--
"Either help out or stop whining" - Evert

SiegeLord
Member #7,827
October 2006
avatar

The current code works fine for everything except IME. My patch in the other thread catches all characters in all input methods I tried, but sometimes generates bogus events. This patch breaks a whole bunch of input methods and doesn't work for the Chinese IME input I am using.

The difference between this patch and mine is that I also rewrite the rest of the unicode input, thus preserving the functionality of other input methods. Unfortunately, it generates bogus events which I don't think is acceptable.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

Hm, what kind of bogus events?

--
"Either help out or stop whining" - Evert

SiegeLord
Member #7,827
October 2006
avatar

E.g. entering the ë key (compare with above):

KEY_DOWN  code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_CHAR  code=069, char=' ' (   0), modifiers=00000001, [KEY69]
KEY_UP    code=069, char=' ' (   0), modifiers=00000000, [KEY69]
KEY_UP    code=215, char=' ' (   0), modifiers=00000000, [LSHIFT]
KEY_DOWN  code=005, char=' ' (   0), modifiers=00000000, [E]
KEY_CHAR  code=005, char='ë' ( 235), modifiers=00000000, [E]
KEY_UP    code=005, char=' ' (   0), modifiers=00000000, [E]

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

So the only problem is extra KEY_CHAR events?

--
"Either help out or stop whining" - Evert

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

So you're saying you shouldn't get a KEY_CHAR event for KEY69 when making that foreign e? How are you supposed to know in advance that they didn't want a KEY_CHAR with KEY69? That may illustrate my lack of knowledge, because I don't even know what key 69 is.

Elias
Member #358
May 2000

Supposedly, Windows sends two WM_CHAR messages, one with just a space (or does the ' ' just mean it was something not printable?) and one with ë.

--
"Either help out or stop whining" - Evert

Thomas Fjellstrom
Member #476
June 2000
avatar

The first one is probably saying "Hey, I'm getting a composed char here...". Getting a CHAR event with an unprintable char should just be ignored in most cases no? (Except for when you actually want to know when you're getting some kind of compose or IME event)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

SiegeLord
Member #7,827
October 2006
avatar

How are you supposed to know in advance that they didn't want a KEY_CHAR with KEY69?

That's the crux of the issue.

Windows sends only one WM_CHAR, the one with the ë character, which is re-sent as the second ALLEGRO_EVENT_CHAR. The first ALLEGRO_EVENT_CHAR is sent by my code, due to imperfect detection of when such events are to be sent.

The algorithm used by my patch is very simple:

1. If we get a WM_CHAR, we send the ALLEGRO_EVENT_CHAR event (unless its a surrogate, in which case we wait for a second WM_CHAR).
2. If we get a WM_KEYDOWN we check to see if there is a WM_CHAR after it (it will be put there by TranslateMessage), if not, we send an ALLEGRO_EVENT_CHAR event.

The second step is necessary for keys like the arrow keys which generate WM_KEYDOWN events but not WM_CHAR events, but generates bogus events as shown above. In principle we could detect KEY69 and not send an event for it... but I don't know, the whole thing is very fragile as is.

Elias said:

So the only problem is extra KEY_CHAR events?

I don't know if it's the only problem, but it is the problem that made me abandon the approach :P. It requires more testing and maybe there are even worse problems.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

I guess what we need to do is:

  1. Create an ALLEGRO_EVENT_CHAR if and only if there is a WM_CHAR

  2. Except, for some known special cases, like cursor keys, we create extra ALLEGRO_EVENT_CHAR

The first rule should ensure that there are no unexpected ALLEGRO_EVENT_CHAR. Only when Windows thinks there should be a unicode character added Allegro will do the same.

The second would be a somewhat unfortunate hack and not really necessary, but for backwards compatibility makes sense to have the ALLEGRO_EVENT_CHAR for some other control keys which do not produce unicode as that's just how Allegro works now.

--
"Either help out or stop whining" - Evert

SiegeLord
Member #7,827
October 2006
avatar

I guess it's a possibility (I recall considering the 'whitelisting' option instead of the current blacklist, but I don't remember my conclusion). It's certainly a pain to identify all these keys.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Elias
Member #358
May 2000

Yes, but it shouldn't be too many. Cursors, home, end, delete, backspace, escape, page up/down, return, tab. If we special case those and then have all the printable Unicode characters, that will be what is expected.

--
"Either help out or stop whining" - Evert

vkensou
Member #15,546
March 2014

i learn a lot from yours.

:)

Go to: