Index: gtk/gtkentry.c
===================================================================
--- gtk/gtkentry.c	(Revision 20397)
+++ gtk/gtkentry.c	(Arbeitskopie)
@@ -539,6 +539,15 @@ gtk_entry_class_init (GtkEntryClass *cla
                                                        GTK_TYPE_BORDER,
                                                        GTK_PARAM_READWRITE));
 
+  /**
+   * GtkEntry:invisible-char:
+   *
+   * The character to use when masking entry contents (in \"password mode\").
+   *
+   * Deprecated: GtkEntry::invisible-char is deprecated and
+   *             should not be used in newly written code. Use
+   *             GtkSettings::invisible-char instead.
+   */
   g_object_class_install_property (gobject_class,
                                    PROP_INVISIBLE_CHAR,
                                    g_param_spec_unichar ("invisible-char",
@@ -901,7 +910,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,
@@ -922,6 +931,34 @@ gtk_entry_class_init (GtkEntryClass *cla
                                                     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));
+
+  /**
+   * GtkSettings:gtk-invisible-char-set:
+   *
+   * Whether to override the default invisible character.
+   *
+   * Since: 2.14
+   */
+  gtk_settings_install_property (g_param_spec_boolean ("gtk-invisible-char-set",
+                                                       P_("Invisible Char Set"),
+                                                       P_("Whether to override the default invisible character"),
+                                                       FALSE,
+                                                       GTK_PARAM_READWRITE));
+
   g_type_class_add_private (gobject_class, sizeof (GtkEntryPrivate));
 }
 
@@ -999,7 +1036,6 @@ gtk_entry_set_property (GObject         
       break;
 
     case PROP_INVISIBLE_CHAR:
-      gtk_entry_set_invisible_char (entry, g_value_get_uint (value));
       break;
 
     case PROP_ACTIVATES_DEFAULT:
@@ -1067,7 +1103,7 @@ 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_ACTIVATES_DEFAULT:
       g_value_set_boolean (value, entry->activates_default);
@@ -1255,11 +1291,62 @@ gtk_entry_finalize (GObject *object)
 }
 
 static void
+gtk_entry_invisible_char_cb (GObject    *gobject,
+                             GParamSpec *arg1,
+                             gpointer    user_data)
+{
+  GtkSettings* gtk_settings;
+  GtkEntry *entry;
+
+  gtk_settings = gtk_widget_get_settings (GTK_WIDGET (entry));
+  entry = GTK_ENTRY (gobject);
+  g_object_get (G_OBJECT (gtk_settings),
+                "gtk-invisible-char", &entry->invisible_char,
+                NULL);
+
+  g_object_notify (gobject, "invisible-char");
+  gtk_entry_recompute (entry);
+
+  g_object_set (gtk_settings,
+                "gtk-invisible-char", entry->invisible_char,
+                NULL);
+}
+
+static void
+gtk_entry_invisible_char_set_cb (GObject    *gobject,
+                                 GParamSpec *arg1,
+                                 gpointer    user_data)
+{
+  GtkSettings* gtk_settings;
+  GtkEntry *entry;
+  gboolean invisible_char_set;
+  GParamSpec *pspec;
+
+  gtk_settings = gtk_widget_get_settings (GTK_WIDGET (entry));
+  entry = GTK_ENTRY (gobject);
+  invisible_char_set = entry->invisible_char_set;
+  g_object_get (gobject,
+                "gtk-invisible-char-set", &entry->invisible_char_set,
+                NULL);
+
+  if (invisible_char_set && !entry->invisible_char_set)
+    {
+      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (gtk_settings),
+                                            "gtk-invisible-char");
+      g_object_set (gtk_settings,
+                    "gtk-invisible-char",
+                    G_PARAM_SPEC_UCHAR (pspec)->default_value,
+                    NULL);
+    }
+}
+
+static void
 gtk_entry_realize (GtkWidget *widget)
 {
   GtkEntry *entry;
   GdkWindowAttr attributes;
   gint attributes_mask;
+  GtkSettings *gtk_settings;
 
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
   entry = GTK_ENTRY (widget);
@@ -1312,6 +1399,12 @@ gtk_entry_realize (GtkWidget *widget)
 
   gtk_entry_adjust_scroll (entry);
   gtk_entry_update_primary_selection (entry);
+
+  gtk_settings = gtk_widget_get_settings (GTK_WIDGET (entry));
+  g_signal_connect (gtk_settings, "notify::invisible-char",
+		    G_CALLBACK (gtk_entry_invisible_char_cb), entry);
+  g_signal_connect (gtk_settings, "notify::invisible-char-set",
+		    G_CALLBACK (gtk_entry_invisible_char_set_cb), entry);
 }
 
 static void
