Commit e63977fb authored by Sam Lantinga's avatar Sam Lantinga

Implemented ToUnicode() support on Windows 95/98/ME/NT/2000/XP

This is a collaborative effort between Alex Volkov and John Popplewell.
Thanks guys!  (Fixes bug #39)

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401256
parent d32b3a37
......@@ -109,4 +109,9 @@ extern void DX5_SoundFocus(HWND window);
GDL_CreateWindow as well */
LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
typedef int (WINAPI *ToUnicodeFN)(UINT, UINT, PBYTE, LPWSTR, int, UINT);
extern ToUnicodeFN SDL_ToUnicode;
#endif /* SDL_lowvideo_h */
......@@ -79,6 +79,15 @@ void (*WIN_PaletteChanged)(_THIS, HWND window);
void (*WIN_WinPAINT)(_THIS, HDC hdc);
extern void DIB_SwapGamma(_THIS);
/* Variables and support functions for SDL_ToUnicode() */
static int codepage;
static int Is9xME();
static int GetCodePage();
static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, BYTE *keystate, Uint16 *wchars, int wsize, UINT flags);
ToUnicodeFN SDL_ToUnicode = ToUnicode9xME;
#if defined(_WIN32_WCE)
// dynamically load aygshell dll because we want SDL to work on HPC and be300
......@@ -622,6 +631,11 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
return(0);
case WM_INPUTLANGCHANGE: {
codepage = GetCodePage();
}
return(TRUE);
default: {
/* Special handling by the video driver */
if (HandleMessage) {
......@@ -728,6 +742,10 @@ int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
/* Check for SDL_WINDOWID hack */
SDL_windowid = getenv("SDL_WINDOWID");
/* Initialise variables for SDL_ToUnicode() */
codepage = GetCodePage();
SDL_ToUnicode = Is9xME() ? ToUnicode9xME : ToUnicode;
app_registered = 1;
return(0);
}
......@@ -751,3 +769,39 @@ void SDL_UnregisterApp()
app_registered = 0;
}
/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */
static int Is9xME()
{
OSVERSIONINFO info;
memset(&info, 0, sizeof(info));
info.dwOSVersionInfoSize = sizeof(info);
if (!GetVersionEx(&info)) {
return 0;
}
return (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
}
static int GetCodePage()
{
char buff[8];
int lcid = MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT);
int cp = GetACP();
if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof(buff))) {
cp = atoi(buff);
}
return cp;
}
static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, PBYTE keystate, LPWSTR wchars, int wsize, UINT flags)
{
BYTE chars[2];
if (ToAsciiEx(vkey, scancode, keystate, (WORD*)chars, 0, GetKeyboardLayout(0)) == 1) {
return MultiByteToWideChar(codepage, 0, chars, 1, wchars, wsize);
}
return 0;
}
......@@ -281,6 +281,7 @@ void DIB_InitOSKeymap(_THIS)
VK_keymap[VK_EQUALS] = SDLK_EQUALS;
VK_keymap[VK_LBRACKET] = SDLK_LEFTBRACKET;
VK_keymap[VK_BACKSLASH] = SDLK_BACKSLASH;
VK_keymap[VK_OEM_102] = SDLK_LESS;
VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET;
VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE;
VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE;
......@@ -385,17 +386,18 @@ static SDL_keysym *TranslateKey(UINT vkey, UINT scancode, SDL_keysym *keysym, in
keysym->sym = VK_keymap[vkey];
keysym->mod = KMOD_NONE;
keysym->unicode = 0;
if ( pressed && SDL_TranslateUNICODE ) { /* Someday use ToUnicode() */
if ( pressed && SDL_TranslateUNICODE ) {
#ifdef NO_GETKEYBOARDSTATE
/* Uh oh, better hope the vkey is close enough.. */
keysym->unicode = vkey;
#else
BYTE keystate[256];
BYTE chars[2];
BYTE keystate[256];
Uint16 wchars[2];
GetKeyboardState(keystate);
if ( ToAscii(vkey,scancode,keystate,(WORD *)chars,0) == 1 ) {
keysym->unicode = chars[0];
if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
{
keysym->unicode = wchars[0];
}
#endif /* NO_GETKEYBOARDSTATE */
}
......
......@@ -77,3 +77,4 @@ static char rcsid =
#define VK_RBRACKET 0xDD
#define VK_APOSTROPHE 0xDE
#define VK_BACKTICK 0xDF
#define VK_OEM_102 0xE2
......@@ -824,11 +824,11 @@ static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
keysym->sym = DIK_keymap[scancode];
keysym->mod = KMOD_NONE;
keysym->unicode = 0;
if ( pressed && SDL_TranslateUNICODE ) { /* Someday use ToUnicode() */
if ( pressed && SDL_TranslateUNICODE ) {
UINT vkey;
#ifndef NO_GETKEYBOARDSTATE
BYTE keystate[256];
BYTE chars[2];
BYTE keystate[256];
Uint16 wchars[2];
#endif
vkey = MapVirtualKey(scancode, 1);
......@@ -837,10 +837,11 @@ static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed)
keysym->unicode = vkey;
#else
GetKeyboardState(keystate);
if ( ToAscii(vkey,scancode,keystate,(WORD *)chars,0) == 1 ) {
keysym->unicode = chars[0];
if (SDL_ToUnicode(vkey, scancode, keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) == 1)
{
keysym->unicode = wchars[0];
}
#endif
#endif /* NO_GETKEYBOARDSTATE */
}
return(keysym);
}
......
......@@ -73,6 +73,8 @@ static void PrintKey(SDL_keysym *sym, int pressed)
/* This is a Latin-1 program, so only show 8-bits */
if ( !(sym->unicode & 0xFF00) )
printf(" (%c)", sym->unicode);
else
printf(" (0x%X)", sym->unicode);
#endif
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment