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
--- a/jdk/make/sun/awt/FILES_export_unix.gmk Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/make/sun/awt/FILES_export_unix.gmk Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
#
-# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -107,7 +107,8 @@
sun/java2d/x11/X11Renderer.java \
sun/java2d/x11/X11SurfaceData.java \
com/sun/java/swing/plaf/gtk/GTKEngine.java \
- com/sun/java/swing/plaf/gtk/GTKStyle.java
+ com/sun/java/swing/plaf/gtk/GTKStyle.java \
+ sun/awt/ExtendedKeyCodes.java
FILES_export2 = \
--- a/jdk/make/sun/awt/FILES_export_windows.gmk Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/make/sun/awt/FILES_export_windows.gmk Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
#
-# Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -154,7 +154,7 @@
sun/awt/datatransfer/DataTransferer.java \
sun/awt/datatransfer/SunClipboard.java \
sun/awt/dnd/SunDragSourceContextPeer.java \
- sun/awt/windows/WToolkitThreadBlockedHandler.java
+ sun/awt/windows/WToolkitThreadBlockedHandler.java
FILES_export3 = \
java/awt/CheckboxMenuItem.java \
@@ -214,6 +214,7 @@
sun/awt/windows/WBufferStrategy.java \
sun/awt/windows/WTrayIconPeer.java \
sun/awt/image/ImagingLib.java \
+ sun/awt/ExtendedKeyCodes.java \
sun/java2d/pipe/hw/AccelSurface.java \
sun/java2d/pipe/hw/AccelDeviceEventNotifier.java \
sun/java2d/pipe/hw/ContextCapabilities.java \
--- a/jdk/make/sun/xawt/mapfile-vers Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/make/sun/xawt/mapfile-vers Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
#
-# Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2002-2009 Sun Microsystems, Inc. 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
@@ -293,16 +293,26 @@
Java_sun_awt_X11_XlibWrapper_XGetIconSizes;
Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym;
Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode;
- Java_sun_awt_X11_XlibWrapper_XQueryKeymap;
+ Java_sun_awt_X11_XlibWrapper_XQueryKeymap;
+ Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup;
+ Java_sun_awt_X11_XlibWrapper_XkbSelectEvents;
+ Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails;
+ Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym;
+ Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion;
+ Java_sun_awt_X11_XlibWrapper_XkbQueryExtension;
+ Java_sun_awt_X11_XlibWrapper_XkbGetMap;
+ Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap;
+ Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard;
+ Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode;
Java_sun_awt_X11_XlibWrapper_XGetModifierMapping;
- Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
+ Java_sun_awt_X11_XlibWrapper_XFreeModifiermap;
Java_sun_awt_X11_XlibWrapper_XChangeActivePointerGrab;
Java_sun_awt_X11_XlibWrapper_XNextSecondaryLoopEvent;
Java_sun_awt_X11_XlibWrapper_ExitSecondaryLoop;
Java_sun_awt_X11_XlibWrapper_XTextPropertyToStringList;
Java_sun_awt_X11_XlibWrapper_XGrabServer;
Java_sun_awt_X11_XlibWrapper_XUngrabServer;
- Java_sun_awt_X11_XlibWrapper_XPutBackEvent;
+ Java_sun_awt_X11_XlibWrapper_XPutBackEvent;
Java_sun_awt_X11_XlibWrapper_XConvertCase;
Java_sun_awt_X11_XlibWrapper_XSynchronize;
Java_java_awt_FileDialog_initIDs;
--- a/jdk/src/share/classes/java/awt/AWTKeyStroke.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/java/awt/AWTKeyStroke.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -329,6 +329,9 @@
* <li><code>java.awt.event.KeyEvent.VK_TAB</code>
* <li><code>java.awt.event.KeyEvent.VK_SPACE</code>
* </ul>
+ * Alternatively, the key code may be obtained by calling
+ * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
+ *
* The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
--- a/jdk/src/share/classes/java/awt/MenuItem.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/java/awt/MenuItem.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1995-2009 Sun Microsystems, Inc. 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
@@ -398,9 +398,11 @@
boolean handleShortcut(KeyEvent e) {
MenuShortcut s = new MenuShortcut(e.getKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
+ MenuShortcut sE = new MenuShortcut(e.getExtendedKeyCode(),
+ (e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
// Fix For 6185151: Menu shortcuts of all menuitems within a menu
// should be disabled when the menu itself is disabled
- if (s.equals(shortcut) && isItemEnabled()) {
+ if ((s.equals(shortcut) || sE.equals(shortcut)) && isItemEnabled()) {
// MenuShortcut match -- issue an event on keydown.
if (e.getID() == KeyEvent.KEY_PRESSED) {
doMenuEvent(e.getWhen(), e.getModifiers());
--- a/jdk/src/share/classes/java/awt/MenuShortcut.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/java/awt/MenuShortcut.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. 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
@@ -34,7 +34,21 @@
* For example, a menu shortcut for Ctrl-a (assuming that Control is
* the accelerator key) would be created with code like the following:
* <p>
- * MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);
+ * <code>MenuShortcut ms = new MenuShortcut(KeyEvent.VK_A, false);</code>
+ * <p> or alternatively
+ * <p>
+ * <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('A'), false);</code>
+ * <p>
+ * Menu shortcuts may also be constructed for a wider set of keycodes
+ * using the <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code> call.
+ * For example, a menu shortcut for "Ctrl+cyrillic ef" is created by
+ * <p>
+ * <code>MenuShortcut ms = new MenuShortcut(KeyEvent.getExtendedKeyCodeForChar('\u0444'), false);</code>
+ * <p>
+ * Note that shortcuts created with a keycode or an extended keycode defined as a constant in <code>KeyEvent</code>
+ * work regardless of the current keyboard layout. However, a shortcut made of
+ * an extended keycode not listed in <code>KeyEvent</code>
+ * only work if the current keyboard layout produces a corresponding letter.
* <p>
* The accelerator key is platform-dependent and may be obtained
* via {@link Toolkit#getMenuShortcutKeyMask}.
--- a/jdk/src/share/classes/java/awt/event/KeyEvent.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/java/awt/event/KeyEvent.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-2009 Sun Microsystems, Inc. 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
@@ -65,15 +65,16 @@
* <p>
* For key pressed and key released events, the getKeyCode method returns
* the event's keyCode. For key typed events, the getKeyCode method
- * always returns VK_UNDEFINED.
+ * always returns {@code VK_UNDEFINED}. The {@code getExtendedKeyCode} method
+ * may also be used with many international keyboard layouts.
*
* <p>
* <em>"Key pressed" and "key released" events</em> are lower-level and depend
* on the platform and keyboard layout. They are generated whenever a key is
* pressed or released, and are the only way to find out about keys that don't
* generate character input (e.g., action keys, modifier keys, etc.). The key
- * being pressed or released is indicated by the getKeyCode method, which returns
- * a virtual key code.
+ * being pressed or released is indicated by the {@code getKeyCode} and {@code getExtendedKeyCode}
+ * methods, which return a virtual key code.
*
* <p>
* <em>Virtual key codes</em> are used to report which keyboard key has
@@ -111,6 +112,11 @@
* platform and keyboard layout. For example, the key that generates VK_Q
* when using a U.S. keyboard layout will generate VK_A when using a French
* keyboard layout.
+ * <li>The key that generates {@code VK_Q} when using a U.S. keyboard layout also
+ * generates a unique code for Russian or Hebrew layout. There is no a
+ * {@code VK_} constant for these and many other codes in various layouts. These codes
+ * may be obtained by using {@code getExtendedKeyCode} and are used whenever
+ * a {@code VK_} constant is used.
* <li>Not all characters have a keycode associated with them. For example,
* there is no keycode for the question mark because there is no keyboard
* for which it appears on the primary layer.
@@ -891,6 +897,12 @@
*/
int keyLocation;
+ //set from native code.
+ private transient long rawCode = 0;
+ private transient long primaryLevelUnicode = 0;
+ private transient long scancode = 0; // for MS Windows only
+ private transient long extendedKeyCode = 0;
+
/*
* JDK 1.1 serialVersionUID
*/
@@ -1315,6 +1327,9 @@
return numpad + "-" + c;
}
+ if ((keyCode & 0x01000000) != 0) {
+ return String.valueOf((char)(keyCode ^ 0x01000000 ));
+ }
String unknown = Toolkit.getProperty("AWT.unknown", "Unknown");
return unknown + " keyCode: 0x" + Integer.toString(keyCode, 16);
}
@@ -1551,9 +1566,44 @@
str.append("KEY_LOCATION_UNKNOWN");
break;
}
+ str.append(",rawCode=").append(rawCode);
+ str.append(",primaryLevelUnicode=").append(primaryLevelUnicode);
+ str.append(",scancode=").append(scancode);
+ str.append(",extendedKeyCode=0x").append(Long.toHexString(extendedKeyCode));
return str.toString();
}
+ /**
+ * Returns an extended key code for the event.
+ * The extended key code is a unique id assigned to a key on the keyboard
+ * just like {@code keyCode}. However, unlike {@code keyCode}, this value depends on the
+ * current keyboard layout. For instance, pressing the left topmost letter key
+ * in a common English layout produces the same value as {@code keyCode}, {@code VK_Q}.
+ * Pressing the same key in a regular Russian layout gives another code, unique for the
+ * letter "Cyrillic I short".
+ *
+ * @since 1.7
+ *
+ */
+ public int getExtendedKeyCode() {
+ return (int)extendedKeyCode;
+ }
+ /**
+ * Returns an extended key code for a unicode character.
+ *
+ * @return for a unicode character with a corresponding {@code VK_} constant -- this
+ * {@code VK_} constant; for a character appearing on the primary
+ * level of a known keyboard layout -- a unique integer.
+ * If a character does not appear on the primary level of a known keyboard,
+ * {@code VK_UNDEFINED} is returned.
+ *
+ * @since 1.7
+ *
+ */
+ public static int getExtendedKeyCodeForChar(int c) {
+ // Return a keycode (if any) associated with a character.
+ return sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(c);
+ }
/**
* Sets new modifiers by the old ones. The key modifiers
--- a/jdk/src/share/classes/javax/swing/AbstractButton.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/AbstractButton.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -1545,6 +1545,9 @@
* A mnemonic must correspond to a single key on the keyboard
* and should be specified using one of the <code>VK_XXX</code>
* keycodes defined in <code>java.awt.event.KeyEvent</code>.
+ * These codes and the wider array of codes for international
+ * keyboards may be obtained through
+ * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
* Mnemonics are case-insensitive, therefore a key event
* with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed.
--- a/jdk/src/share/classes/javax/swing/Action.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/Action.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -272,7 +272,9 @@
* one of the <code>KeyEvent</code> key codes. The value is
* commonly used to specify a mnemonic. For example:
* <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_A)</code>
- * sets the mnemonic of <code>myAction</code> to 'a'.
+ * sets the mnemonic of <code>myAction</code> to 'a', while
+ * <code>myAction.putValue(Action.MNEMONIC_KEY, KeyEvent.getExtendedKeyCodeForChar('\u0444'))</code>
+ * sets the mnemonic of <code>myAction</code> to Cyrillic letter "Ef".
*
* @since 1.3
*/
--- a/jdk/src/share/classes/javax/swing/JComponent.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -2888,7 +2888,10 @@
return false;
}
// Get the KeyStroke
+ // There may be two keystrokes associated with a low-level key event;
+ // in this case a keystroke made of an extended key code has a priority.
KeyStroke ks;
+ KeyStroke ksE = null;
if (e.getID() == KeyEvent.KEY_TYPED) {
ks = KeyStroke.getKeyStroke(e.getKeyChar());
@@ -2896,9 +2899,18 @@
else {
ks = KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
(pressed ? false:true));
+ if (e.getKeyCode() != e.getExtendedKeyCode()) {
+ ksE = KeyStroke.getKeyStroke(e.getExtendedKeyCode(),e.getModifiers(),
+ (pressed ? false:true));
+ }
}
- /* Do we have a key binding for e? */
+ // Do we have a key binding for e?
+ // If we have a binding by an extended code, use it.
+ // If not, check for regular code binding.
+ if(ksE != null && processKeyBinding(ksE, e, WHEN_FOCUSED, pressed)) {
+ return true;
+ }
if(processKeyBinding(ks, e, WHEN_FOCUSED, pressed))
return true;
@@ -2910,6 +2922,9 @@
while (parent != null && !(parent instanceof Window) &&
!(parent instanceof Applet)) {
if(parent instanceof JComponent) {
+ if(ksE != null && ((JComponent)parent).processKeyBinding(ksE, e,
+ WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
+ return true;
if(((JComponent)parent).processKeyBinding(ks, e,
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, pressed))
return true;
--- a/jdk/src/share/classes/javax/swing/JLabel.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/JLabel.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -503,10 +503,10 @@
* @see #setDisplayedMnemonic(int)
*/
public void setDisplayedMnemonic(char aChar) {
- int vk = (int) aChar;
- if(vk >= 'a' && vk <='z')
- vk -= ('a' - 'A');
- setDisplayedMnemonic(vk);
+ int vk = java.awt.event.KeyEvent.getExtendedKeyCodeForChar(aChar);
+ if (vk != java.awt.event.KeyEvent.VK_UNDEFINED) {
+ setDisplayedMnemonic(vk);
+ }
}
--- a/jdk/src/share/classes/javax/swing/JTabbedPane.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/JTabbedPane.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -1628,7 +1628,9 @@
* <p>
* A mnemonic must correspond to a single key on the keyboard
* and should be specified using one of the <code>VK_XXX</code>
- * keycodes defined in <code>java.awt.event.KeyEvent</code>.
+ * keycodes defined in <code>java.awt.event.KeyEvent</code>
+ * or one of the extended keycodes obtained through
+ * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
* Mnemonics are case-insensitive, therefore a key event
* with the corresponding keycode would cause the button to be
* activated whether or not the Shift modifier was pressed.
--- a/jdk/src/share/classes/javax/swing/KeyStroke.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/KeyStroke.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -162,6 +162,9 @@
* <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE
* </ul>
+ * Alternatively, the key code may be obtained by calling
+ * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
+ *
* The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
@@ -210,6 +213,9 @@
* <li>java.awt.event.KeyEvent.VK_TAB
* <li>java.awt.event.KeyEvent.VK_SPACE
* </ul>
+ * Alternatively, the key code may be obtained by calling
+ * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
+ *
* The modifiers consist of any combination of:<ul>
* <li>java.awt.event.InputEvent.SHIFT_DOWN_MASK
* <li>java.awt.event.InputEvent.CTRL_DOWN_MASK
--- a/jdk/src/share/classes/javax/swing/KeyboardManager.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/KeyboardManager.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc. 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
@@ -212,19 +212,35 @@
Thread.dumpStack();
}
+ // There may be two keystrokes associated with a low-level key event;
+ // in this case a keystroke made of an extended key code has a priority.
KeyStroke ks;
+ KeyStroke ksE = null;
if(e.getID() == KeyEvent.KEY_TYPED) {
ks=KeyStroke.getKeyStroke(e.getKeyChar());
} else {
+ if(e.getKeyCode() != e.getExtendedKeyCode()) {
+ ksE=KeyStroke.getKeyStroke(e.getExtendedKeyCode(), e.getModifiers(), !pressed);
+ }
ks=KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers(), !pressed);
}
Hashtable keyMap = containerMap.get(topAncestor);
if (keyMap != null) { // this container isn't registered, so bail
- Object tmp = keyMap.get(ks);
+ Object tmp = null;
+ // extended code has priority
+ if( ksE != null ) {
+ tmp = keyMap.get(ksE);
+ if( tmp != null ) {
+ ks = ksE;
+ }
+ }
+ if( tmp == null ) {
+ tmp = keyMap.get(ks);
+ }
if (tmp == null) {
// don't do anything
@@ -269,7 +285,12 @@
while (iter.hasMoreElements()) {
JMenuBar mb = (JMenuBar)iter.nextElement();
if ( mb.isShowing() && mb.isEnabled() ) { // don't want to give these out
- fireBinding(mb, ks, e, pressed);
+ if( !(ks.equals(ksE)) ) {
+ fireBinding(mb, ksE, e, pressed);
+ }
+ if(ks.equals(ksE) || !e.isConsumed()) {
+ fireBinding(mb, ks, e, pressed);
+ }
if (e.isConsumed()) {
return true;
}
--- a/jdk/src/share/classes/javax/swing/SwingUtilities.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -1589,15 +1589,6 @@
* processing the key bindings associated with JComponents.
*/
static boolean isValidKeyEventForKeyBindings(KeyEvent e) {
- if (e.getID() == KeyEvent.KEY_TYPED) {
- int mod = e.getModifiers();
- if (((mod & ActionEvent.ALT_MASK) != 0) &&
- ((mod & ActionEvent.CTRL_MASK) == 0)) {
- // filter out typed "alt-?" keys, but not those created
- // with AltGr, and not control characters
- return false;
- }
- }
return true;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java Fri Mar 27 12:01:24 2009 +0300
@@ -0,0 +1,670 @@
+package sun.awt;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.awt.event.KeyEvent;
+
+public class ExtendedKeyCodes {
+ /**
+ * ATTN: These are the readonly hashes with load factor == 1;
+ * adding a value, please set the inital capacity to exact number of items
+ * or higher.
+ */
+ // Keycodes declared in KeyEvent.java with corresponding Unicode values.
+ private final static HashMap<Integer, Integer> regularKeyCodesMap =
+ new HashMap<Integer,Integer>(122, 1.0f);
+
+ // Keycodes derived from Unicode values. Here should be collected codes
+ // for characters appearing on the primary layer of at least one
+ // known keyboard layout. For instance, sterling sign is on the primary layer
+ // of the Mac Italian layout.
+ private final static HashSet<Integer> extendedKeyCodesSet =
+ new HashSet<Integer>(501, 1.0f);
+ final public static int getExtendedKeyCodeForChar( int c ) {
+ int rc = KeyEvent.VK_UNDEFINED;
+ int uc = Character.toUpperCase( c );
+ int lc = Character.toLowerCase( c );
+ if (regularKeyCodesMap.containsKey( c )) {
+ if(regularKeyCodesMap.containsKey(uc)) {
+ return regularKeyCodesMap.get( uc );
+ }
+ return regularKeyCodesMap.get( c );
+ }
+ uc += 0x01000000;
+ lc += 0x01000000;
+ if (extendedKeyCodesSet.contains( uc )) {
+ return uc;
+ }else if (extendedKeyCodesSet.contains( lc )) {
+ return lc;
+ }
+ return rc;
+ }
+ static {
+ regularKeyCodesMap.put(0x0a, KeyEvent.VK_ENTER);
+ regularKeyCodesMap.put(0x08, KeyEvent.VK_BACK_SPACE);
+ regularKeyCodesMap.put(0x09, KeyEvent.VK_TAB);
+ regularKeyCodesMap.put(0x1B, KeyEvent.VK_ESCAPE);
+ regularKeyCodesMap.put(0x20, KeyEvent.VK_SPACE);
+ regularKeyCodesMap.put(0x21, KeyEvent.VK_PAGE_UP);
+ regularKeyCodesMap.put(0x22, KeyEvent.VK_PAGE_DOWN);
+ regularKeyCodesMap.put(0x23, KeyEvent.VK_END);
+ regularKeyCodesMap.put(0x24, KeyEvent.VK_HOME);
+ regularKeyCodesMap.put(0x25, KeyEvent.VK_LEFT);
+ regularKeyCodesMap.put(0x26, KeyEvent.VK_UP);
+ regularKeyCodesMap.put(0x27, KeyEvent.VK_RIGHT);
+ regularKeyCodesMap.put(0x28, KeyEvent.VK_DOWN);
+ regularKeyCodesMap.put(0x2C, KeyEvent.VK_COMMA);
+ regularKeyCodesMap.put(0x2D, KeyEvent.VK_MINUS);
+ regularKeyCodesMap.put(0x2E, KeyEvent.VK_PERIOD);
+ regularKeyCodesMap.put(0x2F, KeyEvent.VK_SLASH);
+ regularKeyCodesMap.put(0x30, KeyEvent.VK_0);
+ regularKeyCodesMap.put(0x31, KeyEvent.VK_1);
+ regularKeyCodesMap.put(0x32, KeyEvent.VK_2);
+ regularKeyCodesMap.put(0x33, KeyEvent.VK_3);
+ regularKeyCodesMap.put(0x34, KeyEvent.VK_4);
+ regularKeyCodesMap.put(0x35, KeyEvent.VK_5);
+ regularKeyCodesMap.put(0x36, KeyEvent.VK_6);
+ regularKeyCodesMap.put(0x37, KeyEvent.VK_7);
+ regularKeyCodesMap.put(0x38, KeyEvent.VK_8);
+ regularKeyCodesMap.put(0x39, KeyEvent.VK_9);
+ regularKeyCodesMap.put(0x3B, KeyEvent.VK_SEMICOLON);
+ regularKeyCodesMap.put(0x3D, KeyEvent.VK_EQUALS);
+ regularKeyCodesMap.put(0x41, KeyEvent.VK_A);
+ regularKeyCodesMap.put(0x61, KeyEvent.VK_A);
+ regularKeyCodesMap.put(0x42, KeyEvent.VK_B);
+ regularKeyCodesMap.put(0x62, KeyEvent.VK_B);
+ regularKeyCodesMap.put(0x43, KeyEvent.VK_C);
+ regularKeyCodesMap.put(0x63, KeyEvent.VK_C);
+ regularKeyCodesMap.put(0x44, KeyEvent.VK_D);
+ regularKeyCodesMap.put(0x64, KeyEvent.VK_D);
+ regularKeyCodesMap.put(0x45, KeyEvent.VK_E);
+ regularKeyCodesMap.put(0x65, KeyEvent.VK_E);
+ regularKeyCodesMap.put(0x46, KeyEvent.VK_F);
+ regularKeyCodesMap.put(0x66, KeyEvent.VK_F);
+ regularKeyCodesMap.put(0x47, KeyEvent.VK_G);
+ regularKeyCodesMap.put(0x67, KeyEvent.VK_G);
+ regularKeyCodesMap.put(0x48, KeyEvent.VK_H);
+ regularKeyCodesMap.put(0x68, KeyEvent.VK_H);
+ regularKeyCodesMap.put(0x49, KeyEvent.VK_I);
+ regularKeyCodesMap.put(0x69, KeyEvent.VK_I);
+ regularKeyCodesMap.put(0x4A, KeyEvent.VK_J);
+ regularKeyCodesMap.put(0x6A, KeyEvent.VK_J);
+ regularKeyCodesMap.put(0x4B, KeyEvent.VK_K);
+ regularKeyCodesMap.put(0x6B, KeyEvent.VK_K);
+ regularKeyCodesMap.put(0x4C, KeyEvent.VK_L);
+ regularKeyCodesMap.put(0x6C, KeyEvent.VK_L);
+ regularKeyCodesMap.put(0x4D, KeyEvent.VK_M);
+ regularKeyCodesMap.put(0x6D, KeyEvent.VK_M);
+ regularKeyCodesMap.put(0x4E, KeyEvent.VK_N);
+ regularKeyCodesMap.put(0x6E, KeyEvent.VK_N);
+ regularKeyCodesMap.put(0x4F, KeyEvent.VK_O);
+ regularKeyCodesMap.put(0x6F, KeyEvent.VK_O);
+ regularKeyCodesMap.put(0x50, KeyEvent.VK_P);
+ regularKeyCodesMap.put(0x70, KeyEvent.VK_P);
+ regularKeyCodesMap.put(0x51, KeyEvent.VK_Q);
+ regularKeyCodesMap.put(0x71, KeyEvent.VK_Q);
+ regularKeyCodesMap.put(0x52, KeyEvent.VK_R);
+ regularKeyCodesMap.put(0x72, KeyEvent.VK_R);
+ regularKeyCodesMap.put(0x53, KeyEvent.VK_S);
+ regularKeyCodesMap.put(0x73, KeyEvent.VK_S);
+ regularKeyCodesMap.put(0x54, KeyEvent.VK_T);
+ regularKeyCodesMap.put(0x74, KeyEvent.VK_T);
+ regularKeyCodesMap.put(0x55, KeyEvent.VK_U);
+ regularKeyCodesMap.put(0x75, KeyEvent.VK_U);
+ regularKeyCodesMap.put(0x56, KeyEvent.VK_V);
+ regularKeyCodesMap.put(0x76, KeyEvent.VK_V);
+ regularKeyCodesMap.put(0x57, KeyEvent.VK_W);
+ regularKeyCodesMap.put(0x77, KeyEvent.VK_W);
+ regularKeyCodesMap.put(0x58, KeyEvent.VK_X);
+ regularKeyCodesMap.put(0x78, KeyEvent.VK_X);
+ regularKeyCodesMap.put(0x59, KeyEvent.VK_Y);
+ regularKeyCodesMap.put(0x79, KeyEvent.VK_Y);
+ regularKeyCodesMap.put(0x5A, KeyEvent.VK_Z);
+ regularKeyCodesMap.put(0x7A, KeyEvent.VK_Z);
+ regularKeyCodesMap.put(0x5B, KeyEvent.VK_OPEN_BRACKET);
+ regularKeyCodesMap.put(0x5C, KeyEvent.VK_BACK_SLASH);
+ regularKeyCodesMap.put(0x5D, KeyEvent.VK_CLOSE_BRACKET);
+// regularKeyCodesMap.put(0x60, KeyEvent.VK_NUMPAD0);
+// regularKeyCodesMap.put(0x61, KeyEvent.VK_NUMPAD1);
+// regularKeyCodesMap.put(0x62, KeyEvent.VK_NUMPAD2);
+// regularKeyCodesMap.put(0x63, KeyEvent.VK_NUMPAD3);
+// regularKeyCodesMap.put(0x64, KeyEvent.VK_NUMPAD4);
+// regularKeyCodesMap.put(0x65, KeyEvent.VK_NUMPAD5);
+// regularKeyCodesMap.put(0x66, KeyEvent.VK_NUMPAD6);
+// regularKeyCodesMap.put(0x67, KeyEvent.VK_NUMPAD7);
+// regularKeyCodesMap.put(0x68, KeyEvent.VK_NUMPAD8);
+// regularKeyCodesMap.put(0x69, KeyEvent.VK_NUMPAD9);
+ regularKeyCodesMap.put(0x6A, KeyEvent.VK_MULTIPLY);
+ regularKeyCodesMap.put(0x6B, KeyEvent.VK_ADD);
+ regularKeyCodesMap.put(0x6C, KeyEvent.VK_SEPARATER);
+ regularKeyCodesMap.put(0x6D, KeyEvent.VK_SUBTRACT);
+ regularKeyCodesMap.put(0x6E, KeyEvent.VK_DECIMAL);
+ regularKeyCodesMap.put(0x6F, KeyEvent.VK_DIVIDE);
+ regularKeyCodesMap.put(0x7F, KeyEvent.VK_DELETE);
+ regularKeyCodesMap.put(0xC0, KeyEvent.VK_BACK_QUOTE);
+ regularKeyCodesMap.put(0xDE, KeyEvent.VK_QUOTE);
+ regularKeyCodesMap.put(0x26, KeyEvent.VK_AMPERSAND);
+ regularKeyCodesMap.put(0x2A, KeyEvent.VK_ASTERISK);
+ regularKeyCodesMap.put(0x22, KeyEvent.VK_QUOTEDBL);
+ regularKeyCodesMap.put(0x3C, KeyEvent.VK_LESS);
+ regularKeyCodesMap.put(0x3E, KeyEvent.VK_GREATER);
+ regularKeyCodesMap.put(0x7B, KeyEvent.VK_BRACELEFT);
+ regularKeyCodesMap.put(0x7D, KeyEvent.VK_BRACERIGHT);
+ regularKeyCodesMap.put(0x40, KeyEvent.VK_AT);
+ regularKeyCodesMap.put(0x3A, KeyEvent.VK_COLON);
+ regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX);
+ regularKeyCodesMap.put(0x24, KeyEvent.VK_DOLLAR);
+ regularKeyCodesMap.put(0x20AC, KeyEvent.VK_EURO_SIGN);
+ regularKeyCodesMap.put(0x21, KeyEvent.VK_EXCLAMATION_MARK);
+ regularKeyCodesMap.put(0xA1, KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
+ regularKeyCodesMap.put(0x28, KeyEvent.VK_LEFT_PARENTHESIS);
+ regularKeyCodesMap.put(0x23, KeyEvent.VK_NUMBER_SIGN);
+ regularKeyCodesMap.put(0x2B, KeyEvent.VK_PLUS);
+ regularKeyCodesMap.put(0x29, KeyEvent.VK_RIGHT_PARENTHESIS);
+ regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE);
+
+
+ extendedKeyCodesSet.add(0x01000000+0x0060);
+ extendedKeyCodesSet.add(0x01000000+0x007C);
+ extendedKeyCodesSet.add(0x01000000+0x007E);
+ extendedKeyCodesSet.add(0x01000000+0x00A2);
+ extendedKeyCodesSet.add(0x01000000+0x00A3);
+ extendedKeyCodesSet.add(0x01000000+0x00A5);
+ extendedKeyCodesSet.add(0x01000000+0x00A7);
+ extendedKeyCodesSet.add(0x01000000+0x00A8);
+ extendedKeyCodesSet.add(0x01000000+0x00AB);
+ extendedKeyCodesSet.add(0x01000000+0x00B0);
+ extendedKeyCodesSet.add(0x01000000+0x00B1);
+ extendedKeyCodesSet.add(0x01000000+0x00B2);
+ extendedKeyCodesSet.add(0x01000000+0x00B3);
+ extendedKeyCodesSet.add(0x01000000+0x00B4);
+ extendedKeyCodesSet.add(0x01000000+0x00B5);
+ extendedKeyCodesSet.add(0x01000000+0x00B6);
+ extendedKeyCodesSet.add(0x01000000+0x00B7);
+ extendedKeyCodesSet.add(0x01000000+0x00B9);
+ extendedKeyCodesSet.add(0x01000000+0x00BA);
+ extendedKeyCodesSet.add(0x01000000+0x00BB);
+ extendedKeyCodesSet.add(0x01000000+0x00BC);
+ extendedKeyCodesSet.add(0x01000000+0x00BD);
+ extendedKeyCodesSet.add(0x01000000+0x00BE);
+ extendedKeyCodesSet.add(0x01000000+0x00BF);
+ extendedKeyCodesSet.add(0x01000000+0x00C4);
+ extendedKeyCodesSet.add(0x01000000+0x00C5);
+ extendedKeyCodesSet.add(0x01000000+0x00C6);
+ extendedKeyCodesSet.add(0x01000000+0x00C7);
+ extendedKeyCodesSet.add(0x01000000+0x00D1);
+ extendedKeyCodesSet.add(0x01000000+0x00D6);
+ extendedKeyCodesSet.add(0x01000000+0x00D7);
+ extendedKeyCodesSet.add(0x01000000+0x00D8);
+ extendedKeyCodesSet.add(0x01000000+0x00DF);
+ extendedKeyCodesSet.add(0x01000000+0x00E0);
+ extendedKeyCodesSet.add(0x01000000+0x00E1);
+ extendedKeyCodesSet.add(0x01000000+0x00E2);
+ extendedKeyCodesSet.add(0x01000000+0x00E4);
+ extendedKeyCodesSet.add(0x01000000+0x00E5);
+ extendedKeyCodesSet.add(0x01000000+0x00E6);
+ extendedKeyCodesSet.add(0x01000000+0x00E7);
+ extendedKeyCodesSet.add(0x01000000+0x00E8);
+ extendedKeyCodesSet.add(0x01000000+0x00E9);
+ extendedKeyCodesSet.add(0x01000000+0x00EA);
+ extendedKeyCodesSet.add(0x01000000+0x00EB);
+ extendedKeyCodesSet.add(0x01000000+0x00EC);
+ extendedKeyCodesSet.add(0x01000000+0x00ED);
+ extendedKeyCodesSet.add(0x01000000+0x00EE);
+ extendedKeyCodesSet.add(0x01000000+0x00F0);
+ extendedKeyCodesSet.add(0x01000000+0x00F1);
+ extendedKeyCodesSet.add(0x01000000+0x00F2);
+ extendedKeyCodesSet.add(0x01000000+0x00F3);
+ extendedKeyCodesSet.add(0x01000000+0x00F4);
+ extendedKeyCodesSet.add(0x01000000+0x00F5);
+ extendedKeyCodesSet.add(0x01000000+0x00F6);
+ extendedKeyCodesSet.add(0x01000000+0x00F7);
+ extendedKeyCodesSet.add(0x01000000+0x00F8);
+ extendedKeyCodesSet.add(0x01000000+0x00F9);
+ extendedKeyCodesSet.add(0x01000000+0x00FA);
+ extendedKeyCodesSet.add(0x01000000+0x00FB);
+ extendedKeyCodesSet.add(0x01000000+0x00FC);
+ extendedKeyCodesSet.add(0x01000000+0x00FD);
+ extendedKeyCodesSet.add(0x01000000+0x00FE);
+ extendedKeyCodesSet.add(0x01000000+0x0105);
+ extendedKeyCodesSet.add(0x01000000+0x02DB);
+ extendedKeyCodesSet.add(0x01000000+0x0142);
+ extendedKeyCodesSet.add(0x01000000+0x013E);
+ extendedKeyCodesSet.add(0x01000000+0x015B);
+ extendedKeyCodesSet.add(0x01000000+0x0161);
+ extendedKeyCodesSet.add(0x01000000+0x015F);
+ extendedKeyCodesSet.add(0x01000000+0x0165);
+ extendedKeyCodesSet.add(0x01000000+0x017E);
+ extendedKeyCodesSet.add(0x01000000+0x017C);
+ extendedKeyCodesSet.add(0x01000000+0x0103);
+ extendedKeyCodesSet.add(0x01000000+0x0107);
+ extendedKeyCodesSet.add(0x01000000+0x010D);
+ extendedKeyCodesSet.add(0x01000000+0x0119);
+ extendedKeyCodesSet.add(0x01000000+0x011B);
+ extendedKeyCodesSet.add(0x01000000+0x0111);
+ extendedKeyCodesSet.add(0x01000000+0x0148);
+ extendedKeyCodesSet.add(0x01000000+0x0151);
+ extendedKeyCodesSet.add(0x01000000+0x0171);
+ extendedKeyCodesSet.add(0x01000000+0x0159);
+ extendedKeyCodesSet.add(0x01000000+0x016F);
+ extendedKeyCodesSet.add(0x01000000+0x0163);
+ extendedKeyCodesSet.add(0x01000000+0x02D9);
+ extendedKeyCodesSet.add(0x01000000+0x0130);
+ extendedKeyCodesSet.add(0x01000000+0x0127);
+ extendedKeyCodesSet.add(0x01000000+0x0125);
+ extendedKeyCodesSet.add(0x01000000+0x0131);
+ extendedKeyCodesSet.add(0x01000000+0x011F);
+ extendedKeyCodesSet.add(0x01000000+0x0135);
+ extendedKeyCodesSet.add(0x01000000+0x010B);
+ extendedKeyCodesSet.add(0x01000000+0x0109);
+ extendedKeyCodesSet.add(0x01000000+0x0121);
+ extendedKeyCodesSet.add(0x01000000+0x011D);
+ extendedKeyCodesSet.add(0x01000000+0x016D);
+ extendedKeyCodesSet.add(0x01000000+0x015D);
+ extendedKeyCodesSet.add(0x01000000+0x0138);
+ extendedKeyCodesSet.add(0x01000000+0x0157);
+ extendedKeyCodesSet.add(0x01000000+0x013C);
+ extendedKeyCodesSet.add(0x01000000+0x0113);
+ extendedKeyCodesSet.add(0x01000000+0x0123);
+ extendedKeyCodesSet.add(0x01000000+0x0167);
+ extendedKeyCodesSet.add(0x01000000+0x014B);
+ extendedKeyCodesSet.add(0x01000000+0x0101);
+ extendedKeyCodesSet.add(0x01000000+0x012F);
+ extendedKeyCodesSet.add(0x01000000+0x0117);
+ extendedKeyCodesSet.add(0x01000000+0x012B);
+ extendedKeyCodesSet.add(0x01000000+0x0146);
+ extendedKeyCodesSet.add(0x01000000+0x014D);
+ extendedKeyCodesSet.add(0x01000000+0x0137);
+ extendedKeyCodesSet.add(0x01000000+0x0173);
+ extendedKeyCodesSet.add(0x01000000+0x016B);
+ extendedKeyCodesSet.add(0x01000000+0x0153);
+ extendedKeyCodesSet.add(0x01000000+0x30FC);
+ extendedKeyCodesSet.add(0x01000000+0x30A2);
+ extendedKeyCodesSet.add(0x01000000+0x30A4);
+ extendedKeyCodesSet.add(0x01000000+0x30A6);
+ extendedKeyCodesSet.add(0x01000000+0x30A8);
+ extendedKeyCodesSet.add(0x01000000+0x30AA);
+ extendedKeyCodesSet.add(0x01000000+0x30AB);
+ extendedKeyCodesSet.add(0x01000000+0x30AD);
+ extendedKeyCodesSet.add(0x01000000+0x30AF);
+ extendedKeyCodesSet.add(0x01000000+0x30B1);
+ extendedKeyCodesSet.add(0x01000000+0x30B3);
+ extendedKeyCodesSet.add(0x01000000+0x30B5);
+ extendedKeyCodesSet.add(0x01000000+0x30B7);
+ extendedKeyCodesSet.add(0x01000000+0x30B9);
+ extendedKeyCodesSet.add(0x01000000+0x30BB);
+ extendedKeyCodesSet.add(0x01000000+0x30BD);
+ extendedKeyCodesSet.add(0x01000000+0x30BF);
+ extendedKeyCodesSet.add(0x01000000+0x30C1);
+ extendedKeyCodesSet.add(0x01000000+0x30C4);
+ extendedKeyCodesSet.add(0x01000000+0x30C6);
+ extendedKeyCodesSet.add(0x01000000+0x30C8);
+ extendedKeyCodesSet.add(0x01000000+0x30CA);
+ extendedKeyCodesSet.add(0x01000000+0x30CB);
+ extendedKeyCodesSet.add(0x01000000+0x30CC);
+ extendedKeyCodesSet.add(0x01000000+0x30CD);
+ extendedKeyCodesSet.add(0x01000000+0x30CE);
+ extendedKeyCodesSet.add(0x01000000+0x30CF);
+ extendedKeyCodesSet.add(0x01000000+0x30D2);
+ extendedKeyCodesSet.add(0x01000000+0x30D5);
+ extendedKeyCodesSet.add(0x01000000+0x30D8);
+ extendedKeyCodesSet.add(0x01000000+0x30DB);
+ extendedKeyCodesSet.add(0x01000000+0x30DE);
+ extendedKeyCodesSet.add(0x01000000+0x30DF);
+ extendedKeyCodesSet.add(0x01000000+0x30E0);
+ extendedKeyCodesSet.add(0x01000000+0x30E1);
+ extendedKeyCodesSet.add(0x01000000+0x30E2);
+ extendedKeyCodesSet.add(0x01000000+0x30E4);
+ extendedKeyCodesSet.add(0x01000000+0x30E6);
+ extendedKeyCodesSet.add(0x01000000+0x30E8);
+ extendedKeyCodesSet.add(0x01000000+0x30E9);
+ extendedKeyCodesSet.add(0x01000000+0x30EA);
+ extendedKeyCodesSet.add(0x01000000+0x30EB);
+ extendedKeyCodesSet.add(0x01000000+0x30EC);
+ extendedKeyCodesSet.add(0x01000000+0x30ED);
+ extendedKeyCodesSet.add(0x01000000+0x30EF);
+ extendedKeyCodesSet.add(0x01000000+0x30F3);
+ extendedKeyCodesSet.add(0x01000000+0x309B);
+ extendedKeyCodesSet.add(0x01000000+0x309C);
+ extendedKeyCodesSet.add(0x01000000+0x06F0);
+ extendedKeyCodesSet.add(0x01000000+0x06F1);
+ extendedKeyCodesSet.add(0x01000000+0x06F2);
+ extendedKeyCodesSet.add(0x01000000+0x06F3);
+ extendedKeyCodesSet.add(0x01000000+0x06F4);
+ extendedKeyCodesSet.add(0x01000000+0x06F5);
+ extendedKeyCodesSet.add(0x01000000+0x06F6);
+ extendedKeyCodesSet.add(0x01000000+0x06F7);
+ extendedKeyCodesSet.add(0x01000000+0x06F8);
+ extendedKeyCodesSet.add(0x01000000+0x06F9);
+ extendedKeyCodesSet.add(0x01000000+0x0670);
+ extendedKeyCodesSet.add(0x01000000+0x067E);
+ extendedKeyCodesSet.add(0x01000000+0x0686);
+ extendedKeyCodesSet.add(0x01000000+0x060C);
+ extendedKeyCodesSet.add(0x01000000+0x06D4);
+ extendedKeyCodesSet.add(0x01000000+0x0660);
+ extendedKeyCodesSet.add(0x01000000+0x0661);
+ extendedKeyCodesSet.add(0x01000000+0x0662);
+ extendedKeyCodesSet.add(0x01000000+0x0663);
+ extendedKeyCodesSet.add(0x01000000+0x0664);
+ extendedKeyCodesSet.add(0x01000000+0x0665);
+ extendedKeyCodesSet.add(0x01000000+0x0666);
+ extendedKeyCodesSet.add(0x01000000+0x0667);
+ extendedKeyCodesSet.add(0x01000000+0x0668);
+ extendedKeyCodesSet.add(0x01000000+0x0669);
+ extendedKeyCodesSet.add(0x01000000+0x061B);
+ extendedKeyCodesSet.add(0x01000000+0x0621);
+ extendedKeyCodesSet.add(0x01000000+0x0624);
+ extendedKeyCodesSet.add(0x01000000+0x0626);
+ extendedKeyCodesSet.add(0x01000000+0x0627);
+ extendedKeyCodesSet.add(0x01000000+0x0628);
+ extendedKeyCodesSet.add(0x01000000+0x0629);
+ extendedKeyCodesSet.add(0x01000000+0x062A);
+ extendedKeyCodesSet.add(0x01000000+0x062B);
+ extendedKeyCodesSet.add(0x01000000+0x062C);
+ extendedKeyCodesSet.add(0x01000000+0x062D);
+ extendedKeyCodesSet.add(0x01000000+0x062E);
+ extendedKeyCodesSet.add(0x01000000+0x062F);
+ extendedKeyCodesSet.add(0x01000000+0x0630);
+ extendedKeyCodesSet.add(0x01000000+0x0631);
+ extendedKeyCodesSet.add(0x01000000+0x0632);
+ extendedKeyCodesSet.add(0x01000000+0x0633);
+ extendedKeyCodesSet.add(0x01000000+0x0634);
+ extendedKeyCodesSet.add(0x01000000+0x0635);
+ extendedKeyCodesSet.add(0x01000000+0x0636);
+ extendedKeyCodesSet.add(0x01000000+0x0637);
+ extendedKeyCodesSet.add(0x01000000+0x0638);
+ extendedKeyCodesSet.add(0x01000000+0x0639);
+ extendedKeyCodesSet.add(0x01000000+0x063A);
+ extendedKeyCodesSet.add(0x01000000+0x0641);
+ extendedKeyCodesSet.add(0x01000000+0x0642);
+ extendedKeyCodesSet.add(0x01000000+0x0643);
+ extendedKeyCodesSet.add(0x01000000+0x0644);
+ extendedKeyCodesSet.add(0x01000000+0x0645);
+ extendedKeyCodesSet.add(0x01000000+0x0646);
+ extendedKeyCodesSet.add(0x01000000+0x0647);
+ extendedKeyCodesSet.add(0x01000000+0x0648);
+ extendedKeyCodesSet.add(0x01000000+0x0649);
+ extendedKeyCodesSet.add(0x01000000+0x064A);
+ extendedKeyCodesSet.add(0x01000000+0x064E);
+ extendedKeyCodesSet.add(0x01000000+0x064F);
+ extendedKeyCodesSet.add(0x01000000+0x0650);
+ extendedKeyCodesSet.add(0x01000000+0x0652);
+ extendedKeyCodesSet.add(0x01000000+0x0698);
+ extendedKeyCodesSet.add(0x01000000+0x06A4);
+ extendedKeyCodesSet.add(0x01000000+0x06A9);
+ extendedKeyCodesSet.add(0x01000000+0x06AF);
+ extendedKeyCodesSet.add(0x01000000+0x06BE);
+ extendedKeyCodesSet.add(0x01000000+0x06CC);
+ extendedKeyCodesSet.add(0x01000000+0x06CC);
+ extendedKeyCodesSet.add(0x01000000+0x06D2);
+ extendedKeyCodesSet.add(0x01000000+0x0493);
+ extendedKeyCodesSet.add(0x01000000+0x0497);
+ extendedKeyCodesSet.add(0x01000000+0x049B);
+ extendedKeyCodesSet.add(0x01000000+0x049D);
+ extendedKeyCodesSet.add(0x01000000+0x04A3);
+ extendedKeyCodesSet.add(0x01000000+0x04AF);
+ extendedKeyCodesSet.add(0x01000000+0x04B1);
+ extendedKeyCodesSet.add(0x01000000+0x04B3);
+ extendedKeyCodesSet.add(0x01000000+0x04B9);
+ extendedKeyCodesSet.add(0x01000000+0x04BB);
+ extendedKeyCodesSet.add(0x01000000+0x04D9);
+ extendedKeyCodesSet.add(0x01000000+0x04E9);
+ extendedKeyCodesSet.add(0x01000000+0x0452);
+ extendedKeyCodesSet.add(0x01000000+0x0453);
+ extendedKeyCodesSet.add(0x01000000+0x0451);
+ extendedKeyCodesSet.add(0x01000000+0x0454);
+ extendedKeyCodesSet.add(0x01000000+0x0455);
+ extendedKeyCodesSet.add(0x01000000+0x0456);
+ extendedKeyCodesSet.add(0x01000000+0x0457);
+ extendedKeyCodesSet.add(0x01000000+0x0458);
+ extendedKeyCodesSet.add(0x01000000+0x0459);
+ extendedKeyCodesSet.add(0x01000000+0x045A);
+ extendedKeyCodesSet.add(0x01000000+0x045B);
+ extendedKeyCodesSet.add(0x01000000+0x045C);
+ extendedKeyCodesSet.add(0x01000000+0x0491);
+ extendedKeyCodesSet.add(0x01000000+0x045E);
+ extendedKeyCodesSet.add(0x01000000+0x045F);
+ extendedKeyCodesSet.add(0x01000000+0x2116);
+ extendedKeyCodesSet.add(0x01000000+0x044E);
+ extendedKeyCodesSet.add(0x01000000+0x0430);
+ extendedKeyCodesSet.add(0x01000000+0x0431);
+ extendedKeyCodesSet.add(0x01000000+0x0446);
+ extendedKeyCodesSet.add(0x01000000+0x0434);
+ extendedKeyCodesSet.add(0x01000000+0x0435);
+ extendedKeyCodesSet.add(0x01000000+0x0444);
+ extendedKeyCodesSet.add(0x01000000+0x0433);
+ extendedKeyCodesSet.add(0x01000000+0x0445);
+ extendedKeyCodesSet.add(0x01000000+0x0438);
+ extendedKeyCodesSet.add(0x01000000+0x0439);
+ extendedKeyCodesSet.add(0x01000000+0x043A);
+ extendedKeyCodesSet.add(0x01000000+0x043B);
+ extendedKeyCodesSet.add(0x01000000+0x043C);
+ extendedKeyCodesSet.add(0x01000000+0x043D);
+ extendedKeyCodesSet.add(0x01000000+0x043E);
+ extendedKeyCodesSet.add(0x01000000+0x043F);
+ extendedKeyCodesSet.add(0x01000000+0x044F);
+ extendedKeyCodesSet.add(0x01000000+0x0440);
+ extendedKeyCodesSet.add(0x01000000+0x0441);
+ extendedKeyCodesSet.add(0x01000000+0x0442);
+ extendedKeyCodesSet.add(0x01000000+0x0443);
+ extendedKeyCodesSet.add(0x01000000+0x0436);
+ extendedKeyCodesSet.add(0x01000000+0x0432);
+ extendedKeyCodesSet.add(0x01000000+0x044C);
+ extendedKeyCodesSet.add(0x01000000+0x044B);
+ extendedKeyCodesSet.add(0x01000000+0x0437);
+ extendedKeyCodesSet.add(0x01000000+0x0448);
+ extendedKeyCodesSet.add(0x01000000+0x044D);
+ extendedKeyCodesSet.add(0x01000000+0x0449);
+ extendedKeyCodesSet.add(0x01000000+0x0447);
+ extendedKeyCodesSet.add(0x01000000+0x044A);
+ extendedKeyCodesSet.add(0x01000000+0x2015);
+ extendedKeyCodesSet.add(0x01000000+0x03B1);
+ extendedKeyCodesSet.add(0x01000000+0x03B2);
+ extendedKeyCodesSet.add(0x01000000+0x03B3);
+ extendedKeyCodesSet.add(0x01000000+0x03B4);
+ extendedKeyCodesSet.add(0x01000000+0x03B5);
+ extendedKeyCodesSet.add(0x01000000+0x03B6);
+ extendedKeyCodesSet.add(0x01000000+0x03B7);
+ extendedKeyCodesSet.add(0x01000000+0x03B8);
+ extendedKeyCodesSet.add(0x01000000+0x03B9);
+ extendedKeyCodesSet.add(0x01000000+0x03BA);
+ extendedKeyCodesSet.add(0x01000000+0x03BB);
+ extendedKeyCodesSet.add(0x01000000+0x03BC);
+ extendedKeyCodesSet.add(0x01000000+0x03BD);
+ extendedKeyCodesSet.add(0x01000000+0x03BE);
+ extendedKeyCodesSet.add(0x01000000+0x03BF);
+ extendedKeyCodesSet.add(0x01000000+0x03C0);
+ extendedKeyCodesSet.add(0x01000000+0x03C1);
+ extendedKeyCodesSet.add(0x01000000+0x03C3);
+ extendedKeyCodesSet.add(0x01000000+0x03C2);
+ extendedKeyCodesSet.add(0x01000000+0x03C4);
+ extendedKeyCodesSet.add(0x01000000+0x03C5);
+ extendedKeyCodesSet.add(0x01000000+0x03C6);
+ extendedKeyCodesSet.add(0x01000000+0x03C7);
+ extendedKeyCodesSet.add(0x01000000+0x03C8);
+ extendedKeyCodesSet.add(0x01000000+0x03C9);
+ extendedKeyCodesSet.add(0x01000000+0x2190);
+ extendedKeyCodesSet.add(0x01000000+0x2192);
+ extendedKeyCodesSet.add(0x01000000+0x2193);
+ extendedKeyCodesSet.add(0x01000000+0x2013);
+ extendedKeyCodesSet.add(0x01000000+0x201C);
+ extendedKeyCodesSet.add(0x01000000+0x201D);
+ extendedKeyCodesSet.add(0x01000000+0x201E);
+ extendedKeyCodesSet.add(0x01000000+0x05D0);
+ extendedKeyCodesSet.add(0x01000000+0x05D1);
+ extendedKeyCodesSet.add(0x01000000+0x05D2);
+ extendedKeyCodesSet.add(0x01000000+0x05D3);
+ extendedKeyCodesSet.add(0x01000000+0x05D4);
+ extendedKeyCodesSet.add(0x01000000+0x05D5);
+ extendedKeyCodesSet.add(0x01000000+0x05D6);
+ extendedKeyCodesSet.add(0x01000000+0x05D7);
+ extendedKeyCodesSet.add(0x01000000+0x05D8);
+ extendedKeyCodesSet.add(0x01000000+0x05D9);
+ extendedKeyCodesSet.add(0x01000000+0x05DA);
+ extendedKeyCodesSet.add(0x01000000+0x05DB);
+ extendedKeyCodesSet.add(0x01000000+0x05DC);
+ extendedKeyCodesSet.add(0x01000000+0x05DD);
+ extendedKeyCodesSet.add(0x01000000+0x05DE);
+ extendedKeyCodesSet.add(0x01000000+0x05DF);
+ extendedKeyCodesSet.add(0x01000000+0x05E0);
+ extendedKeyCodesSet.add(0x01000000+0x05E1);
+ extendedKeyCodesSet.add(0x01000000+0x05E2);
+ extendedKeyCodesSet.add(0x01000000+0x05E3);
+ extendedKeyCodesSet.add(0x01000000+0x05E4);
+ extendedKeyCodesSet.add(0x01000000+0x05E5);
+ extendedKeyCodesSet.add(0x01000000+0x05E6);
+ extendedKeyCodesSet.add(0x01000000+0x05E7);
+ extendedKeyCodesSet.add(0x01000000+0x05E8);
+ extendedKeyCodesSet.add(0x01000000+0x05E9);
+ extendedKeyCodesSet.add(0x01000000+0x05EA);
+ extendedKeyCodesSet.add(0x01000000+0x0E01);
+ extendedKeyCodesSet.add(0x01000000+0x0E02);
+ extendedKeyCodesSet.add(0x01000000+0x0E03);
+ extendedKeyCodesSet.add(0x01000000+0x0E04);
+ extendedKeyCodesSet.add(0x01000000+0x0E05);
+ extendedKeyCodesSet.add(0x01000000+0x0E07);
+ extendedKeyCodesSet.add(0x01000000+0x0E08);
+ extendedKeyCodesSet.add(0x01000000+0x0E0A);
+ extendedKeyCodesSet.add(0x01000000+0x0E0C);
+ extendedKeyCodesSet.add(0x01000000+0x0E14);
+ extendedKeyCodesSet.add(0x01000000+0x0E15);
+ extendedKeyCodesSet.add(0x01000000+0x0E16);
+ extendedKeyCodesSet.add(0x01000000+0x0E17);
+ extendedKeyCodesSet.add(0x01000000+0x0E19);
+ extendedKeyCodesSet.add(0x01000000+0x0E1A);
+ extendedKeyCodesSet.add(0x01000000+0x0E1B);
+ extendedKeyCodesSet.add(0x01000000+0x0E1C);
+ extendedKeyCodesSet.add(0x01000000+0x0E1D);
+ extendedKeyCodesSet.add(0x01000000+0x0E1E);
+ extendedKeyCodesSet.add(0x01000000+0x0E1F);
+ extendedKeyCodesSet.add(0x01000000+0x0E20);
+ extendedKeyCodesSet.add(0x01000000+0x0E21);
+ extendedKeyCodesSet.add(0x01000000+0x0E22);
+ extendedKeyCodesSet.add(0x01000000+0x0E23);
+ extendedKeyCodesSet.add(0x01000000+0x0E25);
+ extendedKeyCodesSet.add(0x01000000+0x0E27);
+ extendedKeyCodesSet.add(0x01000000+0x0E2A);
+ extendedKeyCodesSet.add(0x01000000+0x0E2B);
+ extendedKeyCodesSet.add(0x01000000+0x0E2D);
+ extendedKeyCodesSet.add(0x01000000+0x0E30);
+ extendedKeyCodesSet.add(0x01000000+0x0E31);
+ extendedKeyCodesSet.add(0x01000000+0x0E32);
+ extendedKeyCodesSet.add(0x01000000+0x0E33);
+ extendedKeyCodesSet.add(0x01000000+0x0E34);
+ extendedKeyCodesSet.add(0x01000000+0x0E35);
+ extendedKeyCodesSet.add(0x01000000+0x0E36);
+ extendedKeyCodesSet.add(0x01000000+0x0E37);
+ extendedKeyCodesSet.add(0x01000000+0x0E38);
+ extendedKeyCodesSet.add(0x01000000+0x0E39);
+ extendedKeyCodesSet.add(0x01000000+0x0E3F);
+ extendedKeyCodesSet.add(0x01000000+0x0E40);
+ extendedKeyCodesSet.add(0x01000000+0x0E41);
+ extendedKeyCodesSet.add(0x01000000+0x0E43);
+ extendedKeyCodesSet.add(0x01000000+0x0E44);
+ extendedKeyCodesSet.add(0x01000000+0x0E45);
+ extendedKeyCodesSet.add(0x01000000+0x0E46);
+ extendedKeyCodesSet.add(0x01000000+0x0E47);
+ extendedKeyCodesSet.add(0x01000000+0x0E48);
+ extendedKeyCodesSet.add(0x01000000+0x0E49);
+ extendedKeyCodesSet.add(0x01000000+0x0E50);
+ extendedKeyCodesSet.add(0x01000000+0x0E51);
+ extendedKeyCodesSet.add(0x01000000+0x0E52);
+ extendedKeyCodesSet.add(0x01000000+0x0E53);
+ extendedKeyCodesSet.add(0x01000000+0x0E54);
+ extendedKeyCodesSet.add(0x01000000+0x0E55);
+ extendedKeyCodesSet.add(0x01000000+0x0E56);
+ extendedKeyCodesSet.add(0x01000000+0x0E57);
+ extendedKeyCodesSet.add(0x01000000+0x0E58);
+ extendedKeyCodesSet.add(0x01000000+0x0E59);
+ extendedKeyCodesSet.add(0x01000000+0x0587);
+ extendedKeyCodesSet.add(0x01000000+0x0589);
+ extendedKeyCodesSet.add(0x01000000+0x0589);
+ extendedKeyCodesSet.add(0x01000000+0x055D);
+ extendedKeyCodesSet.add(0x01000000+0x055D);
+ extendedKeyCodesSet.add(0x01000000+0x055B);
+ extendedKeyCodesSet.add(0x01000000+0x055B);
+ extendedKeyCodesSet.add(0x01000000+0x055E);
+ extendedKeyCodesSet.add(0x01000000+0x055E);
+ extendedKeyCodesSet.add(0x01000000+0x0561);
+ extendedKeyCodesSet.add(0x01000000+0x0562);
+ extendedKeyCodesSet.add(0x01000000+0x0563);
+ extendedKeyCodesSet.add(0x01000000+0x0564);
+ extendedKeyCodesSet.add(0x01000000+0x0565);
+ extendedKeyCodesSet.add(0x01000000+0x0566);
+ extendedKeyCodesSet.add(0x01000000+0x0567);
+ extendedKeyCodesSet.add(0x01000000+0x0568);
+ extendedKeyCodesSet.add(0x01000000+0x0569);
+ extendedKeyCodesSet.add(0x01000000+0x056A);
+ extendedKeyCodesSet.add(0x01000000+0x056B);
+ extendedKeyCodesSet.add(0x01000000+0x056C);
+ extendedKeyCodesSet.add(0x01000000+0x056D);
+ extendedKeyCodesSet.add(0x01000000+0x056E);
+ extendedKeyCodesSet.add(0x01000000+0x056F);
+ extendedKeyCodesSet.add(0x01000000+0x0570);
+ extendedKeyCodesSet.add(0x01000000+0x0571);
+ extendedKeyCodesSet.add(0x01000000+0x0572);
+ extendedKeyCodesSet.add(0x01000000+0x0573);
+ extendedKeyCodesSet.add(0x01000000+0x0574);
+ extendedKeyCodesSet.add(0x01000000+0x0575);
+ extendedKeyCodesSet.add(0x01000000+0x0576);
+ extendedKeyCodesSet.add(0x01000000+0x0577);
+ extendedKeyCodesSet.add(0x01000000+0x0578);
+ extendedKeyCodesSet.add(0x01000000+0x0579);
+ extendedKeyCodesSet.add(0x01000000+0x057A);
+ extendedKeyCodesSet.add(0x01000000+0x057B);
+ extendedKeyCodesSet.add(0x01000000+0x057C);
+ extendedKeyCodesSet.add(0x01000000+0x057D);
+ extendedKeyCodesSet.add(0x01000000+0x057E);
+ extendedKeyCodesSet.add(0x01000000+0x057F);
+ extendedKeyCodesSet.add(0x01000000+0x0580);
+ extendedKeyCodesSet.add(0x01000000+0x0581);
+ extendedKeyCodesSet.add(0x01000000+0x0582);
+ extendedKeyCodesSet.add(0x01000000+0x0583);
+ extendedKeyCodesSet.add(0x01000000+0x0584);
+ extendedKeyCodesSet.add(0x01000000+0x0585);
+ extendedKeyCodesSet.add(0x01000000+0x0586);
+ extendedKeyCodesSet.add(0x01000000+0x10D0);
+ extendedKeyCodesSet.add(0x01000000+0x10D1);
+ extendedKeyCodesSet.add(0x01000000+0x10D2);
+ extendedKeyCodesSet.add(0x01000000+0x10D3);
+ extendedKeyCodesSet.add(0x01000000+0x10D4);
+ extendedKeyCodesSet.add(0x01000000+0x10D5);
+ extendedKeyCodesSet.add(0x01000000+0x10D6);
+ extendedKeyCodesSet.add(0x01000000+0x10D7);
+ extendedKeyCodesSet.add(0x01000000+0x10D8);
+ extendedKeyCodesSet.add(0x01000000+0x10D9);
+ extendedKeyCodesSet.add(0x01000000+0x10DA);
+ extendedKeyCodesSet.add(0x01000000+0x10DB);
+ extendedKeyCodesSet.add(0x01000000+0x10DC);
+ extendedKeyCodesSet.add(0x01000000+0x10DD);
+ extendedKeyCodesSet.add(0x01000000+0x10DE);
+ extendedKeyCodesSet.add(0x01000000+0x10DF);
+ extendedKeyCodesSet.add(0x01000000+0x10E0);
+ extendedKeyCodesSet.add(0x01000000+0x10E1);
+ extendedKeyCodesSet.add(0x01000000+0x10E2);
+ extendedKeyCodesSet.add(0x01000000+0x10E3);
+ extendedKeyCodesSet.add(0x01000000+0x10E4);
+ extendedKeyCodesSet.add(0x01000000+0x10E5);
+ extendedKeyCodesSet.add(0x01000000+0x10E6);
+ extendedKeyCodesSet.add(0x01000000+0x10E7);
+ extendedKeyCodesSet.add(0x01000000+0x10E8);
+ extendedKeyCodesSet.add(0x01000000+0x10E9);
+ extendedKeyCodesSet.add(0x01000000+0x10EA);
+ extendedKeyCodesSet.add(0x01000000+0x10EB);
+ extendedKeyCodesSet.add(0x01000000+0x10EC);
+ extendedKeyCodesSet.add(0x01000000+0x10ED);
+ extendedKeyCodesSet.add(0x01000000+0x10EE);
+ extendedKeyCodesSet.add(0x01000000+0x10EF);
+ extendedKeyCodesSet.add(0x01000000+0x10F0);
+ extendedKeyCodesSet.add(0x01000000+0x01E7);
+ extendedKeyCodesSet.add(0x01000000+0x0259);
+ extendedKeyCodesSet.add(0x01000000+0x1EB9);
+ extendedKeyCodesSet.add(0x01000000+0x1ECB);
+ extendedKeyCodesSet.add(0x01000000+0x1ECD);
+ extendedKeyCodesSet.add(0x01000000+0x1EE5);
+ extendedKeyCodesSet.add(0x01000000+0x01A1);
+ extendedKeyCodesSet.add(0x01000000+0x01B0);
+ extendedKeyCodesSet.add(0x01000000+0x20AB);
+ }
+}
--- a/jdk/src/solaris/classes/sun/awt/X11/XConstants.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XConstants.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. 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
@@ -684,4 +684,19 @@
public static final int LSBFirst = 0 ;
public static final int MSBFirst = 1 ;
+
+ /* XKB support */
+ public static final int XkbUseCoreKbd = 0x0100 ;
+ public static final int XkbNewKeyboardNotify = 0;
+ public static final int XkbMapNotify = 1;
+ public static final int XkbStateNotify = 2;
+ public static final long XkbNewKeyboardNotifyMask = (1L << 0);
+ public static final long XkbMapNotifyMask = (1L << 1);
+ public static final long XkbStateNotifyMask = (1L << 2);
+ public static final long XkbGroupStateMask = (1L << 4);
+ public static final long XkbKeyTypesMask = (1L<<0);
+ public static final long XkbKeySymsMask = (1L<<1);
+ public static final long XkbModifierMapMask = (1L<<2);
+ public static final long XkbVirtualModsMask = (1L<<6); //server map
+
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XKeysym.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,7 +1,7 @@
// This is a generated file: do not edit! Edit keysym2ucs.h if necessary.
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc. 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
@@ -89,14 +89,47 @@
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.
@@ -198,6 +231,27 @@
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 = keysym2JavaKeycodeHash.get( 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());
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Mar 27 12:01:24 2009 +0300
@@ -292,6 +292,7 @@
if (XlibWrapper.XSetLocaleModifiers("") == null) {
log.finer("X locale modifiers are not supported, using default");
}
+ tryXKB();
AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
awt_defaultFg = defaultScreen.get_blackpixel();
@@ -314,6 +315,7 @@
if (xs != null) {
((XAWTXSettings)xs).dispose();
}
+ freeXKB();
if (log.isLoggable(Level.FINE)) {
dumpPeers();
}
@@ -592,6 +594,9 @@
if (ev.get_type() != XConstants.NoExpose) {
eventNumber++;
}
+ if (awt_UseXKB_Calls && ev.get_type() == awt_XKBBaseEventCode) {
+ processXkbChanges(ev);
+ }
if (XDropTargetEventProcessor.processEvent(ev) ||
XDragSourceContextPeer.processEvent(ev)) {
@@ -2094,8 +2099,12 @@
static boolean awt_ServerInquired = false;
static boolean awt_IsXsunServer = false;
- static boolean awt_XKBInquired = false;
static boolean awt_UseXKB = false;
+ static boolean awt_UseXKB_Calls = false;
+ static int awt_XKBBaseEventCode = 0;
+ static int awt_XKBEffectiveGroup = 0; // so far, I don't use it leaving all calculations
+ // to XkbTranslateKeyCode
+ static long awt_XKBDescPtr = 0;
/**
Try to understand if it is Xsun server.
By now (2005) Sun is vendor of Xsun and Xorg servers; we only return true if Xsun is running.
@@ -2125,23 +2134,143 @@
awtUnlock();
}
}
- /**
- Query XKEYBOARD extension.
- */
static boolean isXKBenabled() {
awtLock();
try {
- if( awt_XKBInquired ) {
- return awt_UseXKB;
+ return awt_UseXKB;
+ } finally {
+ awtUnlock();
+ }
+ }
+
+ /**
+ Query XKEYBOARD extension.
+ If possible, initialize xkb library.
+ */
+ static boolean tryXKB() {
+ awtLock();
+ try {
+ String name = "XKEYBOARD";
+ // First, if there is extension at all.
+ awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
+ if( awt_UseXKB ) {
+ // There is a keyboard extension. Check if a client library is compatible.
+ // If not, don't use xkb calls.
+ // In this case we still may be Xkb-capable application.
+ awt_UseXKB_Calls = XlibWrapper.XkbLibraryVersion( XlibWrapper.larg1, XlibWrapper.larg2);
+ if( awt_UseXKB_Calls ) {
+ awt_UseXKB_Calls = XlibWrapper.XkbQueryExtension( getDisplay(), XlibWrapper.larg1, XlibWrapper.larg2,
+ XlibWrapper.larg3, XlibWrapper.larg4, XlibWrapper.larg5);
+ if( awt_UseXKB_Calls ) {
+ awt_XKBBaseEventCode = Native.getInt(XlibWrapper.larg2);
+ XlibWrapper.XkbSelectEvents (getDisplay(),
+ XConstants.XkbUseCoreKbd,
+ XConstants.XkbNewKeyboardNotifyMask |
+ XConstants.XkbMapNotifyMask ,//|
+ //XConstants.XkbStateNotifyMask,
+ XConstants.XkbNewKeyboardNotifyMask |
+ XConstants.XkbMapNotifyMask );//|
+ //XConstants.XkbStateNotifyMask);
+
+ XlibWrapper.XkbSelectEventDetails(getDisplay(), XConstants.XkbUseCoreKbd,
+ XConstants.XkbStateNotify,
+ XConstants.XkbGroupStateMask,
+ XConstants.XkbGroupStateMask);
+ //XXX ? XkbGroupLockMask last, XkbAllStateComponentsMask before last?
+ awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ XConstants.XkbUseCoreKbd);
+ }
+ }
}
- awt_XKBInquired = true;
- String name = "XKEYBOARD";
- awt_UseXKB = XlibWrapper.XQueryExtension( getDisplay(), name, XlibWrapper.larg1, XlibWrapper.larg2, XlibWrapper.larg3);
return awt_UseXKB;
} finally {
awtUnlock();
}
}
+ static boolean canUseXKBCalls() {
+ awtLock();
+ try {
+ return awt_UseXKB_Calls;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static int getXKBEffectiveGroup() {
+ awtLock();
+ try {
+ return awt_XKBEffectiveGroup;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static int getXKBBaseEventCode() {
+ awtLock();
+ try {
+ return awt_XKBBaseEventCode;
+ } finally {
+ awtUnlock();
+ }
+ }
+ static long getXKBKbdDesc() {
+ awtLock();
+ try {
+ return awt_XKBDescPtr;
+ } finally {
+ awtUnlock();
+ }
+ }
+ void freeXKB() {
+ awtLock();
+ try {
+ if (awt_UseXKB_Calls && awt_XKBDescPtr != 0) {
+ XlibWrapper.XkbFreeKeyboard(awt_XKBDescPtr, 0xFF, true);
+ }
+ } finally {
+ awtUnlock();
+ }
+ }
+ private void processXkbChanges(XEvent ev) {
+ // mapping change --> refresh kbd map
+ // state change --> get a new effective group; do I really need it
+ // or that should be left for XkbTranslateKeyCode?
+ XkbEvent xke = new XkbEvent( ev.getPData() );
+ int xkb_type = xke.get_any().get_xkb_type();
+ switch( xkb_type ) {
+ case XConstants.XkbNewKeyboardNotify :
+ if( awt_XKBDescPtr != 0 ) {
+ freeXKB();
+ }
+ awt_XKBDescPtr = XlibWrapper.XkbGetMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ XConstants.XkbUseCoreKbd);
+ //System.out.println("XkbNewKeyboard:"+(xke.get_new_kbd()));
+ break;
+ case XConstants.XkbMapNotify :
+ //TODO: provide a simple unit test.
+ XlibWrapper.XkbGetUpdatedMap(getDisplay(),
+ XConstants.XkbKeyTypesMask |
+ XConstants.XkbKeySymsMask |
+ XConstants.XkbModifierMapMask |
+ XConstants.XkbVirtualModsMask,
+ awt_XKBDescPtr);
+ //System.out.println("XkbMap:"+(xke.get_map()));
+ break;
+ case XConstants.XkbStateNotify :
+ // May use it later e.g. to obtain an effective group etc.
+ //System.out.println("XkbState:"+(xke.get_state()));
+ break;
+ default:
+ //System.out.println("XkbEvent of xkb_type "+xkb_type);
+ break;
+ }
+ }
private static long eventNumber;
public static long getEventNumber() {
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindow.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc. 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
@@ -128,6 +128,9 @@
private native static void initIDs();
private static Field isPostedField;
+ private static Field rawCodeField;
+ private static Field primaryLevelUnicodeField;
+ private static Field extendedKeyCodeField;
static {
initIDs();
}
@@ -1037,7 +1040,7 @@
Parameter is a keysym basically from keysymdef.h
XXX: how about vendor keys? Is there some with Unicode value and not in the list?
*/
- char keysymToUnicode( long keysym, int state ) {
+ int keysymToUnicode( long keysym, int state ) {
return XKeysym.convertKeysym( keysym, state );
}
int keyEventType2Id( int xEventType ) {
@@ -1047,6 +1050,13 @@
static private long xkeycodeToKeysym(XKeyEvent ev) {
return XKeysym.getKeysym( ev );
}
+ private long xkeycodeToPrimaryKeysym(XKeyEvent ev) {
+ return XKeysym.xkeycode2primary_keysym( ev );
+ }
+ static private int primaryUnicode2JavaKeycode(int uni) {
+ return (uni > 0? sun.awt.ExtendedKeyCodes.getExtendedKeyCodeForChar(uni) : 0);
+ //return (uni > 0? uni + 0x01000000 : 0);
+ }
void logIncomingKeyEvent(XKeyEvent ev) {
keyEventLog.fine("--XWindow.java:handleKeyEvent:"+ev);
dumpKeysymArray(ev);
@@ -1065,7 +1075,7 @@
// un-final it if you need to override it in a subclass.
final void handleKeyPress(XKeyEvent ev) {
long keysym[] = new long[2];
- char unicodeKey = 0;
+ int unicodeKey = 0;
keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(Level.FINE)) {
@@ -1110,19 +1120,36 @@
if( jkc == null ) {
jkc = new XKeysym.Keysym2JavaKeycode(java.awt.event.KeyEvent.VK_UNDEFINED, java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN);
}
+
+ // Take the first keysym from a keysym array associated with the XKeyevent
+ // and convert it to Unicode. Then, even if a Java keycode for the keystroke
+ // is undefined, we still have a guess of what has been engraved on a keytop.
+ int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
+
if (keyEventLog.isLoggable(Level.FINE)) {
keyEventLog.fine(">>>Fire Event:"+
(ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
"jkeycode:decimal="+jkc.getJavaKeycode()+
- ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
+ ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
+ " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
+ ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
);
}
+
+ int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
+ int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
+ primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
+ jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_PRESSED,
ev.get_time(),
- jkc.getJavaKeycode(),
+ jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
+ unicodeFromPrimaryKeysym,
+ jkeyExtended);
+
+
if( unicodeKey > 0 ) {
keyEventLog.fine("fire _TYPED on "+unicodeKey);
postKeyEvent( java.awt.event.KeyEvent.KEY_TYPED,
@@ -1130,7 +1157,10 @@
java.awt.event.KeyEvent.VK_UNDEFINED,
unicodeKey,
java.awt.event.KeyEvent.KEY_LOCATION_UNKNOWN,
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)0,
+ unicodeFromPrimaryKeysym,
+ java.awt.event.KeyEvent.VK_UNDEFINED);
+
}
@@ -1148,7 +1178,7 @@
// un-private it if you need to call it from elsewhere
private void handleKeyRelease(XKeyEvent ev) {
long keysym[] = new long[2];
- char unicodeKey = 0;
+ int unicodeKey = 0;
keysym[0] = XConstants.NoSymbol;
if (keyEventLog.isLoggable(Level.FINE)) {
@@ -1166,7 +1196,9 @@
keyEventLog.fine(">>>Fire Event:"+
(ev.get_type() == XConstants.KeyPress ? "KEY_PRESSED; " : "KEY_RELEASED; ")+
"jkeycode:decimal="+jkc.getJavaKeycode()+
- ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "
+ ", hex=0x"+Integer.toHexString(jkc.getJavaKeycode())+"; "+
+ " legacy jkeycode: decimal="+XKeysym.getLegacyJavaKeycodeOnly(ev)+
+ ", hex=0x"+Integer.toHexString(XKeysym.getLegacyJavaKeycodeOnly(ev))+"; "
);
}
// We obtain keysym from IM and derive unicodeKey from it for KeyPress only.
@@ -1177,12 +1209,24 @@
// That's why we use the same procedure as if there was no IM instance: do-it-yourself unicode.
unicodeKey = keysymToUnicode( xkeycodeToKeysym(ev), ev.get_state() );
+ // Take a first keysym from a keysym array associated with the XKeyevent
+ // and convert it to Unicode. Then, even if Java keycode for the keystroke
+ // is undefined, we still will have a guess of what was engraved on a keytop.
+ int unicodeFromPrimaryKeysym = keysymToUnicode( xkeycodeToPrimaryKeysym(ev) ,0);
+
+ int jkeyToReturn = XKeysym.getLegacyJavaKeycodeOnly(ev); // someway backward compatible
+ int jkeyExtended = jkc.getJavaKeycode() == java.awt.event.KeyEvent.VK_UNDEFINED ?
+ primaryUnicode2JavaKeycode( unicodeFromPrimaryKeysym ) :
+ jkc.getJavaKeycode();
postKeyEvent( java.awt.event.KeyEvent.KEY_RELEASED,
ev.get_time(),
- jkc.getJavaKeycode(),
+ jkeyToReturn,
(unicodeKey == 0 ? java.awt.event.KeyEvent.CHAR_UNDEFINED : unicodeKey),
jkc.getKeyLocation(),
- ev.get_state(),ev.getPData(), XKeyEvent.getSize());
+ ev.get_state(),ev.getPData(), XKeyEvent.getSize(), (long)(ev.get_keycode()),
+ unicodeFromPrimaryKeysym,
+ jkeyExtended);
+
}
@@ -1379,17 +1423,38 @@
}
}
- public void postKeyEvent(int id, long when, int keyCode, char keyChar,
- int keyLocation, int state, long event, int eventSize)
+ public void postKeyEvent(int id, long when, int keyCode, int keyChar,
+ int keyLocation, int state, long event, int eventSize, long rawCode,
+ int unicodeFromPrimaryKeysym, int extendedKeyCode)
+
{
long jWhen = XToolkit.nowMillisUTC_offset(when);
int modifiers = getModifiers(state, 0, keyCode);
+ if (rawCodeField == null) {
+ rawCodeField = XToolkit.getField(KeyEvent.class, "rawCode");
+ }
+ if (primaryLevelUnicodeField == null) {
+ primaryLevelUnicodeField = XToolkit.getField(KeyEvent.class, "primaryLevelUnicode");
+ }
+ if (extendedKeyCodeField == null) {
+ extendedKeyCodeField = XToolkit.getField(KeyEvent.class, "extendedKeyCode");
+ }
+
KeyEvent ke = new KeyEvent((Component)getEventSource(), id, jWhen,
- modifiers, keyCode, keyChar, keyLocation);
+ modifiers, keyCode, (char)keyChar, keyLocation);
if (event != 0) {
byte[] data = Native.toBytes(event, eventSize);
setBData(ke, data);
}
+ try {
+ rawCodeField.set(ke, rawCode);
+ primaryLevelUnicodeField.set(ke, (long)unicodeFromPrimaryKeysym);
+ extendedKeyCodeField.set(ke, (long)extendedKeyCode);
+ } catch (IllegalArgumentException e) {
+ assert(false);
+ } catch (IllegalAccessException e) {
+ assert(false);
+ }
postEventToEventQueue(ke);
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/XlibWrapper.java Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc. 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
@@ -492,6 +492,21 @@
static native int XKeysymToKeycode(long display, long keysym);
+ // xkb-related
+ static native int XkbGetEffectiveGroup(long display);
+ static native long XkbKeycodeToKeysym(long display, int keycode, int group, int level);
+ static native void XkbSelectEvents(long display, long device, long bits_to_change, long values_for_bits);
+ static native void XkbSelectEventDetails(long display, long device, long event_type,
+ long bits_to_change, long values_for_bits);
+ static native boolean XkbQueryExtension(long display, long opcode_rtrn, long event_rtrn,
+ long error_rtrn, long major_in_out, long minor_in_out);
+ static native boolean XkbLibraryVersion(long lib_major_in_out, long lib_minor_in_out);
+ static native long XkbGetMap(long display, long which, long device_spec);
+ static native long XkbGetUpdatedMap(long display, long which, long xkb);
+ static native void XkbFreeKeyboard(long xkb, long which, boolean free_all);
+ static native boolean XkbTranslateKeyCode(long xkb, int keycode, long mods, long mods_rtrn, long keysym_rtrn);
+
+
static native void XConvertCase(long keysym,
long keysym_lowercase,
long keysym_uppercase);
@@ -617,6 +632,15 @@
}
return buf.toString();
}
+ static String getEventToString( int type ) {
+ if( (type >= 0) && (type < eventToString.length)) {
+ return eventToString[type];
+ }else if( type == XToolkit.getXKBBaseEventCode() ) {
+ //XXX TODO various xkb types
+ return "XkbEvent";
+ }
+ return eventToString[0];
+ }
private static boolean getBuildInternal() {
String javaVersion = XToolkit.getSystemProperty("java.version");
--- a/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/generator/WrapperGenerator.java Fri Mar 27 12:01:24 2009 +0300
@@ -1138,6 +1138,7 @@
pw.println("/* This file is an automatically generated file, please do not edit this file, modify the XlibParser.java file instead !*/\n" );
pw.println("#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/Xatom.h>\n#include <stdio.h>\n");
pw.println("#include <X11/extensions/Xdbe.h>");
+ pw.println("#include <X11/XKBlib.h>");
pw.println("#include \"awt_p.h\"");
pw.println("#include \"color.h\"");
pw.println("#include \"colordata.h\"");
--- a/jdk/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/generator/xlibtypes.txt Fri Mar 27 12:01:24 2009 +0300
@@ -119,7 +119,7 @@
length short
feedback pointer
encoding_is_wchar Bool
- string pointer
+ string pointer
XKeymapEvent
type int
serial long
@@ -574,7 +574,7 @@
f.get_pixel pointer
f.put_pixel pointer
f.sub_image pointer
- f.add_pixel pointer
+ f.add_pixel pointer
XIMValuesList
count_values short
supported_values pointer
@@ -728,7 +728,7 @@
awt_icmLUT pointer int
awt_icmLUT2Colors pointer byte
img_grays pointer byte
- img_clr_tbl pointer byte
+ img_clr_tbl pointer byte
img_oda_red pointer byte
img_oda_green pointer byte
img_oda_blue pointer byte
@@ -798,3 +798,227 @@
xerror struct XErrorEvent
xkeymap struct XKeymapEvent
pad array long 24
+
+XkbAnyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+
+XkbNewKeyboardNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ old_device int
+ min_key_code int
+ max_key_code int
+ old_min_key_code int
+ old_max_key_code int
+ changed int
+ req_major byte
+ req_minor byte
+
+XkbMapNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ flags int
+ first_type int
+ num_types int
+ min_key_code int
+ max_key_code int
+ first_key_sym int
+ first_key_act int
+ first_key_behavior int
+ first_key_explicit int
+ first_modmap_key int
+ first_vmodmap_key int
+ num_key_syms int
+ num_key_acts int
+ num_key_behaviors int
+ num_key_explicit int
+ num_modmap_keys int
+ num_vmodmap_keys int
+ vmods int
+
+XkbStateNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ group int
+ base_group int
+ latched_group int
+ locked_group int
+ mods int
+ base_mods int
+ latched_mods int
+ locked_mods int
+ compat_state int
+ grab_mods byte
+ compat_grab_mods byte
+ lookup_mods byte
+ compat_lookup_mods byte
+ ptr_buttons int
+ keycode int
+ event_type byte
+ req_major byte
+ req_minor byte
+
+XkbControlsNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed_ctrls int
+ enabled_ctrls int
+ enabled_ctrl_changes int
+ num_groups int
+ keycode int
+ event_type byte
+ req_major byte
+ req_minor byte
+
+XkbIndicatorNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ state int
+
+XkbNamesNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed int
+ first_type int
+ num_types int
+ first_lvl int
+ num_lvls int
+ num_aliases int
+ num_radio_groups int
+ changed_vmods int
+ changed_groups int
+ changed_indicators int
+ first_key int
+ num_keys int
+
+
+XkbCompatMapNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ changed_groups int
+ first_si int
+ num_si int
+ num_total_si int
+
+XkbBellNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ percent int
+ pitch int
+ duration int
+ bell_class int
+ bell_id int
+ name Atom
+ window long
+ event_only Bool
+
+XkbActionMessageEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ keycode int
+ press Bool
+ key_event_follows Bool
+ group int
+ mods int
+ message array byte 7 //XkbActionMessageLength+1
+
+XkbAccessXNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ detail int
+ keycode int
+ sk_delay int
+ debounce_delay int
+
+XkbExtensionDeviceNotifyEvent
+ type int
+ serial ulong
+ send_event Bool
+ display long
+ time ulong
+ xkb_type int
+ device int
+ reason int
+ supported int
+ unsupported int
+ first_btn int
+ num_btns int
+ leds_defined int
+ led_state int
+ led_class int
+ led_id int
+
+XkbEvent
+ type int
+ any struct XkbAnyEvent
+ new_kbd struct XkbNewKeyboardNotifyEvent
+ map struct XkbMapNotifyEvent
+ state struct XkbStateNotifyEvent
+ ctrls struct XkbControlsNotifyEvent
+ indicators struct XkbIndicatorNotifyEvent
+ names struct XkbNamesNotifyEvent
+ compat struct XkbCompatMapNotifyEvent
+ bell struct XkbBellNotifyEvent
+ message struct XkbActionMessageEvent
+ accessx struct XkbAccessXNotifyEvent
+ device struct XkbExtensionDeviceNotifyEvent
+ core struct XEvent
--- a/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/classes/sun/awt/X11/keysym2ucs.h Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2009 Sun Microsystems, Inc. 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
@@ -39,7 +39,7 @@
*/
tojava /*
-tojava * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
+tojava * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
tojava * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tojava *
tojava * This code is free software; you can redistribute it and/or modify it
@@ -127,14 +127,47 @@
tojava Character ch = keysym2UCSHash.get(ks);
tojava return ch == null ? (char)0 : ch.charValue();
tojava }
+tojava static long xkeycode2keysym_noxkb(XKeyEvent ev, int ndx) {
+tojava XToolkit.awtLock();
+tojava try {
+tojava return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx);
+tojava } finally {
+tojava XToolkit.awtUnlock();
+tojava }
+tojava }
+tojava static long xkeycode2keysym_xkb(XKeyEvent ev, int ndx) {
+tojava XToolkit.awtLock();
+tojava try {
+tojava int mods = ev.get_state();
+tojava if ((ndx == 0) && ((mods & XConstants.ShiftMask) != 0)) {
+tojava // I don't know all possible meanings of 'ndx' in case of XKB
+tojava // and don't want to speculate. But this particular case
+tojava // clearly means that caller needs a so called primary keysym.
+tojava mods ^= XConstants.ShiftMask;
+tojava }
+tojava XlibWrapper.XkbTranslateKeyCode(XToolkit.getXKBKbdDesc(), ev.get_keycode(),
+tojava mods, XlibWrapper.iarg1, XlibWrapper.larg3);
+tojava //XXX unconsumed modifiers?
+tojava return Native.getLong(XlibWrapper.larg3);
+tojava } finally {
+tojava XToolkit.awtUnlock();
+tojava }
+tojava }
tojava static long xkeycode2keysym(XKeyEvent ev, int ndx) {
tojava XToolkit.awtLock();
tojava try {
-tojava return XlibWrapper.XKeycodeToKeysym(ev.get_display(), ev.get_keycode(), ndx );
+tojava if (XToolkit.canUseXKBCalls()) {
+tojava return xkeycode2keysym_xkb(ev, ndx);
+tojava }else{
+tojava return xkeycode2keysym_noxkb(ev, ndx);
+tojava }
tojava } finally {
tojava XToolkit.awtUnlock();
tojava }
tojava }
+tojava static long xkeycode2primary_keysym(XKeyEvent ev) {
+tojava return xkeycode2keysym(ev, 0);
+tojava }
tojava public static boolean isKPEvent( XKeyEvent ev )
tojava {
tojava // Xsun without XKB uses keysymarray[2] keysym to determine if it is KP event.
@@ -236,6 +269,27 @@
tojava Keysym2JavaKeycode jkc = getJavaKeycode( ev );
tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
tojava }
+tojava /**
+tojava * Return an integer java keycode apprx as it was before extending keycodes range.
+tojava * This call would ignore for instance XKB and process whatever is on the bottom
+tojava * of keysym stack. Result will not depend on actual locale, will differ between
+tojava * dual/multiple keyboard setup systems (e.g. English+Russian vs French+Russian)
+tojava * but will be someway compatible with old releases.
+tojava */
+tojava static int getLegacyJavaKeycodeOnly( XKeyEvent ev ) {
+tojava long keysym = XConstants.NoSymbol;
+tojava int ndx = 0;
+tojava if( (ev.get_state() & XToolkit.numLockMask) != 0 &&
+tojava isKPEvent(ev)) {
+tojava keysym = getKeypadKeysym( ev );
+tojava } else {
+tojava // we only need primary-layer keysym to derive a java keycode.
+tojava ndx = 0;
+tojava keysym = xkeycode2keysym_noxkb(ev, ndx);
+tojava }
+tojava Keysym2JavaKeycode jkc = keysym2JavaKeycodeHash.get( keysym );
+tojava return jkc == null ? java.awt.event.KeyEvent.VK_UNDEFINED : jkc.getJavaKeycode();
+tojava }
tojava static long javaKeycode2Keysym( int jkey ) {
tojava Long ks = javaKeycode2KeysymHash.get( jkey );
tojava return (ks == null ? 0 : ks.longValue());
--- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc. 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
@@ -44,6 +44,7 @@
#include <Region.h>
#include "utility/rect.h"
+#include <X11/XKBlib.h>
#if defined(DEBUG) || defined(INTERNAL_BUILD)
static jmethodID lockIsHeldMID = NULL;
@@ -449,6 +450,79 @@
XSelectInput((Display *) jlong_to_ptr(display), (Window) window, mask);
}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEvents
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong bits_to_change, jlong values_for_bits)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbSelectEvents((Display *) jlong_to_ptr(display), (unsigned int)device,
+ (unsigned long)bits_to_change,
+ (unsigned long)values_for_bits);
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbSelectEventDetails
+(JNIEnv *env, jclass clazz, jlong display, jlong device, jlong event_type, jlong bits_to_change, jlong values_for_bits)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbSelectEventDetails((Display *) jlong_to_ptr(display), (unsigned int)device,
+ (unsigned int) event_type,
+ (unsigned long)bits_to_change,
+ (unsigned long)values_for_bits);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbQueryExtension
+(JNIEnv *env, jclass clazz, jlong display, jlong opcode_rtrn, jlong event_rtrn,
+ jlong error_rtrn, jlong major_in_out, jlong minor_in_out)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return XkbQueryExtension( (Display *) jlong_to_ptr(display),
+ (int *) jlong_to_ptr(opcode_rtrn),
+ (int *) jlong_to_ptr(event_rtrn),
+ (int *) jlong_to_ptr(error_rtrn),
+ (int *) jlong_to_ptr(major_in_out),
+ (int *) jlong_to_ptr(minor_in_out));
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbLibraryVersion
+(JNIEnv *env, jclass clazz, jlong lib_major_in_out, jlong lib_minor_in_out)
+{
+ AWT_CHECK_HAVE_LOCK();
+ *((int *)lib_major_in_out) = XkbMajorVersion;
+ *((int *)lib_minor_in_out) = XkbMinorVersion;
+ return XkbLibraryVersion((int *)jlong_to_ptr(lib_major_in_out), (int *)jlong_to_ptr(lib_minor_in_out));
+}
+
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong device_spec)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return (jlong) XkbGetMap( (Display *) jlong_to_ptr(display),
+ (unsigned int) which,
+ (unsigned int) device_spec);
+}
+JNIEXPORT jlong JNICALL Java_sun_awt_X11_XlibWrapper_XkbGetUpdatedMap
+(JNIEnv *env, jclass clazz, jlong display, jlong which, jlong xkb)
+{
+ AWT_CHECK_HAVE_LOCK();
+ return (jlong) XkbGetUpdatedMap( (Display *) jlong_to_ptr(display),
+ (unsigned int) which,
+ (XkbDescPtr) jlong_to_ptr(xkb));
+}
+JNIEXPORT void JNICALL Java_sun_awt_X11_XlibWrapper_XkbFreeKeyboard
+(JNIEnv *env, jclass clazz, jlong xkb, jlong which, jboolean free_all)
+{
+ AWT_CHECK_HAVE_LOCK();
+ XkbFreeKeyboard(jlong_to_ptr(xkb), (unsigned int)which, free_all);
+}
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XlibWrapper_XkbTranslateKeyCode
+(JNIEnv *env, jclass clazz, jlong xkb, jint keycode, jlong mods, jlong mods_rtrn, jlong keysym_rtrn)
+{
+ Bool b;
+ b = XkbTranslateKeyCode((XkbDescPtr)xkb, (unsigned int)keycode, (unsigned int)mods,
+ (unsigned int *)jlong_to_ptr(mods_rtrn),
+ (KeySym *)jlong_to_ptr(keysym_rtrn));
+ //printf("native, input: keycode:0x%0X; mods:0x%0X\n", keycode, mods);
+ //printf("native, output: keysym:0x%0X; mods:0x%0X\n", *(unsigned int *)jlong_to_ptr(keysym_rtrn), *(unsigned int *)jlong_to_ptr(mods_rtrn));
+ return b;
+}
+
+
/*
* Class: sun_awt_X11_XlibWrapper
* Method: XNextEvent
@@ -1673,6 +1747,39 @@
}
JNIEXPORT jint JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbGetEffectiveGroup(JNIEnv *env, jclass clazz,
+ jlong display) {
+ XkbStateRec sr;
+ AWT_CHECK_HAVE_LOCK();
+ memset(&sr, 0, sizeof(XkbStateRec));
+ XkbGetState((Display*) jlong_to_ptr(display), XkbUseCoreKbd, &sr);
+// printf("-------------------------------------VVVV\n");
+// printf(" group:0x%0X\n",sr.group);
+// printf(" base_group:0x%0X\n",sr.base_group);
+// printf(" latched_group:0x%0X\n",sr.latched_group);
+// printf(" locked_group:0x%0X\n",sr.locked_group);
+// printf(" mods:0x%0X\n",sr.mods);
+// printf(" base_mods:0x%0X\n",sr.base_mods);
+// printf(" latched_mods:0x%0X\n",sr.latched_mods);
+// printf(" locked_mods:0x%0X\n",sr.locked_mods);
+// printf(" compat_state:0x%0X\n",sr.compat_state);
+// printf(" grab_mods:0x%0X\n",sr.grab_mods);
+// printf(" compat_grab_mods:0x%0X\n",sr.compat_grab_mods);
+// printf(" lookup_mods:0x%0X\n",sr.lookup_mods);
+// printf(" compat_lookup_mods:0x%0X\n",sr.compat_lookup_mods);
+// printf(" ptr_buttons:0x%0X\n",sr.ptr_buttons);
+// printf("-------------------------------------^^^^\n");
+ return (jint)(sr.group);
+}
+JNIEXPORT jlong JNICALL
+Java_sun_awt_X11_XlibWrapper_XkbKeycodeToKeysym(JNIEnv *env, jclass clazz,
+ jlong display, jint keycode,
+ jint group, jint level) {
+ AWT_CHECK_HAVE_LOCK();
+ return XkbKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (unsigned int)group, (unsigned int)level);
+}
+
+JNIEXPORT jint JNICALL
Java_sun_awt_X11_XlibWrapper_XKeysymToKeycode(JNIEnv *env, jclass clazz,
jlong display, jlong keysym) {
AWT_CHECK_HAVE_LOCK();
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp Fri Mar 27 12:01:24 2009 +0300
@@ -199,6 +199,8 @@
BOOL AwtComponent::sm_rtlReadingOrder =
PRIMARYLANGID(GetInputLanguage()) == LANG_ARABIC;
+BOOL AwtComponent::sm_PrimaryDynamicTableBuilt = FALSE;
+
HWND AwtComponent::sm_cursorOn;
BOOL AwtComponent::m_QueryNewPaletteCalled = FALSE;
@@ -245,6 +247,11 @@
m_MessagesProcessing = 0;
m_wheelRotationAmount = 0;
+ if (!sm_PrimaryDynamicTableBuilt) {
+ // do it once.
+ AwtComponent::BuildPrimaryDynamicTable();
+ sm_PrimaryDynamicTableBuilt = TRUE;
+ }
}
AwtComponent::~AwtComponent()
@@ -2892,6 +2899,19 @@
{0,0}
};
+// The full map of the current keyboard state including
+// windows virtual key, scancode, java virtual key, and unicode
+// for this key sans modifiers.
+// All but first element may be 0.
+// XXX in the update releases this is an addition to the unchanged existing code
+struct DynPrimaryKeymapEntry {
+ UINT wkey;
+ UINT scancode;
+ UINT jkey;
+ WCHAR unicode;
+};
+
+static DynPrimaryKeymapEntry dynPrimaryKeymap[256];
void
AwtComponent::InitDynamicKeyMapTable()
@@ -2900,6 +2920,8 @@
if (!kbdinited) {
AwtComponent::BuildDynamicKeyMapTable();
+ // We cannot build it here since JNI is not available yet:
+ //AwtComponent::BuildPrimaryDynamicTable();
kbdinited = TRUE;
}
}
@@ -3125,7 +3147,11 @@
for (int j = 0; dynamicKeyMapTable[j].windowsKey != 0; j++) {
if (dynamicKeyMapTable[j].windowsKey == windowsKey) {
- return dynamicKeyMapTable[j].javaKey;
+ if (dynamicKeyMapTable[j].javaKey != java_awt_event_KeyEvent_VK_UNDEFINED) {
+ return dynamicKeyMapTable[j].javaKey;
+ }else{
+ break;
+ }
}
}
@@ -3202,6 +3228,122 @@
return FALSE;
}
+static void
+resetKbdState( BYTE kstate[256]) {
+ BYTE tmpState[256];
+ WCHAR wc[2];
+ memmove(tmpState, kstate, sizeof(kstate));
+ tmpState[VK_SHIFT] = 0;
+ tmpState[VK_CONTROL] = 0;
+ tmpState[VK_MENU] = 0;
+
+ ::ToUnicodeEx(VK_SPACE,::MapVirtualKey(VK_SPACE, 0), tmpState, wc, 2, 0, GetKeyboardLayout(0));
+}
+
+// XXX in the update releases this is an addition to the unchanged existing code
+// After the call, a table will have a unicode associated with a windows virtual keycode
+// sans modifiers. With some further simplification, one can
+// derive java keycode from it, and anyway we will pass this unicode value
+// all the way up in a comment to a KeyEvent.
+void
+AwtComponent::BuildPrimaryDynamicTable() {
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ // XXX: how about that?
+ //CriticalSection::Lock l(GetLock());
+ //if (GetPeer(env) == NULL) {
+ // /* event received during termination. */
+ // return;
+ //}
+
+ HKL hkl = GetKeyboardLayout();
+ UINT sc = 0;
+ BYTE kbdState[AwtToolkit::KB_STATE_SIZE];
+ memset(kbdState, 0, sizeof (kbdState));
+
+ // Use JNI call to obtain java key code. We should keep a list
+ // of currently available keycodes in a single place.
+ static jclass extKeyCodesCls;
+ if( extKeyCodesCls == NULL) {
+ jclass extKeyCodesClsLocal = env->FindClass("sun/awt/ExtendedKeyCodes");
+ DASSERT(extKeyCodesClsLocal);
+ if (extKeyCodesClsLocal == NULL) {
+ /* exception already thrown */
+ return;
+ }
+ extKeyCodesCls = (jclass)env->NewGlobalRef(extKeyCodesClsLocal);
+ env->DeleteLocalRef(extKeyCodesClsLocal);
+ }
+ static jmethodID getExtendedKeyCodeForChar;
+ if (getExtendedKeyCodeForChar == NULL) {
+ getExtendedKeyCodeForChar =
+ env->GetStaticMethodID(extKeyCodesCls, "getExtendedKeyCodeForChar", "(I)I");
+ DASSERT(getExtendedKeyCodeForChar);
+ }
+ jint extJKC; //extended Java key code
+
+ for (UINT i = 0; i < 256; i++) {
+ dynPrimaryKeymap[i].wkey = i;
+ dynPrimaryKeymap[i].jkey = java_awt_event_KeyEvent_VK_UNDEFINED;
+ dynPrimaryKeymap[i].unicode = 0;
+
+ if ((sc = MapVirtualKey (i, 0)) == 0) {
+ dynPrimaryKeymap[i].scancode = 0;
+ continue;
+ }
+ dynPrimaryKeymap[i].scancode = sc;
+
+ // XXX process cases like VK_SHIFT etc.
+ kbdState[i] = 0x80; // "key pressed".
+ WCHAR wc[16];
+ int k = ::ToUnicodeEx(i, sc, kbdState, wc, 16, 0, hkl);
+ if (k == 1) {
+ // unicode
+ dynPrimaryKeymap[i].unicode = wc[0];
+ if (dynPrimaryKeymap[i].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {
+ // Convert unicode to java keycode.
+ //dynPrimaryKeymap[i].jkey = ((UINT)(wc[0]) + 0x01000000);
+ //
+ //XXX If this key in on the keypad, we should force a special value equal to
+ //XXX an old java keycode: but how to say if it is a keypad key?
+ //XXX We'll do it in WmKeyUp/Down.
+ extJKC = env->CallStaticIntMethod(extKeyCodesCls,
+ getExtendedKeyCodeForChar, (jint)(wc[0]));
+ dynPrimaryKeymap[i].jkey = extJKC;
+ }
+ }else if (k == -1) {
+ // dead key: use charToDeadVKTable
+ dynPrimaryKeymap[i].unicode = wc[0];
+ resetKbdState( kbdState );
+ for (const CharToVKEntry *map = charToDeadVKTable; map->c != 0; ++map) {
+ if (wc[0] == map->c) {
+ dynPrimaryKeymap[i].jkey = map->javaKey;
+ break;
+ }
+ }
+ } else if (k == 0) {
+ // reset
+ resetKbdState( kbdState );
+ }else {
+ printf ("++++Whats that? wkey 0x%x (%d)\n", i,i);
+ }
+ kbdState[i] = 0; // "key unpressed"
+ }
+}
+void
+AwtComponent::UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers)
+{
+ if( wkey && wkey < 256 ) {
+ if(keyLocation == java_awt_event_KeyEvent_KEY_LOCATION_NUMPAD) {
+ // At the creation time,
+ // dynPrimaryKeymap cannot distinguish between e.g. "/" and "NumPad /"
+ dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
+ }
+ if(dynPrimaryKeymap[wkey].jkey == java_awt_event_KeyEvent_VK_UNDEFINED) {
+ // E.g. it is non-unicode key
+ dynPrimaryKeymap[wkey].jkey = jkeyLegacy;
+ }
+ }
+}
UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
{
@@ -3358,10 +3500,12 @@
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
+
SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_PRESSED,
TimeHelper::windowsToUTC(msg.time), jkey, character,
- modifiers, keyLocation, &msg);
+ modifiers, keyLocation, (jlong)wkey, &msg);
// bugid 4724007: Windows does not create a WM_CHAR for the Del key
// for some reason, so we need to create the KEY_TYPED event on the
@@ -3373,7 +3517,7 @@
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
character, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN);
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0);
}
return mrConsume;
@@ -3398,10 +3542,11 @@
jint keyLocation = GetKeyLocation(wkey, flags);
UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
+ UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
TimeHelper::windowsToUTC(msg.time), jkey, character,
- modifiers, keyLocation, &msg);
+ modifiers, keyLocation, (jlong)wkey, &msg);
return mrConsume;
}
@@ -3417,6 +3562,7 @@
m_idLang = LOWORD(hKeyboardLayout); // lower word of HKL is LANGID
m_CodePage = LangToCodePage(m_idLang);
BuildDynamicKeyMapTable(); // compute new mappings for VK_OEM
+ BuildPrimaryDynamicTable();
return mrConsume; // do not propagate to children
}
@@ -3447,7 +3593,7 @@
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
unicodeChar, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
return mrConsume;
}
@@ -3516,7 +3662,7 @@
TimeHelper::windowsToUTC(msg.time),
java_awt_event_KeyEvent_VK_UNDEFINED,
unicodeChar, modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
return mrConsume;
}
@@ -4525,7 +4671,7 @@
}
void AwtComponent::SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation, MSG *pMsg)
+ jint modifiers, jint keyLocation, jlong nativeCode, MSG *pMsg)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
CriticalSection::Lock l(GetLock());
@@ -4562,6 +4708,18 @@
if (safe_ExceptionOccurred(env)) env->ExceptionDescribe();
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(keyEvent != NULL);
+ env->SetLongField(keyEvent, AwtKeyEvent::rawCodeID, nativeCode);
+ if( nativeCode && nativeCode < 256 ) {
+ env->SetLongField(keyEvent, AwtKeyEvent::primaryLevelUnicodeID, (jlong)(dynPrimaryKeymap[nativeCode].unicode));
+ env->SetLongField(keyEvent, AwtKeyEvent::extendedKeyCodeID, (jlong)(dynPrimaryKeymap[nativeCode].jkey));
+ if( nativeCode < 255 ) {
+ env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(dynPrimaryKeymap[nativeCode].scancode));
+ }else if( pMsg != NULL ) {
+ // unknown key with virtual keycode 0xFF.
+ // Its scancode is not in the table, pickup it from the message.
+ env->SetLongField(keyEvent, AwtKeyEvent::scancodeID, (jlong)(HIWORD(pMsg->lParam) & 0xFF));
+ }
+ }
if (pMsg != NULL) {
AwtAWTEvent::saveMSG(env, pMsg, keyEvent);
}
@@ -4575,6 +4733,7 @@
AwtComponent::SendKeyEventToFocusOwner(jint id, jlong when,
jint raw, jint cooked,
jint modifiers, jint keyLocation,
+ jlong nativeCode,
MSG *msg)
{
/*
@@ -4584,7 +4743,7 @@
HWND hwndTarget = ((sm_focusOwner != NULL) ? sm_focusOwner : AwtComponent::GetFocusedWindow());
if (hwndTarget == GetHWnd()) {
- SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, msg);
+ SendKeyEvent(id, when, raw, cooked, modifiers, keyLocation, nativeCode, msg);
} else {
AwtComponent *target = NULL;
if (hwndTarget != NULL) {
@@ -4595,7 +4754,7 @@
}
if (target != NULL) {
target->SendKeyEvent(id, when, raw, cooked, modifiers,
- keyLocation, msg);
+ keyLocation, nativeCode, msg);
}
}
}
--- a/jdk/src/windows/native/sun/windows/awt_Component.h Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h Fri Mar 27 12:01:24 2009 +0300
@@ -365,7 +365,7 @@
}
void SendKeyEventToFocusOwner(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation,
+ jint modifiers, jint keyLocation, jlong nativeCode,
MSG *msg = NULL);
/*
* Allocate and initialize a new java.awt.event.KeyEvent, and
@@ -373,7 +373,7 @@
* from the target.
*/
void SendKeyEvent(jint id, jlong when, jint raw, jint cooked,
- jint modifiers, jint keyLocation,
+ jint modifiers, jint keyLocation, jlong nativeCode,
MSG *msg = NULL);
/*
@@ -423,10 +423,6 @@
*/
virtual BOOL InheritsNativeMouseWheelBehavior();
- /* Functions for MouseWheel support on Windows95
- * These should only be called if running on 95
- */
-
/* Determines whether the component is obscured by another window */
// Called on Toolkit thread
static jboolean _IsObscured(void *param);
@@ -446,6 +442,7 @@
static UINT GetButtonMK(int mouseButton);
static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers);
static void JavaKeyToWindowsKey(UINT javaKey, UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey);
+ static void UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers);
INLINE static void AwtComponent::JavaKeyToWindowsKey(UINT javaKey,
UINT *windowsKey, UINT *modifiers)
@@ -787,6 +784,8 @@
static BOOL sm_rtl;
static BOOL sm_rtlReadingOrder;
+ static BOOL sm_PrimaryDynamicTableBuilt;
+
jobject m_InputMethod;
BOOL m_useNativeCompWindow;
LPARAM m_bitsCandType;
@@ -850,6 +849,7 @@
AwtComponent* SearchChild(UINT id);
void RemoveChild(UINT id) ;
static BOOL IsNavigationKey(UINT wkey);
+ static void BuildPrimaryDynamicTable();
ChildListItem* m_childList;
--- a/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -176,7 +176,7 @@
java_awt_event_KeyEvent_CHAR_UNDEFINED,
unicodeChar,
modifiers,
- java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN,
+ java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN, (jlong)0,
&msg);
} else {
MSG* pCopiedMsg = new MSG;
--- a/jdk/src/windows/native/sun/windows/awt_KeyEvent.cpp Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_KeyEvent.cpp Fri Mar 27 12:01:24 2009 +0300
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc. 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
@@ -32,6 +32,10 @@
jfieldID AwtKeyEvent::keyCodeID;
jfieldID AwtKeyEvent::keyCharID;
+jfieldID AwtKeyEvent::rawCodeID;
+jfieldID AwtKeyEvent::primaryLevelUnicodeID;
+jfieldID AwtKeyEvent::scancodeID;
+jfieldID AwtKeyEvent::extendedKeyCodeID;
/************************************************************************
* AwtKeyEvent native methods
@@ -45,9 +49,18 @@
AwtKeyEvent::keyCodeID = env->GetFieldID(cls, "keyCode", "I");
AwtKeyEvent::keyCharID = env->GetFieldID(cls, "keyChar", "C");
+ AwtKeyEvent::rawCodeID = env->GetFieldID(cls, "rawCode", "J");
+ AwtKeyEvent::primaryLevelUnicodeID = env->GetFieldID(cls, "primaryLevelUnicode", "J");
+ AwtKeyEvent::scancodeID = env->GetFieldID(cls, "scancode", "J");
+ AwtKeyEvent::extendedKeyCodeID = env->GetFieldID(cls, "extendedKeyCode", "J");
+
DASSERT(AwtKeyEvent::keyCodeID != NULL);
DASSERT(AwtKeyEvent::keyCharID != NULL);
+ DASSERT(AwtKeyEvent::rawCodeID != NULL);
+ DASSERT(AwtKeyEvent::primaryLevelUnicodeID != NULL);
+ DASSERT(AwtKeyEvent::scancodeID != NULL);
+ DASSERT(AwtKeyEvent::extendedKeyCodeID != NULL);
CATCH_BAD_ALLOC;
}
--- a/jdk/src/windows/native/sun/windows/awt_KeyEvent.h Thu Mar 26 14:38:46 2009 +0300
+++ b/jdk/src/windows/native/sun/windows/awt_KeyEvent.h Fri Mar 27 12:01:24 2009 +0300
@@ -39,7 +39,10 @@
/* java.awt.KeyEvent field ids */
static jfieldID keyCodeID;
static jfieldID keyCharID;
-
+ static jfieldID rawCodeID;
+ static jfieldID primaryLevelUnicodeID;
+ static jfieldID scancodeID;
+ static jfieldID extendedKeyCodeID;
};
#endif // AWT_KEYEVENT_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.html Fri Mar 27 12:01:24 2009 +0300
@@ -0,0 +1,20 @@
+<html>
+<!--
+ @test
+ @bug 6680988
+ @summary verify that various shortcuts and accelerators work
+ @author yuri.nesterenko : area=awt.keyboard
+ @run applet/manual=yesno AcceleratorTest.html
+ -->
+<head>
+<title> AcceleratorTest </title>
+</head>
+<body>
+
+<h1>AcceleratorTest<br>Bug ID: </h1>
+
+<p> See the dialog box (usually in upper left corner) for instructions</p>
+
+<APPLET CODE="AcceleratorTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.java Fri Mar 27 12:01:24 2009 +0300
@@ -0,0 +1,305 @@
+/*
+ test
+ @bug 6680988
+ @summary verify that various shortcuts and accelerators work
+ @author yuri.nesterenko : area=awt.keyboard
+ @run applet/manual=yesno AcceleratorTest.html
+*/
+
+/**
+ * AcceleratorTest.java
+ *
+ * summary:
+ */
+
+//import java.applet.Applet;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Hashtable;
+
+
+public class AcceleratorTest extends JApplet
+{
+ //Declare things used in the test, like buttons and labels here
+ static int pressed = 0;
+ Hashtable<String, Integer> cmdHash = new Hashtable<String, Integer>();
+ String[] CMD = {
+ "\u042E, keep me in focus",
+ "Item Cyrl Be",
+ "Item English Period",
+ "Item English N",
+ "\u0436"
+ };
+
+ JFrame jfr;
+
+ public void init()
+ {
+ //Create instructions for the user here, as well as set up
+ // the environment -- set the layout manager, add buttons,
+ // etc.
+ this.setLayout (new BorderLayout ());
+
+ String[] instructions =
+ {
+ " Ensure you have Russian keyboard layout as a currently active.",
+ "(1) Press Ctrl+\u0411 (a key with \",<\" on it) ",
+ "(2) Find a . (period) in this layout (perhaps \"/?\" or \"7&\" key).",
+ "Press Ctrl+.",
+ "(3) Press Crtl+ regular English . (period) key (on \".>\" )",
+ "(4) Press Ctrl+ key with English N.",
+ "(5) Press Alt+\u042E (key with \".>\")",
+ "(6) Press Alt+\u0436 (key with \";:\")",
+ "If all expected commands will be fired, look for message",
+ "\"All tests passed\""
+ };
+ Sysout.createDialogWithInstructions( instructions );
+ for(int i = 0; i < CMD.length; i++) {
+ cmdHash.put(CMD[i], 0);
+ }
+
+ jfr = new JFrame();
+ JButton jbu;
+ jfr.add((jbu = new JButton(CMD[0])));
+ jbu.setMnemonic(java.awt.event.KeyEvent.getExtendedKeyCodeForChar('\u042E'));
+ jbu.addActionListener( new ALi(CMD[0]));
+
+
+ JMenuBar menuBar = new JMenuBar();
+ jfr.setJMenuBar(menuBar);
+ JMenu menu = new JMenu("Menu");
+ menuBar.add(menu);
+
+ JMenuItem menuItem = new JMenuItem(CMD[1]);
+ menuItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.getExtendedKeyCodeForChar('\u0431'),
+ InputEvent.CTRL_DOWN_MASK));
+
+ JMenuItem menuItemEnglish = new JMenuItem(CMD[2]);
+ menuItemEnglish.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD,
+ InputEvent.CTRL_DOWN_MASK));
+ JMenuItem menuItemE1 = new JMenuItem(CMD[3]);
+ menuItemE1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
+ InputEvent.CTRL_DOWN_MASK));
+ menuItem.addActionListener( new ALi(CMD[1]));
+ menuItemEnglish.addActionListener( new ALi(CMD[2]));
+ menuItemE1.addActionListener( new ALi(CMD[3]));
+ menu.add(menuItem);
+ menu.add(menuItemEnglish);
+ menu.add(menuItemE1);
+
+ KeyStroke ks;
+ InputMap im = new InputMap();
+ ks = KeyStroke.getKeyStroke(KeyEvent.getExtendedKeyCodeForChar('\u0436'), java.awt.event.InputEvent.ALT_DOWN_MASK);
+ im.put(ks, "pushAction");
+ im.setParent(jbu.getInputMap(JComponent.WHEN_FOCUSED));
+ jbu.setInputMap(JComponent.WHEN_FOCUSED, im);
+
+ jbu.getActionMap().put("pushAction",
+ new AbstractAction("pushAction") {
+ public void actionPerformed(ActionEvent evt) {
+ if( evt.getActionCommand().equals(CMD[4])) {
+ cmdHash.put(CMD[4], 1);
+ }
+ boolean notYet = false;
+ for(int i = 0; i < CMD.length; i++) {
+ if(cmdHash.get(CMD[i]) == 0 ) notYet = true;
+ }
+ Sysout.println("Fired");
+ if( !notYet ) {
+ Sysout.println("All tests passed.");
+ }
+ }
+ }
+ );
+
+
+ jfr.setBounds(650,0,200,200);
+ jfr.setVisible(true);
+
+ }//End init()
+
+ public void start ()
+ {
+ //Get things going. Request focus, set size, et cetera
+ setSize (200,200);
+ setVisible(true);
+ validate();
+
+ }// start()
+ public class ALi implements ActionListener {
+ String expectedCmd;
+ public ALi( String eCmd ) {
+ expectedCmd = eCmd;
+ }
+ public void actionPerformed(ActionEvent ae) {
+ if( cmdHash.containsKey(ae.getActionCommand()) ) {
+ cmdHash.put(expectedCmd, 1);
+ }
+ boolean notYet = false;
+ for(int i = 0; i < CMD.length; i++) {
+ if(cmdHash.get(CMD[i]) == 0 ) notYet = true;
+ //Sysout.println(CMD[i]+":"+cmdHash.get(CMD[i]));
+ }
+ Sysout.println("FIRED");
+ if( !notYet ) {
+ Sysout.println("All tests passed.");
+ }
+ }
+ }
+
+
+}// class AcceleratorTest
+
+/* Place other classes related to the test after this line */
+
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout
+{
+ private static TestDialog dialog;
+ private static boolean numbering = false;
+ private static int messageNumber = 0;
+
+ public static void createDialogWithInstructions( String[] instructions )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ dialog.printInstructions( instructions );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ public static void createDialog( )
+ {
+ dialog = new TestDialog( new Frame(), "Instructions" );
+ String[] defInstr = { "Instructions will appear here. ", "" } ;
+ dialog.printInstructions( defInstr );
+ dialog.setVisible(true);
+ println( "Any messages for the tester will display here." );
+ }
+
+ /* Enables message counting for the tester. */
+ public static void enableNumbering(boolean enable){
+ numbering = enable;
+ }
+
+ public static void printInstructions( String[] instructions )
+ {
+ dialog.printInstructions( instructions );
+ }
+
+
+ public static void println( String messageIn )
+ {
+ if (numbering) {
+ messageIn = "" + messageNumber + " " + messageIn;
+ messageNumber++;
+ }
+ dialog.displayMessage( messageIn );
+ }
+
+}// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog( Frame frame, String name )
+ {
+ super( frame, name );
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+ add( "North", instructionsText );
+
+ messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+ add("Center", messageText);
+
+ pack();
+
+ setVisible(true);
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions( String[] instructions )
+ {
+ //Clear out any current instructions
+ instructionsText.setText( "" );
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for( int i=0; i < instructions.length; i++ )
+ {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[ i ];
+ while( remainingStr.length() > 0 )
+ {
+ //if longer than max then chop off first max chars to print
+ if( remainingStr.length() >= maxStringLength )
+ {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf( ' ', maxStringLength - 1 );
+
+ if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+ printStr = remainingStr.substring( 0, posOfSpace + 1 );
+ remainingStr = remainingStr.substring( posOfSpace + 1 );
+ }
+ //else just print
+ else
+ {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append( printStr + "\n" );
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage( String messageIn )
+ {
+ messageText.append( messageIn + "\n" );
+ System.out.println(messageIn);
+ }
+
+}// TestDialog class