提交 a469d6d9 编写于 作者: A alexsch

8000626: Implement dead key detection for KeyEvent on Linux

Reviewed-by: kizune
上级 84ada1f4
......@@ -379,6 +379,25 @@ public class XKeysym {
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 --> <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)0x1a2, (char)0x02d8); // XK_breve --> BREVE
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 {
// (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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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()),
......@@ -1149,7 +1152,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
jkeyExtended);
if( unicodeKey > 0 ) {
if (unicodeKey > 0 && !isDeadKey) {
keyEventLog.fine("fire _TYPED on "+unicodeKey);
postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
ev.get_time(),
......@@ -1176,9 +1179,7 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
}
// 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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
// 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 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
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()),
......@@ -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
* unreliable, since mapping changes can happen for a virtual desktop
......
......@@ -695,25 +695,25 @@ SOFTWARE.
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_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_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 /* 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 /* 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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册