--- old/src/solaris/classes/sun/awt/X11/XWindow.java 2012-10-09 11:28:36.000000000 -0400 +++ new/src/solaris/classes/sun/awt/X11/XWindow.java 2012-10-09 11:28:35.000000000 -0400 @@ -1115,7 +1115,10 @@ // (1) either XIM could not handle it or // (2) it was Latin 1:1 mapping. // - XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev); + // Preserve modifiers to get Java key code for dead keys + boolean isDeadKey = isDeadKey(keysym[0]); + XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym[0]) + : XKeysym.getJavaKeycode(ev); if( jkc == null ) { jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); } @@ -1141,7 +1144,7 @@ jkc.getJavaKeycode(); postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED, ev.get_time(), - jkeyToReturn, + isDeadKey ? jkeyExtended : jkeyToReturn, (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey), jkc.getKeyLocation(), ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()), @@ -1176,9 +1179,7 @@ } // un-private it if you need to call it from elsewhere private void handleKeyRelease(XKeyEvent ev) { - long keysym[] = new long[2]; int unicodeKey = 0; - keysym[0] = XConstants.NoSymbol; if (keyEventLog.isLoggable(PlatformLogger.FINE)) { logIncomingKeyEvent( ev ); @@ -1187,7 +1188,11 @@ // and Java KeyEvent keycode should be calculated. // For release we should post released event. // - XKeysym.Keysym2JavaKeycode jkc = XKeysym.getJavaKeycode(ev); + // Preserve modifiers to get Java key code for dead keys + long keysym = xkeycodeToKeysym(ev); + boolean isDeadKey = isDeadKey(keysym); + XKeysym.Keysym2JavaKeycode jkc = isDeadKey ? XKeysym.getJavaKeycode(keysym) + : XKeysym.getJavaKeycode(ev); if( jkc == null ) { jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); } @@ -1219,7 +1224,7 @@ jkc.getJavaKeycode(); postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED, ev.get_time(), - jkeyToReturn, + isDeadKey ? jkeyExtended : jkeyToReturn, (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey), jkc.getKeyLocation(), ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()), @@ -1228,6 +1233,11 @@ } + + + private boolean isDeadKey(long keysym){ + return XKeySymConstants.XK_dead_grave <= keysym && keysym <= XKeySymConstants.XK_dead_semivoiced_sound; + } /* * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are --- old/src/solaris/classes/sun/awt/X11/keysym2ucs.h 2012-10-09 11:28:38.000000000 -0400 +++ new/src/solaris/classes/sun/awt/X11/keysym2ucs.h 2012-10-09 11:28:37.000000000 -0400 @@ -695,25 +695,25 @@ 0x0000 #define XK_ISO_Center_Object 0xFE33 0x0000 #define XK_ISO_Enter 0xFE34 -0x0000 #define XK_dead_grave 0xFE50 -0x0000 #define XK_dead_acute 0xFE51 -0x0000 #define XK_dead_circumflex 0xFE52 -0x0000 #define XK_dead_tilde 0xFE53 -0x0000 #define XK_dead_macron 0xFE54 -0x0000 #define XK_dead_breve 0xFE55 -0x0000 #define XK_dead_abovedot 0xFE56 -0x0000 #define XK_dead_diaeresis 0xFE57 -0x0000 #define XK_dead_abovering 0xFE58 -0x0000 #define XK_dead_doubleacute 0xFE59 -0x0000 #define XK_dead_caron 0xFE5A -0x0000 #define XK_dead_cedilla 0xFE5B -0x0000 #define XK_dead_ogonek 0xFE5C -0x0000 #define XK_dead_iota 0xFE5D -0x0000 #define XK_dead_voiced_sound 0xFE5E -0x0000 #define XK_dead_semivoiced_sound 0xFE5F -0x0000 #define XK_dead_belowdot 0xFE60 -0x0000 #define XK_dead_hook 0xFE61 -0x0000 #define XK_dead_horn 0xFE62 +0x02CB #define XK_dead_grave 0xFE50 +0x02CA #define XK_dead_acute 0xFE51 +0x02C6 #define XK_dead_circumflex 0xFE52 +0x02DC #define XK_dead_tilde 0xFE53 +0x02C9 #define XK_dead_macron 0xFE54 +0x02D8 #define XK_dead_breve 0xFE55 +0x02D9 #define XK_dead_abovedot 0xFE56 +0x00A8 #define XK_dead_diaeresis 0xFE57 +0x02DA #define XK_dead_abovering 0xFE58 +0x02DD #define XK_dead_doubleacute 0xFE59 +0x02C7 #define XK_dead_caron 0xFE5A +0x00B8 #define XK_dead_cedilla 0xFE5B +0x02DB #define XK_dead_ogonek 0xFE5C +0x0269 #define XK_dead_iota 0xFE5D +0x3099 #define XK_dead_voiced_sound 0xFE5E +0x309A #define XK_dead_semivoiced_sound 0xFE5F +0x0323 #define XK_dead_belowdot 0xFE60 +0x0321 #define XK_dead_hook 0xFE61 +0x031B #define XK_dead_horn 0xFE62 0x0000 #define XK_First_Virtual_Screen 0xFED0 0x0000 #define XK_Prev_Virtual_Screen 0xFED1 @@ -2466,6 +2466,7 @@ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Meta_L), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_META, java.awt.event.KeyEvent.KEY_LOCATION_LEFT)); tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Meta_R), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_META, java.awt.event.KeyEvent.KEY_LOCATION_RIGHT)); tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Caps_Lock), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CAPS_LOCK, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Shift_Lock), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CAPS_LOCK, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); tojava tojava /* Misc Functions */ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Print), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_PRINTSCREEN, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); @@ -2640,6 +2641,21 @@ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kanji), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CONVERT, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); tojava /* Type 5c Japanese keyboard: nihongo */ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Henkan_Mode), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_INPUT_METHOD_ON_OFF, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Eisu_Shift ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALPHANUMERIC , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Eisu_toggle ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALPHANUMERIC , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Zenkaku ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_FULL_WIDTH , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Hankaku ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_HALF_WIDTH , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Hiragana ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_HIRAGANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Katakana ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KATAKANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Romaji ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_JAPANESE_ROMAN , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kana_Shift ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kana_Lock ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA_LOCK , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Muhenkan ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_NONCONVERT , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Zen_Koho ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_ALL_CANDIDATES , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kanji_Bangou ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CODE_INPUT , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Mae_Koho ), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_PREVIOUS_CANDIDATE , java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); +tojava +tojava tojava /* VK_KANA_LOCK is handled separately because it generates the tojava * same keysym as ALT_GRAPH in spite of its different behavior. tojava */ --- old/src/solaris/classes/sun/awt/X11/XKeysym.java 2012-10-09 11:28:40.000000000 -0400 +++ new/src/solaris/classes/sun/awt/X11/XKeysym.java 2012-10-09 11:28:39.000000000 -0400 @@ -379,6 +379,25 @@ keysym2UCSHash.put( (long)0xFFB8, (char)0x0038); // XK_KP_8 --> DIGIT EIGHT keysym2UCSHash.put( (long)0xFFB9, (char)0x0039); // XK_KP_9 --> DIGIT NINE keysym2UCSHash.put( (long)0xFE20, (char)0x0009); // XK_ISO_Left_Tab --> + keysym2UCSHash.put( (long)0xFE50, (char)0x02CB); // XK_dead_grave --> MODIFIER LETTER GRAVE ACCENT + keysym2UCSHash.put( (long)0xFE51, (char)0x02CA); // XK_dead_acute --> MODIFIER LETTER ACUTE ACCENT + keysym2UCSHash.put( (long)0xFE52, (char)0x02C6); // XK_dead_circumflex --> MODIFIER LETTER CIRCUMFLEX ACCENT + keysym2UCSHash.put( (long)0xFE53, (char)0x02DC); // XK_dead_tilde --> SMALL TILDE + keysym2UCSHash.put( (long)0xFE54, (char)0x02C9); // XK_dead_macron --> MODIFIER LETTER MACRON + keysym2UCSHash.put( (long)0xFE55, (char)0x02D8); // XK_dead_breve --> BREVE + keysym2UCSHash.put( (long)0xFE56, (char)0x02D9); // XK_dead_abovedot --> DOT ABOVE + keysym2UCSHash.put( (long)0xFE57, (char)0x00A8); // XK_dead_diaeresis --> DIAERESIS + keysym2UCSHash.put( (long)0xFE58, (char)0x02DA); // XK_dead_abovering --> RING ABOVE + keysym2UCSHash.put( (long)0xFE59, (char)0x02DD); // XK_dead_doubleacute --> DOUBLE ACUTE ACCENT + keysym2UCSHash.put( (long)0xFE5A, (char)0x02C7); // XK_dead_caron --> CARON + keysym2UCSHash.put( (long)0xFE5B, (char)0x00B8); // XK_dead_cedilla --> CEDILLA + keysym2UCSHash.put( (long)0xFE5C, (char)0x02DB); // XK_dead_ogonek --> OGONEK + keysym2UCSHash.put( (long)0xFE5D, (char)0x0269); // XK_dead_iota --> LATIN SMALL LETTER IOTA + keysym2UCSHash.put( (long)0xFE5E, (char)0x3099); // XK_dead_voiced_sound --> COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK + keysym2UCSHash.put( (long)0xFE5F, (char)0x309A); // XK_dead_semivoiced_sound --> COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + keysym2UCSHash.put( (long)0xFE60, (char)0x0323); // XK_dead_belowdot --> COMBINING DOT BELOW + keysym2UCSHash.put( (long)0xFE61, (char)0x0321); // XK_dead_hook --> COMBINING PALATALIZED HOOK BELOW + keysym2UCSHash.put( (long)0xFE62, (char)0x031B); // XK_dead_horn --> COMBINING HORN keysym2UCSHash.put( (long)0x1a1, (char)0x0104); // XK_Aogonek --> LATIN CAPITAL LETTER A WITH OGONEK keysym2UCSHash.put( (long)0x1a2, (char)0x02d8); // XK_breve --> BREVE keysym2UCSHash.put( (long)0x1a3, (char)0x0141); // XK_Lstroke --> LATIN CAPITAL LETTER L WITH STROKE