Index: src/orca/orca.py
===================================================================
--- src/orca/orca.py	(revision 2343)
+++ src/orca/orca.py	(working copy)
@@ -667,14 +667,40 @@
 
     keyboardEvent = KeyboardEvent(event)
 
-    # See if this is one of our special Orca modifiers (e.g., "Insert")
+    # See if this is one of our special Orca modifier keys.
     #
-    orcaModifierKeys = settings.orcaModifierKeys
-    orcaModifierKeycodes = []
-    for keysym in orcaModifierKeys:
-        orcaModifierKeycodes.append(keybindings.getKeycode(keysym))
-    isOrcaModifier = orcaModifierKeycodes.count(keyboardEvent.hw_code) > 0
+    # [[[TODO: WDW - Note that just looking at the keycode should
+    # suffice, but there is a "feature" in the Java Access Bridge
+    # where it chooses to emit Java platform-independent keycodes
+    # instead of the keycodes for the base platform:
+    #
+    # http://bugzilla.gnome.org/show_bug.cgi?id=106004
+    # http://bugzilla.gnome.org/show_bug.cgi?id=318615
+    #
+    # So...we need to workaround this problem.
+    #
+    # If you make the following expression True we will get a positive
+    # match for all keysyms associated with a given keysym specified
+    # as an Orca modifier key.
+    #
+    # For example, assume the Orca modifier is set to \ for some
+    # reason.  The key that has \ on it produces \ without the Shift
+    # key and | with the Shift key.  If the following expression is
+    # True, both the \ and | will be viewed as the Orca modifier.  If
+    # the following expression is False, only the \ will be viewed as
+    # the Orca modifier (i.e., Shift+\ will still function as the |
+    # character).  In general, I think we want to avoid sucking in all
+    # possible keysyms because it can have unexpected results.]]]
+    #
+    if False:
+        allPossibleKeysyms = []
+        for keysym in settings.orcaModifierKeys:
+            allPossibleKeysyms.extend(keybindings.getAllKeysyms(keysym))
+    else:
+        allPossibleKeysyms = settings.orcaModifierKeys
 
+    isOrcaModifier = allPossibleKeysyms.count(keyboardEvent.event_string) > 0
+
     if event.type == atspi.Accessibility.KEY_PRESSED_EVENT:
         # Key presses always interrupt speech.
         #
@@ -882,9 +908,30 @@
         debug.println(debug.LEVEL_CONFIGURATION,
                       "Magnification module has NOT been initialized.")
 
+    # We don't want the Caps_Lock modifier to act as a locking
+    # modifier if it used as the Orca modifier key.  In addition, if
+    # the KP_Insert key is used as the Orca modifier key, we want to
+    # make sure we clear any other keysyms that might be in use on
+    # that key since we won't be able to detect them as being the Orca
+    # modifier key.  For example, KP_Insert produces "KP_Insert" when
+    # pressed by itself, but Shift+KP_Insert produces "0".
+    #
+    # The original values are saved/reset in the orca shell script.
+    #
+    # [[[TODO: WDW - we probably should just to a 'xmodmap -e "%s = %s"'
+    # for all of the orcaModifierKeys, but saving/restoring the values
+    # becomes a little more difficult.  If we could assume a writeable
+    # filesystem (we cannot), we could do a 'xmodmap -pke > /tmp/foo'
+    # to save the keymap and a 'xmodmap /tmp/foo' to restore it.
+    # For now, we'll just look at the Orca modifier keys we support
+    # (Caps Lock, KP_Insert, and Insert).]]]
+    #
     for keyName in settings.orcaModifierKeys:
         if keyName == "Caps_Lock":
             os.system('xmodmap -e "clear Lock"')
+        if keyName in ["Caps_Lock", "KP_Insert", "Insert"]:
+            command = 'xmodmap -e "keysym %s = %s"' % (keyName, keyName)
+            os.system(command)
 
     if _currentPresentationManager >= 0:
         _PRESENTATION_MANAGERS[_currentPresentationManager].activate()
