"Michael D. Pritchett" wrote:
>
> Andrew -
>
> I attempt to incorporate your patch against the latest CVS:
> http://parsons.abisource.com/mailinglists/abiword-dev/01/May/0905.html
>
> In the _emitChar function, your changes seem to cause a failure for me when
> I type any character at the following line.
>
> if (UT_iconv( m_iconv, &In, &len_in, &Out, &len_out ) == 0)
> UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
>
> Any suggestions?
Thanks for catching this Michael. I found it myself last night.
Here is the revised patch. I wasn't passing the correct len_in
to iconv in all cases of Unicode input and MBCS input.
Andrew.
--
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/06/01 02:08:25
@@ -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 (!m_bIsUnicodeInput && (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,26 @@
// (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;
+
+ // 2 bytes for Unicode and MBCS
+ len_in = (m_bIsUnicodeInput || (nVirtKey & 0xff00)) ? 2 : 1;
+ 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 ) == -1)
+ 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 +579,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 +642,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/06/01 02:08:26
@@ -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/06/01 02:10:02
@@ -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())