< 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 **** // 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. * 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 --- 1,9 ---- // This is a generated file: do not edit! Edit keysym2ucs.h if necessary. /* ! * 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,72 **** --- 61,76 ---- 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,107 **** return (char)(ks & 0x00ffffff); Character ch = keysym2UCSHash.get(ks); return ch == null ? (char)0 : ch.charValue(); } static long xkeycode2keysym(XKeyEvent ev, int ndx) { XToolkit.awtLock(); try { ! return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx ); } finally { XToolkit.awtUnlock(); } } 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() && ! XToolkit.isXKBenabled() ? 2 : 1; XToolkit.awtLock(); try { return XlibWrapper.IsKeypadKey( XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx ) ); --- 89,144 ---- 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 { ! 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.isXsunKPBehavior() && ! XToolkit.isXKBenabled() ? 2 : 1; XToolkit.awtLock(); try { return XlibWrapper.IsKeypadKey( XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx ) );
*** 140,150 **** 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() && ! XToolkit.isXKBenabled() ) { if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on ndx = 3; keysym = xkeycode2keysym(ev, ndx); } else { --- 177,187 ---- 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.isXsunKPBehavior() && ! XToolkit.isXKBenabled() ) { if( (ev.get_state() & XConstants.ShiftMask) != 0 ) { // shift modifier is on ndx = 3; keysym = xkeycode2keysym(ev, ndx); } else {
*** 162,177 **** keysym = xkeycode2keysym(ev, ndx); } } return 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; --- 199,237 ---- 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. */ static Keysym2JavaKeycode getJavaKeycode( XKeyEvent ev ) { // get from keysym2JavaKeycodeHash. long keysym = XConstants.NoSymbol; int ndx = 0;
*** 182,199 **** // we only need primary-layer keysym to derive a java keycode. ndx = 0; keysym = xkeycode2keysym(ev, ndx); } ! Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym ); return jkc; } static int getJavaKeycodeOnly( XKeyEvent ev ) { Keysym2JavaKeycode jkc = getJavaKeycode( ev ); return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode(); } /** 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 --- 242,284 ---- // we only need primary-layer keysym to derive a java keycode. ndx = 0; keysym = xkeycode2keysym(ev, ndx); } ! 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,285 **** --- 361,390 ---- 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,1582 **** --- 1680,1695 ---- 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 >