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())

Reply via email to