Index: src/orca/orca.in
===================================================================
--- src/orca/orca.in	(revision 2343)
+++ src/orca/orca.in	(working copy)
@@ -99,17 +99,37 @@
     export PYTHONPATH
 
     # We'll save and restore the Caps_Lock as a modifier just in case
-    # the user is using the Caps_Lock as the Orca modifier key.
+    # the user is using the Caps_Lock as the Orca modifier key.  We
+    # will also do so with the KP_Insert key since we want to make
+    # sure it only produces the keysyms we expect (it produces
+    # KP_Insert and KP_0 by default).  See the use of xmodmap in
+    # orca.py:loadUserSettings for the other part of what's going on.
+    # 
+    # [[[WDW: we probably should save/restore the autorepeat value of
+    # the Orca modifier key and turn the autorepeat off when Orca is
+    # running.  That can be done using the 'xset' utility, though
+    # turning it on/off is easy, but getting the current state is not
+    # straightforward.]]]
     #
     if [ "x$DISPLAY" != "x" ]
     then
         CAPSLOCKSETTING=`xmodmap | grep Caps_Lock | cut -f1`
+        KPINSERTSETTING=`xmodmap -pke | grep KP_Insert`
+        INSERTSETTING=`xmodmap -pke | grep Insert | grep -v KP_`
     fi
     @PYTHON@ -c "import orca.orca; orca.orca.main()" "$ARGS"
     if [ "x$CAPSLOCKSETTING" != "x" ]
     then
-        xmodmap -e "add $CAPSLOCKSETTING = Caps_Lock"
+        xmodmap -e "add $CAPSLOCKSETTING = Caps_Lock" > /dev/null 2>&1
     fi
+    if [ "x$KPINSERTSETTING" != "x" ]
+    then
+        xmodmap -e "$KPINSERTSETTING" > /dev/null 2>&1
+    fi
+    if [ "x$INSERTSETTING" != "x" ]
+    then
+        xmodmap -e "$INSERTSETTING" > /dev/null 2>&1
+    fi
 }
 
 # Runs a watchdog process in the background.  It merely attempts to
Index: src/orca/keybindings.py
===================================================================
--- src/orca/keybindings.py	(revision 2343)
+++ src/orca/keybindings.py	(working copy)
@@ -42,8 +42,53 @@
 
 from orca_i18n import _           # for gettext support
 
+_keysymsCache = {}
 _keycodeCache = {}
 
+def getAllKeysyms(keysym):
+    """Given a keysym, find all other keysyms associated with the key
+    that is mapped to the given keysym.  This allows us, for example,
+    to determine that the key bound to KP_Insert is also bound to KP_0."""
+
+    if not _keysymsCache.has_key(keysym):
+        # The keysym itself is always part of the list.
+        #
+        _keysymsCache[keysym] = [keysym]
+
+        # Find the numerical value of the keysym
+        #
+        keyval = gtk.gdk.keyval_from_name(keysym)
+
+        if keyval != 0:
+            # Find the keycodes for the keysym.  Since a keysym
+            # can be associated with more than one key, we'll shoot
+            # for the keysym that's in group 0, regardless of shift
+            # level (each entry is of the form [keycode, group,
+            # level]).
+            #
+            keymap = gtk.gdk.keymap_get_default()
+            entries = keymap.get_entries_for_keyval(keyval)
+            keycode = 0
+            if entries:
+                for entry in entries:
+                    if entry[1] == 0:  # group = 0
+                        keycode = entry[0]
+                        break
+
+            # Find the keysyms bound to the keycode.  These are what
+            # we are looking for.
+            #
+            if keycode != 0:
+                entries = keymap.get_entries_for_keycode(keycode)
+                if entries:
+                    for entry in entries:
+                        keyval = entry[0]
+                        name = gtk.gdk.keyval_name(keyval)
+                        if name and (name != keysym):
+                            _keysymsCache[keysym].append(name)
+
+    return _keysymsCache[keysym]
+
 def getKeycode(keysym):
     """Converts an XKeysym string (e.g., 'KP_Enter') to a keycode that
     should match the event.hw_code for key events.
