Re: Patch: Win32 IME support


Subject: Re: Patch: Win32 IME support
From: Hilary Cheng (hilarycheng@usa.net)
Date: Sun Apr 15 2001 - 08:43:32 CDT


Hi Andrew,

    Is that possible to enable NT AIMME ? Since if we want to enable the users to input
non-english characeter, only AIMME is available.

Regards,

Hilary

Andrew Dunbar ¼g¹D¡G

> Here, finally is my Windows multilingual support including Input
> Methods.
>
> Tested & working:
> * 8 bit encodings:
> * English: 98 & 2000
> * Spanish: 98 & 2000
> * German: 98 & 2000
> * Czech: 98 & 2000
> * Greek: 98 & 2000
> * Russian: 2000
> * Thai: 2000
> * Unicode encodings:
> * Georgian: 2000
> * Hindi: 2000
> * Sanskrit: 2000
> * Multibyte IMEs
> * Chinese Traditional: 2000
> * Chinese Simplified: 2000
> * Japanese: 2000
>
> Tested & not working:
> * Korean: 2000
>
> Needs testing:
> * Multibyte IMEs on Windows 95/98/ME
> * Unicode IMEs (if such a beast exists?)
> * Big endian NT/2000 8 bit, Multibyte, and Unicode.
>
> I believe there are big problems with the Korean support at least
> on Windows. The IME returns garbage but so does importing a
> plain text KSC encoded file. I can't test other Korean encodings
> on my setup. I'm not sure if this is a problem just for Windows
> AbiWord, all AbiWord implementations, or a libiconv problem.
> Can somebody please look into this?
>
> Also regarding IME support, Chinese and Japanese IMEs only work
> correctly when I set the machine's default language to the language
> I want to check and reboot. WM_IME_CHAR messages appear to arrive
> with only one byte of the MBCS character unless the IME matches the
> default language on the machine.
> Can somebody more knowlegeable on Windows IMEs please look into this?
> It seems to go against the MSDN documentation I have at my disposal.
>
> Andrew.
>
> --
> http://linguaphile.sourceforge.net
>
> ------------------------------------------------------------------------
> ? src/af/xap/win/xap_Win32EncodingManager.cpp
> ? src/af/xap/win/xap_Win32EncodingManager.h
> 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/04/15 06:06:49
> @@ -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,17 @@
> strcpy( szCodePage, "CP" );
> if( GetLocaleInfo( LOWORD( hKeyboardLayout ), LOCALE_IDEFAULTANSICODEPAGE, &szCodePage[2], sizeof( szCodePage ) / sizeof( szCodePage[0] ) - 2 ) )
> {
> + // Unicode locale?
> + 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 +383,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 +418,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 +490,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 +512,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 +536,24 @@
> // (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 );
> +i UT_iconv( m_iconv, &In, &len_in, &Out, &len_out );
> }
> 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 +575,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 +638,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/04/15 06:06:49
> @@ -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/af/xap/Makefile
> ===================================================================
> RCS file: /cvsroot/abi/src/af/xap/Makefile,v
> retrieving revision 1.60
> diff -u -r1.60 Makefile
> --- src/af/xap/Makefile 2001/04/11 21:40:15 1.60
> +++ src/af/xap/Makefile 2001/04/15 06:06:52
> @@ -80,7 +80,8 @@
> ifeq ($(ABI_FE), Win32)
> PLATFORM_OBJS += $(OBJDIR)/xap_$(ABI_FE)Slurp.$(OBJ_SUFFIX) \
> $(OBJDIR)/xap_$(ABI_FE)PreviewWidget.$(OBJ_SUFFIX) \
> - $(OBJDIR)/xap_$(ABI_FE)DialogHelper.$(OBJ_SUFFIX)
> + $(OBJDIR)/xap_$(ABI_FE)DialogHelper.$(OBJ_SUFFIX) \
> + $(OBJDIR)/xap_$(ABI_FE)EncodingManager.$(OBJ_SUFFIX)
> endif
>
> ifdef ABI_OPT_GNOME
> Index: src/af/xap/win/Makefile
> ===================================================================
> RCS file: /cvsroot/abi/src/af/xap/win/Makefile,v
> retrieving revision 1.30
> diff -u -r1.30 Makefile
> --- src/af/xap/win/Makefile 2001/03/07 15:45:45 1.30
> +++ src/af/xap/win/Makefile 2001/04/15 06:06:54
> @@ -39,10 +39,27 @@
> xap_Win32Slurp.cpp \
> xap_Win32Toolbar_Icons.cpp \
> xap_Win32DialogHelper.cpp \
> - xap_Win32Module.cpp
> + xap_Win32Module.cpp \
> + xap_Win32EncodingManager.cpp
>
> TARGETS= $(OBJS)
>
> include $(ABI_ROOT)/src/config/abi_rules.mk
> +
> +# Win32 must build libiconv as a peer, Unix should either
> +# have iconv.h available as part of its C library (GNU libc
> +# systems) or have it installed as part of the libiconv-1.0
> +# package.
> +
> +# Test for iconv in system locations
> +HAVE_ICONV_SYSTEM := $(shell if [ -r /usr/include/iconv.h -o -r /usr/local/include/iconv.h ] ; then echo 1 ; fi)
> +
> +ifeq ($(OS_NAME), WIN32)
> +INCLUDES= -I$(ABI_XX_ROOT)/../libiconv/include
> +else
> +ifneq ($(HAVE_ICONV_SYSTEM),1)
> +INCLUDES= -I$(ABI_ROOT)/../libiconv/include
> +endif
> +endif
>
> build:: $(TARGETS)
> Index: src/af/xap/win/xap_Win32App.cpp
> ===================================================================
> RCS file: /cvsroot/abi/src/af/xap/win/xap_Win32App.cpp,v
> retrieving revision 1.40
> diff -u -r1.40 xap_Win32App.cpp
> --- src/af/xap/win/xap_Win32App.cpp 2001/03/19 04:01:31 1.40
> +++ src/af/xap/win/xap_Win32App.cpp 2001/04/15 06:06:56
> @@ -29,6 +29,7 @@
> #include "xap_Win32_TB_CFactory.h"
> #include "xap_Win32Slurp.h"
> #include "xap_Win32Module.h"
> +#include "xap_Win32EncodingManager.h"
>
> #ifdef _MSC_VER
> #pragma warning(disable:4355) // 'this' used in base member initializer list
> @@ -45,6 +46,9 @@
> UT_ASSERT(hInstance);
>
> _setAbiSuiteLibDir();
> +
> + DELETEP(m_pEncMgr);
> + m_pEncMgr = new XAP_Win32EncodingManager();
> }
>
> XAP_Win32App::~XAP_Win32App(void)
> Index: src/wp/ap/win/ap_Win32Frame.cpp
> ===================================================================
> RCS file: /cvsroot/abi/src/wp/ap/win/ap_Win32Frame.cpp,v
> retrieving revision 1.72
> diff -u -r1.72 ap_Win32Frame.cpp
> --- src/wp/ap/win/ap_Win32Frame.cpp 2001/03/25 07:46:35 1.72
> +++ src/wp/ap/win/ap_Win32Frame.cpp 2001/04/15 06:07:18
> @@ -697,6 +697,12 @@
> return _showDocument();
> }
>
> +UT_Error AP_Win32Frame::importDocument(const char * szFilename, int ieft, bool markClean)
> +{
> + UT_ASSERT(UT_TODO);
> + return UT_OK;
> +}
> +
> void AP_Win32Frame::_scrollFuncY(void* pData, UT_sint32 yoff, UT_sint32 /*ylimit*/)
> {
> // this is a static callback function and doesn't have a 'this' pointer.
> @@ -1042,6 +1048,13 @@
> {
> ev_Win32Keyboard *pWin32Keyboard = static_cast<ev_Win32Keyboard *>(f->m_pKeyboard);
> if (pWin32Keyboard->onChar(pView,hwnd,iMsg,wParam,lParam))
> + 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);
> }
> Index: src/wp/ap/win/ap_Win32Frame.h
> ===================================================================
> RCS file: /cvsroot/abi/src/wp/ap/win/ap_Win32Frame.h,v
> retrieving revision 1.25
> diff -u -r1.25 ap_Win32Frame.h
> --- src/wp/ap/win/ap_Win32Frame.h 2001/03/17 16:48:57 1.25
> +++ src/wp/ap/win/ap_Win32Frame.h 2001/04/15 06:07:18
> @@ -36,6 +36,7 @@
> virtual XAP_Frame * cloneFrame(void);
> virtual UT_Error loadDocument(const char * szFilename, int ieft);
> virtual UT_Error loadDocument(const char * szFilename, int ieft, bool createNew);
> + virtual UT_Error importDocument(const char * szFilename, int ieft, bool markClean);
> virtual bool initFrameData(void);
> virtual void killFrameData(void);
>
>
> ------------------------------------------------------------------------
> Name: xap_Win32EncodingManager.h
> xap_Win32EncodingManager.h Type: application/x-unknown-content-type-hfile
> Encoding: base64
>
> [Image]



This archive was generated by hypermail 2b25 : Sun Apr 15 2001 - 08:42:30 CDT