Skip to content

Commit

Permalink
Implemented ToUnicode() support on Windows 95/98/ME/NT/2000/XP
Browse files Browse the repository at this point in the history
This is a collaborative effort between Alex Volkov and John Popplewell.
Thanks guys!  (Fixes bug #39)
  • Loading branch information
slouken committed Jan 19, 2006
1 parent 99f8fc7 commit 9d7817f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 11 deletions.
5 changes: 5 additions & 0 deletions src/video/wincommon/SDL_lowvideo.h
Expand Up @@ -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 */
54 changes: 54 additions & 0 deletions src/video/wincommon/SDL_sysevents.c
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
}

12 changes: 7 additions & 5 deletions src/video/windib/SDL_dibevents.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
}
Expand Down
1 change: 1 addition & 0 deletions src/video/windib/SDL_vkeys.h
Expand Up @@ -77,3 +77,4 @@ static char rcsid =
#define VK_RBRACKET 0xDD
#define VK_APOSTROPHE 0xDE
#define VK_BACKTICK 0xDF
#define VK_OEM_102 0xE2
13 changes: 7 additions & 6 deletions src/video/windx5/SDL_dx5events.c
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions test/checkkeys.c
Expand Up @@ -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
}
}
Expand Down

0 comments on commit 9d7817f

Please sign in to comment.