nanshiki / SDL-IM-plus

SDL-IM (IME対応)
GNU Lesser General Public License v2.1
6 stars 1 forks source link

How to use SDL-IM related interfaces #2

Closed Clinale closed 1 month ago

Clinale commented 2 months ago

I am developing a game based on SDL1.15 and want to support Chinese input in the game. After searching for information, I found that SDL-IM-PLUS supports international input methods. May I ask how to add monitoring input method events in SDL_PollEvent(), and how to obtain the player's Chinese Unicode input?

Do you have any relevant documents or examples to help me understand how to use SDL-IM-PLUS? Thank you.

nanshiki commented 2 months ago

Please refer to the DOSVAXJ3 source. GFX_Events() in src/gui/sdlmain.cpp calls SDL_PollEvent() to process the obtained event message. On Windows or Mac, if event.key.keysym.scancode and event.key.keysym.sym are both 0 with SDL_KEYDOWN, the confirmed string can be obtained with SDL_FlushIMString(). On Windows, if you call SDL_EnableUNICODE(1) beforehand, the character code of the obtained string will be Unicode (UTF-16), but on macOS the character code will be fixed to ShiftJIS. On Linux, SDL_KEYDOWN will put Unicode (UTF-16) in event.key.keysym.unicode and you can get one character at a time. Because it was created for DOSVAXJ3, the behavior varies depending on the OS as shown above.

Clinale commented 2 months ago

Thank you for your reply. I followed your guidance and added SDL_SetIMValues (SDL_IM_ENABLE, 1, NULL) and SDL_SetIMValues (SDL_IM_ONOFF, 1, NULL) after SDL_Init, and then processed the input in the SDL_KEYDOWN event. However, I found that when SDL_IM_ENABLE is enabled, the entire input method interface becomes very laggy, and even reports the error X Error of failed request: BadLength (poly request too large or internal Xlib length error), and SDL_FlushIMString (NULL) returns a string length of 0. Do you know how to solve this problem? Thank you very much. image

nanshiki commented 1 month ago

Are you using Linux? As mentioned above, in Linux, you cannot obtain the string or its length with SDL_FlushIMString(). Once the string is confirmed with IME, each character is sent one by one character event.key.keysym.unicode with SDL_KEYDOWN. We will be fixing this so that SDL_FlushIMString() can be used on Linux in the same way as on Windows and macOS, so please wait a little while.

Clinale commented 1 month ago

I did test it on Linux. Thank you for your answer. In addition. Do I still need to use SDL_SetIMValues (SDL_IM_ENEABLE, 1, NULL) and SDL_SetIMValues (SDL_IM_ONOFF, 1, NULL) to enable IME?. When I enable SDL_IM-ENABLE and SDL_IM-ONOFF in the code, the program does not display the input text in a timely manner when typing on the keyboard, and when typing continuously, the program crashes and exits with the error X Error of failed request: BadLength (poly request too large or internal Xlib length error).

Even if I don't turn on SDL_IM_ENEABLE and SDL_IM_ONOFF, I have found that the program can accept keyboard input and print out the input Chinese characters with Unicode. So, is it not necessary to explicitly turn on SDL_IM_ENEABLE and SDL_IM_ONOFF now?

Another question, I would like to ask how to switch input methods in the program. SDL-IM supports direct input method switching through relevant interfaces?

Thank you very much.

nanshiki commented 1 month ago

To enable IME, you should only need SDL_SetIMValues ​​(SDL_IM_ENEABLE, 1, NULL). SDL_SetIMValues ​​(SDL_IM_ONOFF, 1, NULL) turns IME on, but if you prefer to turn it on and off manually, this is not necessary. In a Japanese environment, you cannot input kanji characters unless you execute SDL_IM_ENABLE. In Japanese, the image shown in the image appears while typing, and you can select and confirm. jpnime I have not encountered any errors in my environment. The error is BadLength (poly request too large or internal Xlib length error), but from what I can see from searching, this error seems to occur in relation to emojis. If you're using Ubuntu, what happens if you execute ”sudo apt install unifont”?

Clinale commented 1 month ago

I have found the solution, the problem lies in the position of SDL_SetIMValues (SDL_IMENEABLE, 1, NULL).

I previously placed SDL_IM_ENABLE after SDL_Init, and this causes IME to not be enabled properly. I tried putting SDL_SetIMValues before SDL_Init, and everything was fine. The program can receive keyboard input normally and can switch input method.

Thank you very much for your patient answer.

nanshiki commented 1 month ago

I'm glad that it worked.

The Linux version has been fixed so that the final string is obtained with SDL_GetFlushString(). This was fixed to make it work the same as the Windows and macOS versions. If you want to obtain the composition string using the current event.key.keysym.unicode, execute SDL_SetIMValue(SDL_IM_MESSAGE_UNICODE,1, NULL);.