@@ -1624,7 +1717,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);
@@ -3327,9 +3420,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);
@@ -3405,9 +3498,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),
@@ -3534,7 +3627,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))
@@ -3800,7 +3893,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;
@@ -3830,7 +3925,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);
 		}
 	    }
 	}
@@ -4191,12 +4286,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);
     }
 }
@@ -4576,14 +4673,12 @@ gtk_entry_get_visibility (GtkEntry *entr
  * gtk_entry_set_invisible_char:
  * @entry: a #GtkEntry
  * @ch: a Unicode character
- * 
- * Sets the character to use in place of the actual text when
- * gtk_entry_set_visibility() has been called to set text visibility
- * to %FALSE. i.e. this is the character used in "password mode" to
- * show the user how many characters have been typed. The default
- * invisible char is an asterisk ('*').  If you set the invisible char
- * to 0, then the user will get no feedback at all; there will be
- * no text on the screen as they type.
+ *
+ * This function has no effect.
+ *
+ * Deprecated: gtk_entry_set_visible_char() is deprecated and
+ *   should not be used in newly-written code. Use
+ *   GtkSettings::invisible-char instead.
  **/
 void
 gtk_entry_set_invisible_char (GtkEntry *entry,
@@ -4596,7 +4691,7 @@ gtk_entry_set_invisible_char (GtkEntry *
 
   entry->invisible_char = ch;
   g_object_notify (G_OBJECT (entry), "invisible-char");
-  gtk_entry_recompute (entry);  
+  gtk_entry_recompute (entry);
 }
 
 /**
@@ -4604,14 +4699,20 @@ gtk_entry_set_invisible_char (GtkEntry *
  * @entry: a #GtkEntry
  *
  * Retrieves the character displayed in place of the real characters
- * for entries with visibility set to false. See gtk_entry_set_invisible_char().
+ * for entries with visibility set to false.
  *
  * Return value: the current invisible char, or 0, if the entry does not
- *               show invisible text at all. 
+ *               show invisible text at all.
+ *
+ * Deprecated: gtk_entry_get_visible_char() is deprecated and
+ *   should not be used in newly-written code. Use
+ *   GtkSettings::invisible-char instead.
  **/
 gunichar
 gtk_entry_get_invisible_char (GtkEntry *entry)
 {
+  gunichar invisible_char;
+
   g_return_val_if_fail (GTK_IS_ENTRY (entry), 0);
 
   return entry->invisible_char;
Index: gtk/gtkentry.h
===================================================================
--- gtk/gtkentry.h	(Revision 20397)
+++ gtk/gtkentry.h	(Arbeitskopie)
@@ -109,6 +109,7 @@ struct _GtkEntry
   gint drag_start_y;
 
   gunichar invisible_char;
+  gboolean invisible_char_set;
 
   gint width_chars;
 };
@@ -156,9 +157,6 @@ GtkWidget* gtk_entry_new            		(v
 void       gtk_entry_set_visibility 		(GtkEntry      *entry,
 						 gboolean       visible);
 gboolean   gtk_entry_get_visibility             (GtkEntry      *entry);
-void       gtk_entry_set_invisible_char         (GtkEntry      *entry,
-                                                 gunichar       ch);
-gunichar   gtk_entry_get_invisible_char         (GtkEntry      *entry);
 void       gtk_entry_set_has_frame              (GtkEntry      *entry,
                                                  gboolean       setting);
 gboolean   gtk_entry_get_has_frame              (GtkEntry      *entry);
@@ -223,6 +221,9 @@ void       gtk_entry_select_region  		(G
 						 gint           end);
 void       gtk_entry_set_editable   		(GtkEntry      *entry,
 						 gboolean       editable);
+void       gtk_entry_set_invisible_char         (GtkEntry      *entry,
+                                                 gunichar       ch);
+gunichar   gtk_entry_get_invisible_char         (GtkEntry      *entry);
 #endif /* GTK_DISABLE_DEPRECATED */
 
 G_END_DECLS
