< prev index next >
src/solaris/classes/sun/awt/X11/XKeysym.java
Print this page
rev 1565 : 5100701: Toolkit.getLockingKeyState() does not work on XToolkit, but works on Motif
Summary: Does not work on Motif but works on XToolkit now; implemented using XQueryPointer.
Reviewed-by: anthony
rev 1566 : 6680988: KeyEvent is still missing VK values for many keyboards
Summary: 2 new methods and some fields added to KeyEvent, plus hash of constants introduced
Reviewed-by: art
rev 1567 : 6871299: Shift+Tab no longer generates a KEY_TYPED event; used to with JRE 1.5
Summary: Add XK_ISO_Left_Tab -> VK_TAB rule
Reviewed-by: dcherepanov
rev 1568 : 6711676: Numpad keys trigger more than one KeyEvent.
Summary: Introduce a new sniffer based on server keymap.
Reviewed-by: art
rev 1569 : 5099725: AWT doesn't seem to handle MappingNotify events under X11.
5036807: Pressing action keys "STOP/AGAIN/COMPOSE" generates keycode of F11/F12 keys.
4787377: VK_STOP key on Solaris generates wrong Key Code
Summary: Added an event processing lumped with similar native code for similar bugs.
Reviewed-by: art
rev 1570 : 8000626: Implement dead key detection for KeyEvent on Linux
Reviewed-by: kizune
@@ -1,9 +1,9 @@
// This is a generated file: do not edit! Edit keysym2ucs.h if necessary.
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -61,12 +61,16 @@
static Hashtable<Long, Character> keysym2UCSHash = new Hashtable<Long, Character>();
static Hashtable<Long, Long> uppercaseHash = new Hashtable<Long, Long>();
// TODO: or not to do: add reverse lookup javakeycode2keysym,
// for robot only it seems to me. After that, we can remove lookup table
// from XWindow.c altogether.
+ // Another use for reverse lookup: query keyboard state, for some keys.
+ static Hashtable<Integer, Long> javaKeycode2KeysymHash = new Hashtable<Integer, Long>();
static long keysym_lowercase = unsafe.allocateMemory(Native.getLongSize());
static long keysym_uppercase = unsafe.allocateMemory(Native.getLongSize());
+ static Keysym2JavaKeycode kanaLock = new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_KANA_LOCK,
+ java.awt.event.KeyEvent.KEY_LOCATION_STANDARD);
public static char convertKeysym( long ks, int state ) {
/* First check for Latin-1 characters (1:1 mapping) */
if ((ks >= 0x0020 && ks <= 0x007e) ||
(ks >= 0x00a0 && ks <= 0x00ff)) {
@@ -85,23 +89,56 @@
return (char)(ks & 0x00ffffff);
Character ch = keysym2UCSHash.get(ks);
return ch == null ? (char)0 : ch.charValue();
}
+ static long xkeycode2keysym_noxkb(XKeyEvent ev, int ndx) {
+ XToolkit.awtLock();
+ try {
+ return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx);
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+ static long xkeycode2keysym_xkb(XKeyEvent ev, int ndx) {
+ XToolkit.awtLock();
+ try {
+ int mods = ev.get_state();
+ if ((ndx == 0) && ((mods & XConstants.ShiftMask) != 0)) {
+ // I don't know all possible meanings of 'ndx' in case of XKB
+ // and don't want to speculate. But this particular case
+ // clearly means that caller needs a so called primary keysym.
+ mods ^= XConstants.ShiftMask;
+ }
+ XlibWrapper.XkbTranslateKeyCode(XToolkit.getXKBKbdDesc(), ev.get_keycode(),
+ mods, XlibWrapper.iarg1, XlibWrapper.larg3);
+ //XXX unconsumed modifiers?
+ return Native.getLong(XlibWrapper.larg3);
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
static long xkeycode2keysym(XKeyEvent ev, int ndx) {
XToolkit.awtLock();
try {
- return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx );
+ if (XToolkit.canUseXKBCalls()) {
+ return xkeycode2keysym_xkb(ev, ndx);
+ }else{
+ return xkeycode2keysym_noxkb(ev, ndx);
+ }
} finally {
XToolkit.awtUnlock();
}
}
+ static long xkeycode2primary_keysym(XKeyEvent ev) {
+ return xkeycode2keysym(ev, 0);
+ }
public static boolean isKPEvent( XKeyEvent ev )
{
// Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
// Otherwise, it is [1].
- int ndx = XToolkit.isXsunServer() &&
+ int ndx = XToolkit.isXsunKPBehavior() &&
! XToolkit.isXKBenabled() ? 2 : 1;
XToolkit.awtLock();
try {
return XlibWrapper.IsKeypadKey(
XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx ) );
@@ -140,11 +177,11 @@
I do not check if this is a keypad event, I just presume it.
*/
private static long getKeypadKeysym( XKeyEvent ev ) {
int ndx = 0;
long keysym = XConstants.NoSymbol;
- if( XToolkit.isXsunServer() &&
+ if( XToolkit.isXsunKPBehavior() &&
! XToolkit.isXKBenabled() ) {
if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on
ndx = 3;
keysym = xkeycode2keysym(ev, ndx);
} else {
@@ -162,16 +199,39 @@
keysym = xkeycode2keysym(ev, ndx);
}
}
return keysym;
}
+
+ /**
+ Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X keysym.
+ Some keysyms maps to more than one keycode, these would require extra processing.
+ */
+ static Keysym2JavaKeycode getJavaKeycode( long keysym ) {
+ if(keysym == XKeySymConstants.XK_Mode_switch){
+ /* XK_Mode_switch on solaris maps either to VK_ALT_GRAPH (default) or VK_KANA_LOCK */
+ if( XToolkit.isKanaKeyboard() ) {
+ return kanaLock;
+ }
+ }else if(keysym == XKeySymConstants.XK_L1){
+ /* if it is Sun keyboard, trick hash to return VK_STOP else VK_F11 (default) */
+ if( XToolkit.isSunKeyboard() ) {
+ keysym = XKeySymConstants.SunXK_Stop;
+ }
+ }else if(keysym == XKeySymConstants.XK_L2) {
+ /* if it is Sun keyboard, trick hash to return VK_AGAIN else VK_F12 (default) */
+ if( XToolkit.isSunKeyboard() ) {
+ keysym = XKeySymConstants.SunXK_Again;
+ }
+ }
+
+ return keysym2JavaKeycodeHash.get( keysym );
+ }
/**
Return java.awt.KeyEvent constant meaning (Java) keycode, derived from X Window KeyEvent.
Algorithm is, extract via XKeycodeToKeysym a proper keysym according to Xlib spec rules and
err exceptions, then search a java keycode in a table.
- Some keysyms maps to more than one keycode, these would require extra processing. If someone
- points me to such a keysym.
*/
static Keysym2JavaKeycode getJavaKeycode( XKeyEvent ev ) {
// get from keysym2JavaKeycodeHash.
long keysym = XConstants.NoSymbol;
int ndx = 0;
@@ -182,18 +242,43 @@
// we only need primary-layer keysym to derive a java keycode.
ndx = 0;
keysym = xkeycode2keysym(ev, ndx);
}
- Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym );
+ Keysym2JavaKeycode jkc = getJavaKeycode( keysym );
return jkc;
}
static int getJavaKeycodeOnly( XKeyEvent ev ) {
Keysym2JavaKeycode jkc = getJavaKeycode( ev );
return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
}
/**
+ * Return an integer java keycode apprx as it was before extending keycodes range.
+ * This call would ignore for instance XKB and process whatever is on the bottom
+ * of keysym stack. Result will not depend on actual locale, will differ between
+ * dual/multiple keyboard setup systems (e.g. English+Russian vs French+Russian)
+ * but will be someway compatible with old releases.
+ */
+ static int getLegacyJavaKeycodeOnly( XKeyEvent ev ) {
+ long keysym = XConstants.NoSymbol;
+ int ndx = 0;
+ if( (ev.get_state() & XToolkit.numLockMask) != 0 &&
+ isKPEvent(ev)) {
+ keysym = getKeypadKeysym( ev );
+ } else {
+ // we only need primary-layer keysym to derive a java keycode.
+ ndx = 0;
+ keysym = xkeycode2keysym_noxkb(ev, ndx);
+ }
+ Keysym2JavaKeycode jkc = getJavaKeycode( keysym );
+ return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
+ }
+ static long javaKeycode2Keysym( int jkey ) {
+ Long ks = javaKeycode2KeysymHash.get( jkey );
+ return (ks == null ? 0 : ks.longValue());
+ }
+ /**
Return keysym derived from a keycode and modifiers.
Usually an input method does this. However non-system input methods (e.g. Java IMs) do not.
For rules, see "Xlib - C Language X Interface",
MIT X Consortium Standard
X Version 11, Release 6
@@ -276,10 +361,30 @@
keysym2UCSHash.put( (long)0xFFB5, (char)0x0035); // XK_KP_5 --> DIGIT FIVE
keysym2UCSHash.put( (long)0xFFB6, (char)0x0036); // XK_KP_6 --> DIGIT SIX
keysym2UCSHash.put( (long)0xFFB7, (char)0x0037); // XK_KP_7 --> DIGIT SEVEN
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
keysym2UCSHash.put( (long)0x1a5, (char)0x013d); // XK_Lcaron --> LATIN CAPITAL LETTER L WITH CARON
keysym2UCSHash.put( (long)0x1a6, (char)0x015a); // XK_Sacute --> LATIN CAPITAL LETTER S WITH ACUTE
@@ -1575,8 +1680,16 @@
keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mute_asciicircum), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_DEAD_CIRCUMFLEX, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mute_diaeresis), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_DEAD_DIAERESIS, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
keysym2JavaKeycodeHash.put( Long.valueOf(XKeySymConstants.hpXK_mute_asciitilde), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_DEAD_TILDE, java.awt.event.KeyEvent.KEY_LOCATION_STANDARD));
keysym2JavaKeycodeHash.put( Long.valueOf(XConstants.NoSymbol), new Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN));
+
+ /* Reverse search of keysym by keycode. */
+
+ /* Add keyboard locking codes. */
+ javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_CAPS_LOCK, XKeySymConstants.XK_Caps_Lock);
+ javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_NUM_LOCK, XKeySymConstants.XK_Num_Lock);
+ javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_SCROLL_LOCK, XKeySymConstants.XK_Scroll_Lock);
+ javaKeycode2KeysymHash.put( java.awt.event.KeyEvent.VK_KANA_LOCK, XKeySymConstants.XK_Kana_Lock);
};
}
< prev index next >