Patch: Win32 IME support


Subject: Patch: Win32 IME support
From: Andrew Dunbar (hippietrail@yahoo.com)
Date: Sun Apr 15 2001 - 01:28:25 CDT


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



xap_Win32EncodingManager.cpp

_________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com



This archive was generated by hypermail 2b25 : Sun Apr 15 2001 - 01:27:02 CDT