mirror of https://github.com/encounter/SDL.git
Fixed bug 1876 - SDL_TEXTINPUT only returns '?' (0x3F) in event.text.text with Khmer language input
Andreas The issue comes down to this line on MSDN: "TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII characters by the keyboard driver." "WM_KEYDOWN and WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message. WM_SYSKEYDOWN and WM_SYSKEYUP combinations produce a WM_SYSCHAR or WM_SYSDEADCHAR message." Except for WM_CHAR, none of these messages are used in SDL. Hence TranslateMessage should be dropped entirely and proper handling be included in the WM_KEYDOWN event. Currently TranslateMessage is called for every message even if it must not be called in certain cases (like "An application should not call TranslateMessage if the TranslateAccelerator function returns a nonzero value."). WM_CHAR message handling should remain for external processes posting these messages - additionally, WM_UNICHAR should be added. I made a patch for src/video/windows/SDL_windowsevents.c that seems to work fine. It doesn't solve the "missing" composition for Khmer, but at least input for languages that cannot be mapped to ASCII characters (and for which IME is not used) will now work on Windows.
This commit is contained in:
parent
bb2671b7e7
commit
b4b12d950e
src/video/windows
|
@ -256,6 +256,33 @@ WIN_CheckRawMouseButtons( ULONG rawButtons, SDL_WindowData *data )
|
|||
}
|
||||
}
|
||||
|
||||
static SDL_FORCE_INLINE BOOL
|
||||
WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
|
||||
{
|
||||
if (codepoint <= 0x7F) {
|
||||
text[0] = (char) codepoint;
|
||||
text[1] = '\0';
|
||||
} else if (codepoint <= 0x7FF) {
|
||||
text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
|
||||
text[1] = 0x80 | (char) (codepoint & 0x3F);
|
||||
text[2] = '\0';
|
||||
} else if (codepoint <= 0xFFFF) {
|
||||
text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
|
||||
text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
|
||||
text[2] = 0x80 | (char) (codepoint & 0x3F);
|
||||
text[3] = '\0';
|
||||
} else if (codepoint <= 0x10FFFF) {
|
||||
text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
|
||||
text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
|
||||
text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
|
||||
text[3] = 0x80 | (char) (codepoint & 0x3F);
|
||||
text[4] = '\0';
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -459,8 +486,23 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
#endif /* WM_MOUSELEAVE */
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
{
|
||||
BYTE keyboardState[256];
|
||||
char text[5];
|
||||
UINT32 utf32 = 0;
|
||||
|
||||
GetKeyboardState(keyboardState);
|
||||
if (ToUnicode(wParam, (lParam >> 16) & 0xff, keyboardState, (LPWSTR)&utf32, 1, 0) > 0) {
|
||||
WORD repitition;
|
||||
for (repitition = lParam & 0xffff; repitition > 0; repitition--) {
|
||||
WIN_ConvertUTF32toUTF8(utf32, text);
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
// no break
|
||||
case WM_SYSKEYDOWN:
|
||||
{
|
||||
SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
|
||||
if ( code != SDL_SCANCODE_UNKNOWN ) {
|
||||
|
@ -485,24 +527,19 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
returnCode = 0;
|
||||
break;
|
||||
|
||||
case WM_UNICHAR:
|
||||
{
|
||||
if (wParam == UNICODE_NOCHAR) {
|
||||
returnCode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// no break
|
||||
case WM_CHAR:
|
||||
{
|
||||
char text[4];
|
||||
char text[5];
|
||||
|
||||
/* Convert to UTF-8 and send it on... */
|
||||
if (wParam <= 0x7F) {
|
||||
text[0] = (char) wParam;
|
||||
text[1] = '\0';
|
||||
} else if (wParam <= 0x7FF) {
|
||||
text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F);
|
||||
text[1] = 0x80 | (char) (wParam & 0x3F);
|
||||
text[2] = '\0';
|
||||
} else {
|
||||
text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F);
|
||||
text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F);
|
||||
text[2] = 0x80 | (char) (wParam & 0x3F);
|
||||
text[3] = '\0';
|
||||
}
|
||||
WIN_ConvertUTF32toUTF8(wParam, text);
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
returnCode = 0;
|
||||
|
@ -772,7 +809,6 @@ WIN_PumpEvents(_THIS)
|
|||
const Uint8 *keystate;
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue