I thought I already submitted this but it looks like I didn't.
This patch adds support for Chinese, Japanese, and Korean input
on all versions of Windows.
Unicode IME support is still coming. This means you can't input
Japanese correctly on a native Chinese machine for instance.
Andrew Dunbar.
--
http://linguaphile.sourceforge.net
Index: src/af/ev/win/ev_Win32Keyboard.cpp
===================================================================
RCS file: /cvsroot/abi/src/af/ev/win/ev_Win32Keyboard.cpp,v
retrieving revision 1.23
diff -u -r1.23 ev_Win32Keyboard.cpp
--- src/af/ev/win/ev_Win32Keyboard.cpp 2001/02/06 22:53:54 1.23
+++ src/af/ev/win/ev_Win32Keyboard.cpp 2001/05/26 05:54:38
@@ -168,6 +168,7 @@
{
m_hKeyboardLayout = 0;
m_iconv = (UT_iconv_t)-1;
+ m_bIsUnicodeInput = false;
remapKeyboard(GetKeyboardLayout(0));
}
@@ -179,7 +180,7 @@
void ev_Win32Keyboard::remapKeyboard(HKL hKeyboardLayout)
{
- char szCodePage[10];
+ char szCodePage[16];
if( m_iconv != (UT_iconv_t)-1 )
{
@@ -191,6 +192,19 @@
strcpy( szCodePage, "CP" );
if( GetLocaleInfo( LOWORD( hKeyboardLayout ),
LOCALE_IDEFAULTANSICODEPAGE, &szCodePage[2], sizeof( szCodePage ) / sizeof(
szCodePage[0] ) - 2 ) )
{
+ // Unicode locale?
+ // TODO Would UCS-2-LE / UCS-2-BE be preferable?
+ // TODO Does NT use UCS-2-BE internally on non-Intel CPUs?
+ if( !strcmp( szCodePage, "CP0" ) )
+ {
+ m_bIsUnicodeInput = true;
+ strcpy( szCodePage, "UCS-2-INTERNAL" );
+ }
+ else
+ m_bIsUnicodeInput = false;
+
+ UT_DEBUGMSG(("New keyboard codepage: %s\n",szCodePage));
+
m_iconv = UT_iconv_open( "UCS-2-INTERNAL", szCodePage );
}
@@ -371,13 +385,14 @@
// an unnamed-virtual-key -- a character key possibly with some sugar on it.
BYTE keyState[256];
- BYTE buffer[2];
+ WCHAR buffer[2] = {0,0};
int count;
unsigned int scancode = (keyData & 0x00ff0000)>>16;
GetKeyboardState(keyState);
- count = ToAsciiEx(nVirtKey,scancode,keyState,(WORD
*)buffer,0,m_hKeyboardLayout);
+ count = _scanCodeToChars(nVirtKey,scancode,keyState,buffer,sizeof(buffer));
+
if (count == -1)
{
// a possible dead-char -- ignore it and wait for possible completed
sequence.
@@ -405,7 +420,7 @@
keyState[VK_RCONTROL] &= ~0x80;
keyState[VK_RMENU] &= ~0x80;
- count = ToAsciiEx(nVirtKey,scancode,keyState,(WORD
*)buffer,0,m_hKeyboardLayout);
+ count =
+_scanCodeToChars(nVirtKey,scancode,keyState,buffer,sizeof(buffer));
if (count == 1)
{
@@ -477,7 +492,7 @@
keyState[VK_RCONTROL] &= ~0x80;
keyState[VK_RMENU] &= ~0x80;
- count = ToAsciiEx(nVirtKey,scancode,keyState,(WORD
*)buffer,0,m_hKeyboardLayout);
+ count =
+_scanCodeToChars(nVirtKey,scancode,keyState,buffer,sizeof(buffer));
if (count == 1)
{
@@ -499,9 +514,22 @@
}
}
+bool ev_Win32Keyboard::onIMEChar(AV_View * pView,
+ HWND hWnd,
+UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+ WCHAR b = wParam;
+
+ // 2nd byte of MBCS is in high byte of word
+ if (wParam & 0xff00)
+ b = ((BYTE)(wParam >> 8)) | ((BYTE)wParam << 8);
+
+ _emitChar(pView,hWnd,iMsg,wParam,lParam,b,0);
+ return true;
+}
+
void ev_Win32Keyboard::_emitChar(AV_View * pView,
HWND hWnd, UINT iMsg,
WPARAM nVirtKey, LPARAM keyData,
- BYTE b,
EV_EditModifierState ems)
+ WCHAR b,
+EV_EditModifierState ems)
{
// do the dirty work of pumping this character thru the state machine.
@@ -510,20 +538,25 @@
// (ems&EV_EMS_CONTROL)?"control":"",
// (ems&EV_EMS_ALT)?"alt":""));
- UT_uint16 charData;
+ UT_uint16 charData[2];
if( m_iconv != (UT_iconv_t)-1 )
{
// convert to 8bit string and null terminate
size_t len_in, len_out;
const char *In = (const char *)&b;
char *Out = (char *)&charData;
+
+ len_in = 2;
+ len_out = 4;
- len_in = 1;
- len_out = 2;
- UT_iconv( m_iconv, &In, &len_in, &Out, &len_out );
+ if (UT_iconv( m_iconv, &In, &len_in, &Out, &len_out ) == 0)
+ UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
}
else
- charData = b;
+ {
+ charData[0] = b;
+ charData[1] = 0;
+ }
EV_EditMethod * pEM;
EV_EditEventMapperResult result = m_pEEM->Keystroke(EV_EKP_PRESS|ems|b,&pEM);
@@ -545,7 +578,7 @@
case EV_EEMR_COMPLETE:
UT_ASSERT(pEM);
- invokeKeyboardMethod(pView,pEM,&charData,1);
+ invokeKeyboardMethod(pView,pEM,charData,1);
break;
case EV_EEMR_INCOMPLETE:
@@ -608,6 +641,15 @@
new_msg.pt.y = 0;
TranslateMessage(&new_msg);
}
+
+int ev_Win32Keyboard::_scanCodeToChars(UINT nVirtKey, UINT wScanCode, CONST PBYTE
+lpKeyState,
+ LPWSTR
+pwszBuff, int cchBuff)
+{
+ if (m_bIsUnicodeInput)
+ return
+ToUnicodeEx(nVirtKey,wScanCode,lpKeyState,pwszBuff,cchBuff,0,m_hKeyboardLayout);
+ else
+ return
+ToAsciiEx(nVirtKey,wScanCode,lpKeyState,pwszBuff,0,m_hKeyboardLayout);
+};
/*****************************************************************/
/*****************************************************************/
Index: src/af/ev/win/ev_Win32Keyboard.h
===================================================================
RCS file: /cvsroot/abi/src/af/ev/win/ev_Win32Keyboard.h,v
retrieving revision 1.14
diff -u -r1.14 ev_Win32Keyboard.h
--- src/af/ev/win/ev_Win32Keyboard.h 2001/02/06 22:53:54 1.14
+++ src/af/ev/win/ev_Win32Keyboard.h 2001/05/26 05:54:39
@@ -37,17 +37,24 @@
bool onKeyDown(AV_View * pView,
HWND hWnd, UINT iMsg, WPARAM nVirtKey,
LPARAM keyData);
+
+ bool onIMEChar(AV_View * pView,
+ HWND hWnd, UINT iMsg, WPARAM nVirtKey,
+LPARAM keyData);
+
bool onChar(AV_View * pView,
HWND hWnd, UINT iMsg, WPARAM nVirtKey, LPARAM
keyData);
-
+
protected:
EV_EditBits _getModifierState(void);
void _translateMessage(HWND hwnd, UINT iMsg, WPARAM
wParam, LPARAM lParam);
void _emitChar(AV_View * pView,
HWND hWnd, UINT
iMsg, WPARAM nVirtKey, LPARAM keyData,
- BYTE b,
EV_EditModifierState ems);
+ WCHAR b,
+EV_EditModifierState ems);
+ int _scanCodeToChars(UINT nVirtKey, UINT
+wScanCode,
+ CONST
+PBYTE lpKeyState, LPWSTR pwszBuff, int cchBuff);
HKL m_hKeyboardLayout;
UT_iconv_t m_iconv; /* Selected translation to Unicode */
+ bool m_bIsUnicodeInput;
};
#endif /* EV_WIN32KEYBOARD_H */
Index: src/wp/ap/win/ap_Win32Frame.cpp
===================================================================
RCS file: /cvsroot/abi/src/wp/ap/win/ap_Win32Frame.cpp,v
retrieving revision 1.73
diff -u -r1.73 ap_Win32Frame.cpp
--- src/wp/ap/win/ap_Win32Frame.cpp 2001/04/18 01:39:20 1.73
+++ src/wp/ap/win/ap_Win32Frame.cpp 2001/05/26 05:55:33
@@ -1122,6 +1122,13 @@
return 0;
return DefWindowProc(hwnd,iMsg,wParam,lParam);
}
+ case WM_IME_CHAR:
+ {
+ ev_Win32Keyboard *pWin32Keyboard = static_cast<ev_Win32Keyboard
+*>(f->m_pKeyboard);
+ if (pWin32Keyboard->onIMEChar(pView,hwnd,iMsg,wParam,lParam))
+ return 0;
+ return DefWindowProc(hwnd,iMsg,wParam,lParam);
+ }
case WM_MOUSEMOVE:
if (f->_isTracking())