Index: gtk/gtkentry.c
===================================================================
--- gtk/gtkentry.c	(Revision 20144)
+++ gtk/gtkentry.c	(Arbeitskopie)
@@ -87,6 +87,7 @@ struct _GtkEntryPrivate 
   guint interior_focus : 1;
   guint real_changed   : 1;
   guint change_count   : 8;
+  gboolean invisible_char_set : 1;
 
   gint focus_width;
   GtkShadowType shadow_type;
@@ -126,6 +127,7 @@ enum {
   PROP_HAS_FRAME,
   PROP_INNER_BORDER,
   PROP_INVISIBLE_CHAR,
+  PROP_INVISIBLE_CHAR_SET,
   PROP_ACTIVATES_DEFAULT,
   PROP_WIDTH_CHARS,
   PROP_SCROLL_OFFSET,
@@ -540,6 +542,21 @@ gtk_entry_class_init (GtkEntryClass *cla
 							 '*',
 							 GTK_PARAM_READWRITE));
 
+  /**
+   * GtkEntry:invisible-char-set:
+   *
+   * Whether to override the default invisible character. 
+   *
+   * Since: 2.14
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_INVISIBLE_CHAR_SET,
+                                   g_param_spec_boolean ("invisible-char-set",
+                                                         P_("Invisible Char Set"),
+                                                         P_("Whether to override the default invisible character"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE));
+
   g_object_class_install_property (gobject_class,
                                    PROP_ACTIVATES_DEFAULT,
                                    g_param_spec_boolean ("activates-default",
@@ -894,7 +911,7 @@ gtk_entry_class_init (GtkEntryClass *cla
                                                                GTK_TYPE_BORDER,
                                                                GTK_PARAM_READABLE));
 
-   gtk_settings_install_property (g_param_spec_boolean ("gtk-entry-select-on-focus",
+  gtk_settings_install_property (g_param_spec_boolean ("gtk-entry-select-on-focus",
 						       P_("Select on focus"),
 						       P_("Whether to select the contents of an entry when it is focused"),
 						       TRUE,
@@ -914,6 +931,21 @@ gtk_entry_class_init (GtkEntryClass *cla
                                                     P_("How long to show the last input character in hidden entries"),
                                                     0, G_MAXUINT, 0,
                                                     GTK_PARAM_READWRITE));
+                                                    
+  /**
+   * GtkSettings:gtk-invisible-char:
+   *
+   * The character to use when masking the contents of an entry in
+   * \"password mode\". This can be overridden locally by calling
+   * gtk_entry_set_invisible_char for a particular entry.
+   *
+   * Since: 2.14
+   */
+  gtk_settings_install_property (g_param_spec_unichar ("gtk-invisible-char",
+						       P_("Invisible character"),
+						       P_("The character to use when masking entry contents (in \"password mode\")"),
+						       '*',
+						       GTK_PARAM_READWRITE));                                   
 
   g_type_class_add_private (gobject_class, sizeof (GtkEntryPrivate));
 }
