United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-5013984 : regression: Java IM not working on Windows platforms

Details
Type:
Bug
Submit Date:
2004-03-16
Status:
Closed
Updated Date:
2005-04-26
Project Name:
JDK
Resolved Date:
2004-04-23
Component:
client-libs
OS:
windows_2003,windows_xp,windows_2000
Sub-Component:
java.awt
CPU:
x86,generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
1.4.2_05,5.0
Fixed Versions:
1.4.2_05 (05)

Related Reports
Backport:
Duplicate:
Duplicate:
Duplicate:

Sub Tasks

Description
Platform: Windows2003, WindowsXP
JDK	: tiger-beta2 b42
Locale	: ja

From tiger beta2 b42, java IM don't work. This problem was seen on Windows only.

To reproduce,
1. place WuBi.jar (attached) in j2sdk1.5.0/jre/lib/ext.
2. launch Notepad demo in sdk.
3. Select WuBi IM and try inputting kanji.

                                    

Comments
SUGGESTED FIX



Name: ssR10077			Date: 04/07/2004


*** /export1/ssi/tiger/webrev/src/windows/native/sun/windows/awt_Component.cpp-	Tue Mar 23 14:52:34 2004
--- /export1/ssi/tiger/webrev/src/windows/native/sun/windows/awt_Component.cpp	Tue Mar 23 14:52:33 2004
***************
*** 27,32 ****
--- 27,33 ----
  #include "awt_Window.h"
  #include "awt_Win32GraphicsDevice.h"
  #include "ddrawUtils.h"
+ #include "Hashtable.h"
  
  #include <jawt.h>
  
***************
*** 3280,3287 ****
      return FALSE;
  }
  
! UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, BOOL isUp)
  {
      // If the windows key is a return, wkey will equal 13 ('\r')
      // In this case, we want to return 10 ('\n')
      // Since ToAscii would convert VK_RETURN to '\r', we need
--- 3281,3298 ----
      return FALSE;
  }
  
! UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
  {
+     static Hashtable transTable("VKEY translations");
+     
+     // Try to translate using last saved translation
+     if (ops == LOAD) {
+        void* value = transTable.remove((void*)wkey);
+        if (value != NULL) {
+            return (UINT)value;
+        }
+     }
+     
      // If the windows key is a return, wkey will equal 13 ('\r')
      // In this case, we want to return 10 ('\n')
      // Since ToAscii would convert VK_RETURN to '\r', we need
***************
*** 3368,3401 ****
      // instead of creating our own conversion tables, I'll let Win32
      // convert the character for me.
      WORD mbChar;
!     UINT isUpFlag = isUp ? (1 << 15) : 0;
!     UINT scancode = ::MapVirtualKey(wkey, 0) | isUpFlag;
      int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
  				&mbChar, 0, GetKeyboardLayout());
! 
!     switch (converted) {
      // No translation available -- try known conversions or else punt.
!     case 0:
          if (wkey == VK_DELETE) {
!             return '\177';
          }
!         else if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
!             return '0' + wkey - VK_NUMPAD0;
!         }
!         else {
!             return java_awt_event_KeyEvent_CHAR_UNDEFINED;
!         }
!     // Dead Key
!     case -1:
!         return java_awt_event_KeyEvent_CHAR_UNDEFINED;
!     default:
!         // the caller expects a Unicode character.
          WCHAR unicodeChar[2];
          VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED, 
          (LPCSTR)&mbChar, 1, unicodeChar, 1));
  
!         return unicodeChar[0];
      }
  }
  
  MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 
--- 3379,3417 ----
      // instead of creating our own conversion tables, I'll let Win32
      // convert the character for me.
      WORD mbChar;
!     UINT scancode = ::MapVirtualKey(wkey, 0);
      int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
  				&mbChar, 0, GetKeyboardLayout());
! 				
!     UINT translation;
!     
!     // Dead Key
!     if (converted < 0) {
!         translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
!     } else    
      // No translation available -- try known conversions or else punt.
