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

Reply via email to