@@ -994,6 +1026,9 @@ gtk_entry_set_property (GObject         
     case PROP_INVISIBLE_CHAR:
       gtk_entry_set_invisible_char (entry, g_value_get_uint (value));
       break;
+    case PROP_INVISIBLE_CHAR_SET:
+      priv->invisible_char_set = g_value_get_boolean (value);;
+      break;
 
     case PROP_ACTIVATES_DEFAULT:
       gtk_entry_set_activates_default (entry, g_value_get_boolean (value));
@@ -1060,7 +1095,10 @@ gtk_entry_get_property (GObject         
       g_value_set_boxed (value, gtk_entry_get_inner_border (entry));
       break;
     case PROP_INVISIBLE_CHAR:
-      g_value_set_uint (value, entry->invisible_char);
+      g_value_set_uint (value, gtk_entry_get_invisible_char (entry));
+      break;
+    case PROP_INVISIBLE_CHAR_SET:
+      g_value_set_boolean (value, priv->invisible_char_set);
       break;
     case PROP_ACTIVATES_DEFAULT:
       g_value_set_boolean (value, entry->activates_default);
@@ -1104,6 +1142,7 @@ gtk_entry_init (GtkEntry *entry)
   entry->editable = TRUE;
   entry->visible = TRUE;
   entry->invisible_char = '*';
+  priv->invisible_char_set = FALSE;
   entry->dnd_position = -1;
   entry->width_chars = -1;
   entry->is_cell_renderer = FALSE;
@@ -1587,7 +1626,7 @@ gtk_entry_expose (GtkWidget      *widget
       
       gtk_entry_draw_text (GTK_ENTRY (widget));
 
-      if ((entry->visible || entry->invisible_char != 0) &&
+      if ((entry->visible || gtk_entry_get_invisible_char (entry) != 0) &&
 	  GTK_WIDGET_HAS_FOCUS (widget) &&
 	  entry->selection_bound == entry->current_pos && entry->cursor_visible)
 	gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD);
@@ -3290,9 +3329,9 @@ gtk_entry_create_layout (GtkEntry *entry
           preedit_len_chars = g_utf8_strlen (preedit_string, -1);
           ch_len += preedit_len_chars;
 
-          if (entry->invisible_char != 0)
-            invisible_char = entry->invisible_char;
-          else
+          invisible_char = gtk_entry_get_invisible_char (entry);
+
+          if (invisible_char == 0)
             invisible_char = ' '; /* just pick a char */
           
           append_char (tmp_string, invisible_char, ch_len);
@@ -3368,9 +3407,9 @@ gtk_entry_create_layout (GtkEntry *entry
                         "gtk-entry-password-hint-timeout", &password_hint_timeout,
                         NULL);
 
-          if (entry->invisible_char != 0)
-            invisible_char = entry->invisible_char;
-          else
+          invisible_char = gtk_entry_get_invisible_char (entry);
+
+          if (invisible_char == 0)
             invisible_char = ' '; /* just pick a char */
 
           password_hint = g_object_get_qdata (G_OBJECT (entry),
@@ -3497,7 +3536,7 @@ gtk_entry_draw_text (GtkEntry *entry)
 {
   GtkWidget *widget;
   
-  if (!entry->visible && entry->invisible_char == 0)
+  if (!entry->visible && gtk_entry_get_invisible_char (entry) == 0)
     return;
   
   if (GTK_WIDGET_DRAWABLE (entry))
@@ -3763,7 +3802,9 @@ gtk_entry_get_cursor_locations (GtkEntry
 				gint       *strong_x,
 				gint       *weak_x)
 {
-  if (!entry->visible && !entry->invisible_char)
+  gunichar invisible_char = gtk_entry_get_invisible_char (entry);
+
+  if (!entry->visible && !invisible_char)
     {
       if (strong_x)
 	*strong_x = 0;
@@ -3793,7 +3834,7 @@ gtk_entry_get_cursor_locations (GtkEntry
 	      else
 		{
 		  gint preedit_len_chars = g_utf8_strlen (text, -1) - entry->text_length;
-		  index += preedit_len_chars * g_unichar_to_utf8 (entry->invisible_char, NULL);
+		  index += preedit_len_chars * g_unichar_to_utf8 (invisible_char, NULL);
 		}
 	    }
 	}
@@ -4154,12 +4195,14 @@ gtk_entry_get_public_chars (GtkEntry *en
   
   if (entry->visible)
     return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
-  else if (!entry->invisible_char)
+    
+  gunichar invisible_char = gtk_entry_get_invisible_char (entry);
+  if (!invisible_char)
     return g_strdup ("");
   else
     {
       GString *str = g_string_new (NULL);
-      append_char (str, entry->invisible_char, end - start);
+      append_char (str, invisible_char, end - start);
       return g_string_free (str, FALSE);
     }
 }
@@ -4554,11 +4597,15 @@ gtk_entry_set_invisible_char (GtkEntry *
 {
   g_return_if_fail (GTK_IS_ENTRY (entry));
 
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
+  priv->invisible_char_set = TRUE;
+
   if (ch == entry->invisible_char)
     return;
 
   entry->invisible_char = ch;
   g_object_notify (G_OBJECT (entry), "invisible-char");
+  g_object_notify (G_OBJECT (entry), "invisible-char-set");
   gtk_entry_recompute (entry);  
 }
 
@@ -4576,8 +4623,19 @@ gunichar
 gtk_entry_get_invisible_char (GtkEntry *entry)
 {
   g_return_val_if_fail (GTK_IS_ENTRY (entry), 0);
+  
+  GtkEntryPrivate *priv = GTK_ENTRY_GET_PRIVATE (entry);
+  
+  if (priv->invisible_char_set)
+    return entry->invisible_char;
+
+  gunichar invisible_char;
+
+  g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)),
+                "gtk-invisible-char", &invisible_char,
+                NULL);
 
-  return entry->invisible_char;
+  return invisible_char;
 }
 
 /**