!     if (converted == 0) {
          if (wkey == VK_DELETE) {
!             translation = '\177';
!         } else
!         if (wkey >= VK_NUMPAD0 && wkey <= VK_NUMPAD9) {
!             translation = '0' + wkey - VK_NUMPAD0;
!         } else {
!             translation = java_awt_event_KeyEvent_CHAR_UNDEFINED;
          }
!     } else    
!     // the caller expects a Unicode character.
!     if (converted > 0) {
          WCHAR unicodeChar[2];
          VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED, 
          (LPCSTR)&mbChar, 1, unicodeChar, 1));
  
!         translation = unicodeChar[0];
      }
+     if (ops == SAVE) {
+         transTable.put((void*)wkey, (void*)translation);
+     }
+     return translation;
  }
  
  MsgRouting AwtComponent::WmKeyDown(UINT wkey, UINT repCnt, 
***************
*** 3415,3421 ****
      UINT modifiers = GetJavaModifiers();
      jint keyLocation = GetKeyLocation(wkey, flags);
      UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
!     UINT character = WindowsKeyToJavaChar(wkey, modifiers, FALSE);
  
      SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
                               nowMillisUTC(msg.time), jkey, character,
--- 3431,3437 ----
      UINT modifiers = GetJavaModifiers();
      jint keyLocation = GetKeyLocation(wkey, flags);
      UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
!     UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
  
      SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
                               nowMillisUTC(msg.time), jkey, character,
***************
*** 3455,3461 ****
      UINT modifiers = GetJavaModifiers();
      jint keyLocation = GetKeyLocation(wkey, flags);
      UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
!     UINT character = WindowsKeyToJavaChar(wkey, modifiers, TRUE);
  
      SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
                               nowMillisUTC(msg.time), jkey, character,
--- 3471,3477 ----
      UINT modifiers = GetJavaModifiers();
      jint keyLocation = GetKeyLocation(wkey, flags);
      UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
!     UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
  
      SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
                               nowMillisUTC(msg.time), jkey, character,
***************
*** 5922,5928 ****
  		      }
  		  }
  
!                   modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, FALSE);
                    bCharChanged = (keyChar != modifiedChar);
                    break; 
  	      }
--- 5938,5944 ----
  		      }
  		  }
  
!                   modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE);
                    bCharChanged = (keyChar != modifiedChar);
                    break; 
  	      }


======================================================================
                                     
2004-06-11
EVALUATION

The reason of this regression is that "KeyChar" value in the KEY_RELEASED event of Ctrl+Space is changed between b41 and b42.

On b41, if the user presses Ctrl+Space, KEY_RELEASED.getCharCode() returns the character code for Space (0x20), but on b42, it returns CHAR_UNDEFINED.

###@###.### 2004-03-16

Name: ssR10077			Date: 04/07/2004


This bug is a regression caused by the fix
4978105: Applets in Plugin on Windows can't see dead keys as KeyEvents

The original bug was caused by the fact Win32 API function ::ToAsciiEx
changes internal window key state on attempt to translate key-code of
dead key if the dead key is not actually pressed on keyboard.

The dead keys are special keys for typing of dotted and capped
composite symbols is some locales such as German, Portuguese, Czech
and so on.

To avoid calling ::ToAsciiEx on WM_KEYUP the code skipped all key
events it thought related to dead key and so didn't pass them to
Java.

The original fix of 4978105 was to use special key-code parameter for
::ToAsciiEx corresponding to released key on WM_KEYUP. This fix caused
the 5013984 regression as ::ToAsciiEx on all platforms except WinXP
ceases to correctly translate released key key-code to correct
key-char.

The new fix is to save in hash-table the key-code to key-char
translation between KeyPress and KeyRelease so on the KeyRelease we
can simply return saved translation. If on KeyRelease the hash-table
doesn't have translation for key-code it's translated using
::ToAsciiEx.

The fix is tested on Win98, W2K, WinXP and with Japanese IME.


======================================================================

Name: rpR10076			Date: 04/21/2004


The fix for this bug also resolves 5031725.
###@###.###
======================================================================
                                     
2004-06-11
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
1.4.2_05
generic
tiger-beta2

FIXED IN:
1.4.2_05
tiger-beta2

INTEGRATED IN:
1.4.2_05
tiger-b49
tiger-beta2

VERIFIED IN:
1.4.2_05
tiger-beta2


                                     
2004-06-14



Hardware and Software, Engineered to Work Together