Index: gdkkeys-x11.c
===================================================================
RCS file: /afs/dev.mit.edu/source/repository/third/gtk2/gdk/x11/gdkkeys-x11.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 gdkkeys-x11.c
--- gdkkeys-x11.c	25 Dec 2002 18:44:42 -0000	1.1.1.1
+++ gdkkeys-x11.c	1 Aug 2003 16:33:35 -0000
@@ -70,6 +70,7 @@
   guint lock_keysym;
   GdkModifierType group_switch_mask;
   GdkModifierType num_lock_mask;
+  gint num_lock_index;
   PangoDirection current_direction;
   gboolean have_direction;
   guint current_serial;
@@ -124,6 +125,7 @@
   keymap->mod_keymap = NULL;
   
   keymap->num_lock_mask = 0;
+  keymap->num_lock_index = 1;
   keymap->group_switch_mask = 0;
   keymap->lock_keysym = GDK_Caps_Lock;
   keymap->have_direction = FALSE;
@@ -226,6 +228,8 @@
       gint i;
       gint map_size;
       gint keycode;
+      KeyCode *lock_keys;
+      char *server_vendor;
 
       keymap_x11->current_serial = display_x11->keymap_serial;
       
@@ -285,6 +289,38 @@
       keymap_x11->group_switch_mask = 0;
       keymap_x11->num_lock_mask = 0;
 
+      /* Get the Lock keysym.  The Lock modifiers are the second set
+       * in the modifier map.
+       */
+      lock_keys = keymap_x11->mod_keymap->modifiermap + (1 * keymap_x11->mod_keymap->max_keypermod);
+      for (i = 0; i < keymap_x11->mod_keymap->max_keypermod; i++)
+        {
+          gint keycode = lock_keys[i];
+      
+          if (keycode >= keymap_x11->min_keycode &&
+              keycode <= keymap_x11->max_keycode)
+            {
+              gint j;
+              KeySym *syms;
+              
+              syms = keymap_x11->keymap + (keycode - keymap_x11->min_keycode) * keymap_x11->keysyms_per_keycode;
+
+              for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)
+                {
+                  /* If any Lock keysym is Caps_Lock, we will interpret
+                   * Lock as Caps_Lock; otherwise, if any is Shift_Lock,
+                   * we will interpret Lock as Shift_Lock.
+                   */
+                  if (syms[j] == GDK_Caps_Lock || syms[j] == GDK_Shift_Lock)
+                    {
+                      keymap_x11->lock_keysym = syms[j];
+                      if (keymap_x11->lock_keysym == GDK_Caps_Lock)
+                        break;
+                    }
+                }
+            }
+        }
+
       /* there are 8 modifiers, and the first 3 are shift, shift lock,
        * and control
        */
@@ -309,17 +345,6 @@
 	       */
 	      guint mask = 1 << ( i / keymap_x11->mod_keymap->max_keypermod);
 
-	      if (mask == GDK_LOCK_MASK)
-		{
-		  for (j = 0; j < keymap_x11->keysyms_per_keycode; j++)
-		    {
-		      if (syms[j] == GDK_Caps_Lock)
-			keymap_x11->lock_keysym = syms[j];
-		      else if (syms[j] == GDK_Shift_Lock && keymap_x11->lock_keysym == GDK_VoidSymbol)
-			keymap_x11->lock_keysym = syms[j];
-		    }
-		}
-	      
 	      /* Some keyboard maps are known to map Mode_Switch as an extra
 	       * Mod1 key. In circumstances like that, it won't be used to
 	       * switch groups.
@@ -348,6 +373,17 @@
 	next:
           ++i;
         }
+
+      /* Hack: The Sun X server puts the keysym to use when the Num Lock
+       * modifier is on in the third element of the keysym array, instead
+       * of the second.
+       */
+      server_vendor = ServerVendor (xdisplay);
+      if (server_vendor &&
+          (strcmp (server_vendor, "Sun Microsystems, Inc.") == 0))
+        keymap_x11->num_lock_index = 2;
+      else
+        keymap_x11->num_lock_index = 1;
     }
 }
 
@@ -980,13 +1016,14 @@
       (SYM (keymap_x11, 0, 0) || SYM (keymap_x11, 0, 1)))
     group = 0;
 
-  if ((state & GDK_SHIFT_MASK) != 0 &&
-      KEYSYM_IS_KEYPAD (SYM (keymap_x11, group, 1)))
+  if ((state & keymap_x11->num_lock_mask) &&
+      KEYSYM_IS_KEYPAD (SYM (keymap_x11, group, keymap_x11->num_lock_index)))
     {
       /* Shift, Shift_Lock cancel Num_Lock
        */
-       shift_level = (state & shift_modifiers) ? 0 : 1;
-      
+       shift_level = ((state & shift_modifiers) ||
+                      !SYM (keymap_x11, group, keymap_x11->num_lock_index))
+         ? 0 : keymap_x11->num_lock_index;
        tmp_keyval = SYM (keymap_x11, group, shift_level);
     }
   else
@@ -1000,7 +1037,7 @@
   
       tmp_keyval = SYM (keymap_x11, group, shift_level);
       
-      if (keymap_x11->lock_keysym == GDK_Caps_Lock && (state & GDK_SHIFT_MASK) != 0)
+      if (keymap_x11->lock_keysym == GDK_Caps_Lock && (state & GDK_LOCK_MASK) != 0)
 	{
 	  guint upper = gdk_keyval_to_upper (tmp_keyval);
 	  if (upper != tmp_keyval)
