提交 a469d6d9 编写于 作者: A alexsch

8000626: Implement dead key detection for KeyEvent on Linux

Reviewed-by: kizune
上级 84ada1f4
...@@ -379,6 +379,25 @@ public class XKeysym { ...@@ -379,6 +379,25 @@ public class XKeysym {
keysym2UCSHash.put( (long)0xFFB8, (char)0x0038); // XK_KP_8 --> DIGIT EIGHT 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)0xFFB9, (char)0x0039); // XK_KP_9 --> DIGIT NINE
keysym2UCSHash.put( (long)0xFE20, (char)0x0009); // XK_ISO_Left_Tab --> <control> keysym2UCSHash.put( (long)0xFE20, (char)0x0009); // XK_ISO_Left_Tab --> <control>
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)0x1a1, (char)0x0104); // XK_Aogonek --> LATIN CAPITAL LETTER A WITH OGONEK
keysym2UCSHash.put( (long)0x1a2, (char)0x02d8); // XK_breve --> BREVE keysym2UCSHash.put( (long)0x1a2, (char)0x02d8); // XK_breve --> BREVE
keysym2UCSHash.put( (long)0x1a3, (char)0x0141); // XK_Lstroke --> LATIN CAPITAL LETTER L WITH STROKE keysym2UCSHash.put( (long)0x1a3, (char)0x0141); // XK_Lstroke --> LATIN CAPITAL LETTER L WITH STROKE
......
...@@ -1115,7 +1115,10 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1115,7 +1115,10 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// (1) either XIM could not handle it or // (1) either XIM could not handle it or
// (2) it was Latin 1:1 mapping. // (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 ) { if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
} }
...@@ -1141,7 +1144,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1141,7 +1144,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
jkc.getJavaKeycode(); jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED, postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
ev.get_time(), ev.get_time(),
jkeyToReturn, isDeadKey ? jkeyExtended : jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey), (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(), jkc.getKeyLocation(),
ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()), ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
...@@ -1149,7 +1152,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1149,7 +1152,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
jkeyExtended); jkeyExtended);
if( unicodeKey > 0 ) { if (unicodeKey > 0 && !isDeadKey) {
keyEventLog.fine("fire _TYPED on "+unicodeKey); keyEventLog.fine("fire _TYPED on "+unicodeKey);
postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED, postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
ev.get_time(), ev.get_time(),
...@@ -1176,9 +1179,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1176,9 +1179,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
} }
// un-private it if you need to call it from elsewhere // un-private it if you need to call it from elsewhere
private void handleKeyRelease(XKeyEvent ev) { private void handleKeyRelease(XKeyEvent ev) {
long keysym[] = new long[2];
int unicodeKey = 0; int unicodeKey = 0;
keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(PlatformLogger.FINE)) { if (keyEventLog.isLoggable(PlatformLogger.FINE)) {
logIncomingKeyEvent( ev ); logIncomingKeyEvent( ev );
...@@ -1187,7 +1188,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1187,7 +1188,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// and Java KeyEvent keycode should be calculated. // and Java KeyEvent keycode should be calculated.
// For release we should post released event. // 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 ) { if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN); jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
} }
...@@ -1219,7 +1224,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1219,7 +1224,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
jkc.getJavaKeycode(); jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED, postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED,
ev.get_time(), ev.get_time(),
jkeyToReturn, isDeadKey ? jkeyExtended : jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey), (unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(), jkc.getKeyLocation(),
ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()), ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
...@@ -1229,6 +1234,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer { ...@@ -1229,6 +1234,11 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
} }
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 * XmNiconic and Map/UnmapNotify (that XmNiconic relies on) are
* unreliable, since mapping changes can happen for a virtual desktop * unreliable, since mapping changes can happen for a virtual desktop
......
...@@ -695,25 +695,25 @@ SOFTWARE. ...@@ -695,25 +695,25 @@ SOFTWARE.
0x0000 #define XK_ISO_Center_Object 0xFE33 0x0000 #define XK_ISO_Center_Object 0xFE33
0x0000 #define XK_ISO_Enter 0xFE34 0x0000 #define XK_ISO_Enter 0xFE34
0x0000 #define XK_dead_grave 0xFE50 0x02CB #define XK_dead_grave 0xFE50
0x0000 #define XK_dead_acute 0xFE51 0x02CA #define XK_dead_acute 0xFE51
0x0000 #define XK_dead_circumflex 0xFE52 0x02C6 #define XK_dead_circumflex 0xFE52
0x0000 #define XK_dead_tilde 0xFE53 0x02DC #define XK_dead_tilde 0xFE53
0x0000 #define XK_dead_macron 0xFE54 0x02C9 #define XK_dead_macron 0xFE54
0x0000 #define XK_dead_breve 0xFE55 0x02D8 #define XK_dead_breve 0xFE55
0x0000 #define XK_dead_abovedot 0xFE56 0x02D9 #define XK_dead_abovedot 0xFE56
0x0000 #define XK_dead_diaeresis 0xFE57 0x00A8 #define XK_dead_diaeresis 0xFE57
0x0000 #define XK_dead_abovering 0xFE58 0x02DA #define XK_dead_abovering 0xFE58
0x0000 #define XK_dead_doubleacute 0xFE59 0x02DD #define XK_dead_doubleacute 0xFE59
0x0000 #define XK_dead_caron 0xFE5A 0x02C7 #define XK_dead_caron 0xFE5A
0x0000 #define XK_dead_cedilla 0xFE5B 0x00B8 #define XK_dead_cedilla 0xFE5B
0x0000 #define XK_dead_ogonek 0xFE5C 0x02DB #define XK_dead_ogonek 0xFE5C
0x0000 #define XK_dead_iota 0xFE5D 0x0269 #define XK_dead_iota 0xFE5D
0x0000 #define XK_dead_voiced_sound 0xFE5E 0x3099 #define XK_dead_voiced_sound 0xFE5E
0x0000 #define XK_dead_semivoiced_sound 0xFE5F 0x309A #define XK_dead_semivoiced_sound 0xFE5F
0x0000 #define XK_dead_belowdot 0xFE60 0x0323 #define XK_dead_belowdot 0xFE60
0x0000 #define XK_dead_hook 0xFE61 0x0321 #define XK_dead_hook 0xFE61
0x0000 #define XK_dead_horn 0xFE62 0x031B #define XK_dead_horn 0xFE62
0x0000 #define XK_First_Virtual_Screen 0xFED0 0x0000 #define XK_First_Virtual_Screen 0xFED0
0x0000 #define XK_Prev_Virtual_Screen 0xFED1 0x0000 #define XK_Prev_Virtual_Screen 0xFED1
...@@ -2466,6 +2466,7 @@ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Alt_ ...@@ -2466,6 +2466,7 @@ tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Alt_
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_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_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_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
tojava /* Misc Functions */ 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)); 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 /* Type 5c Japanese keyboard: henkan */ ...@@ -2640,6 +2641,21 @@ tojava /* Type 5c Japanese keyboard: henkan */
tojava keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.XK_Kanji), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_CONVERT, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD)); 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 /* 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_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 /* VK_KANA_LOCK is handled separately because it generates the
tojava * same keysym as ALT_GRAPH in spite of its different behavior. tojava * same keysym as ALT_GRAPH in spite of its different behavior.
tojava */ tojava */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册