Hi,
This patch was in our bugzilla for a long time and Cameron's paperwork
was on file already. Sorry this took so long Cameron. The patch
implements the key lock state support in the gtk+ awt Toolkit. This is
needed for Batik's DOM UIEvents. BTW Batik's Squiggle SVG browser seems
to work pretty nicely.
2007-01-03 Cameron McCormack <[EMAIL PROTECTED]>
Fixes bug #29246
* java/awt/Toolkit.java (getLockingKeyState): Use AWTUtilities
isValidKey method. Throw UnsupportedOperationException on a valid
key (for which no locking state can be given).
* gnu/java/awt/AWTUtilities.java (isValidKey): New method.
* gnu/java/awt/peer/gtk/GtkToolkit.java (getLockingKeyState): New
method.
* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
(Java_gnu_java_awt_peer_gtk_GtkToolkit_getLockState): New method.
* include/gnu_java_awt_peer_gtk_GtkToolkit.h: Regenerated.
Committed,
Mark
Index: java/awt/Toolkit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Toolkit.java,v
retrieving revision 1.48
diff -u -r1.48 Toolkit.java
--- java/awt/Toolkit.java 10 Dec 2006 20:25:43 -0000 1.48
+++ java/awt/Toolkit.java 3 Jan 2007 21:39:18 -0000
@@ -1,5 +1,5 @@
/* Toolkit.java -- AWT Toolkit superclass
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,6 +40,7 @@
package java.awt;
import gnu.classpath.SystemProperties;
+import gnu.java.awt.AWTUtilities;
import gnu.java.awt.peer.GLightweightPeer;
import gnu.java.awt.peer.headless.HeadlessToolkit;
@@ -802,12 +803,11 @@
*/
public boolean getLockingKeyState(int keyCode)
{
- if (keyCode != KeyEvent.VK_CAPS_LOCK
- && keyCode != KeyEvent.VK_NUM_LOCK
- && keyCode != KeyEvent.VK_SCROLL_LOCK)
- throw new IllegalArgumentException();
-
- throw new UnsupportedOperationException();
+ if (AWTUtilities.isValidKey(keyCode))
+ throw new UnsupportedOperationException
+ ("cannot get locking state of key code " + keyCode);
+
+ throw new IllegalArgumentException("invalid key code " + keyCode);
}
/**
Index: gnu/java/awt/AWTUtilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/AWTUtilities.java,v
retrieving revision 1.6
diff -u -r1.6 AWTUtilities.java
--- gnu/java/awt/AWTUtilities.java 12 Sep 2005 16:17:14 -0000 1.6
+++ gnu/java/awt/AWTUtilities.java 3 Jan 2007 21:39:18 -0000
@@ -1,5 +1,5 @@
/* AWTUtilities.java -- Common utility methods for AWT and Swing.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -47,6 +47,7 @@
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
+import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.AbstractSequentialList;
import java.util.List;
@@ -694,4 +695,204 @@
{
return java.awt.EventQueue.isDispatchThread();
}
+
+ /**
+ * Returns whether the specified key code is valid.
+ */
+ public static boolean isValidKey(int keyCode)
+ {
+ switch (keyCode)
+ {
+ case KeyEvent.VK_ENTER:
+ case KeyEvent.VK_BACK_SPACE:
+ case KeyEvent.VK_TAB:
+ case KeyEvent.VK_CANCEL:
+ case KeyEvent.VK_CLEAR:
+ case KeyEvent.VK_SHIFT:
+ case KeyEvent.VK_CONTROL:
+ case KeyEvent.VK_ALT:
+ case KeyEvent.VK_PAUSE:
+ case KeyEvent.VK_CAPS_LOCK:
+ case KeyEvent.VK_ESCAPE:
+ case KeyEvent.VK_SPACE:
+ case KeyEvent.VK_PAGE_UP:
+ case KeyEvent.VK_PAGE_DOWN:
+ case KeyEvent.VK_END:
+ case KeyEvent.VK_HOME:
+ case KeyEvent.VK_LEFT:
+ case KeyEvent.VK_UP:
+ case KeyEvent.VK_RIGHT:
+ case KeyEvent.VK_DOWN:
+ case KeyEvent.VK_COMMA:
+ case KeyEvent.VK_MINUS:
+ case KeyEvent.VK_PERIOD:
+ case KeyEvent.VK_SLASH:
+ case KeyEvent.VK_0:
+ case KeyEvent.VK_1:
+ case KeyEvent.VK_2:
+ case KeyEvent.VK_3:
+ case KeyEvent.VK_4:
+ case KeyEvent.VK_5:
+ case KeyEvent.VK_6:
+ case KeyEvent.VK_7:
+ case KeyEvent.VK_8:
+ case KeyEvent.VK_9:
+ case KeyEvent.VK_SEMICOLON:
+ case KeyEvent.VK_EQUALS:
+ case KeyEvent.VK_A:
+ case KeyEvent.VK_B:
+ case KeyEvent.VK_C:
+ case KeyEvent.VK_D:
+ case KeyEvent.VK_E:
+ case KeyEvent.VK_F:
+ case KeyEvent.VK_G:
+ case KeyEvent.VK_H:
+ case KeyEvent.VK_I:
+ case KeyEvent.VK_J:
+ case KeyEvent.VK_K:
+ case KeyEvent.VK_L:
+ case KeyEvent.VK_M:
+ case KeyEvent.VK_N:
+ case KeyEvent.VK_O:
+ case KeyEvent.VK_P:
+ case KeyEvent.VK_Q:
+ case KeyEvent.VK_R:
+ case KeyEvent.VK_S:
+ case KeyEvent.VK_T:
+ case KeyEvent.VK_U:
+ case KeyEvent.VK_V:
+ case KeyEvent.VK_W:
+ case KeyEvent.VK_X:
+ case KeyEvent.VK_Y:
+ case KeyEvent.VK_Z:
+ case KeyEvent.VK_OPEN_BRACKET:
+ case KeyEvent.VK_BACK_SLASH:
+ case KeyEvent.VK_CLOSE_BRACKET:
+ case KeyEvent.VK_NUMPAD0:
+ case KeyEvent.VK_NUMPAD1:
+ case KeyEvent.VK_NUMPAD2:
+ case KeyEvent.VK_NUMPAD3:
+ case KeyEvent.VK_NUMPAD4:
+ case KeyEvent.VK_NUMPAD5:
+ case KeyEvent.VK_NUMPAD6:
+ case KeyEvent.VK_NUMPAD7:
+ case KeyEvent.VK_NUMPAD8:
+ case KeyEvent.VK_NUMPAD9:
+ case KeyEvent.VK_MULTIPLY:
+ case KeyEvent.VK_ADD:
+ case KeyEvent.VK_SEPARATOR:
+ case KeyEvent.VK_SUBTRACT:
+ case KeyEvent.VK_DECIMAL:
+ case KeyEvent.VK_DIVIDE:
+ case KeyEvent.VK_DELETE:
+ case KeyEvent.VK_NUM_LOCK:
+ case KeyEvent.VK_SCROLL_LOCK:
+ case KeyEvent.VK_F1:
+ case KeyEvent.VK_F2:
+ case KeyEvent.VK_F3:
+ case KeyEvent.VK_F4:
+ case KeyEvent.VK_F5:
+ case KeyEvent.VK_F6:
+ case KeyEvent.VK_F7:
+ case KeyEvent.VK_F8:
+ case KeyEvent.VK_F9:
+ case KeyEvent.VK_F10:
+ case KeyEvent.VK_F11:
+ case KeyEvent.VK_F12:
+ case KeyEvent.VK_F13:
+ case KeyEvent.VK_F14:
+ case KeyEvent.VK_F15:
+ case KeyEvent.VK_F16:
+ case KeyEvent.VK_F17:
+ case KeyEvent.VK_F18:
+ case KeyEvent.VK_F19:
+ case KeyEvent.VK_F20:
+ case KeyEvent.VK_F21:
+ case KeyEvent.VK_F22:
+ case KeyEvent.VK_F23:
+ case KeyEvent.VK_F24:
+ case KeyEvent.VK_PRINTSCREEN:
+ case KeyEvent.VK_INSERT:
+ case KeyEvent.VK_HELP:
+ case KeyEvent.VK_META:
+ case KeyEvent.VK_BACK_QUOTE:
+ case KeyEvent.VK_QUOTE:
+ case KeyEvent.VK_KP_UP:
+ case KeyEvent.VK_KP_DOWN:
+ case KeyEvent.VK_KP_LEFT:
+ case KeyEvent.VK_KP_RIGHT:
+ case KeyEvent.VK_DEAD_GRAVE:
+ case KeyEvent.VK_DEAD_ACUTE:
+ case KeyEvent.VK_DEAD_CIRCUMFLEX:
+ case KeyEvent.VK_DEAD_TILDE:
+ case KeyEvent.VK_DEAD_MACRON:
+ case KeyEvent.VK_DEAD_BREVE:
+ case KeyEvent.VK_DEAD_ABOVEDOT:
+ case KeyEvent.VK_DEAD_DIAERESIS:
+ case KeyEvent.VK_DEAD_ABOVERING:
+ case KeyEvent.VK_DEAD_DOUBLEACUTE:
+ case KeyEvent.VK_DEAD_CARON:
+ case KeyEvent.VK_DEAD_CEDILLA:
+ case KeyEvent.VK_DEAD_OGONEK:
+ case KeyEvent.VK_DEAD_IOTA:
+ case KeyEvent.VK_DEAD_VOICED_SOUND:
+ case KeyEvent.VK_DEAD_SEMIVOICED_SOUND:
+ case KeyEvent.VK_AMPERSAND:
+ case KeyEvent.VK_ASTERISK:
+ case KeyEvent.VK_QUOTEDBL:
+ case KeyEvent.VK_LESS:
+ case KeyEvent.VK_GREATER:
+ case KeyEvent.VK_BRACELEFT:
+ case KeyEvent.VK_BRACERIGHT:
+ case KeyEvent.VK_AT:
+ case KeyEvent.VK_COLON:
+ case KeyEvent.VK_CIRCUMFLEX:
+ case KeyEvent.VK_DOLLAR:
+ case KeyEvent.VK_EURO_SIGN:
+ case KeyEvent.VK_EXCLAMATION_MARK:
+ case KeyEvent.VK_INVERTED_EXCLAMATION_MARK:
+ case KeyEvent.VK_LEFT_PARENTHESIS:
+ case KeyEvent.VK_NUMBER_SIGN:
+ case KeyEvent.VK_PLUS:
+ case KeyEvent.VK_RIGHT_PARENTHESIS:
+ case KeyEvent.VK_UNDERSCORE:
+ case KeyEvent.VK_FINAL:
+ case KeyEvent.VK_CONVERT:
+ case KeyEvent.VK_NONCONVERT:
+ case KeyEvent.VK_ACCEPT:
+ case KeyEvent.VK_MODECHANGE:
+ case KeyEvent.VK_KANA:
+ case KeyEvent.VK_KANJI:
+ case KeyEvent.VK_ALPHANUMERIC:
+ case KeyEvent.VK_KATAKANA:
+ case KeyEvent.VK_HIRAGANA:
+ case KeyEvent.VK_FULL_WIDTH:
+ case KeyEvent.VK_HALF_WIDTH:
+ case KeyEvent.VK_ROMAN_CHARACTERS:
+ case KeyEvent.VK_ALL_CANDIDATES:
+ case KeyEvent.VK_PREVIOUS_CANDIDATE:
+ case KeyEvent.VK_CODE_INPUT:
+ case KeyEvent.VK_JAPANESE_KATAKANA:
+ case KeyEvent.VK_JAPANESE_HIRAGANA:
+ case KeyEvent.VK_JAPANESE_ROMAN:
+ case KeyEvent.VK_KANA_LOCK:
+ case KeyEvent.VK_INPUT_METHOD_ON_OFF:
+ case KeyEvent.VK_CUT:
+ case KeyEvent.VK_COPY:
+ case KeyEvent.VK_PASTE:
+ case KeyEvent.VK_UNDO:
+ case KeyEvent.VK_AGAIN:
+ case KeyEvent.VK_FIND:
+ case KeyEvent.VK_PROPS:
+ case KeyEvent.VK_STOP:
+ case KeyEvent.VK_COMPOSE:
+ case KeyEvent.VK_ALT_GRAPH:
+ case KeyEvent.VK_BEGIN:
+ case KeyEvent.VK_CONTEXT_MENU:
+ case KeyEvent.VK_WINDOWS:
+ return true;
+ default:
+ return false;
+ }
+ }
}
Index: gnu/java/awt/peer/gtk/GtkToolkit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,v
retrieving revision 1.98
diff -u -r1.98 GtkToolkit.java
--- gnu/java/awt/peer/gtk/GtkToolkit.java 6 Dec 2006 22:21:17 -0000 1.98
+++ gnu/java/awt/peer/gtk/GtkToolkit.java 3 Jan 2007 21:39:18 -0000
@@ -1,5 +1,5 @@
/* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
- Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006
+ Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@
package gnu.java.awt.peer.gtk;
+import gnu.java.awt.AWTUtilities;
import gnu.java.awt.EmbeddedWindow;
import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer;
import gnu.java.awt.dnd.peer.gtk.GtkDragSourceContextPeer;
@@ -84,6 +85,7 @@
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
+import java.awt.event.KeyEvent;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.im.InputMethodHighlight;
@@ -668,6 +670,22 @@
return new GdkRobotPeer (screen);
}
+ public boolean getLockingKeyState(int keyCode)
+ {
+ int state = getLockState(keyCode);
+
+ if (state != -1)
+ return state == 1;
+
+ if (AWTUtilities.isValidKey(keyCode))
+ throw new UnsupportedOperationException
+ ("cannot get locking state of key code " + keyCode);
+
+ throw new IllegalArgumentException("invalid key code " + keyCode);
+ }
+
+ protected native int getLockState(int keyCode);
+
public void registerImageIOSpis(IIORegistry reg)
{
GdkPixbufDecoder.registerSpis(reg);
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c,v
retrieving revision 1.30
diff -u -r1.30 gnu_java_awt_peer_gtk_GtkToolkit.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c 17 Oct 2006 23:22:56 -0000 1.30
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c 3 Jan 2007 21:39:18 -0000
@@ -1,5 +1,5 @@
/* gtktoolkit.c -- Native portion of GtkToolkit
- Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2005, 2007 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -73,6 +73,12 @@
#define AWT_INFO_TEXT 25
#define AWT_NUM_COLORS 26
+#define VK_SHIFT 16
+#define VK_CONTROL 17
+#define VK_ALT 18
+#define VK_CAPS_LOCK 20
+#define VK_META 157
+
struct state_table *cp_gtk_native_state_table;
struct state_table *cp_gtk_native_global_ref_table;
@@ -514,6 +520,53 @@
return (jint) (0xff000000 | (red << 16) | (green << 8) | blue);
}
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkToolkit_getLockState
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jint key)
+{
+ gint coord;
+ GdkModifierType state, mask;
+ GdkWindow *root_window;
+
+ gdk_threads_enter ();
+
+ root_window = gdk_get_default_root_window ();
+ gdk_window_get_pointer (root_window, &coord, &coord, &state);
+
+ switch (key)
+ {
+ case VK_SHIFT:
+ mask = GDK_SHIFT_MASK;
+ break;
+ case VK_CONTROL:
+ mask = GDK_CONTROL_MASK;
+ break;
+ case VK_ALT:
+ /* This is dubious, since MOD1 could have been mapped to something
+ other than ALT. */
+ mask = GDK_MOD1_MASK;
+ break;
+#if GTK_CHECK_VERSION(2, 10, 0)
+ case VK_META:
+ mask = GDK_META_MASK;
+ break;
+#endif
+ case VK_CAPS_LOCK:
+ mask = GDK_LOCK_MASK;
+ break;
+ default:
+ mask = 0;
+ }
+
+ gdk_threads_leave ();
+
+ if (mask == 0)
+ return -1;
+
+ return state & mask ? 1 : 0;
+}
+
static gboolean
post_set_running_flag (gpointer data __attribute__((unused)))
{
Index: include/gnu_java_awt_peer_gtk_GtkToolkit.h
===================================================================
RCS file: /cvsroot/classpath/classpath/include/gnu_java_awt_peer_gtk_GtkToolkit.h,v
retrieving revision 1.14
diff -u -r1.14 gnu_java_awt_peer_gtk_GtkToolkit.h
--- include/gnu_java_awt_peer_gtk_GtkToolkit.h 21 Aug 2006 23:34:45 -0000 1.14
+++ include/gnu_java_awt_peer_gtk_GtkToolkit.h 3 Jan 2007 21:39:18 -0000
@@ -18,6 +18,7 @@
JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_getScreenResolution (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_sync (JNIEnv *env, jobject);
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_loadSystemColors (JNIEnv *env, jobject, jintArray);
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_getLockState (JNIEnv *env, jobject, jint);
JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkToolkit_getMouseNumberOfButtons (JNIEnv *env, jobject);
#ifdef __cplusplus